strapi-plugin-notifier 1.0.2 → 1.1.0

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.
@@ -0,0 +1,221 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect, useRef } from "react";
3
+ import { useFetchClient } from "@strapi/admin/strapi-admin";
4
+ let items = [];
5
+ let countSubscribers = [];
6
+ let itemSubscribers = [];
7
+ const getUnreadCount = () => items.filter((n) => !n.read).length;
8
+ const broadcastCount = () => {
9
+ const n = getUnreadCount();
10
+ countSubscribers.forEach((fn) => fn(n));
11
+ };
12
+ const broadcastItems = () => {
13
+ const snapshot = [...items];
14
+ itemSubscribers.forEach((fn) => fn(snapshot));
15
+ broadcastCount();
16
+ };
17
+ const getNotificationCount = () => getUnreadCount();
18
+ const getNotifications = () => [...items];
19
+ const subscribeToCount = (fn) => {
20
+ countSubscribers.push(fn);
21
+ return () => {
22
+ countSubscribers = countSubscribers.filter((s) => s !== fn);
23
+ };
24
+ };
25
+ const subscribeToNotifications = (fn) => {
26
+ itemSubscribers.push(fn);
27
+ return () => {
28
+ itemSubscribers = itemSubscribers.filter((s) => s !== fn);
29
+ };
30
+ };
31
+ const setNotifications = (next) => {
32
+ items = next;
33
+ broadcastItems();
34
+ };
35
+ const markAsRead = (id) => {
36
+ items = items.map((n) => n.id === id ? { ...n, read: true } : n);
37
+ broadcastItems();
38
+ };
39
+ const markAllAsRead = () => {
40
+ items = items.map((n) => ({ ...n, read: true }));
41
+ broadcastItems();
42
+ };
43
+ const clearNotification = (id) => {
44
+ items = items.filter((n) => n.id !== id);
45
+ broadcastItems();
46
+ };
47
+ const clearAll = () => {
48
+ items = [];
49
+ broadcastItems();
50
+ };
51
+ const useNotificationCount = () => {
52
+ const [count, setCount] = useState(getNotificationCount);
53
+ useEffect(() => subscribeToCount(setCount), []);
54
+ return count;
55
+ };
56
+ const DEFAULT_CONFIG = {
57
+ pollIntervalMs: 3e4,
58
+ pageSize: 20,
59
+ theme: {
60
+ accent: {
61
+ info: "#4945ff",
62
+ success: "#5cb85c",
63
+ warning: "#f0ad4e",
64
+ error: "#ee5e52"
65
+ }
66
+ }
67
+ };
68
+ let config = DEFAULT_CONFIG;
69
+ let subscribers = [];
70
+ const getConfig = () => config;
71
+ const setConfig = (next) => {
72
+ config = { ...DEFAULT_CONFIG, ...next, theme: { accent: { ...DEFAULT_CONFIG.theme.accent, ...next?.theme?.accent } } };
73
+ subscribers.forEach((fn) => fn(config));
74
+ };
75
+ const subscribeToConfig = (fn) => {
76
+ subscribers.push(fn);
77
+ return () => {
78
+ subscribers = subscribers.filter((s) => s !== fn);
79
+ };
80
+ };
81
+ const usePluginConfig = () => {
82
+ const [config2, setConfig2] = useState(getConfig);
83
+ useEffect(() => subscribeToConfig(setConfig2), []);
84
+ return config2;
85
+ };
86
+ const toStoreNotification = (n) => ({
87
+ id: String(n.id),
88
+ title: n.title,
89
+ message: n.message ?? "",
90
+ type: n.type ?? "info",
91
+ read: n.read,
92
+ createdAt: n.createdAt,
93
+ url: n.url
94
+ });
95
+ function Bell() {
96
+ const count = useNotificationCount();
97
+ const config2 = usePluginConfig();
98
+ const { get } = useFetchClient();
99
+ const configLoaded = useRef(false);
100
+ useEffect(() => {
101
+ if (configLoaded.current) return;
102
+ configLoaded.current = true;
103
+ get("/notifier/config").then(({ data }) => {
104
+ if (data) setConfig(data);
105
+ }).catch(() => {
106
+ });
107
+ }, [get]);
108
+ useEffect(() => {
109
+ const poll = async () => {
110
+ try {
111
+ const { data } = await get(`/notifier/notifications?page=1&pageSize=${config2.pageSize}`);
112
+ if (Array.isArray(data?.data)) {
113
+ setNotifications(data.data.map(toStoreNotification));
114
+ }
115
+ } catch {
116
+ }
117
+ };
118
+ poll();
119
+ const id = setInterval(poll, config2.pollIntervalMs);
120
+ return () => clearInterval(id);
121
+ }, [get, config2.pollIntervalMs, config2.pageSize]);
122
+ return /* @__PURE__ */ jsxs("span", { style: { position: "relative", display: "inline-flex" }, children: [
123
+ /* @__PURE__ */ jsxs(
124
+ "svg",
125
+ {
126
+ xmlns: "http://www.w3.org/2000/svg",
127
+ viewBox: "0 0 24 24",
128
+ fill: "none",
129
+ stroke: "currentColor",
130
+ strokeWidth: "2",
131
+ strokeLinecap: "round",
132
+ strokeLinejoin: "round",
133
+ width: "1.5em",
134
+ height: "1.5em",
135
+ children: [
136
+ /* @__PURE__ */ jsx("path", { d: "M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" }),
137
+ /* @__PURE__ */ jsx("path", { d: "M13.73 21a2 2 0 0 1-3.46 0" })
138
+ ]
139
+ }
140
+ ),
141
+ count > 0 && /* @__PURE__ */ jsx(
142
+ "span",
143
+ {
144
+ "aria-label": `${count} unread notification${count === 1 ? "" : "s"}`,
145
+ style: {
146
+ position: "absolute",
147
+ top: "-5px",
148
+ right: "-6px",
149
+ backgroundColor: "#ee5e52",
150
+ color: "#fff",
151
+ borderRadius: "9px",
152
+ fontSize: "9px",
153
+ fontWeight: 700,
154
+ height: "13px",
155
+ minWidth: "13px",
156
+ display: "flex",
157
+ alignItems: "center",
158
+ justifyContent: "center",
159
+ padding: "0 2px",
160
+ lineHeight: 1,
161
+ pointerEvents: "none"
162
+ },
163
+ children: count > 99 ? "99+" : count
164
+ }
165
+ )
166
+ ] });
167
+ }
168
+ const pluginId = "notifier";
169
+ const index = {
170
+ register(app) {
171
+ app.addMenuLink({
172
+ to: `/plugins/${pluginId}`,
173
+ icon: Bell,
174
+ intlLabel: {
175
+ id: `${pluginId}.plugin.name`,
176
+ defaultMessage: "Notifications"
177
+ },
178
+ permissions: [],
179
+ Component: () => import("./Index-_PTtaZsz.mjs")
180
+ });
181
+ app.createSettingSection(
182
+ {
183
+ id: pluginId,
184
+ intlLabel: {
185
+ id: `${pluginId}.settings.section`,
186
+ defaultMessage: "Notifier"
187
+ }
188
+ },
189
+ [
190
+ {
191
+ intlLabel: {
192
+ id: `${pluginId}.settings.page`,
193
+ defaultMessage: "Configuration"
194
+ },
195
+ id: `${pluginId}.settings`,
196
+ to: `/settings/${pluginId}`,
197
+ Component: () => import("./SettingsPage-CuTIslG0.mjs"),
198
+ permissions: [
199
+ { action: `plugin::${pluginId}.settings.read`, subject: null }
200
+ ]
201
+ }
202
+ ]
203
+ );
204
+ app.registerPlugin({
205
+ id: pluginId,
206
+ name: "Notifier"
207
+ });
208
+ }
209
+ };
210
+ export {
211
+ getNotifications as a,
212
+ markAllAsRead as b,
213
+ clearNotification as c,
214
+ clearAll as d,
215
+ subscribeToNotifications as e,
216
+ getConfig as g,
217
+ index as i,
218
+ markAsRead as m,
219
+ setNotifications as s,
220
+ usePluginConfig as u
221
+ };
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ const jsxRuntime = require("react/jsx-runtime");
3
+ const react = require("react");
4
+ const strapiAdmin = require("@strapi/admin/strapi-admin");
5
+ let items = [];
6
+ let countSubscribers = [];
7
+ let itemSubscribers = [];
8
+ const getUnreadCount = () => items.filter((n) => !n.read).length;
9
+ const broadcastCount = () => {
10
+ const n = getUnreadCount();
11
+ countSubscribers.forEach((fn) => fn(n));
12
+ };
13
+ const broadcastItems = () => {
14
+ const snapshot = [...items];
15
+ itemSubscribers.forEach((fn) => fn(snapshot));
16
+ broadcastCount();
17
+ };
18
+ const getNotificationCount = () => getUnreadCount();
19
+ const getNotifications = () => [...items];
20
+ const subscribeToCount = (fn) => {
21
+ countSubscribers.push(fn);
22
+ return () => {
23
+ countSubscribers = countSubscribers.filter((s) => s !== fn);
24
+ };
25
+ };
26
+ const subscribeToNotifications = (fn) => {
27
+ itemSubscribers.push(fn);
28
+ return () => {
29
+ itemSubscribers = itemSubscribers.filter((s) => s !== fn);
30
+ };
31
+ };
32
+ const setNotifications = (next) => {
33
+ items = next;
34
+ broadcastItems();
35
+ };
36
+ const markAsRead = (id) => {
37
+ items = items.map((n) => n.id === id ? { ...n, read: true } : n);
38
+ broadcastItems();
39
+ };
40
+ const markAllAsRead = () => {
41
+ items = items.map((n) => ({ ...n, read: true }));
42
+ broadcastItems();
43
+ };
44
+ const clearNotification = (id) => {
45
+ items = items.filter((n) => n.id !== id);
46
+ broadcastItems();
47
+ };
48
+ const clearAll = () => {
49
+ items = [];
50
+ broadcastItems();
51
+ };
52
+ const useNotificationCount = () => {
53
+ const [count, setCount] = react.useState(getNotificationCount);
54
+ react.useEffect(() => subscribeToCount(setCount), []);
55
+ return count;
56
+ };
57
+ const DEFAULT_CONFIG = {
58
+ pollIntervalMs: 3e4,
59
+ pageSize: 20,
60
+ theme: {
61
+ accent: {
62
+ info: "#4945ff",
63
+ success: "#5cb85c",
64
+ warning: "#f0ad4e",
65
+ error: "#ee5e52"
66
+ }
67
+ }
68
+ };
69
+ let config = DEFAULT_CONFIG;
70
+ let subscribers = [];
71
+ const getConfig = () => config;
72
+ const setConfig = (next) => {
73
+ config = { ...DEFAULT_CONFIG, ...next, theme: { accent: { ...DEFAULT_CONFIG.theme.accent, ...next?.theme?.accent } } };
74
+ subscribers.forEach((fn) => fn(config));
75
+ };
76
+ const subscribeToConfig = (fn) => {
77
+ subscribers.push(fn);
78
+ return () => {
79
+ subscribers = subscribers.filter((s) => s !== fn);
80
+ };
81
+ };
82
+ const usePluginConfig = () => {
83
+ const [config2, setConfig2] = react.useState(getConfig);
84
+ react.useEffect(() => subscribeToConfig(setConfig2), []);
85
+ return config2;
86
+ };
87
+ const toStoreNotification = (n) => ({
88
+ id: String(n.id),
89
+ title: n.title,
90
+ message: n.message ?? "",
91
+ type: n.type ?? "info",
92
+ read: n.read,
93
+ createdAt: n.createdAt,
94
+ url: n.url
95
+ });
96
+ function Bell() {
97
+ const count = useNotificationCount();
98
+ const config2 = usePluginConfig();
99
+ const { get } = strapiAdmin.useFetchClient();
100
+ const configLoaded = react.useRef(false);
101
+ react.useEffect(() => {
102
+ if (configLoaded.current) return;
103
+ configLoaded.current = true;
104
+ get("/notifier/config").then(({ data }) => {
105
+ if (data) setConfig(data);
106
+ }).catch(() => {
107
+ });
108
+ }, [get]);
109
+ react.useEffect(() => {
110
+ const poll = async () => {
111
+ try {
112
+ const { data } = await get(`/notifier/notifications?page=1&pageSize=${config2.pageSize}`);
113
+ if (Array.isArray(data?.data)) {
114
+ setNotifications(data.data.map(toStoreNotification));
115
+ }
116
+ } catch {
117
+ }
118
+ };
119
+ poll();
120
+ const id = setInterval(poll, config2.pollIntervalMs);
121
+ return () => clearInterval(id);
122
+ }, [get, config2.pollIntervalMs, config2.pageSize]);
123
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { position: "relative", display: "inline-flex" }, children: [
124
+ /* @__PURE__ */ jsxRuntime.jsxs(
125
+ "svg",
126
+ {
127
+ xmlns: "http://www.w3.org/2000/svg",
128
+ viewBox: "0 0 24 24",
129
+ fill: "none",
130
+ stroke: "currentColor",
131
+ strokeWidth: "2",
132
+ strokeLinecap: "round",
133
+ strokeLinejoin: "round",
134
+ width: "1.5em",
135
+ height: "1.5em",
136
+ children: [
137
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" }),
138
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M13.73 21a2 2 0 0 1-3.46 0" })
139
+ ]
140
+ }
141
+ ),
142
+ count > 0 && /* @__PURE__ */ jsxRuntime.jsx(
143
+ "span",
144
+ {
145
+ "aria-label": `${count} unread notification${count === 1 ? "" : "s"}`,
146
+ style: {
147
+ position: "absolute",
148
+ top: "-5px",
149
+ right: "-6px",
150
+ backgroundColor: "#ee5e52",
151
+ color: "#fff",
152
+ borderRadius: "9px",
153
+ fontSize: "9px",
154
+ fontWeight: 700,
155
+ height: "13px",
156
+ minWidth: "13px",
157
+ display: "flex",
158
+ alignItems: "center",
159
+ justifyContent: "center",
160
+ padding: "0 2px",
161
+ lineHeight: 1,
162
+ pointerEvents: "none"
163
+ },
164
+ children: count > 99 ? "99+" : count
165
+ }
166
+ )
167
+ ] });
168
+ }
169
+ const pluginId = "notifier";
170
+ const index = {
171
+ register(app) {
172
+ app.addMenuLink({
173
+ to: `/plugins/${pluginId}`,
174
+ icon: Bell,
175
+ intlLabel: {
176
+ id: `${pluginId}.plugin.name`,
177
+ defaultMessage: "Notifications"
178
+ },
179
+ permissions: [],
180
+ Component: () => Promise.resolve().then(() => require("./Index-DVk2enQ2.js"))
181
+ });
182
+ app.createSettingSection(
183
+ {
184
+ id: pluginId,
185
+ intlLabel: {
186
+ id: `${pluginId}.settings.section`,
187
+ defaultMessage: "Notifier"
188
+ }
189
+ },
190
+ [
191
+ {
192
+ intlLabel: {
193
+ id: `${pluginId}.settings.page`,
194
+ defaultMessage: "Configuration"
195
+ },
196
+ id: `${pluginId}.settings`,
197
+ to: `/settings/${pluginId}`,
198
+ Component: () => Promise.resolve().then(() => require("./SettingsPage-DYxNBA3h.js")),
199
+ permissions: [
200
+ { action: `plugin::${pluginId}.settings.read`, subject: null }
201
+ ]
202
+ }
203
+ ]
204
+ );
205
+ app.registerPlugin({
206
+ id: pluginId,
207
+ name: "Notifier"
208
+ });
209
+ }
210
+ };
211
+ exports.clearAll = clearAll;
212
+ exports.clearNotification = clearNotification;
213
+ exports.getConfig = getConfig;
214
+ exports.getNotifications = getNotifications;
215
+ exports.index = index;
216
+ exports.markAllAsRead = markAllAsRead;
217
+ exports.markAsRead = markAsRead;
218
+ exports.setNotifications = setNotifications;
219
+ exports.subscribeToNotifications = subscribeToNotifications;
220
+ exports.usePluginConfig = usePluginConfig;
@@ -1,4 +1,3 @@
1
1
  "use strict";
2
- require("react");
3
- const index = require("../_chunks/index-7WJGsVEY.js");
2
+ const index = require("../_chunks/index-CKh_iBP2.js");
4
3
  module.exports = index.index;
@@ -1,5 +1,4 @@
1
- import "react";
2
- import { i } from "../_chunks/index-CNYabBMJ.mjs";
1
+ import { i } from "../_chunks/index-BgPnE501.mjs";
3
2
  export {
4
3
  i as default
5
4
  };