diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanMilestoneItem/milestoneStatusUtils.ts b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanMilestoneItem/milestoneStatusUtils.ts
index 6186aeef02..3a3bfe4f1e 100644
--- a/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanMilestoneItem/milestoneStatusUtils.ts
+++ b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanMilestoneItem/milestoneStatusUtils.ts
@@ -1,5 +1,8 @@
import type { IReleasePlanMilestone } from 'interfaces/releasePlans';
-import type { MilestoneStatus } from '../ReleasePlanMilestone/ReleasePlanMilestoneStatus.tsx';
+import type {
+ MilestoneStatus,
+ MilestoneProgressionStatus,
+} from '../ReleasePlanMilestone/ReleasePlanMilestoneStatus.tsx';
import { calculateMilestoneStartTime } from '../utils/calculateMilestoneStartTime.js';
export const calculateMilestoneStatus = (
@@ -10,16 +13,18 @@ export const calculateMilestoneStatus = (
environmentIsDisabled: boolean | undefined,
allMilestones: IReleasePlanMilestone[],
): MilestoneStatus => {
- if (milestone.pausedAt) {
- return { type: 'paused' };
- }
+ const progression: MilestoneProgressionStatus = milestone.pausedAt
+ ? 'paused'
+ : 'active';
if (milestone.id === activeMilestoneId) {
- return environmentIsDisabled ? { type: 'paused' } : { type: 'active' };
+ return environmentIsDisabled
+ ? { type: 'paused', progression }
+ : { type: 'active', progression };
}
if (index < activeIndex) {
- return { type: 'completed' };
+ return { type: 'completed', progression };
}
const scheduledAt = calculateMilestoneStartTime(
@@ -31,5 +36,6 @@ export const calculateMilestoneStatus = (
return {
type: 'not-started',
scheduledAt: scheduledAt || undefined,
+ progression,
};
};
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 aa74caeb58..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');
}
};
@@ -232,80 +246,92 @@ export const SafeguardForm = ({
)}
-
+
- filtered by
-
-
- handleApplicationChange(String(e.target.value))
- }
- variant='outlined'
- size='small'
- >
- {applicationNames.map((app) => (
-
- {app === '*' ? 'All' : app}
-
- ))}
-
-
+
+ filtered by
+
+
+ handleApplicationChange(String(e.target.value))
+ }
+ variant='outlined'
+ size='small'
+ >
+ {applicationNames.map((app) => (
+
+ {app === '*' ? 'All' : app}
+
+ ))}
+
+
+
- aggregated by
-
-
-
- is
-
-
- handleOperatorChange(
- e.target.value as CreateSafeguardSchemaOperator,
- )
- }
- variant='outlined'
- size='small'
- >
- More than
- Less than
-
-
-
-
- {
- const value = e.target.value;
- handleThresholdChange(Number(value));
- }}
- placeholder='Value'
- variant='outlined'
- size='small'
- required
+
+ aggregated by
+
-
+
+
+
+
+ is
+
+
+ handleOperatorChange(
+ e.target
+ .value as CreateSafeguardSchemaOperator,
+ )
+ }
+ variant='outlined'
+ size='small'
+ >
+ More than
+ Less than
+
+
- over
-
+
+ {
+ const value = e.target.value;
+ handleThresholdChange(Number(value));
+ }}
+ placeholder='Value'
+ variant='outlined'
+ size='small'
+ required
+ />
+
+
+
+
+ over
+
+
{showButtons && (
diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/hooks/useMilestoneProgressionInfo.ts b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/hooks/useMilestoneProgressionInfo.ts
index 2f986f3769..348ee7b310 100644
--- a/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/hooks/useMilestoneProgressionInfo.ts
+++ b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/hooks/useMilestoneProgressionInfo.ts
@@ -8,7 +8,11 @@ export const useMilestoneProgressionInfo = (
status?: MilestoneStatus,
) => {
const { locationSettings } = useLocationSettings();
- if (!status || status.type !== 'active') {
+ if (
+ !status ||
+ status.type !== 'active' ||
+ status.progression === 'paused'
+ ) {
return null;
}
diff --git a/frontend/src/component/impact-metrics/ChartConfigModal/ImpactMetricsControls/ModeSelector/ModeSelector.tsx b/frontend/src/component/impact-metrics/ChartConfigModal/ImpactMetricsControls/ModeSelector/ModeSelector.tsx
index 5ec8e97e9f..a8bbe5021c 100644
--- a/frontend/src/component/impact-metrics/ChartConfigModal/ImpactMetricsControls/ModeSelector/ModeSelector.tsx
+++ b/frontend/src/component/impact-metrics/ChartConfigModal/ImpactMetricsControls/ModeSelector/ModeSelector.tsx
@@ -6,22 +6,26 @@ export type ModeSelectorProps = {
value: AggregationMode;
onChange: (mode: AggregationMode) => void;
metricType: 'counter' | 'gauge' | 'histogram' | 'unknown';
+ label?: string;
};
export const ModeSelector: FC = ({
value,
onChange,
metricType,
+ label = 'Aggregation Mode',
}) => {
if (metricType === 'unknown') return null;
return (
- Mode
+ {label ? (
+ {label}
+ ) : null}