feature/IO-3096-GlobalNotifications - Checkpoint - Additional String Cleanup, loading spinner

This commit is contained in:
Dave Richer
2025-03-03 12:07:19 -05:00
parent 35b92570e5
commit 86aa5bf5e7
8 changed files with 46 additions and 20 deletions

View File

@@ -180,3 +180,13 @@
.muted-button:hover {
color: darkgrey;
}
.notification-alert-unordered-list {
cursor: pointer;
padding: 0;
margin: 0;
.notification-alert-unordered-list-item {
margin-right: 0;
}
}

View File

@@ -1,6 +1,6 @@
import { Virtuoso } from "react-virtuoso";
import { Alert, Badge, Button, Tooltip, Typography } from "antd";
import { EyeFilled, EyeOutlined, CheckCircleFilled, CheckCircleOutlined } from "@ant-design/icons";
import { Alert, Badge, Button, Space, Spin, Tooltip, Typography } from "antd";
import { CheckCircleFilled, CheckCircleOutlined, EyeFilled, EyeOutlined } from "@ant-design/icons";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import "./notification-center.styles.scss";
@@ -66,7 +66,10 @@ const NotificationCenterComponent = ({
return (
<div className={`notification-center ${visible ? "visible" : ""}`}>
<div className="notification-header">
<h3>{t("notifications.labels.notification-center")}</h3>
<Space direction="horizontal">
<h3>{t("notifications.labels.notification-center")}</h3>
{loading && !error && <Spin spinning={loading} size="small"></Spin>}
</Space>
<div className="notification-controls">
<Tooltip title={t("notifications.labels.show-unread-only")}>
<Button
@@ -94,7 +97,6 @@ const NotificationCenterComponent = ({
endReached={loadMore}
itemContent={renderNotification}
/>
{loading && !error && <div>{t("notifications.labels.loading")}</div>}
</div>
);
};

View File

@@ -12,13 +12,14 @@ import {
MARK_NOTIFICATION_READ
} from "../../graphql/notifications.queries.js";
import { gql, useMutation } from "@apollo/client";
import { useTranslation } from "react-i18next";
const SocketContext = createContext(null);
const INITIAL_NOTIFICATIONS = 10;
/**
* Socket Provider - Scenario Notifications / Web Socket related items.
* Socket Provider - Scenario Notifications / Web Socket related items
* @param children
* @param bodyshop
* @param navigate
@@ -33,6 +34,7 @@ const SocketProvider = ({ children, bodyshop, navigate, currentUser, scenarioNot
const [isConnected, setIsConnected] = useState(false);
const notification = useNotification();
const userAssociationId = bodyshop?.associations?.[0]?.id;
const { t } = useTranslation();
const [markNotificationRead] = useMutation(MARK_NOTIFICATION_READ, {
update: (cache, { data: { update_notifications } }) => {
@@ -284,19 +286,18 @@ const SocketProvider = ({ children, bodyshop, navigate, currentUser, scenarioNot
});
notification.info({
message: `Changes for ${jobRoNumber}:`,
message: t("notifications.labels.notification-popup-title", { ro_number: jobRoNumber }),
description: (
<ul
className="notification-alert-unorderd-list"
className="notification-alert-unordered-list"
onClick={() => {
markNotificationRead({ variables: { id: notificationId } })
.then(() => navigate(`/manage/jobs/${jobId}`))
.catch((e) => console.error(`Error marking notification read: ${e?.message || ""}`));
}}
style={{ cursor: "pointer" }}
>
{notifications.map((notif, index) => (
<li className="notification-alert-unorderd-list-item" key={index}>
<li className="notification-alert-unordered-list-item" key={index}>
{notif.body}
</li>
))}

View File

@@ -23,8 +23,8 @@ const JobWatcherToggle = ({ job, currentUser, bodyshop }) => {
const jobid = job.id;
const [open, setOpen] = useState(false);
const [selectedWatcher, setSelectedWatcher] = useState(null); // New state for selected value
const [selectedTeam, setSelectedTeam] = useState(null); // New state to track selected team
const [selectedWatcher, setSelectedWatcher] = useState(null);
const [selectedTeam, setSelectedTeam] = useState(null);
// Fetch current watchers
const { data: watcherData, loading: watcherLoading } = useQuery(GET_JOB_WATCHERS, { variables: { jobid } });
@@ -109,7 +109,7 @@ const JobWatcherToggle = ({ job, currentUser, bodyshop }) => {
<List.Item.Meta
avatar={<Avatar icon={<UserOutlined />} />}
title={<Text>{displayName}</Text>}
description={watcher.user_email} // Keep the email for reference
description={watcher.user_email}
/>
</List.Item>
);
@@ -118,7 +118,6 @@ const JobWatcherToggle = ({ job, currentUser, bodyshop }) => {
// Popover content
const popoverContent = (
<div style={{ width: 600 }}>
{/* Self-toggle Button */}
<Button
block
type="text"
@@ -128,12 +127,10 @@ const JobWatcherToggle = ({ job, currentUser, bodyshop }) => {
>
{isWatching ? t("notifications.tooltips.unwatch") : t("notifications.tooltips.watch")}
</Button>
{/* List of Watchers */}
<Text type="secondary" style={{ marginBottom: 8, display: "block" }}>
{t("notifications.labels.watching-issue")}
</Text>
{watcherLoading ? <LoadingSpinner /> : <List dataSource={jobWatchers} renderItem={handleRenderItem} />}
{/* Employee Search Select (for adding watchers) */}
<Divider />
<Text type="secondary">{t("notifications.labels.add-watchers")}</Text>

View File

@@ -3781,7 +3781,7 @@
"new-notification-title": "New Notification:",
"show-unread-only": "Show Unread",
"mark-all-read": "Mark Read",
"loading": "Loading Notifications..."
"notification-popup-title": "Changes for Job #{{ro_number}}"
},
"actions": {
"remove": "remove"

View File

@@ -3769,6 +3769,7 @@
},
"notifications": {
"labels": {
"notification-center": "",
"scenario": "",
"notificationscenarios": "",
"save": "",
@@ -3776,7 +3777,11 @@
"add-watchers": "",
"employee-search": "",
"teams-search": "",
"add-watchers-team": ""
"add-watchers-team": "",
"new-notification-title": "",
"show-unread-only": "",
"mark-all-read": "",
"notification-popup-title": ""
},
"actions": {
"remove": ""

View File

@@ -3769,6 +3769,7 @@
},
"notifications": {
"labels": {
"notification-center": "",
"scenario": "",
"notificationscenarios": "",
"save": "",
@@ -3776,7 +3777,11 @@
"add-watchers": "",
"employee-search": "",
"teams-search": "",
"add-watchers-team": ""
"add-watchers-team": "",
"new-notification-title": "",
"show-unread-only": "",
"mark-all-read": "",
"notification-popup-title": ""
},
"actions": {
"remove": ""

View File

@@ -9,7 +9,13 @@ const { getJobAssignmentType } = require("./stringHelpers");
const populateWatchers = (data, result) => {
data.scenarioWatchers.forEach((recipients) => {
const { user, app, fcm, email, firstName, lastName, employeeId, associationId } = recipients;
if (app === true) result.app.recipients.push({ user, bodyShopId: data.bodyShopId, employeeId, associationId });
if (app === true)
result.app.recipients.push({
user,
bodyShopId: data.bodyShopId,
employeeId,
associationId
});
if (fcm === true) result.fcm.recipients.push(user);
if (email === true) result.email.recipients.push({ user, firstName, lastName });
});
@@ -147,7 +153,7 @@ const intakeDeliveryChecklistCompletedBuilder = (data) => {
* Builds notification data for job assignment events.
*/
const jobAssignedToMeBuilder = (data) => {
const body = `You have been assigned to [${getJobAssignmentType(data.scenarioFields?.[0])}]`;
const body = `You have been assigned to ${getJobAssignmentType(data.scenarioFields?.[0])}`;
const result = {
app: {
jobId: data.jobId,