diff --git a/src/app/policyEngine/components/AddPolicyEngine.tsx b/src/app/policyEngine/components/AddPolicyEngine.tsx
index 6374399..55cb704 100644
--- a/src/app/policyEngine/components/AddPolicyEngine.tsx
+++ b/src/app/policyEngine/components/AddPolicyEngine.tsx
@@ -530,9 +530,44 @@ export default function AddPolicyEngine() {
.finally(() => setLoadingPolicy(false));
}, [policyId]);
+ const isFormValid = (() => {
+ if (!policyName.trim()) return false;
+
+ if (audienceType === 'Selected Cohorts' && (!selectedCohorts || selectedCohorts.length === 0)) return false;
+
+ if (!rules || rules.length === 0) return false;
+
+ for (const rule of rules) {
+ if (!rule.category) return false;
+
+ if (!rule.conditions || rule.conditions.length === 0) return false;
+ for (const cond of rule.conditions) {
+ if (!cond.condition || !cond.operator || cond.value === '' || cond.value === undefined || cond.value === null) return false;
+ }
+
+ if (!rule.actions || rule.actions.length === 0) return false;
+ for (const act of rule.actions) {
+ if (!act.actionCategoryId || !act.actionTypeId) return false;
+
+ const fields = actionTypeFieldsMap[act.actionTypeId] || [];
+ for (const field of fields) {
+ if (field.isRequired) {
+ const val = act.fieldValues?.[field.fieldCode];
+ if (val === undefined || val === null || val === '') return false;
+ if (Array.isArray(val) && val.length === 0) return false;
+ if (typeof val === 'object' && !Array.isArray(val)) {
+ if (val.amount === undefined || val.amount === null || val.amount === '') return false;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ })();
+
const handleSavePolicy = async (isDeploy: boolean) => {
- if (!policyName.trim()) {
- alert('Please enter a Policy Name.');
+ if (!isFormValid) {
return;
}
@@ -1337,9 +1372,9 @@ export default function AddPolicyEngine() {
{!isEditMode && (
handleSavePolicy(false)}
- disabled={isSaving}
+ disabled={isSaving || !isFormValid}
>
{isSaving ? 'Saving...' : 'Save Draft'}
@@ -1354,9 +1389,9 @@ export default function AddPolicyEngine() {
handleSavePolicy(true)}
- disabled={isSaving}
+ disabled={isSaving || !isFormValid}
>
{isSaving ? 'Deploying...' : isEditMode ? 'Update & Deploy Policy' : 'Deploy Policy'}
diff --git a/src/app/recoveryIncidents/components/RecoveryIncidentsList.tsx b/src/app/recoveryIncidents/components/RecoveryIncidentsList.tsx
index 43f87c0..43ca927 100644
--- a/src/app/recoveryIncidents/components/RecoveryIncidentsList.tsx
+++ b/src/app/recoveryIncidents/components/RecoveryIncidentsList.tsx
@@ -95,12 +95,6 @@ export default function RecoveryIncidentsList() {
const [error, setError] = useState(null);
const [successMsg, setSuccessMsg] = useState(null);
- useEffect(() => {
- getRecoveryMetrics()
- .then((data) => setMetrics(data))
- .catch((err) => console.error("Failed to fetch recovery metrics:", err));
- }, []);
-
// Pagination
const [currentPage, setCurrentPage] = useState(1);
@@ -143,6 +137,9 @@ export default function RecoveryIncidentsList() {
try {
const data = await getRecoveryIncidents();
setIncidents(data);
+ getRecoveryMetrics()
+ .then((m) => setMetrics(m))
+ .catch((err) => console.error("Failed to fetch recovery metrics:", err));
} catch (error) {
console.error("Failed to fetch recovery incidents", error);
setIncidents([]);
@@ -213,10 +210,9 @@ export default function RecoveryIncidentsList() {
try {
setError(null);
setSuccessMsg(null);
- const { updateIncidentStatus, getRecoveryMetrics } = await import('../RecoveryIncidentsApi');
+ const { updateIncidentStatus } = await import('../RecoveryIncidentsApi');
await updateIncidentStatus(incident.id, text);
fetchIncidents();
- getRecoveryMetrics().then((data) => setMetrics(data)).catch(() => { });
setSuccessMsg(`Incident status updated to ${text} successfully.`);
} catch (error) {
console.error("Failed to update status", error);