feature/IO-3096-GlobalNotifications - Checkpoint - Splits are now in place

This commit is contained in:
Dave Richer
2025-03-03 11:41:10 -05:00
parent b5c03b8cf0
commit 35b92570e5
5 changed files with 85 additions and 34 deletions

View File

@@ -48,6 +48,8 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline
const { t } = useTranslation(); const { t } = useTranslation();
const navigate = useNavigate(); const navigate = useNavigate();
const scenarioNotificationsOn = client?.getTreatment("Realtime_Notifications_UI") === "on";
useEffect(() => { useEffect(() => {
if (!navigator.onLine) { if (!navigator.onLine) {
setOnline(false); setOnline(false);
@@ -201,7 +203,12 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline
path="/manage/*" path="/manage/*"
element={ element={
<ErrorBoundary> <ErrorBoundary>
<SocketProvider bodyshop={bodyshop} navigate={navigate} currentUser={currentUser}> <SocketProvider
bodyshop={bodyshop}
navigate={navigate}
currentUser={currentUser}
scenarioNotificationsOn={scenarioNotificationsOn}
>
<PrivateRoute isAuthorized={currentUser.authorized} /> <PrivateRoute isAuthorized={currentUser.authorized} />
</SocketProvider> </SocketProvider>
</ErrorBoundary> </ErrorBoundary>
@@ -213,7 +220,12 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline
path="/tech/*" path="/tech/*"
element={ element={
<ErrorBoundary> <ErrorBoundary>
<SocketProvider bodyshop={bodyshop} navigate={navigate} currentUser={currentUser}> <SocketProvider
bodyshop={bodyshop}
navigate={navigate}
currentUser={currentUser}
scenarioNotificationsOn={scenarioNotificationsOn}
>
<PrivateRoute isAuthorized={currentUser.authorized} /> <PrivateRoute isAuthorized={currentUser.authorized} />
</SocketProvider> </SocketProvider>
</ErrorBoundary> </ErrorBoundary>

View File

@@ -93,10 +93,11 @@ function Header({
}); });
const { t } = useTranslation(); const { t } = useTranslation();
const { isConnected } = useSocket(); const { isConnected, scenarioNotificationsOn } = useSocket();
const [notificationVisible, setNotificationVisible] = useState(false); const [notificationVisible, setNotificationVisible] = useState(false);
const userAssociationId = bodyshop?.associations?.[0]?.id; const userAssociationId = bodyshop?.associations?.[0]?.id;
const { const {
data: unreadData, data: unreadData,
refetch: refetchUnread, refetch: refetchUnread,
@@ -105,7 +106,7 @@ function Header({
variables: { associationid: userAssociationId }, variables: { associationid: userAssociationId },
fetchPolicy: "network-only", fetchPolicy: "network-only",
pollInterval: isConnected ? 0 : day.duration(60, "seconds").asMilliseconds(), pollInterval: isConnected ? 0 : day.duration(60, "seconds").asMilliseconds(),
skip: !userAssociationId skip: !userAssociationId || !scenarioNotificationsOn
}); });
const unreadCount = unreadData?.notifications_aggregate?.aggregate?.count ?? 0; const unreadCount = unreadData?.notifications_aggregate?.aggregate?.count ?? 0;
@@ -647,20 +648,22 @@ function Header({
]; ];
// Notifications item (always on the right) // Notifications item (always on the right)
const notificationItem = [ const notificationItem = scenarioNotificationsOn
{ ? [
key: "notifications", {
id: "header-notifications", key: "notifications",
icon: unreadLoading ? ( id: "header-notifications",
<Spin size="small" /> icon: unreadLoading ? (
) : ( <Spin size="small" />
<Badge count={unreadCount}> ) : (
<BellFilled /> <Badge count={unreadCount}>
</Badge> <BellFilled />
), </Badge>
onClick: handleNotificationClick ),
} onClick: handleNotificationClick
]; }
]
: [];
return ( return (
<Layout.Header style={{ padding: 0, background: "#001529" }}> <Layout.Header style={{ padding: 0, background: "#001529" }}>
@@ -688,17 +691,21 @@ function Header({
background: "transparent" background: "transparent"
}} }}
/> />
<Menu {scenarioNotificationsOn && (
mode="horizontal" <Menu
theme="dark" mode="horizontal"
selectedKeys={[selectedHeader]} theme="dark"
onClick={handleMenuClick} selectedKeys={[selectedHeader]}
subMenuCloseDelay={0.3} onClick={handleMenuClick}
items={notificationItem} subMenuCloseDelay={0.3}
style={{ flex: "0 0 auto", minWidth: 0, borderBottom: "none", background: "transparent" }} items={notificationItem}
/> style={{ flex: "0 0 auto", minWidth: 0, borderBottom: "none", background: "transparent" }}
/>
)}
</div> </div>
<NotificationCenterContainer visible={notificationVisible} onClose={() => setNotificationVisible(false)} /> {scenarioNotificationsOn && (
<NotificationCenterContainer visible={notificationVisible} onClose={() => setNotificationVisible(false)} />
)}
</Layout.Header> </Layout.Header>
); );
} }

View File

@@ -9,6 +9,7 @@ import { logImEXEvent, updateCurrentPassword } from "../../firebase/firebase.uti
import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import NotificationSettingsForm from "./notification-settings.component.jsx"; import NotificationSettingsForm from "./notification-settings.component.jsx";
import { useSocket } from "../../contexts/SocketIO/socketContext.jsx";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser currentUser: selectCurrentUser
@@ -22,6 +23,7 @@ export default connect(
)(function ProfileMyComponent({ currentUser, updateUserDetails }) { )(function ProfileMyComponent({ currentUser, updateUserDetails }) {
const { t } = useTranslation(); const { t } = useTranslation();
const notification = useNotification(); const notification = useNotification();
const { scenarioNotificationsOn } = useSocket();
const handleFinish = (values) => { const handleFinish = (values) => {
logImEXEvent("profile_update"); logImEXEvent("profile_update");
@@ -117,9 +119,11 @@ export default connect(
</Card> </Card>
</Form> </Form>
</Col> </Col>
<Col span={24}> {scenarioNotificationsOn && (
<NotificationSettingsForm /> <Col span={24}>
</Col> <NotificationSettingsForm />
</Col>
)}
</> </>
); );
}); });

View File

@@ -17,7 +17,17 @@ const SocketContext = createContext(null);
const INITIAL_NOTIFICATIONS = 10; const INITIAL_NOTIFICATIONS = 10;
const SocketProvider = ({ children, bodyshop, navigate, currentUser }) => { /**
* Socket Provider - Scenario Notifications / Web Socket related items.
* @param children
* @param bodyshop
* @param navigate
* @param currentUser
* @param scenarioNotificationsOn
* @returns {JSX.Element}
* @constructor
*/
const SocketProvider = ({ children, bodyshop, navigate, currentUser, scenarioNotificationsOn }) => {
const socketRef = useRef(null); const socketRef = useRef(null);
const [clientId, setClientId] = useState(null); const [clientId, setClientId] = useState(null);
const [isConnected, setIsConnected] = useState(false); const [isConnected, setIsConnected] = useState(false);
@@ -191,6 +201,11 @@ const SocketProvider = ({ children, bodyshop, navigate, currentUser }) => {
}; };
const handleNotification = (data) => { const handleNotification = (data) => {
// Scenario Notifications have been disabled, bail.
if (!scenarioNotificationsOn) {
return;
}
const { jobId, jobRoNumber, notificationId, associationId, notifications } = data; const { jobId, jobRoNumber, notificationId, associationId, notifications } = data;
if (associationId !== userAssociationId) return; if (associationId !== userAssociationId) return;
@@ -295,6 +310,11 @@ const SocketProvider = ({ children, bodyshop, navigate, currentUser }) => {
}; };
const handleSyncNotificationRead = ({ notificationId, timestamp }) => { const handleSyncNotificationRead = ({ notificationId, timestamp }) => {
// Scenario Notifications have been disabled, bail.
if (!scenarioNotificationsOn) {
return;
}
try { try {
const notificationRef = client.cache.identify({ const notificationRef = client.cache.identify({
__typename: "notifications", __typename: "notifications",
@@ -336,6 +356,11 @@ const SocketProvider = ({ children, bodyshop, navigate, currentUser }) => {
}; };
const handleSyncAllNotificationsRead = ({ timestamp }) => { const handleSyncAllNotificationsRead = ({ timestamp }) => {
// Scenario Notifications have been disabled, bail.
if (!scenarioNotificationsOn) {
return;
}
try { try {
const queryVars = { const queryVars = {
limit: INITIAL_NOTIFICATIONS, limit: INITIAL_NOTIFICATIONS,
@@ -436,7 +461,8 @@ const SocketProvider = ({ children, bodyshop, navigate, currentUser }) => {
clientId, clientId,
isConnected, isConnected,
markNotificationRead, markNotificationRead,
markAllNotificationsRead markAllNotificationsRead,
scenarioNotificationsOn
}} }}
> >
{children} {children}

View File

@@ -57,6 +57,7 @@ import dayjs from "../../utils/day";
import UndefinedToNull from "../../utils/undefinedtonull"; import UndefinedToNull from "../../utils/undefinedtonull";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import JobWatcherToggle from "./job-watcher-toggle.component.jsx"; import JobWatcherToggle from "./job-watcher-toggle.component.jsx";
import { useSocket } from "../../contexts/SocketIO/socketContext.jsx";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
@@ -103,6 +104,7 @@ export function JobsDetailPage({
nextFetchPolicy: "network-only" nextFetchPolicy: "network-only"
}); });
const notification = useNotification(); const notification = useNotification();
const { scenarioNotificationsOn } = useSocket();
useEffect(() => { useEffect(() => {
//form.setFieldsValue(transormJobToForm(job)); //form.setFieldsValue(transormJobToForm(job));
@@ -323,7 +325,7 @@ export function JobsDetailPage({
title={ title={
<Space> <Space>
<JobWatcherToggle job={job} /> {scenarioNotificationsOn && <JobWatcherToggle job={job} />}
{job.ro_number || t("general.labels.na")} {job.ro_number || t("general.labels.na")}
</Space> </Space>
} }