@backstage/plugin-catalog-react 1.4.0-next.0 → 1.4.0-next.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,35 @@
1
1
  # @backstage/plugin-catalog-react
2
2
 
3
+ ## 1.4.0-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 65454876fb2: Minor API report tweaks
8
+ - Updated dependencies
9
+ - @backstage/core-components@0.12.5-next.2
10
+ - @backstage/core-plugin-api@1.5.0-next.2
11
+ - @backstage/plugin-permission-react@0.4.11-next.2
12
+ - @backstage/integration@1.4.3-next.0
13
+
14
+ ## 1.4.0-next.1
15
+
16
+ ### Patch Changes
17
+
18
+ - 24916d23494: Do not close `Autocomplete` powered multiple-selection filters when checking boxes
19
+ - Updated dependencies
20
+ - @backstage/core-components@0.12.5-next.1
21
+ - @backstage/errors@1.1.5-next.0
22
+ - @backstage/catalog-client@1.4.0-next.1
23
+ - @backstage/core-plugin-api@1.4.1-next.1
24
+ - @backstage/integration@1.4.3-next.0
25
+ - @backstage/plugin-permission-common@0.7.4-next.0
26
+ - @backstage/theme@0.2.18-next.0
27
+ - @backstage/catalog-model@1.2.1-next.1
28
+ - @backstage/types@1.0.2
29
+ - @backstage/version-bridge@1.0.3
30
+ - @backstage/plugin-catalog-common@1.0.12-next.1
31
+ - @backstage/plugin-permission-react@0.4.11-next.1
32
+
3
33
  ## 1.4.0-next.0
4
34
 
5
35
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-react",
3
- "version": "1.4.0-next.0",
3
+ "version": "1.4.0-next.2",
4
4
  "main": "../dist/alpha.esm.js",
5
5
  "module": "../dist/alpha.esm.js",
