@backstage/plugin-catalog-react 1.7.0-next.1 → 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 +29 -0
- package/alpha/package.json +1 -1
- package/dist/index.d.ts +14 -3
- package/dist/index.esm.js +194 -101
- package/dist/index.esm.js.map +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
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
|
+
|
|
21
|
+
## 1.7.0-next.2
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- d68692aee97e: Make `useRelatedEntities` use `getEntitiesByRefs` under the hood
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
- @backstage/theme@0.4.0-next.1
|
|
28
|
+
- @backstage/core-components@0.13.2-next.2
|
|
29
|
+
- @backstage/core-plugin-api@1.5.2-next.0
|
|
30
|
+
- @backstage/plugin-permission-react@0.4.13-next.0
|
|
31
|
+
|
|
3
32
|
## 1.7.0-next.1
|
|
4
33
|
|
|
5
34
|
### 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}.
|
|
@@ -569,7 +575,12 @@ declare function useEntityTypeFilter(): {
|
|
|
569
575
|
setSelectedTypes: (types: string[]) => void;
|
|
570
576
|
};
|
|
571
577
|
|
|
572
|
-
/**
|
|
578
|
+
/**
|
|
579
|
+
* Fetches all entities that appear in the entity's relations, optionally
|
|
580
|
+
* filtered by relation type and kind.
|
|
581
|
+
*
|
|
582
|
+
* @public
|
|
583
|
+
*/
|
|
573
584
|
declare function useRelatedEntities(entity: Entity, relationFilter: {
|
|
574
585
|
type?: string;
|
|
575
586
|
kind?: string;
|
|
@@ -668,4 +679,4 @@ type EntitySourceLocation = {
|
|
|
668
679
|
/** @public */
|
|
669
680
|
declare function getEntitySourceLocation(entity: Entity, scmIntegrationsApi: ScmIntegrationRegistry): EntitySourceLocation | undefined;
|
|
670
681
|
|
|
671
|
-
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
|
@@ -8,7 +8,7 @@ import { Select, Link, Progress, ErrorPanel, ResponseErrorPanel, OverflowTooltip
|
|
|
8
8
|
import { ANNOTATION_SOURCE_LOCATION, parseLocationRef, stringifyEntityRef, parseEntityRef, RELATION_OWNED_BY, DEFAULT_NAMESPACE, getCompoundEntityRef, isUserEntity, isGroupEntity, RELATION_PART_OF, ANNOTATION_LOCATION, ANNOTATION_ORIGIN_LOCATION } from '@backstage/catalog-model';
|
|
9
9
|
import { g as getEntityRelations } from './esm/useEntity-de64059a.esm.js';
|
|
10
10
|
export { A as AsyncEntityProvider, E as EntityProvider, g as getEntityRelations, a as useAsyncEntity, u as useEntity } from './esm/useEntity-de64059a.esm.js';
|
|
11
|
-
import { compact, isEqual,
|
|
11
|
+
import { compact, isEqual, debounce } from 'lodash';
|
|
12
12
|
import qs from 'qs';
|
|
13
13
|
import { useLocation, useNavigate } from 'react-router-dom';
|
|
14
14
|
import useAsyncFn from 'react-use/lib/useAsyncFn';
|
|
@@ -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';
|
|
@@ -38,7 +38,7 @@ import Star from '@material-ui/icons/Star';
|
|
|
38
38
|
import StarBorder from '@material-ui/icons/StarBorder';
|
|
39
39
|
import WorkIcon from '@material-ui/icons/Work';
|
|
40
40
|
import HelpOutlineIcon from '@material-ui/icons/HelpOutline';
|
|
41
|
-
import groupBy
|
|
41
|
+
import groupBy from 'lodash/groupBy';
|
|
42
42
|
import DialogContentText$1 from '@material-ui/core/DialogContentText';
|
|
43
43
|
import YAML from 'yaml';
|
|
44
44
|
import Alert$1 from '@material-ui/lab/Alert';
|
|
@@ -489,7 +489,6 @@ function useEntityTypeFilter() {
|
|
|
489
489
|
};
|
|
490
490
|
}
|
|
491
491
|
|
|
492
|
-
const BATCH_SIZE = 20;
|
|
493
492
|
function useRelatedEntities(entity, relationFilter) {
|
|
494
493
|
var _a, _b;
|
|
495
494
|
const filterByTypeLower = (_a = relationFilter == null ? void 0 : relationFilter.type) == null ? void 0 : _a.toLocaleLowerCase("en-US");
|
|
@@ -501,43 +500,16 @@ function useRelatedEntities(entity, relationFilter) {
|
|
|
501
500
|
error
|
|
502
501
|
} = useAsync(async () => {
|
|
503
502
|
var _a2;
|
|
504
|
-
const relations = (_a2 = entity.relations) == null ? void 0 : _a2.
|
|
505
|
-
(r) => (!filterByTypeLower || r.type.toLocaleLowerCase("en-US") === filterByTypeLower) && (!filterByKindLower || r.
|
|
503
|
+
const relations = (_a2 = entity.relations) == null ? void 0 : _a2.filter(
|
|
504
|
+
(r) => (!filterByTypeLower || r.type.toLocaleLowerCase("en-US") === filterByTypeLower) && (!filterByKindLower || parseEntityRef(r.targetRef).kind === filterByKindLower)
|
|
506
505
|
);
|
|
507
|
-
if (!relations) {
|
|
506
|
+
if (!(relations == null ? void 0 : relations.length)) {
|
|
508
507
|
return [];
|
|
509
508
|
}
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
);
|
|
515
|
-
const batchedRelationsByKindAndNamespace = [];
|
|
516
|
-
for (const rs of relationsByKindAndNamespace) {
|
|
517
|
-
batchedRelationsByKindAndNamespace.push({
|
|
518
|
-
// All relations in a group have the same kind and namespace, so its arbitrary which we pick
|
|
519
|
-
kind: rs[0].target.kind,
|
|
520
|
-
namespace: rs[0].target.namespace,
|
|
521
|
-
nameBatches: chunk(
|
|
522
|
-
rs.map((r) => r.target.name),
|
|
523
|
-
BATCH_SIZE
|
|
524
|
-
)
|
|
525
|
-
});
|
|
526
|
-
}
|
|
527
|
-
const results = await Promise.all(
|
|
528
|
-
batchedRelationsByKindAndNamespace.flatMap((rs) => {
|
|
529
|
-
return rs.nameBatches.map((names) => {
|
|
530
|
-
return catalogApi.getEntities({
|
|
531
|
-
filter: {
|
|
532
|
-
kind: rs.kind,
|
|
533
|
-
"metadata.namespace": rs.namespace,
|
|
534
|
-
"metadata.name": names
|
|
535
|
-
}
|
|
536
|
-
});
|
|
537
|
-
});
|
|
538
|
-
})
|
|
539
|
-
);
|
|
540
|
-
return results.flatMap((r) => r.items);
|
|
509
|
+
const { items } = await catalogApi.getEntitiesByRefs({
|
|
510
|
+
entityRefs: relations.map((r) => r.targetRef)
|
|
511
|
+
});
|
|
512
|
+
return items.filter((x) => Boolean(x));
|
|
541
513
|
}, [entity, filterByTypeLower, filterByKindLower]);
|
|
542
514
|
return {
|
|
543
515
|
entities,
|
|
@@ -903,42 +875,105 @@ function humanizeEntity(entity, defaultName) {
|
|
|
903
875
|
return defaultName;
|
|
904
876
|
}
|
|
905
877
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
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));
|
|
912
933
|
}
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
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() {
|
|
924
959
|
const catalogApi = useApi(catalogApiRef);
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
960
|
+
return useAsyncFn(
|
|
961
|
+
async (request, options) => {
|
|
962
|
+
var _a;
|
|
928
963
|
const initialRequest = request;
|
|
929
964
|
const cursorRequest = request;
|
|
930
|
-
const limit = 20;
|
|
965
|
+
const limit = (_a = options == null ? void 0 : options.limit) != null ? _a : 20;
|
|
931
966
|
if (cursorRequest.cursor) {
|
|
932
|
-
const
|
|
967
|
+
const response2 = await catalogApi.queryEntities({
|
|
933
968
|
cursor: cursorRequest.cursor,
|
|
934
969
|
limit
|
|
935
970
|
});
|
|
936
971
|
return {
|
|
937
|
-
|
|
938
|
-
items: [...cursorRequest.
|
|
972
|
+
cursor: response2.pageInfo.nextCursor,
|
|
973
|
+
items: [...cursorRequest.items, ...response2.items]
|
|
939
974
|
};
|
|
940
975
|
}
|
|
941
|
-
|
|
976
|
+
const response = await catalogApi.queryEntities({
|
|
942
977
|
fullTextFilter: {
|
|
943
978
|
term: initialRequest.text || "",
|
|
944
979
|
fields: [
|
|
@@ -952,11 +987,84 @@ const EntityOwnerPicker = () => {
|
|
|
952
987
|
orderFields: [{ field: "metadata.name", order: "asc" }],
|
|
953
988
|
limit
|
|
954
989
|
});
|
|
990
|
+
return {
|
|
991
|
+
cursor: response.pageInfo.nextCursor,
|
|
992
|
+
items: response.items
|
|
993
|
+
};
|
|
955
994
|
},
|
|
956
|
-
[
|
|
995
|
+
[],
|
|
996
|
+
{ loading: true }
|
|
957
997
|
);
|
|
958
|
-
|
|
959
|
-
|
|
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("");
|
|
960
1068
|
const queryParamOwners = useMemo(
|
|
961
1069
|
() => [ownersParameter].flat().filter(Boolean),
|
|
962
1070
|
[ownersParameter]
|
|
@@ -964,7 +1072,12 @@ const EntityOwnerPicker = () => {
|
|
|
964
1072
|
const [selectedOwners, setSelectedOwners] = useState(
|
|
965
1073
|
queryParamOwners.length ? queryParamOwners : (_b = (_a = filters.owners) == null ? void 0 : _a.values) != null ? _b : []
|
|
966
1074
|
);
|
|
967
|
-
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) || [];
|
|
968
1081
|
useEffect(() => {
|
|
969
1082
|
if (queryParamOwners.length) {
|
|
970
1083
|
const filter = new EntityOwnerFilter(queryParamOwners);
|
|
@@ -996,8 +1109,11 @@ const EntityOwnerPicker = () => {
|
|
|
996
1109
|
return o === v;
|
|
997
1110
|
},
|
|
998
1111
|
getOptionLabel: (o) => {
|
|
999
|
-
const entity = typeof o === "string" ? getEntity(o) || o
|
|
1000
|
-
|
|
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));
|
|
1001
1117
|
},
|
|
1002
1118
|
onChange: (_, owners) => {
|
|
1003
1119
|
setText("");
|
|
@@ -1005,7 +1121,7 @@ const EntityOwnerPicker = () => {
|
|
|
1005
1121
|
owners.map((e) => {
|
|
1006
1122
|
const entityRef = typeof e === "string" ? e : stringifyEntityRef(e);
|
|
1007
1123
|
if (typeof e !== "string") {
|
|
1008
|
-
setEntity(e);
|
|
1124
|
+
cache.setEntity(e);
|
|
1009
1125
|
}
|
|
1010
1126
|
return entityRef;
|
|
1011
1127
|
})
|
|
@@ -1013,7 +1129,7 @@ const EntityOwnerPicker = () => {
|
|
|
1013
1129
|
},
|
|
1014
1130
|
filterOptions: (x) => x,
|
|
1015
1131
|
renderOption: (entity, { selected }) => {
|
|
1016
|
-
const isGroup = entity.kind === "
|
|
1132
|
+
const isGroup = entity.kind.toLocaleLowerCase("en-US") === "group";
|
|
1017
1133
|
return /* @__PURE__ */ React.createElement(
|
|
1018
1134
|
FormControlLabel,
|
|
1019
1135
|
{
|
|
@@ -1026,7 +1142,10 @@ const EntityOwnerPicker = () => {
|
|
|
1026
1142
|
}
|
|
1027
1143
|
),
|
|
1028
1144
|
onClick: (event) => event.preventDefault(),
|
|
1029
|
-
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
|
+
))
|
|
1030
1149
|
}
|
|
1031
1150
|
);
|
|
1032
1151
|
},
|
|
@@ -1049,11 +1168,8 @@ const EntityOwnerPicker = () => {
|
|
|
1049
1168
|
const hasReachedEnd = Math.abs(
|
|
1050
1169
|
element.scrollHeight - element.clientHeight - element.scrollTop
|
|
1051
1170
|
) < 1;
|
|
1052
|
-
if (hasReachedEnd && (value == null ? void 0 : value.
|
|
1053
|
-
handleFetch({
|
|
1054
|
-
cursor: value.pageInfo.nextCursor,
|
|
1055
|
-
prev: value.items
|
|
1056
|
-
});
|
|
1171
|
+
if (hasReachedEnd && (value == null ? void 0 : value.cursor)) {
|
|
1172
|
+
handleFetch({ items: value.items, cursor: value.cursor });
|
|
1057
1173
|
}
|
|
1058
1174
|
},
|
|
1059
1175
|
"data-testid": "owner-picker-listbox"
|
|
@@ -1061,29 +1177,6 @@ const EntityOwnerPicker = () => {
|
|
|
1061
1177
|
}
|
|
1062
1178
|
)));
|
|
1063
1179
|
};
|
|
1064
|
-
function useSelectedOwners(initialSelectedOwnersRefs) {
|
|
1065
|
-
const allEntities = useRef({});
|
|
1066
|
-
const catalogApi = useApi(catalogApiRef);
|
|
1067
|
-
useAsync(async () => {
|
|
1068
|
-
if (initialSelectedOwnersRefs.length === 0) {
|
|
1069
|
-
return;
|
|
1070
|
-
}
|
|
1071
|
-
const initialSelectedEntities = await catalogApi.getEntitiesByRefs({
|
|
1072
|
-
entityRefs: initialSelectedOwnersRefs
|
|
1073
|
-
});
|
|
1074
|
-
initialSelectedEntities.items.forEach((e) => {
|
|
1075
|
-
if (e) {
|
|
1076
|
-
allEntities.current[stringifyEntityRef(e)] = e;
|
|
1077
|
-
}
|
|
1078
|
-
});
|
|
1079
|
-
}, []);
|
|
1080
|
-
return {
|
|
1081
|
-
getEntity: (entityRef) => allEntities.current[entityRef],
|
|
1082
|
-
setEntity: (entity) => {
|
|
1083
|
-
allEntities.current[stringifyEntityRef(entity)] = entity;
|
|
1084
|
-
}
|
|
1085
|
-
};
|
|
1086
|
-
}
|
|
1087
1180
|
|
|
1088
1181
|
const entityRouteRef = getOrCreateGlobalSingleton(
|
|
1089
1182
|
"catalog:entity-route-ref",
|
|
@@ -1996,7 +2089,7 @@ function OverviewPage(props) {
|
|
|
1996
2089
|
relations = [],
|
|
1997
2090
|
status = {}
|
|
1998
2091
|
} = props.entity;
|
|
1999
|
-
const groupedRelations = groupBy
|
|
2092
|
+
const groupedRelations = groupBy(
|
|
2000
2093
|
sortBy(relations, (r) => r.targetRef),
|
|
2001
2094
|
"type"
|
|
2002
2095
|
);
|