@rytass/bpm-core-react 0.3.8 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +154 -0
- package/README.md +69 -4
- package/dist/chunks/approval-instance-list-page-BF2r5D2-.js +278 -0
- package/dist/chunks/approval-instance-list-page-BF2r5D2-.js.map +1 -0
- package/dist/chunks/approval-instance-list-page-C5ZKPHdA.cjs +2 -0
- package/dist/chunks/approval-instance-list-page-C5ZKPHdA.cjs.map +1 -0
- package/dist/chunks/auth-provider-4BeCw7cI.cjs +2 -0
- package/dist/chunks/auth-provider-4BeCw7cI.cjs.map +1 -0
- package/dist/chunks/auth-provider-B5oPmvk2.js +83 -0
- package/dist/chunks/auth-provider-B5oPmvk2.js.map +1 -0
- package/dist/chunks/{builder-D950gct_.js → builder-BLVnnpnP.js} +474 -478
- package/dist/chunks/builder-BLVnnpnP.js.map +1 -0
- package/dist/chunks/builder-DVE9zIKH.cjs +3 -0
- package/dist/chunks/builder-DVE9zIKH.cjs.map +1 -0
- package/dist/chunks/categories-B6QZKZRt.cjs +2 -0
- package/dist/chunks/categories-B6QZKZRt.cjs.map +1 -0
- package/dist/chunks/categories-DBPoSrsi.js +382 -0
- package/dist/chunks/categories-DBPoSrsi.js.map +1 -0
- package/dist/chunks/chunk-CMqjfN_6.cjs +1 -0
- package/dist/chunks/dashboard-page-CddG1MnK.cjs +2 -0
- package/dist/chunks/dashboard-page-CddG1MnK.cjs.map +1 -0
- package/dist/chunks/dashboard-page-Ib8srCMy.js +119 -0
- package/dist/chunks/dashboard-page-Ib8srCMy.js.map +1 -0
- package/dist/chunks/delegations-C2wLWsDQ.cjs +2 -0
- package/dist/chunks/delegations-C2wLWsDQ.cjs.map +1 -0
- package/dist/chunks/delegations-DDEk-WI6.cjs +2 -0
- package/dist/chunks/delegations-DDEk-WI6.cjs.map +1 -0
- package/dist/chunks/delegations-ZNtodFaD.js +568 -0
- package/dist/chunks/delegations-ZNtodFaD.js.map +1 -0
- package/dist/chunks/delegations-iVnRi3QE.js +641 -0
- package/dist/chunks/delegations-iVnRi3QE.js.map +1 -0
- package/dist/chunks/detail-Dcr5mM8g.cjs +2 -0
- package/dist/chunks/detail-Dcr5mM8g.cjs.map +1 -0
- package/dist/chunks/detail-u9DdLhDW.js +1518 -0
- package/dist/chunks/detail-u9DdLhDW.js.map +1 -0
- package/dist/chunks/format-date-time-XxBzF0F5.cjs +2 -0
- package/dist/chunks/{format-date-time-26_pFvv4.cjs.map → format-date-time-XxBzF0F5.cjs.map} +1 -1
- package/dist/chunks/login-9bCXyjbX.cjs +2 -0
- package/dist/chunks/{login-CQ9MfwcC.cjs.map → login-9bCXyjbX.cjs.map} +1 -1
- package/dist/chunks/{login-C20yVxbc.js → login-BKxpLibd.js} +3 -2
- package/dist/chunks/{login-C20yVxbc.js.map → login-BKxpLibd.js.map} +1 -1
- package/dist/chunks/notifications-BKs4--96.cjs +2 -0
- package/dist/chunks/notifications-BKs4--96.cjs.map +1 -0
- package/dist/chunks/notifications-CSulztkU.js +193 -0
- package/dist/chunks/notifications-CSulztkU.js.map +1 -0
- package/dist/chunks/orgs-BIiqzHvb.cjs +2 -0
- package/dist/chunks/orgs-BIiqzHvb.cjs.map +1 -0
- package/dist/chunks/orgs-Cc18umVt.js +1944 -0
- package/dist/chunks/orgs-Cc18umVt.js.map +1 -0
- package/dist/chunks/router-adapter--gYs13E8.cjs +2 -0
- package/dist/chunks/router-adapter--gYs13E8.cjs.map +1 -0
- package/dist/chunks/router-adapter-DftlFTOd.js +23 -0
- package/dist/chunks/router-adapter-DftlFTOd.js.map +1 -0
- package/dist/chunks/templates-D44FSB46.js +380 -0
- package/dist/chunks/templates-D44FSB46.js.map +1 -0
- package/dist/chunks/templates-w96t83N-.cjs +2 -0
- package/dist/chunks/templates-w96t83N-.cjs.map +1 -0
- package/dist/chunks/users-CUY139DF.js +214 -0
- package/dist/chunks/users-CUY139DF.js.map +1 -0
- package/dist/chunks/users-qghSMtLn.cjs +2 -0
- package/dist/chunks/users-qghSMtLn.cjs.map +1 -0
- package/dist/components/approval-instance-list-page.d.ts +1 -2
- package/dist/components/bpm-notification-bell-button.d.ts +22 -0
- package/dist/components/dashboard-page.d.ts +1 -4
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +206 -97
- package/dist/index.js.map +1 -1
- package/dist/lib/notification-drawer-provider.d.ts +3 -2
- package/dist/lib/notification-unread-provider.d.ts +6 -5
- package/dist/lib/providers.d.ts +3 -2
- package/dist/lib/use-bpm-logout.d.ts +12 -0
- package/dist/lib/use-bpm-member.d.ts +11 -0
- package/dist/next/BPMNextProviders.d.ts +1 -1
- package/dist/next/index.cjs +1 -1
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.js +13 -23
- package/dist/next/index.js.map +1 -1
- package/dist/pages/admin/delegations/index.cjs +1 -1
- package/dist/pages/admin/delegations/index.js +1 -1
- package/dist/pages/admin/orgs/index.cjs +1 -1
- package/dist/pages/admin/orgs/index.js +1 -1
- package/dist/pages/admin/users/index.cjs +1 -1
- package/dist/pages/admin/users/index.js +1 -1
- package/dist/pages/delegations/index.cjs +1 -1
- package/dist/pages/delegations/index.js +1 -1
- package/dist/pages/forms/builder/index.cjs +1 -1
- package/dist/pages/forms/builder/index.js +1 -1
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.js +1 -1
- package/dist/pages/login/index.cjs +1 -1
- package/dist/pages/login/index.js +1 -1
- package/dist/pages/settings/notifications/index.cjs +1 -1
- package/dist/pages/settings/notifications/index.js +1 -1
- package/dist/pages/templates/categories/index.cjs +1 -1
- package/dist/pages/templates/categories/index.js +1 -1
- package/dist/pages/templates/index.cjs +1 -1
- package/dist/pages/templates/index.js +1 -1
- package/dist/views/admin/delegations/AdminDelegationsView.d.ts +1 -4
- package/dist/views/admin/delegations/index.cjs +1 -1
- package/dist/views/admin/delegations/index.js +1 -1
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.js +3 -3
- package/dist/views/admin/orgs/AdminOrgsView.d.ts +1 -4
- package/dist/views/admin/orgs/index.cjs +1 -1
- package/dist/views/admin/orgs/index.js +1 -1
- package/dist/views/admin/users/AdminUsersView.d.ts +1 -4
- package/dist/views/admin/users/index.cjs +1 -1
- package/dist/views/admin/users/index.js +1 -1
- package/dist/views/cc/CcView.d.ts +1 -3
- package/dist/views/cc/index.cjs +1 -1
- package/dist/views/cc/index.cjs.map +1 -1
- package/dist/views/cc/index.js +2 -3
- package/dist/views/cc/index.js.map +1 -1
- package/dist/views/dashboard/DashboardView.d.ts +1 -3
- package/dist/views/dashboard/index.cjs +1 -1
- package/dist/views/dashboard/index.cjs.map +1 -1
- package/dist/views/dashboard/index.js +3 -3
- package/dist/views/dashboard/index.js.map +1 -1
- package/dist/views/delegations/DelegationsView.d.ts +1 -4
- package/dist/views/delegations/index.cjs +1 -1
- package/dist/views/delegations/index.js +1 -1
- package/dist/views/forms/FormsView.d.ts +1 -3
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/index.cjs +1 -1
- package/dist/views/forms/index.cjs.map +1 -1
- package/dist/views/forms/index.js +95 -99
- package/dist/views/forms/index.js.map +1 -1
- package/dist/views/inbox/InboxView.d.ts +1 -3
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.cjs.map +1 -1
- package/dist/views/inbox/index.js +91 -94
- package/dist/views/inbox/index.js.map +1 -1
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.js +1 -1
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.cjs.map +1 -1
- package/dist/views/instances/new/index.js +71 -77
- package/dist/views/instances/new/index.js.map +1 -1
- package/dist/views/login/index.cjs +1 -1
- package/dist/views/login/index.js +1 -1
- package/dist/views/root/RootView.d.ts +1 -3
- package/dist/views/search/SearchView.d.ts +1 -3
- package/dist/views/search/index.cjs +1 -1
- package/dist/views/search/index.cjs.map +1 -1
- package/dist/views/search/index.js +2 -3
- package/dist/views/search/index.js.map +1 -1
- package/dist/views/sent/SentView.d.ts +1 -3
- package/dist/views/sent/index.cjs +1 -1
- package/dist/views/sent/index.cjs.map +1 -1
- package/dist/views/sent/index.js +2 -3
- package/dist/views/sent/index.js.map +1 -1
- package/dist/views/settings/index.cjs +1 -1
- package/dist/views/settings/index.js +1 -1
- package/dist/views/settings/notifications/SettingsNotificationsView.d.ts +1 -4
- package/dist/views/settings/notifications/index.cjs +1 -1
- package/dist/views/settings/notifications/index.js +1 -1
- package/dist/views/templates/TemplatesView.d.ts +1 -4
- package/dist/views/templates/categories/TemplateCategoriesView.d.ts +1 -4
- package/dist/views/templates/categories/index.cjs +1 -1
- package/dist/views/templates/categories/index.js +1 -1
- package/dist/views/templates/designer/TemplateDesignerView.d.ts +1 -2
- package/dist/views/templates/designer/index.cjs +7 -7
- package/dist/views/templates/designer/index.cjs.map +1 -1
- package/dist/views/templates/designer/index.js +707 -711
- package/dist/views/templates/designer/index.js.map +1 -1
- package/dist/views/templates/index.cjs +1 -1
- package/dist/views/templates/index.js +2 -2
- package/dist/views/templates/versions/TemplateVersionsView.d.ts +1 -2
- package/dist/views/templates/versions/index.cjs +1 -1
- package/dist/views/templates/versions/index.cjs.map +1 -1
- package/dist/views/templates/versions/index.js +45 -49
- package/dist/views/templates/versions/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/app-navigation.css +0 -1
- package/dist/chunks/app-navigation-BSkMsEhy.js +0 -268
- package/dist/chunks/app-navigation-BSkMsEhy.js.map +0 -1
- package/dist/chunks/app-navigation-KnlJCUp1.cjs +0 -2
- package/dist/chunks/app-navigation-KnlJCUp1.cjs.map +0 -1
- package/dist/chunks/approval-instance-list-page-CVXgE2K3.cjs +0 -2
- package/dist/chunks/approval-instance-list-page-CVXgE2K3.cjs.map +0 -1
- package/dist/chunks/approval-instance-list-page-CqNdoZqx.js +0 -282
- package/dist/chunks/approval-instance-list-page-CqNdoZqx.js.map +0 -1
- package/dist/chunks/auth-provider-BV8Iiwfb.cjs +0 -2
- package/dist/chunks/auth-provider-BV8Iiwfb.cjs.map +0 -1
- package/dist/chunks/auth-provider-Bnox5gsx.js +0 -98
- package/dist/chunks/auth-provider-Bnox5gsx.js.map +0 -1
- package/dist/chunks/builder-CMlJfQHE.cjs +0 -3
- package/dist/chunks/builder-CMlJfQHE.cjs.map +0 -1
- package/dist/chunks/builder-D950gct_.js.map +0 -1
- package/dist/chunks/categories-5yEM3p3N.cjs +0 -2
- package/dist/chunks/categories-5yEM3p3N.cjs.map +0 -1
- package/dist/chunks/categories-BIpOG451.js +0 -387
- package/dist/chunks/categories-BIpOG451.js.map +0 -1
- package/dist/chunks/dashboard-page-Bx1-Ys3e.js +0 -122
- package/dist/chunks/dashboard-page-Bx1-Ys3e.js.map +0 -1
- package/dist/chunks/dashboard-page-CQNRbMkJ.cjs +0 -2
- package/dist/chunks/dashboard-page-CQNRbMkJ.cjs.map +0 -1
- package/dist/chunks/delegations-B2j-wNEO.js +0 -646
- package/dist/chunks/delegations-B2j-wNEO.js.map +0 -1
- package/dist/chunks/delegations-CsB9ozLu.cjs +0 -2
- package/dist/chunks/delegations-CsB9ozLu.cjs.map +0 -1
- package/dist/chunks/delegations-CvtwTXNP.cjs +0 -2
- package/dist/chunks/delegations-CvtwTXNP.cjs.map +0 -1
- package/dist/chunks/delegations-dKodb0WW.js +0 -573
- package/dist/chunks/delegations-dKodb0WW.js.map +0 -1
- package/dist/chunks/detail-BcGAqJ_R.js +0 -1523
- package/dist/chunks/detail-BcGAqJ_R.js.map +0 -1
- package/dist/chunks/detail-CqjqLd65.cjs +0 -2
- package/dist/chunks/detail-CqjqLd65.cjs.map +0 -1
- package/dist/chunks/format-date-time-26_pFvv4.cjs +0 -2
- package/dist/chunks/login-CQ9MfwcC.cjs +0 -2
- package/dist/chunks/notifications-2swRqDPF.js +0 -198
- package/dist/chunks/notifications-2swRqDPF.js.map +0 -1
- package/dist/chunks/notifications-BaYDebFt.cjs +0 -2
- package/dist/chunks/notifications-BaYDebFt.cjs.map +0 -1
- package/dist/chunks/orgs-CuHxxd_n.js +0 -1949
- package/dist/chunks/orgs-CuHxxd_n.js.map +0 -1
- package/dist/chunks/orgs-YMiVLNvL.cjs +0 -2
- package/dist/chunks/orgs-YMiVLNvL.cjs.map +0 -1
- package/dist/chunks/templates-DTkbSgFY.cjs +0 -2
- package/dist/chunks/templates-DTkbSgFY.cjs.map +0 -1
- package/dist/chunks/templates-DoDWM68t.js +0 -384
- package/dist/chunks/templates-DoDWM68t.js.map +0 -1
- package/dist/chunks/users-3ySyUW4u.cjs +0 -2
- package/dist/chunks/users-3ySyUW4u.cjs.map +0 -1
- package/dist/chunks/users-sMfrSjRQ.js +0 -219
- package/dist/chunks/users-sMfrSjRQ.js.map +0 -1
- package/dist/components/app-navigation.d.ts +0 -41
package/dist/index.js
CHANGED
|
@@ -1,174 +1,247 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { n as e, r as t, t as n } from "./chunks/router-adapter-DftlFTOd.js";
|
|
3
|
+
import { n as r, t as i } from "./chunks/auth-provider-B5oPmvk2.js";
|
|
3
4
|
import { t as a } from "./chunks/format-date-time-CB-LxzqT.js";
|
|
4
|
-
import {
|
|
5
|
-
import { n as d,
|
|
6
|
-
import {
|
|
7
|
-
import { t as
|
|
8
|
-
import { t as
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { jsx as
|
|
12
|
-
import { listNotifications as
|
|
13
|
-
import { CalendarConfigProviderMoment as
|
|
14
|
-
import
|
|
15
|
-
import
|
|
5
|
+
import { n as o, r as s, t as c } from "./chunks/routes-config-dxahImVe.js";
|
|
6
|
+
import { a as l, i as u, n as d, o as f, r as p, t as m } from "./chunks/admin-pickers-DLlG_1du.js";
|
|
7
|
+
import { t as h } from "./chunks/approval-instance-list-page-BF2r5D2-.js";
|
|
8
|
+
import { t as g } from "./chunks/bpm-form-field-Cao0rMol.js";
|
|
9
|
+
import { t as _ } from "./chunks/dashboard-page-Ib8srCMy.js";
|
|
10
|
+
import { Fragment as v, createContext as y, useCallback as b, useContext as x, useEffect as S, useMemo as C, useState as w } from "react";
|
|
11
|
+
import { NavigationIconButton as T } from "@mezzanine-ui/react";
|
|
12
|
+
import { jsx as E, jsxs as D } from "react/jsx-runtime";
|
|
13
|
+
import { listNotifications as O, markAllNotificationsRead as k, markNotificationRead as A, readUnreadNotificationCount as j } from "@rytass/bpm-core-client/workflow";
|
|
14
|
+
import { CalendarConfigProviderMoment as M, CalendarLocale as N } from "@mezzanine-ui/react/moment";
|
|
15
|
+
import P from "@mezzanine-ui/react/Drawer";
|
|
16
|
+
import F from "@mezzanine-ui/react/NotificationCenter";
|
|
17
|
+
import { NotificationUnreadIcon as I } from "@mezzanine-ui/icons";
|
|
18
|
+
import './index.css';//#region src/lib/notification-drawer-provider.tsx
|
|
19
|
+
var L = y(null);
|
|
20
|
+
function R({ children: e }) {
|
|
21
|
+
let [t, n] = w(!1), r = b(() => {
|
|
22
|
+
n(!0);
|
|
23
|
+
}, []), i = b(() => {
|
|
24
|
+
n(!1);
|
|
25
|
+
}, []), a = b(() => {
|
|
26
|
+
n((e) => !e);
|
|
27
|
+
}, []), o = C(() => ({
|
|
28
|
+
close: i,
|
|
29
|
+
isOpen: t,
|
|
30
|
+
open: r,
|
|
31
|
+
toggle: a
|
|
32
|
+
}), [
|
|
33
|
+
i,
|
|
34
|
+
t,
|
|
35
|
+
r,
|
|
36
|
+
a
|
|
37
|
+
]);
|
|
38
|
+
return /* @__PURE__ */ E(L.Provider, {
|
|
39
|
+
value: o,
|
|
40
|
+
children: e
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function z() {
|
|
44
|
+
return x(L) || {
|
|
45
|
+
close: () => void 0,
|
|
46
|
+
isOpen: !1,
|
|
47
|
+
open: () => void 0,
|
|
48
|
+
toggle: () => void 0
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/lib/notification-unread-provider.tsx
|
|
53
|
+
var B = y(null);
|
|
54
|
+
function V({ children: e }) {
|
|
55
|
+
let { member: t } = r(), n = t?.memberId ?? null, [i, a] = w(0), o = b(async () => {
|
|
56
|
+
if (!n) return a(0), 0;
|
|
57
|
+
let e = await j(n);
|
|
58
|
+
return a(e), e;
|
|
59
|
+
}, [n]);
|
|
60
|
+
S(() => {
|
|
61
|
+
let e = !0;
|
|
62
|
+
return (async () => {
|
|
63
|
+
try {
|
|
64
|
+
let t = await o();
|
|
65
|
+
e && a(t);
|
|
66
|
+
} catch {
|
|
67
|
+
e && a(0);
|
|
68
|
+
}
|
|
69
|
+
})(), () => {
|
|
70
|
+
e = !1;
|
|
71
|
+
};
|
|
72
|
+
}, [o]);
|
|
73
|
+
let s = C(() => ({
|
|
74
|
+
refreshUnreadCount: o,
|
|
75
|
+
unreadCount: i
|
|
76
|
+
}), [o, i]);
|
|
77
|
+
return /* @__PURE__ */ E(B.Provider, {
|
|
78
|
+
value: s,
|
|
79
|
+
children: e
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function H() {
|
|
83
|
+
return x(B) || {
|
|
84
|
+
refreshUnreadCount: async () => 0,
|
|
85
|
+
unreadCount: 0
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
16
89
|
//#region src/components/notification-drawer.tsx
|
|
17
|
-
var
|
|
90
|
+
var U = [
|
|
18
91
|
"today",
|
|
19
92
|
"yesterday",
|
|
20
93
|
"past7Days",
|
|
21
94
|
"earlier"
|
|
22
|
-
],
|
|
95
|
+
], W = {
|
|
23
96
|
earlier: "更早",
|
|
24
97
|
past7Days: "過去七天",
|
|
25
98
|
today: "今天",
|
|
26
99
|
yesterday: "昨天"
|
|
27
|
-
},
|
|
28
|
-
function
|
|
29
|
-
let
|
|
30
|
-
if (
|
|
31
|
-
|
|
100
|
+
}, G = 50;
|
|
101
|
+
function K() {
|
|
102
|
+
let e = t(), n = s(), { member: i } = r(), { close: a, isOpen: o } = z(), { refreshUnreadCount: c } = H(), l = i?.memberId ?? null, [u, d] = w([]), [f, p] = w(0), [m, h] = w(1), [g, _] = w(!1), [y, x] = w(!1), [T, j] = w(null), [M, N] = w("all"), I = b(async (e, t) => {
|
|
103
|
+
if (l) {
|
|
104
|
+
_(!0), j(null);
|
|
32
105
|
try {
|
|
33
|
-
let n = await
|
|
106
|
+
let n = await O({
|
|
34
107
|
includeRead: !0,
|
|
35
108
|
page: e,
|
|
36
|
-
pageSize:
|
|
37
|
-
recipientMemberId:
|
|
109
|
+
pageSize: G,
|
|
110
|
+
recipientMemberId: l
|
|
38
111
|
});
|
|
39
|
-
|
|
112
|
+
d((e) => t ? [...e, ...n.notifications] : n.notifications), p(n.totalCount), h(e), await c();
|
|
40
113
|
} catch (e) {
|
|
41
|
-
|
|
114
|
+
j(Y(e));
|
|
42
115
|
} finally {
|
|
43
|
-
|
|
116
|
+
_(!1);
|
|
44
117
|
}
|
|
45
118
|
}
|
|
46
|
-
}, [
|
|
47
|
-
|
|
48
|
-
!
|
|
119
|
+
}, [l, c]);
|
|
120
|
+
S(() => {
|
|
121
|
+
!o || !l || I(1, !1);
|
|
49
122
|
}, [
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
123
|
+
o,
|
|
124
|
+
l,
|
|
125
|
+
I
|
|
53
126
|
]);
|
|
54
|
-
let
|
|
127
|
+
let L = b((e) => {
|
|
55
128
|
let t = e.target.value;
|
|
56
|
-
(t === "all" || t === "read" || t === "unread") &&
|
|
57
|
-
}, []),
|
|
58
|
-
if (!(!
|
|
59
|
-
x(!0),
|
|
129
|
+
(t === "all" || t === "read" || t === "unread") && N(t);
|
|
130
|
+
}, []), R = b(async () => {
|
|
131
|
+
if (!(!l || y)) {
|
|
132
|
+
x(!0), j(null);
|
|
60
133
|
try {
|
|
61
|
-
await
|
|
134
|
+
await k({ recipientMemberId: l }), await I(1, !1);
|
|
62
135
|
} catch (e) {
|
|
63
|
-
|
|
136
|
+
j(Y(e));
|
|
64
137
|
} finally {
|
|
65
138
|
x(!1);
|
|
66
139
|
}
|
|
67
140
|
}
|
|
68
141
|
}, [
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
]),
|
|
73
|
-
|
|
142
|
+
y,
|
|
143
|
+
l,
|
|
144
|
+
I
|
|
145
|
+
]), B = b(() => {
|
|
146
|
+
g || I(m + 1, !0);
|
|
74
147
|
}, [
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
]),
|
|
79
|
-
if (
|
|
80
|
-
await
|
|
148
|
+
g,
|
|
149
|
+
I,
|
|
150
|
+
m
|
|
151
|
+
]), V = b(async (e) => {
|
|
152
|
+
if (l) try {
|
|
153
|
+
await A({
|
|
81
154
|
id: e,
|
|
82
|
-
readerMemberId:
|
|
83
|
-
}), await
|
|
155
|
+
readerMemberId: l
|
|
156
|
+
}), await I(1, !1);
|
|
84
157
|
} catch (e) {
|
|
85
|
-
|
|
158
|
+
j(Y(e));
|
|
86
159
|
}
|
|
87
|
-
}, [
|
|
88
|
-
if (!(!
|
|
89
|
-
|
|
90
|
-
id:
|
|
91
|
-
readerMemberId:
|
|
92
|
-
}), await c()), a(),
|
|
160
|
+
}, [l, I]), K = b(async (t) => {
|
|
161
|
+
if (!(!t.instanceId || !l)) try {
|
|
162
|
+
t.status !== "READ" && (await A({
|
|
163
|
+
id: t.id,
|
|
164
|
+
readerMemberId: l
|
|
165
|
+
}), await c()), a(), e.push(n.caseDetail(t.instanceId));
|
|
93
166
|
} catch (e) {
|
|
94
|
-
|
|
167
|
+
j(Y(e));
|
|
95
168
|
}
|
|
96
169
|
}, [
|
|
97
170
|
a,
|
|
98
|
-
|
|
171
|
+
l,
|
|
99
172
|
c,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
]), X =
|
|
103
|
-
let e = /* @__PURE__ */ new Date(), t =
|
|
173
|
+
e,
|
|
174
|
+
n
|
|
175
|
+
]), X = C(() => u.filter((e) => M === "all" ? !0 : M === "read" ? e.status === "READ" : e.status !== "READ"), [M, u]), Z = C(() => {
|
|
176
|
+
let e = /* @__PURE__ */ new Date(), t = U.reduce((e, t) => (e[t] = [], e), {
|
|
104
177
|
earlier: [],
|
|
105
178
|
past7Days: [],
|
|
106
179
|
today: [],
|
|
107
180
|
yesterday: []
|
|
108
181
|
});
|
|
109
182
|
return X.forEach((n) => {
|
|
110
|
-
t[
|
|
111
|
-
}),
|
|
112
|
-
}, [X]), Q =
|
|
113
|
-
return
|
|
114
|
-
bottomGhostActionDisabled:
|
|
115
|
-
bottomGhostActionLoading:
|
|
183
|
+
t[J(n.createdAt, e)].push(n);
|
|
184
|
+
}), U.map((e) => [e, t[e]]).filter(([, e]) => e.length > 0);
|
|
185
|
+
}, [X]), Q = u.length < f;
|
|
186
|
+
return l ? /* @__PURE__ */ E(P, {
|
|
187
|
+
bottomGhostActionDisabled: y || g,
|
|
188
|
+
bottomGhostActionLoading: y,
|
|
116
189
|
bottomGhostActionText: "全部標為已讀",
|
|
117
190
|
bottomOnGhostActionClick: () => {
|
|
118
|
-
|
|
191
|
+
R();
|
|
119
192
|
},
|
|
120
193
|
bottomOnPrimaryActionClick: () => {
|
|
121
|
-
|
|
194
|
+
B();
|
|
122
195
|
},
|
|
123
|
-
bottomPrimaryActionDisabled: !Q ||
|
|
124
|
-
bottomPrimaryActionLoading:
|
|
196
|
+
bottomPrimaryActionDisabled: !Q || g,
|
|
197
|
+
bottomPrimaryActionLoading: g && Q,
|
|
125
198
|
bottomPrimaryActionText: Q ? "載入更多" : "已顯示全部",
|
|
126
|
-
contentKey: `${
|
|
199
|
+
contentKey: `${M}:${u.length}`,
|
|
127
200
|
filterAreaAllRadioLabel: "全部",
|
|
128
|
-
filterAreaOnRadioChange:
|
|
201
|
+
filterAreaOnRadioChange: L,
|
|
129
202
|
filterAreaReadRadioLabel: "已讀",
|
|
130
203
|
filterAreaShow: !0,
|
|
131
204
|
filterAreaUnreadRadioLabel: "未讀",
|
|
132
|
-
filterAreaValue:
|
|
205
|
+
filterAreaValue: M,
|
|
133
206
|
headerTitle: "通知中心",
|
|
134
207
|
isBottomDisplay: !0,
|
|
135
208
|
isHeaderDisplay: !0,
|
|
136
209
|
onClose: a,
|
|
137
|
-
open:
|
|
210
|
+
open: o,
|
|
138
211
|
size: "medium",
|
|
139
|
-
children: /* @__PURE__ */
|
|
212
|
+
children: /* @__PURE__ */ D("div", {
|
|
140
213
|
role: "list",
|
|
141
214
|
children: [
|
|
142
|
-
|
|
215
|
+
T ? /* @__PURE__ */ E("p", {
|
|
143
216
|
role: "alert",
|
|
144
217
|
style: {
|
|
145
218
|
color: "var(--mzn-color-text-error, #d92d20)",
|
|
146
219
|
padding: "12px 16px"
|
|
147
220
|
},
|
|
148
|
-
children:
|
|
221
|
+
children: T
|
|
149
222
|
}) : null,
|
|
150
|
-
Z.length === 0 ? /* @__PURE__ */
|
|
223
|
+
Z.length === 0 ? /* @__PURE__ */ E("p", {
|
|
151
224
|
style: {
|
|
152
225
|
color: "var(--mzn-color-text-secondary, #6b7280)",
|
|
153
226
|
padding: "24px 16px",
|
|
154
227
|
textAlign: "center"
|
|
155
228
|
},
|
|
156
|
-
children:
|
|
229
|
+
children: g ? "載入中…" : "目前沒有通知"
|
|
157
230
|
}) : null,
|
|
158
|
-
Z.map(([e, t], n) => /* @__PURE__ */
|
|
231
|
+
Z.map(([e, t], n) => /* @__PURE__ */ E(v, { children: t.map((r, i) => /* @__PURE__ */ E(F, {
|
|
159
232
|
appendTips: n === Z.length - 1 && i === t.length - 1 && !Q ? "已顯示全部通知" : void 0,
|
|
160
233
|
cancelButtonText: r.status === "READ" ? void 0 : "標為已讀",
|
|
161
234
|
description: r.body,
|
|
162
235
|
onCancel: r.status === "READ" ? void 0 : () => {
|
|
163
|
-
|
|
236
|
+
V(r.id);
|
|
164
237
|
},
|
|
165
238
|
onConfirm: r.instanceId ? () => {
|
|
166
|
-
|
|
239
|
+
K(r);
|
|
167
240
|
} : void 0,
|
|
168
241
|
confirmButtonText: r.instanceId ? "查看案件" : void 0,
|
|
169
|
-
prependTips: i === 0 ?
|
|
242
|
+
prependTips: i === 0 ? W[e] : void 0,
|
|
170
243
|
reference: r.id,
|
|
171
|
-
severity:
|
|
244
|
+
severity: q(r.type),
|
|
172
245
|
showBadge: r.status !== "READ",
|
|
173
246
|
timeStamp: r.createdAt,
|
|
174
247
|
title: r.title,
|
|
@@ -178,10 +251,10 @@ function B() {
|
|
|
178
251
|
})
|
|
179
252
|
}) : null;
|
|
180
253
|
}
|
|
181
|
-
function
|
|
254
|
+
function q(e) {
|
|
182
255
|
return e === "SLA_OVERDUE" ? "error" : e === "SLA_WARNING" ? "warning" : e === "INSTANCE_COMPLETED" ? "success" : "info";
|
|
183
256
|
}
|
|
184
|
-
function
|
|
257
|
+
function J(e, t) {
|
|
185
258
|
let n = new Date(e);
|
|
186
259
|
if (Number.isNaN(n.getTime())) return "earlier";
|
|
187
260
|
let r = new Date(t.getFullYear(), t.getMonth(), t.getDate()), i = new Date(n.getFullYear(), n.getMonth(), n.getDate());
|
|
@@ -189,22 +262,58 @@ function H(e, t) {
|
|
|
189
262
|
let a = new Date(r);
|
|
190
263
|
return a.setDate(a.getDate() - 1), i.getTime() === a.getTime() ? "yesterday" : (t.getTime() - n.getTime()) / (1e3 * 60 * 60 * 24) <= 7 ? "past7Days" : "earlier";
|
|
191
264
|
}
|
|
192
|
-
function
|
|
265
|
+
function Y(e) {
|
|
193
266
|
return e instanceof Error ? e.message : "發生未知錯誤";
|
|
194
267
|
}
|
|
195
268
|
//#endregion
|
|
196
269
|
//#region src/lib/providers.tsx
|
|
197
|
-
function
|
|
198
|
-
return /* @__PURE__ */
|
|
270
|
+
function X({ children: e, locale: t = N.ZH_TW, publicPaths: n, loginPath: r }) {
|
|
271
|
+
return /* @__PURE__ */ E(M, {
|
|
199
272
|
locale: t,
|
|
200
|
-
children: /* @__PURE__ */
|
|
273
|
+
children: /* @__PURE__ */ E(i, {
|
|
201
274
|
publicPaths: n,
|
|
202
275
|
loginPath: r,
|
|
203
|
-
children: /* @__PURE__ */
|
|
276
|
+
children: /* @__PURE__ */ E(V, { children: /* @__PURE__ */ D(R, { children: [e, /* @__PURE__ */ E(K, {})] }) })
|
|
204
277
|
})
|
|
205
278
|
});
|
|
206
279
|
}
|
|
207
280
|
//#endregion
|
|
208
|
-
|
|
281
|
+
//#region src/lib/use-bpm-logout.ts
|
|
282
|
+
function Z() {
|
|
283
|
+
let { logout: e } = r();
|
|
284
|
+
return e;
|
|
285
|
+
}
|
|
286
|
+
//#endregion
|
|
287
|
+
//#region src/lib/use-bpm-member.ts
|
|
288
|
+
function Q() {
|
|
289
|
+
let { member: e } = r();
|
|
290
|
+
return e;
|
|
291
|
+
}
|
|
292
|
+
var $ = {
|
|
293
|
+
root: "bpm_root_jl5S-",
|
|
294
|
+
badge: "bpm_badge_SIKJk"
|
|
295
|
+
};
|
|
296
|
+
//#endregion
|
|
297
|
+
//#region src/components/bpm-notification-bell-button.tsx
|
|
298
|
+
function ee({ label: e = "通知中心" } = {}) {
|
|
299
|
+
let { open: t } = z(), { unreadCount: n } = H(), r = n > 0 ? `${e},${n} 則未讀` : e;
|
|
300
|
+
return /* @__PURE__ */ D("span", {
|
|
301
|
+
className: $.root,
|
|
302
|
+
children: [/* @__PURE__ */ E(T, {
|
|
303
|
+
"aria-label": r,
|
|
304
|
+
icon: I,
|
|
305
|
+
onClick: () => {
|
|
306
|
+
t();
|
|
307
|
+
},
|
|
308
|
+
title: e,
|
|
309
|
+
type: "button"
|
|
310
|
+
}), n > 0 ? /* @__PURE__ */ E("span", {
|
|
311
|
+
className: $.badge,
|
|
312
|
+
children: n > 99 ? "99+" : n
|
|
313
|
+
}) : null]
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
//#endregion
|
|
317
|
+
export { h as ApprovalInstanceListPage, i as AuthProvider, g as BPMFormField, ee as BPMNotificationBellButton, c as BPMRoutesProvider, _ as DashboardPage, m as MemberPicker, K as NotificationDrawer, R as NotificationDrawerProvider, V as NotificationUnreadProvider, d as OrgUnitPicker, p as PositionPicker, X as Providers, n as RouterAdapterProvider, o as createDefaultBPMRoutes, e as defaultBrowserSearchParams, a as formatDateTime, u as readMemberOption, l as readOrgUnitOption, f as readPositionOption, r as useAuth, Z as useBPMLogout, Q as useBPMMember, s as useBPMRoutes, z as useNotificationDrawer, H as useNotificationUnread, t as useRouterAdapter };
|
|
209
318
|
|
|
210
319
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/components/notification-drawer.tsx","../src/lib/providers.tsx"],"sourcesContent":["'use client';\n\nimport {\n Fragment,\n useCallback,\n useEffect,\n useMemo,\n useState,\n type ChangeEvent,\n type ReactElement,\n} from 'react';\nimport Drawer from '@mezzanine-ui/react/Drawer';\nimport NotificationCenter from '@mezzanine-ui/react/NotificationCenter';\nimport type { NotificationSeverity } from '@mezzanine-ui/core/notification-center';\nimport {\n listNotifications,\n markAllNotificationsRead,\n markNotificationRead,\n type NotificationRecord,\n type NotificationType,\n} from '@rytass/bpm-core-client/workflow';\nimport { useAuth } from '../lib/auth-provider';\nimport { useNotificationDrawer } from '../lib/notification-drawer-provider';\nimport { useNotificationUnread } from '../lib/notification-unread-provider';\nimport { useRouterAdapter } from '../lib/router-adapter';\nimport { useBPMRoutes } from '../lib/routes-config';\n\ntype FilterValue = 'all' | 'read' | 'unread';\n\ntype TimeGroup = 'today' | 'yesterday' | 'past7Days' | 'earlier';\n\nconst TIME_GROUP_ORDER: readonly TimeGroup[] = [\n 'today',\n 'yesterday',\n 'past7Days',\n 'earlier',\n];\n\nconst TIME_GROUP_LABEL: Readonly<Record<TimeGroup, string>> = {\n earlier: '更早',\n past7Days: '過去七天',\n today: '今天',\n yesterday: '昨天',\n};\n\nconst PAGE_SIZE = 50;\n\n/**\n * Right-side notification drawer mounted at the root by `<Providers>`.\n * Opens / closes via `useNotificationDrawer()`, polls\n * `listNotifications()` for the current member, supports filter\n * (`all` / `read` / `unread`), per-row mark-read, bulk mark-all-read, and\n * load-more pagination. Clicking a row with an `instanceId` navigates to\n * `/instances/<id>` via the host's router adapter.\n */\nexport function NotificationDrawer(): ReactElement | null {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const { close, isOpen } = useNotificationDrawer();\n const { refreshUnreadCount } = useNotificationUnread();\n const currentMemberId = member?.memberId ?? null;\n const [rows, setRows] = useState<readonly NotificationRecord[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [page, setPage] = useState(1);\n const [loading, setLoading] = useState(false);\n const [bulkLoading, setBulkLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [filter, setFilter] = useState<FilterValue>('all');\n\n const loadPage = useCallback(\n async (nextPage: number, append: boolean): Promise<void> => {\n if (!currentMemberId) return;\n setLoading(true);\n setError(null);\n try {\n const result = await listNotifications({\n includeRead: true,\n page: nextPage,\n pageSize: PAGE_SIZE,\n recipientMemberId: currentMemberId,\n });\n setRows((current): readonly NotificationRecord[] =>\n append ? [...current, ...result.notifications] : result.notifications,\n );\n setTotalCount(result.totalCount);\n setPage(nextPage);\n await refreshUnreadCount();\n } catch (e: unknown) {\n setError(readErrorMessage(e));\n } finally {\n setLoading(false);\n }\n },\n [currentMemberId, refreshUnreadCount],\n );\n\n useEffect((): void => {\n if (!isOpen || !currentMemberId) return;\n void loadPage(1, false);\n }, [isOpen, currentMemberId, loadPage]);\n\n const handleFilterChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>): void => {\n const next = event.target.value;\n if (next === 'all' || next === 'read' || next === 'unread') setFilter(next);\n },\n [],\n );\n\n const handleMarkAllRead = useCallback(async (): Promise<void> => {\n if (!currentMemberId || bulkLoading) return;\n setBulkLoading(true);\n setError(null);\n try {\n await markAllNotificationsRead({ recipientMemberId: currentMemberId });\n await loadPage(1, false);\n } catch (e: unknown) {\n setError(readErrorMessage(e));\n } finally {\n setBulkLoading(false);\n }\n }, [bulkLoading, currentMemberId, loadPage]);\n\n const handleLoadMore = useCallback((): void => {\n if (loading) return;\n void loadPage(page + 1, true);\n }, [loading, loadPage, page]);\n\n const handleMarkRead = useCallback(\n async (id: string): Promise<void> => {\n if (!currentMemberId) return;\n try {\n await markNotificationRead({ id, readerMemberId: currentMemberId });\n await loadPage(1, false);\n } catch (e: unknown) {\n setError(readErrorMessage(e));\n }\n },\n [currentMemberId, loadPage],\n );\n\n const handleOpenInstance = useCallback(\n async (record: NotificationRecord): Promise<void> => {\n if (!record.instanceId || !currentMemberId) return;\n try {\n if (record.status !== 'READ') {\n await markNotificationRead({\n id: record.id,\n readerMemberId: currentMemberId,\n });\n await refreshUnreadCount();\n }\n close();\n router.push(routes.caseDetail(record.instanceId));\n } catch (e: unknown) {\n setError(readErrorMessage(e));\n }\n },\n [close, currentMemberId, refreshUnreadCount, router, routes],\n );\n\n const filteredRows = useMemo(\n (): readonly NotificationRecord[] =>\n rows.filter((row): boolean => {\n if (filter === 'all') return true;\n if (filter === 'read') return row.status === 'READ';\n return row.status !== 'READ';\n }),\n [filter, rows],\n );\n\n const groupedRows = useMemo(\n (): ReadonlyArray<readonly [TimeGroup, readonly NotificationRecord[]]> => {\n const now = new Date();\n const buckets = TIME_GROUP_ORDER.reduce<\n Record<TimeGroup, NotificationRecord[]>\n >(\n (accumulator, group) => {\n accumulator[group] = [];\n return accumulator;\n },\n { earlier: [], past7Days: [], today: [], yesterday: [] },\n );\n filteredRows.forEach((row): void => {\n buckets[resolveTimeGroup(row.createdAt, now)].push(row);\n });\n return TIME_GROUP_ORDER.map(\n (group) => [group, buckets[group]] as const,\n ).filter(([, items]) => items.length > 0);\n },\n [filteredRows],\n );\n\n const hasMore = rows.length < totalCount;\n\n if (!currentMemberId) return null;\n\n return (\n <Drawer\n bottomGhostActionDisabled={bulkLoading || loading}\n bottomGhostActionLoading={bulkLoading}\n bottomGhostActionText=\"全部標為已讀\"\n bottomOnGhostActionClick={(): void => {\n void handleMarkAllRead();\n }}\n bottomOnPrimaryActionClick={(): void => {\n handleLoadMore();\n }}\n bottomPrimaryActionDisabled={!hasMore || loading}\n bottomPrimaryActionLoading={loading && hasMore}\n bottomPrimaryActionText={hasMore ? '載入更多' : '已顯示全部'}\n contentKey={`${filter}:${rows.length}`}\n filterAreaAllRadioLabel=\"全部\"\n filterAreaOnRadioChange={handleFilterChange}\n filterAreaReadRadioLabel=\"已讀\"\n filterAreaShow\n filterAreaUnreadRadioLabel=\"未讀\"\n filterAreaValue={filter}\n headerTitle=\"通知中心\"\n isBottomDisplay\n isHeaderDisplay\n onClose={close}\n open={isOpen}\n size=\"medium\"\n >\n <div role=\"list\">\n {error ? (\n <p\n role=\"alert\"\n style={{\n color: 'var(--mzn-color-text-error, #d92d20)',\n padding: '12px 16px',\n }}\n >\n {error}\n </p>\n ) : null}\n {groupedRows.length === 0 ? (\n <p\n style={{\n color: 'var(--mzn-color-text-secondary, #6b7280)',\n padding: '24px 16px',\n textAlign: 'center',\n }}\n >\n {loading ? '載入中…' : '目前沒有通知'}\n </p>\n ) : null}\n {groupedRows.map(([group, items], groupIndex) => (\n <Fragment key={group}>\n {items.map((record, itemIndex) => (\n <NotificationCenter\n appendTips={\n groupIndex === groupedRows.length - 1 &&\n itemIndex === items.length - 1 &&\n !hasMore\n ? '已顯示全部通知'\n : undefined\n }\n cancelButtonText={\n record.status !== 'READ' ? '標為已讀' : undefined\n }\n description={record.body}\n key={record.id}\n onCancel={\n record.status !== 'READ'\n ? (): void => {\n void handleMarkRead(record.id);\n }\n : undefined\n }\n onConfirm={\n record.instanceId\n ? (): void => {\n void handleOpenInstance(record);\n }\n : undefined\n }\n confirmButtonText={record.instanceId ? '查看案件' : undefined}\n prependTips={itemIndex === 0 ? TIME_GROUP_LABEL[group] : undefined}\n reference={record.id}\n severity={toSeverity(record.type)}\n showBadge={record.status !== 'READ'}\n timeStamp={record.createdAt}\n title={record.title}\n type=\"drawer\"\n />\n ))}\n </Fragment>\n ))}\n </div>\n </Drawer>\n );\n}\n\nfunction toSeverity(type: NotificationType): NotificationSeverity {\n if (type === 'SLA_OVERDUE') return 'error';\n if (type === 'SLA_WARNING') return 'warning';\n if (type === 'INSTANCE_COMPLETED') return 'success';\n return 'info';\n}\n\nfunction resolveTimeGroup(value: string, now: Date): TimeGroup {\n const notificationDate = new Date(value);\n if (Number.isNaN(notificationDate.getTime())) return 'earlier';\n const nowStartOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const notificationStartOfDay = new Date(\n notificationDate.getFullYear(),\n notificationDate.getMonth(),\n notificationDate.getDate(),\n );\n if (notificationStartOfDay.getTime() === nowStartOfDay.getTime()) return 'today';\n const yesterdayStartOfDay = new Date(nowStartOfDay);\n yesterdayStartOfDay.setDate(yesterdayStartOfDay.getDate() - 1);\n if (notificationStartOfDay.getTime() === yesterdayStartOfDay.getTime())\n return 'yesterday';\n const diffInDays =\n (now.getTime() - notificationDate.getTime()) / (1000 * 60 * 60 * 24);\n if (diffInDays <= 7) return 'past7Days';\n return 'earlier';\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n","'use client';\n\nimport type { ReactElement, ReactNode } from 'react';\nimport {\n CalendarConfigProviderMoment,\n CalendarLocale,\n} from '@mezzanine-ui/react/moment';\nimport { AuthProvider } from './auth-provider';\nimport { NotificationDrawer } from '../components/notification-drawer';\nimport { NotificationDrawerProvider } from './notification-drawer-provider';\nimport { NotificationUnreadProvider } from './notification-unread-provider';\n\ninterface ProvidersProps {\n readonly children: ReactNode;\n /** Override Mezzanine calendar locale. Defaults to `CalendarLocale.ZH_TW`. */\n readonly locale?: CalendarLocale;\n /**\n * Public paths that should not trigger redirect to `/login` when there\n * is no session. Forwarded to `<AuthProvider>`. Defaults to `['/login']`.\n */\n readonly publicPaths?: readonly string[];\n /** Where to send unauthenticated users. Defaults to `'/login'`. */\n readonly loginPath?: string;\n}\n\n/**\n * One-stop BPM admin provider stack. Wires:\n *\n * - Mezzanine UI calendar locale (moment-based, `ZH_TW` by default)\n * - `<AuthProvider>` (BPM session via REST `/auth/*`)\n * - `<NotificationUnreadProvider>` (polls unread count)\n * - `<NotificationDrawerProvider>` (controls drawer open/close state)\n * - `<NotificationDrawer />` mounted at the root so the bell-icon button in\n * `<AppLayout />` can open it.\n *\n * Consumer hosts wrap this **inside** a `<RouterAdapterProvider>` (provided\n * by the `pages/*` subpath shims when consuming via Next.js, or wired by\n * hand for other frameworks).\n */\nexport function Providers({\n children,\n locale = CalendarLocale.ZH_TW,\n publicPaths,\n loginPath,\n}: ProvidersProps): ReactElement {\n return (\n <CalendarConfigProviderMoment locale={locale}>\n <AuthProvider publicPaths={publicPaths} loginPath={loginPath}>\n <NotificationUnreadProvider>\n <NotificationDrawerProvider>\n {children}\n <NotificationDrawer />\n </NotificationDrawerProvider>\n </NotificationUnreadProvider>\n </AuthProvider>\n </CalendarConfigProviderMoment>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/lib/notification-drawer-provider.tsx","../src/lib/notification-unread-provider.tsx","../src/components/notification-drawer.tsx","../src/lib/providers.tsx","../src/lib/use-bpm-logout.ts","../src/lib/use-bpm-member.ts","../src/components/bpm-notification-bell-button.module.scss","../src/components/bpm-notification-bell-button.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\n\ninterface NotificationDrawerContextValue {\n readonly close: () => void;\n readonly isOpen: boolean;\n readonly open: () => void;\n readonly toggle: () => void;\n}\n\nconst NotificationDrawerContext =\n createContext<NotificationDrawerContextValue | null>(null);\n\ninterface NotificationDrawerProviderProps {\n readonly children: ReactNode;\n}\n\n/**\n * Controls the open/closed state of the BPM notification drawer. Wraps\n * children with a context that `<NotificationDrawer />` reads to mount /\n * hide itself, and that the host navigation reads (via\n * `<BPMNotificationBellButton />` or `useNotificationDrawer().open`) to\n * open the drawer when the bell icon is clicked.\n *\n * When used outside this provider, the returned hook is a safe no-op so\n * components don't crash in test or storybook environments.\n */\nexport function NotificationDrawerProvider({\n children,\n}: NotificationDrawerProviderProps): ReactElement {\n const [isOpen, setIsOpen] = useState(false);\n\n const open = useCallback((): void => {\n setIsOpen(true);\n }, []);\n const close = useCallback((): void => {\n setIsOpen(false);\n }, []);\n const toggle = useCallback((): void => {\n setIsOpen((current) => !current);\n }, []);\n\n const value = useMemo<NotificationDrawerContextValue>(\n () => ({ close, isOpen, open, toggle }),\n [close, isOpen, open, toggle],\n );\n\n return (\n <NotificationDrawerContext.Provider value={value}>\n {children}\n </NotificationDrawerContext.Provider>\n );\n}\n\n/**\n * Read the BPM notification drawer's open state and control helpers.\n * Returns a no-op stub when used outside `<NotificationDrawerProvider>`.\n */\nexport function useNotificationDrawer(): NotificationDrawerContextValue {\n const context = useContext(NotificationDrawerContext);\n if (!context) {\n return {\n close: (): void => undefined,\n isOpen: false,\n open: (): void => undefined,\n toggle: (): void => undefined,\n };\n }\n return context;\n}\n","'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { readUnreadNotificationCount } from '@rytass/bpm-core-client/workflow';\nimport { useAuth } from './auth-provider';\n\ninterface NotificationUnreadContextValue {\n readonly refreshUnreadCount: () => Promise<number>;\n readonly unreadCount: number;\n}\n\nconst NotificationUnreadContext =\n createContext<NotificationUnreadContextValue | null>(null);\n\ninterface NotificationUnreadProviderProps {\n readonly children: ReactNode;\n}\n\n/**\n * Polls BPM for the current member's unread notification count via\n * `readUnreadNotificationCount` and exposes it through context for the\n * host navigation (`<BPMNotificationBellButton />` badge or any custom\n * trigger using `useNotificationUnread().unreadCount`) and the BPM\n * `<NotificationDrawer />` (header count). Refresh is triggered on\n * mount and whenever the auth member id changes; consumers can call\n * `refreshUnreadCount()` after acknowledging a notification.\n */\nexport function NotificationUnreadProvider({\n children,\n}: NotificationUnreadProviderProps): ReactElement {\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [unreadCount, setUnreadCount] = useState(0);\n\n const refreshUnreadCount = useCallback(async (): Promise<number> => {\n if (!currentMemberId) {\n setUnreadCount(0);\n return 0;\n }\n const next = await readUnreadNotificationCount(currentMemberId);\n setUnreadCount(next);\n return next;\n }, [currentMemberId]);\n\n useEffect((): (() => void) => {\n let active = true;\n void (async () => {\n try {\n const next = await refreshUnreadCount();\n if (active) setUnreadCount(next);\n } catch {\n if (active) setUnreadCount(0);\n }\n })();\n return (): void => {\n active = false;\n };\n }, [refreshUnreadCount]);\n\n const value = useMemo<NotificationUnreadContextValue>(\n () => ({ refreshUnreadCount, unreadCount }),\n [refreshUnreadCount, unreadCount],\n );\n\n return (\n <NotificationUnreadContext.Provider value={value}>\n {children}\n </NotificationUnreadContext.Provider>\n );\n}\n\n/**\n * Read the current unread-notification count and a manual refresh helper.\n * Returns a zero/no-op stub when used outside\n * `<NotificationUnreadProvider>`.\n */\nexport function useNotificationUnread(): NotificationUnreadContextValue {\n const context = useContext(NotificationUnreadContext);\n if (!context) {\n return {\n refreshUnreadCount: async (): Promise<number> => 0,\n unreadCount: 0,\n };\n }\n return context;\n}\n","'use client';\n\nimport {\n Fragment,\n useCallback,\n useEffect,\n useMemo,\n useState,\n type ChangeEvent,\n type ReactElement,\n} from 'react';\nimport Drawer from '@mezzanine-ui/react/Drawer';\nimport NotificationCenter from '@mezzanine-ui/react/NotificationCenter';\nimport type { NotificationSeverity } from '@mezzanine-ui/core/notification-center';\nimport {\n listNotifications,\n markAllNotificationsRead,\n markNotificationRead,\n type NotificationRecord,\n type NotificationType,\n} from '@rytass/bpm-core-client/workflow';\nimport { useAuth } from '../lib/auth-provider';\nimport { useNotificationDrawer } from '../lib/notification-drawer-provider';\nimport { useNotificationUnread } from '../lib/notification-unread-provider';\nimport { useRouterAdapter } from '../lib/router-adapter';\nimport { useBPMRoutes } from '../lib/routes-config';\n\ntype FilterValue = 'all' | 'read' | 'unread';\n\ntype TimeGroup = 'today' | 'yesterday' | 'past7Days' | 'earlier';\n\nconst TIME_GROUP_ORDER: readonly TimeGroup[] = [\n 'today',\n 'yesterday',\n 'past7Days',\n 'earlier',\n];\n\nconst TIME_GROUP_LABEL: Readonly<Record<TimeGroup, string>> = {\n earlier: '更早',\n past7Days: '過去七天',\n today: '今天',\n yesterday: '昨天',\n};\n\nconst PAGE_SIZE = 50;\n\n/**\n * Right-side notification drawer mounted at the root by `<Providers>`.\n * Opens / closes via `useNotificationDrawer()`, polls\n * `listNotifications()` for the current member, supports filter\n * (`all` / `read` / `unread`), per-row mark-read, bulk mark-all-read, and\n * load-more pagination. Clicking a row with an `instanceId` navigates to\n * `/instances/<id>` via the host's router adapter.\n */\nexport function NotificationDrawer(): ReactElement | null {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const { close, isOpen } = useNotificationDrawer();\n const { refreshUnreadCount } = useNotificationUnread();\n const currentMemberId = member?.memberId ?? null;\n const [rows, setRows] = useState<readonly NotificationRecord[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [page, setPage] = useState(1);\n const [loading, setLoading] = useState(false);\n const [bulkLoading, setBulkLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [filter, setFilter] = useState<FilterValue>('all');\n\n const loadPage = useCallback(\n async (nextPage: number, append: boolean): Promise<void> => {\n if (!currentMemberId) return;\n setLoading(true);\n setError(null);\n try {\n const result = await listNotifications({\n includeRead: true,\n page: nextPage,\n pageSize: PAGE_SIZE,\n recipientMemberId: currentMemberId,\n });\n setRows((current): readonly NotificationRecord[] =>\n append ? [...current, ...result.notifications] : result.notifications,\n );\n setTotalCount(result.totalCount);\n setPage(nextPage);\n await refreshUnreadCount();\n } catch (e: unknown) {\n setError(readErrorMessage(e));\n } finally {\n setLoading(false);\n }\n },\n [currentMemberId, refreshUnreadCount],\n );\n\n useEffect((): void => {\n if (!isOpen || !currentMemberId) return;\n void loadPage(1, false);\n }, [isOpen, currentMemberId, loadPage]);\n\n const handleFilterChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>): void => {\n const next = event.target.value;\n if (next === 'all' || next === 'read' || next === 'unread') setFilter(next);\n },\n [],\n );\n\n const handleMarkAllRead = useCallback(async (): Promise<void> => {\n if (!currentMemberId || bulkLoading) return;\n setBulkLoading(true);\n setError(null);\n try {\n await markAllNotificationsRead({ recipientMemberId: currentMemberId });\n await loadPage(1, false);\n } catch (e: unknown) {\n setError(readErrorMessage(e));\n } finally {\n setBulkLoading(false);\n }\n }, [bulkLoading, currentMemberId, loadPage]);\n\n const handleLoadMore = useCallback((): void => {\n if (loading) return;\n void loadPage(page + 1, true);\n }, [loading, loadPage, page]);\n\n const handleMarkRead = useCallback(\n async (id: string): Promise<void> => {\n if (!currentMemberId) return;\n try {\n await markNotificationRead({ id, readerMemberId: currentMemberId });\n await loadPage(1, false);\n } catch (e: unknown) {\n setError(readErrorMessage(e));\n }\n },\n [currentMemberId, loadPage],\n );\n\n const handleOpenInstance = useCallback(\n async (record: NotificationRecord): Promise<void> => {\n if (!record.instanceId || !currentMemberId) return;\n try {\n if (record.status !== 'READ') {\n await markNotificationRead({\n id: record.id,\n readerMemberId: currentMemberId,\n });\n await refreshUnreadCount();\n }\n close();\n router.push(routes.caseDetail(record.instanceId));\n } catch (e: unknown) {\n setError(readErrorMessage(e));\n }\n },\n [close, currentMemberId, refreshUnreadCount, router, routes],\n );\n\n const filteredRows = useMemo(\n (): readonly NotificationRecord[] =>\n rows.filter((row): boolean => {\n if (filter === 'all') return true;\n if (filter === 'read') return row.status === 'READ';\n return row.status !== 'READ';\n }),\n [filter, rows],\n );\n\n const groupedRows = useMemo(\n (): ReadonlyArray<readonly [TimeGroup, readonly NotificationRecord[]]> => {\n const now = new Date();\n const buckets = TIME_GROUP_ORDER.reduce<\n Record<TimeGroup, NotificationRecord[]>\n >(\n (accumulator, group) => {\n accumulator[group] = [];\n return accumulator;\n },\n { earlier: [], past7Days: [], today: [], yesterday: [] },\n );\n filteredRows.forEach((row): void => {\n buckets[resolveTimeGroup(row.createdAt, now)].push(row);\n });\n return TIME_GROUP_ORDER.map(\n (group) => [group, buckets[group]] as const,\n ).filter(([, items]) => items.length > 0);\n },\n [filteredRows],\n );\n\n const hasMore = rows.length < totalCount;\n\n if (!currentMemberId) return null;\n\n return (\n <Drawer\n bottomGhostActionDisabled={bulkLoading || loading}\n bottomGhostActionLoading={bulkLoading}\n bottomGhostActionText=\"全部標為已讀\"\n bottomOnGhostActionClick={(): void => {\n void handleMarkAllRead();\n }}\n bottomOnPrimaryActionClick={(): void => {\n handleLoadMore();\n }}\n bottomPrimaryActionDisabled={!hasMore || loading}\n bottomPrimaryActionLoading={loading && hasMore}\n bottomPrimaryActionText={hasMore ? '載入更多' : '已顯示全部'}\n contentKey={`${filter}:${rows.length}`}\n filterAreaAllRadioLabel=\"全部\"\n filterAreaOnRadioChange={handleFilterChange}\n filterAreaReadRadioLabel=\"已讀\"\n filterAreaShow\n filterAreaUnreadRadioLabel=\"未讀\"\n filterAreaValue={filter}\n headerTitle=\"通知中心\"\n isBottomDisplay\n isHeaderDisplay\n onClose={close}\n open={isOpen}\n size=\"medium\"\n >\n <div role=\"list\">\n {error ? (\n <p\n role=\"alert\"\n style={{\n color: 'var(--mzn-color-text-error, #d92d20)',\n padding: '12px 16px',\n }}\n >\n {error}\n </p>\n ) : null}\n {groupedRows.length === 0 ? (\n <p\n style={{\n color: 'var(--mzn-color-text-secondary, #6b7280)',\n padding: '24px 16px',\n textAlign: 'center',\n }}\n >\n {loading ? '載入中…' : '目前沒有通知'}\n </p>\n ) : null}\n {groupedRows.map(([group, items], groupIndex) => (\n <Fragment key={group}>\n {items.map((record, itemIndex) => (\n <NotificationCenter\n appendTips={\n groupIndex === groupedRows.length - 1 &&\n itemIndex === items.length - 1 &&\n !hasMore\n ? '已顯示全部通知'\n : undefined\n }\n cancelButtonText={\n record.status !== 'READ' ? '標為已讀' : undefined\n }\n description={record.body}\n key={record.id}\n onCancel={\n record.status !== 'READ'\n ? (): void => {\n void handleMarkRead(record.id);\n }\n : undefined\n }\n onConfirm={\n record.instanceId\n ? (): void => {\n void handleOpenInstance(record);\n }\n : undefined\n }\n confirmButtonText={record.instanceId ? '查看案件' : undefined}\n prependTips={itemIndex === 0 ? TIME_GROUP_LABEL[group] : undefined}\n reference={record.id}\n severity={toSeverity(record.type)}\n showBadge={record.status !== 'READ'}\n timeStamp={record.createdAt}\n title={record.title}\n type=\"drawer\"\n />\n ))}\n </Fragment>\n ))}\n </div>\n </Drawer>\n );\n}\n\nfunction toSeverity(type: NotificationType): NotificationSeverity {\n if (type === 'SLA_OVERDUE') return 'error';\n if (type === 'SLA_WARNING') return 'warning';\n if (type === 'INSTANCE_COMPLETED') return 'success';\n return 'info';\n}\n\nfunction resolveTimeGroup(value: string, now: Date): TimeGroup {\n const notificationDate = new Date(value);\n if (Number.isNaN(notificationDate.getTime())) return 'earlier';\n const nowStartOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const notificationStartOfDay = new Date(\n notificationDate.getFullYear(),\n notificationDate.getMonth(),\n notificationDate.getDate(),\n );\n if (notificationStartOfDay.getTime() === nowStartOfDay.getTime()) return 'today';\n const yesterdayStartOfDay = new Date(nowStartOfDay);\n yesterdayStartOfDay.setDate(yesterdayStartOfDay.getDate() - 1);\n if (notificationStartOfDay.getTime() === yesterdayStartOfDay.getTime())\n return 'yesterday';\n const diffInDays =\n (now.getTime() - notificationDate.getTime()) / (1000 * 60 * 60 * 24);\n if (diffInDays <= 7) return 'past7Days';\n return 'earlier';\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n","'use client';\n\nimport type { ReactElement, ReactNode } from 'react';\nimport {\n CalendarConfigProviderMoment,\n CalendarLocale,\n} from '@mezzanine-ui/react/moment';\nimport { AuthProvider } from './auth-provider';\nimport { NotificationDrawer } from '../components/notification-drawer';\nimport { NotificationDrawerProvider } from './notification-drawer-provider';\nimport { NotificationUnreadProvider } from './notification-unread-provider';\n\ninterface ProvidersProps {\n readonly children: ReactNode;\n /** Override Mezzanine calendar locale. Defaults to `CalendarLocale.ZH_TW`. */\n readonly locale?: CalendarLocale;\n /**\n * Public paths that should not trigger redirect to `/login` when there\n * is no session. Forwarded to `<AuthProvider>`. Defaults to `['/login']`.\n */\n readonly publicPaths?: readonly string[];\n /** Where to send unauthenticated users. Defaults to `'/login'`. */\n readonly loginPath?: string;\n}\n\n/**\n * One-stop BPM admin provider stack. Wires:\n *\n * - Mezzanine UI calendar locale (moment-based, `ZH_TW` by default)\n * - `<AuthProvider>` (BPM session via REST `/auth/*`)\n * - `<NotificationUnreadProvider>` (polls unread count)\n * - `<NotificationDrawerProvider>` (controls drawer open/close state)\n * - `<NotificationDrawer />` mounted at the root so the host navigation\n * bell (`<BPMNotificationBellButton />` or any custom trigger calling\n * `useNotificationDrawer().open`) can open it.\n *\n * Consumer hosts wrap this **inside** a `<RouterAdapterProvider>` (provided\n * by the `pages/*` subpath shims when consuming via Next.js, or wired by\n * hand for other frameworks).\n */\nexport function Providers({\n children,\n locale = CalendarLocale.ZH_TW,\n publicPaths,\n loginPath,\n}: ProvidersProps): ReactElement {\n return (\n <CalendarConfigProviderMoment locale={locale}>\n <AuthProvider publicPaths={publicPaths} loginPath={loginPath}>\n <NotificationUnreadProvider>\n <NotificationDrawerProvider>\n {children}\n <NotificationDrawer />\n </NotificationDrawerProvider>\n </NotificationUnreadProvider>\n </AuthProvider>\n </CalendarConfigProviderMoment>\n );\n}\n","'use client';\n\nimport { useAuth } from './auth-provider';\n\n/**\n * Drop-in logout handler for host navigation menus. Wraps the BPM auth\n * context's logout flow — calls `logoutApi()` against the BPM REST\n * session endpoint, clears the in-memory member, then redirects to the\n * configured `loginPath`.\n *\n * Hosts mount this on their own logout buttons / menu items so they do\n * not need to touch `useAuth()` directly. To customize the post-logout\n * destination, override the `loginPath` prop on `<BPMNextProviders>` or\n * `<AuthProvider>`.\n */\nexport function useBPMLogout(): () => Promise<void> {\n const { logout } = useAuth();\n return logout;\n}\n","'use client';\n\nimport type { ApiMember } from '@rytass/bpm-core-client';\nimport { useAuth } from './auth-provider';\n\n/**\n * Read the currently authenticated BPM member. Returns `null` when there\n * is no active session — typically only seen on the login page or during\n * the brief loading window before `<AuthProvider>` resolves the cookie.\n *\n * Convenience alias for `useAuth().member` aimed at host navigations\n * (avatar, display name, role-based menu visibility) that should not\n * depend on the broader `useAuth()` surface.\n */\nexport function useBPMMember(): ApiMember | null {\n const { member } = useAuth();\n return member;\n}\n",".root {\n display: inline-flex;\n position: relative;\n}\n\n.badge {\n align-items: center;\n background: #d92d20;\n border: 1px solid #fff;\n border-radius: 999px;\n color: #fff;\n display: inline-flex;\n font-size: 10px;\n font-weight: 600;\n height: 16px;\n justify-content: center;\n line-height: 1;\n min-width: 16px;\n padding: 0 4px;\n pointer-events: none;\n position: absolute;\n right: -4px;\n top: -4px;\n}\n","'use client';\n\nimport type { ReactElement } from 'react';\nimport { NavigationIconButton } from '@mezzanine-ui/react';\nimport { NotificationUnreadIcon } from '@mezzanine-ui/icons';\nimport { useNotificationDrawer } from '../lib/notification-drawer-provider';\nimport { useNotificationUnread } from '../lib/notification-unread-provider';\nimport styles from './bpm-notification-bell-button.module.scss';\n\nexport interface BPMNotificationBellButtonProps {\n /** Override the aria-label / tooltip. Defaults to `通知中心`. */\n readonly label?: string;\n}\n\n/**\n * Drop-in notification bell. Reads the unread count from\n * `<NotificationUnreadProvider>`, opens the BPM `<NotificationDrawer />`\n * mounted by `<Providers>` (or `<BPMNextProviders>`) on click, and\n * renders a small red badge with the unread count.\n *\n * Use this when the host navigation wants the BPM notification UX with\n * minimum wiring. Hosts that need a fully custom button can skip this\n * widget and consume `useNotificationDrawer()` + `useNotificationUnread()`\n * directly to wire their own trigger.\n *\n * Visual: uses Mezzanine `NavigationIconButton` so the bell aligns with\n * surrounding Mezzanine navigation chrome. The button is decoupled from\n * the `<Navigation>` container — it does not require a Mezzanine\n * navigation tree to render.\n */\nexport function BPMNotificationBellButton({\n label = '通知中心',\n}: BPMNotificationBellButtonProps = {}): ReactElement {\n const { open } = useNotificationDrawer();\n const { unreadCount } = useNotificationUnread();\n const ariaLabel = unreadCount > 0 ? `${label},${unreadCount} 則未讀` : label;\n return (\n <span className={styles.root}>\n <NavigationIconButton\n aria-label={ariaLabel}\n icon={NotificationUnreadIcon}\n onClick={(): void => {\n open();\n }}\n title={label}\n type=\"button\"\n />\n {unreadCount > 0 ? (\n <span className={styles.badge}>\n {unreadCount > 99 ? '99+' : unreadCount}\n </span>\n ) : null}\n </span>\n );\n}\n"],"mappings":"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"}
|
|
@@ -11,8 +11,9 @@ interface NotificationDrawerProviderProps {
|
|
|
11
11
|
/**
|
|
12
12
|
* Controls the open/closed state of the BPM notification drawer. Wraps
|
|
13
13
|
* children with a context that `<NotificationDrawer />` reads to mount /
|
|
14
|
-
* hide itself, and that
|
|
15
|
-
*
|
|
14
|
+
* hide itself, and that the host navigation reads (via
|
|
15
|
+
* `<BPMNotificationBellButton />` or `useNotificationDrawer().open`) to
|
|
16
|
+
* open the drawer when the bell icon is clicked.
|
|
16
17
|
*
|
|
17
18
|
* When used outside this provider, the returned hook is a safe no-op so
|
|
18
19
|
* components don't crash in test or storybook environments.
|
|
@@ -8,11 +8,12 @@ interface NotificationUnreadProviderProps {
|
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
10
|
* Polls BPM for the current member's unread notification count via
|
|
11
|
-
* `readUnreadNotificationCount` and exposes it through context for
|
|
12
|
-
* `<
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
11
|
+
* `readUnreadNotificationCount` and exposes it through context for the
|
|
12
|
+
* host navigation (`<BPMNotificationBellButton />` badge or any custom
|
|
13
|
+
* trigger using `useNotificationUnread().unreadCount`) and the BPM
|
|
14
|
+
* `<NotificationDrawer />` (header count). Refresh is triggered on
|
|
15
|
+
* mount and whenever the auth member id changes; consumers can call
|
|
16
|
+
* `refreshUnreadCount()` after acknowledging a notification.
|
|
16
17
|
*/
|
|
17
18
|
export declare function NotificationUnreadProvider({ children, }: NotificationUnreadProviderProps): ReactElement;
|
|
18
19
|
/**
|
package/dist/lib/providers.d.ts
CHANGED
|
@@ -19,8 +19,9 @@ interface ProvidersProps {
|
|
|
19
19
|
* - `<AuthProvider>` (BPM session via REST `/auth/*`)
|
|
20
20
|
* - `<NotificationUnreadProvider>` (polls unread count)
|
|
21
21
|
* - `<NotificationDrawerProvider>` (controls drawer open/close state)
|
|
22
|
-
* - `<NotificationDrawer />` mounted at the root so the
|
|
23
|
-
* `<
|
|
22
|
+
* - `<NotificationDrawer />` mounted at the root so the host navigation
|
|
23
|
+
* bell (`<BPMNotificationBellButton />` or any custom trigger calling
|
|
24
|
+
* `useNotificationDrawer().open`) can open it.
|
|
24
25
|
*
|
|
25
26
|
* Consumer hosts wrap this **inside** a `<RouterAdapterProvider>` (provided
|
|
26
27
|
* by the `pages/*` subpath shims when consuming via Next.js, or wired by
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drop-in logout handler for host navigation menus. Wraps the BPM auth
|
|
3
|
+
* context's logout flow — calls `logoutApi()` against the BPM REST
|
|
4
|
+
* session endpoint, clears the in-memory member, then redirects to the
|
|
5
|
+
* configured `loginPath`.
|
|
6
|
+
*
|
|
7
|
+
* Hosts mount this on their own logout buttons / menu items so they do
|
|
8
|
+
* not need to touch `useAuth()` directly. To customize the post-logout
|
|
9
|
+
* destination, override the `loginPath` prop on `<BPMNextProviders>` or
|
|
10
|
+
* `<AuthProvider>`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function useBPMLogout(): () => Promise<void>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ApiMember } from '@rytass/bpm-core-client';
|
|
2
|
+
/**
|
|
3
|
+
* Read the currently authenticated BPM member. Returns `null` when there
|
|
4
|
+
* is no active session — typically only seen on the login page or during
|
|
5
|
+
* the brief loading window before `<AuthProvider>` resolves the cookie.
|
|
6
|
+
*
|
|
7
|
+
* Convenience alias for `useAuth().member` aimed at host navigations
|
|
8
|
+
* (avatar, display name, role-based menu visibility) that should not
|
|
9
|
+
* depend on the broader `useAuth()` surface.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useBPMMember(): ApiMember | null;
|
|
@@ -48,4 +48,4 @@ export interface BPMNextProvidersProps {
|
|
|
48
48
|
* (BPM internal navigation), additionally wrap with
|
|
49
49
|
* `<BPMRoutesProvider>` exported from the same subpath.
|
|
50
50
|
*/
|
|
51
|
-
export declare function BPMNextProviders(
|
|
51
|
+
export declare function BPMNextProviders({ children, locale, publicPaths, loginPath, }: BPMNextProvidersProps): ReactElement;
|
package/dist/next/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../chunks/routes-config-2aKbWq2H.cjs");let t=require("react"),n=require("react/jsx-runtime"),r=require("next/navigation"),i=require("@rytass/bpm-core-react");function a({children:e,locale:a,publicPaths:o,loginPath:s}){let c=(0,r.useRouter)(),l=(0,r.usePathname)()
|
|
1
|
+
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../chunks/routes-config-2aKbWq2H.cjs");let t=require("react"),n=require("react/jsx-runtime"),r=require("next/navigation"),i=require("@rytass/bpm-core-react");function a({children:e,locale:a,publicPaths:o,loginPath:s}){let c=(0,r.useRouter)(),l=(0,r.usePathname)();return(0,n.jsx)(i.RouterAdapterProvider,{value:(0,t.useMemo)(()=>({pathname:l,push:e=>c.push(e),replace:e=>c.replace(e),back:()=>c.back(),searchParams:()=>(0,i.defaultBrowserSearchParams)()}),[c,l]),children:(0,n.jsx)(i.Providers,{locale:a,publicPaths:o,loginPath:s,children:e})})}exports.BPMNextProviders=a,exports.BPMRoutesProvider=e.t,exports.createDefaultBPMRoutes=e.n,exports.useBPMRoutes=e.r;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|