@backstage/plugin-catalog-unprocessed-entities 0.0.0-nightly-20230531023430
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 +31 -0
- package/README.md +29 -0
- package/dist/esm/UnprocessedEntities-16922014.esm.js +218 -0
- package/dist/esm/UnprocessedEntities-16922014.esm.js.map +1 -0
- package/dist/esm/index-a9a60a39.esm.js +58 -0
- package/dist/esm/index-a9a60a39.esm.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.esm.js +4 -0
- package/dist/index.esm.js.map +1 -0
- package/package.json +54 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# @backstage/plugin-catalog-unprocessed-entities
|
|
2
|
+
|
|
3
|
+
## 0.0.0-nightly-20230531023430
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- d44fcd9829c2: Added a new plugin to expose entities which are unprocessed or have errors processing
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @backstage/errors@0.0.0-nightly-20230531023430
|
|
13
|
+
- @backstage/core-components@0.0.0-nightly-20230531023430
|
|
14
|
+
- @backstage/catalog-model@0.0.0-nightly-20230531023430
|
|
15
|
+
- @backstage/core-plugin-api@0.0.0-nightly-20230531023430
|
|
16
|
+
- @backstage/theme@0.0.0-nightly-20230531023430
|
|
17
|
+
|
|
18
|
+
## 0.1.0-next.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- d44fcd9829c2: Added a new plugin to expose entities which are unprocessed or have errors processing
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
- @backstage/errors@1.2.0-next.0
|
|
28
|
+
- @backstage/core-components@0.13.2-next.1
|
|
29
|
+
- @backstage/catalog-model@1.4.0-next.0
|
|
30
|
+
- @backstage/core-plugin-api@1.5.2-next.0
|
|
31
|
+
- @backstage/theme@0.4.0-next.0
|
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# catalog-unprocessed-entities
|
|
2
|
+
|
|
3
|
+
Frontend plugin to view unprocessed entities.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
Requires the `@backstage/plugin-catalog-backend-module-unprocessed` module to be installed.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Import into your App.tsx and include into the `<FlatRoutes>` component:
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { CatalogUnprocessedEntitiesPage } from '@backstage/plugin-catalog-unprocessed-entities';
|
|
15
|
+
//...
|
|
16
|
+
|
|
17
|
+
<Route
|
|
18
|
+
path="/catalog-unprocessed-entities"
|
|
19
|
+
element={<CatalogUnprocessedEntitiesPage />}
|
|
20
|
+
/>;
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Getting started
|
|
24
|
+
|
|
25
|
+
Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/catalog-unprocessed-entities](http://localhost:3000/catalog-unprocessed-entities).
|
|
26
|
+
|
|
27
|
+
You can also serve the plugin in isolation by running `yarn start` in the plugin directory.
|
|
28
|
+
This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads.
|
|
29
|
+
It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory.
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { CodeSnippet, Progress, ErrorPanel, Table, MarkdownContent, Content, Page, Header } from '@backstage/core-components';
|
|
3
|
+
import { makeStyles as makeStyles$1, Typography, Box, Tab } from '@material-ui/core';
|
|
4
|
+
import { TabContext, TabList, TabPanel } from '@material-ui/lab';
|
|
5
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
6
|
+
import Dialog from '@material-ui/core/Dialog';
|
|
7
|
+
import DialogContent from '@material-ui/core/DialogContent';
|
|
8
|
+
import DialogTitle from '@material-ui/core/DialogTitle';
|
|
9
|
+
import IconButton from '@material-ui/core/IconButton';
|
|
10
|
+
import { makeStyles, createStyles } from '@material-ui/core/styles';
|
|
11
|
+
import CloseIcon from '@material-ui/icons/Close';
|
|
12
|
+
import DescriptionIcon from '@material-ui/icons/Description';
|
|
13
|
+
import { c as catalogUnprocessedEntitiesApiRef } from './index-a9a60a39.esm.js';
|
|
14
|
+
import useAsync from 'react-use/lib/useAsync';
|
|
15
|
+
import '@backstage/errors';
|
|
16
|
+
|
|
17
|
+
const useStyles$2 = makeStyles(
|
|
18
|
+
(theme) => createStyles({
|
|
19
|
+
closeButton: {
|
|
20
|
+
position: "absolute",
|
|
21
|
+
right: theme.spacing(1),
|
|
22
|
+
top: theme.spacing(1),
|
|
23
|
+
color: theme.palette.grey[500]
|
|
24
|
+
},
|
|
25
|
+
entity: {
|
|
26
|
+
overflow: "scroll",
|
|
27
|
+
width: "100%"
|
|
28
|
+
},
|
|
29
|
+
codeBox: {
|
|
30
|
+
border: "1px solid black",
|
|
31
|
+
padding: "1em"
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
);
|
|
35
|
+
const EntityDialog = ({ entity }) => {
|
|
36
|
+
const [open, setOpen] = useState(false);
|
|
37
|
+
const classes = useStyles$2();
|
|
38
|
+
const openDialog = () => {
|
|
39
|
+
setOpen(true);
|
|
40
|
+
};
|
|
41
|
+
const closeDialog = () => {
|
|
42
|
+
setOpen(false);
|
|
43
|
+
};
|
|
44
|
+
const dialogContent = () => {
|
|
45
|
+
return /* @__PURE__ */ React.createElement(
|
|
46
|
+
CodeSnippet,
|
|
47
|
+
{
|
|
48
|
+
language: "json",
|
|
49
|
+
showLineNumbers: true,
|
|
50
|
+
text: JSON.stringify(entity, null, 4)
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(IconButton, { color: "primary", onClick: openDialog }, /* @__PURE__ */ React.createElement(DescriptionIcon, null)), /* @__PURE__ */ React.createElement(Dialog, { fullWidth: true, open, onClose: closeDialog }, /* @__PURE__ */ React.createElement(DialogTitle, { id: "dialog-title" }, /* @__PURE__ */ React.createElement(
|
|
55
|
+
IconButton,
|
|
56
|
+
{
|
|
57
|
+
"aria-label": "close",
|
|
58
|
+
className: classes.closeButton,
|
|
59
|
+
onClick: closeDialog
|
|
60
|
+
},
|
|
61
|
+
/* @__PURE__ */ React.createElement(CloseIcon, null)
|
|
62
|
+
)), /* @__PURE__ */ React.createElement(DialogContent, null, dialogContent())));
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const useStyles$1 = makeStyles$1((theme) => ({
|
|
66
|
+
errorBox: {
|
|
67
|
+
color: theme.palette.status.error,
|
|
68
|
+
backgroundColor: theme.palette.errorBackground,
|
|
69
|
+
padding: "1em",
|
|
70
|
+
margin: "1em",
|
|
71
|
+
border: `1px solid ${theme.palette.status.error}`
|
|
72
|
+
},
|
|
73
|
+
errorTitle: {
|
|
74
|
+
width: "100%",
|
|
75
|
+
fontWeight: "bold"
|
|
76
|
+
},
|
|
77
|
+
successMessage: {
|
|
78
|
+
background: theme.palette.infoBackground,
|
|
79
|
+
color: theme.palette.infoText
|
|
80
|
+
}
|
|
81
|
+
}));
|
|
82
|
+
const RenderErrorContext = ({
|
|
83
|
+
error,
|
|
84
|
+
rowData
|
|
85
|
+
}) => {
|
|
86
|
+
var _a;
|
|
87
|
+
if (error.message.includes("tags.")) {
|
|
88
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Typography, null, "Tags"), /* @__PURE__ */ React.createElement("ul", null, (_a = rowData.unprocessed_entity.metadata.tags) == null ? void 0 : _a.map((t) => /* @__PURE__ */ React.createElement("li", null, t))));
|
|
89
|
+
}
|
|
90
|
+
if (error.message.includes("metadata.name")) {
|
|
91
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Typography, null, "Name"), /* @__PURE__ */ React.createElement(Typography, { variant: "caption" }, rowData.unprocessed_entity.metadata.name));
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
};
|
|
95
|
+
const FailedEntities = () => {
|
|
96
|
+
const classes = useStyles$1();
|
|
97
|
+
const unprocessedApi = useApi(catalogUnprocessedEntitiesApiRef);
|
|
98
|
+
const {
|
|
99
|
+
loading,
|
|
100
|
+
error,
|
|
101
|
+
value: data
|
|
102
|
+
} = useAsync(async () => await unprocessedApi.failed());
|
|
103
|
+
if (loading) {
|
|
104
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
105
|
+
}
|
|
106
|
+
if (error) {
|
|
107
|
+
return /* @__PURE__ */ React.createElement(ErrorPanel, { error });
|
|
108
|
+
}
|
|
109
|
+
const columns = [
|
|
110
|
+
{
|
|
111
|
+
title: /* @__PURE__ */ React.createElement(Typography, null, "entityRef"),
|
|
112
|
+
render: (rowData) => rowData.entity_ref
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
title: /* @__PURE__ */ React.createElement(Typography, null, "Kind"),
|
|
116
|
+
render: (rowData) => rowData.unprocessed_entity.kind
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
title: /* @__PURE__ */ React.createElement(Typography, null, "Owner"),
|
|
120
|
+
render: (rowData) => {
|
|
121
|
+
var _a;
|
|
122
|
+
return ((_a = rowData.unprocessed_entity.spec) == null ? void 0 : _a.owner) || "unknown";
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
title: /* @__PURE__ */ React.createElement(Typography, null, "Raw"),
|
|
127
|
+
render: (rowData) => /* @__PURE__ */ React.createElement(EntityDialog, { entity: rowData })
|
|
128
|
+
}
|
|
129
|
+
];
|
|
130
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
131
|
+
Table,
|
|
132
|
+
{
|
|
133
|
+
options: { pageSize: 40, search: true },
|
|
134
|
+
columns,
|
|
135
|
+
data: (data == null ? void 0 : data.entities) || [],
|
|
136
|
+
emptyContent: /* @__PURE__ */ React.createElement(Typography, { className: classes.successMessage }, "No failed entities found"),
|
|
137
|
+
detailPanel: ({ rowData }) => {
|
|
138
|
+
const errors = rowData.errors;
|
|
139
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, errors == null ? void 0 : errors.map((e) => {
|
|
140
|
+
return /* @__PURE__ */ React.createElement(Box, { className: classes.errorBox }, /* @__PURE__ */ React.createElement(Typography, { className: classes.errorTitle }, e.name), /* @__PURE__ */ React.createElement(MarkdownContent, { content: e.message }), /* @__PURE__ */ React.createElement(
|
|
141
|
+
RenderErrorContext,
|
|
142
|
+
{
|
|
143
|
+
error: e,
|
|
144
|
+
rowData
|
|
145
|
+
}
|
|
146
|
+
));
|
|
147
|
+
}));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
));
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const useStyles = makeStyles$1((theme) => ({
|
|
154
|
+
successMessage: {
|
|
155
|
+
background: theme.palette.infoBackground,
|
|
156
|
+
color: theme.palette.infoText,
|
|
157
|
+
padding: theme.spacing(2)
|
|
158
|
+
}
|
|
159
|
+
}));
|
|
160
|
+
const PendingEntities = () => {
|
|
161
|
+
const classes = useStyles();
|
|
162
|
+
const unprocessedApi = useApi(catalogUnprocessedEntitiesApiRef);
|
|
163
|
+
const {
|
|
164
|
+
loading,
|
|
165
|
+
error,
|
|
166
|
+
value: data
|
|
167
|
+
} = useAsync(async () => await unprocessedApi.pending());
|
|
168
|
+
if (loading) {
|
|
169
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
170
|
+
}
|
|
171
|
+
if (error) {
|
|
172
|
+
return /* @__PURE__ */ React.createElement(ErrorPanel, { error });
|
|
173
|
+
}
|
|
174
|
+
const columns = [
|
|
175
|
+
{
|
|
176
|
+
title: /* @__PURE__ */ React.createElement(Typography, null, "entityRef"),
|
|
177
|
+
render: (rowData) => rowData.entity_ref
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
title: /* @__PURE__ */ React.createElement(Typography, null, "Kind"),
|
|
181
|
+
render: (rowData) => rowData.unprocessed_entity.kind
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
title: /* @__PURE__ */ React.createElement(Typography, null, "Owner"),
|
|
185
|
+
render: (rowData) => {
|
|
186
|
+
var _a;
|
|
187
|
+
return ((_a = rowData.unprocessed_entity.spec) == null ? void 0 : _a.owner) || "unknown";
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
title: /* @__PURE__ */ React.createElement(Typography, null, "Raw"),
|
|
192
|
+
render: (rowData) => /* @__PURE__ */ React.createElement(EntityDialog, { entity: rowData })
|
|
193
|
+
}
|
|
194
|
+
];
|
|
195
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
196
|
+
Table,
|
|
197
|
+
{
|
|
198
|
+
options: { pageSize: 40 },
|
|
199
|
+
columns,
|
|
200
|
+
data: (data == null ? void 0 : data.entities) || [],
|
|
201
|
+
emptyContent: /* @__PURE__ */ React.createElement(Typography, { className: classes.successMessage }, "No pending entities found")
|
|
202
|
+
}
|
|
203
|
+
));
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const UnprocessedEntitiesContent = () => {
|
|
207
|
+
const [tab, setTab] = useState("failed");
|
|
208
|
+
const handleChange = (_event, tabValue) => {
|
|
209
|
+
setTab(tabValue);
|
|
210
|
+
};
|
|
211
|
+
return /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(TabContext, { value: tab }, /* @__PURE__ */ React.createElement(TabList, { onChange: handleChange }, /* @__PURE__ */ React.createElement(Tab, { label: "Failed", value: "failed" }), /* @__PURE__ */ React.createElement(Tab, { label: "Pending", value: "pending" })), /* @__PURE__ */ React.createElement(TabPanel, { value: "failed" }, /* @__PURE__ */ React.createElement(FailedEntities, null)), /* @__PURE__ */ React.createElement(TabPanel, { value: "pending" }, /* @__PURE__ */ React.createElement(PendingEntities, null))));
|
|
212
|
+
};
|
|
213
|
+
const UnprocessedEntities = () => {
|
|
214
|
+
return /* @__PURE__ */ React.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React.createElement(Header, { title: "Unprocessed Entitites" }), /* @__PURE__ */ React.createElement(UnprocessedEntitiesContent, null));
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export { UnprocessedEntities, UnprocessedEntitiesContent };
|
|
218
|
+
//# sourceMappingURL=UnprocessedEntities-16922014.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnprocessedEntities-16922014.esm.js","sources":["../../src/components/EntityDialog.tsx","../../src/components/FailedEntities.tsx","../../src/components/PendingEntities.tsx","../../src/components/UnprocessedEntities.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { useState } from 'react';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport IconButton from '@material-ui/core/IconButton';\nimport { makeStyles, createStyles, Theme } from '@material-ui/core/styles';\nimport CloseIcon from '@material-ui/icons/Close';\nimport DescriptionIcon from '@material-ui/icons/Description';\n\nimport { UnprocessedEntity } from './../types';\nimport { CodeSnippet } from '@backstage/core-components';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n closeButton: {\n position: 'absolute',\n right: theme.spacing(1),\n top: theme.spacing(1),\n color: theme.palette.grey[500],\n },\n entity: {\n overflow: 'scroll',\n width: '100%',\n },\n codeBox: {\n border: '1px solid black',\n padding: '1em',\n },\n }),\n);\n\nexport const EntityDialog = ({ entity }: { entity: UnprocessedEntity }) => {\n const [open, setOpen] = useState(false);\n const classes = useStyles();\n\n const openDialog = () => {\n setOpen(true);\n };\n\n const closeDialog = () => {\n setOpen(false);\n };\n\n const dialogContent = () => {\n return (\n <CodeSnippet\n language=\"json\"\n showLineNumbers\n text={JSON.stringify(entity, null, 4)}\n />\n );\n };\n\n return (\n <>\n <IconButton color=\"primary\" onClick={openDialog}>\n <DescriptionIcon />\n </IconButton>\n <Dialog fullWidth open={open} onClose={closeDialog}>\n <DialogTitle id=\"dialog-title\">\n <IconButton\n aria-label=\"close\"\n className={classes.closeButton}\n onClick={closeDialog}\n >\n <CloseIcon />\n </IconButton>\n </DialogTitle>\n <DialogContent>{dialogContent()}</DialogContent>\n </Dialog>\n </>\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\n\nimport {\n ErrorPanel,\n MarkdownContent,\n Progress,\n Table,\n TableColumn,\n} from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { BackstageThemeOptions } from '@backstage/theme';\nimport { Box, Typography, makeStyles } from '@material-ui/core';\n\nimport { UnprocessedEntity } from '../types';\nimport { EntityDialog } from './EntityDialog';\nimport { catalogUnprocessedEntitiesApiRef } from '../api';\nimport useAsync from 'react-use/lib/useAsync';\n\nconst useStyles = makeStyles((theme: BackstageThemeOptions) => ({\n errorBox: {\n color: theme.palette.status.error,\n backgroundColor: theme.palette.errorBackground,\n padding: '1em',\n margin: '1em',\n border: `1px solid ${theme.palette.status.error}`,\n },\n errorTitle: {\n width: '100%',\n fontWeight: 'bold',\n },\n successMessage: {\n background: theme.palette.infoBackground,\n color: theme.palette.infoText,\n },\n}));\n\nconst RenderErrorContext = ({\n error,\n rowData,\n}: {\n error: { message: string };\n rowData: UnprocessedEntity;\n}) => {\n if (error.message.includes('tags.')) {\n return (\n <>\n <Typography>Tags</Typography>\n <ul>\n {rowData.unprocessed_entity.metadata.tags?.map(t => (\n <li>{t}</li>\n ))}\n </ul>\n </>\n );\n }\n\n if (error.message.includes('metadata.name')) {\n return (\n <>\n <Typography>Name</Typography>\n <Typography variant=\"caption\">\n {rowData.unprocessed_entity.metadata.name}\n </Typography>\n </>\n );\n }\n\n return null;\n};\n\nexport const FailedEntities = () => {\n const classes = useStyles();\n const unprocessedApi = useApi(catalogUnprocessedEntitiesApiRef);\n const {\n loading,\n error,\n value: data,\n } = useAsync(async () => await unprocessedApi.failed());\n\n if (loading) {\n return <Progress />;\n }\n if (error) {\n return <ErrorPanel error={error} />;\n }\n\n const columns: TableColumn[] = [\n {\n title: <Typography>entityRef</Typography>,\n render: (rowData: UnprocessedEntity | {}) =>\n (rowData as UnprocessedEntity).entity_ref,\n },\n {\n title: <Typography>Kind</Typography>,\n render: (rowData: UnprocessedEntity | {}) =>\n (rowData as UnprocessedEntity).unprocessed_entity.kind,\n },\n {\n title: <Typography>Owner</Typography>,\n render: (rowData: UnprocessedEntity | {}) =>\n (rowData as UnprocessedEntity).unprocessed_entity.spec?.owner ||\n 'unknown',\n },\n {\n title: <Typography>Raw</Typography>,\n render: (rowData: UnprocessedEntity | {}) => (\n <EntityDialog entity={rowData as UnprocessedEntity} />\n ),\n },\n ];\n return (\n <>\n <Table\n options={{ pageSize: 40, search: true }}\n columns={columns}\n data={data?.entities || []}\n emptyContent={\n <Typography className={classes.successMessage}>\n No failed entities found\n </Typography>\n }\n detailPanel={({ rowData }) => {\n const errors = (rowData as UnprocessedEntity).errors;\n return (\n <>\n {errors?.map(e => {\n return (\n <Box className={classes.errorBox}>\n <Typography className={classes.errorTitle}>\n {e.name}\n </Typography>\n <MarkdownContent content={e.message} />\n <RenderErrorContext\n error={e}\n rowData={rowData as UnprocessedEntity}\n />\n </Box>\n );\n })}\n </>\n );\n }}\n />\n </>\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\n\nimport {\n ErrorPanel,\n Progress,\n TableColumn,\n Table,\n} from '@backstage/core-components';\nimport { Typography, makeStyles } from '@material-ui/core';\n\nimport { UnprocessedEntity } from '../types';\n\nimport { EntityDialog } from './EntityDialog';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\nimport { catalogUnprocessedEntitiesApiRef } from '../api';\nimport { BackstageTheme } from '@backstage/theme';\n\nconst useStyles = makeStyles((theme: BackstageTheme) => ({\n successMessage: {\n background: theme.palette.infoBackground,\n color: theme.palette.infoText,\n padding: theme.spacing(2),\n },\n}));\n\nexport const PendingEntities = () => {\n const classes = useStyles();\n const unprocessedApi = useApi(catalogUnprocessedEntitiesApiRef);\n const {\n loading,\n error,\n value: data,\n } = useAsync(async () => await unprocessedApi.pending());\n\n if (loading) {\n return <Progress />;\n }\n if (error) {\n return <ErrorPanel error={error} />;\n }\n\n const columns: TableColumn[] = [\n {\n title: <Typography>entityRef</Typography>,\n render: (rowData: UnprocessedEntity | {}) =>\n (rowData as UnprocessedEntity).entity_ref,\n },\n {\n title: <Typography>Kind</Typography>,\n render: (rowData: UnprocessedEntity | {}) =>\n (rowData as UnprocessedEntity).unprocessed_entity.kind,\n },\n {\n title: <Typography>Owner</Typography>,\n render: (rowData: UnprocessedEntity | {}) =>\n (rowData as UnprocessedEntity).unprocessed_entity.spec?.owner ||\n 'unknown',\n },\n {\n title: <Typography>Raw</Typography>,\n render: (rowData: UnprocessedEntity | {}) => (\n <EntityDialog entity={rowData as UnprocessedEntity} />\n ),\n },\n ];\n return (\n <>\n <Table\n options={{ pageSize: 40 }}\n columns={columns}\n data={data?.entities || []}\n emptyContent={\n <Typography className={classes.successMessage}>\n No pending entities found\n </Typography>\n }\n />\n </>\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { useState } from 'react';\n\nimport { Page, Header, Content } from '@backstage/core-components';\nimport { Tab } from '@material-ui/core';\nimport { TabContext, TabList, TabPanel } from '@material-ui/lab';\n\nimport { FailedEntities } from './FailedEntities';\nimport { PendingEntities } from './PendingEntities';\n\nexport const UnprocessedEntitiesContent = () => {\n const [tab, setTab] = useState('failed');\n const handleChange = (_event: React.ChangeEvent<{}>, tabValue: string) => {\n setTab(tabValue);\n };\n\n return (\n <Content>\n <TabContext value={tab}>\n <TabList onChange={handleChange}>\n <Tab label=\"Failed\" value=\"failed\" />\n <Tab label=\"Pending\" value=\"pending\" />\n </TabList>\n <TabPanel value=\"failed\">\n <FailedEntities />\n </TabPanel>\n <TabPanel value=\"pending\">\n <PendingEntities />\n </TabPanel>\n </TabContext>\n </Content>\n );\n};\n\nexport const UnprocessedEntities = () => {\n return (\n <Page themeId=\"tool\">\n <Header title=\"Unprocessed Entitites\" />\n <UnprocessedEntitiesContent />\n </Page>\n );\n};\n"],"names":["useStyles","makeStyles"],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createRouteRef, createApiRef, createPlugin, createApiFactory, discoveryApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
|
|
2
|
+
import { ResponseError } from '@backstage/errors';
|
|
3
|
+
|
|
4
|
+
const rootRouteRef = createRouteRef({
|
|
5
|
+
id: "catalog-unprocessed-entities"
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
const catalogUnprocessedEntitiesApiRef = createApiRef({
|
|
9
|
+
id: "plugin.catalog-unprocessed-entities.service"
|
|
10
|
+
});
|
|
11
|
+
class CatalogUnprocessedEntitiesApi {
|
|
12
|
+
constructor(discovery) {
|
|
13
|
+
this.discovery = discovery;
|
|
14
|
+
this.url = "";
|
|
15
|
+
}
|
|
16
|
+
async fetch(path, init) {
|
|
17
|
+
if (!this.url) {
|
|
18
|
+
this.url = await this.discovery.getBaseUrl("catalog");
|
|
19
|
+
}
|
|
20
|
+
const resp = await fetch(`${this.url}/${path}`, init);
|
|
21
|
+
if (!resp.ok) {
|
|
22
|
+
throw await ResponseError.fromResponse(resp);
|
|
23
|
+
}
|
|
24
|
+
return await resp.json();
|
|
25
|
+
}
|
|
26
|
+
async pending() {
|
|
27
|
+
return await this.fetch("entities/unprocessed/pending");
|
|
28
|
+
}
|
|
29
|
+
async failed() {
|
|
30
|
+
return await this.fetch("entities/unprocessed/failed");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const catalogUnprocessedEntitiesPlugin = createPlugin({
|
|
35
|
+
id: "catalog-unprocessed-entities",
|
|
36
|
+
routes: {
|
|
37
|
+
root: rootRouteRef
|
|
38
|
+
},
|
|
39
|
+
apis: [
|
|
40
|
+
createApiFactory({
|
|
41
|
+
api: catalogUnprocessedEntitiesApiRef,
|
|
42
|
+
deps: { discoveryApi: discoveryApiRef },
|
|
43
|
+
factory: ({ discoveryApi }) => new CatalogUnprocessedEntitiesApi(discoveryApi)
|
|
44
|
+
})
|
|
45
|
+
]
|
|
46
|
+
});
|
|
47
|
+
const CatalogUnprocessedEntitiesPage = catalogUnprocessedEntitiesPlugin.provide(
|
|
48
|
+
createRoutableExtension({
|
|
49
|
+
name: "CatalogUnprocessedEntitiesPage",
|
|
50
|
+
component: () => import('./UnprocessedEntities-16922014.esm.js').then(
|
|
51
|
+
(m) => m.UnprocessedEntities
|
|
52
|
+
),
|
|
53
|
+
mountPoint: rootRouteRef
|
|
54
|
+
})
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
export { CatalogUnprocessedEntitiesPage as C, catalogUnprocessedEntitiesPlugin as a, catalogUnprocessedEntitiesApiRef as c };
|
|
58
|
+
//# sourceMappingURL=index-a9a60a39.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-a9a60a39.esm.js","sources":["../../src/routes.ts","../../src/api/index.ts","../../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'catalog-unprocessed-entities',\n});\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { DiscoveryApi, createApiRef } from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport { UnprocessedEntity } from '../types';\n\n/**\n * {@link @backstage/core-plugin-api#ApiRef} for the {@link CatalogUnprocessedEntitiesApi}\n *\n * @public\n */\nexport const catalogUnprocessedEntitiesApiRef =\n createApiRef<CatalogUnprocessedEntitiesApi>({\n id: 'plugin.catalog-unprocessed-entities.service',\n });\n\n/**\n * API client for the Catalog Unprocessed Entities plugin\n *\n * @public\n */\nexport class CatalogUnprocessedEntitiesApi {\n url: string = '';\n\n constructor(public discovery: DiscoveryApi) {}\n\n private async fetch<T>(path: string, init?: RequestInit): Promise<T> {\n if (!this.url) {\n this.url = await this.discovery.getBaseUrl('catalog');\n }\n const resp = await fetch(`${this.url}/${path}`, init);\n if (!resp.ok) {\n throw await ResponseError.fromResponse(resp);\n }\n\n return await resp.json();\n }\n\n async pending(): Promise<{ entities: UnprocessedEntity[] }> {\n return await this.fetch('entities/unprocessed/pending');\n }\n\n async failed(): Promise<{ entities: UnprocessedEntity[] }> {\n return await this.fetch('entities/unprocessed/failed');\n }\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport {\n CatalogUnprocessedEntitiesApi,\n catalogUnprocessedEntitiesApiRef,\n} from './api';\n\n/**\n * Plugin entry point\n *\n * @public\n */\nexport const catalogUnprocessedEntitiesPlugin = createPlugin({\n id: 'catalog-unprocessed-entities',\n routes: {\n root: rootRouteRef,\n },\n apis: [\n createApiFactory({\n api: catalogUnprocessedEntitiesApiRef,\n deps: { discoveryApi: discoveryApiRef },\n factory: ({ discoveryApi }) =>\n new CatalogUnprocessedEntitiesApi(discoveryApi),\n }),\n ],\n});\n\n/**\n * Tool page for the Catalog Unprocessed Entities Plugin\n *\n * @public\n */\nexport const CatalogUnprocessedEntitiesPage =\n catalogUnprocessedEntitiesPlugin.provide(\n createRoutableExtension({\n name: 'CatalogUnprocessedEntitiesPage',\n component: () =>\n import('./components/UnprocessedEntities').then(\n m => m.UnprocessedEntities,\n ),\n mountPoint: rootRouteRef,\n }),\n );\n"],"names":[],"mappings":";;;AAiBO,MAAM,eAAe,cAAe,CAAA;AAAA,EACzC,EAAI,EAAA,8BAAA;AACN,CAAC,CAAA;;ACKM,MAAM,mCACX,YAA4C,CAAA;AAAA,EAC1C,EAAI,EAAA,6CAAA;AACN,CAAC,EAAA;AAOI,MAAM,6BAA8B,CAAA;AAAA,EAGzC,YAAmB,SAAyB,EAAA;AAAzB,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA,CAAA;AAFnB,IAAc,IAAA,CAAA,GAAA,GAAA,EAAA,CAAA;AAAA,GAE+B;AAAA,EAE7C,MAAc,KAAS,CAAA,IAAA,EAAc,IAAgC,EAAA;AACnE,IAAI,IAAA,CAAC,KAAK,GAAK,EAAA;AACb,MAAA,IAAA,CAAK,GAAM,GAAA,MAAM,IAAK,CAAA,SAAA,CAAU,WAAW,SAAS,CAAA,CAAA;AAAA,KACtD;AACA,IAAA,MAAM,OAAO,MAAM,KAAA,CAAM,GAAG,IAAK,CAAA,GAAA,CAAA,CAAA,EAAO,QAAQ,IAAI,CAAA,CAAA;AACpD,IAAI,IAAA,CAAC,KAAK,EAAI,EAAA;AACZ,MAAM,MAAA,MAAM,aAAc,CAAA,YAAA,CAAa,IAAI,CAAA,CAAA;AAAA,KAC7C;AAEA,IAAO,OAAA,MAAM,KAAK,IAAK,EAAA,CAAA;AAAA,GACzB;AAAA,EAEA,MAAM,OAAsD,GAAA;AAC1D,IAAO,OAAA,MAAM,IAAK,CAAA,KAAA,CAAM,8BAA8B,CAAA,CAAA;AAAA,GACxD;AAAA,EAEA,MAAM,MAAqD,GAAA;AACzD,IAAO,OAAA,MAAM,IAAK,CAAA,KAAA,CAAM,6BAA6B,CAAA,CAAA;AAAA,GACvD;AACF;;ACzBO,MAAM,mCAAmC,YAAa,CAAA;AAAA,EAC3D,EAAI,EAAA,8BAAA;AAAA,EACJ,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,YAAA;AAAA,GACR;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,gCAAA;AAAA,MACL,IAAA,EAAM,EAAE,YAAA,EAAc,eAAgB,EAAA;AAAA,MACtC,SAAS,CAAC,EAAE,cACV,KAAA,IAAI,8BAA8B,YAAY,CAAA;AAAA,KACjD,CAAA;AAAA,GACH;AACF,CAAC,EAAA;AAOM,MAAM,iCACX,gCAAiC,CAAA,OAAA;AAAA,EAC/B,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,gCAAA;AAAA,IACN,SAAW,EAAA,MACT,OAAO,uCAAkC,CAAE,CAAA,IAAA;AAAA,MACzC,OAAK,CAAE,CAAA,mBAAA;AAAA,KACT;AAAA,IACF,UAAY,EAAA,YAAA;AAAA,GACb,CAAA;AACH;;;;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Plugin entry point
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
declare const catalogUnprocessedEntitiesPlugin: _backstage_core_plugin_api.BackstagePlugin<{
|
|
10
|
+
root: _backstage_core_plugin_api.RouteRef<undefined>;
|
|
11
|
+
}, {}, {}>;
|
|
12
|
+
/**
|
|
13
|
+
* Tool page for the Catalog Unprocessed Entities Plugin
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
declare const CatalogUnprocessedEntitiesPage: () => JSX.Element;
|
|
18
|
+
|
|
19
|
+
export { CatalogUnprocessedEntitiesPage, catalogUnprocessedEntitiesPlugin };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@backstage/plugin-catalog-unprocessed-entities",
|
|
3
|
+
"version": "0.0.0-nightly-20230531023430",
|
|
4
|
+
"main": "dist/index.esm.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public",
|
|
9
|
+
"main": "dist/index.esm.js",
|
|
10
|
+
"types": "dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"backstage": {
|
|
13
|
+
"role": "frontend-plugin"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"start": "backstage-cli package start",
|
|
17
|
+
"build": "backstage-cli package build",
|
|
18
|
+
"lint": "backstage-cli package lint",
|
|
19
|
+
"test": "backstage-cli package test",
|
|
20
|
+
"clean": "backstage-cli package clean",
|
|
21
|
+
"prepack": "backstage-cli package prepack",
|
|
22
|
+
"postpack": "backstage-cli package postpack"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@backstage/catalog-model": "^0.0.0-nightly-20230531023430",
|
|
26
|
+
"@backstage/core-components": "^0.0.0-nightly-20230531023430",
|
|
27
|
+
"@backstage/core-plugin-api": "^0.0.0-nightly-20230531023430",
|
|
28
|
+
"@backstage/errors": "^0.0.0-nightly-20230531023430",
|
|
29
|
+
"@backstage/theme": "^0.0.0-nightly-20230531023430",
|
|
30
|
+
"@material-ui/core": "^4.9.13",
|
|
31
|
+
"@material-ui/icons": "^4.9.1",
|
|
32
|
+
"@material-ui/lab": "^4.0.0-alpha.60",
|
|
33
|
+
"react-use": "^17.2.4"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"react": "^16.13.1 || ^17.0.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@backstage/cli": "^0.0.0-nightly-20230531023430",
|
|
40
|
+
"@backstage/core-app-api": "^0.0.0-nightly-20230531023430",
|
|
41
|
+
"@backstage/dev-utils": "^0.0.0-nightly-20230531023430",
|
|
42
|
+
"@backstage/test-utils": "^0.0.0-nightly-20230531023430",
|
|
43
|
+
"@testing-library/jest-dom": "^5.10.1",
|
|
44
|
+
"@testing-library/react": "^12.1.3",
|
|
45
|
+
"@testing-library/user-event": "^14.0.0",
|
|
46
|
+
"@types/node": "*",
|
|
47
|
+
"cross-fetch": "^3.1.5",
|
|
48
|
+
"msw": "^1.0.0"
|
|
49
|
+
},
|
|
50
|
+
"files": [
|
|
51
|
+
"dist"
|
|
52
|
+
],
|
|
53
|
+
"module": "./dist/index.esm.js"
|
|
54
|
+
}
|