@backstage/plugin-catalog-react 1.9.0-next.2 → 1.9.1
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 +58 -0
- package/alpha/package.json +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.esm.js +43 -50
- package/dist/index.esm.js.map +1 -1
- package/package.json +16 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-react
|
|
2
2
|
|
|
3
|
+
## 1.9.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ceebf2ca4ba7: Fixed a issue where `CatalogPage` wasn't using the chosen `initiallySelectedFilter` as intended.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @backstage/integration-react@1.1.21
|
|
10
|
+
|
|
11
|
+
## 1.9.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 1e5b7d993a: Added an `EntityPresentationApi` and associated `entityPresentationApiRef`. This
|
|
16
|
+
API lets you control how references to entities (e.g. in links, headings,
|
|
17
|
+
iconography etc) are represented in the user interface.
|
|
18
|
+
|
|
19
|
+
Usage of this API is initially added to the `EntityRefLink` and `EntityRefLinks`
|
|
20
|
+
components, so that they can render richer, more correct representation of
|
|
21
|
+
entity refs. There's also a new `EntityDisplayName` component, which works just like
|
|
22
|
+
the `EntityRefLink` but without the link.
|
|
23
|
+
|
|
24
|
+
Along with that change, the `fetchEntities` and `getTitle` props of
|
|
25
|
+
`EntityRefLinksProps` are deprecated and no longer used, since the same need
|
|
26
|
+
instead is fulfilled (and by default always enabled) by the
|
|
27
|
+
`entityPresentationApiRef`.
|
|
28
|
+
|
|
29
|
+
- 1fd53fa0c6: The `UserListPicker` component has undergone improvements to enhance its performance.
|
|
30
|
+
|
|
31
|
+
The previous implementation inferred the number of owned and starred entities based on the entities available in the `EntityListContext`. The updated version no longer relies on the `EntityListContext` for inference, allowing for better decoupling.
|
|
32
|
+
|
|
33
|
+
The component now loads the entities' count asynchronously, resulting in improved performance and responsiveness. For this purpose, some of the exported filters such as `EntityTagFilter`, `EntityOwnerFilter`, `EntityLifecycleFilter` and `EntityNamespaceFilter` have now the `getCatalogFilters` method implemented.
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- 2ad1bacef7: Add EntityRef to Entity Inspector UI
|
|
38
|
+
- 6c2b872153: Add official support for React 18.
|
|
39
|
+
- 69ee8d75f4: Remove `button` prop from used MaterialUI `MenuItem` component fixing incompatibility with MaterialUI v5.
|
|
40
|
+
- 0bf6ebda88: Added new APIs at the `/alpha` subpath for creating entity page cards and content for the new frontend system.
|
|
41
|
+
- 77f009b35d: Internal updates to match changes in the experimental `@backstage/frontend-plugin-api`.
|
|
42
|
+
- 71c97e7d73: The `spec.type` field in entities will now always be rendered as a string.
|
|
43
|
+
- 69c14904b6: Move the `EntityRefLink` icon to the left hand side as per Material-UI guidelines
|
|
44
|
+
- 000dcd01af: Removed unnecessary `@backstage/integration` dependency, replaced by `@backstage/integration-react`.
|
|
45
|
+
- 6c357184e2: Export `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react`
|
|
46
|
+
- Updated dependencies
|
|
47
|
+
- @backstage/core-components@0.13.8
|
|
48
|
+
- @backstage/frontend-plugin-api@0.3.0
|
|
49
|
+
- @backstage/integration-react@1.1.21
|
|
50
|
+
- @backstage/core-plugin-api@1.8.0
|
|
51
|
+
- @backstage/plugin-permission-react@0.4.17
|
|
52
|
+
- @backstage/version-bridge@1.0.7
|
|
53
|
+
- @backstage/theme@0.4.4
|
|
54
|
+
- @backstage/catalog-client@1.4.6
|
|
55
|
+
- @backstage/plugin-permission-common@0.7.10
|
|
56
|
+
- @backstage/catalog-model@1.4.3
|
|
57
|
+
- @backstage/errors@1.2.3
|
|
58
|
+
- @backstage/types@1.1.1
|
|
59
|
+
- @backstage/plugin-catalog-common@1.0.18
|
|
60
|
+
|
|
3
61
|
## 1.9.0-next.2
|
|
4
62
|
|
|
5
63
|
### Patch Changes
|
package/alpha/package.json
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -259,8 +259,8 @@ type CatalogReactEntityDisplayNameClassKey = 'root' | 'icon';
|
|
|
259
259
|
*/
|
|
260
260
|
type EntityDisplayNameProps = {
|
|
261
261
|
entityRef: Entity | CompoundEntityRef | string;
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
hideIcon?: boolean;
|
|
263
|
+
disableTooltip?: boolean;
|
|
264
264
|
defaultKind?: string;
|
|
265
265
|
defaultNamespace?: string;
|
|
266
266
|
};
|
|
@@ -283,6 +283,7 @@ type EntityRefLinkProps = {
|
|
|
283
283
|
/** @deprecated This option should no longer be used; presentation is requested through the {@link entityPresentationApiRef} instead */
|
|
284
284
|
title?: string;
|
|
285
285
|
children?: React.ReactNode;
|
|
286
|
+
hideIcon?: boolean;
|
|
286
287
|
} & Omit<LinkProps, 'to'>;
|
|
287
288
|
/**
|
|
288
289
|
* Shows a clickable link to an entity.
|
|
@@ -299,6 +300,7 @@ declare const EntityRefLink: (props: EntityRefLinkProps) => JSX.Element;
|
|
|
299
300
|
type EntityRefLinksProps<TRef extends string | CompoundEntityRef | Entity> = {
|
|
300
301
|
defaultKind?: string;
|
|
301
302
|
entityRefs: TRef[];
|
|
303
|
+
hideIcons?: boolean;
|
|
302
304
|
/** @deprecated This option is no longer used; presentation is handled by entityPresentationApiRef instead */
|
|
303
305
|
fetchEntities?: boolean;
|
|
304
306
|
/** @deprecated This option is no longer used; presentation is handled by entityPresentationApiRef instead */
|
package/dist/index.esm.js
CHANGED
|
@@ -13,9 +13,9 @@ import PersonIcon from '@material-ui/icons/Person';
|
|
|
13
13
|
import get from 'lodash/get';
|
|
14
14
|
import React, { useState, useEffect, useMemo, createContext, useCallback, useContext, useRef, memo, forwardRef, useLayoutEffect, Fragment } from 'react';
|
|
15
15
|
import ObservableImpl from 'zen-observable';
|
|
16
|
-
import { Grid, useMediaQuery, useTheme, Button, Drawer, Box, Typography, FormControlLabel, Checkbox, makeStyles, TextField, Tooltip, IconButton, Card, CardContent, Chip, CardActions, Toolbar, FormControl, Input, InputAdornment, withStyles, DialogContentText, ListItemText as ListItemText$1, ListSubheader as ListSubheader$1, ListItem, ListItemIcon, List, Dialog, DialogTitle, DialogContent, Tabs, Tab, DialogActions, Divider, MenuItem
|
|
16
|
+
import { Grid, useMediaQuery, useTheme, Button, Drawer, Box, Typography, FormControlLabel, Checkbox, makeStyles, TextField, Tooltip, IconButton, Card, CardContent, Chip, CardActions, Toolbar, FormControl, Input, InputAdornment, withStyles, DialogContentText, ListItemText as ListItemText$1, ListSubheader as ListSubheader$1, ListItem, ListItemIcon, List, ListItemSecondaryAction, Dialog, DialogTitle, DialogContent, Tabs, Tab, DialogActions, Divider, MenuItem } from '@material-ui/core';
|
|
17
17
|
import FilterListIcon from '@material-ui/icons/FilterList';
|
|
18
|
-
import { Select, Link, ResponseErrorPanel, Progress, OverflowTooltip, Table, DependencyGraph, DependencyGraphTypes, CodeSnippet, EmptyState } from '@backstage/core-components';
|
|
18
|
+
import { Select, Link, ResponseErrorPanel, Progress, OverflowTooltip, Table, DependencyGraph, DependencyGraphTypes, CodeSnippet, CopyTextButton, EmptyState } from '@backstage/core-components';
|
|
19
19
|
import { g as getEntityRelations, u as useEntity } from './esm/useEntity-de64059a.esm.js';
|
|
20
20
|
export { A as AsyncEntityProvider, E as EntityProvider, g as getEntityRelations, a as useAsyncEntity, u as useEntity } from './esm/useEntity-de64059a.esm.js';
|
|
21
21
|
import { compact, isEqual, debounce, intersection } from 'lodash';
|
|
@@ -52,6 +52,7 @@ import YAML from 'yaml';
|
|
|
52
52
|
import Alert$1 from '@material-ui/lab/Alert';
|
|
53
53
|
import { assertError } from '@backstage/errors';
|
|
54
54
|
import SettingsIcon from '@material-ui/icons/Settings';
|
|
55
|
+
import useDeepCompareEffect from 'react-use/lib/useDeepCompareEffect';
|
|
55
56
|
import Box$1 from '@material-ui/core/Box';
|
|
56
57
|
import Button$1 from '@material-ui/core/Button';
|
|
57
58
|
import { makeStyles as makeStyles$1 } from '@material-ui/core/styles';
|
|
@@ -1431,7 +1432,7 @@ const useStyles$e = makeStyles(
|
|
|
1431
1432
|
alignItems: "center"
|
|
1432
1433
|
},
|
|
1433
1434
|
icon: {
|
|
1434
|
-
|
|
1435
|
+
marginRight: theme.spacing(0.5),
|
|
1435
1436
|
color: theme.palette.text.secondary,
|
|
1436
1437
|
lineHeight: 0
|
|
1437
1438
|
}
|
|
@@ -1439,15 +1440,15 @@ const useStyles$e = makeStyles(
|
|
|
1439
1440
|
{ name: "CatalogReactEntityDisplayName" }
|
|
1440
1441
|
);
|
|
1441
1442
|
const EntityDisplayName = (props) => {
|
|
1442
|
-
const { entityRef,
|
|
1443
|
+
const { entityRef, hideIcon, disableTooltip, defaultKind, defaultNamespace } = props;
|
|
1443
1444
|
const classes = useStyles$e();
|
|
1444
1445
|
const { primaryTitle, secondaryTitle, Icon } = useEntityPresentation(
|
|
1445
1446
|
entityRef,
|
|
1446
1447
|
{ defaultKind, defaultNamespace }
|
|
1447
1448
|
);
|
|
1448
1449
|
let content = /* @__PURE__ */ React.createElement(React.Fragment, null, primaryTitle);
|
|
1449
|
-
content = /* @__PURE__ */ React.createElement(Box, { component: "span", className: classes.root },
|
|
1450
|
-
if (secondaryTitle && !
|
|
1450
|
+
content = /* @__PURE__ */ React.createElement(Box, { component: "span", className: classes.root }, Icon && !hideIcon ? /* @__PURE__ */ React.createElement(Box, { component: "span", className: classes.icon }, /* @__PURE__ */ React.createElement(Icon, { fontSize: "inherit" })) : null, content);
|
|
1451
|
+
if (secondaryTitle && !disableTooltip) {
|
|
1451
1452
|
content = /* @__PURE__ */ React.createElement(Tooltip, { enterDelay: 1500, title: secondaryTitle }, content);
|
|
1452
1453
|
}
|
|
1453
1454
|
return content;
|
|
@@ -1478,6 +1479,7 @@ const EntityRefLink = forwardRef(
|
|
|
1478
1479
|
defaultNamespace,
|
|
1479
1480
|
title,
|
|
1480
1481
|
children,
|
|
1482
|
+
hideIcon,
|
|
1481
1483
|
...linkProps
|
|
1482
1484
|
} = props;
|
|
1483
1485
|
const entityRoute = useEntityRoute(props.entityRef);
|
|
@@ -1486,7 +1488,8 @@ const EntityRefLink = forwardRef(
|
|
|
1486
1488
|
{
|
|
1487
1489
|
entityRef,
|
|
1488
1490
|
defaultKind,
|
|
1489
|
-
defaultNamespace
|
|
1491
|
+
defaultNamespace,
|
|
1492
|
+
hideIcon
|
|
1490
1493
|
}
|
|
1491
1494
|
);
|
|
1492
1495
|
return /* @__PURE__ */ React.createElement(Link, { ...linkProps, ref, to: entityRoute }, content);
|
|
@@ -1523,10 +1526,10 @@ function useEntityRoute(entityRef) {
|
|
|
1523
1526
|
}
|
|
1524
1527
|
|
|
1525
1528
|
function EntityRefLinks(props) {
|
|
1526
|
-
const { entityRefs, ...linkProps } = props;
|
|
1529
|
+
const { entityRefs, hideIcons, ...linkProps } = props;
|
|
1527
1530
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, entityRefs.map((r, i) => {
|
|
1528
1531
|
const entityRefString = typeof r === "string" ? r : stringifyEntityRef(r);
|
|
1529
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, { key: `${i}.${entityRefString}` }, i > 0 && ", ", /* @__PURE__ */ React.createElement(EntityRefLink, { ...linkProps, entityRef: r }));
|
|
1532
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, { key: `${i}.${entityRefString}` }, i > 0 && ", ", /* @__PURE__ */ React.createElement(EntityRefLink, { ...linkProps, entityRef: r, hideIcon: hideIcons }));
|
|
1530
1533
|
}));
|
|
1531
1534
|
}
|
|
1532
1535
|
|
|
@@ -2324,13 +2327,14 @@ function OverviewPage(props) {
|
|
|
2324
2327
|
sortBy(relations, (r) => r.targetRef),
|
|
2325
2328
|
"type"
|
|
2326
2329
|
);
|
|
2330
|
+
const entityRef = stringifyEntityRef(props.entity);
|
|
2327
2331
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(DialogContentText, { variant: "h2" }, "Overview"), /* @__PURE__ */ React.createElement("div", { className: classes.root }, /* @__PURE__ */ React.createElement(Container, { title: "Identity" }, /* @__PURE__ */ React.createElement(List, { dense: true }, /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemText, { primary: "apiVersion", secondary: apiVersion })), /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemText, { primary: "kind", secondary: kind })), (spec == null ? void 0 : spec.type) && /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(
|
|
2328
2332
|
ListItemText,
|
|
2329
2333
|
{
|
|
2330
2334
|
primary: "spec.type",
|
|
2331
2335
|
secondary: (_a = spec.type) == null ? void 0 : _a.toString()
|
|
2332
2336
|
}
|
|
2333
|
-
)), metadata.uid && /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemText, { primary: "uid", secondary: metadata.uid })), metadata.etag && /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemText, { primary: "etag", secondary: metadata.etag })))), /* @__PURE__ */ React.createElement(Container, { title: "Metadata" }, !!Object.keys(metadata.annotations || {}).length && /* @__PURE__ */ React.createElement(
|
|
2337
|
+
)), metadata.uid && /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemText, { primary: "uid", secondary: metadata.uid }), /* @__PURE__ */ React.createElement(ListItemSecondaryAction, null, /* @__PURE__ */ React.createElement(CopyTextButton, { text: metadata.uid }))), metadata.etag && /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemText, { primary: "etag", secondary: metadata.etag }), /* @__PURE__ */ React.createElement(ListItemSecondaryAction, null, /* @__PURE__ */ React.createElement(CopyTextButton, { text: metadata.etag }))), /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemText, { primary: "entityRef", secondary: entityRef }), /* @__PURE__ */ React.createElement(ListItemSecondaryAction, null, /* @__PURE__ */ React.createElement(CopyTextButton, { text: entityRef }))))), /* @__PURE__ */ React.createElement(Container, { title: "Metadata" }, !!Object.keys(metadata.annotations || {}).length && /* @__PURE__ */ React.createElement(
|
|
2334
2338
|
List,
|
|
2335
2339
|
{
|
|
2336
2340
|
dense: true,
|
|
@@ -2668,58 +2672,48 @@ function useOwnedEntitiesCount() {
|
|
|
2668
2672
|
// load only on mount
|
|
2669
2673
|
[]
|
|
2670
2674
|
);
|
|
2671
|
-
const
|
|
2672
|
-
const
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
const allFilter = reduceCatalogFilters(compacted);
|
|
2676
|
-
const { ["metadata.name"]: metadata, ...filter2 } = allFilter;
|
|
2677
|
-
const countFilter = getOwnedCountClaims(owners, ownershipEntityRefs);
|
|
2678
|
-
if ((ownershipEntityRefs == null ? void 0 : ownershipEntityRefs.length) === 0 || countFilter === void 0 || Object.keys(filter2).length === 0) {
|
|
2679
|
-
prevRequest.current = void 0;
|
|
2680
|
-
return void 0;
|
|
2681
|
-
}
|
|
2682
|
-
const newRequest = {
|
|
2683
|
-
filter: {
|
|
2684
|
-
...filter2,
|
|
2685
|
-
"relations.ownedBy": countFilter
|
|
2686
|
-
},
|
|
2687
|
-
limit: 0
|
|
2688
|
-
};
|
|
2689
|
-
if (isEqual(newRequest, prevRequest.current)) {
|
|
2690
|
-
return prevRequest.current;
|
|
2691
|
-
}
|
|
2692
|
-
prevRequest.current = newRequest;
|
|
2693
|
-
return newRequest;
|
|
2694
|
-
}, [filters, ownershipEntityRefs]);
|
|
2675
|
+
const { user, owners, ...allFilters } = filters;
|
|
2676
|
+
const { ["metadata.name"]: metadata, ...filter } = reduceCatalogFilters(
|
|
2677
|
+
compact(Object.values(allFilters))
|
|
2678
|
+
);
|
|
2695
2679
|
const [{ value: count, loading: loadingEntityOwnership }, fetchEntities] = useAsyncFn(
|
|
2696
|
-
async (req
|
|
2697
|
-
|
|
2680
|
+
async (req) => {
|
|
2681
|
+
const ownedClaims = getOwnedCountClaims(
|
|
2682
|
+
req.owners,
|
|
2683
|
+
req.ownershipEntityRefs
|
|
2684
|
+
);
|
|
2685
|
+
if (ownedClaims === void 0) {
|
|
2698
2686
|
return 0;
|
|
2699
2687
|
}
|
|
2700
|
-
const { totalItems } = await catalogApi.queryEntities(
|
|
2688
|
+
const { totalItems } = await catalogApi.queryEntities({
|
|
2689
|
+
filter: {
|
|
2690
|
+
...req.filter,
|
|
2691
|
+
"relations.ownedBy": ownedClaims
|
|
2692
|
+
},
|
|
2693
|
+
limit: 0
|
|
2694
|
+
});
|
|
2701
2695
|
return totalItems;
|
|
2702
2696
|
},
|
|
2703
2697
|
[],
|
|
2704
2698
|
{ loading: true }
|
|
2705
2699
|
);
|
|
2706
|
-
|
|
2707
|
-
if (
|
|
2708
|
-
|
|
2709
|
-
return;
|
|
2710
|
-
}
|
|
2711
|
-
fetchEntities(request, ownershipEntityRefs);
|
|
2700
|
+
useDeepCompareEffect(() => {
|
|
2701
|
+
if (Object.keys(filter).length === 0) {
|
|
2702
|
+
return;
|
|
2712
2703
|
}
|
|
2713
|
-
|
|
2704
|
+
if (ownershipEntityRefs === void 0) {
|
|
2705
|
+
return;
|
|
2706
|
+
}
|
|
2707
|
+
fetchEntities({ ownershipEntityRefs, owners, filter });
|
|
2708
|
+
}, [ownershipEntityRefs, owners, filter]);
|
|
2714
2709
|
const loading = loadingEntityRefs || loadingEntityOwnership;
|
|
2715
|
-
const filter = useMemo(
|
|
2716
|
-
() => EntityUserFilter.owned(ownershipEntityRefs != null ? ownershipEntityRefs : []),
|
|
2717
|
-
[ownershipEntityRefs]
|
|
2718
|
-
);
|
|
2719
2710
|
return {
|
|
2720
2711
|
count,
|
|
2721
2712
|
loading,
|
|
2722
|
-
filter
|
|
2713
|
+
filter: useMemo(
|
|
2714
|
+
() => EntityUserFilter.owned(ownershipEntityRefs != null ? ownershipEntityRefs : []),
|
|
2715
|
+
[ownershipEntityRefs]
|
|
2716
|
+
),
|
|
2723
2717
|
ownershipEntityRefs
|
|
2724
2718
|
};
|
|
2725
2719
|
}
|
|
@@ -2975,7 +2969,6 @@ const UserListPicker = (props) => {
|
|
|
2975
2969
|
{
|
|
2976
2970
|
role: "none presentation",
|
|
2977
2971
|
key: item.id,
|
|
2978
|
-
button: true,
|
|
2979
2972
|
divider: true,
|
|
2980
2973
|
onClick: () => setSelectedUserFilter(item.id),
|
|
2981
2974
|
selected: item.id === ((_a2 = filters.user) == null ? void 0 : _a2.value),
|