diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/EnvironmentAccordionBody.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/EnvironmentAccordionBody.tsx
index acfe27e1a7..b4e1dcf065 100644
--- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/EnvironmentAccordionBody.tsx
+++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/EnvironmentAccordionBody.tsx
@@ -66,7 +66,7 @@ export const EnvironmentAccordionBody = ({
const [strategies, setStrategies] = useState(
featureEnvironment?.strategies || [],
);
- const { releasePlans } = useFeatureReleasePlans(
+ const { releasePlans, refetch } = useFeatureReleasePlans(
projectId,
featureId,
featureEnvironment?.name,
@@ -229,6 +229,7 @@ export const EnvironmentAccordionBody = ({
))}
diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlan.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlan.tsx
index 2695640346..c721d84ae1 100644
--- a/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlan.tsx
+++ b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlan.tsx
@@ -4,7 +4,6 @@ import PlayCircle from '@mui/icons-material/PlayCircle';
import { DELETE_FEATURE_STRATEGY } from '@server/types/permissions';
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
import { useReleasePlansApi } from 'hooks/api/actions/useReleasePlansApi/useReleasePlansApi';
-import { useFeatureReleasePlans } from 'hooks/api/getters/useFeatureReleasePlans/useFeatureReleasePlans';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import useToast from 'hooks/useToast';
import type {
@@ -32,7 +31,10 @@ import { ReleasePlanMilestoneItem } from './ReleasePlanMilestoneItem/ReleasePlan
import Add from '@mui/icons-material/Add';
import { StyledActionButton } from './ReleasePlanMilestoneItem/StyledActionButton.tsx';
-import { SafeguardForm } from './SafeguardForm/SafeguardForm.tsx';
+import {
+ SafeguardForm,
+ useSafeguardForm,
+} from './SafeguardForm/SafeguardForm.tsx';
import { useSafeguardsApi } from 'hooks/api/actions/useSafeguardsApi/useSafeguardsApi';
import type { CreateSafeguardSchema } from 'openapi/models/createSafeguardSchema';
import { DeleteSafeguardDialog } from './DeleteSafeguardDialog.tsx';
@@ -120,12 +122,14 @@ interface IReleasePlanProps {
plan: IReleasePlan;
environmentIsDisabled?: boolean;
readonly?: boolean;
+ onAutomationChange?: () => void;
}
export const ReleasePlan = ({
plan,
environmentIsDisabled,
readonly,
+ onAutomationChange,
}: IReleasePlanProps) => {
const {
id,
@@ -139,8 +143,6 @@ export const ReleasePlan = ({
} = plan;
const projectId = useRequiredPathParam('projectId');
- const { refetch, loading: featureReleasePlansLoading } =
- useFeatureReleasePlans(projectId, featureName, environment);
const { removeReleasePlanFromFeature, startReleasePlanMilestone } =
useReleasePlansApi();
const {
@@ -221,9 +223,11 @@ export const ReleasePlan = ({
>(null);
const [milestoneToDeleteProgression, setMilestoneToDeleteProgression] =
useState(null);
- const [safeguardFormOpen, setSafeguardFormOpen] = useState(false);
+
const [safeguardDeleteDialogOpen, setSafeguardDeleteDialogOpen] =
useState(false);
+ const { safeguardFormOpen, setSafeguardFormOpen } =
+ useSafeguardForm(safeguards);
const onChangeRequestConfirm = async () => {
if (!changeRequestAction) return;
@@ -311,7 +315,7 @@ export const ReleasePlan = ({
type: 'success',
});
- refetch();
+ onAutomationChange?.();
setRemoveOpen(false);
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
@@ -337,7 +341,7 @@ export const ReleasePlan = ({
text: `Milestone "${milestone.name}" has started`,
type: 'success',
});
- refetch();
+ onAutomationChange?.();
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
@@ -387,7 +391,7 @@ export const ReleasePlan = ({
featureName,
sourceMilestoneId: milestoneToDeleteProgression.id,
});
- await refetch();
+ onAutomationChange?.();
setMilestoneToDeleteProgression(null);
setToastData({
type: 'success',
@@ -411,7 +415,7 @@ export const ReleasePlan = ({
type: 'success',
text: 'Automation resumed successfully',
});
- refetch();
+ onAutomationChange?.();
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
@@ -434,11 +438,9 @@ export const ReleasePlan = ({
type: 'success',
text: 'Safeguard added successfully',
});
- refetch();
+ onAutomationChange?.();
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
- } finally {
- setSafeguardFormOpen(false);
}
};
@@ -461,7 +463,7 @@ export const ReleasePlan = ({
type: 'success',
text: 'Safeguard deleted successfully',
});
- refetch();
+ onAutomationChange?.();
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
} finally {
@@ -529,20 +531,15 @@ export const ReleasePlan = ({
) : null}
- {safeguardsEnabled ? (
+ {onAutomationChange && safeguardsEnabled ? (
- {safeguards.length > 0 ? (
+ {safeguardFormOpen ? (
setSafeguardFormOpen(false)}
onDelete={handleSafeguardDelete}
/>
- ) : safeguardFormOpen || featureReleasePlansLoading ? (
- setSafeguardFormOpen(false)}
- />
) : (
setSafeguardFormOpen(true)}
@@ -582,7 +579,7 @@ export const ReleasePlan = ({
projectId={projectId}
environment={environment}
featureName={featureName}
- onUpdate={refetch}
+ onUpdate={onAutomationChange}
/>
))}
diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanMilestoneItem/ReleasePlanMilestoneItem.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanMilestoneItem/ReleasePlanMilestoneItem.tsx
index d1b1f8c38a..9cbe107780 100644
--- a/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanMilestoneItem/ReleasePlanMilestoneItem.tsx
+++ b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanMilestoneItem/ReleasePlanMilestoneItem.tsx
@@ -52,7 +52,7 @@ export interface IReleasePlanMilestoneItemProps {
projectId: string;
environment: string;
featureName: string;
- onUpdate: () => void | Promise;
+ onUpdate?: () => void;
}
const getTimeUnit = (intervalMinutes: number): 'minutes' | 'hours' | 'days' => {
@@ -134,7 +134,7 @@ export const ReleasePlanMilestoneItem = ({
text: 'Automation configured successfully',
});
handleCloseProgressionForm();
- await onUpdate();
+ onUpdate?.();
return {};
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/SafeguardForm/SafeguardForm.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/SafeguardForm/SafeguardForm.tsx
index 876a932b24..db86b751f1 100644
--- a/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/SafeguardForm/SafeguardForm.tsx
+++ b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/SafeguardForm/SafeguardForm.tsx
@@ -26,6 +26,20 @@ import type { ISafeguard } from 'interfaces/releasePlans.ts';
const StyledIcon = createStyledIcon(ShieldIcon);
+export const useSafeguardForm = (safeguards: ISafeguard[] | undefined) => {
+ const [safeguardFormOpen, setSafeguardFormOpen] = useState(false);
+
+ useEffect(() => {
+ if (safeguards && safeguards.length > 0) {
+ setSafeguardFormOpen(true);
+ } else {
+ setSafeguardFormOpen(false);
+ }
+ }, [JSON.stringify(safeguards)]);
+
+ return { safeguardFormOpen, setSafeguardFormOpen };
+};
+
interface ISafeguardFormProps {
onSubmit: (data: CreateSafeguardSchema) => void;
onCancel: () => void;
@@ -182,7 +196,7 @@ export const SafeguardForm = ({
threshold: Number(threshold),
});
- if (mode === 'edit') {
+ if (mode === 'edit' || mode === 'create') {
setMode('display');
}
};