@backstage/plugin-notifications 0.0.1-next.0 → 0.0.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 +30 -0
- package/dist/esm/{index-9074aad8.esm.js → index-1ad83349.esm.js} +1 -1
- package/dist/esm/{index-9074aad8.esm.js.map → index-1ad83349.esm.js.map} +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.esm.js +29 -17
- package/dist/index.esm.js.map +1 -1
- package/package.json +15 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @backstage/plugin-notifications
|
|
2
2
|
|
|
3
|
+
## 0.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9873c44: Add support for signal type in notifications
|
|
8
|
+
- 8472188: Added or fixed the `repository` field in `package.json`.
|
|
9
|
+
- fb8fc24: Initial notifications system for backstage
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
- @backstage/core-components@0.14.0
|
|
12
|
+
- @backstage/plugin-signals-react@0.0.1
|
|
13
|
+
- @backstage/plugin-notifications-common@0.0.1
|
|
14
|
+
- @backstage/theme@0.5.1
|
|
15
|
+
- @backstage/core-plugin-api@1.9.0
|
|
16
|
+
- @backstage/errors@1.2.3
|
|
17
|
+
- @backstage/types@1.1.1
|
|
18
|
+
|
|
19
|
+
## 0.0.1-next.1
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 8472188: Added or fixed the `repository` field in `package.json`.
|
|
24
|
+
- Updated dependencies
|
|
25
|
+
- @backstage/theme@0.5.1-next.1
|
|
26
|
+
- @backstage/plugin-notifications-common@0.0.1-next.1
|
|
27
|
+
- @backstage/plugin-signals-react@0.0.1-next.3
|
|
28
|
+
- @backstage/core-components@0.14.0-next.2
|
|
29
|
+
- @backstage/core-plugin-api@1.9.0-next.1
|
|
30
|
+
- @backstage/errors@1.2.3
|
|
31
|
+
- @backstage/types@1.1.1
|
|
32
|
+
|
|
3
33
|
## 0.0.1-next.0
|
|
4
34
|
|
|
5
35
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-1ad83349.esm.js","sources":["../../src/components/NotificationsPage/NotificationsPage.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useEffect, useState } from 'react';\nimport {\n Content,\n ErrorPanel,\n PageWithHeader,\n} from '@backstage/core-components';\nimport { NotificationsTable } from '../NotificationsTable';\nimport { useNotificationsApi } from '../../hooks';\nimport { Button, Grid, makeStyles } from '@material-ui/core';\nimport Bookmark from '@material-ui/icons/Bookmark';\nimport Check from '@material-ui/icons/Check';\nimport Inbox from '@material-ui/icons/Inbox';\nimport { NotificationType } from '@backstage/plugin-notifications-common';\nimport { useSignal } from '@backstage/plugin-signals-react';\n\nconst useStyles = makeStyles(_theme => ({\n filterButton: {\n width: '100%',\n justifyContent: 'start',\n },\n}));\n\nexport const NotificationsPage = () => {\n const [type, setType] = useState<NotificationType>('undone');\n const [refresh, setRefresh] = React.useState(false);\n\n const { error, value, retry } = useNotificationsApi(\n api => api.getNotifications({ type }),\n [type],\n );\n\n useEffect(() => {\n if (refresh) {\n retry();\n setRefresh(false);\n }\n }, [refresh, setRefresh, retry]);\n\n const { lastSignal } = useSignal('notifications');\n useEffect(() => {\n if (lastSignal && lastSignal.action) {\n setRefresh(true);\n }\n }, [lastSignal]);\n\n const onUpdate = () => {\n setRefresh(true);\n };\n\n const styles = useStyles();\n if (error) {\n return <ErrorPanel error={new Error('Failed to load notifications')} />;\n }\n\n return (\n <PageWithHeader title=\"Notifications\" themeId=\"tool\">\n <Content>\n <Grid container>\n <Grid item xs={2}>\n <Button\n className={styles.filterButton}\n startIcon={<Inbox />}\n variant={type === 'undone' ? 'contained' : 'text'}\n onClick={() => setType('undone')}\n >\n Inbox\n </Button>\n <Button\n className={styles.filterButton}\n startIcon={<Check />}\n variant={type === 'done' ? 'contained' : 'text'}\n onClick={() => setType('done')}\n >\n Done\n </Button>\n <Button\n className={styles.filterButton}\n startIcon={<Bookmark />}\n variant={type === 'saved' ? 'contained' : 'text'}\n onClick={() => setType('saved')}\n >\n Saved\n </Button>\n </Grid>\n <Grid item xs={10}>\n <NotificationsTable\n notifications={value}\n type={type}\n onUpdate={onUpdate}\n />\n </Grid>\n </Grid>\n </Content>\n </PageWithHeader>\n );\n};\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ type UpdateNotificationsOptions = {
|
|
|
31
31
|
/** @public */
|
|
32
32
|
interface NotificationsApi {
|
|
33
33
|
getNotifications(options?: GetNotificationsOptions): Promise<Notification$1[]>;
|
|
34
|
+
getNotification(id: string): Promise<Notification$1>;
|
|
34
35
|
getStatus(): Promise<NotificationStatus>;
|
|
35
36
|
updateNotifications(options: UpdateNotificationsOptions): Promise<Notification$1[]>;
|
|
36
37
|
}
|
|
@@ -44,6 +45,7 @@ declare class NotificationsClient implements NotificationsApi {
|
|
|
44
45
|
fetchApi: FetchApi;
|
|
45
46
|
});
|
|
46
47
|
getNotifications(options?: GetNotificationsOptions): Promise<Notification$1[]>;
|
|
48
|
+
getNotification(id: string): Promise<Notification$1>;
|
|
47
49
|
getStatus(): Promise<NotificationStatus>;
|
|
48
50
|
updateNotifications(options: UpdateNotificationsOptions): Promise<Notification$1[]>;
|
|
49
51
|
private request;
|
|
@@ -77,6 +79,7 @@ declare function useWebNotifications(): {
|
|
|
77
79
|
sendWebNotification: (options: {
|
|
78
80
|
title: string;
|
|
79
81
|
description: string;
|
|
82
|
+
link?: string;
|
|
80
83
|
}) => Notification | null;
|
|
81
84
|
};
|
|
82
85
|
|
package/dist/index.esm.js
CHANGED
|
@@ -53,6 +53,9 @@ class NotificationsClient {
|
|
|
53
53
|
const urlSegment = `?${queryString}`;
|
|
54
54
|
return await this.request(urlSegment);
|
|
55
55
|
}
|
|
56
|
+
async getNotification(id) {
|
|
57
|
+
return await this.request(`${id}`);
|
|
58
|
+
}
|
|
56
59
|
async getStatus() {
|
|
57
60
|
return await this.request("status");
|
|
58
61
|
}
|
|
@@ -90,7 +93,7 @@ const notificationsPlugin = createPlugin({
|
|
|
90
93
|
const NotificationsPage = notificationsPlugin.provide(
|
|
91
94
|
createRoutableExtension({
|
|
92
95
|
name: "NotificationsPage",
|
|
93
|
-
component: () => import('./esm/index-
|
|
96
|
+
component: () => import('./esm/index-1ad83349.esm.js').then((m) => m.NotificationsPage),
|
|
94
97
|
mountPoint: rootRouteRef
|
|
95
98
|
})
|
|
96
99
|
);
|
|
@@ -126,6 +129,13 @@ function useWebNotifications() {
|
|
|
126
129
|
const notification = new Notification(options.title, {
|
|
127
130
|
body: options.description
|
|
128
131
|
});
|
|
132
|
+
notification.onclick = (event) => {
|
|
133
|
+
event.preventDefault();
|
|
134
|
+
notification.close();
|
|
135
|
+
if (options.link) {
|
|
136
|
+
window.open(options.link, "_blank");
|
|
137
|
+
}
|
|
138
|
+
};
|
|
129
139
|
return notification;
|
|
130
140
|
},
|
|
131
141
|
[webNotificationPermission]
|
|
@@ -174,6 +184,7 @@ const NotificationsSidebarItem = (props) => {
|
|
|
174
184
|
const { loading, error, value, retry } = useNotificationsApi(
|
|
175
185
|
(api) => api.getStatus()
|
|
176
186
|
);
|
|
187
|
+
const notificationsApi = useApi(notificationsApiRef);
|
|
177
188
|
const [unreadCount, setUnreadCount] = React.useState(0);
|
|
178
189
|
const notificationsRoute = useRouteRef(rootRouteRef);
|
|
179
190
|
const { lastSignal } = useSignal("notifications");
|
|
@@ -188,30 +199,31 @@ const NotificationsSidebarItem = (props) => {
|
|
|
188
199
|
}, [refresh, retry]);
|
|
189
200
|
useEffect(() => {
|
|
190
201
|
const handleWebNotification = (signal) => {
|
|
191
|
-
if (!webNotificationsEnabled ||
|
|
202
|
+
if (!webNotificationsEnabled || signal.action !== "new_notification") {
|
|
192
203
|
return;
|
|
193
204
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
205
|
+
notificationsApi.getNotification(signal.notification_id).then((notification) => {
|
|
206
|
+
var _a;
|
|
207
|
+
if (!notification) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
sendWebNotification({
|
|
211
|
+
title: notification.payload.title,
|
|
212
|
+
description: (_a = notification.payload.description) != null ? _a : "",
|
|
213
|
+
link: notification.payload.link
|
|
214
|
+
});
|
|
201
215
|
});
|
|
202
|
-
if (notification) {
|
|
203
|
-
notification.onclick = (event) => {
|
|
204
|
-
event.preventDefault();
|
|
205
|
-
notification.close();
|
|
206
|
-
window.open(notificationData.link, "_blank");
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
216
|
};
|
|
210
217
|
if (lastSignal && lastSignal.action) {
|
|
211
218
|
handleWebNotification(lastSignal);
|
|
212
219
|
setRefresh(true);
|
|
213
220
|
}
|
|
214
|
-
}, [
|
|
221
|
+
}, [
|
|
222
|
+
lastSignal,
|
|
223
|
+
sendWebNotification,
|
|
224
|
+
webNotificationsEnabled,
|
|
225
|
+
notificationsApi
|
|
226
|
+
]);
|
|
215
227
|
useEffect(() => {
|
|
216
228
|
if (!loading && !error && value) {
|
|
217
229
|
setUnreadCount(value.unread);
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/routes.ts","../src/api/NotificationsApi.ts","../src/api/NotificationsClient.ts","../src/plugin.ts","../src/hooks/useNotificationsApi.ts","../src/hooks/useWebNotifications.ts","../src/hooks/useTitleCounter.ts","../src/components/NotificationsSideBarItem/NotificationsSideBarItem.tsx","../src/components/NotificationsTable/NotificationsTable.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'notifications',\n});\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createApiRef } from '@backstage/core-plugin-api';\nimport {\n Notification,\n NotificationStatus,\n NotificationType,\n} from '@backstage/plugin-notifications-common';\n\n/** @public */\nexport const notificationsApiRef = createApiRef<NotificationsApi>({\n id: 'plugin.notifications.service',\n});\n\n/** @public */\nexport type GetNotificationsOptions = {\n type?: NotificationType;\n offset?: number;\n limit?: number;\n search?: string;\n};\n\n/** @public */\nexport type UpdateNotificationsOptions = {\n ids: string[];\n done?: boolean;\n read?: boolean;\n saved?: boolean;\n};\n\n/** @public */\nexport interface NotificationsApi {\n getNotifications(options?: GetNotificationsOptions): Promise<Notification[]>;\n\n getStatus(): Promise<NotificationStatus>;\n\n updateNotifications(\n options: UpdateNotificationsOptions,\n ): Promise<Notification[]>;\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n GetNotificationsOptions,\n NotificationsApi,\n UpdateNotificationsOptions,\n} from './NotificationsApi';\nimport { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport {\n Notification,\n NotificationStatus,\n} from '@backstage/plugin-notifications-common';\n\n/** @public */\nexport class NotificationsClient implements NotificationsApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n public constructor(options: {\n discoveryApi: DiscoveryApi;\n fetchApi: FetchApi;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n }\n\n async getNotifications(\n options?: GetNotificationsOptions,\n ): Promise<Notification[]> {\n const queryString = new URLSearchParams();\n if (options?.type) {\n queryString.append('type', options.type);\n }\n if (options?.limit !== undefined) {\n queryString.append('limit', options.limit.toString(10));\n }\n if (options?.offset !== undefined) {\n queryString.append('offset', options.offset.toString(10));\n }\n if (options?.search) {\n queryString.append('search', options.search);\n }\n\n const urlSegment = `?${queryString}`;\n\n return await this.request<Notification[]>(urlSegment);\n }\n\n async getStatus(): Promise<NotificationStatus> {\n return await this.request<NotificationStatus>('status');\n }\n\n async updateNotifications(\n options: UpdateNotificationsOptions,\n ): Promise<Notification[]> {\n return await this.request<Notification[]>('update', {\n method: 'POST',\n body: JSON.stringify(options),\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n private async request<T>(path: string, init?: any): Promise<T> {\n const baseUrl = `${await this.discoveryApi.getBaseUrl('notifications')}/`;\n const url = new URL(path, baseUrl);\n\n const response = await this.fetchApi.fetch(url.toString(), init);\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<T>;\n }\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport { notificationsApiRef } from './api/NotificationsApi';\nimport { NotificationsClient } from './api';\n\n/** @public */\nexport const notificationsPlugin = createPlugin({\n id: 'notifications',\n routes: {\n root: rootRouteRef,\n },\n apis: [\n createApiFactory({\n api: notificationsApiRef,\n deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef },\n factory: ({ discoveryApi, fetchApi }) =>\n new NotificationsClient({ discoveryApi, fetchApi }),\n }),\n ],\n});\n\n/** @public */\nexport const NotificationsPage = notificationsPlugin.provide(\n createRoutableExtension({\n name: 'NotificationsPage',\n component: () =>\n import('./components/NotificationsPage').then(m => m.NotificationsPage),\n mountPoint: rootRouteRef,\n }),\n);\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { NotificationsApi, notificationsApiRef } from '../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsyncRetry from 'react-use/lib/useAsyncRetry';\n\n/** @public */\nexport function useNotificationsApi<T>(\n f: (api: NotificationsApi) => Promise<T>,\n deps: any[] = [],\n) {\n const notificationsApi = useApi(notificationsApiRef);\n\n return useAsyncRetry(async () => {\n return await f(notificationsApi);\n }, deps);\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useCallback, useEffect, useState } from 'react';\n\n/** @public */\nexport function useWebNotifications() {\n const [webNotificationPermission, setWebNotificationPermission] =\n useState('default');\n const [webNotifications, setWebNotifications] = useState<Notification[]>([]);\n\n useEffect(() => {\n if ('Notification' in window && webNotificationPermission === 'default') {\n window.Notification.requestPermission().then(permission => {\n setWebNotificationPermission(permission);\n });\n }\n }, [webNotificationPermission]);\n\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'visible') {\n webNotifications.forEach(n => n.close());\n setWebNotifications([]);\n }\n });\n\n const sendWebNotification = useCallback(\n (options: { title: string; description: string }) => {\n if (webNotificationPermission !== 'granted') {\n return null;\n }\n\n const notification = new Notification(options.title, {\n body: options.description,\n });\n return notification;\n },\n [webNotificationPermission],\n );\n\n return { sendWebNotification };\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useCallback, useEffect, useState } from 'react';\n\n/** @public */\nexport function useTitleCounter() {\n const [title, setTitle] = useState(document.title);\n const [count, setCount] = useState(0);\n\n const getPrefix = (value: number) => {\n return value === 0 ? '' : `(${value}) `;\n };\n\n const cleanTitle = (currentTitle: string) => {\n return currentTitle.replace(/^\\(\\d+\\)\\s/, '');\n };\n\n useEffect(() => {\n document.title = title;\n }, [title]);\n\n useEffect(() => {\n const baseTitle = cleanTitle(title);\n setTitle(`${getPrefix(count)}${baseTitle}`);\n return () => {\n document.title = cleanTitle(title);\n };\n }, [title, count]);\n\n const titleElement = document.querySelector('title');\n if (titleElement) {\n new MutationObserver(() => {\n setTitle(document.title);\n }).observe(titleElement, {\n subtree: true,\n characterData: true,\n childList: true,\n });\n }\n\n const setNotificationCount = useCallback(\n (newCount: number) => setCount(newCount),\n [],\n );\n\n return { setNotificationCount };\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { useEffect } from 'react';\nimport { useNotificationsApi } from '../../hooks';\nimport { SidebarItem } from '@backstage/core-components';\nimport NotificationsIcon from '@material-ui/icons/Notifications';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { rootRouteRef } from '../../routes';\nimport { useSignal } from '@backstage/plugin-signals-react';\nimport { useWebNotifications } from '../../hooks/useWebNotifications';\nimport { useTitleCounter } from '../../hooks/useTitleCounter';\nimport { JsonObject } from '@backstage/types';\n\n/** @public */\nexport const NotificationsSidebarItem = (props?: {\n webNotificationsEnabled?: boolean;\n titleCounterEnabled?: boolean;\n}) => {\n const { webNotificationsEnabled = false, titleCounterEnabled = true } =\n props ?? { webNotificationsEnabled: false, titleCounterEnabled: true };\n\n const { loading, error, value, retry } = useNotificationsApi(api =>\n api.getStatus(),\n );\n const [unreadCount, setUnreadCount] = React.useState(0);\n const notificationsRoute = useRouteRef(rootRouteRef);\n // TODO: Add signal type support to `useSignal` to make it a bit easier to use\n // TODO: Do we want to add long polling in case signals are not available\n const { lastSignal } = useSignal('notifications');\n const { sendWebNotification } = useWebNotifications();\n const [refresh, setRefresh] = React.useState(false);\n const { setNotificationCount } = useTitleCounter();\n\n useEffect(() => {\n if (refresh) {\n retry();\n setRefresh(false);\n }\n }, [refresh, retry]);\n\n useEffect(() => {\n const handleWebNotification = (signal: JsonObject) => {\n if (!webNotificationsEnabled || !('notification' in signal)) {\n return;\n }\n\n const notificationData = signal.notification as JsonObject;\n\n if (\n !notificationData ||\n !('title' in notificationData) ||\n !('description' in notificationData) ||\n !('title' in notificationData)\n ) {\n return;\n }\n const notification = sendWebNotification({\n title: notificationData.title as string,\n description: notificationData.description as string,\n });\n if (notification) {\n notification.onclick = event => {\n event.preventDefault();\n notification.close();\n window.open(notificationData.link as string, '_blank');\n };\n }\n };\n\n if (lastSignal && lastSignal.action) {\n handleWebNotification(lastSignal);\n setRefresh(true);\n }\n }, [lastSignal, sendWebNotification, webNotificationsEnabled]);\n\n useEffect(() => {\n if (!loading && !error && value) {\n setUnreadCount(value.unread);\n if (titleCounterEnabled) {\n setNotificationCount(value.unread);\n }\n }\n }, [loading, error, value, titleCounterEnabled, setNotificationCount]);\n\n // TODO: Figure out if the count can be added to hasNotifications\n return (\n <SidebarItem\n icon={NotificationsIcon}\n to={notificationsRoute()}\n text=\"Notifications\"\n hasNotifications={!error && !!unreadCount}\n />\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { useEffect, useState } from 'react';\nimport {\n Box,\n Button,\n IconButton,\n makeStyles,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport {\n Notification,\n NotificationType,\n} from '@backstage/plugin-notifications-common';\nimport { useNavigate } from 'react-router-dom';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport Check from '@material-ui/icons/Check';\nimport Bookmark from '@material-ui/icons/Bookmark';\nimport { notificationsApiRef } from '../../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport Inbox from '@material-ui/icons/Inbox';\nimport CloseIcon from '@material-ui/icons/Close';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\nimport ArrowForwardIcon from '@material-ui/icons/ArrowForward';\n\nconst useStyles = makeStyles(theme => ({\n table: {\n border: `1px solid ${theme.palette.divider}`,\n },\n header: {\n borderBottom: `1px solid ${theme.palette.divider}`,\n },\n\n notificationRow: {\n cursor: 'pointer',\n '&.unread': {\n border: '1px solid rgba(255, 255, 255, .3)',\n },\n '& .hideOnHover': {\n display: 'initial',\n },\n '& .showOnHover': {\n display: 'none',\n },\n '&:hover': {\n '& .hideOnHover': {\n display: 'none',\n },\n '& .showOnHover': {\n display: 'initial',\n },\n },\n },\n actionButton: {\n padding: '9px',\n },\n checkBox: {\n padding: '0 10px 10px 0',\n },\n}));\n\n/** @public */\nexport const NotificationsTable = (props: {\n onUpdate: () => void;\n type: NotificationType;\n notifications?: Notification[];\n}) => {\n const { notifications, type } = props;\n const navigate = useNavigate();\n const styles = useStyles();\n const [selected, setSelected] = useState<string[]>([]);\n const notificationsApi = useApi(notificationsApiRef);\n\n const onCheckBoxClick = (id: string) => {\n const index = selected.indexOf(id);\n if (index !== -1) {\n setSelected(selected.filter(s => s !== id));\n } else {\n setSelected([...selected, id]);\n }\n };\n\n useEffect(() => {\n setSelected([]);\n }, [type]);\n\n const isChecked = (id: string) => {\n return selected.indexOf(id) !== -1;\n };\n\n const isAllSelected = () => {\n return (\n selected.length === notifications?.length && notifications.length > 0\n );\n };\n\n return (\n <Table size=\"small\" className={styles.table}>\n <TableHead>\n <TableRow>\n <TableCell colSpan={3}>\n {type !== 'saved' && !notifications?.length && 'No notifications'}\n {type !== 'saved' && !!notifications?.length && (\n <Checkbox\n size=\"small\"\n style={{ paddingLeft: 0 }}\n checked={isAllSelected()}\n onClick={() => {\n if (isAllSelected()) {\n setSelected([]);\n } else {\n setSelected(\n notifications ? notifications.map(n => n.id) : [],\n );\n }\n }}\n />\n )}\n {type === 'saved' &&\n `${notifications?.length ?? 0} saved notifications`}\n {selected.length === 0 &&\n !!notifications?.length &&\n type !== 'saved' &&\n 'Select all'}\n {selected.length > 0 && `${selected.length} selected`}\n {type === 'done' && selected.length > 0 && (\n <Button\n startIcon={<Inbox fontSize=\"small\" />}\n onClick={() => {\n notificationsApi\n .updateNotifications({ ids: selected, done: false })\n .then(() => props.onUpdate());\n setSelected([]);\n }}\n >\n Move to inbox\n </Button>\n )}\n\n {type === 'undone' && selected.length > 0 && (\n <Button\n startIcon={<Check fontSize=\"small\" />}\n onClick={() => {\n notificationsApi\n .updateNotifications({ ids: selected, done: true })\n .then(() => props.onUpdate());\n setSelected([]);\n }}\n >\n Mark as done\n </Button>\n )}\n </TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {props.notifications?.map(notification => {\n return (\n <TableRow\n key={notification.id}\n className={`${styles.notificationRow} ${\n !notification.read ? 'unread' : ''\n }`}\n hover\n >\n <TableCell\n width=\"60px\"\n style={{ verticalAlign: 'center', paddingRight: '0px' }}\n >\n <Checkbox\n className={styles.checkBox}\n size=\"small\"\n checked={isChecked(notification.id)}\n onClick={() => onCheckBoxClick(notification.id)}\n />\n </TableCell>\n <TableCell\n onClick={() =>\n notificationsApi\n .updateNotifications({ ids: [notification.id], read: true })\n .then(() => navigate(notification.payload.link))\n }\n style={{ paddingLeft: 0 }}\n >\n <Typography variant=\"subtitle2\">\n {notification.payload.title}\n </Typography>\n <Typography variant=\"body2\">\n {notification.payload.description}\n </Typography>\n </TableCell>\n <TableCell style={{ textAlign: 'right' }}>\n <Box className=\"hideOnHover\">\n <RelativeTime value={notification.created} />\n </Box>\n <Box className=\"showOnHover\">\n <Tooltip title={notification.payload.link}>\n <IconButton\n className={styles.actionButton}\n onClick={() =>\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n read: true,\n })\n .then(() => navigate(notification.payload.link))\n }\n >\n <ArrowForwardIcon />\n </IconButton>\n </Tooltip>\n <Tooltip\n title={notification.read ? 'Move to inbox' : 'Mark as done'}\n >\n <IconButton\n className={styles.actionButton}\n onClick={() => {\n if (notification.read) {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n done: false,\n })\n .then(() => {\n props.onUpdate();\n });\n } else {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n done: true,\n })\n .then(() => {\n props.onUpdate();\n });\n }\n }}\n >\n {notification.read ? (\n <Inbox fontSize=\"small\" />\n ) : (\n <Check fontSize=\"small\" />\n )}\n </IconButton>\n </Tooltip>\n <Tooltip\n title={notification.saved ? 'Remove from saved' : 'Save'}\n >\n <IconButton\n className={styles.actionButton}\n onClick={() => {\n if (notification.saved) {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n saved: false,\n })\n .then(() => {\n props.onUpdate();\n });\n } else {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n saved: true,\n })\n .then(() => {\n props.onUpdate();\n });\n }\n }}\n >\n {notification.saved ? (\n <CloseIcon fontSize=\"small\" />\n ) : (\n <Bookmark fontSize=\"small\" />\n )}\n </IconButton>\n </Tooltip>\n </Box>\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/routes.ts","../src/api/NotificationsApi.ts","../src/api/NotificationsClient.ts","../src/plugin.ts","../src/hooks/useNotificationsApi.ts","../src/hooks/useWebNotifications.ts","../src/hooks/useTitleCounter.ts","../src/components/NotificationsSideBarItem/NotificationsSideBarItem.tsx","../src/components/NotificationsTable/NotificationsTable.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'notifications',\n});\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createApiRef } from '@backstage/core-plugin-api';\nimport {\n Notification,\n NotificationStatus,\n NotificationType,\n} from '@backstage/plugin-notifications-common';\n\n/** @public */\nexport const notificationsApiRef = createApiRef<NotificationsApi>({\n id: 'plugin.notifications.service',\n});\n\n/** @public */\nexport type GetNotificationsOptions = {\n type?: NotificationType;\n offset?: number;\n limit?: number;\n search?: string;\n};\n\n/** @public */\nexport type UpdateNotificationsOptions = {\n ids: string[];\n done?: boolean;\n read?: boolean;\n saved?: boolean;\n};\n\n/** @public */\nexport interface NotificationsApi {\n getNotifications(options?: GetNotificationsOptions): Promise<Notification[]>;\n\n getNotification(id: string): Promise<Notification>;\n\n getStatus(): Promise<NotificationStatus>;\n\n updateNotifications(\n options: UpdateNotificationsOptions,\n ): Promise<Notification[]>;\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n GetNotificationsOptions,\n NotificationsApi,\n UpdateNotificationsOptions,\n} from './NotificationsApi';\nimport { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport {\n Notification,\n NotificationStatus,\n} from '@backstage/plugin-notifications-common';\n\n/** @public */\nexport class NotificationsClient implements NotificationsApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n public constructor(options: {\n discoveryApi: DiscoveryApi;\n fetchApi: FetchApi;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n }\n\n async getNotifications(\n options?: GetNotificationsOptions,\n ): Promise<Notification[]> {\n const queryString = new URLSearchParams();\n if (options?.type) {\n queryString.append('type', options.type);\n }\n if (options?.limit !== undefined) {\n queryString.append('limit', options.limit.toString(10));\n }\n if (options?.offset !== undefined) {\n queryString.append('offset', options.offset.toString(10));\n }\n if (options?.search) {\n queryString.append('search', options.search);\n }\n\n const urlSegment = `?${queryString}`;\n\n return await this.request<Notification[]>(urlSegment);\n }\n\n async getNotification(id: string): Promise<Notification> {\n return await this.request<Notification>(`${id}`);\n }\n\n async getStatus(): Promise<NotificationStatus> {\n return await this.request<NotificationStatus>('status');\n }\n\n async updateNotifications(\n options: UpdateNotificationsOptions,\n ): Promise<Notification[]> {\n return await this.request<Notification[]>('update', {\n method: 'POST',\n body: JSON.stringify(options),\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n private async request<T>(path: string, init?: any): Promise<T> {\n const baseUrl = `${await this.discoveryApi.getBaseUrl('notifications')}/`;\n const url = new URL(path, baseUrl);\n\n const response = await this.fetchApi.fetch(url.toString(), init);\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<T>;\n }\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport { notificationsApiRef } from './api/NotificationsApi';\nimport { NotificationsClient } from './api';\n\n/** @public */\nexport const notificationsPlugin = createPlugin({\n id: 'notifications',\n routes: {\n root: rootRouteRef,\n },\n apis: [\n createApiFactory({\n api: notificationsApiRef,\n deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef },\n factory: ({ discoveryApi, fetchApi }) =>\n new NotificationsClient({ discoveryApi, fetchApi }),\n }),\n ],\n});\n\n/** @public */\nexport const NotificationsPage = notificationsPlugin.provide(\n createRoutableExtension({\n name: 'NotificationsPage',\n component: () =>\n import('./components/NotificationsPage').then(m => m.NotificationsPage),\n mountPoint: rootRouteRef,\n }),\n);\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { NotificationsApi, notificationsApiRef } from '../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsyncRetry from 'react-use/lib/useAsyncRetry';\n\n/** @public */\nexport function useNotificationsApi<T>(\n f: (api: NotificationsApi) => Promise<T>,\n deps: any[] = [],\n) {\n const notificationsApi = useApi(notificationsApiRef);\n\n return useAsyncRetry(async () => {\n return await f(notificationsApi);\n }, deps);\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useCallback, useEffect, useState } from 'react';\n\n/** @public */\nexport function useWebNotifications() {\n const [webNotificationPermission, setWebNotificationPermission] =\n useState('default');\n const [webNotifications, setWebNotifications] = useState<Notification[]>([]);\n\n useEffect(() => {\n if ('Notification' in window && webNotificationPermission === 'default') {\n window.Notification.requestPermission().then(permission => {\n setWebNotificationPermission(permission);\n });\n }\n }, [webNotificationPermission]);\n\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'visible') {\n webNotifications.forEach(n => n.close());\n setWebNotifications([]);\n }\n });\n\n const sendWebNotification = useCallback(\n (options: { title: string; description: string; link?: string }) => {\n if (webNotificationPermission !== 'granted') {\n return null;\n }\n\n const notification = new Notification(options.title, {\n body: options.description,\n });\n\n notification.onclick = event => {\n event.preventDefault();\n notification.close();\n if (options.link) {\n window.open(options.link, '_blank');\n }\n };\n\n return notification;\n },\n [webNotificationPermission],\n );\n\n return { sendWebNotification };\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useCallback, useEffect, useState } from 'react';\n\n/** @public */\nexport function useTitleCounter() {\n const [title, setTitle] = useState(document.title);\n const [count, setCount] = useState(0);\n\n const getPrefix = (value: number) => {\n return value === 0 ? '' : `(${value}) `;\n };\n\n const cleanTitle = (currentTitle: string) => {\n return currentTitle.replace(/^\\(\\d+\\)\\s/, '');\n };\n\n useEffect(() => {\n document.title = title;\n }, [title]);\n\n useEffect(() => {\n const baseTitle = cleanTitle(title);\n setTitle(`${getPrefix(count)}${baseTitle}`);\n return () => {\n document.title = cleanTitle(title);\n };\n }, [title, count]);\n\n const titleElement = document.querySelector('title');\n if (titleElement) {\n new MutationObserver(() => {\n setTitle(document.title);\n }).observe(titleElement, {\n subtree: true,\n characterData: true,\n childList: true,\n });\n }\n\n const setNotificationCount = useCallback(\n (newCount: number) => setCount(newCount),\n [],\n );\n\n return { setNotificationCount };\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { useEffect } from 'react';\nimport { useNotificationsApi } from '../../hooks';\nimport { SidebarItem } from '@backstage/core-components';\nimport NotificationsIcon from '@material-ui/icons/Notifications';\nimport { useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport { rootRouteRef } from '../../routes';\nimport { useSignal } from '@backstage/plugin-signals-react';\nimport { NotificationSignal } from '@backstage/plugin-notifications-common';\nimport { useWebNotifications } from '../../hooks/useWebNotifications';\nimport { useTitleCounter } from '../../hooks/useTitleCounter';\nimport { notificationsApiRef } from '../../api';\n\n/** @public */\nexport const NotificationsSidebarItem = (props?: {\n webNotificationsEnabled?: boolean;\n titleCounterEnabled?: boolean;\n}) => {\n const { webNotificationsEnabled = false, titleCounterEnabled = true } =\n props ?? { webNotificationsEnabled: false, titleCounterEnabled: true };\n\n const { loading, error, value, retry } = useNotificationsApi(api =>\n api.getStatus(),\n );\n const notificationsApi = useApi(notificationsApiRef);\n const [unreadCount, setUnreadCount] = React.useState(0);\n const notificationsRoute = useRouteRef(rootRouteRef);\n // TODO: Do we want to add long polling in case signals are not available\n const { lastSignal } = useSignal<NotificationSignal>('notifications');\n const { sendWebNotification } = useWebNotifications();\n const [refresh, setRefresh] = React.useState(false);\n const { setNotificationCount } = useTitleCounter();\n\n useEffect(() => {\n if (refresh) {\n retry();\n setRefresh(false);\n }\n }, [refresh, retry]);\n\n useEffect(() => {\n const handleWebNotification = (signal: NotificationSignal) => {\n if (!webNotificationsEnabled || signal.action !== 'new_notification') {\n return;\n }\n\n notificationsApi\n .getNotification(signal.notification_id)\n .then(notification => {\n if (!notification) {\n return;\n }\n sendWebNotification({\n title: notification.payload.title,\n description: notification.payload.description ?? '',\n link: notification.payload.link,\n });\n });\n };\n\n if (lastSignal && lastSignal.action) {\n handleWebNotification(lastSignal);\n setRefresh(true);\n }\n }, [\n lastSignal,\n sendWebNotification,\n webNotificationsEnabled,\n notificationsApi,\n ]);\n\n useEffect(() => {\n if (!loading && !error && value) {\n setUnreadCount(value.unread);\n if (titleCounterEnabled) {\n setNotificationCount(value.unread);\n }\n }\n }, [loading, error, value, titleCounterEnabled, setNotificationCount]);\n\n // TODO: Figure out if the count can be added to hasNotifications\n return (\n <SidebarItem\n icon={NotificationsIcon}\n to={notificationsRoute()}\n text=\"Notifications\"\n hasNotifications={!error && !!unreadCount}\n />\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { useEffect, useState } from 'react';\nimport {\n Box,\n Button,\n IconButton,\n makeStyles,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport {\n Notification,\n NotificationType,\n} from '@backstage/plugin-notifications-common';\nimport { useNavigate } from 'react-router-dom';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport Check from '@material-ui/icons/Check';\nimport Bookmark from '@material-ui/icons/Bookmark';\nimport { notificationsApiRef } from '../../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport Inbox from '@material-ui/icons/Inbox';\nimport CloseIcon from '@material-ui/icons/Close';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\nimport ArrowForwardIcon from '@material-ui/icons/ArrowForward';\n\nconst useStyles = makeStyles(theme => ({\n table: {\n border: `1px solid ${theme.palette.divider}`,\n },\n header: {\n borderBottom: `1px solid ${theme.palette.divider}`,\n },\n\n notificationRow: {\n cursor: 'pointer',\n '&.unread': {\n border: '1px solid rgba(255, 255, 255, .3)',\n },\n '& .hideOnHover': {\n display: 'initial',\n },\n '& .showOnHover': {\n display: 'none',\n },\n '&:hover': {\n '& .hideOnHover': {\n display: 'none',\n },\n '& .showOnHover': {\n display: 'initial',\n },\n },\n },\n actionButton: {\n padding: '9px',\n },\n checkBox: {\n padding: '0 10px 10px 0',\n },\n}));\n\n/** @public */\nexport const NotificationsTable = (props: {\n onUpdate: () => void;\n type: NotificationType;\n notifications?: Notification[];\n}) => {\n const { notifications, type } = props;\n const navigate = useNavigate();\n const styles = useStyles();\n const [selected, setSelected] = useState<string[]>([]);\n const notificationsApi = useApi(notificationsApiRef);\n\n const onCheckBoxClick = (id: string) => {\n const index = selected.indexOf(id);\n if (index !== -1) {\n setSelected(selected.filter(s => s !== id));\n } else {\n setSelected([...selected, id]);\n }\n };\n\n useEffect(() => {\n setSelected([]);\n }, [type]);\n\n const isChecked = (id: string) => {\n return selected.indexOf(id) !== -1;\n };\n\n const isAllSelected = () => {\n return (\n selected.length === notifications?.length && notifications.length > 0\n );\n };\n\n return (\n <Table size=\"small\" className={styles.table}>\n <TableHead>\n <TableRow>\n <TableCell colSpan={3}>\n {type !== 'saved' && !notifications?.length && 'No notifications'}\n {type !== 'saved' && !!notifications?.length && (\n <Checkbox\n size=\"small\"\n style={{ paddingLeft: 0 }}\n checked={isAllSelected()}\n onClick={() => {\n if (isAllSelected()) {\n setSelected([]);\n } else {\n setSelected(\n notifications ? notifications.map(n => n.id) : [],\n );\n }\n }}\n />\n )}\n {type === 'saved' &&\n `${notifications?.length ?? 0} saved notifications`}\n {selected.length === 0 &&\n !!notifications?.length &&\n type !== 'saved' &&\n 'Select all'}\n {selected.length > 0 && `${selected.length} selected`}\n {type === 'done' && selected.length > 0 && (\n <Button\n startIcon={<Inbox fontSize=\"small\" />}\n onClick={() => {\n notificationsApi\n .updateNotifications({ ids: selected, done: false })\n .then(() => props.onUpdate());\n setSelected([]);\n }}\n >\n Move to inbox\n </Button>\n )}\n\n {type === 'undone' && selected.length > 0 && (\n <Button\n startIcon={<Check fontSize=\"small\" />}\n onClick={() => {\n notificationsApi\n .updateNotifications({ ids: selected, done: true })\n .then(() => props.onUpdate());\n setSelected([]);\n }}\n >\n Mark as done\n </Button>\n )}\n </TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {props.notifications?.map(notification => {\n return (\n <TableRow\n key={notification.id}\n className={`${styles.notificationRow} ${\n !notification.read ? 'unread' : ''\n }`}\n hover\n >\n <TableCell\n width=\"60px\"\n style={{ verticalAlign: 'center', paddingRight: '0px' }}\n >\n <Checkbox\n className={styles.checkBox}\n size=\"small\"\n checked={isChecked(notification.id)}\n onClick={() => onCheckBoxClick(notification.id)}\n />\n </TableCell>\n <TableCell\n onClick={() =>\n notificationsApi\n .updateNotifications({ ids: [notification.id], read: true })\n .then(() => navigate(notification.payload.link))\n }\n style={{ paddingLeft: 0 }}\n >\n <Typography variant=\"subtitle2\">\n {notification.payload.title}\n </Typography>\n <Typography variant=\"body2\">\n {notification.payload.description}\n </Typography>\n </TableCell>\n <TableCell style={{ textAlign: 'right' }}>\n <Box className=\"hideOnHover\">\n <RelativeTime value={notification.created} />\n </Box>\n <Box className=\"showOnHover\">\n <Tooltip title={notification.payload.link}>\n <IconButton\n className={styles.actionButton}\n onClick={() =>\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n read: true,\n })\n .then(() => navigate(notification.payload.link))\n }\n >\n <ArrowForwardIcon />\n </IconButton>\n </Tooltip>\n <Tooltip\n title={notification.read ? 'Move to inbox' : 'Mark as done'}\n >\n <IconButton\n className={styles.actionButton}\n onClick={() => {\n if (notification.read) {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n done: false,\n })\n .then(() => {\n props.onUpdate();\n });\n } else {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n done: true,\n })\n .then(() => {\n props.onUpdate();\n });\n }\n }}\n >\n {notification.read ? (\n <Inbox fontSize=\"small\" />\n ) : (\n <Check fontSize=\"small\" />\n )}\n </IconButton>\n </Tooltip>\n <Tooltip\n title={notification.saved ? 'Remove from saved' : 'Save'}\n >\n <IconButton\n className={styles.actionButton}\n onClick={() => {\n if (notification.saved) {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n saved: false,\n })\n .then(() => {\n props.onUpdate();\n });\n } else {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n saved: true,\n })\n .then(() => {\n props.onUpdate();\n });\n }\n }}\n >\n {notification.saved ? (\n <CloseIcon fontSize=\"small\" />\n ) : (\n <Bookmark fontSize=\"small\" />\n )}\n </IconButton>\n </Tooltip>\n </Box>\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n );\n};\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-notifications",
|
|
3
|
-
"version": "0.0.1
|
|
3
|
+
"version": "0.0.1",
|
|
4
4
|
"main": "dist/index.esm.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
"main": "dist/index.esm.js",
|
|
10
10
|
"types": "dist/index.d.ts"
|
|
11
11
|
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/backstage/backstage",
|
|
15
|
+
"directory": "plugins/notifications"
|
|
16
|
+
},
|
|
12
17
|
"backstage": {
|
|
13
18
|
"role": "frontend-plugin"
|
|
14
19
|
},
|
|
@@ -23,12 +28,12 @@
|
|
|
23
28
|
"postpack": "backstage-cli package postpack"
|
|
24
29
|
},
|
|
25
30
|
"dependencies": {
|
|
26
|
-
"@backstage/core-components": "^0.14.0
|
|
27
|
-
"@backstage/core-plugin-api": "^1.9.0
|
|
31
|
+
"@backstage/core-components": "^0.14.0",
|
|
32
|
+
"@backstage/core-plugin-api": "^1.9.0",
|
|
28
33
|
"@backstage/errors": "^1.2.3",
|
|
29
|
-
"@backstage/plugin-notifications-common": "^0.0.1
|
|
30
|
-
"@backstage/plugin-signals-react": "^0.0.1
|
|
31
|
-
"@backstage/theme": "^0.5.1
|
|
34
|
+
"@backstage/plugin-notifications-common": "^0.0.1",
|
|
35
|
+
"@backstage/plugin-signals-react": "^0.0.1",
|
|
36
|
+
"@backstage/theme": "^0.5.1",
|
|
32
37
|
"@backstage/types": "^1.1.1",
|
|
33
38
|
"@material-ui/core": "^4.9.13",
|
|
34
39
|
"@material-ui/icons": "^4.9.1",
|
|
@@ -42,10 +47,10 @@
|
|
|
42
47
|
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
|
|
43
48
|
},
|
|
44
49
|
"devDependencies": {
|
|
45
|
-
"@backstage/cli": "^0.25.2
|
|
46
|
-
"@backstage/core-app-api": "^1.12.0
|
|
47
|
-
"@backstage/dev-utils": "^1.0.27
|
|
48
|
-
"@backstage/test-utils": "^1.5.0
|
|
50
|
+
"@backstage/cli": "^0.25.2",
|
|
51
|
+
"@backstage/core-app-api": "^1.12.0",
|
|
52
|
+
"@backstage/dev-utils": "^1.0.27",
|
|
53
|
+
"@backstage/test-utils": "^1.5.0",
|
|
49
54
|
"@testing-library/jest-dom": "^6.0.0",
|
|
50
55
|
"@testing-library/react": "^14.0.0",
|
|
51
56
|
"@testing-library/user-event": "^14.0.0",
|