@backstage-community/plugin-announcements 0.7.1 → 0.8.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 +18 -0
- package/README.md +1 -1
- package/dist/components/Admin/AdminPortal/AdminPortal.esm.js +5 -2
- package/dist/components/Admin/AdminPortal/AdminPortal.esm.js.map +1 -1
- package/dist/components/Admin/AnnouncementsContent/AnnouncementsContent.esm.js +13 -4
- package/dist/components/Admin/AnnouncementsContent/AnnouncementsContent.esm.js.map +1 -1
- package/dist/components/Admin/TagsContent/TagsContent.esm.js +146 -0
- package/dist/components/Admin/TagsContent/TagsContent.esm.js.map +1 -0
- package/dist/components/AnnouncementForm/AnnouncementForm.esm.js +44 -13
- package/dist/components/AnnouncementForm/AnnouncementForm.esm.js.map +1 -1
- package/dist/components/AnnouncementForm/CategoryInput.esm.js.map +1 -1
- package/dist/components/AnnouncementForm/TagsInput.esm.js +98 -0
- package/dist/components/AnnouncementForm/TagsInput.esm.js.map +1 -0
- package/dist/components/AnnouncementPage/AnnouncementPage.esm.js.map +1 -1
- package/dist/components/AnnouncementsCard/AnnouncementsCard.esm.js +20 -2
- package/dist/components/AnnouncementsCard/AnnouncementsCard.esm.js.map +1 -1
- package/dist/components/AnnouncementsPage/AnnouncementsPage.esm.js +15 -3
- package/dist/components/AnnouncementsPage/AnnouncementsPage.esm.js.map +1 -1
- package/dist/components/AnnouncementsPage/ContextMenu.esm.js +6 -1
- package/dist/components/AnnouncementsPage/ContextMenu.esm.js.map +1 -1
- package/dist/components/MarkdownRenderer/MarkdownRenderer.esm.js.map +1 -1
- package/dist/components/NewAnnouncementBanner/NewAnnouncementBanner.esm.js +2 -1
- package/dist/components/NewAnnouncementBanner/NewAnnouncementBanner.esm.js.map +1 -1
- package/dist/components/Router.esm.js +1 -0
- package/dist/components/Router.esm.js.map +1 -1
- package/dist/components/TagsForm/TagsForm.esm.js +85 -0
- package/dist/components/TagsForm/TagsForm.esm.js.map +1 -0
- package/dist/components/TagsPage/DeleteTagDialog.esm.js +16 -0
- package/dist/components/TagsPage/DeleteTagDialog.esm.js.map +1 -0
- package/dist/components/TagsPage/useDeleteTagDialogState.esm.js +29 -0
- package/dist/components/TagsPage/useDeleteTagDialogState.esm.js.map +1 -0
- package/dist/index.d.ts +13 -1
- package/dist/routes.esm.js +6 -1
- package/dist/routes.esm.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import Autocomplete, { createFilterOptions } from '@material-ui/lab/Autocomplete';
|
|
4
|
+
import { Chip, TextField, CircularProgress } from '@material-ui/core';
|
|
5
|
+
import { useTags, useAnnouncementsTranslation } from '@backstage-community/plugin-announcements-react';
|
|
6
|
+
|
|
7
|
+
const filter = createFilterOptions();
|
|
8
|
+
function prepareTagFromInput(input) {
|
|
9
|
+
if (typeof input === "string") {
|
|
10
|
+
return input.toLocaleLowerCase("en-US");
|
|
11
|
+
}
|
|
12
|
+
if (input.inputValue) {
|
|
13
|
+
return input.inputValue.toLocaleLowerCase("en-US");
|
|
14
|
+
}
|
|
15
|
+
return input.title.toLocaleLowerCase("en-US");
|
|
16
|
+
}
|
|
17
|
+
function TagsInput({ setForm, form }) {
|
|
18
|
+
const { tags, loading } = useTags();
|
|
19
|
+
const { t } = useAnnouncementsTranslation();
|
|
20
|
+
const createLabel = t("announcementForm.tagsInput.create");
|
|
21
|
+
const existingTags = useMemo(() => {
|
|
22
|
+
if (!form.tags || form.tags.length === 0) return [];
|
|
23
|
+
return form.tags.map((tagSlug) => {
|
|
24
|
+
const foundTag = tags?.find((tag) => tag.slug === tagSlug);
|
|
25
|
+
return foundTag || { title: tagSlug, slug: tagSlug };
|
|
26
|
+
});
|
|
27
|
+
}, [form.tags, tags]);
|
|
28
|
+
const handleTagChange = (_event, newValue) => {
|
|
29
|
+
if (!newValue || newValue.length === 0) {
|
|
30
|
+
setForm({ ...form, tags: [] });
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const processedTags = newValue.map((item) => prepareTagFromInput(item));
|
|
34
|
+
const uniqueTags = Array.from(new Set(processedTags));
|
|
35
|
+
setForm({ ...form, tags: uniqueTags });
|
|
36
|
+
};
|
|
37
|
+
return /* @__PURE__ */ jsx(
|
|
38
|
+
Autocomplete,
|
|
39
|
+
{
|
|
40
|
+
fullWidth: true,
|
|
41
|
+
multiple: true,
|
|
42
|
+
freeSolo: true,
|
|
43
|
+
clearOnBlur: true,
|
|
44
|
+
value: existingTags,
|
|
45
|
+
onChange: handleTagChange,
|
|
46
|
+
options: tags || [],
|
|
47
|
+
loading,
|
|
48
|
+
getOptionLabel: (option) => typeof option === "string" ? option : option.title,
|
|
49
|
+
filterOptions: (options, params) => {
|
|
50
|
+
const filtered = filter(options, params);
|
|
51
|
+
const { inputValue } = params;
|
|
52
|
+
if (inputValue.trim() !== "" && !options.some(
|
|
53
|
+
(option) => typeof option !== "string" && inputValue.toLocaleLowerCase("en-US") === option.title.toLocaleLowerCase("en-US")
|
|
54
|
+
)) {
|
|
55
|
+
filtered.push({
|
|
56
|
+
title: `${createLabel} "${inputValue}"`,
|
|
57
|
+
slug: inputValue.toLocaleLowerCase("en-US"),
|
|
58
|
+
inputValue,
|
|
59
|
+
isNew: true
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return filtered;
|
|
63
|
+
},
|
|
64
|
+
renderTags: (value, getTagProps) => value.map((option, index) => {
|
|
65
|
+
const tag = typeof option === "string" ? { title: option, slug: option.toLocaleLowerCase("en-US") } : option;
|
|
66
|
+
const tagProps = getTagProps({ index });
|
|
67
|
+
const { key, ...chipProps } = tagProps;
|
|
68
|
+
return /* @__PURE__ */ jsx(
|
|
69
|
+
Chip,
|
|
70
|
+
{
|
|
71
|
+
variant: "outlined",
|
|
72
|
+
label: tag.title,
|
|
73
|
+
...chipProps
|
|
74
|
+
},
|
|
75
|
+
key
|
|
76
|
+
);
|
|
77
|
+
}),
|
|
78
|
+
renderInput: (params) => /* @__PURE__ */ jsx(
|
|
79
|
+
TextField,
|
|
80
|
+
{
|
|
81
|
+
...params,
|
|
82
|
+
label: "Tags",
|
|
83
|
+
variant: "outlined",
|
|
84
|
+
InputProps: {
|
|
85
|
+
...params.InputProps,
|
|
86
|
+
endAdornment: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
87
|
+
loading ? /* @__PURE__ */ jsx(CircularProgress, { color: "inherit", size: 20 }) : null,
|
|
88
|
+
params.InputProps.endAdornment
|
|
89
|
+
] })
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export { TagsInput as default };
|
|
98
|
+
//# sourceMappingURL=TagsInput.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagsInput.esm.js","sources":["../../../src/components/AnnouncementForm/TagsInput.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 { useMemo } from 'react';\nimport Autocomplete, {\n createFilterOptions,\n} from '@material-ui/lab/Autocomplete';\nimport { TextField, Chip, CircularProgress } from '@material-ui/core';\nimport {\n useTags,\n useAnnouncementsTranslation,\n} from '@backstage-community/plugin-announcements-react';\nimport { Tag } from '@backstage-community/plugin-announcements-common';\n\nexport interface TagOption extends Tag {\n inputValue?: string;\n isNew?: boolean;\n}\n\nconst filter = createFilterOptions<TagOption>();\n\nfunction prepareTagFromInput(input: string | TagOption): string {\n if (typeof input === 'string') {\n return input.toLocaleLowerCase('en-US');\n }\n if (input.inputValue) {\n return input.inputValue.toLocaleLowerCase('en-US');\n }\n return input.title.toLocaleLowerCase('en-US');\n}\n\ninterface TagsInputProps {\n setForm: (form: any) => void;\n form: any;\n}\n\nexport default function TagsInput({ setForm, form }: TagsInputProps) {\n const { tags, loading } = useTags();\n const { t } = useAnnouncementsTranslation();\n const createLabel = t('announcementForm.tagsInput.create');\n\n const existingTags = useMemo(() => {\n if (!form.tags || form.tags.length === 0) return [];\n return form.tags.map((tagSlug: string) => {\n const foundTag = tags?.find(tag => tag.slug === tagSlug);\n return foundTag || { title: tagSlug, slug: tagSlug };\n });\n }, [form.tags, tags]);\n\n const handleTagChange = (_event: any, newValue: (string | TagOption)[]) => {\n if (!newValue || newValue.length === 0) {\n setForm({ ...form, tags: [] });\n return;\n }\n\n const processedTags = newValue.map(item => prepareTagFromInput(item));\n const uniqueTags = Array.from(new Set(processedTags));\n\n setForm({ ...form, tags: uniqueTags });\n };\n\n return (\n <Autocomplete\n fullWidth\n multiple\n freeSolo\n clearOnBlur\n value={existingTags}\n onChange={handleTagChange}\n options={tags || []}\n loading={loading}\n getOptionLabel={(option: string | TagOption) =>\n typeof option === 'string' ? option : option.title\n }\n filterOptions={(options, params) => {\n const filtered = filter(options as TagOption[], params);\n const { inputValue } = params;\n if (\n inputValue.trim() !== '' &&\n !options.some(\n option =>\n typeof option !== 'string' &&\n inputValue.toLocaleLowerCase('en-US') ===\n option.title.toLocaleLowerCase('en-US'),\n )\n ) {\n filtered.push({\n title: `${createLabel} \"${inputValue}\"`,\n slug: inputValue.toLocaleLowerCase('en-US'),\n inputValue,\n isNew: true,\n });\n }\n return filtered;\n }}\n renderTags={(value: (string | TagOption)[], getTagProps) =>\n value.map((option, index) => {\n const tag =\n typeof option === 'string'\n ? { title: option, slug: option.toLocaleLowerCase('en-US') }\n : option;\n\n const tagProps = getTagProps({ index }) as {\n key: string;\n [key: string]: any;\n };\n const { key, ...chipProps } = tagProps;\n\n return (\n <Chip\n key={key}\n variant=\"outlined\"\n label={tag.title}\n {...chipProps}\n />\n );\n })\n }\n renderInput={params => (\n <TextField\n {...params}\n label=\"Tags\"\n variant=\"outlined\"\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <>\n {loading ? (\n <CircularProgress color=\"inherit\" size={20} />\n ) : null}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n />\n )}\n />\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -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 {\n EntityPeekAheadPopover,\n EntityRefLink,\n} from '@backstage/plugin-catalog-react';\nimport { announcementViewRouteRef, rootRouteRef } from '../../routes';\nimport { announcementsApiRef } from '@backstage-community/plugin-announcements-react';\nimport { Announcement } from '@backstage-community/plugin-announcements-common';\nimport { Grid, Typography } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport {
|
|
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 {\n EntityPeekAheadPopover,\n EntityRefLink,\n} from '@backstage/plugin-catalog-react';\nimport { announcementViewRouteRef, rootRouteRef } from '../../routes';\nimport { announcementsApiRef } from '@backstage-community/plugin-announcements-react';\nimport { Announcement } from '@backstage-community/plugin-announcements-common';\nimport { Grid, Typography } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport {\n MarkdownRenderer,\n MarkdownRendererTypeProps,\n} from '../MarkdownRenderer';\n\nconst AnnouncementDetails = ({\n announcement,\n markdownRenderer,\n}: {\n announcement: Announcement;\n markdownRenderer?: MarkdownRendererTypeProps;\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 <EntityPeekAheadPopover\n entityRef={announcement.on_behalf_of || announcement.publisher}\n >\n <EntityRefLink\n entityRef={announcement.on_behalf_of || announcement.publisher}\n hideIcon\n />\n </EntityPeekAheadPopover>\n , {DateTime.fromISO(announcement.created_at).toRelative()}\n </Typography>\n );\n\n return (\n <InfoCard\n title={announcement.title}\n subheader={subHeader}\n deepLink={deepLink}\n >\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};\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 />\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":"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"}
|
|
@@ -7,13 +7,17 @@ import { announcementEntityPermissions } from '@backstage-community/plugin-annou
|
|
|
7
7
|
import { rootRouteRef, announcementViewRouteRef, announcementCreateRouteRef } from '../../routes.esm.js';
|
|
8
8
|
import { formatAnnouncementStartTime } from '../utils/announcementDateUtils.esm.js';
|
|
9
9
|
import { announcementsApiRef, useAnnouncementsTranslation, useAnnouncements } from '@backstage-community/plugin-announcements-react';
|
|
10
|
-
import { makeStyles, List, ListItem, ListItemIcon, ListItemText, Box, Typography } from '@material-ui/core';
|
|
10
|
+
import { makeStyles, List, ListItem, ListItemIcon, ListItemText, Box, Typography, Chip } from '@material-ui/core';
|
|
11
11
|
import { Alert } from '@material-ui/lab';
|
|
12
12
|
import NewReleasesIcon from '@material-ui/icons/NewReleases';
|
|
13
13
|
|
|
14
14
|
const useStyles = makeStyles({
|
|
15
15
|
newAnnouncementIcon: {
|
|
16
16
|
minWidth: "36px"
|
|
17
|
+
},
|
|
18
|
+
chipStyle: {
|
|
19
|
+
marginRight: 4,
|
|
20
|
+
marginBottom: 4
|
|
17
21
|
}
|
|
18
22
|
});
|
|
19
23
|
const AnnouncementsCard = ({
|
|
@@ -98,7 +102,21 @@ const AnnouncementsCard = ({
|
|
|
98
102
|
)
|
|
99
103
|
] })
|
|
100
104
|
] }),
|
|
101
|
-
/* @__PURE__ */
|
|
105
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "textSecondary", children: [
|
|
106
|
+
announcement.excerpt,
|
|
107
|
+
announcement.tags && announcement.tags.length > 0 && /* @__PURE__ */ jsx(Box, { mt: 1, children: announcement.tags.map((tag) => /* @__PURE__ */ jsx(
|
|
108
|
+
Chip,
|
|
109
|
+
{
|
|
110
|
+
size: "small",
|
|
111
|
+
label: tag.title,
|
|
112
|
+
component: Link,
|
|
113
|
+
to: `${announcementsLink()}?tags=${tag.slug}`,
|
|
114
|
+
clickable: true,
|
|
115
|
+
className: classes.chipStyle
|
|
116
|
+
},
|
|
117
|
+
tag.slug
|
|
118
|
+
)) })
|
|
119
|
+
] }),
|
|
102
120
|
!hideStartAt && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "textSecondary", children: formatAnnouncementStartTime(
|
|
103
121
|
announcement.start_at,
|
|
104
122
|
t("announcementsCard.occurred"),
|
|
@@ -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} 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});\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 hideStartAt?: boolean;\n};\n\nexport const AnnouncementsCard = ({\n title,\n max,\n category,\n active,\n variant = 'gridItem',\n sortBy,\n order,\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 });\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 </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 } 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 hideStartAt?: boolean;\n};\n\nexport const AnnouncementsCard = ({\n title,\n max,\n category,\n active,\n variant = 'gridItem',\n sortBy,\n order,\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 });\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":";;;;;;;;;;;;;AAiDA,MAAM,YAAY,UAAW,CAAA;AAAA,EAC3B,mBAAqB,EAAA;AAAA,IACnB,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,SAAW,EAAA;AAAA,IACT,WAAa,EAAA,CAAA;AAAA,IACb,YAAc,EAAA;AAAA;AAElB,CAAC,CAAA;AAaM,MAAM,oBAAoB,CAAC;AAAA,EAChC,KAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAU,GAAA,UAAA;AAAA,EACV,MAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAA6B,KAAA;AAC3B,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAM,MAAA,gBAAA,GAAmB,OAAO,mBAAmB,CAAA;AACnD,EAAM,MAAA,iBAAA,GAAoB,YAAY,YAAY,CAAA;AAClD,EAAM,MAAA,oBAAA,GAAuB,YAAY,wBAAwB,CAAA;AACjE,EAAM,MAAA,sBAAA,GAAyB,YAAY,0BAA0B,CAAA;AACrE,EAAM,MAAA,QAAA,GAAW,iBAAiB,YAAa,EAAA;AAC/C,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,2BAA4B,EAAA;AAE1C,EAAA,MAAM,EAAE,aAAA,EAAe,OAAS,EAAA,KAAA,KAAU,gBAAiB,CAAA;AAAA,IACzD,KAAK,GAAO,IAAA,CAAA;AAAA,IACZ,QAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAM,MAAA,EAAE,8BAAiC,GAAA,6BAAA;AACzC,EAAA,MAAM,EAAE,OAAS,EAAA,iBAAA,EAAmB,OAAS,EAAA,MAAA,KAAW,aAAc,CAAA;AAAA,IACpE,UAAY,EAAA;AAAA,GACb,CAAA;AAED,EAAA,IAAI,OAAS,EAAA;AACX,IAAA,2BAAQ,QAAS,EAAA,EAAA,CAAA;AAAA,aACR,KAAO,EAAA;AAChB,IAAA,uBAAQ,GAAA,CAAA,KAAA,EAAA,EAAM,QAAS,EAAA,OAAA,EAAS,gBAAM,OAAQ,EAAA,CAAA;AAAA;AAGhD,EAAA,MAAM,QAAW,GAAA;AAAA,IACf,MAAM,iBAAkB,EAAA;AAAA,IACxB,KAAA,EAAO,EAAE,0BAA0B;AAAA,GACrC;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,KAAS,IAAA,CAAA,CAAE,iCAAiC,CAAA;AAAA,MACnD,OAAA;AAAA,MACA,QAAA;AAAA,MAEA,QAAA,kBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAK,IACR,EAAA,QAAA,EAAA;AAAA,QAAA,aAAA,CAAc,OAAQ,CAAA,GAAA,CAAI,CACzB,YAAA,qBAAA,IAAA,CAAC,QACC,EAAA,EAAA,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,YAAA;AAAA,YAAA;AAAA,cACC,WAAW,OAAQ,CAAA,mBAAA;AAAA,cACnB,KAAO,EAAA;AAAA,gBACL,YACE,QAAW,GAAA,QAAA,CAAS,QAAQ,YAAa,CAAA,UAAU,IAC/C,SACA,GAAA;AAAA,eACR;AAAA,cACA,KAAA,EAAO,EAAE,uBAAuB,CAAA;AAAA,cAEhC,8BAAC,eAAgB,EAAA,EAAA;AAAA;AAAA,WACnB;AAAA,0BACA,GAAA;AAAA,YAAC,YAAA;AAAA,YAAA;AAAA,cACC,OACE,kBAAA,GAAA;AAAA,gBAAC,IAAA;AAAA,gBAAA;AAAA,kBACC,IAAI,oBAAqB,CAAA,EAAE,EAAI,EAAA,YAAA,CAAa,IAAI,CAAA;AAAA,kBAChD,OAAQ,EAAA,SAAA;AAAA,kBAEP,QAAa,EAAA,YAAA,CAAA;AAAA;AAAA,eAChB;AAAA,cAEF,SAAA,uBACG,GACC,EAAA,EAAA,QAAA,EAAA;AAAA,gCAAA,IAAA,CAAC,UAAW,EAAA,EAAA,OAAA,EAAQ,OAAQ,EAAA,KAAA,EAAM,eAC/B,EAAA,QAAA,EAAA;AAAA,kBAAA,QAAA,CAAS,OAAQ,CAAA,YAAA,CAAa,UAAU,CAAA,CAAE,UAAW,EAAA;AAAA,kBACrD,YAAA,CAAa,4BAET,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAI,CAAA,CAAA,EAAA,CAAA,CAAE,sBAAsB,CAAC,CAAA,CAAA,CAAA;AAAA,oCAC9B,GAAA;AAAA,sBAAC,IAAA;AAAA,sBAAA;AAAA,wBACC,IAAI,CAAG,EAAA,iBAAA,EAAmB,CACxB,UAAA,EAAA,YAAA,CAAa,SAAS,IACxB,CAAA,CAAA;AAAA,wBACA,OAAQ,EAAA,SAAA;AAAA,wBAEP,uBAAa,QAAS,CAAA;AAAA;AAAA;AACzB,mBACF,EAAA;AAAA,iBAEJ,EAAA,CAAA;AAAA,gCACC,IAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,OAAA,EAAQ,OAAM,eAC/B,EAAA,QAAA,EAAA;AAAA,kBAAa,YAAA,CAAA,OAAA;AAAA,kBACb,YAAa,CAAA,IAAA,IAAQ,YAAa,CAAA,IAAA,CAAK,MAAS,GAAA,CAAA,oBAC9C,GAAA,CAAA,GAAA,EAAA,EAAI,EAAI,EAAA,CAAA,EACN,QAAa,EAAA,YAAA,CAAA,IAAA,CAAK,IAAI,CACrB,GAAA,qBAAA,GAAA;AAAA,oBAAC,IAAA;AAAA,oBAAA;AAAA,sBAEC,IAAK,EAAA,OAAA;AAAA,sBACL,OAAO,GAAI,CAAA,KAAA;AAAA,sBACX,SAAW,EAAA,IAAA;AAAA,sBACX,IAAI,CAAG,EAAA,iBAAA,EAAmB,CAAA,MAAA,EAAS,IAAI,IAAI,CAAA,CAAA;AAAA,sBAC3C,SAAS,EAAA,IAAA;AAAA,sBACT,WAAW,OAAQ,CAAA;AAAA,qBAAA;AAAA,oBANd,GAAI,CAAA;AAAA,mBAQZ,CACH,EAAA;AAAA,iBAEJ,EAAA,CAAA;AAAA,gBACC,CAAC,WACA,oBAAA,GAAA,CAAC,cAAW,OAAQ,EAAA,SAAA,EAAU,OAAM,eACjC,EAAA,QAAA,EAAA,2BAAA;AAAA,kBACC,YAAa,CAAA,QAAA;AAAA,kBACb,EAAE,4BAA4B,CAAA;AAAA,kBAC9B,EAAE,6BAA6B,CAAA;AAAA,kBAC/B,EAAE,yBAAyB;AAAA,iBAE/B,EAAA;AAAA,eAEJ,EAAA;AAAA;AAAA,WAEJ;AAAA,UAAG;AAAA,SAtEU,EAAA,EAAA,YAAA,CAAa,EAuE5B,CACD,CAAA;AAAA,QACA,aAAA,CAAc,UAAU,CAAK,IAAA,CAAC,qBAAqB,MAClD,oBAAA,GAAA,CAAC,QACC,EAAA,EAAA,QAAA,kBAAA,IAAA,CAAC,YACE,EAAA,EAAA,QAAA,EAAA;AAAA,UAAG,CAAA,EAAA,CAAA,CAAE,mCAAmC,CAAC,CAAA,CAAA,CAAA;AAAA,0BAC1C,GAAA,CAAC,QAAK,EAAI,EAAA,sBAAA,IAA0B,OAAQ,EAAA,SAAA,EACzC,QAAE,EAAA,CAAA,CAAA,0BAA0B,CAC/B,EAAA,CAAA;AAAA,UAAO;AAAA,SAAA,EAET,CACF,EAAA;AAAA,OAEJ,EAAA;AAAA;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -15,7 +15,7 @@ import { DeleteAnnouncementDialog } from './DeleteAnnouncementDialog.esm.js';
|
|
|
15
15
|
import { useDeleteAnnouncementDialogState } from './useDeleteAnnouncementDialogState.esm.js';
|
|
16
16
|
import { ContextMenu } from './ContextMenu.esm.js';
|
|
17
17
|
import { useAnnouncementsTranslation, announcementsApiRef, useAnnouncements } from '@backstage-community/plugin-announcements-react';
|
|
18
|
-
import { makeStyles, Tooltip, Typography, Box, Card, CardHeader, CardContent, IconButton, Menu, MenuItem, ListItemIcon } from '@material-ui/core';
|
|
18
|
+
import { makeStyles, Tooltip, Typography, Box, Chip, Card, CardHeader, CardContent, IconButton, Menu, MenuItem, ListItemIcon } from '@material-ui/core';
|
|
19
19
|
import { Alert, Pagination } from '@material-ui/lab';
|
|
20
20
|
import { formatAnnouncementStartTime } from '../utils/announcementDateUtils.esm.js';
|
|
21
21
|
|
|
@@ -98,7 +98,19 @@ const AnnouncementCard = ({
|
|
|
98
98
|
t("announcementsCard.occurred"),
|
|
99
99
|
t("announcementsCard.scheduled"),
|
|
100
100
|
t("announcementsCard.today")
|
|
101
|
-
) }) })
|
|
101
|
+
) }) }),
|
|
102
|
+
announcement.tags && announcement.tags.length > 0 && /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: announcement.tags && announcement.tags.length > 0 && /* @__PURE__ */ jsx(Box, { mt: 1, children: announcement.tags.map((tag) => /* @__PURE__ */ jsx(
|
|
103
|
+
Chip,
|
|
104
|
+
{
|
|
105
|
+
size: "small",
|
|
106
|
+
label: tag.title,
|
|
107
|
+
component: Link,
|
|
108
|
+
to: `${announcementsLink()}?tags=${tag.slug}`,
|
|
109
|
+
clickable: true,
|
|
110
|
+
style: { marginRight: 4, marginBottom: 4 }
|
|
111
|
+
},
|
|
112
|
+
tag.slug
|
|
113
|
+
)) }) })
|
|
102
114
|
] });
|
|
103
115
|
const { loading: loadingDeletePermission, allowed: canDelete } = usePermission({ permission: announcementDeletePermission });
|
|
104
116
|
const { loading: loadingUpdatePermission, allowed: canUpdate } = usePermission({ permission: announcementUpdatePermission });
|
|
@@ -286,7 +298,7 @@ const AnnouncementsPage = (props) => {
|
|
|
286
298
|
maxPerPage: maxPerPage ?? 10,
|
|
287
299
|
category: category ?? queryParams.get("category") ?? void 0,
|
|
288
300
|
cardTitleLength: cardOptions?.titleLength,
|
|
289
|
-
active: hideInactive
|
|
301
|
+
active: !!hideInactive,
|
|
290
302
|
sortBy: sortby ?? "created_at",
|
|
291
303
|
order: order ?? "desc",
|
|
292
304
|
hideStartAt
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnnouncementsPage.esm.js","sources":["../../../src/components/AnnouncementsPage/AnnouncementsPage.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 { MouseEvent, useState, ReactNode } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport {\n announcementCreatePermission,\n announcementUpdatePermission,\n announcementDeletePermission,\n Announcement,\n} from '@backstage-community/plugin-announcements-common';\nimport { DateTime } from 'luxon';\nimport {\n Page,\n Header,\n Content,\n Link,\n ItemCardGrid,\n Progress,\n ContentHeader,\n LinkButton,\n} from '@backstage/core-components';\nimport { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n EntityPeekAheadPopover,\n EntityRefLink,\n} from '@backstage/plugin-catalog-react';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport EditIcon from '@material-ui/icons/Edit';\nimport MoreVertIcon from '@material-ui/icons/MoreVert';\nimport {\n announcementCreateRouteRef,\n announcementEditRouteRef,\n announcementViewRouteRef,\n rootRouteRef,\n} from '../../routes';\nimport { DeleteAnnouncementDialog } from './DeleteAnnouncementDialog';\nimport { useDeleteAnnouncementDialogState } from './useDeleteAnnouncementDialogState';\nimport { ContextMenu } from './ContextMenu';\nimport {\n announcementsApiRef,\n useAnnouncements,\n useAnnouncementsTranslation,\n} from '@backstage-community/plugin-announcements-react';\nimport {\n Box,\n Card,\n CardContent,\n CardHeader,\n IconButton,\n ListItemIcon,\n makeStyles,\n Menu,\n MenuItem,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport { Alert, Pagination } from '@material-ui/lab';\nimport { formatAnnouncementStartTime } from '../utils/announcementDateUtils';\nimport { MarkdownRendererType } from '../MarkdownRenderer/MarkdownRenderer';\n\nconst useStyles = makeStyles(theme => {\n return {\n cardHeader: {\n color: theme?.palette?.text?.primary || '#000',\n },\n pagination: {\n display: 'flex',\n justifyContent: 'center',\n marginTop: theme?.spacing?.(4) || 32,\n },\n };\n});\n/**\n * Truncate text to a given length and add ellipsis\n * @param text the text to truncate\n * @param length the length to truncate to\n * @returns the truncated text\n */\nconst truncate = (text: string, length: number) => {\n return text.length > length ? `${text.substring(0, length)}...` : text;\n};\n\nconst AnnouncementCard = ({\n announcement,\n onDelete,\n options: { titleLength = 50 },\n hideStartAt,\n}: {\n announcement: Announcement;\n onDelete: () => void;\n options: AnnouncementCardProps;\n hideStartAt?: boolean;\n}) => {\n const classes = useStyles();\n const announcementsLink = useRouteRef(rootRouteRef);\n const viewAnnouncementLink = useRouteRef(announcementViewRouteRef);\n const editAnnouncementLink = useRouteRef(announcementEditRouteRef);\n const { t } = useAnnouncementsTranslation();\n\n const title = (\n <Tooltip\n title={announcement.title}\n disableFocusListener\n data-testid=\"announcement-card-title-tooltip\"\n >\n <Link\n className={classes.cardHeader}\n to={viewAnnouncementLink({ id: announcement.id })}\n >\n {truncate(announcement.title, titleLength)}\n </Link>\n </Tooltip>\n );\n const subTitle = (\n <>\n <Typography variant=\"body2\" color=\"textSecondary\" component=\"span\">\n {t('announcementsPage.card.by')}{' '}\n <EntityPeekAheadPopover\n entityRef={announcement.on_behalf_of || announcement.publisher}\n >\n <EntityRefLink\n entityRef={announcement.on_behalf_of || announcement.publisher}\n hideIcon\n />\n </EntityPeekAheadPopover>\n {announcement.category && (\n <>\n {' '}\n {t('announcementsPage.card.in')}{' '}\n <Link\n to={`${announcementsLink()}?category=${\n announcement.category.slug\n }`}\n >\n {announcement.category.title}\n </Link>\n </>\n )}\n , {DateTime.fromISO(announcement.created_at).toRelative()}\n </Typography>\n <Box>\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 const { loading: loadingDeletePermission, allowed: canDelete } =\n usePermission({ permission: announcementDeletePermission });\n const { loading: loadingUpdatePermission, allowed: canUpdate } =\n usePermission({ permission: announcementUpdatePermission });\n\n const AnnouncementEditMenu = () => {\n const [open, setOpen] = useState(false);\n const [anchorEl, setAnchorEl] = useState<undefined | HTMLElement>(\n undefined,\n );\n\n const handleOpenEditMenu = (event: MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n setOpen(true);\n };\n\n const handleCloseEditClose = () => {\n setAnchorEl(undefined);\n setOpen(false);\n };\n\n const canShowMenu =\n (!loadingUpdatePermission && canUpdate) ||\n (!loadingDeletePermission && canDelete);\n\n return (\n <>\n {canShowMenu && (\n <IconButton\n data-testid=\"announcement-edit-menu\"\n aria-label=\"more\"\n onClick={handleOpenEditMenu}\n >\n <MoreVertIcon />\n </IconButton>\n )}\n <Menu anchorEl={anchorEl} open={open} onClose={handleCloseEditClose}>\n {!loadingUpdatePermission && canUpdate && (\n <MenuItem\n data-testid=\"edit-announcement\"\n component={LinkButton}\n to={editAnnouncementLink({ id: announcement.id })}\n >\n <ListItemIcon>\n <EditIcon />\n </ListItemIcon>\n {t('announcementsPage.card.edit')}\n </MenuItem>\n )}\n {!loadingDeletePermission && canDelete && (\n <MenuItem onClick={onDelete}>\n <ListItemIcon>\n <DeleteIcon />\n </ListItemIcon>\n {t('announcementsPage.card.delete')}\n </MenuItem>\n )}\n </Menu>\n </>\n );\n };\n\n return (\n <Card>\n <CardHeader\n action={<AnnouncementEditMenu />}\n title={title}\n subheader={subTitle}\n />\n <CardContent>{announcement.excerpt}</CardContent>\n </Card>\n );\n};\n\nconst AnnouncementsGrid = ({\n maxPerPage,\n category,\n cardTitleLength,\n active,\n sortBy,\n order,\n hideStartAt,\n}: {\n maxPerPage: number;\n category?: string;\n cardTitleLength?: number;\n active?: boolean;\n sortBy?: 'created_at' | 'start_at';\n order?: 'asc' | 'desc';\n hideStartAt?: boolean;\n}) => {\n const classes = useStyles();\n const announcementsApi = useApi(announcementsApiRef);\n const alertApi = useApi(alertApiRef);\n\n const [page, setPage] = useState(1);\n const handleChange = (_event: any, value: number) => {\n setPage(value);\n };\n\n const {\n announcements,\n loading,\n error,\n retry: refresh,\n } = useAnnouncements(\n {\n max: maxPerPage,\n page: page,\n category,\n active,\n sortBy,\n order,\n },\n { dependencies: [maxPerPage, page, category] },\n );\n\n const { t } = useAnnouncementsTranslation();\n\n const {\n isOpen: isDeleteDialogOpen,\n open: openDeleteDialog,\n close: closeDeleteDialog,\n announcement: announcementToDelete,\n } = useDeleteAnnouncementDialogState();\n\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n const onCancelDelete = () => {\n closeDeleteDialog();\n };\n const onConfirmDelete = async () => {\n closeDeleteDialog();\n\n try {\n await announcementsApi.deleteAnnouncementByID(announcementToDelete!.id);\n\n alertApi.post({\n message: t('announcementsPage.grid.announcementDeleted'),\n severity: 'success',\n });\n } catch (err) {\n alertApi.post({ message: (err as Error).message, severity: 'error' });\n }\n\n refresh();\n };\n\n return (\n <>\n <ItemCardGrid>\n {announcements.results.map(announcement => (\n <AnnouncementCard\n key={announcement.id}\n announcement={announcement}\n onDelete={() => openDeleteDialog(announcement)}\n options={{ titleLength: cardTitleLength }}\n hideStartAt={hideStartAt}\n />\n ))}\n </ItemCardGrid>\n\n {announcements && announcements.count !== 0 && (\n <div className={classes.pagination}>\n <Pagination\n count={Math.ceil(announcements.count / maxPerPage)}\n page={page}\n onChange={handleChange}\n />\n </div>\n )}\n\n <DeleteAnnouncementDialog\n open={isDeleteDialogOpen}\n onCancel={onCancelDelete}\n onConfirm={onConfirmDelete}\n />\n </>\n );\n};\n\ntype AnnouncementCardProps = {\n titleLength?: number;\n};\n\ntype AnnouncementCreateButtonProps = {\n name?: string;\n};\n\nexport type AnnouncementsPageProps = {\n themeId: string;\n title: string;\n subtitle?: ReactNode;\n maxPerPage?: number;\n category?: string;\n buttonOptions?: AnnouncementCreateButtonProps;\n cardOptions?: AnnouncementCardProps;\n hideContextMenu?: boolean;\n hideInactive?: boolean;\n hideStartAt?: boolean;\n markdownRenderer?: MarkdownRendererType;\n sortby?: 'created_at' | 'start_at';\n order?: 'asc' | 'desc';\n};\n\nexport const AnnouncementsPage = (props: AnnouncementsPageProps) => {\n const location = useLocation();\n const queryParams = new URLSearchParams(location.search);\n const newAnnouncementLink = useRouteRef(announcementCreateRouteRef);\n const { loading: loadingCreatePermission, allowed: canCreate } =\n usePermission({ permission: announcementCreatePermission });\n const { t } = useAnnouncementsTranslation();\n\n const {\n hideContextMenu,\n hideInactive,\n hideStartAt,\n themeId,\n title,\n subtitle,\n buttonOptions,\n maxPerPage,\n category,\n cardOptions,\n sortby,\n order,\n } = props;\n\n return (\n <Page themeId={themeId}>\n <Header title={title} subtitle={subtitle}>\n {!hideContextMenu && canCreate && <ContextMenu />}\n </Header>\n\n <Content>\n <ContentHeader title=\"\">\n {!loadingCreatePermission && (\n <LinkButton\n disabled={!canCreate}\n to={newAnnouncementLink()}\n color=\"primary\"\n variant=\"contained\"\n >\n {buttonOptions\n ? `${t('announcementsPage.genericNew')} ${buttonOptions.name}`\n : t('announcementsPage.newAnnouncement')}\n </LinkButton>\n )}\n </ContentHeader>\n\n <AnnouncementsGrid\n maxPerPage={maxPerPage ?? 10}\n category={category ?? queryParams.get('category') ?? undefined}\n cardTitleLength={cardOptions?.titleLength}\n active={hideInactive ? true : false}\n sortBy={sortby ?? 'created_at'}\n order={order ?? 'desc'}\n hideStartAt={hideStartAt}\n />\n </Content>\n </Page>\n );\n};\n"],"names":["MoreVertIcon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AnnouncementsPage.esm.js","sources":["../../../src/components/AnnouncementsPage/AnnouncementsPage.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 { MouseEvent, useState, ReactNode } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport {\n announcementCreatePermission,\n announcementUpdatePermission,\n announcementDeletePermission,\n Announcement,\n} from '@backstage-community/plugin-announcements-common';\nimport { DateTime } from 'luxon';\nimport {\n Page,\n Header,\n Content,\n Link,\n ItemCardGrid,\n Progress,\n ContentHeader,\n LinkButton,\n} from '@backstage/core-components';\nimport { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n EntityPeekAheadPopover,\n EntityRefLink,\n} from '@backstage/plugin-catalog-react';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport EditIcon from '@material-ui/icons/Edit';\nimport MoreVertIcon from '@material-ui/icons/MoreVert';\nimport {\n announcementCreateRouteRef,\n announcementEditRouteRef,\n announcementViewRouteRef,\n rootRouteRef,\n} from '../../routes';\nimport { DeleteAnnouncementDialog } from './DeleteAnnouncementDialog';\nimport { useDeleteAnnouncementDialogState } from './useDeleteAnnouncementDialogState';\nimport { ContextMenu } from './ContextMenu';\nimport {\n announcementsApiRef,\n useAnnouncements,\n useAnnouncementsTranslation,\n} from '@backstage-community/plugin-announcements-react';\nimport {\n Box,\n Card,\n CardContent,\n CardHeader,\n Chip,\n IconButton,\n ListItemIcon,\n makeStyles,\n Menu,\n MenuItem,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport { Alert, Pagination } from '@material-ui/lab';\nimport { formatAnnouncementStartTime } from '../utils/announcementDateUtils';\nimport { MarkdownRendererTypeProps } from '../MarkdownRenderer/MarkdownRenderer';\n\nconst useStyles = makeStyles(theme => {\n return {\n cardHeader: {\n color: theme?.palette?.text?.primary || '#000',\n },\n pagination: {\n display: 'flex',\n justifyContent: 'center',\n marginTop: theme?.spacing?.(4) || 32,\n },\n };\n});\n/**\n * Truncate text to a given length and add ellipsis\n * @param text the text to truncate\n * @param length the length to truncate to\n * @returns the truncated text\n */\nconst truncate = (text: string, length: number) => {\n return text.length > length ? `${text.substring(0, length)}...` : text;\n};\n\nconst AnnouncementCard = ({\n announcement,\n onDelete,\n options: { titleLength = 50 },\n hideStartAt,\n}: {\n announcement: Announcement;\n onDelete: () => void;\n options: AnnouncementCardProps;\n hideStartAt?: boolean;\n}) => {\n const classes = useStyles();\n const announcementsLink = useRouteRef(rootRouteRef);\n const viewAnnouncementLink = useRouteRef(announcementViewRouteRef);\n const editAnnouncementLink = useRouteRef(announcementEditRouteRef);\n const { t } = useAnnouncementsTranslation();\n\n const title = (\n <Tooltip\n title={announcement.title}\n disableFocusListener\n data-testid=\"announcement-card-title-tooltip\"\n >\n <Link\n className={classes.cardHeader}\n to={viewAnnouncementLink({ id: announcement.id })}\n >\n {truncate(announcement.title, titleLength)}\n </Link>\n </Tooltip>\n );\n const subTitle = (\n <>\n <Typography variant=\"body2\" color=\"textSecondary\" component=\"span\">\n {t('announcementsPage.card.by')}{' '}\n <EntityPeekAheadPopover\n entityRef={announcement.on_behalf_of || announcement.publisher}\n >\n <EntityRefLink\n entityRef={announcement.on_behalf_of || announcement.publisher}\n hideIcon\n />\n </EntityPeekAheadPopover>\n {announcement.category && (\n <>\n {' '}\n {t('announcementsPage.card.in')}{' '}\n <Link\n to={`${announcementsLink()}?category=${\n announcement.category.slug\n }`}\n >\n {announcement.category.title}\n </Link>\n </>\n )}\n , {DateTime.fromISO(announcement.created_at).toRelative()}\n </Typography>\n <Box>\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 {announcement.tags && announcement.tags.length > 0 && (\n <Typography variant=\"body2\" color=\"textSecondary\">\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 style={{ marginRight: 4, marginBottom: 4 }}\n />\n ))}\n </Box>\n )}\n </Typography>\n )}\n </>\n );\n const { loading: loadingDeletePermission, allowed: canDelete } =\n usePermission({ permission: announcementDeletePermission });\n const { loading: loadingUpdatePermission, allowed: canUpdate } =\n usePermission({ permission: announcementUpdatePermission });\n\n const AnnouncementEditMenu = () => {\n const [open, setOpen] = useState(false);\n const [anchorEl, setAnchorEl] = useState<undefined | HTMLElement>(\n undefined,\n );\n\n const handleOpenEditMenu = (event: MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n setOpen(true);\n };\n\n const handleCloseEditClose = () => {\n setAnchorEl(undefined);\n setOpen(false);\n };\n\n const canShowMenu =\n (!loadingUpdatePermission && canUpdate) ||\n (!loadingDeletePermission && canDelete);\n\n return (\n <>\n {canShowMenu && (\n <IconButton\n data-testid=\"announcement-edit-menu\"\n aria-label=\"more\"\n onClick={handleOpenEditMenu}\n >\n <MoreVertIcon />\n </IconButton>\n )}\n <Menu anchorEl={anchorEl} open={open} onClose={handleCloseEditClose}>\n {!loadingUpdatePermission && canUpdate && (\n <MenuItem\n data-testid=\"edit-announcement\"\n component={LinkButton}\n to={editAnnouncementLink({ id: announcement.id })}\n >\n <ListItemIcon>\n <EditIcon />\n </ListItemIcon>\n {t('announcementsPage.card.edit')}\n </MenuItem>\n )}\n {!loadingDeletePermission && canDelete && (\n <MenuItem onClick={onDelete}>\n <ListItemIcon>\n <DeleteIcon />\n </ListItemIcon>\n {t('announcementsPage.card.delete')}\n </MenuItem>\n )}\n </Menu>\n </>\n );\n };\n\n return (\n <Card>\n <CardHeader\n action={<AnnouncementEditMenu />}\n title={title}\n subheader={subTitle}\n />\n <CardContent>{announcement.excerpt}</CardContent>\n </Card>\n );\n};\n\nconst AnnouncementsGrid = ({\n maxPerPage,\n category,\n cardTitleLength,\n active,\n sortBy,\n order,\n hideStartAt,\n}: {\n maxPerPage: number;\n category?: string;\n cardTitleLength?: number;\n active?: boolean;\n sortBy?: 'created_at' | 'start_at';\n order?: 'asc' | 'desc';\n hideStartAt?: boolean;\n}) => {\n const classes = useStyles();\n const announcementsApi = useApi(announcementsApiRef);\n const alertApi = useApi(alertApiRef);\n\n const [page, setPage] = useState(1);\n const handleChange = (_event: any, value: number) => {\n setPage(value);\n };\n\n const {\n announcements,\n loading,\n error,\n retry: refresh,\n } = useAnnouncements(\n {\n max: maxPerPage,\n page: page,\n category,\n active,\n sortBy,\n order,\n },\n { dependencies: [maxPerPage, page, category] },\n );\n\n const { t } = useAnnouncementsTranslation();\n\n const {\n isOpen: isDeleteDialogOpen,\n open: openDeleteDialog,\n close: closeDeleteDialog,\n announcement: announcementToDelete,\n } = useDeleteAnnouncementDialogState();\n\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n const onCancelDelete = () => {\n closeDeleteDialog();\n };\n const onConfirmDelete = async () => {\n closeDeleteDialog();\n\n try {\n await announcementsApi.deleteAnnouncementByID(announcementToDelete!.id);\n\n alertApi.post({\n message: t('announcementsPage.grid.announcementDeleted'),\n severity: 'success',\n });\n } catch (err) {\n alertApi.post({ message: (err as Error).message, severity: 'error' });\n }\n\n refresh();\n };\n\n return (\n <>\n <ItemCardGrid>\n {announcements.results.map(announcement => (\n <AnnouncementCard\n key={announcement.id}\n announcement={announcement}\n onDelete={() => openDeleteDialog(announcement)}\n options={{ titleLength: cardTitleLength }}\n hideStartAt={hideStartAt}\n />\n ))}\n </ItemCardGrid>\n\n {announcements && announcements.count !== 0 && (\n <div className={classes.pagination}>\n <Pagination\n count={Math.ceil(announcements.count / maxPerPage)}\n page={page}\n onChange={handleChange}\n />\n </div>\n )}\n\n <DeleteAnnouncementDialog\n open={isDeleteDialogOpen}\n onCancel={onCancelDelete}\n onConfirm={onConfirmDelete}\n />\n </>\n );\n};\n\ntype AnnouncementCardProps = {\n titleLength?: number;\n};\n\ntype AnnouncementCreateButtonProps = {\n name?: string;\n};\n\nexport type AnnouncementsPageProps = {\n themeId: string;\n title: string;\n subtitle?: ReactNode;\n maxPerPage?: number;\n category?: string;\n tags?: string[];\n buttonOptions?: AnnouncementCreateButtonProps;\n cardOptions?: AnnouncementCardProps;\n hideContextMenu?: boolean;\n hideInactive?: boolean;\n hideStartAt?: boolean;\n markdownRenderer?: MarkdownRendererTypeProps;\n sortby?: 'created_at' | 'start_at';\n order?: 'asc' | 'desc';\n};\n\nexport const AnnouncementsPage = (props: AnnouncementsPageProps) => {\n const location = useLocation();\n const queryParams = new URLSearchParams(location.search);\n const newAnnouncementLink = useRouteRef(announcementCreateRouteRef);\n const { loading: loadingCreatePermission, allowed: canCreate } =\n usePermission({ permission: announcementCreatePermission });\n const { t } = useAnnouncementsTranslation();\n\n const {\n hideContextMenu,\n hideInactive,\n hideStartAt,\n themeId,\n title,\n subtitle,\n buttonOptions,\n maxPerPage,\n category,\n cardOptions,\n sortby,\n order,\n } = props;\n\n return (\n <Page themeId={themeId}>\n <Header title={title} subtitle={subtitle}>\n {!hideContextMenu && canCreate && <ContextMenu />}\n </Header>\n\n <Content>\n <ContentHeader title=\"\">\n {!loadingCreatePermission && (\n <LinkButton\n disabled={!canCreate}\n to={newAnnouncementLink()}\n color=\"primary\"\n variant=\"contained\"\n >\n {buttonOptions\n ? `${t('announcementsPage.genericNew')} ${buttonOptions.name}`\n : t('announcementsPage.newAnnouncement')}\n </LinkButton>\n )}\n </ContentHeader>\n\n <AnnouncementsGrid\n maxPerPage={maxPerPage ?? 10}\n category={category ?? queryParams.get('category') ?? undefined}\n cardTitleLength={cardOptions?.titleLength}\n active={!!hideInactive}\n sortBy={sortby ?? 'created_at'}\n order={order ?? 'desc'}\n hideStartAt={hideStartAt}\n />\n </Content>\n </Page>\n );\n};\n"],"names":["MoreVertIcon"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { useNavigate } from 'react-router-dom';
|
|
4
4
|
import { useRouteRef } from '@backstage/core-plugin-api';
|
|
5
|
-
import { announcementAdminRouteRef, categoriesListRouteRef } from '../../routes.esm.js';
|
|
5
|
+
import { announcementAdminRouteRef, categoriesListRouteRef, tagsListRouteRef } from '../../routes.esm.js';
|
|
6
6
|
import { useAnnouncementsTranslation } from '@backstage-community/plugin-announcements-react';
|
|
7
7
|
import { makeStyles, Box, IconButton, Popover, MenuList, MenuItem, ListItemIcon, ListItemText } from '@material-ui/core';
|
|
8
8
|
import MoreVert from '@material-ui/icons/MoreVert';
|
|
@@ -18,6 +18,7 @@ function ContextMenu() {
|
|
|
18
18
|
const [anchorEl, setAnchorEl] = useState();
|
|
19
19
|
const announcementsLink = useRouteRef(announcementAdminRouteRef);
|
|
20
20
|
const categoriesLink = useRouteRef(categoriesListRouteRef);
|
|
21
|
+
const tagsLink = useRouteRef(tagsListRouteRef);
|
|
21
22
|
const navigate = useNavigate();
|
|
22
23
|
const { t } = useAnnouncementsTranslation();
|
|
23
24
|
const onOpen = (event) => {
|
|
@@ -61,6 +62,10 @@ function ContextMenu() {
|
|
|
61
62
|
primary: t("announcementsPage.contextMenu.categories")
|
|
62
63
|
}
|
|
63
64
|
)
|
|
65
|
+
] }),
|
|
66
|
+
/* @__PURE__ */ jsxs(MenuItem, { onClick: () => navigate(tagsLink()), children: [
|
|
67
|
+
/* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(Description, { fontSize: "small" }) }),
|
|
68
|
+
/* @__PURE__ */ jsx(ListItemText, { primary: t("announcementsPage.contextMenu.tags") })
|
|
64
69
|
] })
|
|
65
70
|
] })
|
|
66
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu.esm.js","sources":["../../../src/components/AnnouncementsPage/ContextMenu.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 { SyntheticEvent, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport {\n announcementAdminRouteRef,\n categoriesListRouteRef,\n} from '../../routes';\nimport { useAnnouncementsTranslation } from '@backstage-community/plugin-announcements-react';\nimport {\n makeStyles,\n Box,\n IconButton,\n Popover,\n MenuList,\n MenuItem,\n ListItemIcon,\n ListItemText,\n} from '@material-ui/core';\nimport MoreVert from '@material-ui/icons/MoreVert';\nimport Description from '@material-ui/icons/Description';\n\nconst useStyles = makeStyles(theme => ({\n button: {\n color: theme.page.fontColor,\n },\n}));\n\nexport function ContextMenu() {\n const classes = useStyles();\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>();\n const announcementsLink = useRouteRef(announcementAdminRouteRef);\n const categoriesLink = useRouteRef(categoriesListRouteRef);\n const navigate = useNavigate();\n const { t } = useAnnouncementsTranslation();\n\n const onOpen = (event: SyntheticEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n };\n\n const onClose = () => {\n setAnchorEl(undefined);\n };\n\n return (\n <Box data-testid=\"announcements-context-menu\">\n <IconButton\n aria-label=\"more\"\n aria-controls=\"long-menu\"\n aria-haspopup=\"true\"\n onClick={onOpen}\n data-testid=\"menu-button\"\n color=\"inherit\"\n className={classes.button}\n >\n <MoreVert />\n </IconButton>\n <Popover\n open={Boolean(anchorEl)}\n onClose={onClose}\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n >\n <MenuList>\n <MenuItem onClick={() => navigate(announcementsLink())}>\n <ListItemIcon>\n <Description fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={t('announcementsPage.contextMenu.admin')} />\n </MenuItem>\n <MenuItem onClick={() => navigate(categoriesLink())}>\n <ListItemIcon>\n <Description fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText\n primary={t('announcementsPage.contextMenu.categories')}\n />\n </MenuItem>\n </MenuList>\n </Popover>\n </Box>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"ContextMenu.esm.js","sources":["../../../src/components/AnnouncementsPage/ContextMenu.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 { SyntheticEvent, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport {\n announcementAdminRouteRef,\n categoriesListRouteRef,\n tagsListRouteRef,\n} from '../../routes';\nimport { useAnnouncementsTranslation } from '@backstage-community/plugin-announcements-react';\nimport {\n makeStyles,\n Box,\n IconButton,\n Popover,\n MenuList,\n MenuItem,\n ListItemIcon,\n ListItemText,\n} from '@material-ui/core';\nimport MoreVert from '@material-ui/icons/MoreVert';\nimport Description from '@material-ui/icons/Description';\n\nconst useStyles = makeStyles(theme => ({\n button: {\n color: theme.page.fontColor,\n },\n}));\n\nexport function ContextMenu() {\n const classes = useStyles();\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>();\n const announcementsLink = useRouteRef(announcementAdminRouteRef);\n const categoriesLink = useRouteRef(categoriesListRouteRef);\n const tagsLink = useRouteRef(tagsListRouteRef);\n const navigate = useNavigate();\n const { t } = useAnnouncementsTranslation();\n\n const onOpen = (event: SyntheticEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n };\n\n const onClose = () => {\n setAnchorEl(undefined);\n };\n\n return (\n <Box data-testid=\"announcements-context-menu\">\n <IconButton\n aria-label=\"more\"\n aria-controls=\"long-menu\"\n aria-haspopup=\"true\"\n onClick={onOpen}\n data-testid=\"menu-button\"\n color=\"inherit\"\n className={classes.button}\n >\n <MoreVert />\n </IconButton>\n <Popover\n open={Boolean(anchorEl)}\n onClose={onClose}\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n >\n <MenuList>\n <MenuItem onClick={() => navigate(announcementsLink())}>\n <ListItemIcon>\n <Description fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={t('announcementsPage.contextMenu.admin')} />\n </MenuItem>\n <MenuItem onClick={() => navigate(categoriesLink())}>\n <ListItemIcon>\n <Description fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText\n primary={t('announcementsPage.contextMenu.categories')}\n />\n </MenuItem>\n <MenuItem onClick={() => navigate(tagsLink())}>\n <ListItemIcon>\n <Description fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={t('announcementsPage.contextMenu.tags')} />\n </MenuItem>\n </MenuList>\n </Popover>\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownRenderer.esm.js","sources":["../../../src/components/MarkdownRenderer/MarkdownRenderer.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 { MarkdownContent } from '@backstage/core-components';\nimport MDEditor from '@uiw/react-md-editor';\nimport { makeStyles, useTheme } from '@material-ui/core';\n\nexport type
|
|
1
|
+
{"version":3,"file":"MarkdownRenderer.esm.js","sources":["../../../src/components/MarkdownRenderer/MarkdownRenderer.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 { MarkdownContent } from '@backstage/core-components';\nimport MDEditor from '@uiw/react-md-editor';\nimport { makeStyles, useTheme } from '@material-ui/core';\n\n/**\n * @public\n * Use this props to specify which rendering mode the MarkdownRenderer should operate in.\n *\n * - `'backstage'`: Indicates that the renderer should use the Backstage built-in style.\n * - `'md-editor'`: Indicates that the renderer should use the Markdown Editor (WYSIWYG) style.\n *\n */\nexport type MarkdownRendererTypeProps = 'backstage' | 'md-editor';\n\nexport interface MarkdownRendererProps {\n content: string;\n rendererType?: MarkdownRendererTypeProps;\n}\n\n// Custom styles for the MDEditor to match Backstage MUI theme\nconst useStyles = makeStyles(theme => ({\n mdEditor: {\n color: theme.palette.text.primary,\n '& a': {\n color: theme.palette.primary.main,\n },\n '& code': {\n backgroundColor: theme.palette.background.default,\n color: theme.palette.text.primary,\n borderRadius: theme.shape.borderRadius,\n },\n '& pre': {\n backgroundColor: theme.palette.background.default,\n padding: theme.spacing(1),\n borderRadius: theme.shape.borderRadius,\n },\n '& blockquote': {\n paddingLeft: theme.spacing(1),\n color: theme.palette.text.secondary,\n },\n },\n}));\n\nexport const MarkdownRenderer = ({\n content,\n rendererType = 'backstage',\n}: MarkdownRendererProps) => {\n const theme = useTheme();\n const classes = useStyles();\n\n switch (rendererType) {\n case 'md-editor':\n return (\n <MDEditor.Markdown\n source={content}\n className={classes.mdEditor}\n style={{\n backgroundColor: 'transparent',\n color: theme.palette.text.primary,\n fontFamily: theme.typography.fontFamily,\n }}\n />\n );\n case 'backstage':\n default:\n return <MarkdownContent content={content} />;\n }\n};\n"],"names":[],"mappings":";;;;;AAmCA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,QAAU,EAAA;AAAA,IACR,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,OAAA;AAAA,IAC1B,KAAO,EAAA;AAAA,MACL,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,OAAQ,CAAA;AAAA,KAC/B;AAAA,IACA,QAAU,EAAA;AAAA,MACR,eAAA,EAAiB,KAAM,CAAA,OAAA,CAAQ,UAAW,CAAA,OAAA;AAAA,MAC1C,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,OAAA;AAAA,MAC1B,YAAA,EAAc,MAAM,KAAM,CAAA;AAAA,KAC5B;AAAA,IACA,OAAS,EAAA;AAAA,MACP,eAAA,EAAiB,KAAM,CAAA,OAAA,CAAQ,UAAW,CAAA,OAAA;AAAA,MAC1C,OAAA,EAAS,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,MACxB,YAAA,EAAc,MAAM,KAAM,CAAA;AAAA,KAC5B;AAAA,IACA,cAAgB,EAAA;AAAA,MACd,WAAA,EAAa,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,MAC5B,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA;AAAA;AAC5B;AAEJ,CAAE,CAAA,CAAA;AAEK,MAAM,mBAAmB,CAAC;AAAA,EAC/B,OAAA;AAAA,EACA,YAAe,GAAA;AACjB,CAA6B,KAAA;AAC3B,EAAA,MAAM,QAAQ,QAAS,EAAA;AACvB,EAAA,MAAM,UAAU,SAAU,EAAA;AAE1B,EAAA,QAAQ,YAAc;AAAA,IACpB,KAAK,WAAA;AACH,MACE,uBAAA,GAAA;AAAA,QAAC,QAAS,CAAA,QAAA;AAAA,QAAT;AAAA,UACC,MAAQ,EAAA,OAAA;AAAA,UACR,WAAW,OAAQ,CAAA,QAAA;AAAA,UACnB,KAAO,EAAA;AAAA,YACL,eAAiB,EAAA,aAAA;AAAA,YACjB,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,OAAA;AAAA,YAC1B,UAAA,EAAY,MAAM,UAAW,CAAA;AAAA;AAC/B;AAAA,OACF;AAAA,IAEJ,KAAK,WAAA;AAAA,IACL;AACE,MAAO,uBAAA,GAAA,CAAC,mBAAgB,OAAkB,EAAA,CAAA;AAAA;AAEhD;;;;"}
|
|
@@ -108,12 +108,13 @@ const AnnouncementBanner = (props) => {
|
|
|
108
108
|
);
|
|
109
109
|
};
|
|
110
110
|
const NewAnnouncementBanner = (props) => {
|
|
111
|
-
const { max, category, active, variant } = props;
|
|
111
|
+
const { max, category, tags, active, variant } = props;
|
|
112
112
|
const announcementsApi = useApi(announcementsApiRef);
|
|
113
113
|
const [signaledAnnouncement, setSignaledAnnouncement] = useState();
|
|
114
114
|
const { announcements, loading, error } = useAnnouncements({
|
|
115
115
|
max: max ?? 1,
|
|
116
116
|
category,
|
|
117
|
+
tags,
|
|
117
118
|
active
|
|
118
119
|
});
|
|
119
120
|
const lastSeen = announcementsApi.lastSeenDate();
|
|
@@ -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 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\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 AnnouncementBannerProps = {\n announcement: Announcement;\n variant?: 'block' | 'floating';\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\n const handleClick = () => {\n announcementsApi.markLastSeenDate(\n DateTime.fromISO(announcement.created_at),\n );\n setBannerOpen(false);\n };\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 >\n {announcement.title}\n </Link>\n – {announcement.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};\n\nexport const NewAnnouncementBanner = (props: NewAnnouncementBannerProps) => {\n const { max, category, active, variant } = 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 active,\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 />\n ))}\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;AAyCA,MAAM,SAAA,GAAY,WAAW,CAAS,KAAA,KAAA;AACpC,EAAO,OAAA;AAAA;AAAA,IAEL,gBAAkB,EAAA;AAAA,MAChB,OAAS,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,CAAK,IAAA,CAAA;AAAA,MAChC,QAAU,EAAA,UAAA;AAAA,MACV,YAAc,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,CAAK,IAAA,EAAA;AAAA,MACrC,SAAW,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,CAAK,IAAA,CAAA,EAAA;AAAA,MAClC,MAAQ,EAAA;AAAA,KACV;AAAA;AAAA,IAEA,qBAAqB,EAAC;AAAA,IACtB,IAAM,EAAA;AAAA,MACJ,QAAU,EAAA;AAAA,KACZ;AAAA,IACA,UAAY,EAAA;AAAA,MACV,QAAU,EAAA,EAAA;AAAA,MACV,WAAa,EAAA;AAAA,KACf;AAAA,IACA,OAAS,EAAA;AAAA,MACP,KAAO,EAAA,MAAA;AAAA,MACP,QAAU,EAAA,SAAA;AAAA,MACV,QAAU,EAAA,QAAA;AAAA,MACV,eAAiB,EAAA,KAAA,EAAO,OAAS,EAAA,MAAA,EAAQ,IAAQ,IAAA,SAAA;AAAA,MACjD,OAAS,EAAA,MAAA;AAAA,MACT,UAAY,EAAA,QAAA;AAAA,MACZ,KAAO,EAAA,KAAA,EAAO,OAAS,EAAA,MAAA,EAAQ,IAAQ,IAAA,SAAA;AAAA,MACvC,KAAO,EAAA;AAAA,QACL,KAAO,EAAA,KAAA,EAAO,OAAS,EAAA,MAAA,EAAQ,IAAQ,IAAA;AAAA;AACzC;AACF,GACF;AACF,CAAC,CAAA;AAOD,MAAM,kBAAA,GAAqB,CAAC,KAAmC,KAAA;AAC7D,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAM,MAAA,gBAAA,GAAmB,OAAO,mBAAmB,CAAA;AACnD,EAAM,MAAA,oBAAA,GAAuB,YAAY,wBAAwB,CAAA;AACjE,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,2BAA4B,EAAA;AAC1C,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,IAAI,CAAA;AACjD,EAAM,MAAA,OAAA,GAAU,MAAM,OAAW,IAAA,OAAA;AACjC,EAAA,MAAM,eAAe,KAAM,CAAA,YAAA;AAE3B,EAAA,MAAM,cAAc,MAAM;AACxB,IAAiB,gBAAA,CAAA,gBAAA;AAAA,MACf,QAAA,CAAS,OAAQ,CAAA,YAAA,CAAa,UAAU;AAAA,KAC1C;AACA,IAAA,aAAA,CAAc,KAAK,CAAA;AAAA,GACrB;AAEA,EAAA,MAAM,0BAEF,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,SAAU,EAAA,MAAA;AAAA,QACV,WAAW,OAAQ,CAAA,UAAA;AAAA,QACnB,OAAQ,EAAA,SAAA;AAAA,QACT,QAAA,EAAA;AAAA;AAAA,KAED;AAAA,oBACA,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,IAAI,oBAAqB,CAAA,EAAE,EAAI,EAAA,YAAA,CAAa,IAAI,CAAA;AAAA,QAChD,OAAQ,EAAA,SAAA;AAAA,QAEP,QAAa,EAAA,YAAA,CAAA;AAAA;AAAA,KAChB;AAAA,IAAO,aAAA;AAAA,IACE,YAAa,CAAA;AAAA,GACxB,EAAA,CAAA;AAGF,EACE,uBAAA,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,YAAc,EAAA,EAAE,QAAU,EAAA,KAAA,EAAO,YAAY,QAAS,EAAA;AAAA,MACtD,IAAM,EAAA,UAAA;AAAA,MACN,SACE,EAAA,OAAA,KAAY,OACR,GAAA,OAAA,CAAQ,mBACR,OAAQ,CAAA,mBAAA;AAAA,MAGd,QAAA,kBAAA,GAAA;AAAA,QAAC,eAAA;AAAA,QAAA;AAAA,UACC,WAAW,OAAQ,CAAA,OAAA;AAAA,UACnB,OAAA;AAAA,UACA,MAAQ,EAAA;AAAA,4BACN,GAAA;AAAA,cAAC,UAAA;AAAA,cAAA;AAAA,gBAEC,KAAA,EAAO,EAAE,kCAAkC,CAAA;AAAA,gBAC3C,KAAM,EAAA,SAAA;AAAA,gBACN,OAAS,EAAA,WAAA;AAAA,gBAET,QAAC,kBAAA,GAAA,CAAA,KAAA,EAAA,EAAM,SAAW,EAAA,OAAA,CAAQ,IAAM,EAAA;AAAA,eAAA;AAAA,cAL5B;AAAA;AAMN;AACF;AAAA;AACF;AAAA,GACF;AAEJ,CAAA;
|
|
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 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\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 AnnouncementBannerProps = {\n announcement: Announcement;\n variant?: 'block' | 'floating';\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\n const handleClick = () => {\n announcementsApi.markLastSeenDate(\n DateTime.fromISO(announcement.created_at),\n );\n setBannerOpen(false);\n };\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 >\n {announcement.title}\n </Link>\n – {announcement.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 tags?: string[];\n};\n\nexport const NewAnnouncementBanner = (props: NewAnnouncementBannerProps) => {\n const { max, category, tags, active, variant } = 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 });\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 />\n ))}\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,7 @@ import 'react-use/esm/useAsync';
|
|
|
24
24
|
import '@backstage/catalog-model';
|
|
25
25
|
import '@mui/material/Box';
|
|
26
26
|
import '@mui/material/Typography';
|
|
27
|
+
import './AnnouncementForm/TagsInput.esm.js';
|
|
27
28
|
import '@material-ui/icons/SaveAlt';
|
|
28
29
|
import 'luxon';
|
|
29
30
|
import 'slugify';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Router.esm.js","sources":["../../src/components/Router.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 { Routes, Route } from 'react-router-dom';\nimport { RequirePermission } from '@backstage/plugin-permission-react';\nimport {\n announcementCreatePermission,\n announcementUpdatePermission,\n} from '@backstage-community/plugin-announcements-common';\nimport {\n announcementAdminRouteRef,\n announcementCreateRouteRef,\n announcementEditRouteRef,\n announcementViewRouteRef,\n categoriesListRouteRef,\n} from '../routes';\nimport { AnnouncementsPage, AnnouncementsPageProps } from './AnnouncementsPage';\nimport { AnnouncementPage } from './AnnouncementPage';\nimport { CreateAnnouncementPage } from './CreateAnnouncementPage';\nimport { EditAnnouncementPage } from './EditAnnouncementPage';\nimport { CategoriesPage } from './CategoriesPage';\nimport { AdminPortal } from './Admin';\n\ntype RouterProps = {\n themeId?: string;\n title?: string;\n subtitle?: string;\n category?: string;\n hideContextMenu?: boolean;\n cardOptions?: {\n titleLength: number | undefined;\n };\n buttonOptions?: {\n name: string | undefined;\n };\n hideInactive?: boolean;\n hideStartAt?: boolean;\n};\n\nexport const Router = (props: RouterProps) => {\n const propsWithDefaults: AnnouncementsPageProps = {\n themeId: 'home',\n title: 'Announcements',\n hideInactive: false,\n hideStartAt: false,\n markdownRenderer: 'backstage',\n ...props,\n };\n\n return (\n <Routes>\n <Route path=\"/\" element={<AnnouncementsPage {...propsWithDefaults} />} />\n <Route\n path={`${announcementViewRouteRef.path}`}\n element={<AnnouncementPage {...propsWithDefaults} />}\n />\n <Route\n path={`${announcementCreateRouteRef.path}`}\n element={\n <RequirePermission permission={announcementCreatePermission}>\n <CreateAnnouncementPage {...propsWithDefaults} />\n </RequirePermission>\n }\n />\n <Route\n path={`${announcementEditRouteRef.path}`}\n element={\n <RequirePermission permission={announcementUpdatePermission}>\n <EditAnnouncementPage {...propsWithDefaults} />\n </RequirePermission>\n }\n />\n <Route\n path={`${announcementAdminRouteRef.path}`}\n element={\n <RequirePermission permission={announcementCreatePermission}>\n <AdminPortal />\n </RequirePermission>\n }\n />\n\n <Route\n path={`${categoriesListRouteRef.path}`}\n element={<CategoriesPage themeId={propsWithDefaults.themeId} />}\n />\n </Routes>\n );\n};\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Router.esm.js","sources":["../../src/components/Router.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 { Routes, Route } from 'react-router-dom';\nimport { RequirePermission } from '@backstage/plugin-permission-react';\nimport {\n announcementCreatePermission,\n announcementUpdatePermission,\n} from '@backstage-community/plugin-announcements-common';\nimport {\n announcementAdminRouteRef,\n announcementCreateRouteRef,\n announcementEditRouteRef,\n announcementViewRouteRef,\n categoriesListRouteRef,\n} from '../routes';\nimport { AnnouncementsPage, AnnouncementsPageProps } from './AnnouncementsPage';\nimport { AnnouncementPage } from './AnnouncementPage';\nimport { CreateAnnouncementPage } from './CreateAnnouncementPage';\nimport { EditAnnouncementPage } from './EditAnnouncementPage';\nimport { CategoriesPage } from './CategoriesPage';\nimport { AdminPortal } from './Admin';\nimport { MarkdownRendererTypeProps } from './MarkdownRenderer';\n\ntype RouterProps = {\n themeId?: string;\n title?: string;\n subtitle?: string;\n category?: string;\n hideContextMenu?: boolean;\n cardOptions?: {\n titleLength: number | undefined;\n };\n buttonOptions?: {\n name: string | undefined;\n };\n hideInactive?: boolean;\n hideStartAt?: boolean;\n markdownRenderer?: MarkdownRendererTypeProps;\n};\n\nexport const Router = (props: RouterProps) => {\n const propsWithDefaults: AnnouncementsPageProps = {\n themeId: 'home',\n title: 'Announcements',\n hideInactive: false,\n hideStartAt: false,\n markdownRenderer: 'backstage',\n ...props,\n };\n\n return (\n <Routes>\n <Route path=\"/\" element={<AnnouncementsPage {...propsWithDefaults} />} />\n <Route\n path={`${announcementViewRouteRef.path}`}\n element={<AnnouncementPage {...propsWithDefaults} />}\n />\n <Route\n path={`${announcementCreateRouteRef.path}`}\n element={\n <RequirePermission permission={announcementCreatePermission}>\n <CreateAnnouncementPage {...propsWithDefaults} />\n </RequirePermission>\n }\n />\n <Route\n path={`${announcementEditRouteRef.path}`}\n element={\n <RequirePermission permission={announcementUpdatePermission}>\n <EditAnnouncementPage {...propsWithDefaults} />\n </RequirePermission>\n }\n />\n <Route\n path={`${announcementAdminRouteRef.path}`}\n element={\n <RequirePermission permission={announcementCreatePermission}>\n <AdminPortal />\n </RequirePermission>\n }\n />\n\n <Route\n path={`${categoriesListRouteRef.path}`}\n element={<CategoriesPage themeId={propsWithDefaults.themeId} />}\n />\n </Routes>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDa,MAAA,MAAA,GAAS,CAAC,KAAuB,KAAA;AAC5C,EAAA,MAAM,iBAA4C,GAAA;AAAA,IAChD,OAAS,EAAA,MAAA;AAAA,IACT,KAAO,EAAA,eAAA;AAAA,IACP,YAAc,EAAA,KAAA;AAAA,IACd,WAAa,EAAA,KAAA;AAAA,IACb,gBAAkB,EAAA,WAAA;AAAA,IAClB,GAAG;AAAA,GACL;AAEA,EAAA,4BACG,MACC,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAC,GAAA,CAAA,KAAA,EAAA,EAAM,MAAK,GAAI,EAAA,OAAA,sBAAU,iBAAmB,EAAA,EAAA,GAAG,mBAAmB,CAAI,EAAA,CAAA;AAAA,oBACvE,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,CAAG,EAAA,wBAAA,CAAyB,IAAI,CAAA,CAAA;AAAA,QACtC,OAAS,kBAAA,GAAA,CAAC,gBAAkB,EAAA,EAAA,GAAG,iBAAmB,EAAA;AAAA;AAAA,KACpD;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,CAAG,EAAA,0BAAA,CAA2B,IAAI,CAAA,CAAA;AAAA,QACxC,OAAA,sBACG,iBAAkB,EAAA,EAAA,UAAA,EAAY,8BAC7B,QAAC,kBAAA,GAAA,CAAA,sBAAA,EAAA,EAAwB,GAAG,iBAAA,EAAmB,CACjD,EAAA;AAAA;AAAA,KAEJ;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,CAAG,EAAA,wBAAA,CAAyB,IAAI,CAAA,CAAA;AAAA,QACtC,OAAA,sBACG,iBAAkB,EAAA,EAAA,UAAA,EAAY,8BAC7B,QAAC,kBAAA,GAAA,CAAA,oBAAA,EAAA,EAAsB,GAAG,iBAAA,EAAmB,CAC/C,EAAA;AAAA;AAAA,KAEJ;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,CAAG,EAAA,yBAAA,CAA0B,IAAI,CAAA,CAAA;AAAA,QACvC,yBACG,GAAA,CAAA,iBAAA,EAAA,EAAkB,YAAY,4BAC7B,EAAA,QAAA,kBAAA,GAAA,CAAC,eAAY,CACf,EAAA;AAAA;AAAA,KAEJ;AAAA,oBAEA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,CAAG,EAAA,sBAAA,CAAuB,IAAI,CAAA,CAAA;AAAA,QACpC,OAAS,kBAAA,GAAA,CAAC,cAAe,EAAA,EAAA,OAAA,EAAS,kBAAkB,OAAS,EAAA;AAAA;AAAA;AAC/D,GACF,EAAA,CAAA;AAEJ;;;;"}
|