@backstage/plugin-catalog 1.7.2-next.1 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @backstage/plugin-catalog
2
2
 
3
+ ## 1.7.2
4
+
5
+ ### Patch Changes
6
+
7
+ - cebe24ef1d: Add `EntityLabelsCard` to show the labels for an entity.
8
+ - 5353b4df61: There is now tooltip in the entity context menu
9
+ - Updated dependencies
10
+ - @backstage/catalog-model@1.1.5
11
+ - @backstage/catalog-client@1.3.0
12
+ - @backstage/plugin-catalog-react@1.2.4
13
+ - @backstage/core-components@0.12.3
14
+ - @backstage/plugin-search-react@1.4.0
15
+ - @backstage/core-plugin-api@1.3.0
16
+ - @backstage/errors@1.1.4
17
+ - @backstage/integration-react@1.1.9
18
+ - @backstage/theme@0.2.16
19
+ - @backstage/types@1.0.2
20
+ - @backstage/plugin-catalog-common@1.0.10
21
+ - @backstage/plugin-search-common@1.2.1
22
+
23
+ ## 1.7.2-next.2
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies
28
+ - @backstage/plugin-search-react@1.4.0-next.2
29
+ - @backstage/core-plugin-api@1.3.0-next.1
30
+ - @backstage/catalog-client@1.3.0-next.2
31
+ - @backstage/plugin-catalog-react@1.2.4-next.2
32
+ - @backstage/catalog-model@1.1.5-next.1
33
+ - @backstage/core-components@0.12.3-next.2
34
+ - @backstage/errors@1.1.4
35
+ - @backstage/integration-react@1.1.9-next.2
36
+ - @backstage/theme@0.2.16
37
+ - @backstage/types@1.0.2
38
+ - @backstage/plugin-catalog-common@1.0.10-next.1
39
+ - @backstage/plugin-search-common@1.2.1-next.0
40
+
3
41
  ## 1.7.2-next.1
4
42
 
5
43
  ### Patch Changes
@@ -1,11 +1,11 @@
1
1
  import ObservableImpl from 'zen-observable';
2
2
  import { stringifyEntityRef, RELATION_PART_OF, RELATION_OWNED_BY, getEntitySourceLocation, ANNOTATION_EDIT_URL, DEFAULT_NAMESPACE, ANNOTATION_LOCATION, ANNOTATION_VIEW_URL } from '@backstage/catalog-model';
3
3
  import { isArray, isString, capitalize } from 'lodash';
4
- import { Link, HeaderIconLinkRow, OverflowTooltip, WarningPanel, CodeSnippet, Table, Page, Header, Progress, RoutedTabs, Content, HeaderLabel, ResponseErrorPanel } from '@backstage/core-components';
4
+ import { Link, HeaderIconLinkRow, OverflowTooltip, WarningPanel, CodeSnippet, Table, Page, Header, Progress, RoutedTabs, Content, HeaderLabel, ResponseErrorPanel, InfoCard } from '@backstage/core-components';
5
5
  import { createExternalRouteRef, createRouteRef, useElementFilter, useApi, alertApiRef, errorApiRef, useRouteRef, useAnalytics, attachComponentData, useRouteRefParams, useApiHolder, createPlugin, createApiFactory, discoveryApiRef, fetchApiRef, storageApiRef, createRoutableExtension, createComponentExtension } from '@backstage/core-plugin-api';
6
6
  import { scmIntegrationsApiRef, ScmIntegrationIcon } from '@backstage/integration-react';
7
7
  import { getEntityRelations, EntityRefLinks, useEntity, catalogApiRef, getEntitySourceLocation as getEntitySourceLocation$1, useEntityList, EntityKindFilter, EntityRefLink, humanizeEntityRef, useStarredEntities, useEntityPermission, entityRouteRef, useAsyncEntity, UnregisterEntityDialog, InspectEntityDialog, FavoriteEntity, CatalogFilterLayout, starredEntitiesApiRef } from '@backstage/plugin-catalog-react';
