diff --git a/src/headless/index.ts b/src/headless/index.ts index beb412502..a92c66343 100644 --- a/src/headless/index.ts +++ b/src/headless/index.ts @@ -6,6 +6,7 @@ export { useConnection } from "./useConnection"; // Installation Hooks export { useInstallation } from "./installation/useInstallation"; +export { useInstallationValidation } from "./installation/useInstallationValidation"; export { useCreateInstallation } from "./installation/useCreateInstallation"; export { useUpdateInstallation } from "./installation/useUpdateInstallation"; export { useDeleteInstallation } from "./installation/useDeleteInstallation"; diff --git a/src/headless/installation/useCreateInstallation.ts b/src/headless/installation/useCreateInstallation.ts index 2156d0fe6..bd121f9c2 100644 --- a/src/headless/installation/useCreateInstallation.ts +++ b/src/headless/installation/useCreateInstallation.ts @@ -13,11 +13,14 @@ import { useInstallationProps } from "../InstallationProvider"; import { useConnection } from "../useConnection"; import { useInstallation } from "./useInstallation"; +import { useInstallationValidation } from "./useInstallationValidation"; /** * create installation hook * @returns {Object} An object containing: * - `createInstallation` (function): A function to create the installation. + * - `canCreate` (boolean): Whether a new installation can be created. + * - `validationErrors` (Object): Detailed validation error information. * - `isIdle` (boolean): Whether the mutation is idle. * - `isPending` (boolean): Whether the mutation is pending. * - `error` (Error | null): The error object, if any. @@ -29,6 +32,7 @@ export function useCreateInstallation() { const { data: integrationObj } = useIntegrationQuery(integrationNameOrId); const { connection } = useConnection(); const { installation } = useInstallation(); + const { canCreate, validationErrors } = useInstallationValidation(); const queryClient = useQueryClient(); const { mutate: createInstallationMutation, @@ -86,6 +90,8 @@ export function useCreateInstallation() { return { createInstallation, + canCreate, + validationErrors, isIdle, isPending, error, diff --git a/src/headless/installation/useDeleteInstallation.ts b/src/headless/installation/useDeleteInstallation.ts index 08783489d..9bba5a75f 100644 --- a/src/headless/installation/useDeleteInstallation.ts +++ b/src/headless/installation/useDeleteInstallation.ts @@ -6,11 +6,14 @@ import { useIntegrationQuery } from "src/hooks/query/useIntegrationQuery"; import { useInstallationProps } from "../InstallationProvider"; import { useInstallation } from "./useInstallation"; +import { useInstallationValidation } from "./useInstallationValidation"; /** * delete installation hook * @returns {Object} An object containing: * - `deleteInstallation` (function): A function to delete the installation. + * - `canDelete` (boolean): Whether the installation can be deleted. + * - `validationErrors` (Object): Detailed validation error information. * - `isIdle` (boolean): Whether the mutation is idle. * - `isPending` (boolean): Whether the mutation is pending. * - `error` (Error | null): The error object, if any. @@ -21,6 +24,7 @@ export function useDeleteInstallation() { const { integrationNameOrId } = useInstallationProps(); const { data: integrationObj } = useIntegrationQuery(integrationNameOrId); const { installation } = useInstallation(); + const { canDelete, validationErrors } = useInstallationValidation(); const queryClient = useQueryClient(); const { mutate: deleteInstallationMutation, @@ -74,6 +78,8 @@ export function useDeleteInstallation() { return { deleteInstallation, + canDelete, + validationErrors, isIdle, isPending, error, diff --git a/src/headless/installation/useInstallationValidation.ts b/src/headless/installation/useInstallationValidation.ts new file mode 100644 index 000000000..b856c61a6 --- /dev/null +++ b/src/headless/installation/useInstallationValidation.ts @@ -0,0 +1,34 @@ +import { useIntegrationQuery } from "src/hooks/query/useIntegrationQuery"; + +import { useInstallationProps } from "../InstallationProvider"; + +import { useInstallation } from "./useInstallation"; + +/** + * Validation hook that checks prerequisites for installation mutations + * @returns {Object} An object containing: + * - `canCreate` (boolean): Whether a new installation can be created + * - `canUpdate` (boolean): Whether an existing installation can be updated + * - `canDelete` (boolean): Whether an existing installation can be deleted + * - `validationErrors` (Object): Detailed validation error information + */ +export function useInstallationValidation() { + const { integrationNameOrId } = useInstallationProps(); + const { data: integrationObj } = useIntegrationQuery(integrationNameOrId); + const { installation } = useInstallation(); + + const validationErrors = { + noIntegration: !integrationObj, + installationExists: !!installation, + noInstallation: !installation, + }; + + return { + canCreate: !validationErrors.installationExists && !validationErrors.noIntegration, + canUpdate: !validationErrors.noInstallation && !validationErrors.noIntegration, + canDelete: !validationErrors.noInstallation && !validationErrors.noIntegration, + validationErrors, + installation, + integrationObj, + }; +} diff --git a/src/headless/installation/useUpdateInstallation.ts b/src/headless/installation/useUpdateInstallation.ts index 52bae5c64..1608eee39 100644 --- a/src/headless/installation/useUpdateInstallation.ts +++ b/src/headless/installation/useUpdateInstallation.ts @@ -12,11 +12,14 @@ import { toUpdateConfigContent } from "../config/types"; import { useInstallationProps } from "../InstallationProvider"; import { useInstallation } from "./useInstallation"; +import { useInstallationValidation } from "./useInstallationValidation"; /** * update installation hook * @returns {Object} An object containing: * - `updateInstallation` (function): A function to update the installation. + * - `canUpdate` (boolean): Whether the installation can be updated. + * - `validationErrors` (Object): Detailed validation error information. * - `isIdle` (boolean): Whether the mutation is idle. * - `isPending` (boolean): Whether the mutation is pending. * - `error` (Error | null): The error object, if any. @@ -27,6 +30,7 @@ export function useUpdateInstallation() { const { integrationNameOrId } = useInstallationProps(); const { data: integrationObj } = useIntegrationQuery(integrationNameOrId); const { installation } = useInstallation(); + const { canUpdate, validationErrors } = useInstallationValidation(); const queryClient = useQueryClient(); const { mutate: updateInstallationMutation, @@ -115,6 +119,8 @@ export function useUpdateInstallation() { return { updateInstallation, + canUpdate, + validationErrors, isIdle, isPending, error,