Skip to content

Commit

Permalink
🌱 Update application, archetype rest and queries
Browse files Browse the repository at this point in the history
  - Update api functions `createApplication` and `createArchetype` to
    take as input a `New<>` payload and return the newly created entity
    as a result.

  - Update query `useCreateApplicationMutation` to pass the proper
    values to the `onSuccess` and `onError` callbacks.

  - Update various fetch queries to return `isSuccess` so component
    code can ensure at least 1 successful fetch has happened before
    rendering data that depends on the fetch results.

  - Add query `useFetchTagsWithTagItems` as a convenience to get a
    full list of tags with tag category refs, and a `TagItemType`
    transform of the tags to be useful for display.

Signed-off-by: Scott J Dickerson <sdickers@redhat.com>
  • Loading branch information
sjd78 committed Nov 6, 2023
1 parent 3791d04 commit 556cc2d
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 14 deletions.
12 changes: 7 additions & 5 deletions client/src/app/api/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,11 @@ export const deleteIdentity = (identity: Identity): AxiosPromise => {

// Axios direct

export const createApplication = (data: Application) =>
axios.post<Application>(`${APPLICATIONS}`, data);
// success with code 201 and created entity as response data
export const createApplication = (application: New<Application>) =>
axios
.post<Application>(`${APPLICATIONS}`, application)
.then((response) => response.data);

export const deleteApplication = (id: number): Promise<Application> =>
axios.delete(`${APPLICATIONS}/${id}`);
Expand Down Expand Up @@ -742,9 +745,8 @@ export const getArchetypeById = (id: number | string): Promise<Archetype> =>
axios.get(`${ARCHETYPES}/${id}`).then(({ data }) => data);

// success with code 201 and created entity as response data
export const createArchetype = (
archetype: New<Archetype>
): Promise<Archetype> => axios.post(ARCHETYPES, archetype);
export const createArchetype = (archetype: New<Archetype>) =>
axios.post<Archetype>(ARCHETYPES, archetype).then((res) => res.data);

// success with code 204 and therefore no response content
export const updateArchetype = (archetype: Archetype): Promise<void> =>
Expand Down
15 changes: 10 additions & 5 deletions client/src/app/queries/applications.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import axios, { AxiosError } from "axios";

import { Application, ApplicationDependency, MimeType } from "@app/api/models";
import {
Application,
ApplicationDependency,
MimeType,
New,
} from "@app/api/models";
import {
APPLICATIONS,
createApplication,
Expand Down Expand Up @@ -98,14 +103,14 @@ export const useUpdateAllApplicationsMutation = (
};

export const useCreateApplicationMutation = (
onSuccess: (data: Application) => void,
onError: (err: AxiosError) => void
onSuccess: (application: Application, payload: New<Application>) => void,
onError: (err: AxiosError, payload: New<Application>) => void
) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: createApplication,
onSuccess: ({ data }) => {
onSuccess(data);
onSuccess: (application: Application, payload: New<Application>) => {
onSuccess(application, payload);
queryClient.invalidateQueries([ApplicationsQueryKey]);
},
onError: onError,
Expand Down
3 changes: 2 additions & 1 deletion client/src/app/queries/archetypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const ARCHETYPES_QUERY_KEY = "archetypes";
export const ARCHETYPE_QUERY_KEY = "archetype";

export const useFetchArchetypes = () => {
const { isLoading, error, refetch, data } = useQuery({
const { isLoading, isSuccess, error, refetch, data } = useQuery({
initialData: [],
queryKey: [ARCHETYPES_QUERY_KEY],
queryFn: getArchetypes,
Expand All @@ -25,6 +25,7 @@ export const useFetchArchetypes = () => {
return {
archetypes: data || [],
isFetching: isLoading,
isSuccess,
error,
refetch,
};
Expand Down
3 changes: 2 additions & 1 deletion client/src/app/queries/stakeholdergoups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import { AxiosError } from "axios";
export const StakeholderGroupsQueryKey = "stakeholderGroups";

export const useFetchStakeholderGroups = () => {
const { data, isLoading, error, refetch } = useQuery({
const { data, isLoading, isSuccess, error, refetch } = useQuery({
queryKey: [StakeholderGroupsQueryKey],
queryFn: getStakeholderGroups,
onError: (error: AxiosError) => console.log("error, ", error),
});
return {
stakeholderGroups: data || [],
isFetching: isLoading,
isSuccess,
fetchError: error,
refetch,
};
Expand Down
3 changes: 2 additions & 1 deletion client/src/app/queries/stakeholders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Role, Stakeholder, StakeholderWithRole } from "@app/api/models";
export const StakeholdersQueryKey = "stakeholders";

export const useFetchStakeholders = () => {
const { data, isLoading, error, refetch } = useQuery({
const { data, isLoading, isSuccess, error, refetch } = useQuery({
queryKey: [StakeholdersQueryKey],
queryFn: getStakeholders,
onError: (error: AxiosError) => console.log("error, ", error),
Expand All @@ -31,6 +31,7 @@ export const useFetchStakeholders = () => {
return {
stakeholders: data || [],
isFetching: isLoading,
isSuccess,
fetchError: error,
refetch,
};
Expand Down
56 changes: 55 additions & 1 deletion client/src/app/queries/tags.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useMemo } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";

import {
Expand Down Expand Up @@ -30,19 +31,72 @@ export const useFetchTags = () => {
};

export const useFetchTagCategories = () => {
const { data, isLoading, error, refetch } = useQuery({
const { data, isLoading, isSuccess, error, refetch } = useQuery({
queryKey: [TagCategoriesQueryKey, TagsQueryKey],
queryFn: getTagCategories,
onError: (error: AxiosError) => console.log("error, ", error),
});

return {
tagCategories: data || [],
isFetching: isLoading,
isSuccess,
fetchError: error,
refetch,
};
};

/**
* Tag repackaged as an ItemType to make it easier to use and display.
*/
export interface TagItemType {
id: number;
name: string;
tooltip?: string;
}

export const useFetchTagsWithTagItems = () => {
// fetching tag categories with their tags is to most compact way to get all of
// that information in a single call
const { tagCategories, isFetching, isSuccess, fetchError, refetch } =
useFetchTagCategories();

// transform the tag categories in a list of tags with category refs
const tags = useMemo(
() =>
tagCategories
.flatMap(({ id, name, tags }) => {
const ref = { id, name };
return tags?.map((t) => {
t.category = ref;
return t;
});
})
.filter(Boolean),
[tagCategories]
);

// for each tag, build a `TagItemType` for easy use in the UI
const tagItems: TagItemType[] = useMemo(() => {
return tags
.map<TagItemType>((tag) => ({
id: tag.id,
name: `${tag.category?.name} / ${tag.name}`,
tooltip: tag.category?.name,
}))
.sort((a, b) => a.name.localeCompare(b.name));
}, [tags]);

return {
tags,
tagItems,
isFetching,
isSuccess,
fetchError,
refetch,
};
};

export const useCreateTagMutation = (
onSuccess: (res: any) => void,
onError: (err: AxiosError) => void
Expand Down

0 comments on commit 556cc2d

Please sign in to comment.