@backstage/plugin-catalog-react 1.4.1-next.0 → 1.4.1-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 +39 -0
- package/alpha/package.json +1 -1
- package/dist/alpha.esm.js +3 -31
- package/dist/alpha.esm.js.map +1 -1
- package/dist/esm/useEntity-de64059a.esm.js +77 -0
- package/dist/esm/useEntity-de64059a.esm.js.map +1 -0
- package/dist/index.d.ts +21 -21
- package/dist/index.esm.js +17 -77
- package/dist/index.esm.js.map +1 -1
- package/package.json +18 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-react
|
|
2
2
|
|
|
3
|
+
## 1.4.1-next.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 81bee24c5de: Fixed bug in catalog filters where you could not click on the text to select a value.
|
|
8
|
+
- 2898b6c8d52: Minor type tweaks for TypeScript 5.0
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
- @backstage/catalog-client@1.4.1-next.0
|
|
11
|
+
- @backstage/core-components@0.12.6-next.2
|
|
12
|
+
- @backstage/core-plugin-api@1.5.1-next.1
|
|
13
|
+
- @backstage/catalog-model@1.2.1
|
|
14
|
+
- @backstage/errors@1.1.5
|
|
15
|
+
- @backstage/integration@1.4.4-next.0
|
|
16
|
+
- @backstage/theme@0.2.19-next.0
|
|
17
|
+
- @backstage/types@1.0.2
|
|
18
|
+
- @backstage/version-bridge@1.0.4-next.0
|
|
19
|
+
- @backstage/plugin-catalog-common@1.0.13-next.0
|
|
20
|
+
- @backstage/plugin-permission-common@0.7.5-next.0
|
|
21
|
+
- @backstage/plugin-permission-react@0.4.12-next.1
|
|
22
|
+
|
|
23
|
+
## 1.4.1-next.1
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- e0c6e8b9c3c: Update peer dependencies
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @backstage/core-components@0.12.6-next.1
|
|
30
|
+
- @backstage/plugin-permission-common@0.7.5-next.0
|
|
31
|
+
- @backstage/core-plugin-api@1.5.1-next.0
|
|
32
|
+
- @backstage/plugin-permission-react@0.4.12-next.0
|
|
33
|
+
- @backstage/version-bridge@1.0.4-next.0
|
|
34
|
+
- @backstage/integration@1.4.4-next.0
|
|
35
|
+
- @backstage/theme@0.2.19-next.0
|
|
36
|
+
- @backstage/catalog-client@1.4.0
|
|
37
|
+
- @backstage/catalog-model@1.2.1
|
|
38
|
+
- @backstage/errors@1.1.5
|
|
39
|
+
- @backstage/types@1.0.2
|
|
40
|
+
- @backstage/plugin-catalog-common@1.0.13-next.0
|
|
41
|
+
|
|
3
42
|
## 1.4.1-next.0
|
|
4
43
|
|
|
5
44
|
### Patch Changes
|
package/alpha/package.json
CHANGED
package/dist/alpha.esm.js
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RELATION_MEMBER_OF, getCompoundEntityRef, stringifyEntityRef, RELATION_OWNED_BY } from '@backstage/catalog-model';
|
|
2
|
+
import { g as getEntityRelations, a as useAsyncEntity } from './esm/useEntity-de64059a.esm.js';
|
|
2
3
|
import { usePermission } from '@backstage/plugin-permission-react';
|
|
3
4
|
import '@backstage/core-plugin-api';
|
|
4
|
-
import
|
|
5
|
+
import '@backstage/version-bridge';
|
|
5
6
|
import 'react';
|
|
6
7
|
|
|
7
|
-
function getEntityRelations(entity, relationType, filter) {
|
|
8
|
-
var _a;
|
|
9
|
-
let entityNames = ((_a = entity == null ? void 0 : entity.relations) == null ? void 0 : _a.filter((r) => r.type === relationType).map((r) => parseEntityRef(r.targetRef))) || [];
|
|
10
|
-
if (filter == null ? void 0 : filter.kind) {
|
|
11
|
-
entityNames = entityNames.filter(
|
|
12
|
-
(e) => e.kind.toLocaleLowerCase("en-US") === filter.kind.toLocaleLowerCase("en-US")
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
return entityNames;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
8
|
function isOwnerOf(owner, entity) {
|
|
19
9
|
const possibleOwners = new Set(
|
|
20
10
|
[
|
|
@@ -33,24 +23,6 @@ function isOwnerOf(owner, entity) {
|
|
|
33
23
|
return false;
|
|
34
24
|
}
|
|
35
25
|
|
|
36
|
-
createVersionedContext(
|
|
37
|
-
"entity-context"
|
|
38
|
-
);
|
|
39
|
-
function useAsyncEntity() {
|
|
40
|
-
const versionedHolder = useVersionedContext(
|
|
41
|
-
"entity-context"
|
|
42
|
-
);
|
|
43
|
-
if (!versionedHolder) {
|
|
44
|
-
throw new Error("Entity context is not available");
|
|
45
|
-
}
|
|
46
|
-
const value = versionedHolder.atVersion(1);
|
|
47
|
-
if (!value) {
|
|
48
|
-
throw new Error("EntityContext v1 not available");
|
|
49
|
-
}
|
|
50
|
-
const { entity, loading, error, refresh } = value;
|
|
51
|
-
return { entity, loading, error, refresh };
|
|
52
|
-
}
|
|
53
|
-
|
|
54
26
|
function useEntityPermission(permission) {
|
|
55
27
|
const {
|
|
56
28
|
entity,
|
package/dist/alpha.esm.js.map
CHANGED
|
@@ -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 = (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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"}
|
|
1
|
+
{"version":3,"file":"alpha.esm.js","sources":["../src/utils/isOwnerOf.ts","../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 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 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":";;;;;;;AAkCgB,SAAA,SAAA,CAAU,OAAe,MAAgB,EAAA;AACvD,EAAA,MAAM,iBAAiB,IAAI,GAAA;AAAA,IACzB;AAAA,MACE,GAAG,kBAAmB,CAAA,KAAA,EAAO,oBAAoB,EAAE,IAAA,EAAM,SAAS,CAAA;AAAA,MAClE,GAAI,KAAQ,GAAA,CAAC,qBAAqB,KAAK,CAAC,IAAI,EAAC;AAAA,KAC/C,CAAE,IAAI,kBAAkB,CAAA;AAAA,GAC1B,CAAA;AAEA,EAAA,MAAM,MAAS,GAAA,kBAAA,CAAmB,MAAQ,EAAA,iBAAiB,CAAE,CAAA,GAAA;AAAA,IAC3D,kBAAA;AAAA,GACF,CAAA;AAEA,EAAA,KAAA,MAAW,aAAa,MAAQ,EAAA;AAC9B,IAAI,IAAA,cAAA,CAAe,GAAI,CAAA,SAAS,CAAG,EAAA;AACjC,MAAO,OAAA,IAAA,CAAA;AAAA,KACT;AAAA,GACF;AAEA,EAAO,OAAA,KAAA,CAAA;AACT;;ACrBO,SAAS,oBAGd,UAKA,EAAA;AACA,EAAM,MAAA;AAAA,IACJ,MAAA;AAAA,IACA,OAAS,EAAA,aAAA;AAAA,IACT,KAAO,EAAA,WAAA;AAAA,MACL,cAAe,EAAA,CAAA;AACnB,EAAM,MAAA;AAAA,IACJ,OAAA;AAAA,IACA,OAAS,EAAA,iBAAA;AAAA,IACT,KAAO,EAAA,eAAA;AAAA,MACL,aAAc,CAAA;AAAA,IAChB,UAAA;AAAA,IACA,WAAa,EAAA,MAAA,GAAS,kBAAmB,CAAA,MAAM,CAAI,GAAA,KAAA,CAAA;AAAA,GACpD,CAAA,CAAA;AAED,EAAA,IAAI,iBAAiB,iBAAmB,EAAA;AACtC,IAAA,OAAO,EAAE,OAAA,EAAS,IAAM,EAAA,OAAA,EAAS,KAAM,EAAA,CAAA;AAAA,GACzC;AACA,EAAA,IAAI,WAAa,EAAA;AACf,IAAA,OAAO,EAAE,OAAS,EAAA,KAAA,EAAO,OAAS,EAAA,KAAA,EAAO,OAAO,WAAY,EAAA,CAAA;AAAA,GAC9D;AACA,EAAA,OAAO,EAAE,OAAA,EAAS,KAAO,EAAA,OAAA,EAAS,OAAO,eAAgB,EAAA,CAAA;AAC3D;;;;"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';
|
|
2
|
+
import { AnalyticsContext } from '@backstage/core-plugin-api';
|
|
3
|
+
import { createVersionedContext, createVersionedValueMap, useVersionedContext } from '@backstage/version-bridge';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
function getEntityRelations(entity, relationType, filter) {
|
|
7
|
+
var _a;
|
|
8
|
+
let entityNames = ((_a = entity == null ? void 0 : entity.relations) == null ? void 0 : _a.filter((r) => r.type === relationType).map((r) => parseEntityRef(r.targetRef))) || [];
|
|
9
|
+
if (filter == null ? void 0 : filter.kind) {
|
|
10
|
+
entityNames = entityNames.filter(
|
|
11
|
+
(e) => e.kind.toLocaleLowerCase("en-US") === filter.kind.toLocaleLowerCase("en-US")
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
return entityNames;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const NewEntityContext = createVersionedContext(
|
|
18
|
+
"entity-context"
|
|
19
|
+
);
|
|
20
|
+
const AsyncEntityProvider = (props) => {
|
|
21
|
+
const { children, entity, loading, error, refresh } = props;
|
|
22
|
+
const value = { entity, loading, error, refresh };
|
|
23
|
+
return /* @__PURE__ */ React.createElement(NewEntityContext.Provider, { value: createVersionedValueMap({ 1: value }) }, /* @__PURE__ */ React.createElement(
|
|
24
|
+
AnalyticsContext,
|
|
25
|
+
{
|
|
26
|
+
attributes: {
|
|
27
|
+
...entity ? { entityRef: stringifyEntityRef(entity) } : void 0
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
children
|
|
31
|
+
));
|
|
32
|
+
};
|
|
33
|
+
const EntityProvider = (props) => /* @__PURE__ */ React.createElement(
|
|
34
|
+
AsyncEntityProvider,
|
|
35
|
+
{
|
|
36
|
+
entity: props.entity,
|
|
37
|
+
loading: !Boolean(props.entity),
|
|
38
|
+
error: void 0,
|
|
39
|
+
refresh: void 0,
|
|
40
|
+
children: props.children
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
function useEntity() {
|
|
44
|
+
const versionedHolder = useVersionedContext(
|
|
45
|
+
"entity-context"
|
|
46
|
+
);
|
|
47
|
+
if (!versionedHolder) {
|
|
48
|
+
throw new Error("Entity context is not available");
|
|
49
|
+
}
|
|
50
|
+
const value = versionedHolder.atVersion(1);
|
|
51
|
+
if (!value) {
|
|
52
|
+
throw new Error("EntityContext v1 not available");
|
|
53
|
+
}
|
|
54
|
+
if (!value.entity) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
"useEntity hook is being called outside of an EntityLayout where the entity has not been loaded. If this is intentional, please use useAsyncEntity instead."
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return { entity: value.entity };
|
|
60
|
+
}
|
|
61
|
+
function useAsyncEntity() {
|
|
62
|
+
const versionedHolder = useVersionedContext(
|
|
63
|
+
"entity-context"
|
|
64
|
+
);
|
|
65
|
+
if (!versionedHolder) {
|
|
66
|
+
throw new Error("Entity context is not available");
|
|
67
|
+
}
|
|
68
|
+
const value = versionedHolder.atVersion(1);
|
|
69
|
+
if (!value) {
|
|
70
|
+
throw new Error("EntityContext v1 not available");
|
|
71
|
+
}
|
|
72
|
+
const { entity, loading, error, refresh } = value;
|
|
73
|
+
return { entity, loading, error, refresh };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { AsyncEntityProvider as A, EntityProvider as E, useAsyncEntity as a, getEntityRelations as g, useEntity as u };
|
|
77
|
+
//# sourceMappingURL=useEntity-de64059a.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEntity-de64059a.esm.js","sources":["../../src/utils/getEntityRelations.ts","../../src/hooks/useEntity.tsx"],"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 */\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"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -87,14 +87,14 @@ interface EntityKindPickerProps {
|
|
|
87
87
|
declare const EntityKindPicker: (props: EntityKindPickerProps) => JSX.Element | null;
|
|
88
88
|
|
|
89
89
|
/** @public */
|
|
90
|
-
|
|
90
|
+
type CatalogReactEntityLifecyclePickerClassKey = 'input';
|
|
91
91
|
/** @public */
|
|
92
92
|
declare const EntityLifecyclePicker: (props: {
|
|
93
93
|
initialFilter?: string[];
|
|
94
94
|
}) => JSX.Element | null;
|
|
95
95
|
|
|
96
96
|
/** @public */
|
|
97
|
-
|
|
97
|
+
type CatalogReactEntityOwnerPickerClassKey = 'input';
|
|
98
98
|
/** @public */
|
|
99
99
|
declare const EntityOwnerPicker: () => JSX.Element | null;
|
|
100
100
|
|
|
@@ -103,7 +103,7 @@ declare const EntityOwnerPicker: () => JSX.Element | null;
|
|
|
103
103
|
*
|
|
104
104
|
* @public
|
|
105
105
|
*/
|
|
106
|
-
|
|
106
|
+
type EntityRefLinkProps = {
|
|
107
107
|
entityRef: Entity | CompoundEntityRef | string;
|
|
108
108
|
defaultKind?: string;
|
|
109
109
|
title?: string;
|
|
@@ -121,7 +121,7 @@ declare const EntityRefLink: (props: EntityRefLinkProps) => JSX.Element;
|
|
|
121
121
|
*
|
|
122
122
|
* @public
|
|
123
123
|
*/
|
|
124
|
-
|
|
124
|
+
type EntityRefLinksProps<TRef extends string | CompoundEntityRef | Entity> = ({
|
|
125
125
|
defaultKind?: string;
|
|
126
126
|
entityRefs: TRef[];
|
|
127
127
|
fetchEntities?: false;
|
|
@@ -154,7 +154,7 @@ declare function humanizeEntityRef(entityRef: Entity | CompoundEntityRef, opts?:
|
|
|
154
154
|
*
|
|
155
155
|
* @public
|
|
156
156
|
*/
|
|
157
|
-
|
|
157
|
+
type EntityPeekAheadPopoverProps = PropsWithChildren<{
|
|
158
158
|
entityRef: string;
|
|
159
159
|
delayTime?: number;
|
|
160
160
|
}>;
|
|
@@ -166,7 +166,7 @@ declare type EntityPeekAheadPopoverProps = PropsWithChildren<{
|
|
|
166
166
|
declare const EntityPeekAheadPopover: (props: EntityPeekAheadPopoverProps) => JSX.Element;
|
|
167
167
|
|
|
168
168
|
/** @public */
|
|
169
|
-
|
|
169
|
+
type CatalogReactEntitySearchBarClassKey = 'searchToolbar' | 'input';
|
|
170
170
|
/**
|
|
171
171
|
* Renders search bar for filtering the entity list.
|
|
172
172
|
* @public
|
|
@@ -238,9 +238,9 @@ declare const columnFactories: Readonly<{
|
|
|
238
238
|
}>;
|
|
239
239
|
|
|
240
240
|
/** @public */
|
|
241
|
-
|
|
241
|
+
type CatalogReactEntityTagPickerClassKey = 'input';
|
|
242
242
|
/** @public */
|
|
243
|
-
|
|
243
|
+
type EntityTagPickerProps = {
|
|
244
244
|
showCounts?: boolean;
|
|
245
245
|
};
|
|
246
246
|
/** @public */
|
|
@@ -259,7 +259,7 @@ interface EntityTypePickerProps {
|
|
|
259
259
|
declare const EntityTypePicker: (props: EntityTypePickerProps) => JSX.Element | null;
|
|
260
260
|
|
|
261
261
|
/** @public */
|
|
262
|
-
|
|
262
|
+
type FavoriteEntityProps = ComponentProps<typeof IconButton> & {
|
|
263
263
|
entity: Entity;
|
|
264
264
|
};
|
|
265
265
|
/**
|
|
@@ -281,7 +281,7 @@ declare function InspectEntityDialog(props: {
|
|
|
281
281
|
}): JSX.Element | null;
|
|
282
282
|
|
|
283
283
|
/** @public */
|
|
284
|
-
|
|
284
|
+
type UnregisterEntityDialogProps = {
|
|
285
285
|
open: boolean;
|
|
286
286
|
onConfirm: () => any;
|
|
287
287
|
onClose: () => any;
|
|
@@ -291,7 +291,7 @@ declare type UnregisterEntityDialogProps = {
|
|
|
291
291
|
declare const UnregisterEntityDialog: (props: UnregisterEntityDialogProps) => JSX.Element;
|
|
292
292
|
|
|
293
293
|
/** @public */
|
|
294
|
-
|
|
294
|
+
type EntityFilter = {
|
|
295
295
|
/**
|
|
296
296
|
* Get filters to add to the catalog-backend request. These are a dot-delimited field with
|
|
297
297
|
* value(s) to accept, extracted on the backend by parseEntityFilterParams. For example:
|
|
@@ -313,12 +313,12 @@ declare type EntityFilter = {
|
|
|
313
313
|
toQueryValue?: () => string | string[];
|
|
314
314
|
};
|
|
315
315
|
/** @public */
|
|
316
|
-
|
|
316
|
+
type UserListFilterKind = 'owned' | 'starred' | 'all';
|
|
317
317
|
|
|
318
318
|
/** @public */
|
|
319
|
-
|
|
319
|
+
type CatalogReactUserListPickerClassKey = 'root' | 'title' | 'listIcon' | 'menuItem' | 'groupWrapper';
|
|
320
320
|
/** @public */
|
|
321
|
-
|
|
321
|
+
type UserListPickerProps = {
|
|
322
322
|
initialFilter?: UserListFilterKind;
|
|
323
323
|
availableFilters?: UserListFilterKind[];
|
|
324
324
|
};
|
|
@@ -326,12 +326,12 @@ declare type UserListPickerProps = {
|
|
|
326
326
|
declare const UserListPicker: (props: UserListPickerProps) => JSX.Element;
|
|
327
327
|
|
|
328
328
|
/** @public */
|
|
329
|
-
|
|
329
|
+
type CatalogReactEntityProcessingStatusPickerClassKey = 'input';
|
|
330
330
|
/** @public */
|
|
331
331
|
declare const EntityProcessingStatusPicker: () => JSX.Element;
|
|
332
332
|
|
|
333
333
|
/** @public */
|
|
334
|
-
|
|
334
|
+
type EntityLoadingStatus<TEntity extends Entity = Entity> = {
|
|
335
335
|
entity?: TEntity;
|
|
336
336
|
loading: boolean;
|
|
337
337
|
error?: Error;
|
|
@@ -479,7 +479,7 @@ declare class EntityErrorFilter implements EntityFilter {
|
|
|
479
479
|
}
|
|
480
480
|
|
|
481
481
|
/** @public */
|
|
482
|
-
|
|
482
|
+
type DefaultEntityFilters = {
|
|
483
483
|
kind?: EntityKindFilter;
|
|
484
484
|
type?: EntityTypeFilter;
|
|
485
485
|
user?: UserListFilter;
|
|
@@ -491,7 +491,7 @@ declare type DefaultEntityFilters = {
|
|
|
491
491
|
error?: EntityErrorFilter;
|
|
492
492
|
};
|
|
493
493
|
/** @public */
|
|
494
|
-
|
|
494
|
+
type EntityListContextProps<EntityFilters extends DefaultEntityFilters = DefaultEntityFilters> = {
|
|
495
495
|
/**
|
|
496
496
|
* The currently registered filters, adhering to the shape of DefaultEntityFilters or an extension
|
|
497
497
|
* of that default (to add custom filter types).
|
|
@@ -615,7 +615,7 @@ declare function MockEntityListContextProvider<T extends DefaultEntityFilters =
|
|
|
615
615
|
}>): JSX.Element;
|
|
616
616
|
|
|
617
617
|
/** @public */
|
|
618
|
-
|
|
618
|
+
type CatalogReactComponentsNameToClassKey = {
|
|
619
619
|
CatalogReactUserListPicker: CatalogReactUserListPickerClassKey;
|
|
620
620
|
CatalogReactEntityLifecyclePicker: CatalogReactEntityLifecyclePickerClassKey;
|
|
621
621
|
CatalogReactEntitySearchBar: CatalogReactEntitySearchBarClassKey;
|
|
@@ -624,7 +624,7 @@ declare type CatalogReactComponentsNameToClassKey = {
|
|
|
624
624
|
CatalogReactEntityProcessingStatusPicker: CatalogReactEntityProcessingStatusPickerClassKey;
|
|
625
625
|
};
|
|
626
626
|
/** @public */
|
|
627
|
-
|
|
627
|
+
type BackstageOverrides = Overrides & {
|
|
628
628
|
[Name in keyof CatalogReactComponentsNameToClassKey]?: Partial<StyleRules<CatalogReactComponentsNameToClassKey[Name]>>;
|
|
629
629
|
};
|
|
630
630
|
|
|
@@ -638,7 +638,7 @@ declare function getEntityRelations(entity: Entity | undefined, relationType: st
|
|
|
638
638
|
}): CompoundEntityRef[];
|
|
639
639
|
|
|
640
640
|
/** @public */
|
|
641
|
-
|
|
641
|
+
type EntitySourceLocation = {
|
|
642
642
|
locationTargetUrl: string;
|
|
643
643
|
integrationType?: string;
|
|
644
644
|
};
|
package/dist/index.esm.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';
|
|
2
|
-
import { createApiRef, createRouteRef, useRouteRef, useApi,
|
|
2
|
+
import { createApiRef, createRouteRef, useRouteRef, useApi, identityApiRef, alertApiRef, useApiHolder, useApp, configApiRef } from '@backstage/core-plugin-api';
|
|
3
3
|
import ObservableImpl from 'zen-observable';
|
|
4
4
|
import React, { useState, forwardRef, createContext, useMemo, useCallback, useContext, useEffect, useRef, memo, useLayoutEffect, Fragment } from 'react';
|
|
5
5
|
import { Grid, useMediaQuery, useTheme, Button, Drawer, Box, Typography, Tooltip, makeStyles, FormControlLabel, Checkbox, TextField, 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, ListItemSecondaryAction } from '@material-ui/core';
|
|
6
6
|
import FilterListIcon from '@material-ui/icons/FilterList';
|
|
7
7
|
import { Link, Progress, ErrorPanel, Select, ResponseErrorPanel, OverflowTooltip, Table, DependencyGraph, DependencyGraphTypes, CodeSnippet } from '@backstage/core-components';
|
|
8
8
|
import { DEFAULT_NAMESPACE, parseEntityRef, ANNOTATION_SOURCE_LOCATION, parseLocationRef, RELATION_OWNED_BY, stringifyEntityRef, getCompoundEntityRef, isUserEntity, isGroupEntity, RELATION_PART_OF, ANNOTATION_LOCATION, ANNOTATION_ORIGIN_LOCATION } from '@backstage/catalog-model';
|
|
9
|
-
import { getOrCreateGlobalSingleton
|
|
9
|
+
import { getOrCreateGlobalSingleton } from '@backstage/version-bridge';
|
|
10
10
|
import useAsync from 'react-use/lib/useAsync';
|
|
11
|
+
import { g as getEntityRelations } from './esm/useEntity-de64059a.esm.js';
|
|
12
|
+
export { A as AsyncEntityProvider, E as EntityProvider, g as getEntityRelations, a as useAsyncEntity, u as useEntity } from './esm/useEntity-de64059a.esm.js';
|
|
11
13
|
import _, { compact, isEqual, groupBy, chunk, debounce } from 'lodash';
|
|
12
14
|
import qs from 'qs';
|
|
13
15
|
import { useLocation, useNavigate } from 'react-router-dom';
|
|
@@ -204,10 +206,13 @@ function FetchedEntityRefLinks(props) {
|
|
|
204
206
|
error
|
|
205
207
|
} = useAsync(async () => {
|
|
206
208
|
const refs = entityRefs.reduce((acc, current) => {
|
|
207
|
-
|
|
209
|
+
if (typeof current === "object" && "metadata" in current) {
|
|
210
|
+
return acc;
|
|
211
|
+
}
|
|
212
|
+
return [...acc, parseEntityRef(current)];
|
|
208
213
|
}, new Array());
|
|
209
214
|
const pureEntities = entityRefs.filter(
|
|
210
|
-
(ref) => "metadata" in ref
|
|
215
|
+
(ref) => typeof ref === "object" && "metadata" in ref
|
|
211
216
|
);
|
|
212
217
|
return refs.length > 0 ? [
|
|
213
218
|
...(await catalogApi.getEntities({
|
|
@@ -279,17 +284,6 @@ function reduceEntityFilters(filters) {
|
|
|
279
284
|
);
|
|
280
285
|
}
|
|
281
286
|
|
|
282
|
-
function getEntityRelations(entity, relationType, filter) {
|
|
283
|
-
var _a;
|
|
284
|
-
let entityNames = ((_a = entity == null ? void 0 : entity.relations) == null ? void 0 : _a.filter((r) => r.type === relationType).map((r) => parseEntityRef(r.targetRef))) || [];
|
|
285
|
-
if (filter == null ? void 0 : filter.kind) {
|
|
286
|
-
entityNames = entityNames.filter(
|
|
287
|
-
(e) => e.kind.toLocaleLowerCase("en-US") === filter.kind.toLocaleLowerCase("en-US")
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
return entityNames;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
287
|
function getEntitySourceLocation(entity, scmIntegrationsApi) {
|
|
294
288
|
var _a;
|
|
295
289
|
const sourceLocation = (_a = entity.metadata.annotations) == null ? void 0 : _a[ANNOTATION_SOURCE_LOCATION];
|
|
@@ -440,65 +434,6 @@ class EntityErrorFilter {
|
|
|
440
434
|
}
|
|
441
435
|
}
|
|
442
436
|
|
|
443
|
-
const NewEntityContext = createVersionedContext(
|
|
444
|
-
"entity-context"
|
|
445
|
-
);
|
|
446
|
-
const AsyncEntityProvider = (props) => {
|
|
447
|
-
const { children, entity, loading, error, refresh } = props;
|
|
448
|
-
const value = { entity, loading, error, refresh };
|
|
449
|
-
return /* @__PURE__ */ React.createElement(NewEntityContext.Provider, { value: createVersionedValueMap({ 1: value }) }, /* @__PURE__ */ React.createElement(
|
|
450
|
-
AnalyticsContext,
|
|
451
|
-
{
|
|
452
|
-
attributes: {
|
|
453
|
-
...entity ? { entityRef: stringifyEntityRef(entity) } : void 0
|
|
454
|
-
}
|
|
455
|
-
},
|
|
456
|
-
children
|
|
457
|
-
));
|
|
458
|
-
};
|
|
459
|
-
const EntityProvider = (props) => /* @__PURE__ */ React.createElement(
|
|
460
|
-
AsyncEntityProvider,
|
|
461
|
-
{
|
|
462
|
-
entity: props.entity,
|
|
463
|
-
loading: !Boolean(props.entity),
|
|
464
|
-
error: void 0,
|
|
465
|
-
refresh: void 0,
|
|
466
|
-
children: props.children
|
|
467
|
-
}
|
|
468
|
-
);
|
|
469
|
-
function useEntity() {
|
|
470
|
-
const versionedHolder = useVersionedContext(
|
|
471
|
-
"entity-context"
|
|
472
|
-
);
|
|
473
|
-
if (!versionedHolder) {
|
|
474
|
-
throw new Error("Entity context is not available");
|
|
475
|
-
}
|
|
476
|
-
const value = versionedHolder.atVersion(1);
|
|
477
|
-
if (!value) {
|
|
478
|
-
throw new Error("EntityContext v1 not available");
|
|
479
|
-
}
|
|
480
|
-
if (!value.entity) {
|
|
481
|
-
throw new Error(
|
|
482
|
-
"useEntity hook is being called outside of an EntityLayout where the entity has not been loaded. If this is intentional, please use useAsyncEntity instead."
|
|
483
|
-
);
|
|
484
|
-
}
|
|
485
|
-
return { entity: value.entity };
|
|
486
|
-
}
|
|
487
|
-
function useAsyncEntity() {
|
|
488
|
-
const versionedHolder = useVersionedContext(
|
|
489
|
-
"entity-context"
|
|
490
|
-
);
|
|
491
|
-
if (!versionedHolder) {
|
|
492
|
-
throw new Error("Entity context is not available");
|
|
493
|
-
}
|
|
494
|
-
const value = versionedHolder.atVersion(1);
|
|
495
|
-
if (!value) {
|
|
496
|
-
throw new Error("EntityContext v1 not available");
|
|
497
|
-
}
|
|
498
|
-
const { entity, loading, error, refresh } = value;
|
|
499
|
-
return { entity, loading, error, refresh };
|
|
500
|
-
}
|
|
501
|
-
|
|
502
437
|
const EntityListContext = createContext(void 0);
|
|
503
438
|
const EntityListProvider = (props) => {
|
|
504
439
|
const isMounted = useMountedState();
|
|
@@ -984,6 +919,7 @@ const EntityLifecyclePicker = (props) => {
|
|
|
984
919
|
checked: selected
|
|
985
920
|
}
|
|
986
921
|
),
|
|
922
|
+
onClick: (event) => event.preventDefault(),
|
|
987
923
|
label: option
|
|
988
924
|
}
|
|
989
925
|
),
|
|
@@ -1070,6 +1006,7 @@ const EntityOwnerPicker = () => {
|
|
|
1070
1006
|
checked: selected
|
|
1071
1007
|
}
|
|
1072
1008
|
),
|
|
1009
|
+
onClick: (event) => event.preventDefault(),
|
|
1073
1010
|
label: option
|
|
1074
1011
|
}
|
|
1075
1012
|
),
|
|
@@ -1450,7 +1387,8 @@ const EntityAutocompletePickerOption = memo((props) => {
|
|
|
1450
1387
|
FormControlLabel,
|
|
1451
1388
|
{
|
|
1452
1389
|
control: /* @__PURE__ */ React.createElement(OptionCheckbox, { selected }),
|
|
1453
|
-
label
|
|
1390
|
+
label,
|
|
1391
|
+
onClick: (event) => event.preventDefault()
|
|
1454
1392
|
}
|
|
1455
1393
|
);
|
|
1456
1394
|
});
|
|
@@ -1514,7 +1452,8 @@ function EntityAutocompletePicker(props) {
|
|
|
1514
1452
|
[name]: shouldAddFilter ? new Filter(selectedOptions) : void 0
|
|
1515
1453
|
});
|
|
1516
1454
|
}, [name, shouldAddFilter, selectedOptions, Filter, updateFilters]);
|
|
1517
|
-
|
|
1455
|
+
const filter = filters[name];
|
|
1456
|
+
if (filter && typeof filter === "object" && !("values" in filter) || !availableOptions.length) {
|
|
1518
1457
|
return null;
|
|
1519
1458
|
}
|
|
1520
1459
|
return /* @__PURE__ */ React.createElement(Box, { pb: 1, pt: 1 }, /* @__PURE__ */ React.createElement(Typography, { variant: "button", component: "label" }, label, /* @__PURE__ */ React.createElement(
|
|
@@ -2522,6 +2461,7 @@ const EntityProcessingStatusPicker = () => {
|
|
|
2522
2461
|
checked: selected
|
|
2523
2462
|
}
|
|
2524
2463
|
),
|
|
2464
|
+
onClick: (event) => event.preventDefault(),
|
|
2525
2465
|
label: option
|
|
2526
2466
|
}
|
|
2527
2467
|
),
|
|
@@ -2578,5 +2518,5 @@ function MockEntityListContextProvider(props) {
|
|
|
2578
2518
|
return /* @__PURE__ */ React.createElement(EntityListContext.Provider, { value: resolvedValue }, children);
|
|
2579
2519
|
}
|
|
2580
2520
|
|
|
2581
|
-
export {
|
|
2521
|
+
export { CatalogFilterLayout, EntityErrorFilter, EntityKindFilter, EntityKindPicker, EntityLifecycleFilter, EntityLifecyclePicker, EntityListContext, EntityListProvider, EntityOrphanFilter, EntityOwnerFilter, EntityOwnerPicker, EntityPeekAheadPopover, EntityProcessingStatusPicker, EntityRefLink, EntityRefLinks, EntitySearchBar, EntityTable, EntityTagFilter, EntityTagPicker, EntityTextFilter, EntityTypeFilter, EntityTypePicker, FavoriteEntity, InspectEntityDialog, MockEntityListContextProvider, MockStarredEntitiesApi, UnregisterEntityDialog, UserListFilter, UserListPicker, catalogApiRef, columnFactories, entityRouteParams, entityRouteRef, getEntitySourceLocation, humanizeEntityRef, starredEntitiesApiRef, useEntityList, useEntityOwnership, useEntityTypeFilter, useRelatedEntities, useStarredEntities, useStarredEntity };
|
|
2582
2522
|
//# sourceMappingURL=index.esm.js.map
|