@backstage/plugin-catalog-react 0.6.9 → 0.6.12
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/dist/index.cjs.js +57 -53
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +70 -11
- package/dist/index.esm.js +40 -42
- package/dist/index.esm.js.map +1 -1
- package/package.json +14 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-react
|
|
2
2
|
|
|
3
|
+
## 0.6.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3d87019269: The `entityRouteRef` is now a well-known route that should be imported directly from `@backstage/plugin-catalog-react`. It is guaranteed to be globally unique across duplicate installations of the `@backstage/plugin-catalog-react`, starting at this version.
|
|
8
|
+
|
|
9
|
+
Deprecated `entityRoute` in favor of `entityRouteRef`.
|
|
10
|
+
|
|
11
|
+
Deprecated `rootRoute` and `catalogRouteRef`. If you want to refer to the catalog index page from a public plugin you now need to use an `ExternalRouteRef` instead. For private plugins it is possible to take the shortcut of referring directly to `catalogPlugin.routes.indexPage` instead.
|
|
12
|
+
|
|
13
|
+
- 2916a83b9c: Deprecated `loadIdentityOwnerRefs`, since they can now be retrieved as `ownershipEntityRefs` from `identityApi.getBackstageIdentity()` instead.
|
|
14
|
+
- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods.
|
|
15
|
+
- c54c0d9d10: Add useEntityPermission hook
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- @backstage/plugin-permission-react@0.3.0
|
|
18
|
+
- @backstage/core-components@0.8.5
|
|
19
|
+
- @backstage/integration@0.7.2
|
|
20
|
+
- @backstage/plugin-permission-common@0.4.0
|
|
21
|
+
- @backstage/core-plugin-api@0.6.0
|
|
22
|
+
- @backstage/catalog-model@0.9.10
|
|
23
|
+
- @backstage/catalog-client@0.5.5
|
|
24
|
+
|
|
25
|
+
## 0.6.12-next.0
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- 2916a83b9c: Deprecated `loadIdentityOwnerRefs`, since they can now be retrieved as `ownershipEntityRefs` from `identityApi.getBackstageIdentity()` instead.
|
|
30
|
+
- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods.
|
|
31
|
+
- Updated dependencies
|
|
32
|
+
- @backstage/core-components@0.8.5-next.0
|
|
33
|
+
- @backstage/core-plugin-api@0.6.0-next.0
|
|
34
|
+
- @backstage/catalog-model@0.9.10-next.0
|
|
35
|
+
- @backstage/catalog-client@0.5.5-next.0
|
|
36
|
+
- @backstage/integration@0.7.2-next.0
|
|
37
|
+
|
|
38
|
+
## 0.6.11
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- 5333451def: Cleaned up API exports
|
|
43
|
+
- Updated dependencies
|
|
44
|
+
- @backstage/integration@0.7.1
|
|
45
|
+
- @backstage/core-components@0.8.4
|
|
46
|
+
- @backstage/core-plugin-api@0.5.0
|
|
47
|
+
- @backstage/errors@0.2.0
|
|
48
|
+
- @backstage/catalog-client@0.5.4
|
|
49
|
+
- @backstage/catalog-model@0.9.9
|
|
50
|
+
|
|
51
|
+
## 0.6.10
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- fe2a6532ff: Add Override Components for Components in @backstage/plugin-catalog-react
|
|
56
|
+
- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead.
|
|
57
|
+
- Updated dependencies
|
|
58
|
+
- @backstage/core-plugin-api@0.4.1
|
|
59
|
+
- @backstage/core-components@0.8.3
|
|
60
|
+
|
|
3
61
|
## 0.6.9
|
|
4
62
|
|
|
5
63
|
### Patch Changes
|
package/dist/index.cjs.js
CHANGED
|
@@ -11,12 +11,17 @@ var React = require('react');
|
|
|
11
11
|
var lab = require('@material-ui/lab');
|
|
12
12
|
var versionBridge = require('@backstage/version-bridge');
|
|
13
13
|
var reactRouter = require('react-router');
|
|
14
|
-
var
|
|
14
|
+
var useAsyncRetry = require('react-use/lib/useAsyncRetry');
|
|
15
15
|
var qs = require('qs');
|
|
16
|
+
var useAsyncFn = require('react-use/lib/useAsyncFn');
|
|
17
|
+
var useDebounce = require('react-use/lib/useDebounce');
|
|
18
|
+
var useMountedState = require('react-use/lib/useMountedState');
|
|
19
|
+
var useAsync = require('react-use/lib/useAsync');
|
|
16
20
|
var isEqual = require('lodash/isEqual');
|
|
17
21
|
var coreComponents = require('@backstage/core-components');
|
|
18
22
|
var core = require('@material-ui/core');
|
|
19
|
-
var
|
|
23
|
+
var useObservable = require('react-use/lib/useObservable');
|
|
24
|
+
var pluginPermissionReact = require('@backstage/plugin-permission-react');
|
|
20
25
|
var CheckBoxIcon = require('@material-ui/icons/CheckBox');
|
|
21
26
|
var CheckBoxOutlineBlankIcon = require('@material-ui/icons/CheckBoxOutlineBlank');
|
|
22
27
|
var ExpandMoreIcon = require('@material-ui/icons/ExpandMore');
|
|
@@ -33,9 +38,14 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
33
38
|
|
|
34
39
|
var ObservableImpl__default = /*#__PURE__*/_interopDefaultLegacy(ObservableImpl);
|
|
35
40
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
41
|
+
var useAsyncRetry__default = /*#__PURE__*/_interopDefaultLegacy(useAsyncRetry);
|
|
36
42
|
var qs__default = /*#__PURE__*/_interopDefaultLegacy(qs);
|
|
43
|
+
var useAsyncFn__default = /*#__PURE__*/_interopDefaultLegacy(useAsyncFn);
|
|
44
|
+
var useDebounce__default = /*#__PURE__*/_interopDefaultLegacy(useDebounce);
|
|
45
|
+
var useMountedState__default = /*#__PURE__*/_interopDefaultLegacy(useMountedState);
|
|
46
|
+
var useAsync__default = /*#__PURE__*/_interopDefaultLegacy(useAsync);
|
|
37
47
|
var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
|
|
38
|
-
var
|
|
48
|
+
var useObservable__default = /*#__PURE__*/_interopDefaultLegacy(useObservable);
|
|
39
49
|
var CheckBoxIcon__default = /*#__PURE__*/_interopDefaultLegacy(CheckBoxIcon);
|
|
40
50
|
var CheckBoxOutlineBlankIcon__default = /*#__PURE__*/_interopDefaultLegacy(CheckBoxOutlineBlankIcon);
|
|
41
51
|
var ExpandMoreIcon__default = /*#__PURE__*/_interopDefaultLegacy(ExpandMoreIcon);
|
|
@@ -118,11 +128,11 @@ const rootRoute = corePluginApi.createRouteRef({
|
|
|
118
128
|
id: "catalog"
|
|
119
129
|
});
|
|
120
130
|
const catalogRouteRef = rootRoute;
|
|
121
|
-
const
|
|
131
|
+
const entityRouteRef = versionBridge.getOrCreateGlobalSingleton("catalog:entity-route-ref", () => corePluginApi.createRouteRef({
|
|
122
132
|
id: "catalog:entity",
|
|
123
133
|
params: ["namespace", "kind", "name"]
|
|
124
|
-
});
|
|
125
|
-
const
|
|
134
|
+
}));
|
|
135
|
+
const entityRoute = entityRouteRef;
|
|
126
136
|
function entityRouteParams(entity) {
|
|
127
137
|
var _a, _b;
|
|
128
138
|
return {
|
|
@@ -187,7 +197,7 @@ const useEntityFromUrl = () => {
|
|
|
187
197
|
error,
|
|
188
198
|
loading,
|
|
189
199
|
retry: refresh
|
|
190
|
-
} =
|
|
200
|
+
} = useAsyncRetry__default["default"](() => catalogApi.getEntityByName({ kind, namespace, name }), [catalogApi, kind, namespace, name]);
|
|
191
201
|
React.useEffect(() => {
|
|
192
202
|
if (!name) {
|
|
193
203
|
errorApi.post(new Error("No name provided!"));
|
|
@@ -281,7 +291,7 @@ const EntityListContext = React.createContext(void 0);
|
|
|
281
291
|
const EntityListProvider = ({
|
|
282
292
|
children
|
|
283
293
|
}) => {
|
|
284
|
-
const isMounted =
|
|
294
|
+
const isMounted = useMountedState__default["default"]();
|
|
285
295
|
const catalogApi = corePluginApi.useApi(catalogApiRef);
|
|
286
296
|
const [requestedFilters, setRequestedFilters] = React.useState({});
|
|
287
297
|
const [outputState, setOutputState] = React.useState(() => {
|
|
@@ -296,7 +306,7 @@ const EntityListProvider = ({
|
|
|
296
306
|
queryParameters: (_a = query.filters) != null ? _a : {}
|
|
297
307
|
};
|
|
298
308
|
});
|
|
299
|
-
const [{ loading, error }, refresh] =
|
|
309
|
+
const [{ loading, error }, refresh] = useAsyncFn__default["default"](async () => {
|
|
300
310
|
var _a;
|
|
301
311
|
const compacted = lodash.compact(Object.values(requestedFilters));
|
|
302
312
|
const entityFilter = reduceEntityFilters(compacted);
|
|
@@ -336,7 +346,7 @@ const EntityListProvider = ({
|
|
|
336
346
|
(_a = window.history) == null ? void 0 : _a.replaceState(null, document.title, newUrl);
|
|
337
347
|
}
|
|
338
348
|
}, [catalogApi, requestedFilters, outputState], { loading: true });
|
|
339
|
-
|
|
349
|
+
useDebounce__default["default"](refresh, 10, [requestedFilters]);
|
|
340
350
|
const updateFilters = React.useCallback((update) => {
|
|
341
351
|
setRequestedFilters((prevFilters) => {
|
|
342
352
|
const newFilters = typeof update === "function" ? update(prevFilters) : update;
|
|
@@ -546,7 +556,7 @@ function useEntityTypeFilter() {
|
|
|
546
556
|
error,
|
|
547
557
|
loading,
|
|
548
558
|
value: entities
|
|
549
|
-
} =
|
|
559
|
+
} = useAsync__default["default"](async () => {
|
|
550
560
|
if (kind) {
|
|
551
561
|
const items = await catalogApi.getEntities({
|
|
552
562
|
filter: { kind },
|
|
@@ -603,7 +613,7 @@ function useEntityKinds() {
|
|
|
603
613
|
error,
|
|
604
614
|
loading,
|
|
605
615
|
value: kinds
|
|
606
|
-
} =
|
|
616
|
+
} = useAsync__default["default"](async () => {
|
|
607
617
|
const entities = await catalogApi.getEntities({ fields: ["kind"] }).then((response) => response.items);
|
|
608
618
|
return [...new Set(entities.map((e) => e.kind))].sort();
|
|
609
619
|
});
|
|
@@ -613,11 +623,13 @@ function useEntityKinds() {
|
|
|
613
623
|
function useOwnUser() {
|
|
614
624
|
const catalogApi = corePluginApi.useApi(catalogApiRef);
|
|
615
625
|
const identityApi = corePluginApi.useApi(corePluginApi.identityApiRef);
|
|
616
|
-
return
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
626
|
+
return useAsync__default["default"](async () => {
|
|
627
|
+
const identity = await identityApi.getBackstageIdentity();
|
|
628
|
+
return catalogApi.getEntityByName(catalogModel.parseEntityRef(identity.userEntityRef, {
|
|
629
|
+
defaultKind: "User",
|
|
630
|
+
defaultNamespace: catalogModel.ENTITY_DEFAULT_NAMESPACE
|
|
631
|
+
}));
|
|
632
|
+
}, [catalogApi, identityApi]);
|
|
621
633
|
}
|
|
622
634
|
|
|
623
635
|
const BATCH_SIZE = 20;
|
|
@@ -627,7 +639,7 @@ function useRelatedEntities(entity, { type, kind }) {
|
|
|
627
639
|
loading,
|
|
628
640
|
value: entities,
|
|
629
641
|
error
|
|
630
|
-
} =
|
|
642
|
+
} = useAsync__default["default"](async () => {
|
|
631
643
|
const relations = entity.relations && entity.relations.filter((r) => (!type || r.type.toLocaleLowerCase("en-US") === type.toLocaleLowerCase("en-US")) && (!kind || r.target.kind.toLocaleLowerCase("en-US") === kind.toLocaleLowerCase("en-US")));
|
|
632
644
|
if (!relations) {
|
|
633
645
|
return [];
|
|
@@ -668,7 +680,7 @@ function getEntityRef$1(entityOrRef) {
|
|
|
668
680
|
}
|
|
669
681
|
function useStarredEntities() {
|
|
670
682
|
const starredEntitiesApi = corePluginApi.useApi(starredEntitiesApiRef);
|
|
671
|
-
const starredEntities =
|
|
683
|
+
const starredEntities = useObservable__default["default"](starredEntitiesApi.starredEntitie$(), /* @__PURE__ */ new Set());
|
|
672
684
|
const isStarredEntity = React.useCallback((entityOrRef) => starredEntities.has(getEntityRef$1(entityOrRef)), [starredEntities]);
|
|
673
685
|
const toggleStarredEntity = React.useCallback((entityOrRef) => starredEntitiesApi.toggleStarred(getEntityRef$1(entityOrRef)).then(), [starredEntitiesApi]);
|
|
674
686
|
return {
|
|
@@ -701,34 +713,9 @@ function useStarredEntity(entityOrRef) {
|
|
|
701
713
|
};
|
|
702
714
|
}
|
|
703
715
|
|
|
704
|
-
function extendUserId(id) {
|
|
705
|
-
try {
|
|
706
|
-
const ref = catalogModel.parseEntityRef(id, {
|
|
707
|
-
defaultKind: "User",
|
|
708
|
-
defaultNamespace: "default"
|
|
709
|
-
});
|
|
710
|
-
return catalogModel.stringifyEntityRef(ref);
|
|
711
|
-
} catch {
|
|
712
|
-
return id;
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
716
|
async function loadIdentityOwnerRefs(identityApi) {
|
|
716
|
-
const
|
|
717
|
-
|
|
718
|
-
const result = [];
|
|
719
|
-
if (id) {
|
|
720
|
-
result.push(extendUserId(id));
|
|
721
|
-
}
|
|
722
|
-
if (token) {
|
|
723
|
-
try {
|
|
724
|
-
const decoded = jwtDecoder__default["default"](token);
|
|
725
|
-
if (decoded == null ? void 0 : decoded.ent) {
|
|
726
|
-
[decoded.ent].flat().filter((x) => typeof x === "string").map((x) => x.toLocaleLowerCase("en-US")).forEach((x) => result.push(x));
|
|
727
|
-
}
|
|
728
|
-
} catch {
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
return result;
|
|
717
|
+
const identity = await identityApi.getBackstageIdentity();
|
|
718
|
+
return identity.ownershipEntityRefs;
|
|
732
719
|
}
|
|
733
720
|
async function loadCatalogOwnerRefs(catalogApi, identityOwnerRefs) {
|
|
734
721
|
const result = new Array();
|
|
@@ -749,10 +736,10 @@ async function loadCatalogOwnerRefs(catalogApi, identityOwnerRefs) {
|
|
|
749
736
|
function useEntityOwnership() {
|
|
750
737
|
const identityApi = corePluginApi.useApi(corePluginApi.identityApiRef);
|
|
751
738
|
const catalogApi = corePluginApi.useApi(catalogApiRef);
|
|
752
|
-
const { loading, value: refs } =
|
|
753
|
-
const
|
|
754
|
-
const catalogRefs = await loadCatalogOwnerRefs(catalogApi,
|
|
755
|
-
return /* @__PURE__ */ new Set([...
|
|
739
|
+
const { loading, value: refs } = useAsync__default["default"](async () => {
|
|
740
|
+
const { ownershipEntityRefs } = await identityApi.getBackstageIdentity();
|
|
741
|
+
const catalogRefs = await loadCatalogOwnerRefs(catalogApi, ownershipEntityRefs);
|
|
742
|
+
return /* @__PURE__ */ new Set([...ownershipEntityRefs, ...catalogRefs]);
|
|
756
743
|
}, []);
|
|
757
744
|
const isOwnedEntity = React.useMemo(() => {
|
|
758
745
|
const myOwnerRefs = new Set(refs != null ? refs : []);
|
|
@@ -772,7 +759,7 @@ function useEntityOwnership() {
|
|
|
772
759
|
function useOwnedEntities(allowedKinds) {
|
|
773
760
|
const identityApi = corePluginApi.useApi(corePluginApi.identityApiRef);
|
|
774
761
|
const catalogApi = corePluginApi.useApi(catalogApiRef);
|
|
775
|
-
const { loading, value: refs } =
|
|
762
|
+
const { loading, value: refs } = useAsync__default["default"](async () => {
|
|
776
763
|
const identityRefs = await loadIdentityOwnerRefs(identityApi);
|
|
777
764
|
const catalogRefs = await loadCatalogOwnerRefs(catalogApi, identityRefs);
|
|
778
765
|
const catalogs = await catalogApi.getEntities(allowedKinds ? {
|
|
@@ -793,6 +780,22 @@ function useOwnedEntities(allowedKinds) {
|
|
|
793
780
|
return React.useMemo(() => ({ loading, ownedEntities }), [loading, ownedEntities]);
|
|
794
781
|
}
|
|
795
782
|
|
|
783
|
+
function useEntityPermission(permission) {
|
|
784
|
+
const { entity, loading: loadingEntity, error: entityError } = useEntity();
|
|
785
|
+
const {
|
|
786
|
+
allowed,
|
|
787
|
+
loading: loadingPermission,
|
|
788
|
+
error: permissionError
|
|
789
|
+
} = pluginPermissionReact.usePermission(permission, entity ? catalogModel.stringifyEntityRef(entity) : void 0);
|
|
790
|
+
if (loadingEntity || loadingPermission) {
|
|
791
|
+
return { loading: true, allowed: false };
|
|
792
|
+
}
|
|
793
|
+
if (entityError) {
|
|
794
|
+
return { loading: false, allowed: false, error: entityError };
|
|
795
|
+
}
|
|
796
|
+
return { loading: false, allowed, error: permissionError };
|
|
797
|
+
}
|
|
798
|
+
|
|
796
799
|
const EntityKindPicker = ({
|
|
797
800
|
initialFilter,
|
|
798
801
|
hidden
|
|
@@ -945,7 +948,7 @@ const EntitySearchBar = () => {
|
|
|
945
948
|
const classes = useStyles$4();
|
|
946
949
|
const { filters, updateFilters } = useEntityListProvider();
|
|
947
950
|
const [search, setSearch] = React.useState((_b = (_a = filters.text) == null ? void 0 : _a.value) != null ? _b : "");
|
|
948
|
-
|
|
951
|
+
useDebounce__default["default"](() => {
|
|
949
952
|
updateFilters({
|
|
950
953
|
text: search.length ? new EntityTextFilter(search) : void 0
|
|
951
954
|
});
|
|
@@ -1268,7 +1271,7 @@ function useUnregisterEntityDialogState(entity) {
|
|
|
1268
1271
|
const locationRef = (_a = entity.metadata.annotations) == null ? void 0 : _a[catalogModel.ORIGIN_LOCATION_ANNOTATION];
|
|
1269
1272
|
const uid = entity.metadata.uid;
|
|
1270
1273
|
const isBootstrap = locationRef === "bootstrap:bootstrap";
|
|
1271
|
-
const prerequisites =
|
|
1274
|
+
const prerequisites = useAsync__default["default"](async () => {
|
|
1272
1275
|
const locationPromise = catalogApi.getOriginLocationByEntity(entity);
|
|
1273
1276
|
let colocatedEntitiesPromise;
|
|
1274
1277
|
if (!locationRef) {
|
|
@@ -1662,6 +1665,7 @@ exports.useEntityFromUrl = useEntityFromUrl;
|
|
|
1662
1665
|
exports.useEntityKinds = useEntityKinds;
|
|
1663
1666
|
exports.useEntityListProvider = useEntityListProvider;
|
|
1664
1667
|
exports.useEntityOwnership = useEntityOwnership;
|
|
1668
|
+
exports.useEntityPermission = useEntityPermission;
|
|
1665
1669
|
exports.useEntityTypeFilter = useEntityTypeFilter;
|
|
1666
1670
|
exports.useOwnUser = useOwnUser;
|
|
1667
1671
|
exports.useOwnedEntities = useOwnedEntities;
|