diff --git a/src/Core/Domain/ProjectModel.ts b/src/Core/Domain/ProjectModel.ts index 2b55ee9f3..6a30b512d 100644 --- a/src/Core/Domain/ProjectModel.ts +++ b/src/Core/Domain/ProjectModel.ts @@ -16,6 +16,7 @@ export interface EnvironmentModel { repo_url: string; description?: string; icon?: string; + halted: boolean; } export interface FlatEnvironment extends EnvironmentModel { diff --git a/src/Data/Managers/Helpers/QueryManager/ContinuousWithEnv.test.tsx b/src/Data/Managers/Helpers/QueryManager/ContinuousWithEnv.test.tsx index 31b8e4269..bbace848a 100644 --- a/src/Data/Managers/Helpers/QueryManager/ContinuousWithEnv.test.tsx +++ b/src/Data/Managers/Helpers/QueryManager/ContinuousWithEnv.test.tsx @@ -31,6 +31,10 @@ test("GIVEN QueryManager.ContinuousWithEnv WHEN environment changes THEN the api repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, + settings: { + enable_lsm_expert_mode: false, + }, }, { id: "bbb", @@ -39,6 +43,10 @@ test("GIVEN QueryManager.ContinuousWithEnv WHEN environment changes THEN the api repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, + settings: { + enable_lsm_expert_mode: false, + }, }, ]), ); diff --git a/src/Data/Managers/V2/DELETE/DeleteDesiredStateVersion/useDeleteDesiredStateVersion.ts b/src/Data/Managers/V2/DELETE/DeleteDesiredStateVersion/useDeleteDesiredStateVersion.ts index 701e5feb7..5f5d59046 100644 --- a/src/Data/Managers/V2/DELETE/DeleteDesiredStateVersion/useDeleteDesiredStateVersion.ts +++ b/src/Data/Managers/V2/DELETE/DeleteDesiredStateVersion/useDeleteDesiredStateVersion.ts @@ -3,45 +3,24 @@ import { useMutation, useQueryClient, } from "@tanstack/react-query"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useDelete } from "../../helpers/useQueries"; /** * React Query hook for deleting version of Desired State * - * @param {string} env - The environment in which we are trying to remove the version. * @returns {Mutation} - The mutation object provided by `useMutation` hook. */ -export const useDeleteDesiredStateVersion = ( - env: string, -): UseMutationResult => { +export const useDeleteDesiredStateVersion = (): UseMutationResult< + void, + Error, + string, + unknown +> => { const client = useQueryClient(); - const { createHeaders, handleErrors } = useFetchHelpers(); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Deletes a version of the desired state. - * - * @param {string} version - The version of the desired state to be removed. - * @returns {Promise} - A promise that resolves when the version is successfully removed. - * @throws {Error} If the response is not successful, an error with the error message is thrown. - */ - const deleteOrder = async (version: string): Promise => { - const response = await fetch(baseUrl + `/api/v1/version/${version}`, { - method: "DELETE", - headers: createHeaders(env), - }); - - await handleErrors(response); - }; + const deleteFn = useDelete(); return useMutation({ - mutationFn: deleteOrder, + mutationFn: (version) => deleteFn(`/api/v1/version/${version}`), mutationKey: ["delete_desired_state_version"], onSuccess: () => { //invalidate the desired state queries to update the list diff --git a/src/Data/Managers/V2/DELETE/DeleteInstance/useDeleteInstance.ts b/src/Data/Managers/V2/DELETE/DeleteInstance/useDeleteInstance.ts index 061927e8e..37e63d6f1 100644 --- a/src/Data/Managers/V2/DELETE/DeleteInstance/useDeleteInstance.ts +++ b/src/Data/Managers/V2/DELETE/DeleteInstance/useDeleteInstance.ts @@ -1,7 +1,6 @@ import { UseMutationResult, useMutation } from "@tanstack/react-query"; import { ParsedNumber } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useDelete } from "../../helpers/useQueries"; /** * React Query hook for Deleting an instance. @@ -9,41 +8,17 @@ import { useFetchHelpers } from "../../helpers"; * @returns {Mutation} - The mutation object provided by `useMutation` hook. */ export const useDeleteInstance = ( - environment: string, instance_id: string, service_entity: string, version: ParsedNumber, -): UseMutationResult => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Delete an instance. - * - * @returns {Promise} - A promise that resolves when the instance is succesfully deleted - */ - const deleteInstance = async (): Promise => { - const response = await fetch( - baseUrl + - `/lsm/v1/service_inventory/${service_entity}/${instance_id}?current_version=${version}`, - { - method: "DELETE", - headers: headers, - }, - ); - - await handleErrors(response); - }; +): UseMutationResult => { + const deleteFn = useDelete(); return useMutation({ - mutationFn: deleteInstance, + mutationFn: () => + deleteFn( + `/lsm/v1/service_inventory/${service_entity}/${instance_id}?current_version=${version}`, + ), mutationKey: ["delete_instance"], }); }; diff --git a/src/Data/Managers/V2/DELETE/DeleteService/useDeleteService.ts b/src/Data/Managers/V2/DELETE/DeleteService/useDeleteService.ts index 3957acd38..b46a55457 100644 --- a/src/Data/Managers/V2/DELETE/DeleteService/useDeleteService.ts +++ b/src/Data/Managers/V2/DELETE/DeleteService/useDeleteService.ts @@ -3,8 +3,7 @@ import { useMutation, useQueryClient, } from "@tanstack/react-query"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useDelete } from "../../helpers/useQueries"; /** * React Query hook for Deleting an Service. @@ -12,39 +11,13 @@ import { useFetchHelpers } from "../../helpers"; * @returns {Mutation} - The mutation object provided by `useMutation` hook. */ export const useDeleteService = ( - environment: string, service_entity: string, ): UseMutationResult => { const client = useQueryClient(); - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Delete an Service. - * - * @returns {Promise} - A promise that resolves when the Service is successfully deleted - */ - const deleteService = async (): Promise => { - const response = await fetch( - baseUrl + `/lsm/v1/service_catalog/${service_entity}`, - { - method: "DELETE", - headers: headers, - }, - ); - - await handleErrors(response); - }; + const deleteFn = useDelete(); return useMutation({ - mutationFn: deleteService, + mutationFn: () => deleteFn(`/lsm/v1/service_catalog/${service_entity}`), mutationKey: ["delete_service"], onSuccess: () => { client.refetchQueries({ queryKey: ["get_service_models-continuous"] }); diff --git a/src/Data/Managers/V2/DELETE/DestroyInstance/useDestroyInstance.ts b/src/Data/Managers/V2/DELETE/DestroyInstance/useDestroyInstance.ts index 20c035dc7..f9bb81bb0 100644 --- a/src/Data/Managers/V2/DELETE/DestroyInstance/useDestroyInstance.ts +++ b/src/Data/Managers/V2/DELETE/DestroyInstance/useDestroyInstance.ts @@ -1,7 +1,6 @@ import { UseMutationResult, useMutation } from "@tanstack/react-query"; import { ParsedNumber } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useDelete } from "../../helpers/useQueries"; /** * React Query hook for destroying an instance. @@ -10,44 +9,18 @@ import { useFetchHelpers } from "../../helpers"; * @returns {Mutation} - The mutation object provided by `useMutation` hook. */ export const useDestroyInstance = ( - environment: string, instance_id: string, service_entity: string, version: ParsedNumber, message: string, -): UseMutationResult => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - headers.append("message", message); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Destroy an instance. - * - * @returns {Promise} - A promise that resolves when the instance is succesfully destroyed. - */ - const destroyInstance = async (): Promise => { - const response = await fetch( - baseUrl + - `/lsm/v2/service_inventory/${service_entity}/${instance_id}/expert?current_version=${version}`, - { - method: "DELETE", - headers: headers, - }, - ); - - await handleErrors(response); - }; +): UseMutationResult => { + const deleteFn = useDelete({ message }); return useMutation({ - mutationFn: destroyInstance, + mutationFn: () => + deleteFn( + `/lsm/v2/service_inventory/${service_entity}/${instance_id}/expert?current_version=${version}`, + ), mutationKey: ["destroy_instance"], }); }; diff --git a/src/Data/Managers/V2/DELETE/RemoveUser/useRemoveUser.ts b/src/Data/Managers/V2/DELETE/RemoveUser/useRemoveUser.ts index 390f7ded2..69cc4478e 100644 --- a/src/Data/Managers/V2/DELETE/RemoveUser/useRemoveUser.ts +++ b/src/Data/Managers/V2/DELETE/RemoveUser/useRemoveUser.ts @@ -3,8 +3,7 @@ import { useMutation, useQueryClient, } from "@tanstack/react-query"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useDelete } from "../../helpers/useQueries"; /** * React Query hook for removing a user from the server. @@ -18,31 +17,10 @@ export const useRemoveUser = (): UseMutationResult< unknown > => { const client = useQueryClient(); - const { createHeaders, handleErrors } = useFetchHelpers(); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Deletes a user from the server. - * - * @param {string} username - The username of the user to be removed. - * @returns {Promise} - A promise that resolves when the user is successfully removed. - */ - const deleteOrder = async (username: string): Promise => { - const response = await fetch(baseUrl + `/api/v2/user/${username}`, { - method: "DELETE", - headers: createHeaders(), - }); - - await handleErrors(response); - }; + const deleteFn = useDelete(); return useMutation({ - mutationFn: deleteOrder, + mutationFn: (username) => deleteFn(`/api/v2/user/${username}`), mutationKey: ["removeUser"], onSuccess: () => { // Refetch the users query to update the list diff --git a/src/Data/Managers/V2/GETTERS/FormSuggestions/useSuggestions.ts b/src/Data/Managers/V2/GETTERS/FormSuggestions/useSuggestions.ts index f49494a75..6a2a1a579 100644 --- a/src/Data/Managers/V2/GETTERS/FormSuggestions/useSuggestions.ts +++ b/src/Data/Managers/V2/GETTERS/FormSuggestions/useSuggestions.ts @@ -1,7 +1,10 @@ import { useQuery } from "@tanstack/react-query"; import { FormSuggestion } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; + +interface ResponseData { + parameter: Record>; +} /** * React Query hook to handle suggested values for a parameter. @@ -10,16 +13,13 @@ import { useFetchHelpers } from "../../helpers"; * if the suggestions are null or undefined, it will return null as data, and a success status. * * @param suggestions - The suggestions for the parameter. - * @param environment - The environment for the parameter. * * @returns The result of the query, {data, status, error, isLoading}. */ export const useSuggestedValues = ( suggestions: FormSuggestion | null | undefined, - environment: string, ) => { - //extracted headers to avoid breaking rules of Hooks - const { createHeaders, handleErrors } = useFetchHelpers(); + const get = useGet(); if (!suggestions) { return { @@ -41,24 +41,6 @@ export const useSuggestedValues = ( }, }; } - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - const fetchParameter = async () => { - const response = await fetch( - `${baseUrl}/api/v1/parameter/${suggestions.parameter_name}`, - { - headers: createHeaders(environment), - }, - ); - - await handleErrors(response); - - return response.json(); - }; return { /** @@ -67,12 +49,8 @@ export const useSuggestedValues = ( */ useOneTime: () => useQuery({ - queryKey: [ - "get_parameter-one_time", - suggestions.parameter_name, - environment, - ], - queryFn: fetchParameter, + queryKey: ["get_parameter-one_time", suggestions.parameter_name], + queryFn: () => get(`/api/v1/parameter/${suggestions.parameter_name}`), retry: false, select: (data) => data.parameter, }), diff --git a/src/Data/Managers/V2/GETTERS/GetCurrentUser/useGetCurrentUser.ts b/src/Data/Managers/V2/GETTERS/GetCurrentUser/useGetCurrentUser.ts index 5aba224c6..8fbfe975e 100644 --- a/src/Data/Managers/V2/GETTERS/GetCurrentUser/useGetCurrentUser.ts +++ b/src/Data/Managers/V2/GETTERS/GetCurrentUser/useGetCurrentUser.ts @@ -1,6 +1,5 @@ import { UseQueryResult, useQuery } from "@tanstack/react-query"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; interface LoggedUser { username: string; @@ -12,23 +11,8 @@ interface LoggedUser { * @returns {Query} - An object containing a custom hook to fetch user information. */ export const useGetCurrentUser = () => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - const currentUserOrder = async (): Promise<{ data: LoggedUser }> => { - const response = await fetch(baseUrl + `/api/v2/current_user/`, { - headers: createHeaders(), - }); - - await handleErrors(response); - - return response.json(); - }; + const url = `/api/v2/current_user/`; + const get = useGet()<{ data: LoggedUser }>; return { /** @@ -37,7 +21,7 @@ export const useGetCurrentUser = () => { */ useOneTime: (): UseQueryResult => useQuery({ - queryFn: currentUserOrder, + queryFn: () => get(url), queryKey: ["get_current_user"], select: (data) => data.data, }), diff --git a/src/Data/Managers/V2/GETTERS/GetDesiredStates/useGetDesiredStates.ts b/src/Data/Managers/V2/GETTERS/GetDesiredStates/useGetDesiredStates.ts index 7bcd663a1..748b522c8 100644 --- a/src/Data/Managers/V2/GETTERS/GetDesiredStates/useGetDesiredStates.ts +++ b/src/Data/Managers/V2/GETTERS/GetDesiredStates/useGetDesiredStates.ts @@ -5,8 +5,7 @@ import { DesiredStateVersion, DesiredStateVersionStatus, } from "@/Slices/DesiredState/Core/Domain"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; import { getUrl } from "./getUrl"; /** @@ -45,48 +44,13 @@ interface GetDesiredStates { /** * React Query hook to fetch a list of desired States - * @param environment {string} - the environment in which the instance belongs * * @returns {GetDesiredStates} An object containing the available queries. * @returns {UseQueryResult} returns.useOneTime - Fetch the desired states with a single query. * @returns {UseQueryResult} returns.useContinuous - Fetch the desired states with a recurrent query with an interval of 5s. */ -export const useGetDesiredStates = (environment: string): GetDesiredStates => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Fetches the desired states from the API. - * - * @param {PageSize.PageSize} pageSize - The number of desired states to fetch per page. - * @param {Filter} filter - The filter to apply to the desired states. - * @param {CurrentPage} currentPage - The current page of desired states to fetch. - * @returns {Promise} - A promise that resolves with the fetched desired states. - * @throws {Error} If the response is not successful, an error with the error message is thrown. - */ - const fetchDesiredStates = async ( - pageSize: PageSize.PageSize, - filter: Filter, - currentPage: CurrentPage, - ): Promise => { - const response = await fetch( - baseUrl + - getUrl({ pageSize, filter, currentPage, kind: "GetDesiredStates" }), - { - headers, - }, - ); - - await handleErrors(response, `Failed to fetch desired states`); - - return response.json(); - }; +export const useGetDesiredStates = (): GetDesiredStates => { + const get = useGet(); return { useOneTime: ( @@ -101,7 +65,10 @@ export const useGetDesiredStates = (environment: string): GetDesiredStates => { filter, currentPage, ], - queryFn: () => fetchDesiredStates(pageSize, filter, currentPage), + queryFn: () => + get( + getUrl({ pageSize, filter, currentPage, kind: "GetDesiredStates" }), + ), retry: false, }), useContinuous: ( @@ -116,7 +83,10 @@ export const useGetDesiredStates = (environment: string): GetDesiredStates => { filter, currentPage, ], - queryFn: () => fetchDesiredStates(pageSize, filter, currentPage), + queryFn: () => + get( + getUrl({ pageSize, filter, currentPage, kind: "GetDesiredStates" }), + ), refetchInterval: 5000, }), }; diff --git a/src/Data/Managers/V2/GETTERS/GetDiagnostics/useGetDiagnostics.tsx b/src/Data/Managers/V2/GETTERS/GetDiagnostics/useGetDiagnostics.tsx index 173bbd888..b93699b25 100644 --- a/src/Data/Managers/V2/GETTERS/GetDiagnostics/useGetDiagnostics.tsx +++ b/src/Data/Managers/V2/GETTERS/GetDiagnostics/useGetDiagnostics.tsx @@ -1,7 +1,6 @@ import { useQuery, UseQueryResult } from "@tanstack/react-query"; import { RawDiagnostics } from "@/Slices/Diagnose/Core/Domain"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; /** * Return Signature of the useGetDiagnostics React Query @@ -15,7 +14,6 @@ interface GetDiagnostics { * * @param service {string} - the service entity * @param instanceId {string} - the instance ID for which the data needs to be fetched. - * @param environment {string} - the environment in which the instance belongs * * @returns {GetInstance} An object containing the different available queries. * @returns {UseQueryResult} returns.useOneTime - Fetch the diagnose report with a single query. @@ -23,40 +21,16 @@ interface GetDiagnostics { export const useGetDiagnostics = ( service: string, instanceId: string, - environment: string, ): GetDiagnostics => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - const fetchDiagnostics = async ( - lookBehind: string, - ): Promise<{ data: RawDiagnostics }> => { - const response = await fetch( - `${baseUrl}/lsm/v1/service_inventory/${service}/${instanceId}/diagnose?rejection_lookbehind=${lookBehind}&failure_lookbehind=${lookBehind}`, - { - headers, - }, - ); - - await handleErrors( - response, - `Failed to fetch diagnostics for id: ${instanceId}`, - ); - - return response.json(); - }; + const url = (lookBehind) => + `/lsm/v1/service_inventory/${service}/${instanceId}/diagnose?rejection_lookbehind=${lookBehind}&failure_lookbehind=${lookBehind}`; + const get = useGet()<{ data: RawDiagnostics }>; return { useOneTime: (lookBehind: string): UseQueryResult => useQuery({ queryKey: ["get_diagnostics-one_time", service, instanceId, lookBehind], - queryFn: () => fetchDiagnostics(lookBehind), + queryFn: () => get(url(lookBehind)), retry: false, select: (data) => data.data, }), diff --git a/src/Data/Managers/V2/GETTERS/GetInfiniteInstanceLogs/useGetInfiniteInstanceLogs.ts b/src/Data/Managers/V2/GETTERS/GetInfiniteInstanceLogs/useGetInfiniteInstanceLogs.ts index eb550ba73..0acc5285f 100644 --- a/src/Data/Managers/V2/GETTERS/GetInfiniteInstanceLogs/useGetInfiniteInstanceLogs.ts +++ b/src/Data/Managers/V2/GETTERS/GetInfiniteInstanceLogs/useGetInfiniteInstanceLogs.ts @@ -4,8 +4,7 @@ import { } from "@tanstack/react-query"; import { Pagination } from "@/Core"; import { InstanceLog } from "@/Core/Domain/HistoryLog"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; export interface LogsResponse { data: InstanceLog[]; @@ -27,7 +26,6 @@ interface GetInfiniteInstanceLogs { * * @param service {string} - the service entity * @param instanceId {string} - the instance ID for which the data needs to be fetched. - * @param environment {string} - the environment in which the instance belongs * * @returns {GetInfiniteInstanceLogs} An object containing the different available queries. * @returns {UseInfiniteQueryResult} returns.useOneTime - Fetch the logs with a single query. @@ -36,36 +34,8 @@ interface GetInfiniteInstanceLogs { export const useGetInfiniteInstanceLogs = ( service: string, instance: string, - environment: string, ): GetInfiniteInstanceLogs => { - const { createHeaders, handleErrors } = useFetchHelpers(); - - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - const fetchInstance = async ( - { pageParam }, - selectedVersion, - ): Promise => { - const initialParameters = selectedVersion - ? `limit=50&end=${Number(selectedVersion) + 1}` - : "limit=50"; - - const response = await fetch( - `${baseUrl}/lsm/v1/service_inventory/${service}/${instance}/log?${pageParam ? pageParam : initialParameters}`, - { - headers, - }, - ); - - await handleErrors(response, `Failed to fetch logs for: ${instance}`); - - return response.json(); - }; + const get = useGet(); return { useContinuous: ( @@ -73,7 +43,15 @@ export const useGetInfiniteInstanceLogs = ( ): UseInfiniteQueryResult => useInfiniteQuery({ queryKey: ["get_instance_logs-continuous", service, instance], - queryFn: (query) => fetchInstance(query, selectedVersion), + queryFn: ({ pageParam }) => { + const initialParameters = selectedVersion + ? `limit=50&end=${Number(selectedVersion) + 1}` + : "limit=50"; + + return get( + `/lsm/v1/service_inventory/${service}/${instance}/log?${pageParam ? pageParam : initialParameters}`, + ); + }, refetchInterval: 5000, select: (data) => { return data.pages.flatMap((page) => page.data); diff --git a/src/Data/Managers/V2/GETTERS/GetInstance/useGetInstance.ts b/src/Data/Managers/V2/GETTERS/GetInstance/useGetInstance.ts index 29f060338..8784855a2 100644 --- a/src/Data/Managers/V2/GETTERS/GetInstance/useGetInstance.ts +++ b/src/Data/Managers/V2/GETTERS/GetInstance/useGetInstance.ts @@ -1,7 +1,6 @@ import { UseQueryResult, useQuery } from "@tanstack/react-query"; import { ServiceInstanceModel } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; /** * Return Signature of the useGetInstance React Query @@ -16,7 +15,6 @@ interface GetInstance { * * @param service {string} - the service entity * @param instanceId {string} - the instance ID for which the data needs to be fetched. - * @param environment {string} - the environment in which the instance belongs * * @returns {GetInstance} An object containing the different available queries. * @returns {UseQueryResult} returns.useOneTime - Fetch the instance with a single query. @@ -25,45 +23,22 @@ interface GetInstance { export const useGetInstance = ( service: string, instanceId: string, - environment: string, ): GetInstance => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - const fetchInstance = async (): Promise<{ data: ServiceInstanceModel }> => { - const response = await fetch( - `${baseUrl}/lsm/v1/service_inventory/${service}/${instanceId}?include_deployment_progress=true`, - { - headers, - }, - ); - - await handleErrors( - response, - `Failed to fetch instance for id: ${instanceId}`, - ); - - return response.json(); - }; + const url = `/lsm/v1/service_inventory/${service}/${instanceId}?include_deployment_progress=true`; + const get = useGet()<{ data: ServiceInstanceModel }>; return { useOneTime: (): UseQueryResult => useQuery({ queryKey: ["get_instance-one_time", service, instanceId], - queryFn: fetchInstance, + queryFn: () => get(url), retry: false, select: (data): ServiceInstanceModel => data.data, }), useContinuous: (): UseQueryResult => useQuery({ queryKey: ["get_instance-continuous", service, instanceId], - queryFn: fetchInstance, + queryFn: () => get(url), refetchInterval: 5000, select: (data): ServiceInstanceModel => data.data, }), diff --git a/src/Data/Managers/V2/GETTERS/GetInstanceLogs/useGetInstanceLogs.ts b/src/Data/Managers/V2/GETTERS/GetInstanceLogs/useGetInstanceLogs.ts index 524d801f2..ef91d66a6 100644 --- a/src/Data/Managers/V2/GETTERS/GetInstanceLogs/useGetInstanceLogs.ts +++ b/src/Data/Managers/V2/GETTERS/GetInstanceLogs/useGetInstanceLogs.ts @@ -1,7 +1,6 @@ import { UseQueryResult, useQuery } from "@tanstack/react-query"; import { InstanceLog } from "@/Core/Domain/HistoryLog"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; /** * Return Signature of the useGetInstanceLogs React Query @@ -16,7 +15,6 @@ interface GetInstanceLogs { * * @param service {string} - the service entity * @param instanceId {string} - the instance ID for which the data needs to be fetched. - * @param environment {string} - the environment in which the instance belongs * * @returns {GetInstanceLogs} An object containing the different available queries. * @returns {UseQueryResult} returns.useOneTime - Fetch the logs with a single query. @@ -25,42 +23,22 @@ interface GetInstanceLogs { export const useGetInstanceLogs = ( service: string, instance: string, - environment: string, ): GetInstanceLogs => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - const fetchInstance = async (): Promise<{ data: InstanceLog[] }> => { - const response = await fetch( - `${baseUrl}/lsm/v1/service_inventory/${service}/${instance}/log`, - { - headers, - }, - ); - - await handleErrors(response, `Failed to fetch logs for: ${instance}`); - - return response.json(); - }; + const url = `/lsm/v1/service_inventory/${service}/${instance}/log`; + const get = useGet()<{ data: InstanceLog[] }>; return { useOneTime: (): UseQueryResult => useQuery({ queryKey: ["get_instance_logs-one_time", service, instance], - queryFn: fetchInstance, + queryFn: () => get(url), retry: false, select: (data) => data.data, }), useContinuous: (): UseQueryResult => useQuery({ queryKey: ["get_instance_logs-continuous", service, instance], - queryFn: fetchInstance, + queryFn: () => get(url), refetchInterval: 5000, select: (data) => data.data, }), diff --git a/src/Data/Managers/V2/GETTERS/GetInstanceResources/useGetInstanceResources.tsx b/src/Data/Managers/V2/GETTERS/GetInstanceResources/useGetInstanceResources.tsx index 7207bbbfd..b4ff1cfa9 100644 --- a/src/Data/Managers/V2/GETTERS/GetInstanceResources/useGetInstanceResources.tsx +++ b/src/Data/Managers/V2/GETTERS/GetInstanceResources/useGetInstanceResources.tsx @@ -1,7 +1,6 @@ import { UseQueryResult, useQuery } from "@tanstack/react-query"; import { InstanceResourceModel } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; /** * Return Signature of the useGetInstanceResources React Query @@ -16,7 +15,7 @@ interface getInstanceResources { * * @param {string} id - the service instance id * @param {string} serviceName - the service name - * @param environment {string} - the environment in which the instance belongs + * @param {string} version - the version of service instance * * @returns {getInstanceResources} An object containing the different available queries. * @returns {UseQueryResult} returns.useOneTime - Fetch the service instance resources ies as a single query. @@ -26,52 +25,21 @@ export const useGetInstanceResources = ( id: string, service_entity: string, version: string, - environment: string, ): getInstanceResources => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Fetches the all the resources for a given service instance. - * - * @returns A promise that resolves to an object containing an array of service instance resources - * @throws Will throw an error if the fetch operation fails. - */ - const fetchResources = async (): Promise<{ - data: InstanceResourceModel[]; - }> => { - const response = await fetch( - `${baseUrl}/lsm/v1/service_inventory/${service_entity}/${id}/resources?current_version=${version}`, - { - headers, - }, - ); - - await handleErrors( - response, - `Failed to fetch service instance resources for instance of id: ${id}`, - ); - - return response.json(); - }; + const url = `/lsm/v1/service_inventory/${service_entity}/${id}/resources?current_version=${version}`; + const get = useGet()<{ data: InstanceResourceModel[] }>; return { useOneTime: (): UseQueryResult => useQuery({ queryKey: ["get_instance_resources-one_time", id], - queryFn: fetchResources, + queryFn: () => get(url), retry: false, }), useContinuous: (): UseQueryResult => useQuery({ queryKey: ["get_instance_resources-continuous", id], - queryFn: fetchResources, + queryFn: () => get(url), refetchInterval: 5000, select: (data): InstanceResourceModel[] => data.data, retry: false, diff --git a/src/Data/Managers/V2/GETTERS/GetInstanceWithRelations/useGetInstanceWithRelations.test.tsx b/src/Data/Managers/V2/GETTERS/GetInstanceWithRelations/useGetInstanceWithRelations.test.tsx index e938e678d..7e4d437c4 100644 --- a/src/Data/Managers/V2/GETTERS/GetInstanceWithRelations/useGetInstanceWithRelations.test.tsx +++ b/src/Data/Managers/V2/GETTERS/GetInstanceWithRelations/useGetInstanceWithRelations.test.tsx @@ -1,9 +1,14 @@ import React from "react"; +import { MemoryRouter, useLocation } from "react-router-dom"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { renderHook, waitFor } from "@testing-library/react"; +import { StoreProvider } from "easy-peasy"; import { HttpResponse, http } from "msw"; import { setupServer } from "msw/node"; -import { ServiceInstanceModel } from "@/Core"; +import { RemoteData, ServiceInstanceModel } from "@/Core"; +import { getStoreInstance } from "@/Data/Store"; +import { dependencies } from "@/Test"; +import { DependencyProvider, EnvironmentHandlerImpl } from "@/UI"; import { childModel, testInstance, @@ -66,7 +71,11 @@ afterEach(() => server.resetHandlers()); afterAll(() => server.close()); const createWrapper = () => { - // creates a new QueryClient for each test + const environmentHandler = EnvironmentHandlerImpl( + useLocation, + dependencies.routeManager, + ); + const store = getStoreInstance(); const queryClient = new QueryClient({ defaultOptions: { queries: { @@ -74,21 +83,51 @@ const createWrapper = () => { }, }, }); + const env = { + id: "aaa", + name: "env-a", + project_id: "ppp", + repo_branch: "branch", + repo_url: "repo", + projectName: "project", + halted: false, + settings: {}, + }; + + store.dispatch.environment.setEnvironments(RemoteData.success([env])); + + store.dispatch.environment.setEnvironmentDetailsById({ + id: "aaa", + value: RemoteData.success(env), + }); return ({ children }) => ( - {children} + + + + {children} + + + ); }; test("if the fetched instance has referenced instance(s), then query will return the given instance with that related instance(s)", async () => { const { result } = renderHook( () => - useGetInstanceWithRelations( - "test_id", - "env", - false, - testService, - ).useOneTime(), + useGetInstanceWithRelations("test_id", false, testService).useOneTime(), { wrapper: createWrapper(), }, @@ -108,12 +147,7 @@ test("if the fetched instance has referenced instance(s), then query will return test("if the fetched instance has inter-service relation(s) in the model, then query will return the given instance with that related instance(s)", async () => { const { result } = renderHook( () => - useGetInstanceWithRelations( - "child_id", - "env", - false, - childModel, - ).useOneTime(), + useGetInstanceWithRelations("child_id", false, childModel).useOneTime(), { wrapper: createWrapper(), }, @@ -178,12 +212,7 @@ test("if the fetched instance has inter-service relation(s) in the model, and th ); const { result } = renderHook( () => - useGetInstanceWithRelations( - "child_id", - "env", - false, - childModel, - ).useOneTime(), + useGetInstanceWithRelations("child_id", false, childModel).useOneTime(), { wrapper: createWrapper(), }, @@ -205,7 +234,6 @@ test("when instance returned has not referenced instance(s), then the query will () => useGetInstanceWithRelations( "test_mpn_id", - "env", false, testService, ).useOneTime(), diff --git a/src/Data/Managers/V2/GETTERS/GetInstanceWithRelations/useGetInstanceWithRelations.ts b/src/Data/Managers/V2/GETTERS/GetInstanceWithRelations/useGetInstanceWithRelations.ts index dc6e5c3f2..3399cef3f 100644 --- a/src/Data/Managers/V2/GETTERS/GetInstanceWithRelations/useGetInstanceWithRelations.ts +++ b/src/Data/Managers/V2/GETTERS/GetInstanceWithRelations/useGetInstanceWithRelations.ts @@ -5,8 +5,7 @@ import { ServiceInstanceModel, ServiceModel, } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; /* * interface for the service instance with its related instances and eventual coordinates on canvas @@ -28,47 +27,18 @@ interface GetInstanceWithRelationsHook { /** * React Query hook to fetch an instance with its related instances from the API. The related instances are all instances connected with given instance by inter-service relation, both, as a parent and as a child. * @param {string} id - The ID of the instance to fetch. - * @param {string} environment - The environment in which we are looking for instances. * @param {boolean} includesReferencedBy - A flag indicating if we should fetch instances that reference our main instance - defaults to false. * @param {ServiceModel} [serviceModel] - The service Model of the instance (optional as it can be undefined at the init of the component that use the hook) * @returns {GetInstanceWithRelationsHook} An object containing a custom hook to fetch the instance with its related instances. */ export const useGetInstanceWithRelations = ( instanceId: string, - environment: string, includesReferencedBy: boolean = false, serviceModel?: ServiceModel, ): GetInstanceWithRelationsHook => { - //extracted headers to avoid breaking rules of Hooks - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Fetches a service instance - * @param {string} id - The ID of the instance to fetch. - * @returns {Promise<{data: ServiceInstanceModel}>} An object containing the fetched instance. - * @throws Error if the instance fails to fetch. - */ - const fetchSingleInstance = async ( - id: string, - ): Promise<{ data: ServiceInstanceModel }> => { - //we use this endpoint instead /lsm/v1/service_inventory/{service_entity}/{service_id} because referenced_by property includes only ids, without information about service_entity for given ids - const response = await fetch( - `${baseUrl}/lsm/v1/service_inventory?service_id=${id}&include_deployment_progress=false&exclude_read_only_attributes=false&include_referenced_by=${includesReferencedBy}&include_metadata=true`, - { - headers, - }, - ); - - await handleErrors(response, "Failed to fetch instance with id: " + id); - - return await response.json(); - }; + const getUrl = (id: string) => + `/lsm/v1/service_inventory?service_id=${id}&include_deployment_progress=false&exclude_read_only_attributes=false&include_referenced_by=${includesReferencedBy}&include_metadata=true`; + const get = useGet()<{ data: ServiceInstanceModel }>; /** * This function is responsible for extracting the names of all inter-service relations from the provided service model or embedded entity. @@ -171,7 +141,7 @@ export const useGetInstanceWithRelations = ( id: string, ): Promise => { const interServiceRelations: ServiceInstanceModel[] = []; - const { data: instance } = await fetchSingleInstance(id); + const { data: instance } = await get(getUrl(id)); let serviceIds: string[] = []; if (serviceModel) { @@ -194,7 +164,7 @@ export const useGetInstanceWithRelations = ( await Promise.all( allIds.map(async (relatedId) => { - const interServiceRelation = await fetchSingleInstance(relatedId); + const interServiceRelation = await get(getUrl(relatedId)); if (interServiceRelation) { interServiceRelations.push(interServiceRelation.data); @@ -217,11 +187,7 @@ export const useGetInstanceWithRelations = ( */ useOneTime: (): UseQueryResult => useQuery({ - queryKey: [ - "get_instance_with_relations-one_time", - instanceId, - environment, - ], + queryKey: ["get_instance_with_relations-one_time", instanceId], queryFn: () => fetchInstanceWithRelations(instanceId), retry: false, enabled: serviceModel !== undefined, @@ -229,11 +195,7 @@ export const useGetInstanceWithRelations = ( }), useContinuous: (): UseQueryResult => useQuery({ - queryKey: [ - "get_instance_with_relations-continuous", - instanceId, - environment, - ], + queryKey: ["get_instance_with_relations-continuous", instanceId], queryFn: () => fetchInstanceWithRelations(instanceId), retry: false, refetchInterval: 5000, diff --git a/src/Data/Managers/V2/GETTERS/GetInventoryList/useGetInventoryList.ts b/src/Data/Managers/V2/GETTERS/GetInventoryList/useGetInventoryList.ts index 1a6a10793..25a8af93c 100644 --- a/src/Data/Managers/V2/GETTERS/GetInventoryList/useGetInventoryList.ts +++ b/src/Data/Managers/V2/GETTERS/GetInventoryList/useGetInventoryList.ts @@ -1,7 +1,6 @@ import { UseQueryResult, useQuery } from "@tanstack/react-query"; import { ServiceInstanceModel } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; /** * Inventories interface @@ -24,7 +23,6 @@ interface GetInventoryList { * React Query hook to fetch the service inventory of each service in the list of service names. * * @param {string[]} serviceNames - the array of service names - * @param environment {string} - the environment in which the instance belongs * * @returns {GetInventoryList} An object containing the different available queries. * @returns {UseQueryResult} returns.useOneTime - Fetch the service inventories as a single query. @@ -32,41 +30,8 @@ interface GetInventoryList { */ export const useGetInventoryList = ( serviceNames: string[], - environment: string, ): GetInventoryList => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Fetches the inventory for a single service. - * - * @param service - The name of the service to fetch the inventory for. - * @returns A promise that resolves to an object containing an array of service instance models. - * @throws Will throw an error if the fetch operation fails. - */ - const fetchSingleService = async ( - service: string, - ): Promise<{ data: ServiceInstanceModel[] }> => { - const response = await fetch( - `${baseUrl}/lsm/v1/service_inventory/${service}?limit=1000`, - { - headers, - }, - ); - - await handleErrors( - response, - `Failed to fetch service inventory for name: ${service}`, - ); - - return response.json(); - }; + const get = useGet()<{ data: ServiceInstanceModel[] }>; /** * Fetches the inventory for all services. @@ -76,7 +41,9 @@ export const useGetInventoryList = ( */ const fetchAllServices = async (): Promise => { const responses = await Promise.all( - serviceNames.map(async (serviceName) => fetchSingleService(serviceName)), + serviceNames.map(async (serviceName) => + get(`/lsm/v1/service_inventory/${serviceName}?limit=1000`), + ), ); // Map the responses to an object of service names and arrays of service instances for each service diff --git a/src/Data/Managers/V2/GETTERS/GetJSONSchema/GetJSONSchema.ts b/src/Data/Managers/V2/GETTERS/GetJSONSchema/GetJSONSchema.ts index 6aee872d6..2137f2271 100644 --- a/src/Data/Managers/V2/GETTERS/GetJSONSchema/GetJSONSchema.ts +++ b/src/Data/Managers/V2/GETTERS/GetJSONSchema/GetJSONSchema.ts @@ -1,11 +1,10 @@ import { UseQueryResult, useQuery } from "@tanstack/react-query"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; /** * Return Signature of the useGetJSONSchema React Query */ -interface GetJSONShema { +interface GetJSONSchema { useOneTime: () => UseQueryResult; } @@ -13,47 +12,18 @@ interface GetJSONShema { * React Query hook to fetch JSON Schema for a service_entity. * * @param {string} service_id - The service entity. - * @param {string} environment - The environment. * * @returns {GetJSONShema} The result of the query. * @returns {UseQueryResult} returns.useOneTime - Fetch the JSON Schema with a single query. */ -export const useGetJSONSchema = ( - service_id: string, - environment: string, -): GetJSONShema => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - // [GET] /lsm/v1/service_catalog//schema - const fetchJSONSchema = async (): Promise<{ - data: unknown; - }> => { - const response = await fetch( - `${baseUrl}/lsm/v1/service_catalog/${service_id}/schema`, - { - headers, - }, - ); - - await handleErrors( - response, - `Failed to fetch JSON Schema for: ${service_id}`, - ); - - return response.json(); - }; +export const useGetJSONSchema = (service_id: string): GetJSONSchema => { + const get = useGet()<{ data: unknown }>; return { useOneTime: () => useQuery({ - queryKey: ["get_JSON_schema-one_time", service_id, environment], - queryFn: fetchJSONSchema, + queryKey: ["get_JSON_schema-one_time", service_id], + queryFn: () => get(`/lsm/v1/service_catalog/${service_id}/schema`), retry: false, select: (data) => data.data, }), diff --git a/src/Data/Managers/V2/GETTERS/GetMetadata/useGetMetadata.ts b/src/Data/Managers/V2/GETTERS/GetMetadata/useGetMetadata.ts index 65efc1d7e..66fd58614 100644 --- a/src/Data/Managers/V2/GETTERS/GetMetadata/useGetMetadata.ts +++ b/src/Data/Managers/V2/GETTERS/GetMetadata/useGetMetadata.ts @@ -1,7 +1,6 @@ import { UseQueryResult, useQuery } from "@tanstack/react-query"; import { ParsedNumber } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; /** * Interface containing the metadata. @@ -19,7 +18,6 @@ interface GetMetadataHook { /** * React Query hook to fetch metadata for a specific service instance and key. - * @param {string} environment - The environment of the service. * @param {string} service_entity - The entity name of the service. * @param {string} service_id - The ID of the service. * @param {string} key - The key for the metadata. @@ -27,48 +25,25 @@ interface GetMetadataHook { * @returns {GetMetadataHook} An object containing the custom hook. */ export const useGetMetadata = ( - environment: string, service_entity: string, service_id: string, key: string, instanceVersion?: ParsedNumber | null, ): GetMetadataHook => { - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - const getMetadata = async (): Promise => { - const response = await fetch( - baseUrl + - `/lsm/v1/service_inventory/${service_entity}/${service_id}/metadata/${key}?current_version=${instanceVersion}`, - { - headers, - }, - ); - - await handleErrors(response); - - return response.json(); - }; + const get = useGet(); return { - /** - * Single time query hook to fetch the metadata. - * @returns {GetMetadataHook} The result of the query. - */ useOneTime: () => useQuery({ - queryFn: getMetadata, + queryFn: () => + get( + `/lsm/v1/service_inventory/${service_entity}/${service_id}/metadata/${key}?current_version=${instanceVersion}`, + ), queryKey: [ "get_metadata", service_entity, service_id, key, - environment, instanceVersion, ], retry: false, diff --git a/src/Data/Managers/V2/GETTERS/GetServiceConfig/useGetServiceConfig.ts b/src/Data/Managers/V2/GETTERS/GetServiceConfig/useGetServiceConfig.ts index 745242f95..fddd59d06 100644 --- a/src/Data/Managers/V2/GETTERS/GetServiceConfig/useGetServiceConfig.ts +++ b/src/Data/Managers/V2/GETTERS/GetServiceConfig/useGetServiceConfig.ts @@ -1,7 +1,6 @@ import { UseQueryResult, useQuery } from "@tanstack/react-query"; import { Config } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; /** * Return Signature of the useGetServiceConfig React Query @@ -14,45 +13,18 @@ interface GetServiceConfig { * React Query hook to fetch the service config * * @param service {string} - the service entity - * @param environment {string} - the environment in which the instance belongs * * @returns {GetServiceConfig} An object containing the different available queries. * @returns {UseQueryResult} returns.useOneTime - Fetch the service config with a single query. */ -export const useGetServiceConfig = ( - service: string, - environment: string, -): GetServiceConfig => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - const fetchInstance = async (): Promise<{ data: Config }> => { - const response = await fetch( - `${baseUrl}/lsm/v1/service_catalog/${service}/config`, - { - headers, - }, - ); - - await handleErrors( - response, - `Failed to fetch Service Config for: ${service}`, - ); - - return response.json(); - }; +export const useGetServiceConfig = (service: string): GetServiceConfig => { + const get = useGet()<{ data: Config }>; return { useOneTime: (): UseQueryResult => useQuery({ queryKey: ["get_service_config-one_time", service], - queryFn: fetchInstance, + queryFn: () => get(`/lsm/v1/service_catalog/${service}/config`), retry: false, select: (data) => data.data, }), diff --git a/src/Data/Managers/V2/GETTERS/GetServiceModel/useGetServiceModel.ts b/src/Data/Managers/V2/GETTERS/GetServiceModel/useGetServiceModel.ts index f0dc8461c..0743bc56c 100644 --- a/src/Data/Managers/V2/GETTERS/GetServiceModel/useGetServiceModel.ts +++ b/src/Data/Managers/V2/GETTERS/GetServiceModel/useGetServiceModel.ts @@ -1,7 +1,6 @@ import { UseQueryResult, useQuery } from "@tanstack/react-query"; import { ServiceModel } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; /** * Return Signature of the useGetServiceModel React Query @@ -15,53 +14,28 @@ interface GetServiceModel { * React Query hook to fetch the service model * * @param service {string} - the service entity - * @param environment {string} - the environment in which the instance belongs * * @returns {GetServiceModel} An object containing the different available queries. * @returns {UseQueryResult} returns.useOneTime - Fetch the service model with a single query. * @returns {UseQueryResult} returns.useContinuous - Fetch the service model with a recursive query with an interval of 5s. */ -export const useGetServiceModel = ( - service: string, - environment: string, -): GetServiceModel => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - const fetchInstance = async (): Promise<{ data: ServiceModel }> => { - const response = await fetch( - `${baseUrl}/lsm/v1/service_catalog/${service}?instance_summary=True`, - { - headers, - }, - ); - - await handleErrors( - response, - `Failed to fetch Service Model for: ${service}`, - ); - - return response.json(); - }; +export const useGetServiceModel = (service: string): GetServiceModel => { + const get = useGet()<{ data: ServiceModel }>; return { useOneTime: (): UseQueryResult => useQuery({ queryKey: ["get_service_model-one_time", service], - queryFn: fetchInstance, + queryFn: () => + get(`/lsm/v1/service_catalog/${service}?instance_summary=True`), retry: false, select: (data) => data.data, }), useContinuous: (): UseQueryResult => useQuery({ queryKey: ["get_service_model-continuous", service], - queryFn: fetchInstance, + queryFn: () => + get(`/lsm/v1/service_catalog/${service}?instance_summary=True`), refetchInterval: 5000, select: (data) => data.data, }), diff --git a/src/Data/Managers/V2/GETTERS/GetServiceModels/useGetServiceModels.ts b/src/Data/Managers/V2/GETTERS/GetServiceModels/useGetServiceModels.ts index b6ddcb7b5..2c0e7bbcf 100644 --- a/src/Data/Managers/V2/GETTERS/GetServiceModels/useGetServiceModels.ts +++ b/src/Data/Managers/V2/GETTERS/GetServiceModels/useGetServiceModels.ts @@ -1,7 +1,6 @@ import { UseQueryResult, useQuery } from "@tanstack/react-query"; import { ServiceModel } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { useGet } from "../../helpers/useQueries"; /** * Return Signature of the useGetServiceModel React Query @@ -20,41 +19,21 @@ interface GetServiceModels { * @returns {UseQueryResult} returns.useOneTime - Fetch the service models with a single query. * @returns {UseQueryResult} returns.useContinuous - Fetch the service models with an interval of 5s. */ -export const useGetServiceModels = (environment: string): GetServiceModels => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - const fetchServices = async (): Promise<{ data: ServiceModel[] }> => { - const response = await fetch( - `${baseUrl}/lsm/v1/service_catalog?instance_summary=True`, - { - headers, - }, - ); - - await handleErrors(response, `Failed to fetch Service Models`); - - return response.json(); - }; +export const useGetServiceModels = (): GetServiceModels => { + const get = useGet()<{ data: ServiceModel[] }>; return { useOneTime: (): UseQueryResult => useQuery({ queryKey: ["get_service_models-one_time"], - queryFn: fetchServices, + queryFn: () => get("/lsm/v1/service_catalog?instance_summary=True"), retry: false, select: (data) => data.data, }), useContinuous: (): UseQueryResult => useQuery({ queryKey: ["get_service_models-continuous"], - queryFn: fetchServices, + queryFn: () => get("/lsm/v1/service_catalog?instance_summary=True"), refetchInterval: 5000, select: (data) => data.data, }), diff --git a/src/Data/Managers/V2/PATCH/PatchAttributesExpert/usePatchAttributesExpert.ts b/src/Data/Managers/V2/PATCH/PatchAttributesExpert/usePatchAttributesExpert.ts index 8463bdaf3..5d3284043 100644 --- a/src/Data/Managers/V2/PATCH/PatchAttributesExpert/usePatchAttributesExpert.ts +++ b/src/Data/Managers/V2/PATCH/PatchAttributesExpert/usePatchAttributesExpert.ts @@ -1,8 +1,6 @@ import { UseMutationResult, useMutation } from "@tanstack/react-query"; import { ParsedNumber } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; - -import { useFetchHelpers } from "../../helpers"; +import { usePatch } from "../../helpers/useQueries"; /** * Required attributes to construct the patch request to edit an instance attribute set in Expert mode @@ -28,49 +26,22 @@ interface PatchEdit { /** * React Query to Patch the attributes of a certain set, for an instance, in expert mode. * - * @param {string} environment - The Environment where the instance is located * @param {string} instance_id - the UUID of the instance * @param {string } service_entity - The service entity type of the instance * @returns {UseMutationResult} The useMutation ReactQuery Hook */ export const usePatchAttributesExpert = ( - environment: string, instance_id: string, service_entity: string, ): UseMutationResult => { - const { createHeaders, handleErrors } = useFetchHelpers(); - - const headers = createHeaders(environment); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Expert Edit an instance. - * - * @returns {Promise} - A promise that resolves when the instance is succesfully edited in Expert mode. - */ - const patchAttributesExpert = async ( - data: ExpertPatchAttributes, - ): Promise => { - const response = await fetch( - baseUrl + - `/lsm/v2/service_inventory/${service_entity}/${instance_id}/expert`, - { - method: "PATCH", - body: JSON.stringify(data), - headers, - }, - ); - - await handleErrors(response); - }; + const patch = usePatch(); return useMutation({ - mutationFn: patchAttributesExpert, + mutationFn: (data) => + patch( + `/lsm/v2/service_inventory/${service_entity}/${instance_id}/expert`, + data, + ), mutationKey: ["patch_expert_edit"], }); }; diff --git a/src/Data/Managers/V2/POST/AddUser/useAddUser.ts b/src/Data/Managers/V2/POST/AddUser/useAddUser.ts index 2f5de0271..480be31ac 100644 --- a/src/Data/Managers/V2/POST/AddUser/useAddUser.ts +++ b/src/Data/Managers/V2/POST/AddUser/useAddUser.ts @@ -1,6 +1,17 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { usePost } from "../../helpers/useQueries"; + +interface AddUSerResponse { + data: { + username: "string"; + auth_method: "database"; + }; +} + +interface AddUserBody { + username: string; + password: string; +} /** * React Query hook for adding a user. @@ -8,43 +19,10 @@ import { useFetchHelpers } from "../../helpers"; */ export const useAddUser = () => { const client = useQueryClient(); - const { createHeaders, handleErrors } = useFetchHelpers(); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Function for making a POST request to add a user. - * @param {Object} orderBody - The body of the POST request. - * @param {string} orderBody.username - The username of the user. - * @param {string} orderBody.password - The password of the user. - * @returns {Promise} The response object containing the added user's information. - * @throws {Error} If the response is not successful, an error is thrown with the error message. - */ - const postOrder = async (orderBody: { - username: string; - password: string; - }): Promise<{ - data: { - username: string; - auth_method: string; - }; - }> => { - const response = await fetch(baseUrl + `/api/v2/user`, { - method: "POST", - body: JSON.stringify(orderBody), - headers: createHeaders(), - }); - - await handleErrors(response); - - return response.json(); - }; + const post = usePost(); return useMutation({ - mutationFn: postOrder, + mutationFn: (body: AddUserBody) => post(`/api/v2/user`, body), mutationKey: ["add_user"], onSuccess: () => { //refetch the users query to update the list diff --git a/src/Data/Managers/V2/POST/Login/useLogin.ts b/src/Data/Managers/V2/POST/Login/useLogin.ts index 29f57f167..ec8d0db77 100644 --- a/src/Data/Managers/V2/POST/Login/useLogin.ts +++ b/src/Data/Managers/V2/POST/Login/useLogin.ts @@ -1,6 +1,20 @@ import { useMutation } from "@tanstack/react-query"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { usePostWithoutEnv } from "../../helpers/useQueries"; + +interface LoginResponse { + data: { + token: string; + user: { + username: string; + auth_method: string; + }; + }; +} + +interface LoginBody { + username: string; + password: string; +} /** * Custom hook for performing user login mutation for database authentication - for keycloak head to keycloak.js library. @@ -8,45 +22,10 @@ import { useFetchHelpers } from "../../helpers"; * @returns A tuple containing the mutation function and mutation state. */ export const useLogin = () => { - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - const { handleErrors } = useFetchHelpers(); - - /** - * Asynchronously posts login credentials to the server and retrieves the response. - * @param {Object} orderBody - Object containing username and password. - * @param {string} orderBody.username - User's username. - * @param {string} orderBody.password - User's password. - * @returns {Promise} A promise resolving to an object containing token and user information. - * @throws {Error} If the response from the server is not successful, an error is thrown with the error message. - */ - const postOrder = async (orderBody: { - username: string; - password: string; - }): Promise<{ - data: { - token: string; - user: { - username: string; - auth_method: string; - }; - }; - }> => { - const response = await fetch(baseUrl + "/api/v2/login", { - method: "POST", - body: JSON.stringify(orderBody), - headers: { - "Content-Type": "application/json", - }, - }); - - await handleErrors(response); - - return response.json(); - }; + const post = usePostWithoutEnv(); - return useMutation({ mutationFn: postOrder, mutationKey: ["login"] }); + return useMutation({ + mutationFn: (body: LoginBody) => post("/api/v2/login", body), + mutationKey: ["login"], + }); }; diff --git a/src/Data/Managers/V2/POST/PostExpertStateTransfer/usePostExpertStateTransfer.ts b/src/Data/Managers/V2/POST/PostExpertStateTransfer/usePostExpertStateTransfer.ts index f77ba9a78..6668efe8f 100644 --- a/src/Data/Managers/V2/POST/PostExpertStateTransfer/usePostExpertStateTransfer.ts +++ b/src/Data/Managers/V2/POST/PostExpertStateTransfer/usePostExpertStateTransfer.ts @@ -1,8 +1,6 @@ import { UseMutationResult, useMutation } from "@tanstack/react-query"; import { ParsedNumber } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; - -import { useFetchHelpers } from "../../helpers"; +import { usePost } from "../../helpers/useQueries"; /** * Required attributes to construct the post request to force update the state of an instance in Expert mode @@ -17,49 +15,22 @@ export interface PostExpertStateTransfer { /** * React Query to Force update the state of an instance in expert mode. * - * @param {string} environment - The Environment where the instance is located * @param {string} instance_id - the UUID of the instance * @param {string } service_entity - The service entity type of the instance * @returns {UseMutationResult} The useMutation ReactQuery Hook */ export const usePostExpertStateTransfer = ( - environment: string, instance_id: string, service_entity: string, ): UseMutationResult => { - const { createHeaders, handleErrors } = useFetchHelpers(); - - const headers = createHeaders(environment); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Expert Post state request - * - * @returns {Promise} - A promise that resolves when the state is updated in Expert mode. - */ - const postStateTransferExpert = async ( - data: PostExpertStateTransfer, - ): Promise => { - const response = await fetch( - baseUrl + - `/lsm/v1/service_inventory/${service_entity}/${instance_id}/expert/state`, - { - method: "POST", - body: JSON.stringify(data), - headers, - }, - ); - - await handleErrors(response); - }; + const deleteRequest = usePost(); return useMutation({ - mutationFn: postStateTransferExpert, + mutationFn: (data) => + deleteRequest( + `/lsm/v1/service_inventory/${service_entity}/${instance_id}/expert/state`, + data, + ), mutationKey: ["post_state_transfer_expert"], }); }; diff --git a/src/Data/Managers/V2/POST/PostMetadata/usePostMetadata.ts b/src/Data/Managers/V2/POST/PostMetadata/usePostMetadata.ts index fed5cb6b1..b2450e078 100644 --- a/src/Data/Managers/V2/POST/PostMetadata/usePostMetadata.ts +++ b/src/Data/Managers/V2/POST/PostMetadata/usePostMetadata.ts @@ -1,7 +1,6 @@ import { UseMutationResult, useMutation } from "@tanstack/react-query"; import { ParsedNumber } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { usePost } from "../../helpers/useQueries"; export interface PostMetadataInfo { service_entity: string; @@ -16,42 +15,22 @@ export interface PostMetadataInfo { /** * React Query hook for posting metadata. * - * @param {string} environment - The environment to use for creating headers. * @returns {UseMutationResult}- The mutation object from `useMutation` hook. */ -export const usePostMetadata = ( - environment: string, -): UseMutationResult => { - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Posts metadata. - * - * @param info {PostMetadataInfo} - The metadata information to post. - */ - const postMetadata = async (info: PostMetadataInfo): Promise => { - const { service_entity, service_id, key, body } = info; - const response = await fetch( - baseUrl + - `/lsm/v1/service_inventory/${service_entity}/${service_id}/metadata/${key}`, - { - method: "POST", - body: JSON.stringify(body), - headers, - }, - ); - - await handleErrors(response); - }; +export const usePostMetadata = (): UseMutationResult< + void, + Error, + PostMetadataInfo, + unknown +> => { + const post = usePost(); return useMutation({ - mutationFn: postMetadata, + mutationFn: (info) => + post( + `/lsm/v1/service_inventory/${info.service_entity}/${info.service_id}/metadata/${info.key}`, + info, + ), mutationKey: ["post_metadata"], }); }; diff --git a/src/Data/Managers/V2/POST/PostOrder/usePostOrder.ts b/src/Data/Managers/V2/POST/PostOrder/usePostOrder.ts index 5fae08fcb..62842d420 100644 --- a/src/Data/Managers/V2/POST/PostOrder/usePostOrder.ts +++ b/src/Data/Managers/V2/POST/PostOrder/usePostOrder.ts @@ -1,46 +1,31 @@ import { UseMutationResult, useMutation } from "@tanstack/react-query"; -import { PrimaryBaseUrlManager, words } from "@/UI"; +import { words } from "@/UI"; import { ComposerServiceOrderItem } from "@/UI/Components/Diagram/interfaces"; +import { usePost } from "../../helpers/useQueries"; -import { useFetchHelpers } from "../../helpers"; +interface PostOrderBody { + service_order_items: ComposerServiceOrderItem[]; + description: string; +} /** * React Query hook for sending an order batch from Instance Composer. * @returns {Mutation} The mutation object for sending an order. */ -export const usePostOrder = ( - environment: string, -): UseMutationResult => { - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); +export const usePostOrder = (): UseMutationResult< + void, + Error, + ComposerServiceOrderItem[], + unknown +> => { + const post = usePost(); - /** - * Sends an order with the provided bundle instances. - * @param {ComposerServiceOrderItem[]} serviceOrderItems - The bundled instances to include in the order. - * @throws {Error} If the response is not successful, an error with the error message is thrown. - */ - const postOrder = async ( - serviceOrderItems: ComposerServiceOrderItem[], - ): Promise => { - const response = await fetch(baseUrl + `/lsm/v2/order`, { - method: "POST", - body: JSON.stringify({ - service_order_items: serviceOrderItems, + return useMutation({ + mutationFn: (service_order_items) => + post(`/lsm/v2/order`, { + service_order_items, description: words("instanceComposer.orderDescription"), }), - headers, - }); - - await handleErrors(response); - }; - - return useMutation({ - mutationFn: postOrder, mutationKey: ["post_order"], }); }; diff --git a/src/Data/Managers/V2/POST/PostStateTransfer/usePostStateTransfer.ts b/src/Data/Managers/V2/POST/PostStateTransfer/usePostStateTransfer.ts index 63130ac2b..977e3d915 100644 --- a/src/Data/Managers/V2/POST/PostStateTransfer/usePostStateTransfer.ts +++ b/src/Data/Managers/V2/POST/PostStateTransfer/usePostStateTransfer.ts @@ -1,8 +1,6 @@ import { UseMutationResult, useMutation } from "@tanstack/react-query"; import { ParsedNumber } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; - -import { useFetchHelpers } from "../../helpers"; +import { usePost } from "../../helpers/useQueries"; export interface PostStateTransfer { message: string; @@ -13,47 +11,22 @@ export interface PostStateTransfer { /** * React Query to update the state of an instance. * - * @param {string} environment - The Environment where the instance is located * @param {string} instance_id - the UUID of the instance * @param {string } service_entity - The service entity type of the instance * @returns {UseMutationResult} The useMutation ReactQuery Hook */ export const usePostStateTransfer = ( - environment: string, instance_id: string, service_entity: string, ): UseMutationResult => { - const { createHeaders, handleErrors } = useFetchHelpers(); - - const headers = createHeaders(environment); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Post state request - * - * @returns {Promise} - A promise that resolves when the state is updated. - */ - const postStateTransfer = async (data: PostStateTransfer): Promise => { - const response = await fetch( - baseUrl + - `/lsm/v1/service_inventory/${service_entity}/${instance_id}/state`, - { - method: "POST", - body: JSON.stringify(data), - headers, - }, - ); - - await handleErrors(response); - }; + const post = usePost(); return useMutation({ - mutationFn: postStateTransfer, + mutationFn: (body) => + post( + `/lsm/v1/service_inventory/${service_entity}/${instance_id}/state`, + body, + ), mutationKey: ["post_state_transfer"], }); }; diff --git a/src/Data/Managers/V2/POST/PromoteDesiredStateVersion/usePromoteDesiredStateVersion.ts b/src/Data/Managers/V2/POST/PromoteDesiredStateVersion/usePromoteDesiredStateVersion.ts index 171699335..1ac15aae3 100644 --- a/src/Data/Managers/V2/POST/PromoteDesiredStateVersion/usePromoteDesiredStateVersion.ts +++ b/src/Data/Managers/V2/POST/PromoteDesiredStateVersion/usePromoteDesiredStateVersion.ts @@ -3,47 +3,24 @@ import { useMutation, useQueryClient, } from "@tanstack/react-query"; -import { PrimaryBaseUrlManager } from "@/UI"; - -import { useFetchHelpers } from "../../helpers"; +import { usePost } from "../../helpers/useQueries"; /** * React Query hook for promoting a version of desired state * - * @param {string} env - The environment in which we are trying to promote the version. * @returns {Mutation} The mutation object for sending the request. */ -export const usePromoteDesiredStateVersion = ( - environment: string, -): UseMutationResult => { +export const usePromoteDesiredStateVersion = (): UseMutationResult< + void, + Error, + string, + unknown +> => { const client = useQueryClient(); - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Sends a request to promote a version of desired state - * @param {string} version - the stringified version of desired state. - * @throws {Error} If the response is not successful, an error with the error message is thrown. - */ - const promoteDesiredStateVersion = async (version: string): Promise => { - const response = await fetch( - baseUrl + `/api/v2/desiredstate/${version}/promote`, - { - method: "POST", - headers, - }, - ); - - await handleErrors(response); - }; + const post = usePost(); return useMutation({ - mutationFn: promoteDesiredStateVersion, + mutationFn: (version) => post(`/api/v2/desiredstate/${version}/promote`), mutationKey: ["promote_version"], onSuccess: () => { // Refetch the desired state queries to update the list diff --git a/src/Data/Managers/V2/POST/UpdateCatalog/useUpdateCatalog.ts b/src/Data/Managers/V2/POST/UpdateCatalog/useUpdateCatalog.ts index fcc0d7402..dbb159083 100644 --- a/src/Data/Managers/V2/POST/UpdateCatalog/useUpdateCatalog.ts +++ b/src/Data/Managers/V2/POST/UpdateCatalog/useUpdateCatalog.ts @@ -3,47 +3,24 @@ import { useMutation, useQueryClient, } from "@tanstack/react-query"; -import { PrimaryBaseUrlManager } from "@/UI"; -import { useFetchHelpers } from "../../helpers"; +import { usePost } from "../../helpers/useQueries"; /** * React Query hook for updating environment catalog. * - * @param {string} environment - The environment to use for creating headers. * @returns {UseMutationResult}- The mutation object from `useMutation` hook. */ -export const useUpdateCatalog = ( - environment: string, -): UseMutationResult => { +export const useUpdateCatalog = (): UseMutationResult< + void, + Error, + void, + unknown +> => { const client = useQueryClient(); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Update the environment catalog. - * - * @returns {Promise} - The promise object of the fetch request. - * @throws {Error} If the response is not successful, an error with the error message is thrown. - */ - const updateCatalog = async (): Promise => { - const response = await fetch( - baseUrl + `/lsm/v1/exporter/export_service_definition`, - { - method: "POST", - headers, - }, - ); - - await handleErrors(response); - }; + const post = usePost(); return useMutation({ - mutationFn: updateCatalog, + mutationFn: () => post(`/lsm/v1/exporter/export_service_definition`), mutationKey: ["update_catalog"], onSuccess: () => { client.invalidateQueries({ queryKey: ["get_service_models-one_time"] }); diff --git a/src/Data/Managers/V2/POST/UpdateEnvConfig/useUpdateEnvConfig.ts b/src/Data/Managers/V2/POST/UpdateEnvConfig/useUpdateEnvConfig.ts index 035eba88f..ff59a7967 100644 --- a/src/Data/Managers/V2/POST/UpdateEnvConfig/useUpdateEnvConfig.ts +++ b/src/Data/Managers/V2/POST/UpdateEnvConfig/useUpdateEnvConfig.ts @@ -4,9 +4,8 @@ import { useQueryClient, } from "@tanstack/react-query"; import { ParsedNumber } from "@/Core"; -import { PrimaryBaseUrlManager } from "@/UI"; import { Dict } from "@/UI/Components"; -import { useFetchHelpers } from "../../helpers"; +import { usePost } from "../../helpers/useQueries"; interface ConfigUpdate { id: string; @@ -16,47 +15,21 @@ interface ConfigUpdate { /** * React Query hook for updating environment configuration settings. * - * @param {string} environment - The environment to use for creating headers. * @returns {UseMutationResult}- The mutation object from `useMutation` hook. */ -export const useUpdateEnvConfig = ( - environment: string, -): UseMutationResult => { +export const useUpdateEnvConfig = (): UseMutationResult< + void, + Error, + ConfigUpdate, + unknown +> => { const client = useQueryClient(); - const baseUrlManager = new PrimaryBaseUrlManager( - globalThis.location.origin, - globalThis.location.pathname, - ); - const { createHeaders, handleErrors } = useFetchHelpers(); - const headers = createHeaders(environment); - const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); - - /** - * Update the environment configuration setting. - * - * @param {ConfigUpdate} configUpdate - The info about the config setting to update - * - * @returns {Promise} - The promise object of the fetch request. - * @throws {Error} If the response is not successful, an error with the error message is thrown. - */ - const updateConfig = async (configUpdate: ConfigUpdate): Promise => { - const { id, value } = configUpdate; - - const response = await fetch( - baseUrl + `/api/v2/environment_settings/${id}`, - { - method: "POST", - body: JSON.stringify({ value }), - headers, - }, - ); - - await handleErrors(response); - }; + const post = usePost(); return useMutation({ - mutationFn: updateConfig, + mutationFn: ({ id, value }) => + post(`/api/v2/environment_settings/${id}`, value), mutationKey: ["update_env_config"], onSuccess: () => { client.invalidateQueries({ diff --git a/src/Data/Managers/V2/helpers/useFetchHelpers.test.tsx b/src/Data/Managers/V2/helpers/useFetchHelpers.test.tsx index 2f6a3cd28..0295ec101 100644 --- a/src/Data/Managers/V2/helpers/useFetchHelpers.test.tsx +++ b/src/Data/Managers/V2/helpers/useFetchHelpers.test.tsx @@ -28,13 +28,29 @@ describe("createHeaders", () => { const env = "1234abcd"; const wrapper = setup(); - const { result } = renderHook(() => useFetchHelpers().createHeaders(env), { - wrapper, - }); + const { result } = renderHook( + () => useFetchHelpers().createHeaders({ env }), + { + wrapper, + }, + ); expect(result.current.get("X-Inmanta-Tid")).toEqual(env); }); + it("should return headers with message when message is defined", () => { + const wrapper = setup(); + + const { result } = renderHook( + () => useFetchHelpers().createHeaders({ message: "test-message" }), + { + wrapper, + }, + ); + + expect(result.current.get("message")).toEqual("test-message"); + }); + it("should return headers without environment when env is undefined", () => { const wrapper = setup(); diff --git a/src/Data/Managers/V2/helpers/useFetchHelpers.ts b/src/Data/Managers/V2/helpers/useFetchHelpers.ts index 6dbd7221b..5b2aab68e 100644 --- a/src/Data/Managers/V2/helpers/useFetchHelpers.ts +++ b/src/Data/Managers/V2/helpers/useFetchHelpers.ts @@ -34,7 +34,8 @@ export const useFetchHelpers = () => { * @param env - The environment identifier. * @returns The headers object. */ - function createHeaders(env?: string) { + function createHeaders(options?: { env?: string; message?: string }) { + const { env, message } = options || {}; const headers = new Headers({ "Content-Type": "application/json" }); if (env) { @@ -45,6 +46,10 @@ export const useFetchHelpers = () => { headers.append("Authorization", `Bearer ${authHelper.getToken()}`); } + if (message) { + headers.append("message", message); + } + return headers; } diff --git a/src/Data/Managers/V2/helpers/useQueries.ts b/src/Data/Managers/V2/helpers/useQueries.ts new file mode 100644 index 000000000..21f172b6c --- /dev/null +++ b/src/Data/Managers/V2/helpers/useQueries.ts @@ -0,0 +1,356 @@ +import { useContext } from "react"; +import { DependencyContext, PrimaryBaseUrlManager } from "@/UI"; +import { useFetchHelpers } from "../helpers"; + +/** + * Custom hook to perform a GET request. + * + * This hook constructs the base URL and headers, and provides a function to perform a GET request to the specified path. + * + * @returns {Function} A function that performs a GET request and returns the response data. + * + * @template ResponseData - The type of the response data. + */ +export const useGet = (options?: { + message?: string; +}): ((path: string) => Promise) => { + const baseUrlManager = new PrimaryBaseUrlManager( + globalThis.location.origin, + globalThis.location.pathname, + ); + const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); + const { environmentHandler } = useContext(DependencyContext); + const env = environmentHandler.useId(); + const { createHeaders, handleErrors } = useFetchHelpers(); + const headers = createHeaders({ env, message: options?.message }); + + return async (path: string): Promise => { + try { + const response = await fetch(`${baseUrl}${path}`, { + headers, + }); + + await handleErrors(response); + + return response.json(); + } catch (error) { + console.error("Error fetching data:", error); + throw error; + } + }; +}; + +/** + * Custom hook to perform a GET request. + * + * This hook constructs the base URL and headers, and provides a function to perform a GET request to the specified path. + * In comparison to useGet, this hook does not use the environment context, so it can be used only to perform requests that are environment-agnostic. + * + * @returns {Function} A function that performs a GET request and returns the response data. + * + * @template ResponseData - The type of the response data. + */ +export const useGetWithoutEnv = (options?: { + message?: string; +}): ((path: string) => Promise) => { + const baseUrlManager = new PrimaryBaseUrlManager( + globalThis.location.origin, + globalThis.location.pathname, + ); + const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); + const { createHeaders, handleErrors } = useFetchHelpers(); + const headers = createHeaders({ message: options?.message }); + + return async (path: string): Promise => { + try { + const response = await fetch(`${baseUrl}${path}`, { + headers, + }); + + await handleErrors(response); + + return response.json(); + } catch (error) { + console.error("Error fetching data:", error); + throw error; + } + }; +}; + +export const usePost = (options?: { + message?: string; +}): (( + path: string, + body: Body, +) => Promise) => { + const baseUrlManager = new PrimaryBaseUrlManager( + globalThis.location.origin, + globalThis.location.pathname, + ); + const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); + const { environmentHandler } = useContext(DependencyContext); + const env = environmentHandler.useId(); + const { createHeaders, handleErrors } = useFetchHelpers(); + const headers = createHeaders({ env, message: options?.message }); + + return async ( + path: string, + body: Body, + ): Promise => { + try { + const response = await fetch(`${baseUrl}${path}`, { + method: "POST", + headers, + body: JSON.stringify(body), + }); + + await handleErrors(response); + + return response.json(); + } catch (error) { + console.error("Error posting data:", error); + throw error; + } + }; +}; + +export const usePostWithoutEnv = (options?: { + message?: string; +}): (( + path: string, + body: Body, +) => Promise) => { + const baseUrlManager = new PrimaryBaseUrlManager( + globalThis.location.origin, + globalThis.location.pathname, + ); + const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); + const { createHeaders, handleErrors } = useFetchHelpers(); + const headers = createHeaders({ message: options?.message }); + + return async ( + path: string, + body: Body, + ): Promise => { + try { + const response = await fetch(`${baseUrl}${path}`, { + method: "POST", + headers, + body: JSON.stringify(body), + }); + + await handleErrors(response); + + return response.json(); + } catch (error) { + console.error("Error posting data:", error); + throw error; + } + }; +}; + +export const usePut = (options?: { + message?: string; +}): (( + path: string, + body: Body, +) => Promise) => { + const baseUrlManager = new PrimaryBaseUrlManager( + globalThis.location.origin, + globalThis.location.pathname, + ); + const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); + const { environmentHandler } = useContext(DependencyContext); + const env = environmentHandler.useId(); + const { createHeaders, handleErrors } = useFetchHelpers(); + const headers = createHeaders({ env, message: options?.message }); + + return async ( + path: string, + body: Body, + ): Promise => { + try { + const response = await fetch(`${baseUrl}${path}`, { + method: "PUT", + headers, + body: JSON.stringify(body), + }); + + await handleErrors(response); + + return response.json(); + } catch (error) { + console.error("Error putting data:", error); + throw error; + } + }; +}; + +export const usePutWithoutEnv = (options?: { + message?: string; +}): (( + path: string, + body: Body, +) => Promise) => { + const baseUrlManager = new PrimaryBaseUrlManager( + globalThis.location.origin, + globalThis.location.pathname, + ); + const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); + const { createHeaders, handleErrors } = useFetchHelpers(); + const headers = createHeaders({ message: options?.message }); + + return async ( + path: string, + body: Body, + ): Promise => { + try { + const response = await fetch(`${baseUrl}${path}`, { + method: "PUT", + headers, + body: JSON.stringify(body), + }); + + await handleErrors(response); + + return response.json(); + } catch (error) { + console.error("Error putting data:", error); + throw error; + } + }; +}; + +export const usePatch = (options?: { + message?: string; +}): (( + path: string, + body: Body, +) => Promise) => { + const baseUrlManager = new PrimaryBaseUrlManager( + globalThis.location.origin, + globalThis.location.pathname, + ); + const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); + const { environmentHandler } = useContext(DependencyContext); + const env = environmentHandler.useId(); + const { createHeaders, handleErrors } = useFetchHelpers(); + const headers = createHeaders({ env, message: options?.message }); + + return async ( + path: string, + body: Body, + ): Promise => { + try { + const response = await fetch(`${baseUrl}${path}`, { + method: "PATCH", + headers, + body: JSON.stringify(body), + }); + + await handleErrors(response); + + return response.json(); + } catch (error) { + console.error("Error patching data:", error); + throw error; + } + }; +}; + +export const usePatchWithoutEnv = (options?: { + message?: string; +}): (( + path: string, + body: Body, +) => Promise) => { + const baseUrlManager = new PrimaryBaseUrlManager( + globalThis.location.origin, + globalThis.location.pathname, + ); + const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); + const { createHeaders, handleErrors } = useFetchHelpers(); + const headers = createHeaders({ message: options?.message }); + + return async ( + path: string, + body: Body, + ): Promise => { + try { + const response = await fetch(`${baseUrl}${path}`, { + method: "PATCH", + headers, + body: JSON.stringify(body), + }); + + await handleErrors(response); + + return response.json(); + } catch (error) { + console.error("Error patching data:", error); + throw error; + } + }; +}; + +export const useDelete = (options?: { + message?: string; +}): ((path: string) => Promise) => { + const baseUrlManager = new PrimaryBaseUrlManager( + globalThis.location.origin, + globalThis.location.pathname, + ); + const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); + const { environmentHandler } = useContext(DependencyContext); + const env = environmentHandler.useId(); + const { createHeaders, handleErrors } = useFetchHelpers(); + const headers = createHeaders({ env, message: options?.message }); + + if (options?.message) { + headers.append("message", options.message); + } + + return async (path: string): Promise => { + try { + const response = await fetch(`${baseUrl}${path}`, { + method: "DELETE", + headers, + }); + + await handleErrors(response); + + return response.json(); + } catch (error) { + console.error("Error deleting data:", error); + throw error; + } + }; +}; + +export const useDeleteWithoutEnv = (options?: { + message?: string; +}): ((path: string) => Promise) => { + const baseUrlManager = new PrimaryBaseUrlManager( + globalThis.location.origin, + globalThis.location.pathname, + ); + const baseUrl = baseUrlManager.getBaseUrl(process.env.API_BASEURL); + const { createHeaders, handleErrors } = useFetchHelpers(); + const headers = createHeaders({ message: options?.message }); + + return async (path: string): Promise => { + try { + const response = await fetch(`${baseUrl}${path}`, { + method: "DELETE", + headers, + }); + + await handleErrors(response); + + return response.json(); + } catch (error) { + console.error("Error deleting data:", error); + throw error; + } + }; +}; diff --git a/src/Slices/CreateInstance/UI/Page.tsx b/src/Slices/CreateInstance/UI/Page.tsx index 3a2e843bc..24867cd1a 100644 --- a/src/Slices/CreateInstance/UI/Page.tsx +++ b/src/Slices/CreateInstance/UI/Page.tsx @@ -1,20 +1,15 @@ -import React, { useContext } from "react"; +import React from "react"; import { useGetServiceModel } from "@/Data/Managers/V2/GETTERS/GetServiceModel"; import { ErrorView, LoadingView, PageContainer } from "@/UI/Components"; -import { DependencyContext } from "@/UI/Dependency"; import { useRouteParams } from "@/UI/Routing"; import { words } from "@/UI/words"; import { CreateInstance } from "./CreateInstance"; export const Page: React.FC = () => { const { service: serviceName } = useRouteParams<"CreateInstance">(); - const { environmentHandler } = useContext(DependencyContext); - const env = environmentHandler.useId(); - const { data, isError, error, isSuccess, refetch } = useGetServiceModel( - serviceName, - env, - ).useContinuous(); + const { data, isError, error, isSuccess, refetch } = + useGetServiceModel(serviceName).useContinuous(); if (isError) { diff --git a/src/Slices/DesiredState/UI/Components/PromoteAction.tsx b/src/Slices/DesiredState/UI/Components/PromoteAction.tsx index ebf529858..a850b4520 100644 --- a/src/Slices/DesiredState/UI/Components/PromoteAction.tsx +++ b/src/Slices/DesiredState/UI/Components/PromoteAction.tsx @@ -23,12 +23,9 @@ interface Props { * @returns {React.FC} - The dropdown item that has logic to promote the desired state version wrapped in tooltip. */ export const PromoteAction: React.FC = ({ version, isDisabled }) => { - const { environmentModifier, environmentHandler } = - useContext(DependencyContext); + const { environmentModifier } = useContext(DependencyContext); const { setErrorMessage } = useContext(GetDesiredStatesContext); - const { mutate, isError, error } = usePromoteDesiredStateVersion( - environmentHandler.useId(), - ); + const { mutate, isError, error } = usePromoteDesiredStateVersion(); const isHalted = environmentModifier.useIsHalted(); /** diff --git a/src/Slices/DesiredState/UI/Page.tsx b/src/Slices/DesiredState/UI/Page.tsx index 8107c59ea..9a46947bc 100644 --- a/src/Slices/DesiredState/UI/Page.tsx +++ b/src/Slices/DesiredState/UI/Page.tsx @@ -14,7 +14,6 @@ import { LoadingView, ErrorView, } from "@/UI/Components"; -import { DependencyContext } from "@/UI/Dependency"; import { ModalContext } from "@/UI/Root/Components/ModalProvider"; import { words } from "@/UI/words"; import { Filter } from "@S/DesiredState/Core/Query"; @@ -29,10 +28,8 @@ import { CompareSelection } from "./Utils"; * @returns {React.FC} The rendered desired state page. */ export const Page: React.FC = () => { - const { environmentHandler } = useContext(DependencyContext); - const envId = environmentHandler.useId(); const { triggerModal, closeModal } = useContext(ModalContext); - const deleteVersion = useDeleteDesiredStateVersion(envId); + const deleteVersion = useDeleteDesiredStateVersion(); const [errorMessage, setErrorMessage] = useState(""); @@ -51,9 +48,8 @@ export const Page: React.FC = () => { kind: "None", }); - const { data, refetch, isError, error, isSuccess } = useGetDesiredStates( - envId, - ).useContinuous(pageSize, filter, currentPage); + const { data, refetch, isError, error, isSuccess } = + useGetDesiredStates().useContinuous(pageSize, filter, currentPage); /** * function that will open a modal to confirm action to delete a version diff --git a/src/Slices/Diagnose/UI/Diagnose.test.tsx b/src/Slices/Diagnose/UI/Diagnose.test.tsx index 5cdb38218..b684060c0 100644 --- a/src/Slices/Diagnose/UI/Diagnose.test.tsx +++ b/src/Slices/Diagnose/UI/Diagnose.test.tsx @@ -42,6 +42,10 @@ function setup() { repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, + settings: { + enable_lsm_expert_mode: false, + }, }, ]), ); diff --git a/src/Slices/Diagnose/UI/Diagnose.tsx b/src/Slices/Diagnose/UI/Diagnose.tsx index 9aa9272f1..dfee0d045 100644 --- a/src/Slices/Diagnose/UI/Diagnose.tsx +++ b/src/Slices/Diagnose/UI/Diagnose.tsx @@ -1,7 +1,6 @@ -import React, { useContext } from "react"; +import React from "react"; import { useGetDiagnostics } from "@/Data/Managers/V2/GETTERS/GetDiagnostics"; import { EmptyView, ErrorView, LoadingView } from "@/UI/Components"; -import { DependencyContext } from "@/UI/Dependency"; import { words } from "@/UI/words"; import { DiagnoseCardLayout } from "./DiagnoseCardLayout"; @@ -18,12 +17,9 @@ export const Diagnose: React.FC = ({ lookBehind, instanceIdentity, }) => { - const { environmentHandler } = useContext(DependencyContext); - const env = environmentHandler.useId(); const { data, error, isError, isSuccess } = useGetDiagnostics( serviceName, instanceId, - env, ).useOneTime(lookBehind); if (isError) { diff --git a/src/Slices/Diagnose/UI/Page.tsx b/src/Slices/Diagnose/UI/Page.tsx index e7ca5e29f..17a65e8aa 100644 --- a/src/Slices/Diagnose/UI/Page.tsx +++ b/src/Slices/Diagnose/UI/Page.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from "react"; +import React from "react"; import { useUrlStateWithString } from "@/Data"; import { useGetInstance } from "@/Data/Managers/V2/GETTERS/GetInstance"; @@ -8,7 +8,6 @@ import { LoadingView, PageContainer, } from "@/UI/Components"; -import { DependencyContext } from "@/UI/Dependency"; import { useRouteParams } from "@/UI/Routing"; import { words } from "@/UI/words"; import { Diagnose } from "./Diagnose"; @@ -16,7 +15,6 @@ import { LookBackSlider } from "./LookBackSlider"; export const Page: React.FC = () => { const { service, instance } = useRouteParams<"Diagnose">(); - const { environmentHandler } = useContext(DependencyContext); const [amountOfVersionToLookBehind, setAmountOfVersionToLookBehind] = useUrlStateWithString({ @@ -27,7 +25,6 @@ export const Page: React.FC = () => { const { data, error, isError, isSuccess } = useGetInstance( service, instance, - environmentHandler.useId(), ).useContinuous(); const handleSliding = (value: number) => { diff --git a/src/Slices/ServiceCatalog/UI/Page.tsx b/src/Slices/ServiceCatalog/UI/Page.tsx index a17e4e62e..880ec8554 100644 --- a/src/Slices/ServiceCatalog/UI/Page.tsx +++ b/src/Slices/ServiceCatalog/UI/Page.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from "react"; +import React from "react"; import { useGetServiceModels } from "@/Data/Managers/V2/GETTERS/GetServiceModels"; import { EmptyView, @@ -7,15 +7,12 @@ import { PageContainer, } from "@/UI/Components"; import { CatalogActions } from "@/UI/Components/CatalogActions"; -import { DependencyContext } from "@/UI/Dependency"; import { words } from "@/UI/words"; import { CatalogDataList } from "./CatalogDataList"; export const Page: React.FC = () => { - const { environmentHandler } = useContext(DependencyContext); - const env = environmentHandler.useId(); const { data, isError, error, isSuccess, refetch } = - useGetServiceModels(env).useContinuous(); + useGetServiceModels().useContinuous(); let component: React.JSX.Element = ( diff --git a/src/Slices/ServiceCatalog/UI/ServiceItem.tsx b/src/Slices/ServiceCatalog/UI/ServiceItem.tsx index 676c7dc88..f533c368a 100644 --- a/src/Slices/ServiceCatalog/UI/ServiceItem.tsx +++ b/src/Slices/ServiceCatalog/UI/ServiceItem.tsx @@ -39,10 +39,9 @@ interface Props { */ export const ServiceItem: React.FC = ({ service }) => { const { triggerModal, closeModal } = useContext(ModalContext); - const { routeManager, environmentHandler } = useContext(DependencyContext); - const env = environmentHandler.useId(); + const { routeManager } = useContext(DependencyContext); const [isOpen, setIsOpen] = useState(false); - const { mutate, isError, error } = useDeleteService(env, service.name); + const { mutate, isError, error } = useDeleteService(service.name); const [errorMessage, setErrorMessage] = useState(""); const serviceKey = service.name + "-item"; const rowRefs = useRef>({}); diff --git a/src/Slices/ServiceDetails/UI/Tabs/AttributeTable.test.tsx b/src/Slices/ServiceDetails/UI/Tabs/AttributeTable.test.tsx index 9bca0467b..afa088ec1 100644 --- a/src/Slices/ServiceDetails/UI/Tabs/AttributeTable.test.tsx +++ b/src/Slices/ServiceDetails/UI/Tabs/AttributeTable.test.tsx @@ -20,6 +20,7 @@ import { import { multiNestedEditable } from "@/Test/Data/Service/EmbeddedEntity"; import { DependencyProvider, EnvironmentHandlerImpl } from "@/UI"; import { AttributeTable } from "./AttributeTable"; +import { halted } from "@/Test/Data/EnvironmentDetails"; expect.extend(toHaveNoViolations); @@ -73,6 +74,7 @@ function setup(service: ServiceModel) { repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, settings: { enable_lsm_expert_mode: true, }, diff --git a/src/Slices/ServiceDetails/UI/Tabs/Config.tsx b/src/Slices/ServiceDetails/UI/Tabs/Config.tsx index e74a54404..a1206d321 100644 --- a/src/Slices/ServiceDetails/UI/Tabs/Config.tsx +++ b/src/Slices/ServiceDetails/UI/Tabs/Config.tsx @@ -1,8 +1,7 @@ -import React, { useContext } from "react"; +import React from "react"; import { Card, CardBody } from "@patternfly/react-core"; import { useGetServiceConfig } from "@/Data/Managers/V2/GETTERS/GetServiceConfig/useGetServiceConfig"; import { ErrorView, LoadingView } from "@/UI/Components"; -import { DependencyContext } from "@/UI/Dependency"; import { ConfigList } from "./ConfigList"; interface Props { @@ -10,12 +9,8 @@ interface Props { } export const Config: React.FC = ({ serviceName }) => { - const { environmentHandler } = useContext(DependencyContext); - const env = environmentHandler.useId(); - const { data, isSuccess, isError, error, refetch } = useGetServiceConfig( - serviceName, - env, - ).useOneTime(); + const { data, isSuccess, isError, error, refetch } = + useGetServiceConfig(serviceName).useOneTime(); if (isError) { diff --git a/src/Slices/ServiceInstanceDetails/Test/mockSetup.tsx b/src/Slices/ServiceInstanceDetails/Test/mockSetup.tsx index eab9baf34..8c1c7d246 100644 --- a/src/Slices/ServiceInstanceDetails/Test/mockSetup.tsx +++ b/src/Slices/ServiceInstanceDetails/Test/mockSetup.tsx @@ -82,6 +82,7 @@ export const SetupWrapper: React.FC> = ({ repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, settings: { enable_lsm_expert_mode: expertMode, }, diff --git a/src/Slices/ServiceInstanceDetails/UI/Components/AttributesComponents/AttributesEditor.tsx b/src/Slices/ServiceInstanceDetails/UI/Components/AttributesComponents/AttributesEditor.tsx index 416d1a1a8..e4e1037bd 100644 --- a/src/Slices/ServiceInstanceDetails/UI/Components/AttributesComponents/AttributesEditor.tsx +++ b/src/Slices/ServiceInstanceDetails/UI/Components/AttributesComponents/AttributesEditor.tsx @@ -44,11 +44,10 @@ export const AttributesEditor: React.FC = ({ service_entity, selectedVersion, }) => { - const { environmentHandler, authHelper } = useContext(DependencyContext); + const { authHelper } = useContext(DependencyContext); const { instance } = useContext(InstanceDetailsContext); const isLatestVersion = String(instance.version) === selectedVersion; - const environment = environmentHandler.useId(); const username = authHelper.getUser(); const [selectedSet, setSelectedSet] = useState(dropdownOptions[0]); @@ -62,7 +61,7 @@ export const AttributesEditor: React.FC = ({ const [errorMessage, setErrorMessage] = useState(""); const { mutate, isError, error, isPending, isSuccess } = - usePatchAttributesExpert(environment, instance.id, instance.service_entity); + usePatchAttributesExpert(instance.id, instance.service_entity); /** * Handles the change of the selected attribute Set. diff --git a/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/DeleteAction.tsx b/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/DeleteAction.tsx index 17199e4e9..e73e6ed30 100644 --- a/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/DeleteAction.tsx +++ b/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/DeleteAction.tsx @@ -1,9 +1,9 @@ -import React, { useCallback, useContext, useEffect, useState } from "react"; +import React, { useCallback, useEffect, useState } from "react"; import { DropdownItem, Content } from "@patternfly/react-core"; import { TrashAltIcon } from "@patternfly/react-icons"; import { ParsedNumber } from "@/Core"; import { useDeleteInstance } from "@/Data/Managers/V2/DELETE/DeleteInstance"; -import { DependencyContext, words } from "@/UI"; +import { words } from "@/UI"; import { ConfirmationModal } from "../../ConfirmModal"; import { ToastAlertMessage } from "../../ToastAlert"; @@ -43,12 +43,7 @@ export const DeleteAction: React.FC = ({ const [isModalOpen, setIsModalOpen] = useState(false); const [errorMessage, setErrorMessage] = useState(""); - const { environmentHandler } = useContext(DependencyContext); - - const environment = environmentHandler.useId(); - const { mutate, isError, error, isSuccess, isPending } = useDeleteInstance( - environment, instance_id, service_entity, version, @@ -66,7 +61,7 @@ export const DeleteAction: React.FC = ({ * async method sending out the request to delete the instance */ const onSubmitDelete = async (): Promise => { - mutate(""); + mutate(); }; /** diff --git a/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/DestroyAction.tsx b/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/DestroyAction.tsx index 483d6b789..273ebd018 100644 --- a/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/DestroyAction.tsx +++ b/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/DestroyAction.tsx @@ -50,7 +50,6 @@ export const DestroyAction: React.FC = ({ const message = words("instanceDetails.API.message.update")(username); const { mutate, isError, error, isSuccess, isPending } = useDestroyInstance( - environment, instance_id, service_entity, version, @@ -78,7 +77,7 @@ export const DestroyAction: React.FC = ({ * async method sending out the request to destroy the instance */ const onSubmitDestroy = async (): Promise => { - mutate(""); + mutate(); }; useEffect(() => { diff --git a/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/ExpertStateTransfer.tsx b/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/ExpertStateTransfer.tsx index 111e247f7..b7ddc2d74 100644 --- a/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/ExpertStateTransfer.tsx +++ b/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/ExpertStateTransfer.tsx @@ -66,14 +66,13 @@ export const ExpertStateTransfer: React.FC = ({ "rollback", ]; - const { environmentHandler, authHelper } = useContext(DependencyContext); + const { authHelper } = useContext(DependencyContext); - const environment = environmentHandler.useId(); const username = authHelper.getUser(); const message = words("instanceDetails.API.message.update")(username); const { mutate, isError, error, isSuccess, isPending } = - usePostExpertStateTransfer(environment, instance_id, service_entity); + usePostExpertStateTransfer(instance_id, service_entity); /** * When a state is selected in the list, block the interface, open the modal, diff --git a/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/StateAction.tsx b/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/StateAction.tsx index c6b054fbc..22537723d 100644 --- a/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/StateAction.tsx +++ b/src/Slices/ServiceInstanceDetails/UI/Components/InstanceActions/Actions/StateAction.tsx @@ -44,11 +44,9 @@ export const StateAction: React.FC = ({ const [targetState, setTargetState] = useState(""); const [errorMessage, setErrorMessage] = useState(""); - const { environmentHandler, authHelper } = useContext(DependencyContext); - const environment = environmentHandler.useId(); + const { authHelper } = useContext(DependencyContext); const { mutate, isError, error, isSuccess, isPending } = usePostStateTransfer( - environment, instance_id, service_entity, ); diff --git a/src/Slices/ServiceInstanceDetails/UI/Page.tsx b/src/Slices/ServiceInstanceDetails/UI/Page.tsx index 6dfd677a2..2d5a6239e 100644 --- a/src/Slices/ServiceInstanceDetails/UI/Page.tsx +++ b/src/Slices/ServiceInstanceDetails/UI/Page.tsx @@ -1,9 +1,9 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { useUrlStateWithString } from "@/Data"; import { useGetInfiniteInstanceLogs } from "@/Data/Managers/V2/GETTERS/GetInfiniteInstanceLogs"; import { useGetInstance } from "@/Data/Managers/V2/GETTERS/GetInstance"; import { useGetServiceModel } from "@/Data/Managers/V2/GETTERS/GetServiceModel"; -import { DependencyContext, useRouteParams, words } from "@/UI"; +import { useRouteParams, words } from "@/UI"; import { ErrorView, LoadingView, PageContainer } from "@/UI/Components"; import { InstanceDetailsContext } from "../Core/Context"; import { VersionedPageTitleWithActions } from "./Components/Sections"; @@ -31,25 +31,14 @@ export const ServiceInstanceDetails: React.FC = ({ instanceId, version, }) => { - const { environmentHandler } = useContext(DependencyContext); - const environment = environmentHandler.useId(); - - const instanceDetails = useGetInstance( - service, - instanceId, - environment, - ).useContinuous(); + const instanceDetails = useGetInstance(service, instanceId).useContinuous(); const logsQuery = useGetInfiniteInstanceLogs( service, instanceId, - environment, ).useContinuous(version); - const serviceModelQuery = useGetServiceModel( - service, - environment, - ).useOneTime(); + const serviceModelQuery = useGetServiceModel(service).useOneTime(); const pageTitle = `${service}: ${instance}`; diff --git a/src/Slices/ServiceInstanceDetails/UI/Tabs/ResourcesTabContent.test.tsx b/src/Slices/ServiceInstanceDetails/UI/Tabs/ResourcesTabContent.test.tsx index 34b7c4bdf..2c6bd87c9 100644 --- a/src/Slices/ServiceInstanceDetails/UI/Tabs/ResourcesTabContent.test.tsx +++ b/src/Slices/ServiceInstanceDetails/UI/Tabs/ResourcesTabContent.test.tsx @@ -43,11 +43,6 @@ it("should render error view correctly", async () => { await screen.findByLabelText("Error_view-Resources-content"), ).toBeVisible(); expect(screen.getByText("Something went wrong")).toBeVisible(); - expect( - screen.getByText( - "Failed to fetch service instance resources for instance of id: 1d96a1ab", - ), - ).toBeVisible(); server.close(); }); diff --git a/src/Slices/ServiceInstanceDetails/UI/Tabs/ResourcesTabContent.tsx b/src/Slices/ServiceInstanceDetails/UI/Tabs/ResourcesTabContent.tsx index 48a2b2439..941c53606 100644 --- a/src/Slices/ServiceInstanceDetails/UI/Tabs/ResourcesTabContent.tsx +++ b/src/Slices/ServiceInstanceDetails/UI/Tabs/ResourcesTabContent.tsx @@ -1,7 +1,7 @@ import React, { useContext } from "react"; import { Content, TabContent, TabContentBody } from "@patternfly/react-core"; import { useGetInstanceResources } from "@/Data/Managers/V2/GETTERS/GetInstanceResources"; -import { DependencyContext, words } from "@/UI"; +import { words } from "@/UI"; import { EmptyView, ErrorView, @@ -13,14 +13,11 @@ import { TabContentWrapper } from "./TabContentWrapper"; export const ResourcesTabContent: React.FC = () => { const { instance } = useContext(InstanceDetailsContext); - const { environmentHandler } = useContext(DependencyContext); - const environment = environmentHandler.useId(); const { data, isSuccess, isError, error } = useGetInstanceResources( instance.id, instance.service_entity, String(instance.version), - environment, ).useContinuous(); if (isSuccess) { diff --git a/src/Slices/ServiceInventory/UI/InventoryTable.test.tsx b/src/Slices/ServiceInventory/UI/InventoryTable.test.tsx index 543953017..eda4778c1 100644 --- a/src/Slices/ServiceInventory/UI/InventoryTable.test.tsx +++ b/src/Slices/ServiceInventory/UI/InventoryTable.test.tsx @@ -37,6 +37,7 @@ import { import { ModalProvider } from "@/UI/Root/Components/ModalProvider"; import { InventoryTable } from "./InventoryTable"; import { InventoryTablePresenter } from "./Presenters"; +import { halted } from "@/Test/Data/EnvironmentDetails"; const dummySetter = () => { return; @@ -57,6 +58,7 @@ function setup(expertMode = false, setSortFn: (props) => void = dummySetter) { repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, settings: { enable_lsm_expert_mode: expertMode, }, diff --git a/src/Slices/ServiceInventory/UI/ServiceInventory.test.tsx b/src/Slices/ServiceInventory/UI/ServiceInventory.test.tsx index c1bcf2995..a27bea9bd 100644 --- a/src/Slices/ServiceInventory/UI/ServiceInventory.test.tsx +++ b/src/Slices/ServiceInventory/UI/ServiceInventory.test.tsx @@ -105,6 +105,7 @@ function setup(service = Service.a, pageSize = "") { repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, settings: { enable_lsm_expert_mode: false, }, diff --git a/src/Test/Data/Environment.ts b/src/Test/Data/Environment.ts index f6c89759d..064a6b520 100644 --- a/src/Test/Data/Environment.ts +++ b/src/Test/Data/Environment.ts @@ -6,6 +6,7 @@ export const a: EnvironmentModel = { project_id: "project_id_a", repo_branch: "", repo_url: "", + halted: false, }; export const b: EnvironmentModel = { @@ -14,6 +15,7 @@ export const b: EnvironmentModel = { project_id: "project_id_b", repo_branch: "", repo_url: "", + halted: false, }; export const c: EnvironmentModel = { @@ -22,6 +24,7 @@ export const c: EnvironmentModel = { project_id: "project_id_b", repo_branch: "", repo_url: "", + halted: false, }; export const d: EnvironmentModel = { @@ -30,6 +33,7 @@ export const d: EnvironmentModel = { project_id: "project_id_c", repo_branch: "", repo_url: "", + halted: false, }; export const e: EnvironmentModel = { @@ -38,6 +42,7 @@ export const e: EnvironmentModel = { project_id: "project_id_d", repo_branch: "", repo_url: "", + halted: false, }; export const filterable: EnvironmentExpertOnly[] = [ @@ -50,6 +55,7 @@ export const filterable: EnvironmentExpertOnly[] = [ repo_url: "github.com/test", description: "Test desc", icon: "image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiCiAgICAgd2lkdGg9IjMwIiBoZWlnaHQ9IjIwIgogICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iYmxhY2siIC8+CiAgPGNpcmNsZSBjeD0iMTUiIGN5PSIxMCIgcj0iOCIgZmlsbD0id2hpdGUiIC8+Cjwvc3ZnPg==", + halted: false, settings: { enable_lsm_expert_mode: true, }, @@ -61,6 +67,7 @@ export const filterable: EnvironmentExpertOnly[] = [ projectName: "default", repo_branch: "master", repo_url: "github.com/test2", + halted: false, settings: { enable_lsm_expert_mode: true, }, @@ -72,6 +79,8 @@ export const filterable: EnvironmentExpertOnly[] = [ project_id: "444", repo_branch: "master", repo_url: "gitlab.com/test", + halted: false, + settings: { enable_lsm_expert_mode: true, }, @@ -83,6 +92,7 @@ export const filterable: EnvironmentExpertOnly[] = [ project_id: "444", repo_branch: "master", repo_url: "gitlab.com/test123", + halted: false, settings: { enable_lsm_expert_mode: true, }, diff --git a/src/Test/Data/Project.ts b/src/Test/Data/Project.ts index a8bc1470a..e70749418 100644 --- a/src/Test/Data/Project.ts +++ b/src/Test/Data/Project.ts @@ -38,6 +38,7 @@ export const filterable: ProjectModel[] = [ project_id: "1", repo_branch: "master", repo_url: "github.com/test", + halted: false, }, { id: "456", @@ -45,6 +46,7 @@ export const filterable: ProjectModel[] = [ project_id: "1", repo_branch: "master", repo_url: "github.com/test2", + halted: false, }, ], }, @@ -58,6 +60,7 @@ export const filterable: ProjectModel[] = [ project_id: "444", repo_branch: "master", repo_url: "gitlab.com/test", + halted: false, }, { id: "101", @@ -65,6 +68,7 @@ export const filterable: ProjectModel[] = [ project_id: "444", repo_branch: "master", repo_url: "gitlab.com/test123", + halted: false, }, ], }, diff --git a/src/UI/Components/Diagram/Canvas.test.tsx b/src/UI/Components/Diagram/Canvas.test.tsx index b86f82c47..468e0dc5e 100644 --- a/src/UI/Components/Diagram/Canvas.test.tsx +++ b/src/UI/Components/Diagram/Canvas.test.tsx @@ -62,6 +62,10 @@ const setup = ( repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, + settings: { + enable_lsm_expert_mode: false, + }, }, { id: "bbb", @@ -70,6 +74,10 @@ const setup = ( repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, + settings: { + enable_lsm_expert_mode: false, + }, }, ]), ); diff --git a/src/UI/Components/Diagram/Context/ComposerCreatorProvider.test.tsx b/src/UI/Components/Diagram/Context/ComposerCreatorProvider.test.tsx index f082e6f28..35c0ac4db 100644 --- a/src/UI/Components/Diagram/Context/ComposerCreatorProvider.test.tsx +++ b/src/UI/Components/Diagram/Context/ComposerCreatorProvider.test.tsx @@ -44,6 +44,10 @@ const setup = () => { repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, + settings: { + enable_lsm_expert_mode: false, + }, }, ]), ); diff --git a/src/UI/Components/Diagram/Context/ComposerCreatorProvider.tsx b/src/UI/Components/Diagram/Context/ComposerCreatorProvider.tsx index 82835a0bf..961de705c 100644 --- a/src/UI/Components/Diagram/Context/ComposerCreatorProvider.tsx +++ b/src/UI/Components/Diagram/Context/ComposerCreatorProvider.tsx @@ -1,8 +1,8 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { FlexItem, Flex } from "@patternfly/react-core"; import { useGetInventoryList } from "@/Data/Managers/V2/GETTERS/GetInventoryList"; import { useGetServiceModels } from "@/Data/Managers/V2/GETTERS/GetServiceModels"; -import { DependencyContext, words } from "@/UI"; +import { words } from "@/UI"; import { ErrorView, LoadingView, PageContainer } from "@/UI/Components"; import { Canvas } from "@/UI/Components/Diagram/Canvas"; import { ComposerActions } from "../components"; @@ -38,14 +38,11 @@ export const ComposerCreatorProvider: React.FC = ({ serviceName }) => { const [interServiceRelationNames, setInterServiceRelationNames] = useState< string[] >([]); - const { environmentHandler } = useContext(DependencyContext); - const environment = environmentHandler.useId(); - const serviceModels = useGetServiceModels(environment).useContinuous(); + const serviceModels = useGetServiceModels().useContinuous(); const relatedInventoriesQuery = useGetInventoryList( interServiceRelationNames, - environment, ).useContinuous(); useEffect(() => { diff --git a/src/UI/Components/Diagram/Context/ComposerEditorProvider.test.tsx b/src/UI/Components/Diagram/Context/ComposerEditorProvider.test.tsx index 72c0d3d01..2d38d8d8d 100644 --- a/src/UI/Components/Diagram/Context/ComposerEditorProvider.test.tsx +++ b/src/UI/Components/Diagram/Context/ComposerEditorProvider.test.tsx @@ -49,6 +49,10 @@ const setup = (instanceId: string, editable: boolean = true) => { repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, + settings: { + enable_lsm_expert_mode: false, + }, }, ]), ); diff --git a/src/UI/Components/Diagram/Context/ComposerEditorProvider.tsx b/src/UI/Components/Diagram/Context/ComposerEditorProvider.tsx index 445e876d8..afb111ec7 100644 --- a/src/UI/Components/Diagram/Context/ComposerEditorProvider.tsx +++ b/src/UI/Components/Diagram/Context/ComposerEditorProvider.tsx @@ -1,9 +1,9 @@ -import React, { useContext, useEffect, useMemo, useState } from "react"; +import React, { useEffect, useMemo, useState } from "react"; import { Flex, FlexItem } from "@patternfly/react-core"; import { useGetInstanceWithRelations } from "@/Data/Managers/V2/GETTERS/GetInstanceWithRelations"; import { useGetInventoryList } from "@/Data/Managers/V2/GETTERS/GetInventoryList"; import { useGetServiceModels } from "@/Data/Managers/V2/GETTERS/GetServiceModels"; -import { DependencyContext, words } from "@/UI"; +import { words } from "@/UI"; import { ErrorView, LoadingView, PageContainer } from "@/UI/Components"; import { Canvas } from "@/UI/Components/Diagram/Canvas"; import { ComposerActions } from "../components"; @@ -51,10 +51,8 @@ export const ComposerEditorProvider: React.FC = ({ const [interServiceRelationNames, setInterServiceRelationNames] = useState< string[] >([]); - const { environmentHandler } = useContext(DependencyContext); - const environment = environmentHandler.useId(); - const serviceModelsQuery = useGetServiceModels(environment).useContinuous(); + const serviceModelsQuery = useGetServiceModels().useContinuous(); const mainService = useMemo(() => { const data = serviceModelsQuery.data; @@ -68,14 +66,12 @@ export const ComposerEditorProvider: React.FC = ({ const instanceWithRelationsQuery = useGetInstanceWithRelations( instance, - environment, !editable, //if editable is true, we don't fetch referenced_by instances as they should not be displayed to keep it aligned with the regular instance form, they are only displayed in the composer viewer mainService, ).useOneTime(); const relatedInventoriesQuery = useGetInventoryList( interServiceRelationNames, - environment, ).useContinuous(); useEffect(() => { diff --git a/src/UI/Components/Diagram/components/ComposerActions.test.tsx b/src/UI/Components/Diagram/components/ComposerActions.test.tsx index 161b44760..643e38794 100644 --- a/src/UI/Components/Diagram/components/ComposerActions.test.tsx +++ b/src/UI/Components/Diagram/components/ComposerActions.test.tsx @@ -45,18 +45,23 @@ describe("ComposerActions.", () => { ); const store = getStoreInstance(); - store.dispatch.environment.setEnvironments( - RemoteData.success([ - { - id: "aaa", - name: "env-a", - project_id: "ppp", - repo_branch: "branch", - repo_url: "repo", - projectName: "project", - }, - ]), - ); + const env = { + id: "aaa", + name: "env-a", + project_id: "ppp", + repo_branch: "branch", + repo_url: "repo", + projectName: "project", + halted: false, + settings: {}, + }; + + store.dispatch.environment.setEnvironments(RemoteData.success([env])); + + store.dispatch.environment.setEnvironmentDetailsById({ + id: "aaa", + value: RemoteData.success(env), + }); return ( @@ -195,7 +200,9 @@ describe("ComposerActions.", () => { it("shows success message and redirects when deploy button is clicked", async () => { server.use( http.post("/lsm/v2/order", async () => { - return HttpResponse.json(); + return HttpResponse.json({ + data: [], + }); }), ); @@ -222,7 +229,9 @@ describe("ComposerActions.", () => { http.post("/lsm/v2/order", async () => { await delay(); - return HttpResponse.json(); + return HttpResponse.json({ + data: [], + }); }), ); const canvasContext = { diff --git a/src/UI/Components/Diagram/components/ComposerActions.tsx b/src/UI/Components/Diagram/components/ComposerActions.tsx index 857196f3d..f2ffa0915 100644 --- a/src/UI/Components/Diagram/components/ComposerActions.tsx +++ b/src/UI/Components/Diagram/components/ComposerActions.tsx @@ -48,15 +48,13 @@ export const ComposerActions: React.FC = ({ serviceName, editable }) => { diagramHandlers, interServiceRelationsOnCanvas, } = useContext(CanvasContext); - const { routeManager, environmentHandler } = useContext(DependencyContext); + const { routeManager } = useContext(DependencyContext); const [alertMessage, setAlertMessage] = useState(""); const [alertType, setAlertType] = useState(AlertVariant.danger); - const environment = environmentHandler.useId(); - - const metadataMutation = usePostMetadata(environment); - const orderMutation = usePostOrder(environment); + const metadataMutation = usePostMetadata(); + const orderMutation = usePostOrder(); const navigate = useNavigate(); const url = routeManager.useUrl("Inventory", { diff --git a/src/UI/Components/Diagram/components/EntityForm.test.tsx b/src/UI/Components/Diagram/components/EntityForm.test.tsx index 10d165e4d..5bf06a044 100644 --- a/src/UI/Components/Diagram/components/EntityForm.test.tsx +++ b/src/UI/Components/Diagram/components/EntityForm.test.tsx @@ -54,6 +54,10 @@ describe("EntityForm.", () => { repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, + settings: { + enable_lsm_expert_mode: false, + }, }, { id: "bbb", @@ -62,6 +66,10 @@ describe("EntityForm.", () => { repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, + settings: { + enable_lsm_expert_mode: false, + }, }, ]), ); diff --git a/src/UI/Components/Diagram/components/RightSidebar.test.tsx b/src/UI/Components/Diagram/components/RightSidebar.test.tsx index 39e2441cb..b5c14d60f 100644 --- a/src/UI/Components/Diagram/components/RightSidebar.test.tsx +++ b/src/UI/Components/Diagram/components/RightSidebar.test.tsx @@ -47,6 +47,10 @@ describe("RightSidebar.", () => { repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, + settings: { + enable_lsm_expert_mode: false, + }, }, { id: "bbb", @@ -55,6 +59,10 @@ describe("RightSidebar.", () => { repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, + settings: { + enable_lsm_expert_mode: false, + }, }, ]), ); diff --git a/src/UI/Components/ExpertBanner/ExpertBanner.test.tsx b/src/UI/Components/ExpertBanner/ExpertBanner.test.tsx index 009f355eb..5930c8151 100644 --- a/src/UI/Components/ExpertBanner/ExpertBanner.test.tsx +++ b/src/UI/Components/ExpertBanner/ExpertBanner.test.tsx @@ -27,7 +27,7 @@ const setup = (flag: boolean) => { > - + diff --git a/src/UI/Components/ExpertBanner/ExpertBanner.tsx b/src/UI/Components/ExpertBanner/ExpertBanner.tsx index e47f0e40f..f8460b13a 100644 --- a/src/UI/Components/ExpertBanner/ExpertBanner.tsx +++ b/src/UI/Components/ExpertBanner/ExpertBanner.tsx @@ -5,21 +5,16 @@ import { DependencyContext } from "@/UI/Dependency"; import { words } from "@/UI/words"; import { ToastAlert } from "../ToastAlert"; -interface Props { - environmentId: string; -} - /** * A React component that displays a banner when the expert mode is enabled. * * @props {object} props - The properties passed to the component. - * @prop {string} environmentId -The ID of the environment. * @returns { React.FC | null} The rendered banner if the expert mode is enabled, otherwise null. */ -export const ExpertBanner: React.FC = ({ environmentId }) => { +export const ExpertBanner: React.FC = () => { const [errorMessage, setMessage] = useState(undefined); const { environmentModifier } = useContext(DependencyContext); - const { mutate, isError, error } = useUpdateEnvConfig(environmentId); + const { mutate, isError, error } = useUpdateEnvConfig(); const [isLoading, setIsLoading] = useState(false); // isLoading is to indicate the asynchronous operation is in progress, as we need to wait until setting will be updated, getters are still in the V1 - task https://github.com/inmanta/web-console/issues/5999 useEffect(() => { diff --git a/src/UI/Components/JSONEditor/JSONEditor.tsx b/src/UI/Components/JSONEditor/JSONEditor.tsx index e7868692d..19b61c2d7 100644 --- a/src/UI/Components/JSONEditor/JSONEditor.tsx +++ b/src/UI/Components/JSONEditor/JSONEditor.tsx @@ -1,8 +1,8 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { Editor, OnValidate, useMonaco } from "@monaco-editor/react"; import { Spinner } from "@patternfly/react-core"; import { useGetJSONSchema } from "@/Data/Managers/V2/GETTERS/GetJSONSchema"; -import { DependencyContext, words } from "@/UI"; +import { words } from "@/UI"; import { getThemePreference } from "../DarkmodeOption"; import { ErrorMessageContainer } from "../ErrorMessageContainer"; @@ -34,15 +34,13 @@ export const JSONEditor: React.FC = ({ onChange, readOnly = false, }) => { - const { environmentHandler } = useContext(DependencyContext); const preferedTheme = getThemePreference() || "light"; - const environment = environmentHandler.useId(); const [isLoading, setIsLoading] = useState(true); const [editorState, setEditorState] = useState(data); const [errors, setErrors] = useState([]); - const schema = useGetJSONSchema(service_entity, environment).useOneTime(); + const schema = useGetJSONSchema(service_entity).useOneTime(); const monaco = useMonaco(); diff --git a/src/UI/Components/ServiceInstanceForm/Components/FieldInput.tsx b/src/UI/Components/ServiceInstanceForm/Components/FieldInput.tsx index 5f523f15a..5369dd3d3 100644 --- a/src/UI/Components/ServiceInstanceForm/Components/FieldInput.tsx +++ b/src/UI/Components/ServiceInstanceForm/Components/FieldInput.tsx @@ -1,10 +1,4 @@ -import React, { - useCallback, - useContext, - useEffect, - useMemo, - useState, -} from "react"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Button, FormFieldGroupExpandable, @@ -23,7 +17,6 @@ import { import { toOptionalBoolean } from "@/Data"; import { useSuggestedValues } from "@/Data/Managers/V2/GETTERS/FormSuggestions"; import { createFormState } from "@/UI/Components/ServiceInstanceForm/Helpers"; -import { DependencyContext } from "@/UI/Dependency"; import { words } from "@/UI/words"; import { BooleanFormInput } from "./BooleanFormInput"; import { BooleanToggleInput } from "./BooleanToggleInput"; @@ -85,12 +78,8 @@ export const FieldInput: React.FC = ({ isNew = false, suggestions, }) => { - const { environmentHandler } = useContext(DependencyContext); - const environment = environmentHandler.useId(); - const { data, isLoading, error } = useSuggestedValues( - suggestions, - environment, - ).useOneTime(); + const { data, isLoading, error } = + useSuggestedValues(suggestions).useOneTime(); const [suggestionsList, setSuggestionsList] = useState(null); // Get the controlled value for the field diff --git a/src/UI/Components/ServiceInstanceForm/Components/RelatedServiceProvider.tsx b/src/UI/Components/ServiceInstanceForm/Components/RelatedServiceProvider.tsx index b3edb915e..45401d976 100644 --- a/src/UI/Components/ServiceInstanceForm/Components/RelatedServiceProvider.tsx +++ b/src/UI/Components/ServiceInstanceForm/Components/RelatedServiceProvider.tsx @@ -1,7 +1,6 @@ -import React, { useContext } from "react"; +import React from "react"; import { Alert, Button } from "@patternfly/react-core"; import { useGetServiceModel } from "@/Data/Managers/V2/GETTERS/GetServiceModel"; -import { DependencyContext } from "@/UI/Dependency"; import { words } from "@/UI/words"; import { AutoCompleteInputProvider } from "./AutoCompleteInputProvider"; @@ -41,12 +40,8 @@ export const RelatedServiceProvider: React.FC = ({ alreadySelected, multi, }) => { - const { environmentHandler } = useContext(DependencyContext); - const env = environmentHandler.useId(); - const { isError, error, isSuccess, refetch } = useGetServiceModel( - serviceName, - env, - ).useContinuous(); + const { isError, error, isSuccess, refetch } = + useGetServiceModel(serviceName).useContinuous(); if (isError) { return ( diff --git a/src/UI/Components/ServiceInstanceForm/ServiceInstanceForm.test.tsx b/src/UI/Components/ServiceInstanceForm/ServiceInstanceForm.test.tsx index 98eed5ee6..633b78e32 100644 --- a/src/UI/Components/ServiceInstanceForm/ServiceInstanceForm.test.tsx +++ b/src/UI/Components/ServiceInstanceForm/ServiceInstanceForm.test.tsx @@ -1,6 +1,6 @@ import React from "react"; import "@testing-library/jest-dom"; -import { Route, Routes } from "react-router-dom"; +import { MemoryRouter, Route, Routes, useLocation } from "react-router-dom"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { render, screen, within } from "@testing-library/react"; import { userEvent } from "@testing-library/user-event"; @@ -13,6 +13,7 @@ import { EnumField, InstanceAttributeModel, NestedField, + RemoteData, TextField, Textarea, } from "@/Core"; @@ -23,9 +24,7 @@ import { } from "@/Data"; import * as Test from "@/Test"; import { DeferredApiHelper, StaticScheduler, dependencies } from "@/Test"; -import { DependencyProvider } from "@/UI"; -import CustomRouter from "@/UI/Routing/CustomRouter"; -import history from "@/UI/Routing/history"; +import { DependencyProvider, EnvironmentHandlerImpl } from "@/UI"; import { words } from "@/UI/words"; import { ServiceInstanceForm } from "./ServiceInstanceForm"; @@ -42,6 +41,10 @@ const setup = ( isEdit = false, originalAttributes: InstanceAttributeModel | undefined = undefined, ) => { + const environmentHandler = EnvironmentHandlerImpl( + useLocation, + dependencies.routeManager, + ); const store = getStoreInstance(); const scheduler = new StaticScheduler(); const apiHelper = new DeferredApiHelper(); @@ -49,9 +52,36 @@ const setup = ( new QueryManagerResolverImpl(store, apiHelper, scheduler, scheduler), ); + const env = { + id: "aaa", + name: "env-a", + project_id: "ppp", + repo_branch: "branch", + repo_url: "repo", + projectName: "project", + halted: false, + settings: {}, + }; + + store.dispatch.environment.setEnvironments(RemoteData.success([env])); + + store.dispatch.environment.setEnvironmentDetailsById({ + id: "aaa", + value: RemoteData.success(env), + }); + const component = ( - - + + - + ); return { component, apiHelper, scheduler }; }; -function createQuerryWrapper(children: React.ReactNode) { +function createQueryWrapper(children: React.ReactNode) { const queryClient = new QueryClient(); return ( {children} ); } +const server = setupServer(); + +beforeAll(() => { + server.listen(); + server.use( + http.get("/api/v1/parameter/param_name", () => { + return HttpResponse.json({ + parameter: undefined, + }); + }), + ); +}); + +beforeEach(() => { + server.resetHandlers(); + server.use( + http.get("/api/v1/parameter/param_name", () => { + return HttpResponse.json({ + parameter: undefined, + }); + }), + ); +}); + +afterAll(() => server.close()); test("GIVEN ServiceInstanceForm WHEN passed a TextField THEN shows that field", async () => { const { component } = setup([Test.Field.text]); @@ -132,10 +187,9 @@ test("GIVEN ServiceInstanceForm WHEN passed a TextField with suggestions THEN sh test("GIVEN ServiceInstanceForm WHEN passed a TextField with parameter suggestions THEN shows that field", async () => { // Provide the server-side API with the request handlers. - const server = setupServer( - http.get("/api/v1/parameter/:id", ({ params }) => { - expect(params.id).toEqual("param_name"); - + server.resetHandlers(); + server.use( + http.get("/api/v1/parameter/param_name", () => { return HttpResponse.json({ parameter: { value: "metadata", @@ -154,12 +208,9 @@ test("GIVEN ServiceInstanceForm WHEN passed a TextField with parameter suggestio }), ); - // Start the interception. - server.listen(); - const { component } = setup([Test.Field.textSuggestions2]); - render(createQuerryWrapper(component)); + render(createQueryWrapper(component)); expect( screen.getByRole("generic", { @@ -178,15 +229,13 @@ test("GIVEN ServiceInstanceForm WHEN passed a TextField with parameter suggestio expect(suggestions).toHaveLength(3); - server.close(); + server.resetHandlers(); }); test("GIVEN ServiceInstanceForm WHEN passed a TextField with parameter suggestions AND no parameters could be retrieved THEN shows that field without suggestions", async () => { // Provide the server-side API with the request handlers. const server = setupServer( - http.get("/api/v1/parameter/:id", ({ params }) => { - expect(params.id).toEqual("param_name"); - + http.get("/api/v1/parameter/param_name", () => { return HttpResponse.error(); }), ); @@ -196,7 +245,7 @@ test("GIVEN ServiceInstanceForm WHEN passed a TextField with parameter suggestio const { component } = setup([Test.Field.textSuggestions2]); - render(createQuerryWrapper(component)); + render(createQueryWrapper(component)); expect( screen.getByRole("generic", { @@ -214,8 +263,6 @@ test("GIVEN ServiceInstanceForm WHEN passed a TextField with parameter suggestio const suggestions = screen.queryAllByRole("menuitem"); expect(suggestions).toHaveLength(0); - - server.close(); }); test("GIVEN ServiceInstanceForm WHEN passed a BooleanField THEN shows that field", async () => { diff --git a/src/UI/Components/ServiceProvider/ServiceProvider.tsx b/src/UI/Components/ServiceProvider/ServiceProvider.tsx index e0e887bb3..1991bef96 100644 --- a/src/UI/Components/ServiceProvider/ServiceProvider.tsx +++ b/src/UI/Components/ServiceProvider/ServiceProvider.tsx @@ -1,9 +1,8 @@ -import React, { useContext } from "react"; +import React from "react"; import { ServiceModel } from "@/Core"; import { useGetServiceModel } from "@/Data/Managers/V2/GETTERS/GetServiceModel"; import { ErrorView } from "@/UI/Components/ErrorView"; import { LoadingView } from "@/UI/Components/LoadingView"; -import { DependencyContext } from "@/UI/Dependency"; interface Props { serviceName: string; @@ -16,12 +15,8 @@ export const ServiceProvider: React.FunctionComponent = ({ Wrapper, Dependant, }) => { - const { environmentHandler } = useContext(DependencyContext); - const env = environmentHandler.useId(); - const { data, isError, error, isSuccess, refetch } = useGetServiceModel( - serviceName, - env, - ).useContinuous(); + const { data, isError, error, isSuccess, refetch } = + useGetServiceModel(serviceName).useContinuous(); if (isError) { diff --git a/src/UI/Components/ServicesProvider/ServicesProvider.tsx b/src/UI/Components/ServicesProvider/ServicesProvider.tsx index 41df42f75..020e3f8ef 100644 --- a/src/UI/Components/ServicesProvider/ServicesProvider.tsx +++ b/src/UI/Components/ServicesProvider/ServicesProvider.tsx @@ -1,9 +1,8 @@ -import React, { useContext } from "react"; +import React from "react"; import { ServiceModel } from "@/Core"; import { useGetServiceModels } from "@/Data/Managers/V2/GETTERS/GetServiceModels"; import { ErrorView } from "@/UI/Components/ErrorView"; import { LoadingView } from "@/UI/Components/LoadingView"; -import { DependencyContext } from "@/UI/Dependency"; interface Props { serviceName: string; @@ -16,10 +15,8 @@ export const ServicesProvider: React.FunctionComponent = ({ Wrapper, Dependant, }) => { - const { environmentHandler } = useContext(DependencyContext); - const env = environmentHandler.useId(); const { data, isError, error, isSuccess, refetch } = - useGetServiceModels(env).useContinuous(); + useGetServiceModels().useContinuous(); if (isError) { diff --git a/src/UI/Components/TreeTable/TreeRow/CellWithCopyExpert.test.tsx b/src/UI/Components/TreeTable/TreeRow/CellWithCopyExpert.test.tsx index e7079ecd5..b16ba1823 100644 --- a/src/UI/Components/TreeTable/TreeRow/CellWithCopyExpert.test.tsx +++ b/src/UI/Components/TreeTable/TreeRow/CellWithCopyExpert.test.tsx @@ -28,6 +28,7 @@ import { } from "@/UI/Dependency"; import { ModalProvider } from "@/UI/Root/Components/ModalProvider"; import { CellWithCopyExpert } from "./CellWithCopyExpert"; +import { halted } from "@/Test/Data/EnvironmentDetails"; function setup(props, expertMode = false) { const store = getStoreInstance(); @@ -59,6 +60,7 @@ function setup(props, expertMode = false) { repo_branch: "branch", repo_url: "repo", projectName: "project", + halted: false, settings: { enable_lsm_expert_mode: expertMode, }, diff --git a/src/UI/Root/Components/Header/EnvSelector/EnvironmentSelector.test.tsx b/src/UI/Root/Components/Header/EnvSelector/EnvironmentSelector.test.tsx index 5e10a447d..b4657390b 100644 --- a/src/UI/Root/Components/Header/EnvSelector/EnvironmentSelector.test.tsx +++ b/src/UI/Root/Components/Header/EnvSelector/EnvironmentSelector.test.tsx @@ -1,16 +1,22 @@ import React from "react"; -import { MemoryRouter } from "react-router"; +import { MemoryRouter, useLocation } from "react-router"; import { Router } from "react-router-dom"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { render, screen, waitFor } from "@testing-library/react"; import { userEvent } from "@testing-library/user-event"; +import { StoreProvider } from "easy-peasy"; import { createMemoryHistory } from "history"; import { HttpResponse, http } from "msw"; import { setupServer } from "msw/node"; import { FlatEnvironment, RemoteData } from "@/Core"; -import { AuthProvider, KeycloakAuthConfig, LocalConfig } from "@/Data"; +import { + AuthProvider, + getStoreInstance, + KeycloakAuthConfig, + LocalConfig, +} from "@/Data"; import { AuthTestWrapper, Environment, dependencies } from "@/Test"; -import { DependencyProvider } from "@/UI/Dependency"; +import { DependencyProvider, EnvironmentHandlerImpl } from "@/UI/Dependency"; import ErrorBoundary from "@/UI/Utils/ErrorBoundary"; import { EnvSelectorWithData as EnvironmentSelector } from "./EnvSelectorWithData"; import { EnvironmentSelectorItem } from "./EnvSelectorWrapper"; @@ -21,20 +27,45 @@ const setup = ( environments: FlatEnvironment[] = Environment.filterable, ) => { const queryClient = new QueryClient(); + const environmentHandler = EnvironmentHandlerImpl( + useLocation, + dependencies.routeManager, + ); + const store = getStoreInstance(); + + store.dispatch.environment.setEnvironments(RemoteData.success(environments)); + + store.dispatch.environment.setEnvironmentDetailsById({ + id: "123", + value: RemoteData.success(Environment.filterable[0]), + }); return ( - + - - - - - + + + + + + + + + diff --git a/src/UI/Root/Components/PageFrame/PageFrame.tsx b/src/UI/Root/Components/PageFrame/PageFrame.tsx index c3985b8e2..3436f3148 100644 --- a/src/UI/Root/Components/PageFrame/PageFrame.tsx +++ b/src/UI/Root/Components/PageFrame/PageFrame.tsx @@ -26,7 +26,7 @@ export const PageFrame: React.FC> = ({ return ( <>
- {environmentId && } + {environmentId && }