6
6
  "types": "../dist/alpha.d.ts"
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.esm.js","sources":["../src/utils/getEntityRelations.ts","../src/utils/isOwnerOf.ts","../src/hooks/useEntity.tsx","../src/hooks/useEntityPermission.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n CompoundEntityRef,\n parseEntityRef,\n} from '@backstage/catalog-model';\n\n// TODO(freben): This should be returning entity refs instead\n/**\n * Get the related entity references.\n *\n * @public\n */\nexport function getEntityRelations(\n entity: Entity | undefined,\n relationType: string,\n filter?: { kind: string },\n): CompoundEntityRef[] {\n let entityNames =\n entity?.relations\n ?.filter(r => r.type === relationType)\n .map(r => parseEntityRef(r.targetRef)) || [];\n\n if (filter?.kind) {\n entityNames = entityNames.filter(\n e =>\n e.kind.toLocaleLowerCase('en-US') ===\n filter.kind.toLocaleLowerCase('en-US'),\n );\n }\n\n return entityNames;\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n getCompoundEntityRef,\n RELATION_MEMBER_OF,\n RELATION_OWNED_BY,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { getEntityRelations } from './getEntityRelations';\n\n/**\n * Returns true if the `owner` argument is a direct owner on the `entity` argument.\n *\n * @alpha\n * @remarks\n *\n * Note that this ownership is not the same as using the claims in the auth-resolver, it only will take into account ownership as expressed by direct entity relations.\n * It doesn't know anything about the additional groups that a user might belong to which the claims contain.\n */\nexport function isOwnerOf(owner: Entity, entity: Entity) {\n const possibleOwners = new Set(\n [\n ...getEntityRelations(owner, RELATION_MEMBER_OF, { kind: 'group' }),\n ...(owner ? [getCompoundEntityRef(owner)] : []),\n ].map(stringifyEntityRef),\n );\n\n const owners = getEntityRelations(entity, RELATION_OWNED_BY).map(\n stringifyEntityRef,\n );\n\n for (const ownerItem of owners) {\n if (possibleOwners.has(ownerItem)) {\n return true;\n }\n }\n\n return false;\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { AnalyticsContext } from '@backstage/core-plugin-api';\nimport {\n createVersionedContext,\n createVersionedValueMap,\n useVersionedContext,\n} from '@backstage/version-bridge';\nimport React, { ReactNode } from 'react';\n\n/** @public */\nexport type EntityLoadingStatus<TEntity extends Entity = Entity> = {\n entity?: TEntity;\n loading: boolean;\n error?: Error;\n refresh?: VoidFunction;\n};\n\n// This context has support for multiple concurrent versions of this package.\n// It is currently used in parallel with the old context in order to provide\n// a smooth transition, but will eventually be the only context we use.\nconst NewEntityContext = createVersionedContext<{ 1: EntityLoadingStatus }>(\n 'entity-context',\n);\n\n/**\n * Properties for the AsyncEntityProvider component.\n *\n * @public\n */\nexport interface AsyncEntityProviderProps {\n children: ReactNode;\n entity?: Entity;\n loading: boolean;\n error?: Error;\n refresh?: VoidFunction;\n}\n\n/**\n * Provides a loaded entity to be picked up by the `useEntity` hook.\n *\n * @public\n */\nexport const AsyncEntityProvider = ({\n children,\n entity,\n loading,\n error,\n refresh,\n}: AsyncEntityProviderProps) => {\n const value = { entity, loading, error, refresh };\n // We provide both the old and the new context, since\n // consumers might be doing things like `useContext(EntityContext)`\n return (\n <NewEntityContext.Provider value={createVersionedValueMap({ 1: value })}>\n <AnalyticsContext\n attributes={{\n ...(entity ? { entityRef: stringifyEntityRef(entity) } : undefined),\n }}\n >\n {children}\n </AnalyticsContext>\n </NewEntityContext.Provider>\n );\n};\n\n/**\n * Properties for the EntityProvider component.\n *\n * @public\n */\nexport interface EntityProviderProps {\n children: ReactNode;\n entity?: Entity;\n}\n\n/**\n * Provides an entity to be picked up by the `useEntity` hook.\n *\n * @public\n */\nexport const EntityProvider = (props: EntityProviderProps) => (\n <AsyncEntityProvider\n entity={props.entity}\n loading={!Boolean(props.entity)}\n error={undefined}\n refresh={undefined}\n children={props.children}\n />\n);\n\n/**\n * Grab the current entity from the context, throws if the entity has not yet been loaded\n * or is not available.\n *\n * @public\n */\nexport function useEntity<TEntity extends Entity = Entity>(): {\n entity: TEntity;\n} {\n const versionedHolder = useVersionedContext<{ 1: EntityLoadingStatus }>(\n 'entity-context',\n );\n\n if (!versionedHolder) {\n throw new Error('Entity context is not available');\n }\n\n const value = versionedHolder.atVersion(1);\n if (!value) {\n throw new Error('EntityContext v1 not available');\n }\n\n if (!value.entity) {\n throw new Error(\n 'useEntity hook is being called outside of an EntityLayout where the entity has not been loaded. If this is intentional, please use useAsyncEntity instead.',\n );\n }\n\n return { entity: value.entity as TEntity };\n}\n\n/**\n * Grab the current entity from the context, provides loading state and errors, and the ability to refresh.\n *\n * @public\n */\nexport function useAsyncEntity<\n TEntity extends Entity = Entity,\n>(): EntityLoadingStatus<TEntity> {\n const versionedHolder = useVersionedContext<{ 1: EntityLoadingStatus }>(\n 'entity-context',\n );\n\n if (!versionedHolder) {\n throw new Error('Entity context is not available');\n }\n const value = versionedHolder.atVersion(1);\n if (!value) {\n throw new Error('EntityContext v1 not available');\n }\n\n const { entity, loading, error, refresh } = value;\n return { entity: entity as TEntity, loading, error, refresh };\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { ResourcePermission } from '@backstage/plugin-permission-common';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport { useAsyncEntity } from './useEntity';\n\n/**\n * A thin wrapper around the\n * {@link @backstage/plugin-permission-react#usePermission} hook which uses the\n * current entity in context to make an authorization request for the given\n * {@link @backstage/plugin-catalog-common#CatalogEntityPermission}.\n *\n * Note: this hook blocks the permission request until the entity has loaded in\n * context. If you have the entityRef and need concurrent requests, use the\n * `usePermission` hook directly.\n * @alpha\n */\nexport function useEntityPermission(\n // TODO(joeporpeglia) Replace with `CatalogEntityPermission` when the issue described in\n // https://github.com/backstage/backstage/pull/10128 is fixed.\n permission: ResourcePermission<'catalog-entity'>,\n): {\n loading: boolean;\n allowed: boolean;\n error?: Error;\n} {\n const {\n entity,\n loading: loadingEntity,\n error: entityError,\n } = useAsyncEntity();\n const {\n allowed,\n loading: loadingPermission,\n error: permissionError,\n } = usePermission({\n permission,\n resourceRef: entity ? stringifyEntityRef(entity) : undefined,\n });\n\n if (loadingEntity || loadingPermission) {\n return { loading: true, allowed: false };\n }\n if (entityError) {\n return { loading: false, allowed: false, error: entityError };\n }\n return { loading: false, allowed, error: permissionError };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"alpha.esm.js","sources":["../src/utils/getEntityRelations.ts","../src/utils/isOwnerOf.ts","../src/hooks/useEntity.tsx","../src/hooks/useEntityPermission.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n CompoundEntityRef,\n parseEntityRef,\n} from '@backstage/catalog-model';\n\n// TODO(freben): This should be returning entity refs instead\n/**\n * Get the related entity references.\n *\n * @public\n */\nexport function getEntityRelations(\n entity: Entity | undefined,\n relationType: string,\n filter?: { kind: string },\n): CompoundEntityRef[] {\n let entityNames =\n entity?.relations\n ?.filter(r => r.type === relationType)\n .map(r => parseEntityRef(r.targetRef)) || [];\n\n if (filter?.kind) {\n entityNames = entityNames.filter(\n e =>\n e.kind.toLocaleLowerCase('en-US') ===\n filter.kind.toLocaleLowerCase('en-US'),\n );\n }\n\n return entityNames;\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n getCompoundEntityRef,\n RELATION_MEMBER_OF,\n RELATION_OWNED_BY,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { getEntityRelations } from './getEntityRelations';\n\n/**\n * Returns true if the `owner` argument is a direct owner on the `entity` argument.\n *\n * @alpha\n * @remarks\n *\n * Note that this ownership is not the same as using the claims in the auth-resolver, it only will take into account ownership as expressed by direct entity relations.\n * It doesn't know anything about the additional groups that a user might belong to which the claims contain.\n */\nexport function isOwnerOf(owner: Entity, entity: Entity) {\n const possibleOwners = new Set(\n [\n ...getEntityRelations(owner, RELATION_MEMBER_OF, { kind: 'group' }),\n ...(owner ? [getCompoundEntityRef(owner)] : []),\n ].map(stringifyEntityRef),\n );\n\n const owners = getEntityRelations(entity, RELATION_OWNED_BY).map(\n stringifyEntityRef,\n );\n\n for (const ownerItem of owners) {\n if (possibleOwners.has(ownerItem)) {\n return true;\n }\n }\n\n return false;\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { AnalyticsContext } from '@backstage/core-plugin-api';\nimport {\n createVersionedContext,\n createVersionedValueMap,\n useVersionedContext,\n} from '@backstage/version-bridge';\nimport React, { ReactNode } from 'react';\n\n/** @public */\nexport type EntityLoadingStatus<TEntity extends Entity = Entity> = {\n entity?: TEntity;\n loading: boolean;\n error?: Error;\n refresh?: VoidFunction;\n};\n\n// This context has support for multiple concurrent versions of this package.\n// It is currently used in parallel with the old context in order to provide\n// a smooth transition, but will eventually be the only context we use.\nconst NewEntityContext = createVersionedContext<{ 1: EntityLoadingStatus }>(\n 'entity-context',\n);\n\n/**\n * Properties for the AsyncEntityProvider component.\n *\n * @public\n */\nexport interface AsyncEntityProviderProps {\n children: ReactNode;\n entity?: Entity;\n loading: boolean;\n error?: Error;\n refresh?: VoidFunction;\n}\n\n/**\n * Provides a loaded entity to be picked up by the `useEntity` hook.\n *\n * @public\n */\nexport const AsyncEntityProvider = (props: AsyncEntityProviderProps) => {\n const { children, entity, loading, error, refresh } = props;\n const value = { entity, loading, error, refresh };\n // We provide both the old and the new context, since\n // consumers might be doing things like `useContext(EntityContext)`\n return (\n <NewEntityContext.Provider value={createVersionedValueMap({ 1: value })}>\n <AnalyticsContext\n attributes={{\n ...(entity ? { entityRef: stringifyEntityRef(entity) } : undefined),\n }}\n >\n {children}\n </AnalyticsContext>\n </NewEntityContext.Provider>\n );\n};\n\n/**\n * Properties for the EntityProvider component.\n *\n * @public\n */\nexport interface EntityProviderProps {\n children: ReactNode;\n entity?: Entity;\n}\n\n/**\n * Provides an entity to be picked up by the `useEntity` hook.\n *\n * @public\n */\nexport const EntityProvider = (props: EntityProviderProps) => (\n <AsyncEntityProvider\n entity={props.entity}\n loading={!Boolean(props.entity)}\n error={undefined}\n refresh={undefined}\n children={props.children}\n />\n);\n\n/**\n * Grab the current entity from the context, throws if the entity has not yet been loaded\n * or is not available.\n *\n * @public\n */\nexport function useEntity<TEntity extends Entity = Entity>(): {\n entity: TEntity;\n} {\n const versionedHolder = useVersionedContext<{ 1: EntityLoadingStatus }>(\n 'entity-context',\n );\n\n if (!versionedHolder) {\n throw new Error('Entity context is not available');\n }\n\n const value = versionedHolder.atVersion(1);\n if (!value) {\n throw new Error('EntityContext v1 not available');\n }\n\n if (!value.entity) {\n throw new Error(\n 'useEntity hook is being called outside of an EntityLayout where the entity has not been loaded. If this is intentional, please use useAsyncEntity instead.',\n );\n }\n\n return { entity: value.entity as TEntity };\n}\n\n/**\n * Grab the current entity from the context, provides loading state and errors, and the ability to refresh.\n *\n * @public\n */\nexport function useAsyncEntity<\n TEntity extends Entity = Entity,\n>(): EntityLoadingStatus<TEntity> {\n const versionedHolder = useVersionedContext<{ 1: EntityLoadingStatus }>(\n 'entity-context',\n );\n\n if (!versionedHolder) {\n throw new Error('Entity context is not available');\n }\n const value = versionedHolder.atVersion(1);\n if (!value) {\n throw new Error('EntityContext v1 not available');\n }\n\n const { entity, loading, error, refresh } = value;\n return { entity: entity as TEntity, loading, error, refresh };\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { ResourcePermission } from '@backstage/plugin-permission-common';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport { useAsyncEntity } from './useEntity';\n\n/**\n * A thin wrapper around the\n * {@link @backstage/plugin-permission-react#usePermission} hook which uses the\n * current entity in context to make an authorization request for the given\n * {@link @backstage/plugin-catalog-common#CatalogEntityPermission}.\n *\n * Note: this hook blocks the permission request until the entity has loaded in\n * context. If you have the entityRef and need concurrent requests, use the\n * `usePermission` hook directly.\n * @alpha\n */\nexport function useEntityPermission(\n // TODO(joeporpeglia) Replace with `CatalogEntityPermission` when the issue described in\n // https://github.com/backstage/backstage/pull/10128 is fixed.\n permission: ResourcePermission<'catalog-entity'>,\n): {\n loading: boolean;\n allowed: boolean;\n error?: Error;\n} {\n const {\n entity,\n loading: loadingEntity,\n error: entityError,\n } = useAsyncEntity();\n const {\n allowed,\n loading: loadingPermission,\n error: permissionError,\n } = usePermission({\n permission,\n resourceRef: entity ? stringifyEntityRef(entity) : undefined,\n });\n\n if (loadingEntity || loadingPermission) {\n return { loading: true, allowed: false };\n }\n if (entityError) {\n return { loading: false, allowed: false, error: entityError };\n }\n return { loading: false, allowed, error: permissionError };\n}\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -354,7 +354,7 @@ interface AsyncEntityProviderProps {
354
354
  *