8
- import { makeStyles, Typography, Grid, Box, useMediaQuery, ImageList, ImageListItem, Chip, Card, CardHeader, IconButton, Divider, CardContent, createStyles, Select, InputBase, MenuItem, ListItem, ListItemIcon, ListItemText, Popover, MenuList, Dialog, DialogTitle, DialogActions, Button } from '@material-ui/core';
8
+ import { makeStyles, Typography, Grid, Box, useMediaQuery, ImageList, ImageListItem, Chip, Card, CardHeader, IconButton, Divider, CardContent, createStyles, Select, InputBase, MenuItem, ListItem, ListItemIcon, ListItemText, Tooltip, Popover, MenuList, Dialog, DialogTitle, DialogActions, Button } from '@material-ui/core';
9
9
  import CachedIcon from '@material-ui/icons/Cached';
10
10
  import DocsIcon from '@material-ui/icons/Description';
11
11
  import EditIcon from '@material-ui/icons/Edit';
@@ -106,7 +106,7 @@ const rootRouteRef = createRouteRef({
106
106
  id: "catalog"
107
107
  });
108
108
 
109
- const useStyles$6 = makeStyles((theme) => ({
109
+ const useStyles$8 = makeStyles((theme) => ({
110
110
  value: {
111
111
  fontWeight: "bold",
112
112
  overflow: "hidden",
@@ -125,13 +125,13 @@ const useStyles$6 = makeStyles((theme) => ({
125
125
  }));
126
126
  function AboutField(props) {
127
127
  const { label, value, gridSizes, children } = props;
128
- const classes = useStyles$6();
128
+ const classes = useStyles$8();
129
129
  const childElements = useElementFilter(children, (c) => c.getElements());
130
130
  const content = childElements.length > 0 ? childElements : /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.value }, value || `unknown`);
131
131
  return /* @__PURE__ */ React.createElement(Grid, { item: true, ...gridSizes }, /* @__PURE__ */ React.createElement(Typography, { variant: "h2", className: classes.label }, label), content);
132
132
  }
133
133
 
134
- const useStyles$5 = makeStyles({
134
+ const useStyles$7 = makeStyles({
135
135
  svgIcon: {
136
136
  display: "inline-block",
137
137
  "& svg": {
@@ -143,7 +143,7 @@ const useStyles$5 = makeStyles({
143
143
  });
144
144
  function IconLink(props) {
145
145
  const { href, text, Icon } = props;
146
- const classes = useStyles$5();
146
+ const classes = useStyles$7();
147
147
  return /* @__PURE__ */ React.createElement(Box, { display: "flex" }, /* @__PURE__ */ React.createElement(Box, { mr: 1, className: classes.svgIcon }, /* @__PURE__ */ React.createElement(Typography, { component: "div" }, Icon ? /* @__PURE__ */ React.createElement(Icon, null) : /* @__PURE__ */ React.createElement(LanguageIcon, null))), /* @__PURE__ */ React.createElement(Box, { flexGrow: "1" }, /* @__PURE__ */ React.createElement(Link, { to: href, target: "_blank", rel: "noopener" }, text || href)));
148
148
  }
149
149
 
@@ -179,7 +179,7 @@ function LinksGridList(props) {
179
179
  return /* @__PURE__ */ React.createElement(ImageList, { rowHeight: "auto", cols: numOfCols }, items.map(({ text, href, Icon }, i) => /* @__PURE__ */ React.createElement(ImageListItem, { key: i }, /* @__PURE__ */ React.createElement(IconLink, { href, text: text != null ? text : href, Icon }))));
180
180
  }
181
181
 
182
- const useStyles$4 = makeStyles({
182
+ const useStyles$6 = makeStyles({
183
183
  description: {
184
184
  wordBreak: "break-word"
185
185
  }
@@ -197,7 +197,7 @@ function getLocationTargetHref(target, type, entitySourceLocation) {
197
197
  function AboutContent(props) {
198
198
  var _a, _b, _c, _d, _e, _f, _g, _h;
199
199
  const { entity } = props;
200
- const classes = useStyles$4();
200
+ const classes = useStyles$6();
201
201
  const isSystem = entity.kind.toLocaleLowerCase("en-US") === "system";
202
202
  const isResource = entity.kind.toLocaleLowerCase("en-US") === "resource";
203
203
  const isComponent = entity.kind.toLocaleLowerCase("en-US") === "component";
@@ -316,11 +316,12 @@ function AboutContent(props) {
316
316
  )));
317
317
  }
318
318
 
319
- const useStyles$3 = makeStyles({
319
+ const useStyles$5 = makeStyles({
320
320
  gridItemCard: {
321
321
  display: "flex",
322
322
  flexDirection: "column",
323
323
  height: "calc(100% - 10px)",
324
+ // for pages without content header
324
325
  marginBottom: "10px"
325
326
  },
326
327
  fullHeightCard: {
@@ -338,7 +339,7 @@ const useStyles$3 = makeStyles({
338
339
  function AboutCard(props) {
339
340
  var _a, _b, _c;
340
341
  const { variant } = props;
341
- const classes = useStyles$3();
342
+ const classes = useStyles$5();
342
343
  const { entity } = useEntity();
343
344
  const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
344
345
  const catalogApi = useApi(catalogApiRef);
@@ -452,7 +453,7 @@ function filterKinds(allKinds, allowedKinds, forcedKinds) {
452
453
  return kindsMap;
453
454
  }
454
455
 
455
- const useStyles$2 = makeStyles(
456
+ const useStyles$4 = makeStyles(
456
457
  (theme) => createStyles({
457
458
  root: {
458
459
  ...theme.typography.h4
@@ -462,7 +463,7 @@ const useStyles$2 = makeStyles(
462
463
  function CatalogKindHeader(props) {
463
464
  var _a, _b;
464
465
  const { initialFilter = "component", allowedKinds } = props;
465
- const classes = useStyles$2();
466
+ const classes = useStyles$4();
466
467
  const { allKinds } = useAllKinds();
467
468
  const {
468
469
  filters,
@@ -505,7 +506,7 @@ function CatalogKindHeader(props) {
505
506
  );
506
507
  }
507
508
 
508
- const useStyles$1 = makeStyles({
509
+ const useStyles$3 = makeStyles({
509
510
  flexContainer: {
510
511
  flexWrap: "wrap"
511
512
  },
@@ -518,7 +519,7 @@ const useStyles$1 = makeStyles({
518
519
  function CatalogSearchResultListItem(props) {
519
520
  const result = props.result;
520
521
  const highlight = props.highlight;
521
- const classes = useStyles$1();
522
+ const classes = useStyles$3();
522
523
  const analytics = useAnalytics();
523
524
  const handleClick = () => {
524
525
  analytics.captureEvent("discover", result.title, {
@@ -882,7 +883,7 @@ function UnregisterEntity(props) {
882
883
  return /* @__PURE__ */ React.createElement(React.Fragment, null, unregisterButton);
883
884
  }
884
885
 
885
- const useStyles = makeStyles$1(
886
+ const useStyles$2 = makeStyles$1(
886
887
  (theme) => {
887
888
  return {
888
889
  button: {
@@ -900,7 +901,7 @@ function EntityContextMenu(props) {
900
901
  onInspectEntity
901
902
  } = props;
902
903
  const [anchorEl, setAnchorEl] = useState();
903
- const classes = useStyles();
904
+ const classes = useStyles$2();
904
905
  const unregisterPermission = useEntityPermission(
905
906
  catalogEntityDeletePermission
906
907
  );
@@ -930,7 +931,7 @@ function EntityContextMenu(props) {
930
931
  )),
931
932
  /* @__PURE__ */ React.createElement(Divider, { key: "the divider is here!" })
932
933
  ];
933
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
934
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "More", arrow: true }, /* @__PURE__ */ React.createElement(
934
935
  IconButton,
935
936
  {
936
937
  "aria-label": "more",
@@ -944,7 +945,7 @@ function EntityContextMenu(props) {
944
945
  id: "long-menu"
945
946
  },
946
947
  /* @__PURE__ */ React.createElement(MoreVert, null)
947
- ), /* @__PURE__ */ React.createElement(
948
+ )), /* @__PURE__ */ React.createElement(
948
949
  Popover,
949
950
  {
950
951
  open: Boolean(anchorEl),
@@ -1314,6 +1315,91 @@ const FilteredEntityLayout = CatalogFilterLayout;
1314
1315
  const FilterContainer = CatalogFilterLayout.Filters;
1315
1316
  const EntityListContainer = CatalogFilterLayout.Content;
1316
1317
 
1318
+ const ENTITY_YAML = `metadata:
1319
+ name: example
1320
+ labels:
1321
+ javaVersion: 1.2.3`;
1322
+ const useStyles$1 = makeStyles(
1323
+ (theme) => ({
1324
+ code: {
1325
+ borderRadius: 6,
1326
+ margin: `${theme.spacing(2)}px 0px`,
1327
+ background: theme.palette.type === "dark" ? "#444" : "#fff"
1328
+ }
1329
+ }),
1330
+ { name: "PluginCatalogEntityLabelsEmptyState" }
1331
+ );
1332
+ function EntityLabelsEmptyState() {
1333
+ const classes = useStyles$1();
1334
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Typography, { variant: "body1" }, "No labels defined for this entity. You can add labels to your entity YAML as shown in the highlighted example below:"), /* @__PURE__ */ React.createElement("div", { className: classes.code }, /* @__PURE__ */ React.createElement(
1335
+ CodeSnippet,
1336
+ {
1337
+ text: ENTITY_YAML,
1338
+ language: "yaml",
1339
+ showLineNumbers: true,
1340
+ highlightedNumbers: [3, 4, 5, 6],
1341
+ customStyle: { background: "inherit", fontSize: "115%" }
1342
+ }
1343
+ )), /* @__PURE__ */ React.createElement(
1344
+ Button,
1345
+ {
1346
+ variant: "contained",
1347
+ color: "primary",
1348
+ target: "_blank",
1349
+ href: "https://backstage.io/docs/features/software-catalog/descriptor-format#labels-optional"
1350
+ },
1351
+ "Read more"
1352
+ ));
1353
+ }
1354
+
1355
+ const useStyles = makeStyles((_) => ({
1356
+ key: {
1357
+ fontWeight: "bold"
1358
+ }
1359
+ }));
1360
+ const EntityLabelsCard$1 = (props) => {
1361
+ var _a;
1362
+ const { variant, title } = props;
1363
+ const { entity } = useEntity();
1364
+ const classes = useStyles();
1365
+ const columns = [
1366
+ {
1367
+ render: (row) => {
1368
+ return /* @__PURE__ */ React.createElement(Typography, { className: classes.key, variant: "body2" }, row.key);
1369
+ }
1370
+ },
1371
+ {
1372
+ field: "value"
1373
+ }
1374
+ ];
1375
+ const labels = (_a = entity == null ? void 0 : entity.metadata) == null ? void 0 : _a.labels;
1376
+ return /* @__PURE__ */ React.createElement(InfoCard, { title: title || "Labels", variant }, !labels || Object.keys(labels).length === 0 ? /* @__PURE__ */ React.createElement(EntityLabelsEmptyState, null) : /* @__PURE__ */ React.createElement(
1377
+ Table,
1378
+ {
1379
+ columns,
1380
+ data: Object.keys(labels).map((labelKey) => ({
1381
+ key: labelKey,
1382
+ value: labels[labelKey]
1383
+ })),
1384
+ options: {
1385
+ search: false,
1386
+ showTitle: true,
1387
+ loadingType: "linear",
1388
+ header: false,
1389
+ padding: "dense",
1390
+ pageSize: 5,
1391
+ toolbar: false,
1392
+ paging: Object.keys(labels).length > 5
1393
+ }
1394
+ }
1395
+ ));
1396
+ };
1397
+
1398
+ function hasLabels(entity) {
1399
+ var _a, _b;
1400
+ return ((_a = entity == null ? void 0 : entity.metadata) == null ? void 0 : _a.labels) ? Object.keys((_b = entity == null ? void 0 : entity.metadata) == null ? void 0 : _b.labels).some(Boolean) : false;
1401
+ }
1402
+
1317
1403
  const catalogPlugin = createPlugin({
1318
1404
  id: "catalog",
1319
1405
  apis: [
@@ -1349,7 +1435,7 @@ const catalogPlugin = createPlugin({
1349
1435
  const CatalogIndexPage = catalogPlugin.provide(
1350
1436
  createRoutableExtension({
1351
1437
  name: "CatalogIndexPage",
1352
- component: () => import('./index-e2a687cd.esm.js').then((m) => m.CatalogPage),
1438
+ component: () => import('./index-eb346a82.esm.js').then((m) => m.CatalogPage),
1353
1439
  mountPoint: rootRouteRef
1354
1440
  })
1355
1441
  );
@@ -1364,7 +1450,7 @@ const EntityAboutCard = catalogPlugin.provide(
1364
1450
  createComponentExtension({
1365
1451
  name: "EntityAboutCard",
1366
1452
  component: {
1367
- lazy: () => import('./index-c04e9bd4.esm.js').then((m) => m.AboutCard)
1453
+ lazy: () => import('./index-2c3b0303.esm.js').then((m) => m.AboutCard)
1368
1454
  }
1369
1455
  })
1370
1456
  );
@@ -1372,7 +1458,15 @@ const EntityLinksCard = catalogPlugin.provide(
1372
1458
  createComponentExtension({
1373
1459
  name: "EntityLinksCard",
1374
1460
  component: {
1375
- lazy: () => import('./index-e79d2b74.esm.js').then((m) => m.EntityLinksCard)
1461
+ lazy: () => import('./index-07f33109.esm.js').then((m) => m.EntityLinksCard)
1462
+ }
1463
+ })
1464
+ );
1465
+ const EntityLabelsCard = catalogPlugin.provide(
1466
+ createComponentExtension({
1467
+ name: "EntityLabelsCard",
1468
+ component: {
1469
+ lazy: () => import('./index-75a7574f.esm.js').then((m) => m.EntityLabelsCard)
1376
1470
  }
1377
1471
  })
1378
1472
  );
@@ -1451,5 +1545,5 @@ const RelatedEntitiesCard = catalogPlugin.provide(
1451
1545
  })
1452
1546
  );
1453
1547
 
1454
- export { AboutCard as A, EntityListContainer as B, CatalogTable as C, DefaultStarredEntitiesApi as D, EntityAboutCard as E, FilteredEntityLayout as F, LinksGridList as L, RelatedEntitiesCard as R, AboutContent as a, AboutField as b, createComponentRouteRef as c, CatalogEntityPage as d, CatalogIndexPage as e, catalogPlugin as f, EntityDependencyOfComponentsCard as g, EntityDependsOnComponentsCard as h, EntityDependsOnResourcesCard as i, EntityHasComponentsCard as j, EntityHasResourcesCard as k, EntityHasSubcomponentsCard as l, EntityHasSystemsCard as m, EntityLinksCard as n, CatalogKindHeader as o, CatalogSearchResultListItem as p, EntityLayout as q, EntityOrphanWarning as r, isOrphan as s, EntityProcessingErrorsPanel as t, hasCatalogProcessingErrors as u, EntitySwitch as v, isKind as w, isNamespace as x, isComponentType as y, FilterContainer as z };
1455
- //# sourceMappingURL=index-24abea03.esm.js.map
1548
+ export { AboutCard as A, isNamespace as B, CatalogTable as C, DefaultStarredEntitiesApi as D, EntityLabelsCard$1 as E, isComponentType as F, FilteredEntityLayout as G, FilterContainer as H, EntityListContainer as I, LinksGridList as L, RelatedEntitiesCard as R, AboutContent as a, AboutField as b, createComponentRouteRef as c, CatalogEntityPage as d, CatalogIndexPage as e, catalogPlugin as f, EntityAboutCard as g, hasLabels as h, EntityDependencyOfComponentsCard as i, EntityDependsOnComponentsCard as j, EntityDependsOnResourcesCard as k, EntityHasComponentsCard as l, EntityHasResourcesCard as m, EntityHasSubcomponentsCard as n, EntityHasSystemsCard as o, EntityLinksCard as p, EntityLabelsCard as q, CatalogKindHeader as r, CatalogSearchResultListItem as s, EntityLayout as t, EntityOrphanWarning as u, isOrphan as v, EntityProcessingErrorsPanel as w, hasCatalogProcessingErrors as x, EntitySwitch as y, isKind as z };
1549
+ //# sourceMappingURL=index-05290c15.esm.js.map