feature/IO-3225-Notifications-1.5: DB Changes

This commit is contained in:
Dave Richer
2025-05-05 15:02:44 -04:00
parent 2deb7fd520
commit 8109a12898
8 changed files with 292 additions and 20 deletions

View File

@@ -1,12 +1,16 @@
import { useMutation, useQuery } from "@apollo/client";
import { useEffect, useState } from "react";
import { Button, Card, Checkbox, Form, Space, Table } from "antd";
import { Button, Card, Checkbox, Form, Space, Switch, Table } from "antd";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectCurrentUser } from "../../redux/user/user.selectors";
import AlertComponent from "../alert/alert.component";
import { QUERY_NOTIFICATION_SETTINGS, UPDATE_NOTIFICATION_SETTINGS } from "../../graphql/user.queries.js";
import {
QUERY_NOTIFICATION_SETTINGS,
UPDATE_NOTIFICATION_SETTINGS,
UPDATE_NOTIFICATIONS_AUTOADD
} from "../../graphql/user.queries.js";
import { notificationScenarios } from "../../utils/jobNotificationScenarios.js";
import LoadingSpinner from "../loading-spinner/loading-spinner.component.jsx";
import PropTypes from "prop-types";
@@ -24,9 +28,11 @@ const NotificationSettingsForm = ({ currentUser }) => {
const [form] = Form.useForm();
const [initialValues, setInitialValues] = useState({});
const [isDirty, setIsDirty] = useState(false);
const [autoAddEnabled, setAutoAddEnabled] = useState(false);
const [initialAutoAdd, setInitialAutoAdd] = useState(false);
const notification = useNotification();
// Fetch notification settings.
// Fetch notification settings and notifications_autoadd
const { loading, error, data } = useQuery(QUERY_NOTIFICATION_SETTINGS, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
@@ -34,13 +40,16 @@ const NotificationSettingsForm = ({ currentUser }) => {
skip: !currentUser
});
const [updateNotificationSettings, { loading: saving }] = useMutation(UPDATE_NOTIFICATION_SETTINGS);
const [updateNotificationSettings, { loading: savingSettings }] = useMutation(UPDATE_NOTIFICATION_SETTINGS);
const [updateNotificationsAutoAdd, { loading: savingAutoAdd }] = useMutation(UPDATE_NOTIFICATIONS_AUTOADD);
// Populate form with fetched data.
// Populate form with fetched data
useEffect(() => {
if (data?.associations?.length > 0) {
const settings = data.associations[0].notification_settings || {};
// Ensure each scenario has an object with { app, email, fcm }.
const autoAdd = data.associations[0].notifications_autoadd ?? false;
// Ensure each scenario has an object with { app, email, fcm }
const formattedValues = notificationScenarios.reduce((acc, scenario) => {
acc[scenario] = settings[scenario] ?? { app: false, email: false, fcm: false };
return acc;
@@ -48,32 +57,66 @@ const NotificationSettingsForm = ({ currentUser }) => {
setInitialValues(formattedValues);
form.setFieldsValue(formattedValues);
setIsDirty(false); // Reset dirty state when new data loads.
setAutoAddEnabled(autoAdd);
setInitialAutoAdd(autoAdd);
setIsDirty(false); // Reset dirty state when new data loads
}
}, [data, form]);
// Handle toggle of notifications_autoadd
const handleAutoAddToggle = async (checked) => {
if (data?.associations?.length > 0) {
const userId = data.associations[0].id;
try {
const result = await updateNotificationsAutoAdd({
variables: { id: userId, autoadd: checked }
});
if (!result?.errors) {
setAutoAddEnabled(checked);
setInitialAutoAdd(checked);
notification.success({ message: t("notifications.labels.auto-add-success") });
setIsDirty(false); // Reset dirty state if only auto-add was changed
} else {
throw new Error("Failed to update auto-add setting");
}
} catch (err) {
setAutoAddEnabled(!checked); // Revert on error
notification.error({ message: t("notifications.labels.auto-add-failure") });
}
}
};
// Handle save of notification settings
const handleSave = async (values) => {
if (data?.associations?.length > 0) {
const userId = data.associations[0].id;
// Save the updated notification settings.
const result = await updateNotificationSettings({ variables: { id: userId, ns: values } });
if (!result?.errors) {
notification.success({ message: t("notifications.labels.notification-settings-success") });
setInitialValues(values);
setIsDirty(false);
} else {
try {
const result = await updateNotificationSettings({ variables: { id: userId, ns: values } });
if (!result?.errors) {
notification.success({ message: t("notifications.labels.notification-settings-success") });
setInitialValues(values);
setIsDirty(false);
} else {
throw new Error("Failed to update notification settings");
}
} catch (err) {
notification.error({ message: t("notifications.labels.notification-settings-failure") });
}
}
};
// Mark the form as dirty on any manual change.
// Mark the form as dirty on any manual change
const handleFormChange = () => {
setIsDirty(true);
};
// Check if auto-add has changed
const isAutoAddDirty = autoAddEnabled !== initialAutoAdd;
// Handle reset of form and auto-add
const handleReset = () => {
form.setFieldsValue(initialValues);
setAutoAddEnabled(initialAutoAdd);
setIsDirty(false);
};
@@ -139,11 +182,17 @@ const NotificationSettingsForm = ({ currentUser }) => {
title={t("notifications.labels.notificationscenarios")}
extra={
<Space>
<Button type="default" onClick={handleReset} disabled={!isDirty}>
<Switch
checked={autoAddEnabled}
onChange={handleAutoAddToggle}
loading={savingAutoAdd}
checkedChildren={t("notifications.labels.auto-add-on")}
unCheckedChildren={t("notifications.labels.auto-add-off")}
/>
<Button type="default" onClick={handleReset} disabled={!isDirty && !isAutoAddDirty}>
{t("general.actions.clear")}
</Button>
<Button type="primary" htmlType="submit" disabled={!isDirty} loading={saving}>
<Button type="primary" htmlType="submit" disabled={!isDirty} loading={savingSettings}>
{t("notifications.labels.save")}
</Button>
</Space>