@backstage/plugin-notifications 0.1.0 → 0.1.2

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 CHANGED
@@ -1,5 +1,35 @@
1
1
  # @backstage/plugin-notifications
2
2
 
3
+ ## 0.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - e8f026a: Use ESM exports of react-use library
8
+ - 6a2fe4b: Added ESLint rule `no-top-level-material-ui-4-imports` in the `notifications` plugin to migrate the Material UI imports.
9
+ - Updated dependencies
10
+ - @backstage/core-components@0.14.3
11
+ - @backstage/core-plugin-api@1.9.1
12
+ - @backstage/errors@1.2.4
13
+ - @backstage/theme@0.5.2
14
+ - @backstage/types@1.1.1
15
+ - @backstage/plugin-notifications-common@0.0.2
16
+ - @backstage/plugin-signals-react@0.0.2
17
+
18
+ ## 0.1.1
19
+
20
+ ### Patch Changes
21
+
22
+ - e8f026a: Use ESM exports of react-use library
23
+ - 6a2fe4b: Added ESLint rule `no-top-level-material-ui-4-imports` in the `notifications` plugin to migrate the Material UI imports.
24
+ - Updated dependencies
25
+ - @backstage/core-components@0.14.2
26
+ - @backstage/core-plugin-api@1.9.1
27
+ - @backstage/errors@1.2.4
28
+ - @backstage/theme@0.5.2
29
+ - @backstage/types@1.1.1
30
+ - @backstage/plugin-notifications-common@0.0.2
31
+ - @backstage/plugin-signals-react@0.0.2
32
+
3
33
  ## 0.1.0
4
34
 
5
35
  ### Minor Changes
@@ -1,14 +1,23 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import { ResponseErrorPanel, PageWithHeader, Content } from '@backstage/core-components';
3
- import { Grid, Typography, Divider, FormControl, InputLabel, Select, MenuItem } from '@material-ui/core';
3
+ import Grid from '@material-ui/core/Grid';
4
4
  import { useSignal } from '@backstage/plugin-signals-react';
5
5
  import { useNotificationsApi, NotificationsTable } from '../index.esm.js';
6
+ import Divider from '@material-ui/core/Divider';
7
+ import FormControl from '@material-ui/core/FormControl';
8
+ import InputLabel from '@material-ui/core/InputLabel';
9
+ import MenuItem from '@material-ui/core/MenuItem';
10
+ import Select from '@material-ui/core/Select';
11
+ import Typography from '@material-ui/core/Typography';
6
12
  import '@backstage/core-plugin-api';
7
13
  import '@backstage/errors';
8
- import 'react-use/lib/useAsyncRetry';
14
+ import 'react-use/esm/useAsyncRetry';
9
15
  import '@material-ui/icons/Notifications';
10
16
  import 'lodash/throttle';
11
17
  import 'react-relative-time';
18
+ import '@material-ui/core/Box';
19
+ import '@material-ui/core/IconButton';
20
+ import '@material-ui/core/Tooltip';
12
21
  import '@material-ui/icons/Markunread';
13
22
  import '@material-ui/icons/CheckCircle';
14
23
  import '@material-ui/icons/LabelOff';
@@ -265,4 +274,4 @@ const NotificationsPage = () => {
265
274
  };
266
275
 
267
276
  export { NotificationsPage };
268
- //# sourceMappingURL=index-9328bf59.esm.js.map
277
+ //# sourceMappingURL=index-Bu8bbvQt.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-Bu8bbvQt.esm.js","sources":["../../src/components/NotificationsFilters/NotificationsFilters.tsx","../../src/components/NotificationsPage/NotificationsPage.tsx"],"sourcesContent":["/*\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 React from 'react';\n\nimport Divider from '@material-ui/core/Divider';\nimport FormControl from '@material-ui/core/FormControl';\nimport Grid from '@material-ui/core/Grid';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Select from '@material-ui/core/Select';\nimport Typography from '@material-ui/core/Typography';\nimport { GetNotificationsOptions } from '../../api';\nimport { NotificationSeverity } from '@backstage/plugin-notifications-common';\n\nexport type SortBy = Required<\n Pick<GetNotificationsOptions, 'sort' | 'sortOrder'>\n>;\n\nexport type NotificationsFiltersProps = {\n unreadOnly?: boolean;\n onUnreadOnlyChanged: (checked: boolean | undefined) => void;\n createdAfter?: string;\n onCreatedAfterChanged: (value: string) => void;\n sorting: SortBy;\n onSortingChanged: (sortBy: SortBy) => void;\n saved?: boolean;\n onSavedChanged: (checked: boolean | undefined) => void;\n severity: NotificationSeverity;\n onSeverityChanged: (severity: NotificationSeverity) => void;\n};\n\nexport const CreatedAfterOptions: {\n [key: string]: { label: string; getDate: () => Date };\n} = {\n last24h: {\n label: 'Last 24h',\n getDate: () => new Date(Date.now() - 24 * 3600 * 1000),\n },\n lastWeek: {\n label: 'Last week',\n getDate: () => new Date(Date.now() - 7 * 24 * 3600 * 1000),\n },\n all: {\n label: 'Any time',\n getDate: () => new Date(0),\n },\n};\n\nexport const SortByOptions: {\n [key: string]: {\n label: string;\n sortBy: SortBy;\n };\n} = {\n newest: {\n label: 'Newest on top',\n sortBy: {\n sort: 'created',\n sortOrder: 'desc',\n },\n },\n oldest: {\n label: 'Oldest on top',\n sortBy: {\n sort: 'created',\n sortOrder: 'asc',\n },\n },\n topic: {\n label: 'Topic',\n sortBy: {\n sort: 'topic',\n sortOrder: 'asc',\n },\n },\n origin: {\n label: 'Origin',\n sortBy: {\n sort: 'origin',\n sortOrder: 'asc',\n },\n },\n};\n\nconst getSortByText = (sortBy?: SortBy): string => {\n if (sortBy?.sort === 'created' && sortBy?.sortOrder === 'asc') {\n return 'oldest';\n }\n if (sortBy?.sort === 'topic') {\n return 'topic';\n }\n if (sortBy?.sort === 'origin') {\n return 'origin';\n }\n\n return 'newest';\n};\n\nconst AllSeverityOptions: { [key in NotificationSeverity]: string } = {\n critical: 'Critical',\n high: 'High',\n normal: 'Normal',\n low: 'Low',\n};\n\nexport const NotificationsFilters = ({\n sorting,\n onSortingChanged,\n unreadOnly,\n onUnreadOnlyChanged,\n createdAfter,\n onCreatedAfterChanged,\n saved,\n onSavedChanged,\n severity,\n onSeverityChanged,\n}: NotificationsFiltersProps) => {\n const sortByText = getSortByText(sorting);\n\n const handleOnCreatedAfterChanged = (\n event: React.ChangeEvent<{ name?: string; value: unknown }>,\n ) => {\n onCreatedAfterChanged(event.target.value as string);\n };\n\n const handleOnViewChanged = (\n event: React.ChangeEvent<{ name?: string; value: unknown }>,\n ) => {\n if (event.target.value === 'unread') {\n onUnreadOnlyChanged(true);\n onSavedChanged(undefined);\n } else if (event.target.value === 'read') {\n onUnreadOnlyChanged(false);\n onSavedChanged(undefined);\n } else if (event.target.value === 'saved') {\n onUnreadOnlyChanged(undefined);\n onSavedChanged(true);\n } else {\n // All\n onUnreadOnlyChanged(undefined);\n onSavedChanged(undefined);\n }\n };\n\n const handleOnSortByChanged = (\n event: React.ChangeEvent<{ name?: string; value: unknown }>,\n ) => {\n const idx = (event.target.value as string) || 'newest';\n const option = SortByOptions[idx];\n onSortingChanged({ ...option.sortBy });\n };\n\n let viewValue = 'all';\n if (saved) {\n viewValue = 'saved';\n } else if (unreadOnly) {\n viewValue = 'unread';\n } else if (unreadOnly === false) {\n viewValue = 'read';\n }\n\n const handleOnSeverityChanged = (\n event: React.ChangeEvent<{ name?: string; value: unknown }>,\n ) => {\n const value: NotificationSeverity =\n (event.target.value as NotificationSeverity) || 'normal';\n onSeverityChanged(value);\n };\n\n return (\n <>\n <Grid container>\n <Grid item xs={12}>\n <Typography variant=\"h6\">Filters</Typography>\n <Divider variant=\"fullWidth\" />\n </Grid>\n\n <Grid item xs={12}>\n <FormControl fullWidth variant=\"outlined\" size=\"small\">\n <InputLabel id=\"notifications-filter-view\">View</InputLabel>\n <Select\n labelId=\"notifications-filter-view\"\n label=\"View\"\n value={viewValue}\n onChange={handleOnViewChanged}\n >\n <MenuItem value=\"unread\">New only</MenuItem>\n <MenuItem value=\"saved\">Saved</MenuItem>\n <MenuItem value=\"read\">Marked as read</MenuItem>\n <MenuItem value=\"all\">All</MenuItem>\n </Select>\n </FormControl>\n </Grid>\n\n <Grid item xs={12}>\n <FormControl fullWidth variant=\"outlined\" size=\"small\">\n <InputLabel id=\"notifications-filter-created\">\n Created after\n </InputLabel>\n\n <Select\n label=\"Created after\"\n labelId=\"notifications-filter-created\"\n placeholder=\"Notifications since\"\n value={createdAfter}\n onChange={handleOnCreatedAfterChanged}\n >\n {Object.keys(CreatedAfterOptions).map((key: string) => (\n <MenuItem value={key} key={key}>\n {CreatedAfterOptions[key].label}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n\n <Grid item xs={12}>\n <FormControl fullWidth variant=\"outlined\" size=\"small\">\n <InputLabel id=\"notifications-filter-sort\">Sort by</InputLabel>\n\n <Select\n label=\"Sort by\"\n labelId=\"notifications-filter-sort\"\n placeholder=\"Field to sort by\"\n value={sortByText}\n onChange={handleOnSortByChanged}\n >\n {Object.keys(SortByOptions).map((key: string) => (\n <MenuItem value={key} key={key}>\n {SortByOptions[key].label}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n\n <Grid item xs={12}>\n <FormControl fullWidth variant=\"outlined\" size=\"small\">\n <InputLabel id=\"notifications-filter-severity\">Severity</InputLabel>\n\n <Select\n label=\"Severity\"\n labelId=\"notifications-filter-severity\"\n value={severity}\n onChange={handleOnSeverityChanged}\n >\n {Object.keys(AllSeverityOptions).map((key: string) => (\n <MenuItem value={key} key={key}>\n {AllSeverityOptions[key as NotificationSeverity]}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n </Grid>\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 */\n\nimport React, { useEffect } from 'react';\nimport {\n Content,\n PageWithHeader,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport Grid from '@material-ui/core/Grid';\nimport { useSignal } from '@backstage/plugin-signals-react';\n\nimport { NotificationsTable } from '../NotificationsTable';\nimport { useNotificationsApi } from '../../hooks';\nimport {\n CreatedAfterOptions,\n NotificationsFilters,\n SortBy,\n SortByOptions,\n} from '../NotificationsFilters';\nimport { GetNotificationsOptions } from '../../api';\nimport { NotificationSeverity } from '@backstage/plugin-notifications-common';\n\nexport const NotificationsPage = () => {\n const [refresh, setRefresh] = React.useState(false);\n const { lastSignal } = useSignal('notifications');\n const [unreadOnly, setUnreadOnly] = React.useState<boolean | undefined>(true);\n const [saved, setSaved] = React.useState<boolean | undefined>(undefined);\n const [pageNumber, setPageNumber] = React.useState(0);\n const [pageSize, setPageSize] = React.useState(5);\n const [containsText, setContainsText] = React.useState<string>();\n const [createdAfter, setCreatedAfter] = React.useState<string>('lastWeek');\n const [sorting, setSorting] = React.useState<SortBy>(\n SortByOptions.newest.sortBy,\n );\n const [severity, setSeverity] = React.useState<NotificationSeverity>('low');\n\n const { error, value, retry, loading } = useNotificationsApi(\n api => {\n const options: GetNotificationsOptions = {\n search: containsText,\n limit: pageSize,\n offset: pageNumber * pageSize,\n minimumSeverity: severity,\n ...(sorting || {}),\n };\n if (unreadOnly !== undefined) {\n options.read = !unreadOnly;\n }\n if (saved !== undefined) {\n options.saved = saved;\n }\n\n const createdAfterDate = CreatedAfterOptions[createdAfter].getDate();\n if (createdAfterDate.valueOf() > 0) {\n options.createdAfter = createdAfterDate;\n }\n\n return api.getNotifications(options);\n },\n [\n containsText,\n unreadOnly,\n createdAfter,\n pageNumber,\n pageSize,\n sorting,\n saved,\n severity,\n ],\n );\n\n useEffect(() => {\n if (refresh) {\n retry();\n setRefresh(false);\n }\n }, [refresh, setRefresh, retry]);\n\n useEffect(() => {\n if (lastSignal && lastSignal.action) {\n setRefresh(true);\n }\n }, [lastSignal]);\n\n const onUpdate = () => {\n setRefresh(true);\n };\n\n if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n return (\n <PageWithHeader title=\"Notifications\" themeId=\"tool\">\n <Content>\n <Grid container>\n <Grid item xs={2}>\n <NotificationsFilters\n unreadOnly={unreadOnly}\n onUnreadOnlyChanged={setUnreadOnly}\n createdAfter={createdAfter}\n onCreatedAfterChanged={setCreatedAfter}\n onSortingChanged={setSorting}\n sorting={sorting}\n saved={saved}\n onSavedChanged={setSaved}\n severity={severity}\n onSeverityChanged={setSeverity}\n />\n </Grid>\n <Grid item xs={10}>\n <NotificationsTable\n isLoading={loading}\n notifications={value?.notifications}\n onUpdate={onUpdate}\n setContainsText={setContainsText}\n onPageChange={setPageNumber}\n onRowsPerPageChange={setPageSize}\n page={pageNumber}\n pageSize={pageSize}\n totalCount={value?.totalCount}\n />\n </Grid>\n </Grid>\n </Content>\n </PageWithHeader>\n );\n};\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -115,4 +115,4 @@ type NotificationsTableProps = Pick<TableProps, 'onPageChange' | 'onRowsPerPageC
115
115
  /** @public */
