feature/IO-3096-GlobalNotifications - Checkpoint - Splits are now in place
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user