@backstage/plugin-catalog-react 1.9.1 → 1.9.2-next.1
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 +44 -3
- package/alpha/package.json +1 -1
- package/dist/alpha.d.ts +8 -18
- package/dist/alpha.esm.js +28 -51
- package/dist/alpha.esm.js.map +1 -1
- package/dist/index.d.ts +18 -2
- package/dist/index.esm.js +101 -56
- package/dist/index.esm.js.map +1 -1
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,53 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-react
|
|
2
2
|
|
|
3
|
-
## 1.9.1
|
|
3
|
+
## 1.9.2-next.1
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- 53600976bb: Ensure that passed-in icons are taken advantage of in the presentation API
|
|
8
|
+
- 08d9e67199: Add default icon for kind resource.
|
|
9
|
+
- a5a04739e1: Internal refactor of alpha exports due to a change in how extension factories are defined.
|
|
10
|
+
- e223f2264d: Breaking alpha-API change to entity visibility filter functions to accept a bare entity as their first argument, instead of an object with an entity property.
|
|
11
|
+
|
|
12
|
+
Functions that accept such filters now also support the string expression form of filters.
|
|
13
|
+
|
|
8
14
|
- Updated dependencies
|
|
9
|
-
- @backstage/
|
|
15
|
+
- @backstage/frontend-plugin-api@0.4.0-next.1
|
|
16
|
+
- @backstage/core-components@0.13.9-next.1
|
|
17
|
+
- @backstage/core-plugin-api@1.8.1-next.1
|
|
18
|
+
- @backstage/catalog-client@1.5.0-next.0
|
|
19
|
+
- @backstage/integration-react@1.1.22-next.1
|
|
20
|
+
- @backstage/plugin-permission-react@0.4.18-next.1
|
|
21
|
+
- @backstage/catalog-model@1.4.3
|
|
22
|
+
- @backstage/errors@1.2.3
|
|
23
|
+
- @backstage/theme@0.5.0-next.0
|
|
24
|
+
- @backstage/types@1.1.1
|
|
25
|
+
- @backstage/version-bridge@1.0.7
|
|
26
|
+
- @backstage/plugin-catalog-common@1.0.18
|
|
27
|
+
- @backstage/plugin-permission-common@0.7.10
|
|
28
|
+
|
|
29
|
+
## 1.9.2-next.0
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- 8587f067d2: Added pagination support to `EntityListProvider`.
|
|
34
|
+
- aaa6fb3bc9: Minor updates for TypeScript 5.2.2+ compatibility
|
|
35
|
+
- 4d9e3b39e4: Register component overrides in the global `OverrideComponentNameToClassKeys` provided by `@backstage/theme`. This will in turn will provide component style override types for `createUnifiedTheme`.
|
|
36
|
+
- eee0ff2946: Fixed a issue where `CatalogPage` wasn't using the chosen `initiallySelectedFilter` as intended.
|
|
37
|
+
- Updated dependencies
|
|
38
|
+
- @backstage/core-plugin-api@1.8.1-next.0
|
|
39
|
+
- @backstage/core-components@0.13.9-next.0
|
|
40
|
+
- @backstage/theme@0.5.0-next.0
|
|
41
|
+
- @backstage/frontend-plugin-api@0.3.1-next.0
|
|
42
|
+
- @backstage/integration-react@1.1.22-next.0
|
|
43
|
+
- @backstage/plugin-permission-react@0.4.18-next.0
|
|
44
|
+
- @backstage/catalog-client@1.4.6
|
|
45
|
+
- @backstage/catalog-model@1.4.3
|
|
46
|
+
- @backstage/errors@1.2.3
|
|
47
|
+
- @backstage/types@1.1.1
|
|
48
|
+
- @backstage/version-bridge@1.0.7
|
|
49
|
+
- @backstage/plugin-catalog-common@1.0.18
|
|
50
|
+
- @backstage/plugin-permission-common@0.7.10
|
|
10
51
|
|
|
11
52
|
## 1.9.0
|
|
12
53
|
|
package/alpha/package.json
CHANGED
package/dist/alpha.d.ts
CHANGED
|
@@ -43,9 +43,9 @@ declare function useEntityPermission(permission: ResourcePermission<'catalog-ent
|
|
|
43
43
|
/** @alpha */
|
|
44
44
|
declare const entityContentTitleExtensionDataRef: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, {}>;
|
|
45
45
|
/** @alpha */
|
|
46
|
-
declare const
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
declare const entityFilterFunctionExtensionDataRef: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, {}>;
|
|
47
|
+
/** @alpha */
|
|
48
|
+
declare const entityFilterExpressionExtensionDataRef: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, {}>;
|
|
49
49
|
/** @alpha */
|
|
50
50
|
declare function createEntityCardExtension<TInputs extends AnyExtensionInputMap>(options: {
|
|
51
51
|
id: string;
|
|
@@ -55,17 +55,12 @@ declare function createEntityCardExtension<TInputs extends AnyExtensionInputMap>
|
|
|
55
55
|
};
|
|
56
56
|
disabled?: boolean;
|
|
57
57
|
inputs?: TInputs;
|
|
58
|
-
filter?:
|
|
59
|
-
entity: Entity;
|
|
60
|
-
}) => boolean;
|
|
58
|
+
filter?: typeof entityFilterFunctionExtensionDataRef.T | typeof entityFilterExpressionExtensionDataRef.T;
|
|
61
59
|
loader: (options: {
|
|
62
60
|
inputs: Expand<ExtensionInputValues<TInputs>>;
|
|
63
61
|
}) => Promise<JSX.Element>;
|
|
64
62
|
}): _backstage_frontend_plugin_api.Extension<{
|
|
65
|
-
filter?:
|
|
66
|
-
isKind?: string | undefined;
|
|
67
|
-
isType?: string | undefined;
|
|
68
|
-
}[] | undefined;
|
|
63
|
+
filter?: string | undefined;
|
|
69
64
|
}>;
|
|
70
65
|
/** @alpha */
|
|
71
66
|
declare function createEntityContentExtension<TInputs extends AnyExtensionInputMap>(options: {
|
|
@@ -79,19 +74,14 @@ declare function createEntityContentExtension<TInputs extends AnyExtensionInputM
|
|
|
79
74
|
routeRef?: RouteRef;
|
|
80
75
|
defaultPath: string;
|
|
81
76
|
defaultTitle: string;
|
|
82
|
-
filter?:
|
|
83
|
-
entity: Entity;
|
|
84
|
-
}) => boolean;
|
|
77
|
+
filter?: typeof entityFilterFunctionExtensionDataRef.T | typeof entityFilterExpressionExtensionDataRef.T;
|
|
85
78
|
loader: (options: {
|
|
86
79
|
inputs: Expand<ExtensionInputValues<TInputs>>;
|
|
87
80
|
}) => Promise<JSX.Element>;
|
|
88
81
|
}): _backstage_frontend_plugin_api.Extension<{
|
|
89
82
|
title: string;
|
|
90
83
|
path: string;
|
|
91
|
-
filter?:
|
|
92
|
-
isKind?: string | undefined;
|
|
93
|
-
isType?: string | undefined;
|
|
94
|
-
}[] | undefined;
|
|
84
|
+
filter?: string | undefined;
|
|
95
85
|
}>;
|
|
96
86
|
|
|
97
|
-
export { createEntityCardExtension, createEntityContentExtension, entityContentTitleExtensionDataRef,
|
|
87
|
+
export { createEntityCardExtension, createEntityContentExtension, entityContentTitleExtensionDataRef, entityFilterExpressionExtensionDataRef, entityFilterFunctionExtensionDataRef, isOwnerOf, useEntityPermission };
|
package/dist/alpha.esm.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React, { lazy } from 'react';
|
|
2
1
|
import { createExtensionDataRef, createExtension, coreExtensionData, createSchemaFromZod, ExtensionBoundary } from '@backstage/frontend-plugin-api';
|
|
2
|
+
import React, { lazy } from 'react';
|
|
3
3
|
import { RELATION_MEMBER_OF, getCompoundEntityRef, stringifyEntityRef, RELATION_OWNED_BY } from '@backstage/catalog-model';
|
|
4
|
-
import { g as getEntityRelations, a as useAsyncEntity } from './esm/useEntity-de64059a.esm.js';
|
|
5
4
|
import { usePermission } from '@backstage/plugin-permission-react';
|
|
5
|
+
import { g as getEntityRelations, a as useAsyncEntity } from './esm/useEntity-de64059a.esm.js';
|
|
6
6
|
import '@backstage/core-plugin-api';
|
|
7
7
|
import '@backstage/version-bridge';
|
|
8
8
|
|
|
@@ -48,34 +48,8 @@ function useEntityPermission(permission) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
const entityContentTitleExtensionDataRef = createExtensionDataRef("plugin.catalog.entity.content.title");
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
if (!a) {
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
return a.toLocaleLowerCase("en-US") === (b == null ? void 0 : b.toLocaleLowerCase("en-US"));
|
|
57
|
-
}
|
|
58
|
-
function buildFilter(config, filterFunc) {
|
|
59
|
-
return (ctx) => {
|
|
60
|
-
var _a;
|
|
61
|
-
const configuredFilterMatch = (_a = config.filter) == null ? void 0 : _a.some((filter) => {
|
|
62
|
-
var _a2, _b;
|
|
63
|
-
const kindMatch = applyFilter(filter.isKind, ctx.entity.kind);
|
|
64
|
-
const typeMatch = applyFilter(
|
|
65
|
-
filter.isType,
|
|
66
|
-
(_b = (_a2 = ctx.entity.spec) == null ? void 0 : _a2.type) == null ? void 0 : _b.toString()
|
|
67
|
-
);
|
|
68
|
-
return kindMatch && typeMatch;
|
|
69
|
-
});
|
|
70
|
-
if (configuredFilterMatch) {
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
if (filterFunc) {
|
|
74
|
-
return filterFunc(ctx);
|
|
75
|
-
}
|
|
76
|
-
return true;
|
|
77
|
-
};
|
|
78
|
-
}
|
|
51
|
+
const entityFilterFunctionExtensionDataRef = createExtensionDataRef("plugin.catalog.entity.filter.fn");
|
|
52
|
+
const entityFilterExpressionExtensionDataRef = createExtensionDataRef("plugin.catalog.entity.filter.expression");
|
|
79
53
|
function createEntityCardExtension(options) {
|
|
80
54
|
var _a, _b;
|
|
81
55
|
const id = `entity.cards.${options.id}`;
|
|
@@ -88,26 +62,22 @@ function createEntityCardExtension(options) {
|
|
|
88
62
|
disabled: (_b = options.disabled) != null ? _b : true,
|
|
89
63
|
output: {
|
|
90
64
|
element: coreExtensionData.reactElement,
|
|
91
|
-
|
|
65
|
+
filterFunction: entityFilterFunctionExtensionDataRef.optional(),
|
|
66
|
+
filterExpression: entityFilterExpressionExtensionDataRef.optional()
|
|
92
67
|
},
|
|
93
68
|
inputs: options.inputs,
|
|
94
69
|
configSchema: createSchemaFromZod(
|
|
95
70
|
(z) => z.object({
|
|
96
|
-
filter: z.
|
|
97
|
-
z.object({
|
|
98
|
-
isKind: z.string().optional(),
|
|
99
|
-
isType: z.string().optional()
|
|
100
|
-
})
|
|
101
|
-
).optional()
|
|
71
|
+
filter: z.string().optional()
|
|
102
72
|
})
|
|
103
73
|
),
|
|
104
|
-
factory({ config, inputs,
|
|
74
|
+
factory({ config, inputs, node }) {
|
|
105
75
|
const ExtensionComponent = lazy(
|
|
106
76
|
() => options.loader({ inputs }).then((element) => ({ default: () => element }))
|
|
107
77
|
);
|
|
108
78
|
return {
|
|
109
|
-
element: /* @__PURE__ */ React.createElement(ExtensionBoundary, {
|
|
110
|
-
|
|
79
|
+
element: /* @__PURE__ */ React.createElement(ExtensionBoundary, { node }, /* @__PURE__ */ React.createElement(ExtensionComponent, null)),
|
|
80
|
+
...mergeFilters({ config, options })
|
|
111
81
|
};
|
|
112
82
|
}
|
|
113
83
|
});
|
|
@@ -127,22 +97,18 @@ function createEntityContentExtension(options) {
|
|
|
127
97
|
path: coreExtensionData.routePath,
|
|
128
98
|
routeRef: coreExtensionData.routeRef.optional(),
|
|
129
99
|
title: entityContentTitleExtensionDataRef,
|
|
130
|
-
|
|
100
|
+
filterFunction: entityFilterFunctionExtensionDataRef.optional(),
|
|
101
|
+
filterExpression: entityFilterExpressionExtensionDataRef.optional()
|
|
131
102
|
},
|
|
132
103
|
inputs: options.inputs,
|
|
133
104
|
configSchema: createSchemaFromZod(
|
|
134
105
|
(z) => z.object({
|
|
135
106
|
path: z.string().default(options.defaultPath),
|
|
136
107
|
title: z.string().default(options.defaultTitle),
|
|
137
|
-
filter: z.
|
|
138
|
-
z.object({
|
|
139
|
-
isKind: z.string().optional(),
|
|
140
|
-
isType: z.string().optional()
|
|
141
|
-
})
|
|
142
|
-
).optional()
|
|
108
|
+
filter: z.string().optional()
|
|
143
109
|
})
|
|
144
110
|
),
|
|
145
|
-
factory({ config, inputs,
|
|
111
|
+
factory({ config, inputs, node }) {
|
|
146
112
|
const ExtensionComponent = lazy(
|
|
147
113
|
() => options.loader({ inputs }).then((element) => ({ default: () => element }))
|
|
148
114
|
);
|
|
@@ -150,12 +116,23 @@ function createEntityContentExtension(options) {
|
|
|
150
116
|
path: config.path,
|
|
151
117
|
title: config.title,
|
|
152
118
|
routeRef: options.routeRef,
|
|
153
|
-
element: /* @__PURE__ */ React.createElement(ExtensionBoundary, {
|
|
154
|
-
|
|
119
|
+
element: /* @__PURE__ */ React.createElement(ExtensionBoundary, { node, routable: true }, /* @__PURE__ */ React.createElement(ExtensionComponent, null)),
|
|
120
|
+
...mergeFilters({ config, options })
|
|
155
121
|
};
|
|
156
122
|
}
|
|
157
123
|
});
|
|
158
124
|
}
|
|
125
|
+
function mergeFilters(inputs) {
|
|
126
|
+
const { options, config } = inputs;
|
|
127
|
+
if (config.filter) {
|
|
128
|
+
return { filterExpression: config.filter };
|
|
129
|
+
} else if (typeof options.filter === "string") {
|
|
130
|
+
return { filterExpression: options.filter };
|
|
131
|
+
} else if (typeof options.filter === "function") {
|
|
132
|
+
return { filterFunction: options.filter };
|
|
133
|
+
}
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
159
136
|
|
|
160
|
-
export { createEntityCardExtension, createEntityContentExtension, entityContentTitleExtensionDataRef,
|
|
137
|
+
export { createEntityCardExtension, createEntityContentExtension, entityContentTitleExtensionDataRef, entityFilterExpressionExtensionDataRef, entityFilterFunctionExtensionDataRef, isOwnerOf, useEntityPermission };
|
|
161
138
|
//# sourceMappingURL=alpha.esm.js.map
|
package/dist/alpha.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alpha.esm.js","sources":["../src/utils/isOwnerOf.ts","../src/hooks/useEntityPermission.ts","../src/alpha.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 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","/*\n * Copyright 2023 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 React, { lazy } from 'react';\nimport {\n AnyExtensionInputMap,\n ExtensionBoundary,\n ExtensionInputValues,\n RouteRef,\n coreExtensionData,\n createExtension,\n createExtensionDataRef,\n createSchemaFromZod,\n} from '@backstage/frontend-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { Expand } from '../../../packages/frontend-plugin-api/src/types';\nimport { Entity } from '@backstage/catalog-model';\n\nexport { isOwnerOf } from './utils';\nexport { useEntityPermission } from './hooks/useEntityPermission';\n\n/** @alpha */\nexport const entityContentTitleExtensionDataRef =\n createExtensionDataRef<string>('plugin.catalog.entity.content.title');\n\n/** @alpha */\nexport const entityFilterExtensionDataRef = createExtensionDataRef<\n (ctx: { entity: Entity }) => boolean\n>('plugin.catalog.entity.filter');\n\nfunction applyFilter(a?: string, b?: string): boolean {\n if (!a) {\n return true;\n }\n return a.toLocaleLowerCase('en-US') === b?.toLocaleLowerCase('en-US');\n}\n\n// TODO: Only two hardcoded isKind and isType filters are available for now\n// This is just an initial config filter implementation and needs to be revisited\nfunction buildFilter(\n config: { filter?: { isKind?: string; isType?: string }[] },\n filterFunc?: (ctx: { entity: Entity }) => boolean,\n) {\n return (ctx: { entity: Entity }) => {\n const configuredFilterMatch = config.filter?.some(filter => {\n const kindMatch = applyFilter(filter.isKind, ctx.entity.kind);\n const typeMatch = applyFilter(\n filter.isType,\n ctx.entity.spec?.type?.toString(),\n );\n return kindMatch && typeMatch;\n });\n if (configuredFilterMatch) {\n return true;\n }\n if (filterFunc) {\n return filterFunc(ctx);\n }\n return true;\n };\n}\n\n// TODO: Figure out how to merge with provided config schema\n/** @alpha */\nexport function createEntityCardExtension<\n TInputs extends AnyExtensionInputMap,\n>(options: {\n id: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n filter?: (ctx: { entity: Entity }) => boolean;\n loader: (options: {\n inputs: Expand<ExtensionInputValues<TInputs>>;\n }) => Promise<JSX.Element>;\n}) {\n const id = `entity.cards.${options.id}`;\n\n return createExtension({\n id,\n attachTo: options.attachTo ?? {\n id: 'entity.content.overview',\n input: 'cards',\n },\n disabled: options.disabled ?? true,\n output: {\n element: coreExtensionData.reactElement,\n filter: entityFilterExtensionDataRef,\n },\n inputs: options.inputs,\n configSchema: createSchemaFromZod(z =>\n z.object({\n filter: z\n .array(\n z.object({\n isKind: z.string().optional(),\n isType: z.string().optional(),\n }),\n )\n .optional(),\n }),\n ),\n factory({ config, inputs, source }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ inputs })\n .then(element => ({ default: () => element })),\n );\n\n return {\n element: (\n <ExtensionBoundary id={id} source={source}>\n <ExtensionComponent />\n </ExtensionBoundary>\n ),\n filter: buildFilter(config, options.filter),\n };\n },\n });\n}\n\n/** @alpha */\nexport function createEntityContentExtension<\n TInputs extends AnyExtensionInputMap,\n>(options: {\n id: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n routeRef?: RouteRef;\n defaultPath: string;\n defaultTitle: string;\n filter?: (ctx: { entity: Entity }) => boolean;\n loader: (options: {\n inputs: Expand<ExtensionInputValues<TInputs>>;\n }) => Promise<JSX.Element>;\n}) {\n const id = `entity.content.${options.id}`;\n\n return createExtension({\n id,\n attachTo: options.attachTo ?? {\n id: 'plugin.catalog.page.entity',\n input: 'contents',\n },\n disabled: options.disabled ?? true,\n output: {\n element: coreExtensionData.reactElement,\n path: coreExtensionData.routePath,\n routeRef: coreExtensionData.routeRef.optional(),\n title: entityContentTitleExtensionDataRef,\n filter: entityFilterExtensionDataRef,\n },\n inputs: options.inputs,\n configSchema: createSchemaFromZod(z =>\n z.object({\n path: z.string().default(options.defaultPath),\n title: z.string().default(options.defaultTitle),\n filter: z\n .array(\n z.object({\n isKind: z.string().optional(),\n isType: z.string().optional(),\n }),\n )\n .optional(),\n }),\n ),\n factory({ config, inputs, source }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ inputs })\n .then(element => ({ default: () => element })),\n );\n\n return {\n path: config.path,\n title: config.title,\n routeRef: options.routeRef,\n element: (\n <ExtensionBoundary id={id} source={source} routable>\n <ExtensionComponent />\n </ExtensionBoundary>\n ),\n filter: buildFilter(config, options.filter),\n };\n },\n });\n}\n"],"names":["_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"alpha.esm.js","sources":["../src/utils/isOwnerOf.ts","../src/hooks/useEntityPermission.ts","../src/alpha.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 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","/*\n * Copyright 2023 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 AnyExtensionInputMap,\n ExtensionBoundary,\n ExtensionInputValues,\n RouteRef,\n coreExtensionData,\n createExtension,\n createExtensionDataRef,\n createSchemaFromZod,\n} from '@backstage/frontend-plugin-api';\nimport React, { lazy } from 'react';\nimport { Entity } from '@backstage/catalog-model';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { Expand } from '../../../packages/frontend-plugin-api/src/types';\n\nexport { useEntityPermission } from './hooks/useEntityPermission';\nexport { isOwnerOf } from './utils';\n\n/** @alpha */\nexport const entityContentTitleExtensionDataRef =\n createExtensionDataRef<string>('plugin.catalog.entity.content.title');\n\n/** @alpha */\nexport const entityFilterFunctionExtensionDataRef = createExtensionDataRef<\n (entity: Entity) => boolean\n>('plugin.catalog.entity.filter.fn');\n\n/** @alpha */\nexport const entityFilterExpressionExtensionDataRef =\n createExtensionDataRef<string>('plugin.catalog.entity.filter.expression');\n\n// TODO: Figure out how to merge with provided config schema\n/** @alpha */\nexport function createEntityCardExtension<\n TInputs extends AnyExtensionInputMap,\n>(options: {\n id: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n filter?:\n | typeof entityFilterFunctionExtensionDataRef.T\n | typeof entityFilterExpressionExtensionDataRef.T;\n loader: (options: {\n inputs: Expand<ExtensionInputValues<TInputs>>;\n }) => Promise<JSX.Element>;\n}) {\n const id = `entity.cards.${options.id}`;\n\n return createExtension({\n id,\n attachTo: options.attachTo ?? {\n id: 'entity.content.overview',\n input: 'cards',\n },\n disabled: options.disabled ?? true,\n output: {\n element: coreExtensionData.reactElement,\n filterFunction: entityFilterFunctionExtensionDataRef.optional(),\n filterExpression: entityFilterExpressionExtensionDataRef.optional(),\n },\n inputs: options.inputs,\n configSchema: createSchemaFromZod(z =>\n z.object({\n filter: z.string().optional(),\n }),\n ),\n factory({ config, inputs, node }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ inputs })\n .then(element => ({ default: () => element })),\n );\n\n return {\n element: (\n <ExtensionBoundary node={node}>\n <ExtensionComponent />\n </ExtensionBoundary>\n ),\n ...mergeFilters({ config, options }),\n };\n },\n });\n}\n\n/** @alpha */\nexport function createEntityContentExtension<\n TInputs extends AnyExtensionInputMap,\n>(options: {\n id: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n routeRef?: RouteRef;\n defaultPath: string;\n defaultTitle: string;\n filter?:\n | typeof entityFilterFunctionExtensionDataRef.T\n | typeof entityFilterExpressionExtensionDataRef.T;\n loader: (options: {\n inputs: Expand<ExtensionInputValues<TInputs>>;\n }) => Promise<JSX.Element>;\n}) {\n const id = `entity.content.${options.id}`;\n\n return createExtension({\n id,\n attachTo: options.attachTo ?? {\n id: 'plugin.catalog.page.entity',\n input: 'contents',\n },\n disabled: options.disabled ?? true,\n output: {\n element: coreExtensionData.reactElement,\n path: coreExtensionData.routePath,\n routeRef: coreExtensionData.routeRef.optional(),\n title: entityContentTitleExtensionDataRef,\n filterFunction: entityFilterFunctionExtensionDataRef.optional(),\n filterExpression: entityFilterExpressionExtensionDataRef.optional(),\n },\n inputs: options.inputs,\n configSchema: createSchemaFromZod(z =>\n z.object({\n path: z.string().default(options.defaultPath),\n title: z.string().default(options.defaultTitle),\n filter: z.string().optional(),\n }),\n ),\n factory({ config, inputs, node }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ inputs })\n .then(element => ({ default: () => element })),\n );\n\n return {\n path: config.path,\n title: config.title,\n routeRef: options.routeRef,\n element: (\n <ExtensionBoundary node={node} routable>\n <ExtensionComponent />\n </ExtensionBoundary>\n ),\n ...mergeFilters({ config, options }),\n };\n },\n });\n}\n\n/**\n * Decides what filter outputs to produce, given some options and config\n */\nfunction mergeFilters(inputs: {\n options: {\n filter?:\n | typeof entityFilterFunctionExtensionDataRef.T\n | typeof entityFilterExpressionExtensionDataRef.T;\n };\n config: {\n filter?: string;\n };\n}): {\n filterFunction?: typeof entityFilterFunctionExtensionDataRef.T;\n filterExpression?: typeof entityFilterExpressionExtensionDataRef.T;\n} {\n const { options, config } = inputs;\n if (config.filter) {\n return { filterExpression: config.filter };\n } else if (typeof options.filter === 'string') {\n return { filterExpression: options.filter };\n } else if (typeof options.filter === 'function') {\n return { filterFunction: options.filter };\n }\n return {};\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -678,17 +678,29 @@ type EntityListContextProps<EntityFilters extends DefaultEntityFilters = Default
|
|
|
678
678
|
queryParameters: Partial<Record<keyof EntityFilters, string | string[]>>;
|
|
679
679
|
loading: boolean;
|
|
680
680
|
error?: Error;
|
|
681
|
+
pageInfo?: {
|
|
682
|
+
next?: () => void;
|
|
683
|
+
prev?: () => void;
|
|
684
|
+
};
|
|
681
685
|
};
|
|
682
686
|
/**
|
|
683
687
|
* Creates new context for entity listing and filtering.
|
|
684
688
|
* @public
|
|
685
689
|
*/
|
|
686
690
|
declare const EntityListContext: React.Context<EntityListContextProps<any> | undefined>;
|
|
691
|
+
/**
|
|
692
|
+
* @public
|
|
693
|
+
*/
|
|
694
|
+
type EntityListProviderProps = PropsWithChildren<{
|
|
695
|
+
pagination?: boolean | {
|
|
696
|
+
limit?: number;
|
|
697
|
+
};
|
|
698
|
+
}>;
|
|
687
699
|
/**
|
|
688
700
|
* Provides entities and filters for a catalog listing.
|
|
689
701
|
* @public
|
|
690
702
|
*/
|
|
691
|
-
declare const EntityListProvider: <EntityFilters extends DefaultEntityFilters>(props:
|
|
703
|
+
declare const EntityListProvider: <EntityFilters extends DefaultEntityFilters>(props: EntityListProviderProps) => React.JSX.Element;
|
|
692
704
|
/**
|
|
693
705
|
* Hook for interacting with the entity list context provided by the {@link EntityListProvider}.
|
|
694
706
|
* @public
|
|
@@ -883,6 +895,10 @@ type CatalogReactComponentsNameToClassKey = {
|
|
|
883
895
|
type BackstageOverrides = Overrides & {
|
|
884
896
|
[Name in keyof CatalogReactComponentsNameToClassKey]?: Partial<StyleRules<CatalogReactComponentsNameToClassKey[Name]>>;
|
|
885
897
|
};
|
|
898
|
+
declare module '@backstage/theme' {
|
|
899
|
+
interface OverrideComponentNameToClassKeys extends CatalogReactComponentsNameToClassKey {
|
|
900
|
+
}
|
|
901
|
+
}
|
|
886
902
|
|
|
887
903
|
/**
|
|
888
904
|
* Get the related entity references.
|
|
@@ -901,4 +917,4 @@ type EntitySourceLocation = {
|
|
|
901
917
|
/** @public */
|
|
902
918
|
declare function getEntitySourceLocation(entity: Entity, scmIntegrationsApi: typeof scmIntegrationsApiRef.T): EntitySourceLocation | undefined;
|
|
903
919
|
|
|
904
|
-
export { AllowedEntityFilters, AsyncEntityProvider, AsyncEntityProviderProps, BackstageOverrides, CatalogFilterLayout, CatalogReactComponentsNameToClassKey, CatalogReactEntityDisplayNameClassKey, CatalogReactEntityLifecyclePickerClassKey, CatalogReactEntityNamespacePickerClassKey, CatalogReactEntityOwnerPickerClassKey, CatalogReactEntityProcessingStatusPickerClassKey, CatalogReactEntitySearchBarClassKey, CatalogReactEntityTagPickerClassKey, CatalogReactUserListPickerClassKey, DefaultEntityFilters, EntityAutocompletePicker, EntityAutocompletePickerProps, EntityDisplayName, EntityDisplayNameProps, EntityErrorFilter, EntityFilter, EntityKindFilter, EntityKindPicker, EntityKindPickerProps, EntityLifecycleFilter, EntityLifecyclePicker, EntityListContext, EntityListContextProps, EntityListProvider, EntityLoadingStatus, EntityNamespaceFilter, EntityNamespacePicker, EntityOrphanFilter, EntityOwnerFilter, EntityOwnerPicker, EntityOwnerPickerProps, EntityPeekAheadPopover, EntityPeekAheadPopoverProps, EntityPresentationApi, EntityProcessingStatusPicker, EntityProvider, EntityProviderProps, EntityRefLink, EntityRefLinkProps, EntityRefLinks, EntityRefLinksProps, EntityRefPresentation, EntityRefPresentationSnapshot, EntitySearchBar, EntitySourceLocation, EntityTable, EntityTableProps, EntityTagFilter, EntityTagPicker, EntityTagPickerProps, EntityTextFilter, EntityTypeFilter, EntityTypePicker, EntityTypePickerProps, EntityUserFilter, FavoriteEntity, FavoriteEntityProps, InspectEntityDialog, MissingAnnotationEmptyState, MissingAnnotationEmptyStateClassKey, MockEntityListContextProvider, MockStarredEntitiesApi, StarredEntitiesApi, UnregisterEntityDialog, UnregisterEntityDialogProps, UserListFilter, UserListFilterKind, UserListPicker, UserListPickerProps, catalogApiRef, columnFactories, defaultEntityPresentation, entityPresentationApiRef, entityRouteParams, entityRouteRef, getEntityRelations, getEntitySourceLocation, humanizeEntityRef, starredEntitiesApiRef, useAsyncEntity, useEntity, useEntityList, useEntityOwnership, useEntityPresentation, useEntityTypeFilter, useRelatedEntities, useStarredEntities, useStarredEntity };
|
|
920
|
+
export { AllowedEntityFilters, AsyncEntityProvider, AsyncEntityProviderProps, BackstageOverrides, CatalogFilterLayout, CatalogReactComponentsNameToClassKey, CatalogReactEntityDisplayNameClassKey, CatalogReactEntityLifecyclePickerClassKey, CatalogReactEntityNamespacePickerClassKey, CatalogReactEntityOwnerPickerClassKey, CatalogReactEntityProcessingStatusPickerClassKey, CatalogReactEntitySearchBarClassKey, CatalogReactEntityTagPickerClassKey, CatalogReactUserListPickerClassKey, DefaultEntityFilters, EntityAutocompletePicker, EntityAutocompletePickerProps, EntityDisplayName, EntityDisplayNameProps, EntityErrorFilter, EntityFilter, EntityKindFilter, EntityKindPicker, EntityKindPickerProps, EntityLifecycleFilter, EntityLifecyclePicker, EntityListContext, EntityListContextProps, EntityListProvider, EntityListProviderProps, EntityLoadingStatus, EntityNamespaceFilter, EntityNamespacePicker, EntityOrphanFilter, EntityOwnerFilter, EntityOwnerPicker, EntityOwnerPickerProps, EntityPeekAheadPopover, EntityPeekAheadPopoverProps, EntityPresentationApi, EntityProcessingStatusPicker, EntityProvider, EntityProviderProps, EntityRefLink, EntityRefLinkProps, EntityRefLinks, EntityRefLinksProps, EntityRefPresentation, EntityRefPresentationSnapshot, EntitySearchBar, EntitySourceLocation, EntityTable, EntityTableProps, EntityTagFilter, EntityTagPicker, EntityTagPickerProps, EntityTextFilter, EntityTypeFilter, EntityTypePicker, EntityTypePickerProps, EntityUserFilter, FavoriteEntity, FavoriteEntityProps, InspectEntityDialog, MissingAnnotationEmptyState, MissingAnnotationEmptyStateClassKey, MockEntityListContextProvider, MockStarredEntitiesApi, StarredEntitiesApi, UnregisterEntityDialog, UnregisterEntityDialogProps, UserListFilter, UserListFilterKind, UserListPicker, UserListPickerProps, catalogApiRef, columnFactories, defaultEntityPresentation, entityPresentationApiRef, entityRouteParams, entityRouteRef, getEntityRelations, getEntitySourceLocation, humanizeEntityRef, starredEntitiesApiRef, useAsyncEntity, useEntity, useEntityList, useEntityOwnership, useEntityPresentation, useEntityTypeFilter, useRelatedEntities, useStarredEntities, useStarredEntity };
|
package/dist/index.esm.js
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
export { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';
|
|
2
2
|
import { createApiRef, useApiHolder, useApi, identityApiRef, alertApiRef, createRouteRef, useRouteRef, useApp, configApiRef } from '@backstage/core-plugin-api';
|
|
3
3
|
import { stringifyEntityRef, DEFAULT_NAMESPACE, ANNOTATION_SOURCE_LOCATION, parseLocationRef, parseEntityRef, RELATION_OWNED_BY, getCompoundEntityRef, isUserEntity, isGroupEntity, RELATION_PART_OF, ANNOTATION_LOCATION, ANNOTATION_ORIGIN_LOCATION } from '@backstage/catalog-model';
|
|
4
|
-
import ApartmentIcon from '@material-ui/icons/Apartment';
|
|
5
|
-
import BusinessIcon from '@material-ui/icons/Business';
|
|
6
|
-
import ExtensionIcon from '@material-ui/icons/Extension';
|
|
7
|
-
import HelpIcon$1 from '@material-ui/icons/Help';
|
|
8
|
-
import LibraryAddIcon from '@material-ui/icons/LibraryAdd';
|
|
9
|
-
import LocationOnIcon from '@material-ui/icons/LocationOn';
|
|
10
|
-
import MemoryIcon from '@material-ui/icons/Memory';
|
|
11
|
-
import PeopleIcon from '@material-ui/icons/People';
|
|
12
|
-
import PersonIcon from '@material-ui/icons/Person';
|
|
13
4
|
import get from 'lodash/get';
|
|
14
5
|
import React, { useState, useEffect, useMemo, createContext, useCallback, useContext, useRef, memo, forwardRef, useLayoutEffect, Fragment } from 'react';
|
|
15
6
|
import ObservableImpl from 'zen-observable';
|
|
@@ -34,6 +25,7 @@ import CheckBoxIcon from '@material-ui/icons/CheckBox';
|
|
|
34
25
|
import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';
|
|
35
26
|
import classNames from 'classnames';
|
|
36
27
|
import { useMountEffect, useDebouncedEffect } from '@react-hookz/web';
|
|
28
|
+
import PersonIcon from '@material-ui/icons/Person';
|
|
37
29
|
import GroupIcon from '@material-ui/icons/Group';
|
|
38
30
|
import { getOrCreateGlobalSingleton } from '@backstage/version-bridge';
|
|
39
31
|
import HoverPopover from 'material-ui-popup-state/HoverPopover';
|
|
@@ -66,20 +58,8 @@ const entityPresentationApiRef = createApiRef({
|
|
|
66
58
|
id: "plugin.catalog.entity-presentation"
|
|
67
59
|
});
|
|
68
60
|
|
|
69
|
-
const UNKNOWN_KIND_ICON = HelpIcon$1;
|
|
70
|
-
const DEFAULT_ICONS = {
|
|
71
|
-
api: ExtensionIcon,
|
|
72
|
-
component: MemoryIcon,
|
|
73
|
-
system: BusinessIcon,
|
|
74
|
-
domain: ApartmentIcon,
|
|
75
|
-
location: LocationOnIcon,
|
|
76
|
-
user: PersonIcon,
|
|
77
|
-
group: PeopleIcon,
|
|
78
|
-
template: LibraryAddIcon
|
|
79
|
-
};
|
|
80
61
|
function defaultEntityPresentation(entityOrRef, context) {
|
|
81
62
|
const { kind, namespace, name, title, description, displayName, type } = getParts(entityOrRef);
|
|
82
|
-
const Icon = kind && DEFAULT_ICONS[kind.toLocaleLowerCase("en-US")] || UNKNOWN_KIND_ICON;
|
|
83
63
|
const entityRef = stringifyEntityRef({
|
|
84
64
|
kind: kind || "unknown",
|
|
85
65
|
namespace: namespace || DEFAULT_NAMESPACE,
|
|
@@ -98,7 +78,8 @@ function defaultEntityPresentation(entityOrRef, context) {
|
|
|
98
78
|
entityRef,
|
|
99
79
|
primaryTitle: primary,
|
|
100
80
|
secondaryTitle: secondary || void 0,
|
|
101
|
-
Icon
|
|
81
|
+
Icon: void 0
|
|
82
|
+
// leave it up to the presentation API to handle
|
|
102
83
|
};
|
|
103
84
|
}
|
|
104
85
|
function getParts(entityOrRef) {
|
|
@@ -561,21 +542,26 @@ const EntityListProvider = (props) => {
|
|
|
561
542
|
{}
|
|
562
543
|
);
|
|
563
544
|
const location = useLocation();
|
|
564
|
-
const
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
|
|
545
|
+
const enablePagination = props.pagination === true || typeof props.pagination === "object";
|
|
546
|
+
const limit = props.pagination && typeof props.pagination === "object" && typeof props.pagination.limit === "number" ? props.pagination.limit : 20;
|
|
547
|
+
const { queryParameters, cursor: initialCursor } = useMemo(() => {
|
|
548
|
+
var _a;
|
|
549
|
+
const parsed = qs.parse(location.search, {
|
|
550
|
+
ignoreQueryPrefix: true
|
|
551
|
+
});
|
|
552
|
+
return {
|
|
553
|
+
queryParameters: (_a = parsed.filters) != null ? _a : {},
|
|
554
|
+
cursor: typeof parsed.cursor === "string" ? parsed.cursor : void 0
|
|
555
|
+
};
|
|
556
|
+
}, [location]);
|
|
557
|
+
const [cursor, setCursor] = useState(initialCursor);
|
|
573
558
|
const [outputState, setOutputState] = useState(
|
|
574
559
|
() => {
|
|
575
560
|
return {
|
|
576
561
|
appliedFilters: {},
|
|
577
562
|
entities: [],
|
|
578
|
-
backendEntities: []
|
|
563
|
+
backendEntities: [],
|
|
564
|
+
pageInfo: enablePagination ? {} : void 0
|
|
579
565
|
};
|
|
580
566
|
}
|
|
581
567
|
);
|
|
@@ -583,11 +569,6 @@ const EntityListProvider = (props) => {
|
|
|
583
569
|
async () => {
|
|
584
570
|
var _a;
|
|
585
571
|
const compacted = compact(Object.values(requestedFilters));
|
|
586
|
-
const entityFilter = reduceEntityFilters(compacted);
|
|
587
|
-
const backendFilter = reduceBackendCatalogFilters(compacted);
|
|
588
|
-
const previousBackendFilter = reduceBackendCatalogFilters(
|
|
589
|
-
compact(Object.values(outputState.appliedFilters))
|
|
590
|
-
);
|
|
591
572
|
const queryParams = Object.keys(requestedFilters).reduce(
|
|
592
573
|
(params, key) => {
|
|
593
574
|
const filter = requestedFilters[key];
|
|
@@ -598,40 +579,91 @@ const EntityListProvider = (props) => {
|
|
|
598
579
|
},
|
|
599
580
|
{}
|
|
600
581
|
);
|
|
601
|
-
if (
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
582
|
+
if (enablePagination) {
|
|
583
|
+
if (cursor) {
|
|
584
|
+
if (cursor !== outputState.appliedCursor) {
|
|
585
|
+
const entityFilter = reduceEntityFilters(compacted);
|
|
586
|
+
const response = await catalogApi.queryEntities({
|
|
587
|
+
cursor,
|
|
588
|
+
limit
|
|
589
|
+
});
|
|
590
|
+
setOutputState({
|
|
591
|
+
appliedFilters: requestedFilters,
|
|
592
|
+
appliedCursor: cursor,
|
|
593
|
+
backendEntities: response.items,
|
|
594
|
+
entities: response.items.filter(entityFilter),
|
|
595
|
+
pageInfo: response.pageInfo
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
} else {
|
|
599
|
+
const entityFilter = reduceEntityFilters(compacted);
|
|
600
|
+
const backendFilter = reduceCatalogFilters(compacted);
|
|
601
|
+
const previousBackendFilter = reduceCatalogFilters(
|
|
602
|
+
compact(Object.values(outputState.appliedFilters))
|
|
603
|
+
);
|
|
604
|
+
if (!isEqual(previousBackendFilter, backendFilter)) {
|
|
605
|
+
const response = await catalogApi.queryEntities({
|
|
606
|
+
filter: backendFilter,
|
|
607
|
+
limit,
|
|
608
|
+
orderFields: [{ field: "metadata.name", order: "asc" }]
|
|
609
|
+
});
|
|
610
|
+
setOutputState({
|
|
611
|
+
appliedFilters: requestedFilters,
|
|
612
|
+
backendEntities: response.items,
|
|
613
|
+
entities: response.items.filter(entityFilter),
|
|
614
|
+
pageInfo: response.pageInfo
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
}
|
|
610
618
|
} else {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
619
|
+
const entityFilter = reduceEntityFilters(compacted);
|
|
620
|
+
const backendFilter = reduceBackendCatalogFilters(compacted);
|
|
621
|
+
const previousBackendFilter = reduceBackendCatalogFilters(
|
|
622
|
+
compact(Object.values(outputState.appliedFilters))
|
|
623
|
+
);
|
|
624
|
+
if (!isEqual(previousBackendFilter, backendFilter)) {
|
|
625
|
+
const response = await catalogApi.getEntities({
|
|
626
|
+
filter: backendFilter
|
|
627
|
+
});
|
|
628
|
+
setOutputState({
|
|
629
|
+
appliedFilters: requestedFilters,
|
|
630
|
+
backendEntities: response.items,
|
|
631
|
+
entities: response.items.filter(entityFilter)
|
|
632
|
+
});
|
|
633
|
+
} else {
|
|
634
|
+
setOutputState({
|
|
635
|
+
appliedFilters: requestedFilters,
|
|
636
|
+
backendEntities: outputState.backendEntities,
|
|
637
|
+
entities: outputState.backendEntities.filter(entityFilter)
|
|
638
|
+
});
|
|
639
|
+
}
|
|
616
640
|
}
|
|
617
641
|
if (isMounted()) {
|
|
618
642
|
const oldParams = qs.parse(location.search, {
|
|
619
643
|
ignoreQueryPrefix: true
|
|
620
644
|
});
|
|
621
645
|
const newParams = qs.stringify(
|
|
622
|
-
{ ...oldParams, filters: queryParams },
|
|
646
|
+
{ ...oldParams, filters: queryParams, cursor },
|
|
623
647
|
{ addQueryPrefix: true, arrayFormat: "repeat" }
|
|
624
648
|
);
|
|
625
649
|
const newUrl = `${window.location.pathname}${newParams}`;
|
|
626
650
|
(_a = window.history) == null ? void 0 : _a.replaceState(null, document.title, newUrl);
|
|
627
651
|
}
|
|
628
652
|
},
|
|
629
|
-
[
|
|
653
|
+
[
|
|
654
|
+
catalogApi,
|
|
655
|
+
queryParameters,
|
|
656
|
+
requestedFilters,
|
|
657
|
+
outputState,
|
|
658
|
+
cursor,
|
|
659
|
+
enablePagination
|
|
660
|
+
],
|
|
630
661
|
{ loading: true }
|
|
631
662
|
);
|
|
632
|
-
useDebounce(refresh, 10, [requestedFilters]);
|
|
663
|
+
useDebounce(refresh, 10, [requestedFilters, cursor]);
|
|
633
664
|
const updateFilters = useCallback(
|
|
634
665
|
(update) => {
|
|
666
|
+
setCursor(void 0);
|
|
635
667
|
setRequestedFilters((prevFilters) => {
|
|
636
668
|
const newFilters = typeof update === "function" ? update(prevFilters) : update;
|
|
637
669
|
return { ...prevFilters, ...newFilters };
|
|
@@ -639,6 +671,18 @@ const EntityListProvider = (props) => {
|
|
|
639
671
|
},
|
|
640
672
|
[]
|
|
641
673
|
);
|
|
674
|
+
const pageInfo = useMemo(() => {
|
|
675
|
+
var _a, _b;
|
|
676
|
+
if (!enablePagination) {
|
|
677
|
+
return void 0;
|
|
678
|
+
}
|
|
679
|
+
const prevCursor = (_a = outputState.pageInfo) == null ? void 0 : _a.prevCursor;
|
|
680
|
+
const nextCursor = (_b = outputState.pageInfo) == null ? void 0 : _b.nextCursor;
|
|
681
|
+
return {
|
|
682
|
+
prev: prevCursor ? () => setCursor(prevCursor) : void 0,
|
|
683
|
+
next: nextCursor ? () => setCursor(nextCursor) : void 0
|
|
684
|
+
};
|
|
685
|
+
}, [enablePagination, outputState.pageInfo]);
|
|
642
686
|
const value = useMemo(
|
|
643
687
|
() => ({
|
|
644
688
|
filters: outputState.appliedFilters,
|
|
@@ -647,9 +691,10 @@ const EntityListProvider = (props) => {
|
|
|
647
691
|
updateFilters,
|
|
648
692
|
queryParameters,
|
|
649
693
|
loading,
|
|
650
|
-
error
|
|
694
|
+
error,
|
|
695
|
+
pageInfo
|
|
651
696
|
}),
|
|
652
|
-
[outputState, updateFilters, queryParameters, loading, error]
|
|
697
|
+
[outputState, updateFilters, queryParameters, loading, error, pageInfo]
|
|
653
698
|
);
|
|
654
699
|
return /* @__PURE__ */ React.createElement(EntityListContext.Provider, { value }, props.children);
|
|
655
700
|
};
|