@backstage/plugin-catalog-react 1.7.0-next.2 → 1.7.0-next.3
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/alpha/package.json +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.esm.js +184 -63
- package/dist/index.esm.js.map +1 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-react
|
|
2
2
|
|
|
3
|
+
## 1.7.0-next.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/core-components@0.13.2-next.3
|
|
9
|
+
- @backstage/catalog-model@1.4.0-next.1
|
|
10
|
+
- @backstage/catalog-client@1.4.2-next.2
|
|
11
|
+
- @backstage/core-plugin-api@1.5.2-next.0
|
|
12
|
+
- @backstage/errors@1.2.0-next.0
|
|
13
|
+
- @backstage/integration@1.5.0-next.0
|
|
14
|
+
- @backstage/theme@0.4.0-next.1
|
|
15
|
+
- @backstage/types@1.0.2
|
|
16
|
+
- @backstage/version-bridge@1.0.4
|
|
17
|
+
- @backstage/plugin-catalog-common@1.0.14-next.1
|
|
18
|
+
- @backstage/plugin-permission-common@0.7.6-next.0
|
|
19
|
+
- @backstage/plugin-permission-react@0.4.13-next.0
|
|
20
|
+
|
|
3
21
|
## 1.7.0-next.2
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/alpha/package.json
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -95,8 +95,14 @@ declare const EntityLifecyclePicker: (props: {
|
|
|
95
95
|
|
|
96
96
|
/** @public */
|
|
97
97
|
type CatalogReactEntityOwnerPickerClassKey = 'input';
|
|
98
|
+
/**
|
|
99
|
+
* @public
|
|
100
|
+
*/
|
|
101
|
+
type EntityOwnerPickerProps = {
|
|
102
|
+
mode?: 'owners-only' | 'all';
|
|
103
|
+
};
|
|
98
104
|
/** @public */
|
|
99
|
-
declare const EntityOwnerPicker: () => JSX.Element | null;
|
|
105
|
+
declare const EntityOwnerPicker: (props?: EntityOwnerPickerProps) => JSX.Element | null;
|
|
100
106
|
|
|
101
107
|
/**
|
|
102
108
|
* Props for {@link EntityRefLink}.
|
|
@@ -673,4 +679,4 @@ type EntitySourceLocation = {
|
|
|
673
679
|
/** @public */
|
|
674
680
|
declare function getEntitySourceLocation(entity: Entity, scmIntegrationsApi: ScmIntegrationRegistry): EntitySourceLocation | undefined;
|
|
675
681
|
|
|
676
|
-
export { AsyncEntityProvider, AsyncEntityProviderProps, BackstageOverrides, CatalogFilterLayout, CatalogReactComponentsNameToClassKey, CatalogReactEntityLifecyclePickerClassKey, CatalogReactEntityNamespacePickerClassKey, CatalogReactEntityOwnerPickerClassKey, CatalogReactEntityProcessingStatusPickerClassKey, CatalogReactEntitySearchBarClassKey, CatalogReactEntityTagPickerClassKey, CatalogReactUserListPickerClassKey, DefaultEntityFilters, EntityErrorFilter, EntityFilter, EntityKindFilter, EntityKindPicker, EntityKindPickerProps, EntityLifecycleFilter, EntityLifecyclePicker, EntityListContext, EntityListContextProps, EntityListProvider, EntityLoadingStatus, EntityNamespaceFilter, EntityNamespacePicker, EntityOrphanFilter, EntityOwnerFilter, EntityOwnerPicker, EntityPeekAheadPopover, EntityPeekAheadPopoverProps, EntityProcessingStatusPicker, EntityProvider, EntityProviderProps, EntityRefLink, EntityRefLinkProps, EntityRefLinks, EntityRefLinksProps, EntitySearchBar, EntitySourceLocation, EntityTable, EntityTableProps, EntityTagFilter, EntityTagPicker, EntityTagPickerProps, EntityTextFilter, EntityTypeFilter, EntityTypePicker, EntityTypePickerProps, FavoriteEntity, FavoriteEntityProps, InspectEntityDialog, MockEntityListContextProvider, MockStarredEntitiesApi, StarredEntitiesApi, UnregisterEntityDialog, UnregisterEntityDialogProps, UserListFilter, UserListFilterKind, UserListPicker, UserListPickerProps, catalogApiRef, columnFactories, entityRouteParams, entityRouteRef, getEntityRelations, getEntitySourceLocation, humanizeEntityRef, starredEntitiesApiRef, useAsyncEntity, useEntity, useEntityList, useEntityOwnership, useEntityTypeFilter, useRelatedEntities, useStarredEntities, useStarredEntity };
|
|
682
|
+
export { AsyncEntityProvider, AsyncEntityProviderProps, BackstageOverrides, CatalogFilterLayout, CatalogReactComponentsNameToClassKey, CatalogReactEntityLifecyclePickerClassKey, CatalogReactEntityNamespacePickerClassKey, CatalogReactEntityOwnerPickerClassKey, CatalogReactEntityProcessingStatusPickerClassKey, CatalogReactEntitySearchBarClassKey, CatalogReactEntityTagPickerClassKey, CatalogReactUserListPickerClassKey, DefaultEntityFilters, EntityErrorFilter, EntityFilter, EntityKindFilter, EntityKindPicker, EntityKindPickerProps, EntityLifecycleFilter, EntityLifecyclePicker, EntityListContext, EntityListContextProps, EntityListProvider, EntityLoadingStatus, EntityNamespaceFilter, EntityNamespacePicker, EntityOrphanFilter, EntityOwnerFilter, EntityOwnerPicker, EntityOwnerPickerProps, EntityPeekAheadPopover, EntityPeekAheadPopoverProps, EntityProcessingStatusPicker, EntityProvider, EntityProviderProps, EntityRefLink, EntityRefLinkProps, EntityRefLinks, EntityRefLinksProps, EntitySearchBar, EntitySourceLocation, EntityTable, EntityTableProps, EntityTagFilter, EntityTagPicker, EntityTagPickerProps, EntityTextFilter, EntityTypeFilter, EntityTypePicker, EntityTypePickerProps, FavoriteEntity, FavoriteEntityProps, InspectEntityDialog, MockEntityListContextProvider, MockStarredEntitiesApi, StarredEntitiesApi, UnregisterEntityDialog, UnregisterEntityDialogProps, UserListFilter, UserListFilterKind, UserListPicker, UserListPickerProps, catalogApiRef, columnFactories, entityRouteParams, entityRouteRef, getEntityRelations, getEntitySourceLocation, humanizeEntityRef, starredEntitiesApiRef, useAsyncEntity, useEntity, useEntityList, useEntityOwnership, useEntityTypeFilter, useRelatedEntities, useStarredEntities, useStarredEntity };
|
package/dist/index.esm.js
CHANGED
|
@@ -23,7 +23,7 @@ import { Autocomplete, Alert } from '@material-ui/lab';
|
|
|
23
23
|
import CheckBoxIcon from '@material-ui/icons/CheckBox';
|
|
24
24
|
import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';
|
|
25
25
|
import classNames from 'classnames';
|
|
26
|
-
import { useDebouncedEffect } from '@react-hookz/web';
|
|
26
|
+
import { useMountEffect, useDebouncedEffect } from '@react-hookz/web';
|
|
27
27
|
import PersonIcon from '@material-ui/icons/Person';
|
|
28
28
|
import GroupIcon from '@material-ui/icons/Group';
|
|
29
29
|
import get from 'lodash/get';
|
|
@@ -875,42 +875,105 @@ function humanizeEntity(entity, defaultName) {
|
|
|
875
875
|
return defaultName;
|
|
876
876
|
}
|
|
877
877
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
878
|
+
function useFacetsEntities({ enabled }) {
|
|
879
|
+
const catalogApi = useApi(catalogApiRef);
|
|
880
|
+
const [facetsPromise] = useState(async () => {
|
|
881
|
+
if (!enabled) {
|
|
882
|
+
return [];
|
|
883
|
+
}
|
|
884
|
+
const facet = "relations.ownedBy";
|
|
885
|
+
return catalogApi.getEntityFacets({ facets: [facet] }).then(
|
|
886
|
+
(response) => response.facets[facet].map((e) => e.value).map((ref) => {
|
|
887
|
+
const { kind, name, namespace } = parseEntityRef(ref);
|
|
888
|
+
return {
|
|
889
|
+
apiVersion: "backstage.io/v1beta1",
|
|
890
|
+
kind,
|
|
891
|
+
metadata: { name, namespace }
|
|
892
|
+
};
|
|
893
|
+
}).sort(
|
|
894
|
+
(a, b) => (a.metadata.namespace || "").localeCompare(
|
|
895
|
+
b.metadata.namespace || "",
|
|
896
|
+
"en-US"
|
|
897
|
+
) || a.metadata.name.localeCompare(b.metadata.name, "en-US") || a.kind.localeCompare(b.kind, "en-US")
|
|
898
|
+
)
|
|
899
|
+
).catch(() => []);
|
|
900
|
+
});
|
|
901
|
+
return useAsyncFn(
|
|
902
|
+
async (request, options) => {
|
|
903
|
+
var _a;
|
|
904
|
+
const facets = await facetsPromise;
|
|
905
|
+
if (!facets) {
|
|
906
|
+
return {
|
|
907
|
+
items: []
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
const limit = (_a = options == null ? void 0 : options.limit) != null ? _a : 20;
|
|
911
|
+
const { text, start } = decodeCursor(request);
|
|
912
|
+
const filteredRefs = facets.filter((e) => filterEntity(text, e));
|
|
913
|
+
const end = start + limit;
|
|
914
|
+
return {
|
|
915
|
+
items: filteredRefs.slice(0, end),
|
|
916
|
+
...encodeCursor({
|
|
917
|
+
entities: filteredRefs,
|
|
918
|
+
limit: end,
|
|
919
|
+
payload: {
|
|
920
|
+
text,
|
|
921
|
+
start: end
|
|
922
|
+
}
|
|
923
|
+
})
|
|
924
|
+
};
|
|
925
|
+
},
|
|
926
|
+
[facetsPromise],
|
|
927
|
+
{ loading: true, value: { items: [] } }
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
function decodeCursor(request) {
|
|
931
|
+
if (isFacetsResponse(request) && request.cursor) {
|
|
932
|
+
return JSON.parse(atob(request.cursor));
|
|
884
933
|
}
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
934
|
+
return {
|
|
935
|
+
text: request.text || "",
|
|
936
|
+
start: 0
|
|
937
|
+
};
|
|
938
|
+
}
|
|
939
|
+
function isFacetsResponse(request) {
|
|
940
|
+
return !!request.cursor;
|
|
941
|
+
}
|
|
942
|
+
function encodeCursor({
|
|
943
|
+
entities,
|
|
944
|
+
limit,
|
|
945
|
+
payload
|
|
946
|
+
}) {
|
|
947
|
+
if (entities.length > limit) {
|
|
948
|
+
return { cursor: btoa(JSON.stringify(payload)) };
|
|
949
|
+
}
|
|
950
|
+
return {};
|
|
951
|
+
}
|
|
952
|
+
function filterEntity(text, entity) {
|
|
953
|
+
var _a;
|
|
954
|
+
const normalizedText = text.trim();
|
|
955
|
+
return entity.kind.includes(normalizedText) || ((_a = entity.metadata.namespace) == null ? void 0 : _a.includes(normalizedText)) || entity.metadata.name.includes(normalizedText);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
function useQueryEntities() {
|
|
896
959
|
const catalogApi = useApi(catalogApiRef);
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
960
|
+
return useAsyncFn(
|
|
961
|
+
async (request, options) => {
|
|
962
|
+
var _a;
|
|
900
963
|
const initialRequest = request;
|
|
901
964
|
const cursorRequest = request;
|
|
902
|
-
const limit = 20;
|
|
965
|
+
const limit = (_a = options == null ? void 0 : options.limit) != null ? _a : 20;
|
|
903
966
|
if (cursorRequest.cursor) {
|
|
904
|
-
const
|
|
967
|
+
const response2 = await catalogApi.queryEntities({
|
|
905
968
|
cursor: cursorRequest.cursor,
|
|
906
969
|
limit
|
|
907
970
|
});
|
|
908
971
|
return {
|
|
909
|
-
|
|
910
|
-
items: [...cursorRequest.
|
|
972
|
+
cursor: response2.pageInfo.nextCursor,
|
|
973
|
+
items: [...cursorRequest.items, ...response2.items]
|
|
911
974
|
};
|
|
912
975
|
}
|
|
913
|
-
|
|
976
|
+
const response = await catalogApi.queryEntities({
|
|
914
977
|
fullTextFilter: {
|
|
915
978
|
term: initialRequest.text || "",
|
|
916
979
|
fields: [
|
|
@@ -924,11 +987,84 @@ const EntityOwnerPicker = () => {
|
|
|
924
987
|
orderFields: [{ field: "metadata.name", order: "asc" }],
|
|
925
988
|
limit
|
|
926
989
|
});
|
|
990
|
+
return {
|
|
991
|
+
cursor: response.pageInfo.nextCursor,
|
|
992
|
+
items: response.items
|
|
993
|
+
};
|
|
927
994
|
},
|
|
928
|
-
[
|
|
995
|
+
[],
|
|
996
|
+
{ loading: true }
|
|
929
997
|
);
|
|
930
|
-
|
|
931
|
-
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
function useFetchEntities({
|
|
1001
|
+
mode,
|
|
1002
|
+
initialSelectedOwnersRefs
|
|
1003
|
+
}) {
|
|
1004
|
+
const isOwnersOnlyMode = mode === "owners-only";
|
|
1005
|
+
const queryEntitiesResponse = useQueryEntities();
|
|
1006
|
+
const facetsEntitiesResponse = useFacetsEntities({
|
|
1007
|
+
enabled: isOwnersOnlyMode
|
|
1008
|
+
});
|
|
1009
|
+
const [state, handleFetch] = isOwnersOnlyMode ? facetsEntitiesResponse : queryEntitiesResponse;
|
|
1010
|
+
return [
|
|
1011
|
+
state,
|
|
1012
|
+
handleFetch,
|
|
1013
|
+
useSelectedOwners({
|
|
1014
|
+
enabled: !isOwnersOnlyMode,
|
|
1015
|
+
initialSelectedOwnersRefs
|
|
1016
|
+
})
|
|
1017
|
+
];
|
|
1018
|
+
}
|
|
1019
|
+
function useSelectedOwners({
|
|
1020
|
+
enabled,
|
|
1021
|
+
initialSelectedOwnersRefs
|
|
1022
|
+
}) {
|
|
1023
|
+
const allEntities = useRef({});
|
|
1024
|
+
const catalogApi = useApi(catalogApiRef);
|
|
1025
|
+
const [, handleFetch] = useAsyncFn(async () => {
|
|
1026
|
+
const initialSelectedEntities = await catalogApi.getEntitiesByRefs({
|
|
1027
|
+
entityRefs: initialSelectedOwnersRefs
|
|
1028
|
+
});
|
|
1029
|
+
initialSelectedEntities.items.forEach((e) => {
|
|
1030
|
+
if (e) {
|
|
1031
|
+
allEntities.current[stringifyEntityRef(e)] = e;
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
1034
|
+
}, []);
|
|
1035
|
+
useMountEffect(() => {
|
|
1036
|
+
if (enabled && initialSelectedOwnersRefs.length > 0) {
|
|
1037
|
+
handleFetch();
|
|
1038
|
+
}
|
|
1039
|
+
});
|
|
1040
|
+
return {
|
|
1041
|
+
getEntity: (entityRef) => allEntities.current[entityRef],
|
|
1042
|
+
setEntity: (entity) => {
|
|
1043
|
+
allEntities.current[stringifyEntityRef(entity)] = entity;
|
|
1044
|
+
}
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
const useStyles$d = makeStyles(
|
|
1049
|
+
{
|
|
1050
|
+
input: {}
|
|
1051
|
+
},
|
|
1052
|
+
{
|
|
1053
|
+
name: "CatalogReactEntityOwnerPicker"
|
|
1054
|
+
}
|
|
1055
|
+
);
|
|
1056
|
+
const icon$1 = /* @__PURE__ */ React.createElement(CheckBoxOutlineBlankIcon, { fontSize: "small" });
|
|
1057
|
+
const checkedIcon$1 = /* @__PURE__ */ React.createElement(CheckBoxIcon, { fontSize: "small" });
|
|
1058
|
+
const EntityOwnerPicker = (props) => {
|
|
1059
|
+
var _a, _b, _c;
|
|
1060
|
+
const classes = useStyles$d();
|
|
1061
|
+
const { mode = "owners-only" } = props || {};
|
|
1062
|
+
const {
|
|
1063
|
+
updateFilters,
|
|
1064
|
+
filters,
|
|
1065
|
+
queryParameters: { owners: ownersParameter }
|
|
1066
|
+
} = useEntityList();
|
|
1067
|
+
const [text, setText] = useState("");
|
|
932
1068
|
const queryParamOwners = useMemo(
|
|
933
1069
|
() => [ownersParameter].flat().filter(Boolean),
|
|
934
1070
|
[ownersParameter]
|
|
@@ -936,7 +1072,12 @@ const EntityOwnerPicker = () => {
|
|
|
936
1072
|
const [selectedOwners, setSelectedOwners] = useState(
|
|
937
1073
|
queryParamOwners.length ? queryParamOwners : (_b = (_a = filters.owners) == null ? void 0 : _a.values) != null ? _b : []
|
|
938
1074
|
);
|
|
939
|
-
const {
|
|
1075
|
+
const [{ value, loading }, handleFetch, cache] = useFetchEntities({
|
|
1076
|
+
mode,
|
|
1077
|
+
initialSelectedOwnersRefs: selectedOwners
|
|
1078
|
+
});
|
|
1079
|
+
useDebouncedEffect(() => handleFetch({ text }), [text, handleFetch], 250);
|
|
1080
|
+
const availableOwners = (value == null ? void 0 : value.items) || [];
|
|
940
1081
|
useEffect(() => {
|
|
941
1082
|
if (queryParamOwners.length) {
|
|
942
1083
|
const filter = new EntityOwnerFilter(queryParamOwners);
|
|
@@ -968,8 +1109,11 @@ const EntityOwnerPicker = () => {
|
|
|
968
1109
|
return o === v;
|
|
969
1110
|
},
|
|
970
1111
|
getOptionLabel: (o) => {
|
|
971
|
-
const entity = typeof o === "string" ? getEntity(o) || o
|
|
972
|
-
|
|
1112
|
+
const entity = typeof o === "string" ? cache.getEntity(o) || parseEntityRef(o, {
|
|
1113
|
+
defaultKind: "group",
|
|
1114
|
+
defaultNamespace: "default"
|
|
1115
|
+
}) : o;
|
|
1116
|
+
return humanizeEntity(entity, humanizeEntityRef(entity));
|
|
973
1117
|
},
|
|
974
1118
|
onChange: (_, owners) => {
|
|
975
1119
|
setText("");
|
|
@@ -977,7 +1121,7 @@ const EntityOwnerPicker = () => {
|
|
|
977
1121
|
owners.map((e) => {
|
|
978
1122
|
const entityRef = typeof e === "string" ? e : stringifyEntityRef(e);
|
|
979
1123
|
if (typeof e !== "string") {
|
|
980
|
-
setEntity(e);
|
|
1124
|
+
cache.setEntity(e);
|
|
981
1125
|
}
|
|
982
1126
|
return entityRef;
|
|
983
1127
|
})
|
|
@@ -985,7 +1129,7 @@ const EntityOwnerPicker = () => {
|
|
|
985
1129
|
},
|
|
986
1130
|
filterOptions: (x) => x,
|
|
987
1131
|
renderOption: (entity, { selected }) => {
|
|
988
|
-
const isGroup = entity.kind === "
|
|
1132
|
+
const isGroup = entity.kind.toLocaleLowerCase("en-US") === "group";
|
|
989
1133
|
return /* @__PURE__ */ React.createElement(
|
|
990
1134
|
FormControlLabel,
|
|
991
1135
|
{
|
|
@@ -998,7 +1142,10 @@ const EntityOwnerPicker = () => {
|
|
|
998
1142
|
}
|
|
999
1143
|
),
|
|
1000
1144
|
onClick: (event) => event.preventDefault(),
|
|
1001
|
-
label: /* @__PURE__ */ React.createElement(Box, { display: "flex", flexWrap: "wrap", alignItems: "center" }, isGroup ? /* @__PURE__ */ React.createElement(GroupIcon, { fontSize: "small" }) : /* @__PURE__ */ React.createElement(PersonIcon, { fontSize: "small" }), "\xA0", humanizeEntity(
|
|
1145
|
+
label: /* @__PURE__ */ React.createElement(Box, { display: "flex", flexWrap: "wrap", alignItems: "center" }, isGroup ? /* @__PURE__ */ React.createElement(GroupIcon, { fontSize: "small" }) : /* @__PURE__ */ React.createElement(PersonIcon, { fontSize: "small" }), "\xA0", humanizeEntity(
|
|
1146
|
+
entity,
|
|
1147
|
+
humanizeEntityRef(entity, { defaultKind: entity.kind })
|
|
1148
|
+
))
|
|
1002
1149
|
}
|
|
1003
1150
|
);
|
|
1004
1151
|
},
|
|
@@ -1021,11 +1168,8 @@ const EntityOwnerPicker = () => {
|
|
|
1021
1168
|
const hasReachedEnd = Math.abs(
|
|
1022
1169
|
element.scrollHeight - element.clientHeight - element.scrollTop
|
|
1023
1170
|
) < 1;
|
|
1024
|
-
if (hasReachedEnd && (value == null ? void 0 : value.
|
|
1025
|
-
handleFetch({
|
|
1026
|
-
cursor: value.pageInfo.nextCursor,
|
|
1027
|
-
prev: value.items
|
|
1028
|
-
});
|
|
1171
|
+
if (hasReachedEnd && (value == null ? void 0 : value.cursor)) {
|
|
1172
|
+
handleFetch({ items: value.items, cursor: value.cursor });
|
|
1029
1173
|
}
|
|
1030
1174
|
},
|
|
1031
1175
|
"data-testid": "owner-picker-listbox"
|
|
@@ -1033,29 +1177,6 @@ const EntityOwnerPicker = () => {
|
|
|
1033
1177
|
}
|
|
1034
1178
|
)));
|
|
1035
1179
|
};
|
|
1036
|
-
function useSelectedOwners(initialSelectedOwnersRefs) {
|
|
1037
|
-
const allEntities = useRef({});
|
|
1038
|
-
const catalogApi = useApi(catalogApiRef);
|
|
1039
|
-
useAsync(async () => {
|
|
1040
|
-
if (initialSelectedOwnersRefs.length === 0) {
|
|
1041
|
-
return;
|
|
1042
|
-
}
|
|
1043
|
-
const initialSelectedEntities = await catalogApi.getEntitiesByRefs({
|
|
1044
|
-
entityRefs: initialSelectedOwnersRefs
|
|
1045
|
-
});
|
|
1046
|
-
initialSelectedEntities.items.forEach((e) => {
|
|
1047
|
-
if (e) {
|
|
1048
|
-
allEntities.current[stringifyEntityRef(e)] = e;
|
|
1049
|
-
}
|
|
1050
|
-
});
|
|
1051
|
-
}, []);
|
|
1052
|
-
return {
|
|
1053
|
-
getEntity: (entityRef) => allEntities.current[entityRef],
|
|
1054
|
-
setEntity: (entity) => {
|
|
1055
|
-
allEntities.current[stringifyEntityRef(entity)] = entity;
|
|
1056
|
-
}
|
|
1057
|
-
};
|
|
1058
|
-
}
|
|
1059
1180
|
|
|
1060
1181
|
const entityRouteRef = getOrCreateGlobalSingleton(
|
|
1061
1182
|
"catalog:entity-route-ref",
|