@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 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
@@ -96,7 +96,6 @@ app:
96
96
  extensions:
97
97
  - announcements/banner:
98
98
  config:
99
- variant: floating
100
99
  max: 2
101
100
  category: updates
102
101
  active: true
@@ -7,8 +7,7 @@ const announcementsBanner = AppRootElementBlueprint.makeWithOverrides({
7
7
  name: "banner",
8
8
  config: {
9
9
  schema: {
10
- variant: (z) => z.enum(["block", "floating"]).default("floating"),
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 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
+ {"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 RecordVoiceOverIcon from '@material-ui/icons/RecordVoiceOver';
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: RecordVoiceOverIcon
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 { NavItemBlueprint } from '@backstage/frontend-plugin-api';\nimport { convertLegacyRouteRef } from '@backstage/core-compat-api';\nimport { rootRouteRef } from '../routes';\nimport RecordVoiceOverIcon from '@material-ui/icons/RecordVoiceOver';\n\n/**\n * @alpha\n */\nexport const announcementsNavItem = NavItemBlueprint.make({\n params: {\n title: 'Announcements',\n routeRef: convertLegacyRouteRef(rootRouteRef),\n icon: RecordVoiceOverIcon,\n },\n});\n\nexport default [announcementsNavItem];\n"],"names":[],"mappings":";;;;;AAuBa,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;;;;"}
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;;;;"}
@@ -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 RecordVoiceOverIcon from '@material-ui/icons/RecordVoiceOver';
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(RecordVoiceOverIcon, {})
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(RecordVoiceOverIcon, {})
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 RecordVoiceOverIcon from '@material-ui/icons/RecordVoiceOver';\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: <RecordVoiceOverIcon />,\n },\n });\n\nexport const announcementsSearchFilterResultType =\n SearchFilterResultTypeBlueprint.make({\n name: 'announcements-results-type',\n params: {\n name: 'Announcements',\n value: 'announcements',\n icon: <RecordVoiceOverIcon />,\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,mBAAoB,EAAA,EAAA;AAAA;AAE/B,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,mBAAoB,EAAA,EAAA;AAAA;AAE/B,CAAC;;;;"}
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
- variant: "block" | "floating";
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;
@@ -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 RecordVoiceOverIcon from '@material-ui/icons/RecordVoiceOver';
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(RecordVoiceOverIcon, {}) }),
55
+ /* @__PURE__ */ jsx(ListItemIcon, { title: t("announcementSearchResultListItem.announcement"), children: /* @__PURE__ */ jsx(RiMegaphoneLine, {}) }),
56
56
  /* @__PURE__ */ jsx(
57
57
  ListItemText,
58
58
  {
@@ -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 RecordVoiceOverIcon from '@material-ui/icons/RecordVoiceOver';\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 <RecordVoiceOverIcon />\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,uBAAoB,CACvB,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
+ {"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/core-components';
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 { makeStyles, Typography, Snackbar, SnackbarContent, IconButton } from '@material-ui/core';
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 useStyles = makeStyles((theme) => {
16
- return {
17
- // showing on top, as a block
18
- blockPositioning: {
19
- padding: theme?.spacing?.(0) ?? 0,
20
- position: "relative",
21
- marginBottom: theme?.spacing?.(4) ?? 32,
22
- marginTop: theme?.spacing?.(3) ?? -24,
23
- zIndex: "unset"
24
- },
25
- // showing on top, as a floating alert
26
- floatingPositioning: {},
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 message = /* @__PURE__ */ jsxs(Fragment, { children: [
86
- /* @__PURE__ */ jsx(
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
- to: viewAnnouncementLink({ id: announcement.id }),
99
- variant: "inherit",
65
+ href: viewAnnouncementLink({ id: announcement.id }),
100
66
  onClick: handleLinkClick,
101
- children: title
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
- Snackbar,
96
+ Alert,
120
97
  {
121
- anchorOrigin: { vertical: "top", horizontal: "center" },
122
- open: bannerOpen,
123
- className: variant === "block" ? classes.blockPositioning : classes.floatingPositioning,
124
- children: /* @__PURE__ */ jsx(
125
- SnackbarContent,
126
- {
127
- className: classes.content,
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, { severity: "error", children: error.message });
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 &nbsp;– {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.4.0",
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",