diff --git a/client/src/app/api/models.ts b/client/src/app/api/models.ts index 1fd51790c..88c519539 100644 --- a/client/src/app/api/models.ts +++ b/client/src/app/api/models.ts @@ -41,7 +41,7 @@ export interface BusinessService { id: number; name: string; description?: string; - owner?: Stakeholder; + owner?: Ref; } export interface Stakeholder { diff --git a/client/src/app/api/rest.ts b/client/src/app/api/rest.ts index 14e1cb1eb..203f5f2ed 100644 --- a/client/src/app/api/rest.ts +++ b/client/src/app/api/rest.ts @@ -618,27 +618,27 @@ export const updateStakeholderGroup = ( ): Promise => axios.put(`${STAKEHOLDER_GROUPS}/${obj.id}`, obj); +// --------------------------------------- // Business services +// +export const getBusinessServices = () => + axios + .get(BUSINESS_SERVICES) + .then((response) => response.data); -export const getBusinessServices = (): Promise => - axios.get(BUSINESS_SERVICES).then((response) => response.data); - -export const deleteBusinessService = ( - id: number | string -): Promise => axios.delete(`${BUSINESS_SERVICES}/${id}`); +export const getBusinessServiceById = (id: number | string) => + axios + .get(`${BUSINESS_SERVICES}/${id}`) + .then((response) => response.data); -export const createBusinessService = ( - obj: New -): Promise => axios.post(BUSINESS_SERVICES, obj); +export const createBusinessService = (obj: New) => + axios.post(BUSINESS_SERVICES, obj); -export const updateBusinessService = ( - obj: BusinessService -): Promise => axios.put(`${BUSINESS_SERVICES}/${obj.id}`, obj); +export const updateBusinessService = (obj: BusinessService) => + axios.put(`${BUSINESS_SERVICES}/${obj.id}`, obj); -export const getBusinessServiceById = ( - id: number | string -): Promise => - axios.get(`${BUSINESS_SERVICES}/${id}`).then((response) => response.data); +export const deleteBusinessService = (id: number | string) => + axios.delete(`${BUSINESS_SERVICES}/${id}`); // Job functions diff --git a/client/src/app/pages/controls/business-services/components/business-service-form.tsx b/client/src/app/pages/controls/business-services/components/business-service-form.tsx index 36a012324..8365ae46a 100644 --- a/client/src/app/pages/controls/business-services/components/business-service-form.tsx +++ b/client/src/app/pages/controls/business-services/components/business-service-form.tsx @@ -1,6 +1,6 @@ import React from "react"; import { useTranslation } from "react-i18next"; -import { AxiosError, AxiosResponse } from "axios"; +import { AxiosError } from "axios"; import { object, string } from "yup"; import { @@ -27,6 +27,7 @@ import { } from "@app/components/HookFormPFFields"; import { OptionWithValue, SimpleSelect } from "@app/components/SimpleSelect"; import { NotificationsContext } from "@app/components/NotificationsContext"; +import { matchItemsToRef } from "@app/utils/model-utils"; export interface FormValues { name: string; @@ -44,10 +45,16 @@ export const BusinessServiceForm: React.FC = ({ onClose, }) => { const { t } = useTranslation(); - const { pushNotification } = React.useContext(NotificationsContext); - const { businessServices } = useFetchBusinessServices(); - const { stakeholders } = useFetchStakeholders(); + const { + businessServices, + stakeholders, + stakeholderToRef, + createBusinessService, + updateBusinessService, + } = useBusinessServiceFormData({ + onActionSuccess: onClose, + }); const stakeholdersOptions = stakeholders.map((stakeholder) => { return { @@ -92,65 +99,11 @@ export const BusinessServiceForm: React.FC = ({ mode: "all", }); - const onCreateBusinessServiceSuccess = ( - response: AxiosResponse - ) => { - pushNotification({ - title: t("toastr.success.createWhat", { - type: t("terms.businessService"), - what: response.data.name, - }), - variant: "success", - }); - onClose(); - }; - - const onUpdateBusinessServiceSuccess = () => { - pushNotification({ - title: t("toastr.success.save", { - type: t("terms.businessService"), - }), - variant: "success", - }); - onClose(); - }; - - const onCreateBusinessServiceError = (error: AxiosError) => { - pushNotification({ - title: t("toastr.fail.create", { - type: t("terms.businessService").toLowerCase(), - }), - variant: "danger", - }); - }; - - const { mutate: createBusinessService } = useCreateBusinessServiceMutation( - onCreateBusinessServiceSuccess, - onCreateBusinessServiceError - ); - - const onUpdateBusinessServiceError = (error: AxiosError) => { - pushNotification({ - title: t("toastr.fail.save", { - type: t("terms.businessService").toLowerCase(), - }), - variant: "danger", - }); - }; - - const { mutate: updateBusinessService } = useUpdateBusinessServiceMutation( - onUpdateBusinessServiceSuccess, - onUpdateBusinessServiceError - ); - const onSubmit = (formValues: FormValues) => { - const matchingStakeholderRef = stakeholders.find( - (stakeholder) => stakeholder.name === formValues.owner - ); const payload: New = { name: formValues.name.trim(), description: formValues.description.trim(), - owner: matchingStakeholderRef, + owner: stakeholderToRef(formValues.owner), }; if (businessService) { @@ -158,7 +111,6 @@ export const BusinessServiceForm: React.FC = ({ } else { createBusinessService(payload); } - onClose(); }; return ( @@ -223,3 +175,91 @@ export const BusinessServiceForm: React.FC = ({ ); }; + +const useBusinessServiceFormData = ({ + onActionSuccess = () => {}, + onActionFail = () => {}, +}: { + onActionSuccess?: () => void; + onActionFail?: () => void; +}) => { + const { t } = useTranslation(); + const { pushNotification } = React.useContext(NotificationsContext); + + // Fetch data + const { businessServices } = useFetchBusinessServices(); + const { stakeholders } = useFetchStakeholders(); + + // Helpers + const stakeholderToRef = (name: string | undefined | null) => + matchItemsToRef(stakeholders, (i) => i.name, name); + + // Mutation notification handlers + const onCreateBusinessServiceSuccess = (data: BusinessService) => { + pushNotification({ + title: t("toastr.success.createWhat", { + type: t("terms.businessService"), + what: data.name, + }), + variant: "success", + }); + onActionSuccess(); + }; + + const onCreateBusinessServiceError = ( + _error: AxiosError, + _payload: New + ) => { + pushNotification({ + title: t("toastr.fail.create", { + type: t("terms.businessService").toLowerCase(), + }), + variant: "danger", + }); + onActionFail(); + }; + + const onUpdateBusinessServiceSuccess = (payload: BusinessService) => { + pushNotification({ + title: t("toastr.success.saveWhat", { + type: t("terms.businessService"), + what: payload.name, + }), + variant: "success", + }); + onActionSuccess(); + }; + + const onUpdateBusinessServiceError = ( + _error: AxiosError, + _payload: New + ) => { + pushNotification({ + title: t("toastr.fail.save", { + type: t("terms.businessService").toLowerCase(), + }), + variant: "danger", + }); + onActionFail(); + }; + + // Mutations + const { mutate: createBusinessService } = useCreateBusinessServiceMutation( + onCreateBusinessServiceSuccess, + onCreateBusinessServiceError + ); + + const { mutate: updateBusinessService } = useUpdateBusinessServiceMutation( + onUpdateBusinessServiceSuccess, + onUpdateBusinessServiceError + ); + + // Send back source data and action that are needed by the ApplicationForm + return { + businessServices, + stakeholders, + stakeholderToRef, + createBusinessService, + updateBusinessService, + }; +}; diff --git a/client/src/app/queries/businessservices.ts b/client/src/app/queries/businessservices.ts index 772ee682c..abd764355 100644 --- a/client/src/app/queries/businessservices.ts +++ b/client/src/app/queries/businessservices.ts @@ -8,6 +8,7 @@ import { getBusinessServices, updateBusinessService, } from "@app/api/rest"; +import { BusinessService, New } from "@app/api/models"; export const BusinessServicesQueryKey = "businessservices"; export const BusinessServiceQueryKey = "businessservice"; @@ -40,15 +41,15 @@ export const useFetchBusinessServiceByID = (id: number | string) => { }; export const useCreateBusinessServiceMutation = ( - onSuccess: (res: any) => void, - onError: (err: AxiosError) => void + onSuccess: (res: BusinessService) => void, + onError: (err: AxiosError, payload: New) => void ) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: createBusinessService, - onSuccess: (res) => { - onSuccess(res); + onSuccess: ({ data }, _payload) => { + onSuccess(data); queryClient.invalidateQueries([BusinessServicesQueryKey]); }, onError, @@ -56,14 +57,14 @@ export const useCreateBusinessServiceMutation = ( }; export const useUpdateBusinessServiceMutation = ( - onSuccess: () => void, - onError: (err: AxiosError) => void + onSuccess: (payload: BusinessService) => void, + onError: (err: AxiosError, payload: BusinessService) => void ) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: updateBusinessService, - onSuccess: () => { - onSuccess(); + onSuccess: (_res, payload) => { + onSuccess(payload); queryClient.invalidateQueries([BusinessServicesQueryKey]); }, onError: onError, @@ -71,18 +72,19 @@ export const useUpdateBusinessServiceMutation = ( }; export const useDeleteBusinessServiceMutation = ( - onSuccess: (res: any) => void, - onError: (err: AxiosError) => void + onSuccess: (id: number | string) => void, + onError: (err: AxiosError, id: number | string) => void ) => { const queryClient = useQueryClient(); - const { isLoading, mutate, error } = useMutation(deleteBusinessService, { - onSuccess: (res) => { - onSuccess(res); + const { isLoading, mutate, error } = useMutation({ + mutationFn: deleteBusinessService, + onSuccess: (_res, id) => { + onSuccess(id); queryClient.invalidateQueries([BusinessServicesQueryKey]); }, - onError: (err: AxiosError) => { - onError(err); + onError: (err: AxiosError, id) => { + onError(err, id); queryClient.invalidateQueries([BusinessServicesQueryKey]); }, });