116
116
  declare const NotificationsTable: ({ isLoading, notifications, onUpdate, setContainsText, onPageChange, onRowsPerPageChange, page, pageSize, totalCount, }: NotificationsTableProps) => React__default.JSX.Element;
117
117
 
118
- export { GetNotificationsOptions, GetNotificationsResponse, NotificationsApi, NotificationsClient, NotificationsPage, NotificationsSidebarItem, NotificationsTable, NotificationsTableProps, UpdateNotificationsOptions, notificationsApiRef, notificationsPlugin, useNotificationsApi, useTitleCounter, useWebNotifications };
118
+ export { type GetNotificationsOptions, type GetNotificationsResponse, type NotificationsApi, NotificationsClient, NotificationsPage, NotificationsSidebarItem, NotificationsTable, type NotificationsTableProps, type UpdateNotificationsOptions, notificationsApiRef, notificationsPlugin, useNotificationsApi, useTitleCounter, useWebNotifications };
package/dist/index.esm.js CHANGED
@@ -1,13 +1,17 @@
1
1
  import { createRouteRef, createApiRef, createPlugin, createApiFactory, discoveryApiRef, fetchApiRef, createRoutableExtension, useApi, useRouteRef } from '@backstage/core-plugin-api';
2
2
  import { ResponseError } from '@backstage/errors';
3
- import useAsyncRetry from 'react-use/lib/useAsyncRetry';
3
+ import useAsyncRetry from 'react-use/esm/useAsyncRetry';
4
4
  import React, { useState, useEffect, useCallback, useMemo } from 'react';
5
5
  import { SidebarItem, Link, Table } from '@backstage/core-components';
6
6
  import NotificationsIcon from '@material-ui/icons/Notifications';
7
7
  import { useSignal } from '@backstage/plugin-signals-react';
8
8
  import throttle from 'lodash/throttle';
9
9
  import RelativeTime from 'react-relative-time';
10
- import { Box, Typography, Grid, Tooltip, IconButton } from '@material-ui/core';
10
+ import Box from '@material-ui/core/Box';
11
+ import Grid from '@material-ui/core/Grid';
12
+ import IconButton from '@material-ui/core/IconButton';
13
+ import Tooltip from '@material-ui/core/Tooltip';
14
+ import Typography from '@material-ui/core/Typography';
11
15
  import MarkAsUnreadIcon from '@material-ui/icons/Markunread';
12
16
  import MarkAsReadIcon from '@material-ui/icons/CheckCircle';
13
17
  import MarkAsUnsavedIcon from '@material-ui/icons/LabelOff';
