@backstage-community/plugin-announcements 0.16.1 → 0.16.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 +7 -0
- package/dist/alpha/banner.esm.js +2 -1
- package/dist/alpha/banner.esm.js.map +1 -1
- package/dist/components/AnnouncementPage/AnnouncementPage.esm.js +14 -1
- package/dist/components/AnnouncementPage/AnnouncementPage.esm.js.map +1 -1
- package/dist/components/AnnouncementsCard/AnnouncementsCard.esm.js +8 -1
- package/dist/components/AnnouncementsCard/AnnouncementsCard.esm.js.map +1 -1
- package/dist/components/NewAnnouncementBanner/NewAnnouncementBanner.esm.js +34 -4
- package/dist/components/NewAnnouncementBanner/NewAnnouncementBanner.esm.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @backstage-community/plugin-announcements
|
|
2
2
|
|
|
3
|
+
## 0.16.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 43e6d99: Added analytics event tracking for announcement link clicks. When users click on an announcement with a `link` property, an analytics event is now captured using the [Plugin Analytics](https://backstage.io/docs/plugins/analytics/#capturing-events). This applies to the following components: `AnnouncementsCard`, `AnnouncementPage`,`NewAnnouncementBanner`.
|
|
8
|
+
- 0b8dedf: Fix Announcements banner error `Routing context is not available` when using the banner with the new frontend system.
|
|
9
|
+
|
|
3
10
|
## 0.16.1
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
package/dist/alpha/banner.esm.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { compatWrapper } from '@backstage/core-compat-api';
|
|
2
3
|
import { AppRootElementBlueprint } from '@backstage/frontend-plugin-api';
|
|
3
4
|
import { NewAnnouncementBanner } from '../components/NewAnnouncementBanner/NewAnnouncementBanner.esm.js';
|
|
4
5
|
|
|
@@ -16,7 +17,7 @@ const announcementsBanner = AppRootElementBlueprint.makeWithOverrides({
|
|
|
16
17
|
},
|
|
17
18
|
factory: (originalFactory, { config }) => {
|
|
18
19
|
return originalFactory({
|
|
19
|
-
element: /* @__PURE__ */ jsx(NewAnnouncementBanner, { ...config })
|
|
20
|
+
element: compatWrapper(/* @__PURE__ */ jsx(NewAnnouncementBanner, { ...config }))
|
|
20
21
|
});
|
|
21
22
|
}
|
|
22
23
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"banner.esm.js","sources":["../../src/alpha/banner.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 { AppRootElementBlueprint } from '@backstage/frontend-plugin-api';\nimport { NewAnnouncementBanner } from '../components/NewAnnouncementBanner';\n\n/**\n * @alpha\n */\nexport const announcementsBanner = AppRootElementBlueprint.makeWithOverrides({\n name: 'banner',\n config: {\n schema: {\n variant: z => z.enum(['block', 'floating']).default('floating'),\n max: z => z.number().optional(),\n category: z => z.string().optional(),\n active: z => z.boolean().optional(),\n current: z => z.boolean().optional(),\n tags: z => z.array(z.string()).optional(),\n },\n },\n factory: (originalFactory, { config }) => {\n return originalFactory({\n element: <NewAnnouncementBanner {...config}
|
|
1
|
+
{"version":3,"file":"banner.esm.js","sources":["../../src/alpha/banner.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 { compatWrapper } from '@backstage/core-compat-api';\nimport { AppRootElementBlueprint } from '@backstage/frontend-plugin-api';\nimport { NewAnnouncementBanner } from '../components/NewAnnouncementBanner';\n\n/**\n * @alpha\n */\nexport const announcementsBanner = AppRootElementBlueprint.makeWithOverrides({\n name: 'banner',\n config: {\n schema: {\n variant: z => z.enum(['block', 'floating']).default('floating'),\n max: z => z.number().optional(),\n category: z => z.string().optional(),\n active: z => z.boolean().optional(),\n current: z => z.boolean().optional(),\n tags: z => z.array(z.string()).optional(),\n },\n },\n factory: (originalFactory, { config }) => {\n return originalFactory({\n element: compatWrapper(<NewAnnouncementBanner {...config} />),\n });\n },\n});\n"],"names":[],"mappings":";;;;;AAuBa,MAAA,mBAAA,GAAsB,wBAAwB,iBAAkB,CAAA;AAAA,EAC3E,IAAM,EAAA,QAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA;AAAA,MACN,OAAA,EAAS,CAAK,CAAA,KAAA,CAAA,CAAE,IAAK,CAAA,CAAC,SAAS,UAAU,CAAC,CAAE,CAAA,OAAA,CAAQ,UAAU,CAAA;AAAA,MAC9D,GAAK,EAAA,CAAA,CAAA,KAAK,CAAE,CAAA,MAAA,GAAS,QAAS,EAAA;AAAA,MAC9B,QAAU,EAAA,CAAA,CAAA,KAAK,CAAE,CAAA,MAAA,GAAS,QAAS,EAAA;AAAA,MACnC,MAAQ,EAAA,CAAA,CAAA,KAAK,CAAE,CAAA,OAAA,GAAU,QAAS,EAAA;AAAA,MAClC,OAAS,EAAA,CAAA,CAAA,KAAK,CAAE,CAAA,OAAA,GAAU,QAAS,EAAA;AAAA,MACnC,IAAA,EAAM,OAAK,CAAE,CAAA,KAAA,CAAM,EAAE,MAAO,EAAC,EAAE,QAAS;AAAA;AAC1C,GACF;AAAA,EACA,OAAS,EAAA,CAAC,eAAiB,EAAA,EAAE,QAAa,KAAA;AACxC,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,SAAS,aAAc,iBAAA,GAAA,CAAC,qBAAuB,EAAA,EAAA,GAAG,QAAQ,CAAE;AAAA,KAC7D,CAAA;AAAA;AAEL,CAAC;;;;"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { useEffect } from 'react';
|
|
2
3
|
import useAsync from 'react-use/lib/useAsync';
|
|
3
4
|
import { DateTime } from 'luxon';
|
|
4
5
|
import { Page, Header, Content, InfoCard, Progress } from '@backstage/core-components';
|
|
5
|
-
import { useApi, useRouteRefParams, useRouteRef } from '@backstage/core-plugin-api';
|
|
6
|
+
import { useApi, useRouteRefParams, useAnalytics, useRouteRef } from '@backstage/core-plugin-api';
|
|
6
7
|
import { EntityRefLink } from '@backstage/plugin-catalog-react';
|
|
7
8
|
import { announcementViewRouteRef, rootRouteRef } from '../../routes.esm.js';
|
|
8
9
|
import { announcementsApiRef } from '@backstage-community/plugin-announcements-react';
|
|
@@ -50,6 +51,7 @@ const AnnouncementDetails = ({
|
|
|
50
51
|
const AnnouncementPage = (props) => {
|
|
51
52
|
const announcementsApi = useApi(announcementsApiRef);
|
|
52
53
|
const { id } = useRouteRefParams(announcementViewRouteRef);
|
|
54
|
+
const analytics = useAnalytics();
|
|
53
55
|
const { value, loading, error } = useAsync(
|
|
54
56
|
async () => announcementsApi.announcementByID(id),
|
|
55
57
|
[id]
|
|
@@ -76,6 +78,17 @@ const AnnouncementPage = (props) => {
|
|
|
76
78
|
announcementsApi.markLastSeenDate(announcementCreatedAt);
|
|
77
79
|
}
|
|
78
80
|
}
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (!value) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
analytics.captureEvent("view", value.title, {
|
|
86
|
+
attributes: {
|
|
87
|
+
announcementId: value.id,
|
|
88
|
+
location: "AnnouncementPage"
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}, [analytics, value]);
|
|
79
92
|
return /* @__PURE__ */ jsxs(Page, { themeId: props.themeId, children: [
|
|
80
93
|
/* @__PURE__ */ jsx(Header, { title, subtitle: props.subtitle }),
|
|
81
94
|
/* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsx(Grid, { container: true, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx(Grid, { item: true, sm: 6, children: content }) }) })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnnouncementPage.esm.js","sources":["../../../src/components/AnnouncementPage/AnnouncementPage.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 { ReactNode } from 'react';\nimport useAsync from 'react-use/lib/useAsync';\nimport { DateTime } from 'luxon';\nimport {\n Progress,\n Page,\n Header,\n Content,\n InfoCard,\n} from '@backstage/core-components';\nimport {\n useApi,\n useRouteRef,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport { EntityRefLink } from '@backstage/plugin-catalog-react';\nimport { announcementViewRouteRef, rootRouteRef } from '../../routes';\nimport { announcementsApiRef } from '@backstage-community/plugin-announcements-react';\nimport {\n Announcement,\n MAX_TITLE_LENGTH,\n} from '@backstage-community/plugin-announcements-common';\nimport { Grid, Tooltip, Typography } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport {\n MarkdownRenderer,\n MarkdownRendererTypeProps,\n} from '../MarkdownRenderer';\nimport { truncate } from '../utils/truncateUtils';\n\nconst AnnouncementDetails = ({\n announcement,\n markdownRenderer,\n titleLength,\n}: {\n announcement: Announcement;\n markdownRenderer?: MarkdownRendererTypeProps;\n titleLength?: number;\n}) => {\n const announcementsLink = useRouteRef(rootRouteRef);\n const deepLink = {\n link: announcementsLink(),\n title: 'Back to announcements',\n };\n const subHeader = (\n <Typography>\n By{' '}\n <EntityRefLink\n entityRef={announcement.on_behalf_of || announcement.publisher}\n hideIcon\n />\n , {DateTime.fromISO(announcement.created_at).toRelative()}\n </Typography>\n );\n\n const maxLength = titleLength ?? MAX_TITLE_LENGTH;\n const title = truncate(announcement.title, maxLength);\n const isTruncated = announcement.title.length > maxLength;\n\n const titleElement = isTruncated ? (\n <Tooltip title={announcement.title} arrow>\n <Typography component=\"span\">{title}</Typography>\n </Tooltip>\n ) : (\n title\n );\n return (\n <InfoCard title={titleElement} subheader={subHeader} deepLink={deepLink}>\n <MarkdownRenderer\n content={announcement.body}\n rendererType={markdownRenderer}\n />\n </InfoCard>\n );\n};\n\ntype AnnouncementPageProps = {\n themeId: string;\n title: string;\n subtitle?: ReactNode;\n markdownRenderer?: MarkdownRendererTypeProps;\n titleLength?: number;\n};\n\nexport const AnnouncementPage = (props: AnnouncementPageProps) => {\n const announcementsApi = useApi(announcementsApiRef);\n const { id } = useRouteRefParams(announcementViewRouteRef);\n const { value, loading, error } = useAsync(\n async () => announcementsApi.announcementByID(id),\n [id],\n );\n\n let title = props.title;\n let content: ReactNode;\n\n if (loading) {\n content = <Progress />;\n } else if (error) {\n content = <Alert severity=\"error\">{error.message}</Alert>;\n } else {\n title = `${value!.title} – ${title}`;\n content = (\n <AnnouncementDetails\n announcement={value!}\n markdownRenderer={props.markdownRenderer}\n titleLength={props.titleLength}\n />\n );\n\n const lastSeen = announcementsApi.lastSeenDate();\n const announcementCreatedAt = DateTime.fromISO(value!.created_at);\n\n if (announcementCreatedAt > lastSeen) {\n announcementsApi.markLastSeenDate(announcementCreatedAt);\n }\n }\n\n return (\n <Page themeId={props.themeId}>\n <Header title={title} subtitle={props.subtitle} />\n\n <Content>\n <Grid container justifyContent=\"center\" alignItems=\"center\">\n <Grid item sm={6}>\n {content}\n </Grid>\n </Grid>\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AnnouncementPage.esm.js","sources":["../../../src/components/AnnouncementPage/AnnouncementPage.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 { ReactNode, useEffect } from 'react';\nimport useAsync from 'react-use/lib/useAsync';\nimport { DateTime } from 'luxon';\nimport {\n Progress,\n Page,\n Header,\n Content,\n InfoCard,\n} from '@backstage/core-components';\nimport {\n useApi,\n useRouteRef,\n useRouteRefParams,\n useAnalytics,\n} from '@backstage/core-plugin-api';\nimport { EntityRefLink } from '@backstage/plugin-catalog-react';\nimport { announcementViewRouteRef, rootRouteRef } from '../../routes';\nimport { announcementsApiRef } from '@backstage-community/plugin-announcements-react';\nimport {\n Announcement,\n MAX_TITLE_LENGTH,\n} from '@backstage-community/plugin-announcements-common';\nimport { Grid, Tooltip, Typography } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport {\n MarkdownRenderer,\n MarkdownRendererTypeProps,\n} from '../MarkdownRenderer';\nimport { truncate } from '../utils/truncateUtils';\n\nconst AnnouncementDetails = ({\n announcement,\n markdownRenderer,\n titleLength,\n}: {\n announcement: Announcement;\n markdownRenderer?: MarkdownRendererTypeProps;\n titleLength?: number;\n}) => {\n const announcementsLink = useRouteRef(rootRouteRef);\n const deepLink = {\n link: announcementsLink(),\n title: 'Back to announcements',\n };\n const subHeader = (\n <Typography>\n By{' '}\n <EntityRefLink\n entityRef={announcement.on_behalf_of || announcement.publisher}\n hideIcon\n />\n , {DateTime.fromISO(announcement.created_at).toRelative()}\n </Typography>\n );\n\n const maxLength = titleLength ?? MAX_TITLE_LENGTH;\n const title = truncate(announcement.title, maxLength);\n const isTruncated = announcement.title.length > maxLength;\n\n const titleElement = isTruncated ? (\n <Tooltip title={announcement.title} arrow>\n <Typography component=\"span\">{title}</Typography>\n </Tooltip>\n ) : (\n title\n );\n return (\n <InfoCard title={titleElement} subheader={subHeader} deepLink={deepLink}>\n <MarkdownRenderer\n content={announcement.body}\n rendererType={markdownRenderer}\n />\n </InfoCard>\n );\n};\n\ntype AnnouncementPageProps = {\n themeId: string;\n title: string;\n subtitle?: ReactNode;\n markdownRenderer?: MarkdownRendererTypeProps;\n titleLength?: number;\n};\n\nexport const AnnouncementPage = (props: AnnouncementPageProps) => {\n const announcementsApi = useApi(announcementsApiRef);\n const { id } = useRouteRefParams(announcementViewRouteRef);\n const analytics = useAnalytics();\n const { value, loading, error } = useAsync(\n async () => announcementsApi.announcementByID(id),\n [id],\n );\n\n let title = props.title;\n let content: ReactNode;\n\n if (loading) {\n content = <Progress />;\n } else if (error) {\n content = <Alert severity=\"error\">{error.message}</Alert>;\n } else {\n title = `${value!.title} – ${title}`;\n content = (\n <AnnouncementDetails\n announcement={value!}\n markdownRenderer={props.markdownRenderer}\n titleLength={props.titleLength}\n />\n );\n\n const lastSeen = announcementsApi.lastSeenDate();\n const announcementCreatedAt = DateTime.fromISO(value!.created_at);\n\n if (announcementCreatedAt > lastSeen) {\n announcementsApi.markLastSeenDate(announcementCreatedAt);\n }\n }\n\n useEffect(() => {\n if (!value) {\n return;\n }\n\n analytics.captureEvent('view', value.title, {\n attributes: {\n announcementId: value.id,\n location: 'AnnouncementPage',\n },\n });\n }, [analytics, value]);\n\n return (\n <Page themeId={props.themeId}>\n <Header title={title} subtitle={props.subtitle} />\n\n <Content>\n <Grid container justifyContent=\"center\" alignItems=\"center\">\n <Grid item sm={6}>\n {content}\n </Grid>\n </Grid>\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import { DateTime } from 'luxon';
|
|
3
3
|
import { usePermission } from '@backstage/plugin-permission-react';
|
|
4
4
|
import { Progress, InfoCard, Link } from '@backstage/core-components';
|
|
5
|
-
import { useApi, useRouteRef } from '@backstage/core-plugin-api';
|
|
5
|
+
import { useApi, useRouteRef, useAnalytics } from '@backstage/core-plugin-api';
|
|
6
6
|
import { announcementEntityPermissions } from '@backstage-community/plugin-announcements-common';
|
|
7
7
|
import { rootRouteRef, announcementViewRouteRef, announcementCreateRouteRef } from '../../routes.esm.js';
|
|
8
8
|
import { formatAnnouncementStartTime } from '../utils/announcementDateUtils.esm.js';
|
|
@@ -37,6 +37,7 @@ const AnnouncementsCard = ({
|
|
|
37
37
|
const viewAnnouncementLink = useRouteRef(announcementViewRouteRef);
|
|
38
38
|
const createAnnouncementLink = useRouteRef(announcementCreateRouteRef);
|
|
39
39
|
const lastSeen = announcementsApi.lastSeenDate();
|
|
40
|
+
const analytics = useAnalytics();
|
|
40
41
|
const { t } = useAnnouncementsTranslation();
|
|
41
42
|
const { announcements, loading, error } = useAnnouncements({
|
|
42
43
|
max: max || 5,
|
|
@@ -86,6 +87,12 @@ const AnnouncementsCard = ({
|
|
|
86
87
|
{
|
|
87
88
|
to: viewAnnouncementLink({ id: announcement.id }),
|
|
88
89
|
variant: "inherit",
|
|
90
|
+
onClick: () => analytics.captureEvent("click", announcement.title, {
|
|
91
|
+
attributes: {
|
|
92
|
+
announcementId: announcement.id,
|
|
93
|
+
location: "AnnouncementsCard"
|
|
94
|
+
}
|
|
95
|
+
}),
|
|
89
96
|
children: announcement.title
|
|
90
97
|
}
|
|
91
98
|
),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnnouncementsCard.esm.js","sources":["../../../src/components/AnnouncementsCard/AnnouncementsCard.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 { DateTime } from 'luxon';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport {\n InfoCard,\n InfoCardVariants,\n Link,\n Progress,\n} from '@backstage/core-components';\nimport { useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport { announcementEntityPermissions } from '@backstage-community/plugin-announcements-common';\nimport {\n announcementCreateRouteRef,\n announcementViewRouteRef,\n rootRouteRef,\n} from '../../routes';\nimport { formatAnnouncementStartTime } from '../utils/announcementDateUtils';\nimport {\n announcementsApiRef,\n useAnnouncements,\n useAnnouncementsTranslation,\n} from '@backstage-community/plugin-announcements-react';\nimport {\n makeStyles,\n List,\n ListItem,\n ListItemIcon,\n ListItemText,\n Typography,\n Box,\n Chip,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport NewReleasesIcon from '@material-ui/icons/NewReleases';\n\nconst useStyles = makeStyles({\n newAnnouncementIcon: {\n minWidth: '36px',\n },\n chipStyle: {\n marginRight: 4,\n marginBottom: 4,\n },\n});\n\ntype AnnouncementsCardOpts = {\n title?: string;\n max?: number;\n category?: string;\n active?: boolean;\n variant?: InfoCardVariants;\n sortBy?: 'created_at' | 'start_at';\n order?: 'asc' | 'desc';\n current?: boolean;\n hideStartAt?: boolean;\n};\n\nexport const AnnouncementsCard = ({\n title,\n max,\n category,\n active,\n variant = 'gridItem',\n sortBy,\n order,\n current,\n hideStartAt,\n}: AnnouncementsCardOpts) => {\n const classes = useStyles();\n const announcementsApi = useApi(announcementsApiRef);\n const announcementsLink = useRouteRef(rootRouteRef);\n const viewAnnouncementLink = useRouteRef(announcementViewRouteRef);\n const createAnnouncementLink = useRouteRef(announcementCreateRouteRef);\n const lastSeen = announcementsApi.lastSeenDate();\n const { t } = useAnnouncementsTranslation();\n\n const { announcements, loading, error } = useAnnouncements({\n max: max || 5,\n category,\n active,\n sortBy,\n order,\n current,\n });\n\n const { announcementCreatePermission } = announcementEntityPermissions;\n const { loading: loadingPermission, allowed: canAdd } = usePermission({\n permission: announcementCreatePermission,\n });\n\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n const deepLink = {\n link: announcementsLink(),\n title: t('announcementsCard.seeAll'),\n };\n\n return (\n <InfoCard\n title={title || t('announcementsCard.announcements')}\n variant={variant}\n deepLink={deepLink}\n >\n <List dense>\n {announcements.results.map(announcement => (\n <ListItem key={announcement.id}>\n <ListItemIcon\n className={classes.newAnnouncementIcon}\n style={{\n visibility:\n lastSeen < DateTime.fromISO(announcement.created_at)\n ? 'visible'\n : 'hidden',\n }}\n title={t('announcementsCard.new')}\n >\n <NewReleasesIcon />\n </ListItemIcon>\n <ListItemText\n primary={\n <Link\n to={viewAnnouncementLink({ id: announcement.id })}\n variant=\"inherit\"\n >\n {announcement.title}\n </Link>\n }\n secondary={\n <Box>\n <Typography variant=\"body2\" color=\"textSecondary\">\n {DateTime.fromISO(announcement.created_at).toRelative()}\n {announcement.category && (\n <>\n {` ${t('announcementsCard.in')} `}\n <Link\n to={`${announcementsLink()}?category=${\n announcement.category.slug\n }`}\n variant=\"inherit\"\n >\n {announcement.category.title}\n </Link>\n </>\n )}\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n {announcement.excerpt}\n {announcement.tags && announcement.tags.length > 0 && (\n <Box mt={1}>\n {announcement.tags.map(tag => (\n <Chip\n key={tag.slug}\n size=\"small\"\n label={tag.title}\n component={Link}\n to={`${announcementsLink()}?tags=${tag.slug}`}\n clickable\n className={classes.chipStyle}\n />\n ))}\n </Box>\n )}\n </Typography>\n {!hideStartAt && (\n <Typography variant=\"caption\" color=\"textSecondary\">\n {formatAnnouncementStartTime(\n announcement.start_at,\n t('announcementsCard.occurred'),\n t('announcementsCard.scheduled'),\n t('announcementsCard.today'),\n )}\n </Typography>\n )}\n </Box>\n }\n />{' '}\n </ListItem>\n ))}\n {announcements.count === 0 && !loadingPermission && canAdd && (\n <ListItem>\n <ListItemText>\n {`${t('announcementsCard.noAnnouncements')} `}\n <Link to={createAnnouncementLink()} variant=\"inherit\">\n {t('announcementsCard.addOne')}\n </Link>\n ?\n </ListItemText>\n </ListItem>\n )}\n </List>\n </InfoCard>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AnnouncementsCard.esm.js","sources":["../../../src/components/AnnouncementsCard/AnnouncementsCard.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 { DateTime } from 'luxon';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport {\n InfoCard,\n InfoCardVariants,\n Link,\n Progress,\n} from '@backstage/core-components';\nimport { useApi, useRouteRef, useAnalytics } from '@backstage/core-plugin-api';\nimport { announcementEntityPermissions } from '@backstage-community/plugin-announcements-common';\nimport {\n announcementCreateRouteRef,\n announcementViewRouteRef,\n rootRouteRef,\n} from '../../routes';\nimport { formatAnnouncementStartTime } from '../utils/announcementDateUtils';\nimport {\n announcementsApiRef,\n useAnnouncements,\n useAnnouncementsTranslation,\n} from '@backstage-community/plugin-announcements-react';\nimport {\n makeStyles,\n List,\n ListItem,\n ListItemIcon,\n ListItemText,\n Typography,\n Box,\n Chip,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport NewReleasesIcon from '@material-ui/icons/NewReleases';\n\nconst useStyles = makeStyles({\n newAnnouncementIcon: {\n minWidth: '36px',\n },\n chipStyle: {\n marginRight: 4,\n marginBottom: 4,\n },\n});\n\ntype AnnouncementsCardOpts = {\n title?: string;\n max?: number;\n category?: string;\n active?: boolean;\n variant?: InfoCardVariants;\n sortBy?: 'created_at' | 'start_at';\n order?: 'asc' | 'desc';\n current?: boolean;\n hideStartAt?: boolean;\n};\n\nexport const AnnouncementsCard = ({\n title,\n max,\n category,\n active,\n variant = 'gridItem',\n sortBy,\n order,\n current,\n hideStartAt,\n}: AnnouncementsCardOpts) => {\n const classes = useStyles();\n const announcementsApi = useApi(announcementsApiRef);\n const announcementsLink = useRouteRef(rootRouteRef);\n const viewAnnouncementLink = useRouteRef(announcementViewRouteRef);\n const createAnnouncementLink = useRouteRef(announcementCreateRouteRef);\n const lastSeen = announcementsApi.lastSeenDate();\n const analytics = useAnalytics();\n const { t } = useAnnouncementsTranslation();\n\n const { announcements, loading, error } = useAnnouncements({\n max: max || 5,\n category,\n active,\n sortBy,\n order,\n current,\n });\n\n const { announcementCreatePermission } = announcementEntityPermissions;\n const { loading: loadingPermission, allowed: canAdd } = usePermission({\n permission: announcementCreatePermission,\n });\n\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n const deepLink = {\n link: announcementsLink(),\n title: t('announcementsCard.seeAll'),\n };\n\n return (\n <InfoCard\n title={title || t('announcementsCard.announcements')}\n variant={variant}\n deepLink={deepLink}\n >\n <List dense>\n {announcements.results.map(announcement => (\n <ListItem key={announcement.id}>\n <ListItemIcon\n className={classes.newAnnouncementIcon}\n style={{\n visibility:\n lastSeen < DateTime.fromISO(announcement.created_at)\n ? 'visible'\n : 'hidden',\n }}\n title={t('announcementsCard.new')}\n >\n <NewReleasesIcon />\n </ListItemIcon>\n <ListItemText\n primary={\n <Link\n to={viewAnnouncementLink({ id: announcement.id })}\n variant=\"inherit\"\n onClick={() =>\n analytics.captureEvent('click', announcement.title, {\n attributes: {\n announcementId: announcement.id,\n location: 'AnnouncementsCard',\n },\n })\n }\n >\n {announcement.title}\n </Link>\n }\n secondary={\n <Box>\n <Typography variant=\"body2\" color=\"textSecondary\">\n {DateTime.fromISO(announcement.created_at).toRelative()}\n {announcement.category && (\n <>\n {` ${t('announcementsCard.in')} `}\n <Link\n to={`${announcementsLink()}?category=${\n announcement.category.slug\n }`}\n variant=\"inherit\"\n >\n {announcement.category.title}\n </Link>\n </>\n )}\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n {announcement.excerpt}\n {announcement.tags && announcement.tags.length > 0 && (\n <Box mt={1}>\n {announcement.tags.map(tag => (\n <Chip\n key={tag.slug}\n size=\"small\"\n label={tag.title}\n component={Link}\n to={`${announcementsLink()}?tags=${tag.slug}`}\n clickable\n className={classes.chipStyle}\n />\n ))}\n </Box>\n )}\n </Typography>\n {!hideStartAt && (\n <Typography variant=\"caption\" color=\"textSecondary\">\n {formatAnnouncementStartTime(\n announcement.start_at,\n t('announcementsCard.occurred'),\n t('announcementsCard.scheduled'),\n t('announcementsCard.today'),\n )}\n </Typography>\n )}\n </Box>\n }\n />{' '}\n </ListItem>\n ))}\n {announcements.count === 0 && !loadingPermission && canAdd && (\n <ListItem>\n <ListItemText>\n {`${t('announcementsCard.noAnnouncements')} `}\n <Link to={createAnnouncementLink()} variant=\"inherit\">\n {t('announcementsCard.addOne')}\n </Link>\n ?\n </ListItemText>\n </ListItem>\n )}\n </List>\n </InfoCard>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
3
|
import { DateTime } from 'luxon';
|
|
4
4
|
import { Link } from '@backstage/core-components';
|
|
5
|
-
import { useApi, useRouteRef } from '@backstage/core-plugin-api';
|
|
5
|
+
import { useApi, useRouteRef, useAnalytics } from '@backstage/core-plugin-api';
|
|
6
6
|
import { announcementViewRouteRef } from '../../routes.esm.js';
|
|
7
7
|
import { announcementsApiRef, useAnnouncements, useAnnouncementsTranslation } from '@backstage-community/plugin-announcements-react';
|
|
8
8
|
import { SIGNALS_CHANNEL_ANNOUNCEMENTS, MAX_TITLE_LENGTH, MAX_EXCERPT_LENGTH } from '@backstage-community/plugin-announcements-common';
|
|
@@ -49,18 +49,37 @@ const AnnouncementBanner = (props) => {
|
|
|
49
49
|
const classes = useStyles();
|
|
50
50
|
const announcementsApi = useApi(announcementsApiRef);
|
|
51
51
|
const viewAnnouncementLink = useRouteRef(announcementViewRouteRef);
|
|
52
|
+
const analytics = useAnalytics();
|
|
52
53
|
const { t } = useAnnouncementsTranslation();
|
|
53
54
|
const [bannerOpen, setBannerOpen] = useState(true);
|
|
54
55
|
const variant = props.variant || "block";
|
|
55
56
|
const announcement = props.announcement;
|
|
56
57
|
const titleLength = props.cardOptions?.titleLength;
|
|
57
58
|
const excerptLength = props.cardOptions?.excerptLength;
|
|
58
|
-
const
|
|
59
|
+
const markSeen = () => {
|
|
59
60
|
announcementsApi.markLastSeenDate(
|
|
60
61
|
DateTime.fromISO(announcement.created_at)
|
|
61
62
|
);
|
|
62
63
|
setBannerOpen(false);
|
|
63
64
|
};
|
|
65
|
+
const handleLinkClick = () => {
|
|
66
|
+
analytics.captureEvent("click", announcement.title, {
|
|
67
|
+
attributes: {
|
|
68
|
+
announcementId: announcement.id,
|
|
69
|
+
location: "NewAnnouncementBanner"
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
markSeen();
|
|
73
|
+
};
|
|
74
|
+
const handleDismiss = () => {
|
|
75
|
+
analytics.captureEvent("dismiss", announcement.title, {
|
|
76
|
+
attributes: {
|
|
77
|
+
announcementId: announcement.id,
|
|
78
|
+
location: "NewAnnouncementBanner"
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
markSeen();
|
|
82
|
+
};
|
|
64
83
|
const title = titleLength ? truncate(announcement.title, titleLength) : announcement.title;
|
|
65
84
|
const excerpt = excerptLength ? truncate(announcement.excerpt, excerptLength) : announcement.excerpt;
|
|
66
85
|
const message = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -78,13 +97,24 @@ const AnnouncementBanner = (props) => {
|
|
|
78
97
|
{
|
|
79
98
|
to: viewAnnouncementLink({ id: announcement.id }),
|
|
80
99
|
variant: "inherit",
|
|
81
|
-
onClick:
|
|
100
|
+
onClick: handleLinkClick,
|
|
82
101
|
children: title
|
|
83
102
|
}
|
|
84
103
|
),
|
|
85
104
|
"\xA0\u2013 ",
|
|
86
105
|
excerpt
|
|
87
106
|
] });
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (!bannerOpen) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
analytics.captureEvent("view", announcement.title, {
|
|
112
|
+
attributes: {
|
|
113
|
+
announcementId: announcement.id,
|
|
114
|
+
location: "NewAnnouncementBanner"
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}, [analytics, announcement.id, announcement.title, bannerOpen]);
|
|
88
118
|
return /* @__PURE__ */ jsx(
|
|
89
119
|
Snackbar,
|
|
90
120
|
{
|
|
@@ -102,7 +132,7 @@ const AnnouncementBanner = (props) => {
|
|
|
102
132
|
{
|
|
103
133
|
title: t("newAnnouncementBanner.markAsSeen"),
|
|
104
134
|
color: "inherit",
|
|
105
|
-
onClick:
|
|
135
|
+
onClick: handleDismiss,
|
|
106
136
|
children: /* @__PURE__ */ jsx(Close, { className: classes.icon })
|
|
107
137
|
},
|
|
108
138
|
"dismiss"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NewAnnouncementBanner.esm.js","sources":["../../../src/components/NewAnnouncementBanner/NewAnnouncementBanner.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 { useEffect, useState } from 'react';\nimport { DateTime } from 'luxon';\nimport { Link } from '@backstage/core-components';\nimport { useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport { announcementViewRouteRef } from '../../routes';\nimport {\n announcementsApiRef,\n useAnnouncements,\n useAnnouncementsTranslation,\n} from '@backstage-community/plugin-announcements-react';\nimport {\n Announcement,\n AnnouncementSignal,\n MAX_EXCERPT_LENGTH,\n MAX_TITLE_LENGTH,\n SIGNALS_CHANNEL_ANNOUNCEMENTS,\n} from '@backstage-community/plugin-announcements-common';\nimport { useSignal } from '@backstage/plugin-signals-react';\nimport {\n makeStyles,\n Snackbar,\n SnackbarContent,\n IconButton,\n Typography,\n} from '@material-ui/core';\nimport Close from '@material-ui/icons/Close';\nimport { Alert } from '@material-ui/lab';\nimport { truncate } from '../utils/truncateUtils';\n\nconst useStyles = makeStyles(theme => {\n return {\n // showing on top, as a block\n blockPositioning: {\n padding: theme?.spacing?.(0) ?? 0,\n position: 'relative',\n marginBottom: theme?.spacing?.(4) ?? 32,\n marginTop: theme?.spacing?.(3) ?? -24,\n zIndex: 'unset',\n },\n // showing on top, as a floating alert\n floatingPositioning: {},\n icon: {\n fontSize: 20,\n },\n bannerIcon: {\n fontSize: 20,\n marginRight: '0.5rem',\n },\n content: {\n width: '100%',\n maxWidth: 'inherit',\n flexWrap: 'nowrap',\n backgroundColor: theme?.palette?.banner?.info ?? '#f0f0f0',\n display: 'flex',\n alignItems: 'center',\n color: theme?.palette?.banner?.text ?? '#000000',\n '& a': {\n color: theme?.palette?.banner?.link ?? '#0068c8',\n },\n },\n };\n});\n\ntype CardOptions = {\n titleLength?: number;\n excerptLength?: number;\n};\n\ntype AnnouncementBannerProps = {\n announcement: Announcement;\n variant?: 'block' | 'floating';\n cardOptions?: CardOptions;\n};\n\nconst AnnouncementBanner = (props: AnnouncementBannerProps) => {\n const classes = useStyles();\n const announcementsApi = useApi(announcementsApiRef);\n const viewAnnouncementLink = useRouteRef(announcementViewRouteRef);\n const { t } = useAnnouncementsTranslation();\n const [bannerOpen, setBannerOpen] = useState(true);\n const variant = props.variant || 'block';\n const announcement = props.announcement;\n const titleLength = props.cardOptions?.titleLength;\n const excerptLength = props.cardOptions?.excerptLength;\n\n const handleClick = () => {\n announcementsApi.markLastSeenDate(\n DateTime.fromISO(announcement.created_at),\n );\n setBannerOpen(false);\n };\n\n const title = titleLength\n ? truncate(announcement.title, titleLength)\n : announcement.title;\n const excerpt = excerptLength\n ? truncate(announcement.excerpt, excerptLength)\n : announcement.excerpt;\n\n const message = (\n <>\n <Typography\n component=\"span\"\n className={classes.bannerIcon}\n variant=\"inherit\"\n >\n 📣\n </Typography>\n <Link\n to={viewAnnouncementLink({ id: announcement.id })}\n variant=\"inherit\"\n onClick={handleClick}\n >\n {title}\n </Link>\n – {excerpt}\n </>\n );\n\n return (\n <Snackbar\n anchorOrigin={{ vertical: 'top', horizontal: 'center' }}\n open={bannerOpen}\n className={\n variant === 'block'\n ? classes.blockPositioning\n : classes.floatingPositioning\n }\n >\n <SnackbarContent\n className={classes.content}\n message={message}\n action={[\n <IconButton\n key=\"dismiss\"\n title={t('newAnnouncementBanner.markAsSeen')}\n color=\"inherit\"\n onClick={handleClick}\n >\n <Close className={classes.icon} />\n </IconButton>,\n ]}\n />\n </Snackbar>\n );\n};\n\ntype NewAnnouncementBannerProps = {\n variant?: 'block' | 'floating';\n max?: number;\n category?: string;\n active?: boolean;\n current?: boolean;\n tags?: string[];\n sortBy?: 'created_at' | 'updated_at';\n cardOptions?: CardOptions;\n};\n\nexport const NewAnnouncementBanner = (props: NewAnnouncementBannerProps) => {\n const {\n max,\n category,\n tags,\n active,\n variant,\n current,\n sortBy,\n cardOptions = {\n titleLength: MAX_TITLE_LENGTH,\n excerptLength: MAX_EXCERPT_LENGTH,\n },\n } = props;\n\n const announcementsApi = useApi(announcementsApiRef);\n\n const [signaledAnnouncement, setSignaledAnnouncement] = useState<\n AnnouncementSignal['data'] | undefined\n >();\n\n const { announcements, loading, error } = useAnnouncements({\n max: max ?? 1,\n category,\n tags,\n active,\n current,\n sortBy,\n });\n const lastSeen = announcementsApi.lastSeenDate();\n\n const { lastSignal } = useSignal<AnnouncementSignal>(\n SIGNALS_CHANNEL_ANNOUNCEMENTS,\n );\n\n useEffect(() => {\n if (!lastSignal) {\n return;\n }\n\n setSignaledAnnouncement(lastSignal?.data);\n }, [lastSignal]);\n\n if (loading) {\n return null;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n if (announcements.count === 0) {\n return null;\n }\n\n const unseenAnnouncements = announcements.results.filter(announcement => {\n return lastSeen < DateTime.fromISO(announcement.created_at);\n });\n\n if (signaledAnnouncement) {\n unseenAnnouncements.push(signaledAnnouncement);\n }\n\n if (unseenAnnouncements?.length === 0) {\n return null;\n }\n\n return (\n <>\n {unseenAnnouncements.map(announcement => (\n <AnnouncementBanner\n key={announcement.id}\n announcement={announcement}\n variant={variant}\n cardOptions={cardOptions}\n />\n ))}\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NewAnnouncementBanner.esm.js","sources":["../../../src/components/NewAnnouncementBanner/NewAnnouncementBanner.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 { useEffect, useState } from 'react';\nimport { DateTime } from 'luxon';\nimport { Link } from '@backstage/core-components';\nimport { useApi, useRouteRef, useAnalytics } from '@backstage/core-plugin-api';\nimport { announcementViewRouteRef } from '../../routes';\nimport {\n announcementsApiRef,\n useAnnouncements,\n useAnnouncementsTranslation,\n} from '@backstage-community/plugin-announcements-react';\nimport {\n Announcement,\n AnnouncementSignal,\n MAX_EXCERPT_LENGTH,\n MAX_TITLE_LENGTH,\n SIGNALS_CHANNEL_ANNOUNCEMENTS,\n} from '@backstage-community/plugin-announcements-common';\nimport { useSignal } from '@backstage/plugin-signals-react';\nimport {\n makeStyles,\n Snackbar,\n SnackbarContent,\n IconButton,\n Typography,\n} from '@material-ui/core';\nimport Close from '@material-ui/icons/Close';\nimport { Alert } from '@material-ui/lab';\nimport { truncate } from '../utils/truncateUtils';\n\nconst useStyles = makeStyles(theme => {\n return {\n // showing on top, as a block\n blockPositioning: {\n padding: theme?.spacing?.(0) ?? 0,\n position: 'relative',\n marginBottom: theme?.spacing?.(4) ?? 32,\n marginTop: theme?.spacing?.(3) ?? -24,\n zIndex: 'unset',\n },\n // showing on top, as a floating alert\n floatingPositioning: {},\n icon: {\n fontSize: 20,\n },\n bannerIcon: {\n fontSize: 20,\n marginRight: '0.5rem',\n },\n content: {\n width: '100%',\n maxWidth: 'inherit',\n flexWrap: 'nowrap',\n backgroundColor: theme?.palette?.banner?.info ?? '#f0f0f0',\n display: 'flex',\n alignItems: 'center',\n color: theme?.palette?.banner?.text ?? '#000000',\n '& a': {\n color: theme?.palette?.banner?.link ?? '#0068c8',\n },\n },\n };\n});\n\ntype CardOptions = {\n titleLength?: number;\n excerptLength?: number;\n};\n\ntype AnnouncementBannerProps = {\n announcement: Announcement;\n variant?: 'block' | 'floating';\n cardOptions?: CardOptions;\n};\n\nconst AnnouncementBanner = (props: AnnouncementBannerProps) => {\n const classes = useStyles();\n const announcementsApi = useApi(announcementsApiRef);\n const viewAnnouncementLink = useRouteRef(announcementViewRouteRef);\n const analytics = useAnalytics();\n const { t } = useAnnouncementsTranslation();\n const [bannerOpen, setBannerOpen] = useState(true);\n const variant = props.variant || 'block';\n const announcement = props.announcement;\n const titleLength = props.cardOptions?.titleLength;\n const excerptLength = props.cardOptions?.excerptLength;\n\n const markSeen = () => {\n announcementsApi.markLastSeenDate(\n DateTime.fromISO(announcement.created_at),\n );\n setBannerOpen(false);\n };\n\n const handleLinkClick = () => {\n analytics.captureEvent('click', announcement.title, {\n attributes: {\n announcementId: announcement.id,\n location: 'NewAnnouncementBanner',\n },\n });\n\n markSeen();\n };\n\n const handleDismiss = () => {\n analytics.captureEvent('dismiss', announcement.title, {\n attributes: {\n announcementId: announcement.id,\n location: 'NewAnnouncementBanner',\n },\n });\n\n markSeen();\n };\n\n const title = titleLength\n ? truncate(announcement.title, titleLength)\n : announcement.title;\n const excerpt = excerptLength\n ? truncate(announcement.excerpt, excerptLength)\n : announcement.excerpt;\n\n const message = (\n <>\n <Typography\n component=\"span\"\n className={classes.bannerIcon}\n variant=\"inherit\"\n >\n 📣\n </Typography>\n <Link\n to={viewAnnouncementLink({ id: announcement.id })}\n variant=\"inherit\"\n onClick={handleLinkClick}\n >\n {title}\n </Link>\n – {excerpt}\n </>\n );\n\n useEffect(() => {\n if (!bannerOpen) {\n return;\n }\n\n analytics.captureEvent('view', announcement.title, {\n attributes: {\n announcementId: announcement.id,\n location: 'NewAnnouncementBanner',\n },\n });\n }, [analytics, announcement.id, announcement.title, bannerOpen]);\n\n return (\n <Snackbar\n anchorOrigin={{ vertical: 'top', horizontal: 'center' }}\n open={bannerOpen}\n className={\n variant === 'block'\n ? classes.blockPositioning\n : classes.floatingPositioning\n }\n >\n <SnackbarContent\n className={classes.content}\n message={message}\n action={[\n <IconButton\n key=\"dismiss\"\n title={t('newAnnouncementBanner.markAsSeen')}\n color=\"inherit\"\n onClick={handleDismiss}\n >\n <Close className={classes.icon} />\n </IconButton>,\n ]}\n />\n </Snackbar>\n );\n};\n\ntype NewAnnouncementBannerProps = {\n variant?: 'block' | 'floating';\n max?: number;\n category?: string;\n active?: boolean;\n current?: boolean;\n tags?: string[];\n sortBy?: 'created_at' | 'updated_at';\n cardOptions?: CardOptions;\n};\n\nexport const NewAnnouncementBanner = (props: NewAnnouncementBannerProps) => {\n const {\n max,\n category,\n tags,\n active,\n variant,\n current,\n sortBy,\n cardOptions = {\n titleLength: MAX_TITLE_LENGTH,\n excerptLength: MAX_EXCERPT_LENGTH,\n },\n } = props;\n\n const announcementsApi = useApi(announcementsApiRef);\n\n const [signaledAnnouncement, setSignaledAnnouncement] = useState<\n AnnouncementSignal['data'] | undefined\n >();\n\n const { announcements, loading, error } = useAnnouncements({\n max: max ?? 1,\n category,\n tags,\n active,\n current,\n sortBy,\n });\n const lastSeen = announcementsApi.lastSeenDate();\n\n const { lastSignal } = useSignal<AnnouncementSignal>(\n SIGNALS_CHANNEL_ANNOUNCEMENTS,\n );\n\n useEffect(() => {\n if (!lastSignal) {\n return;\n }\n\n setSignaledAnnouncement(lastSignal?.data);\n }, [lastSignal]);\n\n if (loading) {\n return null;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n if (announcements.count === 0) {\n return null;\n }\n\n const unseenAnnouncements = announcements.results.filter(announcement => {\n return lastSeen < DateTime.fromISO(announcement.created_at);\n });\n\n if (signaledAnnouncement) {\n unseenAnnouncements.push(signaledAnnouncement);\n }\n\n if (unseenAnnouncements?.length === 0) {\n return null;\n }\n\n return (\n <>\n {unseenAnnouncements.map(announcement => (\n <AnnouncementBanner\n key={announcement.id}\n announcement={announcement}\n variant={variant}\n cardOptions={cardOptions}\n />\n ))}\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -115,6 +115,9 @@ declare const AnnouncementsCard: ({ title, max, category, active, variant, sortB
|
|
|
115
115
|
category?: string | undefined;
|
|
116
116
|
active?: boolean | undefined;
|
|
117
117
|
variant?: _backstage_core_components.InfoCardVariants | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* @public
|
|
120
|
+
*/
|
|
118
121
|
sortBy?: "created_at" | "start_at" | undefined;
|
|
119
122
|
order?: "desc" | "asc" | undefined;
|
|
120
123
|
current?: boolean | undefined;
|