@backstage-community/plugin-announcements 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +0 -1
- package/dist/alpha/banner.esm.js +1 -2
- package/dist/alpha/banner.esm.js.map +1 -1
- package/dist/alpha/navItems.esm.js +2 -2
- package/dist/alpha/navItems.esm.js.map +1 -1
- package/dist/alpha/search.esm.js +3 -3
- package/dist/alpha/search.esm.js.map +1 -1
- package/dist/alpha.d.ts +1 -3
- package/dist/components/AnnouncementSearchResultListItem/AnnouncementSearchResultListItem.esm.js +2 -2
- package/dist/components/AnnouncementSearchResultListItem/AnnouncementSearchResultListItem.esm.js.map +1 -1
- package/dist/components/NewAnnouncementBanner/NewAnnouncementBanner.esm.js +41 -81
- package/dist/components/NewAnnouncementBanner/NewAnnouncementBanner.esm.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/package.json +1 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @backstage-community/plugin-announcements
|
|
2
2
|
|
|
3
|
+
## 2.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a598f92: Migrate Announcements Banner to the Backstage UI using the Alert component.
|
|
8
|
+
|
|
9
|
+
This change also removes the `variant` React prop. If you were using the prop with the `block` or `floating` values, it can be safely removed, as the banner now uses the Backstage UI Alert default style.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 693fc2f: Replace Announcements plugin icon from Material UI's RecordVoiceOverIcon to Remix Icon's RiMegaphoneLine. This change is made in the SearchPage component, the search result list item component, the search result type blueprint and use by default for nav blueprint.
|
|
14
|
+
|
|
3
15
|
## 2.4.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/README.md
CHANGED
package/dist/alpha/banner.esm.js
CHANGED
|
@@ -7,8 +7,7 @@ const announcementsBanner = AppRootElementBlueprint.makeWithOverrides({
|
|
|
7
7
|
name: "banner",
|
|
8
8
|
config: {
|
|
9
9
|
schema: {
|
|
10
|
-
|
|
11
|
-
max: (z) => z.number().optional(),
|
|
10
|
+
max: (z) => z.number().optional().default(1),
|
|
12
11
|
category: (z) => z.string().optional(),
|
|
13
12
|
active: (z) => z.boolean().optional(),
|
|
14
13
|
current: (z) => z.boolean().optional(),
|
|
@@ -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 { 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
|
|
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 max: z => z.number().optional().default(1),\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,GAAA,EAAK,OAAK,CAAE,CAAA,MAAA,GAAS,QAAS,EAAA,CAAE,QAAQ,CAAC,CAAA;AAAA,MACzC,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,13 +1,13 @@
|
|
|
1
1
|
import { NavItemBlueprint } from '@backstage/frontend-plugin-api';
|
|
2
2
|
import { convertLegacyRouteRef } from '@backstage/core-compat-api';
|
|
3
3
|
import { rootRouteRef } from '../routes.esm.js';
|
|
4
|
-
import
|
|
4
|
+
import { RiMegaphoneLine } from '@remixicon/react';
|
|
5
5
|
|
|
6
6
|
const announcementsNavItem = NavItemBlueprint.make({
|
|
7
7
|
params: {
|
|
8
8
|
title: "Announcements",
|
|
9
9
|
routeRef: convertLegacyRouteRef(rootRouteRef),
|
|
10
|
-
icon:
|
|
10
|
+
icon: RiMegaphoneLine
|
|
11
11
|
}
|
|
12
12
|
});
|
|
13
13
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navItems.esm.js","sources":["../../src/alpha/navItems.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 {
|
|
1
|
+
{"version":3,"file":"navItems.esm.js","sources":["../../src/alpha/navItems.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 {\n IconComponent,\n NavItemBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { convertLegacyRouteRef } from '@backstage/core-compat-api';\nimport { rootRouteRef } from '../routes';\nimport { RiMegaphoneLine } from '@remixicon/react';\n/**\n * @alpha\n */\nexport const announcementsNavItem = NavItemBlueprint.make({\n params: {\n title: 'Announcements',\n routeRef: convertLegacyRouteRef(rootRouteRef),\n icon: RiMegaphoneLine as IconComponent,\n },\n});\n\nexport default [announcementsNavItem];\n"],"names":[],"mappings":";;;;;AAyBa,MAAA,oBAAA,GAAuB,iBAAiB,IAAK,CAAA;AAAA,EACxD,MAAQ,EAAA;AAAA,IACN,KAAO,EAAA,eAAA;AAAA,IACP,QAAA,EAAU,sBAAsB,YAAY,CAAA;AAAA,IAC5C,IAAM,EAAA;AAAA;AAEV,CAAC;;;;"}
|
package/dist/alpha/search.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { SearchResultListItemBlueprint, SearchFilterResultTypeBlueprint } from '@backstage/plugin-search-react/alpha';
|
|
3
|
-
import
|
|
3
|
+
import { RiMegaphoneLine } from '@remixicon/react';
|
|
4
4
|
|
|
5
5
|
const announcementsSearchResultListItem = SearchResultListItemBlueprint.make({
|
|
6
6
|
params: {
|
|
@@ -8,7 +8,7 @@ const announcementsSearchResultListItem = SearchResultListItemBlueprint.make({
|
|
|
8
8
|
(m) => m.AnnouncementSearchResultListItem
|
|
9
9
|
),
|
|
10
10
|
predicate: (result) => result.type === "announcements",
|
|
11
|
-
icon: /* @__PURE__ */ jsx(
|
|
11
|
+
icon: /* @__PURE__ */ jsx(RiMegaphoneLine, {})
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
14
|
const announcementsSearchFilterResultType = SearchFilterResultTypeBlueprint.make({
|
|
@@ -16,7 +16,7 @@ const announcementsSearchFilterResultType = SearchFilterResultTypeBlueprint.make
|
|
|
16
16
|
params: {
|
|
17
17
|
name: "Announcements",
|
|
18
18
|
value: "announcements",
|
|
19
|
-
icon: /* @__PURE__ */ jsx(
|
|
19
|
+
icon: /* @__PURE__ */ jsx(RiMegaphoneLine, {})
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.esm.js","sources":["../../src/alpha/search.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 */\nimport {\n SearchFilterResultTypeBlueprint,\n SearchResultListItemBlueprint,\n} from '@backstage/plugin-search-react/alpha';\nimport
|
|
1
|
+
{"version":3,"file":"search.esm.js","sources":["../../src/alpha/search.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 */\nimport {\n SearchFilterResultTypeBlueprint,\n SearchResultListItemBlueprint,\n} from '@backstage/plugin-search-react/alpha';\nimport { RiMegaphoneLine } from '@remixicon/react';\n\nexport const announcementsSearchResultListItem =\n SearchResultListItemBlueprint.make({\n params: {\n component: () =>\n import('../components/AnnouncementSearchResultListItem').then(\n m => m.AnnouncementSearchResultListItem,\n ),\n predicate: result => result.type === 'announcements',\n icon: <RiMegaphoneLine />,\n },\n });\n\nexport const announcementsSearchFilterResultType =\n SearchFilterResultTypeBlueprint.make({\n name: 'announcements-results-type',\n params: {\n name: 'Announcements',\n value: 'announcements',\n icon: <RiMegaphoneLine />,\n },\n });\n"],"names":[],"mappings":";;;;AAqBa,MAAA,iCAAA,GACX,8BAA8B,IAAK,CAAA;AAAA,EACjC,MAAQ,EAAA;AAAA,IACN,SAAW,EAAA,MACT,OAAO,6DAAgD,CAAE,CAAA,IAAA;AAAA,MACvD,OAAK,CAAE,CAAA;AAAA,KACT;AAAA,IACF,SAAA,EAAW,CAAU,MAAA,KAAA,MAAA,CAAO,IAAS,KAAA,eAAA;AAAA,IACrC,IAAA,sBAAO,eAAgB,EAAA,EAAA;AAAA;AAE3B,CAAC;AAEU,MAAA,mCAAA,GACX,gCAAgC,IAAK,CAAA;AAAA,EACnC,IAAM,EAAA,4BAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,eAAA;AAAA,IACN,KAAO,EAAA,eAAA;AAAA,IACP,IAAA,sBAAO,eAAgB,EAAA,EAAA;AAAA;AAE3B,CAAC;;;;"}
|
package/dist/alpha.d.ts
CHANGED
|
@@ -25,15 +25,13 @@ declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin
|
|
|
25
25
|
}>;
|
|
26
26
|
"app-root-element:announcements/banner": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
27
27
|
config: {
|
|
28
|
-
|
|
29
|
-
max: number | undefined;
|
|
28
|
+
max: number;
|
|
30
29
|
category: string | undefined;
|
|
31
30
|
active: boolean | undefined;
|
|
32
31
|
current: boolean | undefined;
|
|
33
32
|
tags: string[] | undefined;
|
|
34
33
|
};
|
|
35
34
|
configInput: {
|
|
36
|
-
variant?: "block" | "floating" | undefined;
|
|
37
35
|
max?: number | undefined;
|
|
38
36
|
active?: boolean | undefined;
|
|
39
37
|
current?: boolean | undefined;
|
package/dist/components/AnnouncementSearchResultListItem/AnnouncementSearchResultListItem.esm.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Link } from '@backstage/core-components';
|
|
|
4
4
|
import { HighlightedSearchResultText } from '@backstage/plugin-search-react';
|
|
5
5
|
import { useAnnouncementsTranslation } from '@backstage-community/plugin-announcements-react';
|
|
6
6
|
import { makeStyles, Typography, ListItem, ListItemIcon, ListItemText } from '@material-ui/core';
|
|
7
|
-
import
|
|
7
|
+
import { RiMegaphoneLine } from '@remixicon/react';
|
|
8
8
|
|
|
9
9
|
const useStyles = makeStyles({
|
|
10
10
|
createdAt: {
|
|
@@ -52,7 +52,7 @@ const AnnouncementSearchResultListItem = ({
|
|
|
52
52
|
) : result.text })
|
|
53
53
|
] });
|
|
54
54
|
return /* @__PURE__ */ jsxs(ListItem, { alignItems: "center", children: [
|
|
55
|
-
/* @__PURE__ */ jsx(ListItemIcon, { title: t("announcementSearchResultListItem.announcement"), children: /* @__PURE__ */ jsx(
|
|
55
|
+
/* @__PURE__ */ jsx(ListItemIcon, { title: t("announcementSearchResultListItem.announcement"), children: /* @__PURE__ */ jsx(RiMegaphoneLine, {}) }),
|
|
56
56
|
/* @__PURE__ */ jsx(
|
|
57
57
|
ListItemText,
|
|
58
58
|
{
|
package/dist/components/AnnouncementSearchResultListItem/AnnouncementSearchResultListItem.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnnouncementSearchResultListItem.esm.js","sources":["../../../src/components/AnnouncementSearchResultListItem/AnnouncementSearchResultListItem.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 { Link } from '@backstage/core-components';\nimport {\n IndexableDocument,\n ResultHighlight,\n} from '@backstage/plugin-search-common';\nimport { HighlightedSearchResultText } from '@backstage/plugin-search-react';\nimport { useAnnouncementsTranslation } from '@backstage-community/plugin-announcements-react';\nimport {\n makeStyles,\n ListItem,\n ListItemIcon,\n ListItemText,\n Typography,\n} from '@material-ui/core';\nimport
|
|
1
|
+
{"version":3,"file":"AnnouncementSearchResultListItem.esm.js","sources":["../../../src/components/AnnouncementSearchResultListItem/AnnouncementSearchResultListItem.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 { Link } from '@backstage/core-components';\nimport {\n IndexableDocument,\n ResultHighlight,\n} from '@backstage/plugin-search-common';\nimport { HighlightedSearchResultText } from '@backstage/plugin-search-react';\nimport { useAnnouncementsTranslation } from '@backstage-community/plugin-announcements-react';\nimport {\n makeStyles,\n ListItem,\n ListItemIcon,\n ListItemText,\n Typography,\n} from '@material-ui/core';\nimport { RiMegaphoneLine } from '@remixicon/react';\n\nconst useStyles = makeStyles({\n createdAt: {\n display: 'block',\n marginTop: '0.2rem',\n marginBottom: '0.8rem',\n },\n excerpt: {\n lineHeight: '1.55',\n },\n itemText: {\n wordBreak: 'break-all',\n },\n});\n\ntype IndexableAnnouncement = IndexableDocument & {\n createdAt: string;\n};\n\n/** @public */\nexport interface AnnouncementSearchResultProps {\n result?: IndexableDocument;\n highlight?: ResultHighlight;\n rank?: number;\n}\n\nexport const AnnouncementSearchResultListItem = ({\n result,\n highlight,\n}: AnnouncementSearchResultProps) => {\n const classes = useStyles();\n const { t } = useAnnouncementsTranslation();\n\n if (!result) {\n return null;\n }\n\n const document = result as IndexableAnnouncement;\n\n const title = (\n <Link noTrack to={result.location}>\n {highlight?.fields.title ? (\n <HighlightedSearchResultText\n text={highlight.fields.title}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.title\n )}\n </Link>\n );\n\n const excerpt = (\n <>\n <Typography component=\"span\" className={classes.createdAt}>\n {`${t('announcementSearchResultListItem.published')} `}\n <Typography component=\"span\" title={document.createdAt}>\n {DateTime.fromISO(document.createdAt).toRelative()}\n </Typography>\n </Typography>\n <>\n {highlight?.fields.text ? (\n <HighlightedSearchResultText\n text={highlight.fields.text}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.text\n )}\n </>\n </>\n );\n\n return (\n <ListItem alignItems=\"center\">\n <ListItemIcon title={t('announcementSearchResultListItem.announcement')}>\n <RiMegaphoneLine />\n </ListItemIcon>\n <ListItemText\n primary={title}\n secondary={excerpt}\n className={classes.itemText}\n primaryTypographyProps={{ variant: 'h6' }}\n />\n </ListItem>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAgCA,MAAM,YAAY,UAAW,CAAA;AAAA,EAC3B,SAAW,EAAA;AAAA,IACT,OAAS,EAAA,OAAA;AAAA,IACT,SAAW,EAAA,QAAA;AAAA,IACX,YAAc,EAAA;AAAA,GAChB;AAAA,EACA,OAAS,EAAA;AAAA,IACP,UAAY,EAAA;AAAA,GACd;AAAA,EACA,QAAU,EAAA;AAAA,IACR,SAAW,EAAA;AAAA;AAEf,CAAC,CAAA;AAaM,MAAM,mCAAmC,CAAC;AAAA,EAC/C,MAAA;AAAA,EACA;AACF,CAAqC,KAAA;AACnC,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,2BAA4B,EAAA;AAE1C,EAAA,IAAI,CAAC,MAAQ,EAAA;AACX,IAAO,OAAA,IAAA;AAAA;AAGT,EAAA,MAAM,QAAW,GAAA,MAAA;AAEjB,EAAM,MAAA,KAAA,mBACH,GAAA,CAAA,IAAA,EAAA,EAAK,OAAO,EAAA,IAAA,EAAC,IAAI,MAAO,CAAA,QAAA,EACtB,QAAW,EAAA,SAAA,EAAA,MAAA,CAAO,KACjB,mBAAA,GAAA;AAAA,IAAC,2BAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,UAAU,MAAO,CAAA,KAAA;AAAA,MACvB,QAAQ,SAAU,CAAA,MAAA;AAAA,MAClB,SAAS,SAAU,CAAA;AAAA;AAAA,GACrB,GAEA,OAAO,KAEX,EAAA,CAAA;AAGF,EAAA,MAAM,0BAEF,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,UAAW,EAAA,EAAA,SAAA,EAAU,MAAO,EAAA,SAAA,EAAW,QAAQ,SAC7C,EAAA,QAAA,EAAA;AAAA,MAAG,CAAA,EAAA,CAAA,CAAE,4CAA4C,CAAC,CAAA,CAAA,CAAA;AAAA,sBAClD,GAAA,CAAA,UAAA,EAAA,EAAW,SAAU,EAAA,MAAA,EAAO,KAAO,EAAA,QAAA,CAAS,SAC1C,EAAA,QAAA,EAAA,QAAA,CAAS,OAAQ,CAAA,QAAA,CAAS,SAAS,CAAA,CAAE,YACxC,EAAA;AAAA,KACF,EAAA,CAAA;AAAA,oBACA,GAAA,CAAA,QAAA,EAAA,EACG,QAAW,EAAA,SAAA,EAAA,MAAA,CAAO,IACjB,mBAAA,GAAA;AAAA,MAAC,2BAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,UAAU,MAAO,CAAA,IAAA;AAAA,QACvB,QAAQ,SAAU,CAAA,MAAA;AAAA,QAClB,SAAS,SAAU,CAAA;AAAA;AAAA,KACrB,GAEA,OAAO,IAEX,EAAA;AAAA,GACF,EAAA,CAAA;AAGF,EACE,uBAAA,IAAA,CAAC,QAAS,EAAA,EAAA,UAAA,EAAW,QACnB,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,gBAAa,KAAO,EAAA,CAAA,CAAE,+CAA+C,CACpE,EAAA,QAAA,kBAAA,GAAA,CAAC,mBAAgB,CACnB,EAAA,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,OAAS,EAAA,KAAA;AAAA,QACT,SAAW,EAAA,OAAA;AAAA,QACX,WAAW,OAAQ,CAAA,QAAA;AAAA,QACnB,sBAAA,EAAwB,EAAE,OAAA,EAAS,IAAK;AAAA;AAAA;AAC1C,GACF,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1,58 +1,33 @@
|
|
|
1
1
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
3
|
import { DateTime } from 'luxon';
|
|
4
|
-
import { Link } from '@backstage/
|
|
4
|
+
import { Alert, Box, Link, ButtonIcon } from '@backstage/ui';
|
|
5
5
|
import { useApi, useRouteRef, useAnalytics } from '@backstage/core-plugin-api';
|
|
6
6
|
import { announcementsApiRef, useAnnouncements, useAnnouncementsTranslation } from '@backstage-community/plugin-announcements-react';
|
|
7
7
|
import { SIGNALS_CHANNEL_ANNOUNCEMENTS, MAX_TITLE_LENGTH, MAX_EXCERPT_LENGTH } from '@backstage-community/plugin-announcements-common';
|
|
8
8
|
import { useSignal } from '@backstage/plugin-signals-react';
|
|
9
|
-
import {
|
|
10
|
-
import Close from '@material-ui/icons/Close';
|
|
11
|
-
import { Alert } from '@material-ui/lab';
|
|
9
|
+
import { RiExternalLinkLine, RiCloseLine, RiMegaphoneLine } from '@remixicon/react';
|
|
12
10
|
import { announcementViewRouteRef } from '../../routes.esm.js';
|
|
13
11
|
import { truncate } from '../utils/truncateUtils.esm.js';
|
|
14
12
|
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
icon: {
|
|
28
|
-
fontSize: 20
|
|
29
|
-
},
|
|
30
|
-
bannerIcon: {
|
|
31
|
-
fontSize: 20,
|
|
32
|
-
marginRight: "0.5rem"
|
|
33
|
-
},
|
|
34
|
-
content: {
|
|
35
|
-
width: "100%",
|
|
36
|
-
maxWidth: "inherit",
|
|
37
|
-
flexWrap: "nowrap",
|
|
38
|
-
backgroundColor: theme?.palette?.banner?.info ?? "#f0f0f0",
|
|
39
|
-
display: "flex",
|
|
40
|
-
alignItems: "center",
|
|
41
|
-
color: theme?.palette?.banner?.text ?? "#000000",
|
|
42
|
-
"& a": {
|
|
43
|
-
color: theme?.palette?.banner?.link ?? "#0068c8"
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
});
|
|
13
|
+
const floatingStyle = {
|
|
14
|
+
position: "fixed",
|
|
15
|
+
top: 20,
|
|
16
|
+
left: "50%",
|
|
17
|
+
transform: "translateX(-50%)"
|
|
18
|
+
};
|
|
19
|
+
const externalLinkIconStyle = {
|
|
20
|
+
width: "0.85em",
|
|
21
|
+
height: "0.85em",
|
|
22
|
+
verticalAlign: "middle",
|
|
23
|
+
marginLeft: 5
|
|
24
|
+
};
|
|
48
25
|
const AnnouncementBanner = (props) => {
|
|
49
|
-
const classes = useStyles();
|
|
50
26
|
const announcementsApi = useApi(announcementsApiRef);
|
|
51
27
|
const viewAnnouncementLink = useRouteRef(announcementViewRouteRef);
|
|
52
28
|
const analytics = useAnalytics();
|
|
53
29
|
const { t } = useAnnouncementsTranslation();
|
|
54
30
|
const [bannerOpen, setBannerOpen] = useState(true);
|
|
55
|
-
const variant = props.variant || "block";
|
|
56
31
|
const announcement = props.announcement;
|
|
57
32
|
const titleLength = props.cardOptions?.titleLength;
|
|
58
33
|
const excerptLength = props.cardOptions?.excerptLength;
|
|
@@ -82,28 +57,27 @@ const AnnouncementBanner = (props) => {
|
|
|
82
57
|
};
|
|
83
58
|
const title = titleLength ? truncate(announcement.title, titleLength) : announcement.title;
|
|
84
59
|
const excerpt = excerptLength ? truncate(announcement.excerpt, excerptLength) : announcement.excerpt;
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
Typography,
|
|
88
|
-
{
|
|
89
|
-
component: "span",
|
|
90
|
-
className: classes.bannerIcon,
|
|
91
|
-
variant: "inherit",
|
|
92
|
-
children: "\u{1F4E3}"
|
|
93
|
-
}
|
|
94
|
-
),
|
|
60
|
+
const bannerTitle = /* @__PURE__ */ jsxs(Box, { children: [
|
|
61
|
+
title,
|
|
95
62
|
/* @__PURE__ */ jsx(
|
|
96
63
|
Link,
|
|
97
64
|
{
|
|
98
|
-
|
|
99
|
-
variant: "inherit",
|
|
65
|
+
href: viewAnnouncementLink({ id: announcement.id }),
|
|
100
66
|
onClick: handleLinkClick,
|
|
101
|
-
|
|
67
|
+
variant: "body-large",
|
|
68
|
+
children: /* @__PURE__ */ jsx(RiExternalLinkLine, { "aria-hidden": true, style: externalLinkIconStyle })
|
|
102
69
|
}
|
|
103
|
-
)
|
|
104
|
-
"\xA0\u2013 ",
|
|
105
|
-
excerpt
|
|
70
|
+
)
|
|
106
71
|
] });
|
|
72
|
+
const closeButton = /* @__PURE__ */ jsx(
|
|
73
|
+
ButtonIcon,
|
|
74
|
+
{
|
|
75
|
+
icon: /* @__PURE__ */ jsx(RiCloseLine, {}),
|
|
76
|
+
"aria-label": t("newAnnouncementBanner.markAsSeen"),
|
|
77
|
+
onPress: handleDismiss,
|
|
78
|
+
variant: "tertiary"
|
|
79
|
+
}
|
|
80
|
+
);
|
|
107
81
|
useEffect(() => {
|
|
108
82
|
if (!bannerOpen) {
|
|
109
83
|
return;
|
|
@@ -115,31 +89,19 @@ const AnnouncementBanner = (props) => {
|
|
|
115
89
|
}
|
|
116
90
|
});
|
|
117
91
|
}, [analytics, announcement.id, announcement.title, bannerOpen]);
|
|
92
|
+
if (!bannerOpen) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
118
95
|
return /* @__PURE__ */ jsx(
|
|
119
|
-
|
|
96
|
+
Alert,
|
|
120
97
|
{
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
message,
|
|
129
|
-
action: [
|
|
130
|
-
/* @__PURE__ */ jsx(
|
|
131
|
-
IconButton,
|
|
132
|
-
{
|
|
133
|
-
title: t("newAnnouncementBanner.markAsSeen"),
|
|
134
|
-
color: "inherit",
|
|
135
|
-
onClick: handleDismiss,
|
|
136
|
-
children: /* @__PURE__ */ jsx(Close, { className: classes.icon })
|
|
137
|
-
},
|
|
138
|
-
"dismiss"
|
|
139
|
-
)
|
|
140
|
-
]
|
|
141
|
-
}
|
|
142
|
-
)
|
|
98
|
+
style: floatingStyle,
|
|
99
|
+
status: "info",
|
|
100
|
+
icon: /* @__PURE__ */ jsx(RiMegaphoneLine, {}),
|
|
101
|
+
title: bannerTitle,
|
|
102
|
+
description: excerpt,
|
|
103
|
+
customActions: closeButton,
|
|
104
|
+
mb: "4"
|
|
143
105
|
}
|
|
144
106
|
);
|
|
145
107
|
};
|
|
@@ -149,7 +111,6 @@ const NewAnnouncementBanner = (props) => {
|
|
|
149
111
|
category,
|
|
150
112
|
tags,
|
|
151
113
|
active,
|
|
152
|
-
variant,
|
|
153
114
|
current,
|
|
154
115
|
sortBy,
|
|
155
116
|
cardOptions = {
|
|
@@ -180,7 +141,7 @@ const NewAnnouncementBanner = (props) => {
|
|
|
180
141
|
if (loading) {
|
|
181
142
|
return null;
|
|
182
143
|
} else if (error) {
|
|
183
|
-
return /* @__PURE__ */ jsx(Alert, {
|
|
144
|
+
return /* @__PURE__ */ jsx(Alert, { status: "danger", title: error.message });
|
|
184
145
|
}
|
|
185
146
|
if (announcements.count === 0) {
|
|
186
147
|
return null;
|
|
@@ -198,7 +159,6 @@ const NewAnnouncementBanner = (props) => {
|
|
|
198
159
|
AnnouncementBanner,
|
|
199
160
|
{
|
|
200
161
|
announcement,
|
|
201
|
-
variant,
|
|
202
162
|
cardOptions
|
|
203
163
|
},
|
|
204
164
|
announcement.id
|
|
@@ -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, useAnalytics } from '@backstage/core-plugin-api';\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';\n\nimport { announcementViewRouteRef } from '../../routes';\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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"}
|
|
1
|
+
{"version":3,"file":"NewAnnouncementBanner.esm.js","sources":["../../../src/components/NewAnnouncementBanner/NewAnnouncementBanner.tsx"],"sourcesContent":["/*\n * Copyright 2026 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, Alert, ButtonIcon, Box } from '@backstage/ui';\nimport { useApi, useRouteRef, useAnalytics } from '@backstage/core-plugin-api';\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 RiCloseLine,\n RiMegaphoneLine,\n RiExternalLinkLine,\n} from '@remixicon/react';\n\nimport { announcementViewRouteRef } from '../../routes';\nimport { truncate } from '../utils/truncateUtils';\n\ntype CardOptions = {\n titleLength?: number;\n excerptLength?: number;\n};\n\ntype AnnouncementBannerProps = {\n announcement: Announcement;\n cardOptions?: CardOptions;\n};\n\nconst floatingStyle: React.CSSProperties = {\n position: 'fixed',\n top: 20,\n left: '50%',\n transform: 'translateX(-50%)',\n};\n\nconst externalLinkIconStyle: React.CSSProperties = {\n width: '0.85em',\n height: '0.85em',\n verticalAlign: 'middle',\n marginLeft: 5,\n};\n\nconst AnnouncementBanner = (props: AnnouncementBannerProps) => {\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 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 bannerTitle = (\n <Box>\n {title}\n <Link\n href={viewAnnouncementLink({ id: announcement.id })}\n onClick={handleLinkClick}\n variant=\"body-large\"\n >\n <RiExternalLinkLine aria-hidden style={externalLinkIconStyle} />\n </Link>\n </Box>\n );\n\n const closeButton = (\n <ButtonIcon\n icon={<RiCloseLine />}\n aria-label={t('newAnnouncementBanner.markAsSeen')}\n onPress={handleDismiss}\n variant=\"tertiary\"\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 if (!bannerOpen) {\n return null;\n }\n\n return (\n <Alert\n style={floatingStyle}\n status=\"info\"\n icon={<RiMegaphoneLine />}\n title={bannerTitle}\n description={excerpt}\n customActions={closeButton}\n mb=\"4\"\n />\n );\n};\n\ntype NewAnnouncementBannerProps = {\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 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 status=\"danger\" title={error.message} />;\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 cardOptions={cardOptions}\n />\n ))}\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -56,7 +56,6 @@ declare const AnnouncementsCard: ({ title, max, category, active, variant, sortB
|
|
|
56
56
|
* @public
|
|
57
57
|
*/
|
|
58
58
|
declare const NewAnnouncementBanner: (props: {
|
|
59
|
-
variant?: "block" | "floating" | undefined;
|
|
60
59
|
max?: number | undefined;
|
|
61
60
|
category?: string | undefined;
|
|
62
61
|
active?: boolean | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage-community/plugin-announcements",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"main": "./dist/index.esm.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -64,7 +64,6 @@
|
|
|
64
64
|
"@backstage-community/plugin-announcements-common": "^0.18.0",
|
|
65
65
|
"@backstage-community/plugin-announcements-react": "^0.22.0",
|
|
66
66
|
"@backstage/catalog-model": "^1.7.6",
|
|
67
|
-
"@backstage/core-app-api": "^1.19.5",
|
|
68
67
|
"@backstage/core-compat-api": "^0.5.8",
|
|
69
68
|
"@backstage/core-components": "^0.18.7",
|
|
70
69
|
"@backstage/core-plugin-api": "^1.12.3",
|
|
@@ -80,7 +79,6 @@
|
|
|
80
79
|
"@material-ui/core": "^4.12.2",
|
|
81
80
|
"@material-ui/icons": "^4.11.3",
|
|
82
81
|
"@material-ui/lab": "4.0.0-alpha.61",
|
|
83
|
-
"@mui/icons-material": "^5.15.6",
|
|
84
82
|
"@mui/material": "^5.15.6",
|
|
85
83
|
"@remixicon/react": "^4.7.0",
|
|
86
84
|
"@types/react": "^17.0.0 || ^18.0.0",
|