@@ -111,7 +115,7 @@ const notificationsPlugin = createPlugin({
111
115
  const NotificationsPage = notificationsPlugin.provide(
112
116
  createRoutableExtension({
113
117
  name: "NotificationsPage",
114
- component: () => import('./esm/index-9328bf59.esm.js').then((m) => m.NotificationsPage),
118
+ component: () => import('./esm/index-Bu8bbvQt.esm.js').then((m) => m.NotificationsPage),
115
119
  mountPoint: rootRouteRef
116
120
  })
117
121
  );
@@ -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/SeverityIcon.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 NotificationSeverity,\n NotificationStatus,\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 offset?: number;\n limit?: number;\n search?: string;\n read?: boolean;\n saved?: boolean;\n createdAfter?: Date;\n sort?: 'created' | 'topic' | 'origin';\n sortOrder?: 'asc' | 'desc';\n minimumSeverity?: NotificationSeverity;\n};\n\n/** @public */\nexport type UpdateNotificationsOptions = {\n ids: string[];\n read?: boolean;\n saved?: boolean;\n};\n\n/** @public */\nexport type GetNotificationsResponse = {\n notifications: Notification[];\n totalCount: number;\n};\n\n/** @public */\nexport interface NotificationsApi {\n getNotifications(\n options?: GetNotificationsOptions,\n ): Promise<GetNotificationsResponse>;\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 GetNotificationsResponse,\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<GetNotificationsResponse> {\n const queryString = new URLSearchParams();\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?.sort !== undefined) {\n queryString.append(\n 'orderField',\n `${options.sort},${options?.sortOrder ?? 'desc'}`,\n );\n }\n if (options?.search) {\n queryString.append('search', options.search);\n }\n if (options?.read !== undefined) {\n queryString.append('read', options.read ? 'true' : 'false');\n }\n if (options?.saved !== undefined) {\n queryString.append('saved', options.saved ? 'true' : 'false');\n }\n if (options?.createdAfter !== undefined) {\n queryString.append('createdAfter', options.createdAfter.toISOString());\n }\n if (options?.minimumSeverity !== undefined) {\n queryString.append('minimal_severity', options.minimumSeverity);\n }\n const urlSegment = `?${queryString}`;\n\n return await this.request<GetNotificationsResponse>(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 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 React from 'react';\nimport { NotificationSeverity } from '@backstage/plugin-notifications-common';\nimport NormalIcon from '@material-ui/icons/CheckOutlined';\nimport CriticalIcon from '@material-ui/icons/ErrorOutline';\nimport HighIcon from '@material-ui/icons/WarningOutlined';\nimport LowIcon from '@material-ui/icons/InfoOutlined';\n\nexport const SeverityIcon = ({\n severity,\n}: {\n severity?: NotificationSeverity;\n}) => {\n switch (severity) {\n case 'critical':\n return <CriticalIcon htmlColor=\"#C9190B\" />;\n case 'high':\n return <HighIcon htmlColor=\"#F0AB00\" />;\n case 'low':\n return <LowIcon htmlColor=\"#2B9AF3\" />;\n case 'normal':\n default:\n return <NormalIcon htmlColor=\"#5BA352\" />;\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, { useMemo } from 'react';\nimport throttle from 'lodash/throttle';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\nimport { Box, Grid, IconButton, Tooltip, Typography } from '@material-ui/core';\nimport { Notification } from '@backstage/plugin-notifications-common';\n\nimport { notificationsApiRef } from '../../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n Link,\n Table,\n TableProps,\n TableColumn,\n} from '@backstage/core-components';\n\nimport MarkAsUnreadIcon from '@material-ui/icons/Markunread' /* TODO: use Drafts and MarkAsUnread once we have mui 5 icons */;\nimport MarkAsReadIcon from '@material-ui/icons/CheckCircle';\nimport MarkAsUnsavedIcon from '@material-ui/icons/LabelOff' /* TODO: use BookmarkRemove and BookmarkAdd once we have mui 5 icons */;\nimport MarkAsSavedIcon from '@material-ui/icons/Label';\nimport { SeverityIcon } from './SeverityIcon';\n\nconst ThrottleDelayMs = 1000;\n\n/** @public */\nexport type NotificationsTableProps = Pick<\n TableProps,\n 'onPageChange' | 'onRowsPerPageChange' | 'page' | 'totalCount'\n> & {\n isLoading?: boolean;\n notifications?: Notification[];\n onUpdate: () => void;\n setContainsText: (search: string) => void;\n pageSize: number;\n};\n\n/** @public */\nexport const NotificationsTable = ({\n isLoading,\n notifications = [],\n onUpdate,\n setContainsText,\n onPageChange,\n onRowsPerPageChange,\n page,\n pageSize,\n totalCount,\n}: NotificationsTableProps) => {\n const notificationsApi = useApi(notificationsApiRef);\n\n const onSwitchReadStatus = React.useCallback(\n (notification: Notification) => {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n read: !notification.read,\n })\n .then(() => onUpdate());\n },\n [notificationsApi, onUpdate],\n );\n\n const onSwitchSavedStatus = React.useCallback(\n (notification: Notification) => {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n saved: !notification.saved,\n })\n .then(() => onUpdate());\n },\n [notificationsApi, onUpdate],\n );\n\n const throttledContainsTextHandler = useMemo(\n () => throttle(setContainsText, ThrottleDelayMs),\n [setContainsText],\n );\n\n const compactColumns = React.useMemo(\n (): TableColumn<Notification>[] => [\n {\n width: '1rem',\n render: (notification: Notification) => (\n <SeverityIcon severity={notification.payload?.severity} />\n ),\n },\n {\n customFilterAndSearch: () =>\n true /* Keep it on backend due to pagination. If recent flickering is an issue, implement search here as well. */,\n render: (notification: Notification) => {\n // Compact content\n return (\n <>\n <Box>\n <Typography variant=\"subtitle2\">\n {notification.payload.link ? (\n <Link to={notification.payload.link}>\n {notification.payload.title}\n </Link>\n ) : (\n notification.payload.title\n )}\n </Typography>\n <Typography variant=\"body2\">\n {notification.payload.description}\n </Typography>\n <Typography variant=\"caption\">\n {notification.origin && (\n <>{notification.origin}&nbsp;&bull;&nbsp;</>\n )}\n {notification.payload.topic && (\n <>{notification.payload.topic}&nbsp;&bull;&nbsp;</>\n )}\n {notification.created && (\n <RelativeTime value={notification.created} />\n )}\n </Typography>\n </Box>\n </>\n );\n },\n },\n // {\n // // TODO: additional action links\n // width: '25%',\n // render: (notification: Notification) => {\n // return (\n // notification.payload.link && (\n // <Grid container>\n // {/* TODO: render additionalLinks of different titles */}\n // <Grid item>\n // <Link\n // key={notification.payload.link}\n // to={notification.payload.link}\n // >\n // &nbsp;More info\n // </Link>\n // </Grid>\n // </Grid>\n // )\n // );\n // },\n // },\n {\n // actions\n width: '1rem',\n render: (notification: Notification) => {\n const markAsReadText = !!notification.read\n ? 'Return among unread'\n : 'Mark as read';\n const IconComponent = !!notification.read\n ? MarkAsUnreadIcon\n : MarkAsReadIcon;\n\n const markAsSavedText = !!notification.saved\n ? 'Undo save'\n : 'Save for later';\n\n const SavedIconComponent = !!notification.saved\n ? MarkAsUnsavedIcon\n : MarkAsSavedIcon;\n\n return (\n <Grid container wrap=\"nowrap\">\n <Grid item>\n <Tooltip title={markAsSavedText}>\n <IconButton\n onClick={() => {\n onSwitchSavedStatus(notification);\n }}\n >\n <SavedIconComponent aria-label={markAsSavedText} />\n </IconButton>\n </Tooltip>\n </Grid>\n\n <Grid item>\n <Tooltip title={markAsReadText}>\n <IconButton\n onClick={() => {\n onSwitchReadStatus(notification);\n }}\n >\n <IconComponent aria-label={markAsReadText} />\n </IconButton>\n </Tooltip>\n </Grid>\n </Grid>\n );\n },\n },\n ],\n [onSwitchReadStatus, onSwitchSavedStatus],\n );\n\n return (\n <Table<Notification>\n isLoading={isLoading}\n options={{\n search: true,\n paging: true,\n pageSize,\n header: false,\n sorting: false,\n }}\n onPageChange={onPageChange}\n onRowsPerPageChange={onRowsPerPageChange}\n page={page}\n totalCount={totalCount}\n onSearchChange={throttledContainsTextHandler}\n data={notifications}\n columns={compactColumns}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAiBO,MAAM,eAAe,cAAe,CAAA;AAAA,EACzC,EAAI,EAAA,eAAA;AACN,CAAC,CAAA;;ACIM,MAAM,sBAAsB,YAA+B,CAAA;AAAA,EAChE,EAAI,EAAA,8BAAA;AACN,CAAC;;;;;;;;ACIM,MAAM,mBAAgD,CAAA;AAAA,EAIpD,YAAY,OAGhB,EAAA;AANH,IAAiB,aAAA,CAAA,IAAA,EAAA,cAAA,CAAA,CAAA;AACjB,IAAiB,aAAA,CAAA,IAAA,EAAA,UAAA,CAAA,CAAA;AAMf,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA,CAAA;AAC5B,IAAA,IAAA,CAAK,WAAW,OAAQ,CAAA,QAAA,CAAA;AAAA,GAC1B;AAAA,EAEA,MAAM,iBACJ,OACmC,EAAA;AA3CvC,IAAA,IAAA,EAAA,CAAA;AA4CI,IAAM,MAAA,WAAA,GAAc,IAAI,eAAgB,EAAA,CAAA;AACxC,IAAI,IAAA,CAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAS,WAAU,KAAW,CAAA,EAAA;AAChC,MAAA,WAAA,CAAY,OAAO,OAAS,EAAA,OAAA,CAAQ,KAAM,CAAA,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA;AAAA,KACxD;AACA,IAAI,IAAA,CAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAS,YAAW,KAAW,CAAA,EAAA;AACjC,MAAA,WAAA,CAAY,OAAO,QAAU,EAAA,OAAA,CAAQ,MAAO,CAAA,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA;AAAA,KAC1D;AACA,IAAI,IAAA,CAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAS,UAAS,KAAW,CAAA,EAAA;AAC/B,MAAY,WAAA,CAAA,MAAA;AAAA,QACV,YAAA;AAAA,QACA,GAAG,OAAQ,CAAA,IAAI,KAAI,EAAS,GAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,SAAA,KAAT,YAAsB,MAAM,CAAA,CAAA;AAAA,OACjD,CAAA;AAAA,KACF;AACA,IAAA,IAAI,mCAAS,MAAQ,EAAA;AACnB,MAAY,WAAA,CAAA,MAAA,CAAO,QAAU,EAAA,OAAA,CAAQ,MAAM,CAAA,CAAA;AAAA,KAC7C;AACA,IAAI,IAAA,CAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAS,UAAS,KAAW,CAAA,EAAA;AAC/B,MAAA,WAAA,CAAY,MAAO,CAAA,MAAA,EAAQ,OAAQ,CAAA,IAAA,GAAO,SAAS,OAAO,CAAA,CAAA;AAAA,KAC5D;AACA,IAAI,IAAA,CAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAS,WAAU,KAAW,CAAA,EAAA;AAChC,MAAA,WAAA,CAAY,MAAO,CAAA,OAAA,EAAS,OAAQ,CAAA,KAAA,GAAQ,SAAS,OAAO,CAAA,CAAA;AAAA,KAC9D;AACA,IAAI,IAAA,CAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAS,kBAAiB,KAAW,CAAA,EAAA;AACvC,MAAA,WAAA,CAAY,MAAO,CAAA,cAAA,EAAgB,OAAQ,CAAA,YAAA,CAAa,aAAa,CAAA,CAAA;AAAA,KACvE;AACA,IAAI,IAAA,CAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAS,qBAAoB,KAAW,CAAA,EAAA;AAC1C,MAAY,WAAA,CAAA,MAAA,CAAO,kBAAoB,EAAA,OAAA,CAAQ,eAAe,CAAA,CAAA;AAAA,KAChE;AACA,IAAM,MAAA,UAAA,GAAa,IAAI,WAAW,CAAA,CAAA,CAAA;AAElC,IAAO,OAAA,MAAM,IAAK,CAAA,OAAA,CAAkC,UAAU,CAAA,CAAA;AAAA,GAChE;AAAA,EAEA,MAAM,gBAAgB,EAAmC,EAAA;AACvD,IAAA,OAAO,MAAM,IAAA,CAAK,OAAsB,CAAA,CAAA,EAAG,EAAE,CAAE,CAAA,CAAA,CAAA;AAAA,GACjD;AAAA,EAEA,MAAM,SAAyC,GAAA;AAC7C,IAAO,OAAA,MAAM,IAAK,CAAA,OAAA,CAA4B,QAAQ,CAAA,CAAA;AAAA,GACxD;AAAA,EAEA,MAAM,oBACJ,OACyB,EAAA;AACzB,IAAO,OAAA,MAAM,IAAK,CAAA,OAAA,CAAwB,QAAU,EAAA;AAAA,MAClD,MAAQ,EAAA,MAAA;AAAA,MACR,IAAA,EAAM,IAAK,CAAA,SAAA,CAAU,OAAO,CAAA;AAAA,MAC5B,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAmB,EAAA;AAAA,KAC/C,CAAA,CAAA;AAAA,GACH;AAAA,EAEA,MAAc,OAAW,CAAA,IAAA,EAAc,IAAwB,EAAA;AAC7D,IAAA,MAAM,UAAU,CAAG,EAAA,MAAM,KAAK,YAAa,CAAA,UAAA,CAAW,eAAe,CAAC,CAAA,CAAA,CAAA,CAAA;AACtE,IAAA,MAAM,GAAM,GAAA,IAAI,GAAI,CAAA,IAAA,EAAM,OAAO,CAAA,CAAA;AAEjC,IAAM,MAAA,QAAA,GAAW,MAAM,IAAK,CAAA,QAAA,CAAS,MAAM,GAAI,CAAA,QAAA,IAAY,IAAI,CAAA,CAAA;AAE/D,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAM,MAAA,MAAM,aAAc,CAAA,YAAA,CAAa,QAAQ,CAAA,CAAA;AAAA,KACjD;AAEA,IAAA,OAAO,SAAS,IAAK,EAAA,CAAA;AAAA,GACvB;AACF;;AC/EO,MAAM,sBAAsB,YAAa,CAAA;AAAA,EAC9C,EAAI,EAAA,eAAA;AAAA,EACJ,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,YAAA;AAAA,GACR;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,mBAAA;AAAA,MACL,IAAM,EAAA,EAAE,YAAc,EAAA,eAAA,EAAiB,UAAU,WAAY,EAAA;AAAA,MAC7D,OAAA,EAAS,CAAC,EAAE,YAAc,EAAA,QAAA,EACxB,KAAA,IAAI,mBAAoB,CAAA,EAAE,YAAc,EAAA,QAAA,EAAU,CAAA;AAAA,KACrD,CAAA;AAAA,GACH;AACF,CAAC,EAAA;AAGM,MAAM,oBAAoB,mBAAoB,CAAA,OAAA;AAAA,EACnD,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,mBAAA;AAAA,IACN,SAAA,EAAW,MACT,OAAO,6BAAgC,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,iBAAiB,CAAA;AAAA,IACxE,UAAY,EAAA,YAAA;AAAA,GACb,CAAA;AACH;;AC9BO,SAAS,mBACd,CAAA,CAAA,EACA,IAAc,GAAA,EACd,EAAA;AACA,EAAM,MAAA,gBAAA,GAAmB,OAAO,mBAAmB,CAAA,CAAA;AAEnD,EAAA,OAAO,cAAc,YAAY;AAC/B,IAAO,OAAA,MAAM,EAAE,gBAAgB,CAAA,CAAA;AAAA,KAC9B,IAAI,CAAA,CAAA;AACT;;ACZO,SAAS,mBAAsB,GAAA;AACpC,EAAA,MAAM,CAAC,yBAAA,EAA2B,4BAA4B,CAAA,GAC5D,SAAS,SAAS,CAAA,CAAA;AACpB,EAAA,MAAM,CAAC,gBAAkB,EAAA,mBAAmB,CAAI,GAAA,QAAA,CAAyB,EAAE,CAAA,CAAA;AAE3E,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,cAAA,IAAkB,MAAU,IAAA,yBAAA,KAA8B,SAAW,EAAA;AACvE,MAAA,MAAA,CAAO,YAAa,CAAA,iBAAA,EAAoB,CAAA,IAAA,CAAK,CAAc,UAAA,KAAA;AACzD,QAAA,4BAAA,CAA6B,UAAU,CAAA,CAAA;AAAA,OACxC,CAAA,CAAA;AAAA,KACH;AAAA,GACF,EAAG,CAAC,yBAAyB,CAAC,CAAA,CAAA;AAE9B,EAAS,QAAA,CAAA,gBAAA,CAAiB,oBAAoB,MAAM;AAClD,IAAI,IAAA,QAAA,CAAS,oBAAoB,SAAW,EAAA;AAC1C,MAAA,gBAAA,CAAiB,OAAQ,CAAA,CAAA,CAAA,KAAK,CAAE,CAAA,KAAA,EAAO,CAAA,CAAA;AACvC,MAAA,mBAAA,CAAoB,EAAE,CAAA,CAAA;AAAA,KACxB;AAAA,GACD,CAAA,CAAA;AAED,EAAA,MAAM,mBAAsB,GAAA,WAAA;AAAA,IAC1B,CAAC,OAAmE,KAAA;AAClE,MAAA,IAAI,8BAA8B,SAAW,EAAA;AAC3C,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAEA,MAAA,MAAM,YAAe,GAAA,IAAI,YAAa,CAAA,OAAA,CAAQ,KAAO,EAAA;AAAA,QACnD,MAAM,OAAQ,CAAA,WAAA;AAAA,OACf,CAAA,CAAA;AAED,MAAA,YAAA,CAAa,UAAU,CAAS,KAAA,KAAA;AAC9B,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,YAAA,CAAa,KAAM,EAAA,CAAA;AACnB,QAAA,IAAI,QAAQ,IAAM,EAAA;AAChB,UAAO,MAAA,CAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,EAAM,QAAQ,CAAA,CAAA;AAAA,SACpC;AAAA,OACF,CAAA;AAEA,MAAO,OAAA,YAAA,CAAA;AAAA,KACT;AAAA,IACA,CAAC,yBAAyB,CAAA;AAAA,GAC5B,CAAA;AAEA,EAAA,OAAO,EAAE,mBAAoB,EAAA,CAAA;AAC/B;;AC5CO,SAAS,eAAkB,GAAA;AAChC,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAA,QAAA,CAAS,SAAS,KAAK,CAAA,CAAA;AACjD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,CAAC,CAAA,CAAA;AAEpC,EAAM,MAAA,SAAA,GAAY,CAAC,KAAkB,KAAA;AACnC,IAAA,OAAO,KAAU,KAAA,CAAA,GAAI,EAAK,GAAA,CAAA,CAAA,EAAI,KAAK,CAAA,EAAA,CAAA,CAAA;AAAA,GACrC,CAAA;AAEA,EAAM,MAAA,UAAA,GAAa,CAAC,YAAyB,KAAA;AAC3C,IAAO,OAAA,YAAA,CAAa,OAAQ,CAAA,YAAA,EAAc,EAAE,CAAA,CAAA;AAAA,GAC9C,CAAA;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,QAAA,CAAS,KAAQ,GAAA,KAAA,CAAA;AAAA,GACnB,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AAEV,EAAA,SAAA,CAAU,MAAM;AACd,IAAM,MAAA,SAAA,GAAY,WAAW,KAAK,CAAA,CAAA;AAClC,IAAA,QAAA,CAAS,GAAG,SAAU,CAAA,KAAK,CAAC,CAAA,EAAG,SAAS,CAAE,CAAA,CAAA,CAAA;AAC1C,IAAA,OAAO,MAAM;AACX,MAAS,QAAA,CAAA,KAAA,GAAQ,WAAW,KAAK,CAAA,CAAA;AAAA,KACnC,CAAA;AAAA,GACC,EAAA,CAAC,KAAO,EAAA,KAAK,CAAC,CAAA,CAAA;AAEjB,EAAM,MAAA,YAAA,GAAe,QAAS,CAAA,aAAA,CAAc,OAAO,CAAA,CAAA;AACnD,EAAA,IAAI,YAAc,EAAA;AAChB,IAAA,IAAI,iBAAiB,MAAM;AACzB,MAAA,QAAA,CAAS,SAAS,KAAK,CAAA,CAAA;AAAA,KACxB,CAAE,CAAA,OAAA,CAAQ,YAAc,EAAA;AAAA,MACvB,OAAS,EAAA,IAAA;AAAA,MACT,aAAe,EAAA,IAAA;AAAA,MACf,SAAW,EAAA,IAAA;AAAA,KACZ,CAAA,CAAA;AAAA,GACH;AAEA,EAAA,MAAM,oBAAuB,GAAA,WAAA;AAAA,IAC3B,CAAC,QAAqB,KAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,IACvC,EAAC;AAAA,GACH,CAAA;AAEA,EAAA,OAAO,EAAE,oBAAqB,EAAA,CAAA;AAChC;;AC/Ba,MAAA,wBAAA,GAA2B,CAAC,KAGnC,KAAA;AACJ,EAAM,MAAA,EAAE,uBAA0B,GAAA,KAAA,EAAO,mBAAsB,GAAA,IAAA,EAC7D,GAAA,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,EAAE,uBAAA,EAAyB,KAAO,EAAA,mBAAA,EAAqB,IAAK,EAAA,CAAA;AAEvE,EAAA,MAAM,EAAE,OAAA,EAAS,KAAO,EAAA,KAAA,EAAO,OAAU,GAAA,mBAAA;AAAA,IAAoB,CAAA,GAAA,KAC3D,IAAI,SAAU,EAAA;AAAA,GAChB,CAAA;AACA,EAAM,MAAA,gBAAA,GAAmB,OAAO,mBAAmB,CAAA,CAAA;AACnD,EAAA,MAAM,CAAC,WAAa,EAAA,cAAc,CAAI,GAAA,KAAA,CAAM,SAAS,CAAC,CAAA,CAAA;AACtD,EAAM,MAAA,kBAAA,GAAqB,YAAY,YAAY,CAAA,CAAA;AAEnD,EAAA,MAAM,EAAE,UAAA,EAAe,GAAA,SAAA,CAA8B,eAAe,CAAA,CAAA;AACpE,EAAM,MAAA,EAAE,mBAAoB,EAAA,GAAI,mBAAoB,EAAA,CAAA;AACpD,EAAA,MAAM,CAAC,OAAS,EAAA,UAAU,CAAI,GAAA,KAAA,CAAM,SAAS,KAAK,CAAA,CAAA;AAClD,EAAM,MAAA,EAAE,oBAAqB,EAAA,GAAI,eAAgB,EAAA,CAAA;AAEjD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAS,EAAA;AACX,MAAM,KAAA,EAAA,CAAA;AACN,MAAA,UAAA,CAAW,KAAK,CAAA,CAAA;AAAA,KAClB;AAAA,GACC,EAAA,CAAC,OAAS,EAAA,KAAK,CAAC,CAAA,CAAA;AAEnB,EAAA,SAAA,CAAU,MAAM;AACd,IAAM,MAAA,qBAAA,GAAwB,CAAC,MAA+B,KAAA;AAC5D,MAAA,IAAI,CAAC,uBAAA,IAA2B,MAAO,CAAA,MAAA,KAAW,kBAAoB,EAAA;AACpE,QAAA,OAAA;AAAA,OACF;AAEA,MAAA,gBAAA,CACG,eAAgB,CAAA,MAAA,CAAO,eAAe,CAAA,CACtC,KAAK,CAAgB,YAAA,KAAA;AA9D9B,QAAA,IAAA,EAAA,CAAA;AA+DU,QAAA,IAAI,CAAC,YAAc,EAAA;AACjB,UAAA,OAAA;AAAA,SACF;AACA,QAAoB,mBAAA,CAAA;AAAA,UAClB,KAAA,EAAO,aAAa,OAAQ,CAAA,KAAA;AAAA,UAC5B,WAAa,EAAA,CAAA,EAAA,GAAA,YAAA,CAAa,OAAQ,CAAA,WAAA,KAArB,IAAoC,GAAA,EAAA,GAAA,EAAA;AAAA,UACjD,IAAA,EAAM,aAAa,OAAQ,CAAA,IAAA;AAAA,SAC5B,CAAA,CAAA;AAAA,OACF,CAAA,CAAA;AAAA,KACL,CAAA;AAEA,IAAI,IAAA,UAAA,IAAc,WAAW,MAAQ,EAAA;AACnC,MAAA,qBAAA,CAAsB,UAAU,CAAA,CAAA;AAChC,MAAA,UAAA,CAAW,IAAI,CAAA,CAAA;AAAA,KACjB;AAAA,GACC,EAAA;AAAA,IACD,UAAA;AAAA,IACA,mBAAA;AAAA,IACA,uBAAA;AAAA,IACA,gBAAA;AAAA,GACD,CAAA,CAAA;AAED,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,KAAA,IAAS,KAAO,EAAA;AAC/B,MAAA,cAAA,CAAe,MAAM,MAAM,CAAA,CAAA;AAC3B,MAAA,IAAI,mBAAqB,EAAA;AACvB,QAAA,oBAAA,CAAqB,MAAM,MAAM,CAAA,CAAA;AAAA,OACnC;AAAA,KACF;AAAA,KACC,CAAC,OAAA,EAAS,OAAO,KAAO,EAAA,mBAAA,EAAqB,oBAAoB,CAAC,CAAA,CAAA;AAGrE,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,IAAM,EAAA,iBAAA;AAAA,MACN,IAAI,kBAAmB,EAAA;AAAA,MACvB,IAAK,EAAA,eAAA;AAAA,MACL,gBAAkB,EAAA,CAAC,KAAS,IAAA,CAAC,CAAC,WAAA;AAAA,KAAA;AAAA,GAChC,CAAA;AAEJ;;ACjFO,MAAM,eAAe,CAAC;AAAA,EAC3B,QAAA;AACF,CAEM,KAAA;AACJ,EAAA,QAAQ,QAAU;AAAA,IAChB,KAAK,UAAA;AACH,MAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,YAAa,EAAA,EAAA,SAAA,EAAU,SAAU,EAAA,CAAA,CAAA;AAAA,IAC3C,KAAK,MAAA;AACH,MAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,QAAS,EAAA,EAAA,SAAA,EAAU,SAAU,EAAA,CAAA,CAAA;AAAA,IACvC,KAAK,KAAA;AACH,MAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,SAAA,EAAU,SAAU,EAAA,CAAA,CAAA;AAAA,IACtC,KAAK,QAAA,CAAA;AAAA,IACL;AACE,MAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,UAAW,EAAA,EAAA,SAAA,EAAU,SAAU,EAAA,CAAA,CAAA;AAAA,GAC3C;AACF,CAAA;;ACDA,MAAM,eAAkB,GAAA,GAAA,CAAA;AAejB,MAAM,qBAAqB,CAAC;AAAA,EACjC,SAAA;AAAA,EACA,gBAAgB,EAAC;AAAA,EACjB,QAAA;AAAA,EACA,eAAA;AAAA,EACA,YAAA;AAAA,EACA,mBAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AACF,CAA+B,KAAA;AAC7B,EAAM,MAAA,gBAAA,GAAmB,OAAO,mBAAmB,CAAA,CAAA;AAEnD,EAAA,MAAM,qBAAqB,KAAM,CAAA,WAAA;AAAA,IAC/B,CAAC,YAA+B,KAAA;AAC9B,MAAA,gBAAA,CACG,mBAAoB,CAAA;AAAA,QACnB,GAAA,EAAK,CAAC,YAAA,CAAa,EAAE,CAAA;AAAA,QACrB,IAAA,EAAM,CAAC,YAAa,CAAA,IAAA;AAAA,OACrB,CAAA,CACA,IAAK,CAAA,MAAM,UAAU,CAAA,CAAA;AAAA,KAC1B;AAAA,IACA,CAAC,kBAAkB,QAAQ,CAAA;AAAA,GAC7B,CAAA;AAEA,EAAA,MAAM,sBAAsB,KAAM,CAAA,WAAA;AAAA,IAChC,CAAC,YAA+B,KAAA;AAC9B,MAAA,gBAAA,CACG,mBAAoB,CAAA;AAAA,QACnB,GAAA,EAAK,CAAC,YAAA,CAAa,EAAE,CAAA;AAAA,QACrB,KAAA,EAAO,CAAC,YAAa,CAAA,KAAA;AAAA,OACtB,CAAA,CACA,IAAK,CAAA,MAAM,UAAU,CAAA,CAAA;AAAA,KAC1B;AAAA,IACA,CAAC,kBAAkB,QAAQ,CAAA;AAAA,GAC7B,CAAA;AAEA,EAAA,MAAM,4BAA+B,GAAA,OAAA;AAAA,IACnC,MAAM,QAAS,CAAA,eAAA,EAAiB,eAAe,CAAA;AAAA,IAC/C,CAAC,eAAe,CAAA;AAAA,GAClB,CAAA;AAEA,EAAA,MAAM,iBAAiB,KAAM,CAAA,OAAA;AAAA,IAC3B,MAAmC;AAAA,MACjC;AAAA,QACE,KAAO,EAAA,MAAA;AAAA,QACP,MAAA,EAAQ,CAAC,YAA4B,KAAA;AAlG7C,UAAA,IAAA,EAAA,CAAA;AAmGU,UAAA,uBAAA,KAAA,CAAA,aAAA,CAAC,YAAa,EAAA,EAAA,QAAA,EAAA,CAAU,EAAa,GAAA,YAAA,CAAA,OAAA,KAAb,mBAAsB,QAAU,EAAA,CAAA,CAAA;AAAA,SAAA;AAAA,OAE5D;AAAA,MACA;AAAA,QACE,uBAAuB,MACrB,IAAA;AAAA,QACF,MAAA,EAAQ,CAAC,YAA+B,KAAA;AAEtC,UAAA,uBAEI,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,GACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,UAAW,EAAA,EAAA,OAAA,EAAQ,WACjB,EAAA,EAAA,YAAA,CAAa,OAAQ,CAAA,IAAA,mBACnB,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,EAAI,EAAA,YAAA,CAAa,OAAQ,CAAA,IAAA,EAAA,EAC5B,YAAa,CAAA,OAAA,CAAQ,KACxB,CAAA,GAEA,YAAa,CAAA,OAAA,CAAQ,KAEzB,CAAA,kBACC,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,OAAA,EAAA,EACjB,YAAa,CAAA,OAAA,CAAQ,WACxB,CAAA,kBACC,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,SAAA,EAAA,EACjB,YAAa,CAAA,MAAA,oBACT,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EAAA,YAAA,CAAa,MAAO,EAAA,gBAAkB,CAE1C,EAAA,YAAA,CAAa,OAAQ,CAAA,KAAA,oBACjB,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EAAA,YAAA,CAAa,OAAQ,CAAA,KAAA,EAAM,gBAAkB,CAAA,EAEjD,YAAa,CAAA,OAAA,oBACX,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,EAAa,KAAO,EAAA,YAAA,CAAa,OAAS,EAAA,CAE/C,CACF,CACF,CAAA,CAAA;AAAA,SAEJ;AAAA,OACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAsBA;AAAA;AAAA,QAEE,KAAO,EAAA,MAAA;AAAA,QACP,MAAA,EAAQ,CAAC,YAA+B,KAAA;AACtC,UAAA,MAAM,cAAiB,GAAA,CAAC,CAAC,YAAA,CAAa,OAClC,qBACA,GAAA,cAAA,CAAA;AACJ,UAAA,MAAM,aAAgB,GAAA,CAAC,CAAC,YAAA,CAAa,OACjC,gBACA,GAAA,cAAA,CAAA;AAEJ,UAAA,MAAM,eAAkB,GAAA,CAAC,CAAC,YAAA,CAAa,QACnC,WACA,GAAA,gBAAA,CAAA;AAEJ,UAAA,MAAM,kBAAqB,GAAA,CAAC,CAAC,YAAA,CAAa,QACtC,iBACA,GAAA,eAAA,CAAA;AAEJ,UAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,SAAS,EAAA,IAAA,EAAC,IAAK,EAAA,QAAA,EAAA,kBAClB,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,IAAI,EAAA,IAAA,EAAA,kBACP,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EAAQ,OAAO,eACd,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,YAAC,UAAA;AAAA,YAAA;AAAA,cACC,SAAS,MAAM;AACb,gBAAA,mBAAA,CAAoB,YAAY,CAAA,CAAA;AAAA,eAClC;AAAA,aAAA;AAAA,4BAEA,KAAA,CAAA,aAAA,CAAC,kBAAmB,EAAA,EAAA,YAAA,EAAY,eAAiB,EAAA,CAAA;AAAA,WAErD,CACF,CAAA,kBAEC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,MAAI,IACR,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,KAAA,EAAO,cACd,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,YAAC,UAAA;AAAA,YAAA;AAAA,cACC,SAAS,MAAM;AACb,gBAAA,kBAAA,CAAmB,YAAY,CAAA,CAAA;AAAA,eACjC;AAAA,aAAA;AAAA,4BAEA,KAAA,CAAA,aAAA,CAAC,aAAc,EAAA,EAAA,YAAA,EAAY,cAAgB,EAAA,CAAA;AAAA,WAE/C,CACF,CACF,CAAA,CAAA;AAAA,SAEJ;AAAA,OACF;AAAA,KACF;AAAA,IACA,CAAC,oBAAoB,mBAAmB,CAAA;AAAA,GAC1C,CAAA;AAEA,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,OAAS,EAAA;AAAA,QACP,MAAQ,EAAA,IAAA;AAAA,QACR,MAAQ,EAAA,IAAA;AAAA,QACR,QAAA;AAAA,QACA,MAAQ,EAAA,KAAA;AAAA,QACR,OAAS,EAAA,KAAA;AAAA,OACX;AAAA,MACA,YAAA;AAAA,MACA,mBAAA;AAAA,MACA,IAAA;AAAA,MACA,UAAA;AAAA,MACA,cAAgB,EAAA,4BAAA;AAAA,MAChB,IAAM,EAAA,aAAA;AAAA,MACN,OAAS,EAAA,cAAA;AAAA,KAAA;AAAA,GACX,CAAA;AAEJ;;;;"}
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/SeverityIcon.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 NotificationSeverity,\n NotificationStatus,\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 offset?: number;\n limit?: number;\n search?: string;\n read?: boolean;\n saved?: boolean;\n createdAfter?: Date;\n sort?: 'created' | 'topic' | 'origin';\n sortOrder?: 'asc' | 'desc';\n minimumSeverity?: NotificationSeverity;\n};\n\n/** @public */\nexport type UpdateNotificationsOptions = {\n ids: string[];\n read?: boolean;\n saved?: boolean;\n};\n\n/** @public */\nexport type GetNotificationsResponse = {\n notifications: Notification[];\n totalCount: number;\n};\n\n/** @public */\nexport interface NotificationsApi {\n getNotifications(\n options?: GetNotificationsOptions,\n ): Promise<GetNotificationsResponse>;\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 GetNotificationsResponse,\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<GetNotificationsResponse> {\n const queryString = new URLSearchParams();\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?.sort !== undefined) {\n queryString.append(\n 'orderField',\n `${options.sort},${options?.sortOrder ?? 'desc'}`,\n );\n }\n if (options?.search) {\n queryString.append('search', options.search);\n }\n if (options?.read !== undefined) {\n queryString.append('read', options.read ? 'true' : 'false');\n }\n if (options?.saved !== undefined) {\n queryString.append('saved', options.saved ? 'true' : 'false');\n }\n if (options?.createdAfter !== undefined) {\n queryString.append('createdAfter', options.createdAfter.toISOString());\n }\n if (options?.minimumSeverity !== undefined) {\n queryString.append('minimal_severity', options.minimumSeverity);\n }\n const urlSegment = `?${queryString}`;\n\n return await this.request<GetNotificationsResponse>(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/esm/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 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 React from 'react';\nimport { NotificationSeverity } from '@backstage/plugin-notifications-common';\nimport NormalIcon from '@material-ui/icons/CheckOutlined';\nimport CriticalIcon from '@material-ui/icons/ErrorOutline';\nimport HighIcon from '@material-ui/icons/WarningOutlined';\nimport LowIcon from '@material-ui/icons/InfoOutlined';\n\nexport const SeverityIcon = ({\n severity,\n}: {\n severity?: NotificationSeverity;\n}) => {\n switch (severity) {\n case 'critical':\n return <CriticalIcon htmlColor=\"#C9190B\" />;\n case 'high':\n return <HighIcon htmlColor=\"#F0AB00\" />;\n case 'low':\n return <LowIcon htmlColor=\"#2B9AF3\" />;\n case 'normal':\n default:\n return <NormalIcon htmlColor=\"#5BA352\" />;\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, { useMemo } from 'react';\nimport throttle from 'lodash/throttle';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\nimport Box from '@material-ui/core/Box';\nimport Grid from '@material-ui/core/Grid';\nimport IconButton from '@material-ui/core/IconButton';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { Notification } from '@backstage/plugin-notifications-common';\n\nimport { notificationsApiRef } from '../../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n Link,\n Table,\n TableProps,\n TableColumn,\n} from '@backstage/core-components';\n\nimport MarkAsUnreadIcon from '@material-ui/icons/Markunread' /* TODO: use Drafts and MarkAsUnread once we have mui 5 icons */;\nimport MarkAsReadIcon from '@material-ui/icons/CheckCircle';\nimport MarkAsUnsavedIcon from '@material-ui/icons/LabelOff' /* TODO: use BookmarkRemove and BookmarkAdd once we have mui 5 icons */;\nimport MarkAsSavedIcon from '@material-ui/icons/Label';\nimport { SeverityIcon } from './SeverityIcon';\n\nconst ThrottleDelayMs = 1000;\n\n/** @public */\nexport type NotificationsTableProps = Pick<\n TableProps,\n 'onPageChange' | 'onRowsPerPageChange' | 'page' | 'totalCount'\n> & {\n isLoading?: boolean;\n notifications?: Notification[];\n onUpdate: () => void;\n setContainsText: (search: string) => void;\n pageSize: number;\n};\n\n/** @public */\nexport const NotificationsTable = ({\n isLoading,\n notifications = [],\n onUpdate,\n setContainsText,\n onPageChange,\n onRowsPerPageChange,\n page,\n pageSize,\n totalCount,\n}: NotificationsTableProps) => {\n const notificationsApi = useApi(notificationsApiRef);\n\n const onSwitchReadStatus = React.useCallback(\n (notification: Notification) => {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n read: !notification.read,\n })\n .then(() => onUpdate());\n },\n [notificationsApi, onUpdate],\n );\n\n const onSwitchSavedStatus = React.useCallback(\n (notification: Notification) => {\n notificationsApi\n .updateNotifications({\n ids: [notification.id],\n saved: !notification.saved,\n })\n .then(() => onUpdate());\n },\n [notificationsApi, onUpdate],\n );\n\n const throttledContainsTextHandler = useMemo(\n () => throttle(setContainsText, ThrottleDelayMs),\n [setContainsText],\n );\n\n const compactColumns = React.useMemo(\n (): TableColumn<Notification>[] => [\n {\n width: '1rem',\n render: (notification: Notification) => (\n <SeverityIcon severity={notification.payload?.severity} />\n ),\n },\n {\n customFilterAndSearch: () =>\n true /* Keep it on backend due to pagination. If recent flickering is an issue, implement search here as well. */,\n render: (notification: Notification) => {\n // Compact content\n return (\n <>\n <Box>\n <Typography variant=\"subtitle2\">\n {notification.payload.link ? (\n <Link to={notification.payload.link}>\n {notification.payload.title}\n </Link>\n ) : (\n notification.payload.title\n )}\n </Typography>\n <Typography variant=\"body2\">\n {notification.payload.description}\n </Typography>\n <Typography variant=\"caption\">\n {notification.origin && (\n <>{notification.origin}&nbsp;&bull;&nbsp;</>\n )}\n {notification.payload.topic && (\n <>{notification.payload.topic}&nbsp;&bull;&nbsp;</>\n )}\n {notification.created && (\n <RelativeTime value={notification.created} />\n )}\n </Typography>\n </Box>\n </>\n );\n },\n },\n // {\n // // TODO: additional action links\n // width: '25%',\n // render: (notification: Notification) => {\n // return (\n // notification.payload.link && (\n // <Grid container>\n // {/* TODO: render additionalLinks of different titles */}\n // <Grid item>\n // <Link\n // key={notification.payload.link}\n // to={notification.payload.link}\n // >\n // &nbsp;More info\n // </Link>\n // </Grid>\n // </Grid>\n // )\n // );\n // },\n // },\n {\n // actions\n width: '1rem',\n render: (notification: Notification) => {\n const markAsReadText = !!notification.read\n ? 'Return among unread'\n : 'Mark as read';\n const IconComponent = !!notification.read\n ? MarkAsUnreadIcon\n : MarkAsReadIcon;\n\n const markAsSavedText = !!notification.saved\n ? 'Undo save'\n : 'Save for later';\n\n const SavedIconComponent = !!notification.saved\n ? MarkAsUnsavedIcon\n : MarkAsSavedIcon;\n\n return (\n <Grid container wrap=\"nowrap\">\n <Grid item>\n <Tooltip title={markAsSavedText}>\n <IconButton\n onClick={() => {\n onSwitchSavedStatus(notification);\n }}\n >\n <SavedIconComponent aria-label={markAsSavedText} />\n </IconButton>\n </Tooltip>\n </Grid>\n\n <Grid item>\n <Tooltip title={markAsReadText}>\n <IconButton\n onClick={() => {\n onSwitchReadStatus(notification);\n }}\n >\n <IconComponent aria-label={markAsReadText} />\n </IconButton>\n </Tooltip>\n </Grid>\n </Grid>\n );\n },\n },\n ],\n [onSwitchReadStatus, onSwitchSavedStatus],\n );\n\n return (\n <Table<Notification>\n isLoading={isLoading}\n options={{\n search: true,\n paging: true,\n pageSize,\n header: false,\n sorting: false,\n }}\n onPageChange={onPageChange}\n onRowsPerPageChange={onRowsPerPageChange}\n page={page}\n totalCount={totalCount}\n onSearchChange={throttledContainsTextHandler}\n data={notifications}\n columns={compactColumns}\n />\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.1.0",
3
+ "version": "0.1.2",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -28,7 +28,7 @@
28
28
  "postpack": "backstage-cli package postpack"
29
29
  },
30
30
  "dependencies": {
31
- "@backstage/core-components": "^0.14.1",
31
+ "@backstage/core-components": "^0.14.3",
32
32
  "@backstage/core-plugin-api": "^1.9.1",
33
33
  "@backstage/errors": "^1.2.4",
34
34
  "@backstage/plugin-notifications-common": "^0.0.2",
@@ -48,10 +48,10 @@
48
48
  "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
49
49
  },
50
50
  "devDependencies": {
51
- "@backstage/cli": "^0.26.0",
52
- "@backstage/core-app-api": "^1.12.1",
53
- "@backstage/dev-utils": "^1.0.28",
54
- "@backstage/test-utils": "^1.5.1",
51
+ "@backstage/cli": "^0.26.2",
52
+ "@backstage/core-app-api": "^1.12.3",
53
+ "@backstage/dev-utils": "^1.0.30",
54
+ "@backstage/test-utils": "^1.5.3",
55
55
  "@testing-library/jest-dom": "^6.0.0",
56
56
  "@testing-library/react": "^14.0.0",
57
57
  "@testing-library/user-event": "^14.0.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-9328bf59.esm.js","sources":["../../src/components/NotificationsFilters/NotificationsFilters.tsx","../../src/components/NotificationsPage/NotificationsPage.tsx"],"sourcesContent":["/*\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 React from 'react';\n\nimport {\n Divider,\n FormControl,\n Grid,\n InputLabel,\n MenuItem,\n Select,\n Typography,\n} from '@material-ui/core';\nimport { GetNotificationsOptions } from '../../api';\nimport { NotificationSeverity } from '@backstage/plugin-notifications-common';\n\nexport type SortBy = Required<\n Pick<GetNotificationsOptions, 'sort' | 'sortOrder'>\n>;\n\nexport type NotificationsFiltersProps = {\n unreadOnly?: boolean;\n onUnreadOnlyChanged: (checked: boolean | undefined) => void;\n createdAfter?: string;\n onCreatedAfterChanged: (value: string) => void;\n sorting: SortBy;\n onSortingChanged: (sortBy: SortBy) => void;\n saved?: boolean;\n onSavedChanged: (checked: boolean | undefined) => void;\n severity: NotificationSeverity;\n onSeverityChanged: (severity: NotificationSeverity) => void;\n};\n\nexport const CreatedAfterOptions: {\n [key: string]: { label: string; getDate: () => Date };\n} = {\n last24h: {\n label: 'Last 24h',\n getDate: () => new Date(Date.now() - 24 * 3600 * 1000),\n },\n lastWeek: {\n label: 'Last week',\n getDate: () => new Date(Date.now() - 7 * 24 * 3600 * 1000),\n },\n all: {\n label: 'Any time',\n getDate: () => new Date(0),\n },\n};\n\nexport const SortByOptions: {\n [key: string]: {\n label: string;\n sortBy: SortBy;\n };\n} = {\n newest: {\n label: 'Newest on top',\n sortBy: {\n sort: 'created',\n sortOrder: 'desc',\n },\n },\n oldest: {\n label: 'Oldest on top',\n sortBy: {\n sort: 'created',\n sortOrder: 'asc',\n },\n },\n topic: {\n label: 'Topic',\n sortBy: {\n sort: 'topic',\n sortOrder: 'asc',\n },\n },\n origin: {\n label: 'Origin',\n sortBy: {\n sort: 'origin',\n sortOrder: 'asc',\n },\n },\n};\n\nconst getSortByText = (sortBy?: SortBy): string => {\n if (sortBy?.sort === 'created' && sortBy?.sortOrder === 'asc') {\n return 'oldest';\n }\n if (sortBy?.sort === 'topic') {\n return 'topic';\n }\n if (sortBy?.sort === 'origin') {\n return 'origin';\n }\n\n return 'newest';\n};\n\nconst AllSeverityOptions: { [key in NotificationSeverity]: string } = {\n critical: 'Critical',\n high: 'High',\n normal: 'Normal',\n low: 'Low',\n};\n\nexport const NotificationsFilters = ({\n sorting,\n onSortingChanged,\n unreadOnly,\n onUnreadOnlyChanged,\n createdAfter,\n onCreatedAfterChanged,\n saved,\n onSavedChanged,\n severity,\n onSeverityChanged,\n}: NotificationsFiltersProps) => {\n const sortByText = getSortByText(sorting);\n\n const handleOnCreatedAfterChanged = (\n event: React.ChangeEvent<{ name?: string; value: unknown }>,\n ) => {\n onCreatedAfterChanged(event.target.value as string);\n };\n\n const handleOnViewChanged = (\n event: React.ChangeEvent<{ name?: string; value: unknown }>,\n ) => {\n if (event.target.value === 'unread') {\n onUnreadOnlyChanged(true);\n onSavedChanged(undefined);\n } else if (event.target.value === 'read') {\n onUnreadOnlyChanged(false);\n onSavedChanged(undefined);\n } else if (event.target.value === 'saved') {\n onUnreadOnlyChanged(undefined);\n onSavedChanged(true);\n } else {\n // All\n onUnreadOnlyChanged(undefined);\n onSavedChanged(undefined);\n }\n };\n\n const handleOnSortByChanged = (\n event: React.ChangeEvent<{ name?: string; value: unknown }>,\n ) => {\n const idx = (event.target.value as string) || 'newest';\n const option = SortByOptions[idx];\n onSortingChanged({ ...option.sortBy });\n };\n\n let viewValue = 'all';\n if (saved) {\n viewValue = 'saved';\n } else if (unreadOnly) {\n viewValue = 'unread';\n } else if (unreadOnly === false) {\n viewValue = 'read';\n }\n\n const handleOnSeverityChanged = (\n event: React.ChangeEvent<{ name?: string; value: unknown }>,\n ) => {\n const value: NotificationSeverity =\n (event.target.value as NotificationSeverity) || 'normal';\n onSeverityChanged(value);\n };\n\n return (\n <>\n <Grid container>\n <Grid item xs={12}>\n <Typography variant=\"h6\">Filters</Typography>\n <Divider variant=\"fullWidth\" />\n </Grid>\n\n <Grid item xs={12}>\n <FormControl fullWidth variant=\"outlined\" size=\"small\">\n <InputLabel id=\"notifications-filter-view\">View</InputLabel>\n <Select\n labelId=\"notifications-filter-view\"\n label=\"View\"\n value={viewValue}\n onChange={handleOnViewChanged}\n >\n <MenuItem value=\"unread\">New only</MenuItem>\n <MenuItem value=\"saved\">Saved</MenuItem>\n <MenuItem value=\"read\">Marked as read</MenuItem>\n <MenuItem value=\"all\">All</MenuItem>\n </Select>\n </FormControl>\n </Grid>\n\n <Grid item xs={12}>\n <FormControl fullWidth variant=\"outlined\" size=\"small\">\n <InputLabel id=\"notifications-filter-created\">\n Created after\n </InputLabel>\n\n <Select\n label=\"Created after\"\n labelId=\"notifications-filter-created\"\n placeholder=\"Notifications since\"\n value={createdAfter}\n onChange={handleOnCreatedAfterChanged}\n >\n {Object.keys(CreatedAfterOptions).map((key: string) => (\n <MenuItem value={key} key={key}>\n {CreatedAfterOptions[key].label}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n\n <Grid item xs={12}>\n <FormControl fullWidth variant=\"outlined\" size=\"small\">\n <InputLabel id=\"notifications-filter-sort\">Sort by</InputLabel>\n\n <Select\n label=\"Sort by\"\n labelId=\"notifications-filter-sort\"\n placeholder=\"Field to sort by\"\n value={sortByText}\n onChange={handleOnSortByChanged}\n >\n {Object.keys(SortByOptions).map((key: string) => (\n <MenuItem value={key} key={key}>\n {SortByOptions[key].label}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n\n <Grid item xs={12}>\n <FormControl fullWidth variant=\"outlined\" size=\"small\">\n <InputLabel id=\"notifications-filter-severity\">Severity</InputLabel>\n\n <Select\n label=\"Severity\"\n labelId=\"notifications-filter-severity\"\n value={severity}\n onChange={handleOnSeverityChanged}\n >\n {Object.keys(AllSeverityOptions).map((key: string) => (\n <MenuItem value={key} key={key}>\n {AllSeverityOptions[key as NotificationSeverity]}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n </Grid>\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 */\n\nimport React, { useEffect } from 'react';\nimport {\n Content,\n PageWithHeader,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { Grid } from '@material-ui/core';\nimport { useSignal } from '@backstage/plugin-signals-react';\n\nimport { NotificationsTable } from '../NotificationsTable';\nimport { useNotificationsApi } from '../../hooks';\nimport {\n CreatedAfterOptions,\n NotificationsFilters,\n SortBy,\n SortByOptions,\n} from '../NotificationsFilters';\nimport { GetNotificationsOptions } from '../../api';\nimport { NotificationSeverity } from '@backstage/plugin-notifications-common';\n\nexport const NotificationsPage = () => {\n const [refresh, setRefresh] = React.useState(false);\n const { lastSignal } = useSignal('notifications');\n const [unreadOnly, setUnreadOnly] = React.useState<boolean | undefined>(true);\n const [saved, setSaved] = React.useState<boolean | undefined>(undefined);\n const [pageNumber, setPageNumber] = React.useState(0);\n const [pageSize, setPageSize] = React.useState(5);\n const [containsText, setContainsText] = React.useState<string>();\n const [createdAfter, setCreatedAfter] = React.useState<string>('lastWeek');\n const [sorting, setSorting] = React.useState<SortBy>(\n SortByOptions.newest.sortBy,\n );\n const [severity, setSeverity] = React.useState<NotificationSeverity>('low');\n\n const { error, value, retry, loading } = useNotificationsApi(\n api => {\n const options: GetNotificationsOptions = {\n search: containsText,\n limit: pageSize,\n offset: pageNumber * pageSize,\n minimumSeverity: severity,\n ...(sorting || {}),\n };\n if (unreadOnly !== undefined) {\n options.read = !unreadOnly;\n }\n if (saved !== undefined) {\n options.saved = saved;\n }\n\n const createdAfterDate = CreatedAfterOptions[createdAfter].getDate();\n if (createdAfterDate.valueOf() > 0) {\n options.createdAfter = createdAfterDate;\n }\n\n return api.getNotifications(options);\n },\n [\n containsText,\n unreadOnly,\n createdAfter,\n pageNumber,\n pageSize,\n sorting,\n saved,\n severity,\n ],\n );\n\n useEffect(() => {\n if (refresh) {\n retry();\n setRefresh(false);\n }\n }, [refresh, setRefresh, retry]);\n\n useEffect(() => {\n if (lastSignal && lastSignal.action) {\n setRefresh(true);\n }\n }, [lastSignal]);\n\n const onUpdate = () => {\n setRefresh(true);\n };\n\n if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n return (\n <PageWithHeader title=\"Notifications\" themeId=\"tool\">\n <Content>\n <Grid container>\n <Grid item xs={2}>\n <NotificationsFilters\n unreadOnly={unreadOnly}\n onUnreadOnlyChanged={setUnreadOnly}\n createdAfter={createdAfter}\n onCreatedAfterChanged={setCreatedAfter}\n onSortingChanged={setSorting}\n sorting={sorting}\n saved={saved}\n onSavedChanged={setSaved}\n severity={severity}\n onSeverityChanged={setSeverity}\n />\n </Grid>\n <Grid item xs={10}>\n <NotificationsTable\n isLoading={loading}\n notifications={value?.notifications}\n onUpdate={onUpdate}\n setContainsText={setContainsText}\n onPageChange={setPageNumber}\n onRowsPerPageChange={setPageSize}\n page={pageNumber}\n pageSize={pageSize}\n totalCount={value?.totalCount}\n />\n </Grid>\n </Grid>\n </Content>\n </PageWithHeader>\n );\n};\n"],"names":[],"mappings":"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"}