355
355
  * @public
356
356
  */
357
- declare const AsyncEntityProvider: ({ children, entity, loading, error, refresh, }: AsyncEntityProviderProps) => JSX.Element;
357
+ declare const AsyncEntityProvider: (props: AsyncEntityProviderProps) => JSX.Element;
358
358
  /**
359
359
  * Properties for the EntityProvider component.
360
360
  *
@@ -526,7 +526,7 @@ declare const EntityListContext: React.Context<EntityListContextProps<any> | und
526
526
  * Provides entities and filters for a catalog listing.
527
527
  * @public
528
528
  */
529
- declare const EntityListProvider: <EntityFilters extends DefaultEntityFilters>({ children, }: PropsWithChildren<{}>) => JSX.Element;
529
+ declare const EntityListProvider: <EntityFilters extends DefaultEntityFilters>(props: PropsWithChildren<{}>) => JSX.Element;
530
530
  /**
531
531
  * Hook for interacting with the entity list context provided by the {@link EntityListProvider}.
532
532
  * @public
@@ -610,7 +610,7 @@ declare function entityRouteParams(entity: Entity): {
610
610
  };
611
611
 
612
612
  /** @public */
613
- declare function MockEntityListContextProvider<T extends DefaultEntityFilters = DefaultEntityFilters>({ children, value, }: PropsWithChildren<{
613
+ declare function MockEntityListContextProvider<T extends DefaultEntityFilters = DefaultEntityFilters>(props: PropsWithChildren<{
614
614
  value?: Partial<EntityListContextProps<T>>;
615
615
  }>): JSX.Element;
616
616
 
package/dist/index.esm.js CHANGED
@@ -443,13 +443,8 @@ class EntityErrorFilter {
443
443
  const NewEntityContext = createVersionedContext(
444
444
  "entity-context"
445
445
  );
446
- const AsyncEntityProvider = ({
447
- children,
448
- entity,
449
- loading,
450
- error,
451
- refresh
452
- }) => {
446
+ const AsyncEntityProvider = (props) => {
447
+ const { children, entity, loading, error, refresh } = props;
453
448
  const value = { entity, loading, error, refresh };
454
449
  return /* @__PURE__ */ React.createElement(NewEntityContext.Provider, { value: createVersionedValueMap({ 1: value }) }, /* @__PURE__ */ React.createElement(
455
450
  AnalyticsContext,
@@ -505,9 +500,7 @@ function useAsyncEntity() {
505
500
  }
506
501
 
507
502
  const EntityListContext = createContext(void 0);
508
- const EntityListProvider = ({
509
- children
510
- }) => {
503
+ const EntityListProvider = (props) => {
511
504
  const isMounted = useMountedState();
512
505
  const catalogApi = useApi(catalogApiRef);
513
506
  const [requestedFilters, setRequestedFilters] = useState(
@@ -604,7 +597,7 @@ const EntityListProvider = ({
604
597
  }),
605
598
  [outputState, updateFilters, queryParameters, loading, error]
606
599
  );
607
- return /* @__PURE__ */ React.createElement(EntityListContext.Provider, { value }, children);
600
+ return /* @__PURE__ */ React.createElement(EntityListContext.Provider, { value }, props.children);
608
601
  };
609
602
  function useEntityList() {
610
603
  const context = useContext(EntityListContext);
@@ -976,6 +969,7 @@ const EntityLifecyclePicker = (props) => {
976
969
  Autocomplete,
977
970
  {
978
971
  multiple: true,
972
+ disableCloseOnSelect: true,
979
973
  options: availableLifecycles,
980
974
  value: selectedLifecycles,
981
975
  onChange: (_, value) => setSelectedLifecycles(value),
@@ -1061,6 +1055,7 @@ const EntityOwnerPicker = () => {
1061
1055
  Autocomplete,
1062
1056
  {
1063
1057
  multiple: true,
1058
+ disableCloseOnSelect: true,
1064
1059
  options: availableOwners,
1065
1060
  value: selectedOwners,
1066
1061
  onChange: (_, value) => setSelectedOwners(value),
@@ -1526,6 +1521,7 @@ function EntityAutocompletePicker(props) {
1526
1521
  Autocomplete,
1527
1522
  {
1528
1523
  multiple: true,
1524
+ disableCloseOnSelect: true,
1529
1525
  options: availableOptions,
1530
1526
  value: selectedOptions,
1531
1527
  onChange: (_event, options) => setSelectedOptions(options),
@@ -2507,6 +2503,7 @@ const EntityProcessingStatusPicker = () => {
2507
2503
  Autocomplete,
2508
2504
  {
2509
2505
  multiple: true,
2506
+ disableCloseOnSelect: true,
2510
2507
  options: availableAdvancedItems,
2511
2508
  value: selectedAdvancedItems,
2512
2509
  onChange: (_, value) => {
@@ -2542,11 +2539,9 @@ const EntityProcessingStatusPicker = () => {
2542
2539
  )));
2543
2540
  };
2544
2541
 
2545
- function MockEntityListContextProvider({
2546
- children,
2547
- value
2548
- }) {
2542
+ function MockEntityListContextProvider(props) {
2549
2543
  var _a;
2544
+ const { children, value } = props;
2550
2545
  const [filters, setFilters] = useState((_a = value == null ? void 0 : value.filters) != null ? _a : {});
2551
2546
  const updateFilters = useCallback(
2552
2547
  (update) => {