@backstage/plugin-catalog-react 1.8.5 → 1.9.0-next.0
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 -0
- package/alpha/package.json +1 -1
- package/dist/alpha.d.ts +66 -1
- package/dist/alpha.esm.js +113 -2
- package/dist/alpha.esm.js.map +1 -1
- package/dist/index.d.ts +197 -13
- package/dist/index.esm.js +530 -161
- package/dist/index.esm.js.map +1 -1
- package/package.json +14 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-react
|
|
2
2
|
|
|
3
|
+
## 1.9.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 1e5b7d993a: Added an `EntityPresentationApi` and associated `entityPresentationApiRef`. This
|
|
8
|
+
API lets you control how references to entities (e.g. in links, headings,
|
|
9
|
+
iconography etc) are represented in the user interface.
|
|
10
|
+
|
|
11
|
+
Usage of this API is initially added to the `EntityRefLink` and `EntityRefLinks`
|
|
12
|
+
components, so that they can render richer, more correct representation of
|
|
13
|
+
entity refs. There's also a new `EntityDisplayName` component, which works just like
|
|
14
|
+
the `EntityRefLink` but without the link.
|
|
15
|
+
|
|
16
|
+
Along with that change, the `fetchEntities` and `getTitle` props of
|
|
17
|
+
`EntityRefLinksProps` are deprecated and no longer used, since the same need
|
|
18
|
+
instead is fulfilled (and by default always enabled) by the
|
|
19
|
+
`entityPresentationApiRef`.
|
|
20
|
+
|
|
21
|
+
- 1fd53fa0c6: The `UserListPicker` component has undergone improvements to enhance its performance.
|
|
22
|
+
|
|
23
|
+
The previous implementation inferred the number of owned and starred entities based on the entities available in the `EntityListContext`. The updated version no longer relies on the `EntityListContext` for inference, allowing for better decoupling.
|
|
24
|
+
|
|
25
|
+
The component now loads the entities' count asynchronously, resulting in improved performance and responsiveness. For this purpose, some of the exported filters such as `EntityTagFilter`, `EntityOwnerFilter`, `EntityLifecycleFilter` and `EntityNamespaceFilter` have now the `getCatalogFilters` method implemented.
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- 6c2b872153: Add official support for React 18.
|
|
30
|
+
- 0bf6ebda88: Added new APIs at the `/alpha` subpath for creating entity page cards and content for the new frontend system.
|
|
31
|
+
- 71c97e7d73: The `spec.type` field in entities will now always be rendered as a string.
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
- @backstage/core-components@0.13.7-next.0
|
|
34
|
+
- @backstage/frontend-plugin-api@0.3.0-next.0
|
|
35
|
+
- @backstage/core-plugin-api@1.8.0-next.0
|
|
36
|
+
- @backstage/plugin-permission-react@0.4.17-next.0
|
|
37
|
+
- @backstage/version-bridge@1.0.7-next.0
|
|
38
|
+
- @backstage/theme@0.4.4-next.0
|
|
39
|
+
- @backstage/integration@1.7.1
|
|
40
|
+
- @backstage/catalog-client@1.4.5
|
|
41
|
+
- @backstage/catalog-model@1.4.3
|
|
42
|
+
- @backstage/errors@1.2.3
|
|
43
|
+
- @backstage/types@1.1.1
|
|
44
|
+
- @backstage/plugin-catalog-common@1.0.17
|
|
45
|
+
- @backstage/plugin-permission-common@0.7.9
|
|
46
|
+
|
|
3
47
|
## 1.8.5
|
|
4
48
|
|
|
5
49
|
### Patch Changes
|
package/alpha/package.json
CHANGED
package/dist/alpha.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
3
|
+
import { AnyExtensionInputMap, ExtensionInputValues, RouteRef } from '@backstage/frontend-plugin-api';
|
|
1
4
|
import { Entity } from '@backstage/catalog-model';
|
|
2
5
|
import { ResourcePermission } from '@backstage/plugin-permission-common';
|
|
3
6
|
|
|
@@ -12,6 +15,14 @@ import { ResourcePermission } from '@backstage/plugin-permission-common';
|
|
|
12
15
|
*/
|
|
13
16
|
declare function isOwnerOf(owner: Entity, entity: Entity): boolean;
|
|
14
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Utility type to expand type aliases into their equivalent type.
|
|
20
|
+
* @ignore
|
|
21
|
+
*/
|
|
22
|
+
type Expand<T> = T extends infer O ? {
|
|
23
|
+
[K in keyof O]: O[K];
|
|
24
|
+
} : never;
|
|
25
|
+
|
|
15
26
|
/**
|
|
16
27
|
* A thin wrapper around the
|
|
17
28
|
* {@link @backstage/plugin-permission-react#usePermission} hook which uses the
|
|
@@ -29,4 +40,58 @@ declare function useEntityPermission(permission: ResourcePermission<'catalog-ent
|
|
|
29
40
|
error?: Error;
|
|
30
41
|
};
|
|
31
42
|
|
|
32
|
-
|
|
43
|
+
/** @alpha */
|
|
44
|
+
declare const entityContentTitleExtensionDataRef: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, {}>;
|
|
45
|
+
/** @alpha */
|
|
46
|
+
declare const entityFilterExtensionDataRef: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(ctx: {
|
|
47
|
+
entity: Entity;
|
|
48
|
+
}) => boolean, {}>;
|
|
49
|
+
/** @alpha */
|
|
50
|
+
declare function createEntityCardExtension<TInputs extends AnyExtensionInputMap>(options: {
|
|
51
|
+
id: string;
|
|
52
|
+
attachTo?: {
|
|
53
|
+
id: string;
|
|
54
|
+
input: string;
|
|
55
|
+
};
|
|
56
|
+
disabled?: boolean;
|
|
57
|
+
inputs?: TInputs;
|
|
58
|
+
filter?: (ctx: {
|
|
59
|
+
entity: Entity;
|
|
60
|
+
}) => boolean;
|
|
61
|
+
loader: (options: {
|
|
62
|
+
inputs: Expand<ExtensionInputValues<TInputs>>;
|
|
63
|
+
}) => Promise<JSX.Element>;
|
|
64
|
+
}): _backstage_frontend_plugin_api.Extension<{
|
|
65
|
+
filter?: {
|
|
66
|
+
isKind?: string | undefined;
|
|
67
|
+
isType?: string | undefined;
|
|
68
|
+
}[] | undefined;
|
|
69
|
+
}>;
|
|
70
|
+
/** @alpha */
|
|
71
|
+
declare function createEntityContentExtension<TInputs extends AnyExtensionInputMap>(options: {
|
|
72
|
+
id: string;
|
|
73
|
+
attachTo?: {
|
|
74
|
+
id: string;
|
|
75
|
+
input: string;
|
|
76
|
+
};
|
|
77
|
+
disabled?: boolean;
|
|
78
|
+
inputs?: TInputs;
|
|
79
|
+
routeRef?: RouteRef;
|
|
80
|
+
defaultPath: string;
|
|
81
|
+
defaultTitle: string;
|
|
82
|
+
filter?: (ctx: {
|
|
83
|
+
entity: Entity;
|
|
84
|
+
}) => boolean;
|
|
85
|
+
loader: (options: {
|
|
86
|
+
inputs: Expand<ExtensionInputValues<TInputs>>;
|
|
87
|
+
}) => Promise<JSX.Element>;
|
|
88
|
+
}): _backstage_frontend_plugin_api.Extension<{
|
|
89
|
+
title: string;
|
|
90
|
+
path: string;
|
|
91
|
+
filter?: {
|
|
92
|
+
isKind?: string | undefined;
|
|
93
|
+
isType?: string | undefined;
|
|
94
|
+
}[] | undefined;
|
|
95
|
+
}>;
|
|
96
|
+
|
|
97
|
+
export { createEntityCardExtension, createEntityContentExtension, entityContentTitleExtensionDataRef, entityFilterExtensionDataRef, isOwnerOf, useEntityPermission };
|
package/dist/alpha.esm.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import React, { lazy } from 'react';
|
|
2
|
+
import { createExtensionDataRef, createExtension, coreExtensionData, createSchemaFromZod, ExtensionBoundary } from '@backstage/frontend-plugin-api';
|
|
1
3
|
import { RELATION_MEMBER_OF, getCompoundEntityRef, stringifyEntityRef, RELATION_OWNED_BY } from '@backstage/catalog-model';
|
|
2
4
|
import { g as getEntityRelations, a as useAsyncEntity } from './esm/useEntity-de64059a.esm.js';
|
|
3
5
|
import { usePermission } from '@backstage/plugin-permission-react';
|
|
4
6
|
import '@backstage/core-plugin-api';
|
|
5
7
|
import '@backstage/version-bridge';
|
|
6
|
-
import 'react';
|
|
7
8
|
|
|
8
9
|
function isOwnerOf(owner, entity) {
|
|
9
10
|
const possibleOwners = new Set(
|
|
@@ -46,5 +47,115 @@ function useEntityPermission(permission) {
|
|
|
46
47
|
return { loading: false, allowed, error: permissionError };
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
const entityContentTitleExtensionDataRef = createExtensionDataRef("plugin.catalog.entity.content.title");
|
|
51
|
+
const entityFilterExtensionDataRef = createExtensionDataRef("plugin.catalog.entity.filter");
|
|
52
|
+
function applyFilter(a, b) {
|
|
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
|
+
}
|
|
79
|
+
function createEntityCardExtension(options) {
|
|
80
|
+
var _a, _b;
|
|
81
|
+
const id = `entity.cards.${options.id}`;
|
|
82
|
+
return createExtension({
|
|
83
|
+
id,
|
|
84
|
+
attachTo: (_a = options.attachTo) != null ? _a : {
|
|
85
|
+
id: "entity.content.overview",
|
|
86
|
+
input: "cards"
|
|
87
|
+
},
|
|
88
|
+
disabled: (_b = options.disabled) != null ? _b : true,
|
|
89
|
+
output: {
|
|
90
|
+
element: coreExtensionData.reactElement,
|
|
91
|
+
filter: entityFilterExtensionDataRef
|
|
92
|
+
},
|
|
93
|
+
inputs: options.inputs,
|
|
94
|
+
configSchema: createSchemaFromZod(
|
|
95
|
+
(z) => z.object({
|
|
96
|
+
filter: z.array(
|
|
97
|
+
z.object({
|
|
98
|
+
isKind: z.string().optional(),
|
|
99
|
+
isType: z.string().optional()
|
|
100
|
+
})
|
|
101
|
+
).optional()
|
|
102
|
+
})
|
|
103
|
+
),
|
|
104
|
+
factory({ bind, config, inputs, source }) {
|
|
105
|
+
const ExtensionComponent = lazy(
|
|
106
|
+
() => options.loader({ inputs }).then((element) => ({ default: () => element }))
|
|
107
|
+
);
|
|
108
|
+
bind({
|
|
109
|
+
element: /* @__PURE__ */ React.createElement(ExtensionBoundary, { id, source }, /* @__PURE__ */ React.createElement(ExtensionComponent, null)),
|
|
110
|
+
filter: buildFilter(config, options.filter)
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function createEntityContentExtension(options) {
|
|
116
|
+
var _a, _b;
|
|
117
|
+
const id = `entity.content.${options.id}`;
|
|
118
|
+
return createExtension({
|
|
119
|
+
id,
|
|
120
|
+
attachTo: (_a = options.attachTo) != null ? _a : {
|
|
121
|
+
id: "plugin.catalog.page.entity",
|
|
122
|
+
input: "contents"
|
|
123
|
+
},
|
|
124
|
+
disabled: (_b = options.disabled) != null ? _b : true,
|
|
125
|
+
output: {
|
|
126
|
+
element: coreExtensionData.reactElement,
|
|
127
|
+
path: coreExtensionData.routePath,
|
|
128
|
+
routeRef: coreExtensionData.routeRef.optional(),
|
|
129
|
+
title: entityContentTitleExtensionDataRef,
|
|
130
|
+
filter: entityFilterExtensionDataRef
|
|
131
|
+
},
|
|
132
|
+
inputs: options.inputs,
|
|
133
|
+
configSchema: createSchemaFromZod(
|
|
134
|
+
(z) => z.object({
|
|
135
|
+
path: z.string().default(options.defaultPath),
|
|
136
|
+
title: z.string().default(options.defaultTitle),
|
|
137
|
+
filter: z.array(
|
|
138
|
+
z.object({
|
|
139
|
+
isKind: z.string().optional(),
|
|
140
|
+
isType: z.string().optional()
|
|
141
|
+
})
|
|
142
|
+
).optional()
|
|
143
|
+
})
|
|
144
|
+
),
|
|
145
|
+
factory({ bind, config, inputs, source }) {
|
|
146
|
+
const ExtensionComponent = lazy(
|
|
147
|
+
() => options.loader({ inputs }).then((element) => ({ default: () => element }))
|
|
148
|
+
);
|
|
149
|
+
bind({
|
|
150
|
+
path: config.path,
|
|
151
|
+
title: config.title,
|
|
152
|
+
routeRef: options.routeRef,
|
|
153
|
+
element: /* @__PURE__ */ React.createElement(ExtensionBoundary, { id, source, routable: true }, /* @__PURE__ */ React.createElement(ExtensionComponent, null)),
|
|
154
|
+
filter: buildFilter(config, options.filter)
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export { createEntityCardExtension, createEntityContentExtension, entityContentTitleExtensionDataRef, entityFilterExtensionDataRef, isOwnerOf, useEntityPermission };
|
|
50
161
|
//# 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"],"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;;;;"}
|
|
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({ bind, config, inputs, source }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ inputs })\n .then(element => ({ default: () => element })),\n );\n\n bind({\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({ bind, config, inputs, source }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ inputs })\n .then(element => ({ default: () => element })),\n );\n\n bind({\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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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
1
2
|
import { CatalogApi } from '@backstage/catalog-client';
|
|
2
3
|
export { CATALOG_FILTER_EXISTS, CatalogApi } from '@backstage/catalog-client';
|
|
3
4
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
4
|
-
import { ApiRef } from '@backstage/core-plugin-api';
|
|
5
|
-
import { Observable } from '@backstage/types';
|
|
6
|
-
import React, { PropsWithChildren, ReactNode, ComponentProps } from 'react';
|
|
5
|
+
import { ApiRef, IconComponent } from '@backstage/core-plugin-api';
|
|
7
6
|
import * as _backstage_catalog_model from '@backstage/catalog-model';
|
|
8
7
|
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
|
|
8
|
+
import { Observable } from '@backstage/types';
|
|
9
|
+
import React, { PropsWithChildren, ReactNode, ComponentProps } from 'react';
|
|
9
10
|
import { LinkProps, InfoCardVariants, TableColumn, TableOptions } from '@backstage/core-components';
|
|
10
11
|
import { IconButton, TextFieldProps } from '@material-ui/core';
|
|
11
12
|
import { Overrides } from '@material-ui/core/styles/overrides';
|
|
@@ -18,6 +19,143 @@ import { ScmIntegrationRegistry } from '@backstage/integration';
|
|
|
18
19
|
*/
|
|
19
20
|
declare const catalogApiRef: _backstage_core_plugin_api.ApiRef<CatalogApi>;
|
|
20
21
|
|
|
22
|
+
/**
|
|
23
|
+
* An API that handles how to represent entities in the interface.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
declare const entityPresentationApiRef: ApiRef<EntityPresentationApi>;
|
|
28
|
+
/**
|
|
29
|
+
* The visual presentation of an entity reference at some point in time.
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
interface EntityRefPresentationSnapshot {
|
|
34
|
+
/**
|
|
35
|
+
* The ref to the entity that this snapshot represents.
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
*
|
|
39
|
+
* Note that when the input data was broken or had missing vital pieces of
|
|
40
|
+
* information, this string may contain placeholders such as "unknown". You
|
|
41
|
+
* can therefore not necessarily assume that the ref is completely valid and
|
|
42
|
+
* usable for example for forming a clickable link to the entity.
|
|
43
|
+
*/
|
|
44
|
+
entityRef: string;
|
|
45
|
+
/**
|
|
46
|
+
* A string that can be used as a plain representation of the entity, for
|
|
47
|
+
* example in a header or a link.
|
|
48
|
+
*
|
|
49
|
+
* @remarks
|
|
50
|
+
*
|
|
51
|
+
* The title may be short and not contain all of the information that the
|
|
52
|
+
* entity holds. When rendering the primary title, you may also want to
|
|
53
|
+
* make sure to add more contextual information nearby such as the icon or
|
|
54
|
+
* secondary title, since the primary could for example just be the
|
|
55
|
+
* `metadata.name` of the entity which might be ambiguous to the reader.
|
|
56
|
+
*/
|
|
57
|
+
primaryTitle: string;
|
|
58
|
+
/**
|
|
59
|
+
* Optionally, some additional textual information about the entity, to be
|
|
60
|
+
* used as a clarification on top of the primary title.
|
|
61
|
+
*
|
|
62
|
+
* @remarks
|
|
63
|
+
*
|
|
64
|
+
* This text can for example be rendered in a tooltip or be used as a
|
|
65
|
+
* subtitle. It may not be sufficient to display on its own; it should
|
|
66
|
+
* typically be used in conjunction with the primary title. It can contain
|
|
67
|
+
* such information as the entity ref and/or a `spec.type` etc.
|
|
68
|
+
*/
|
|
69
|
+
secondaryTitle?: string;
|
|
70
|
+
/**
|
|
71
|
+
* Optionally, an icon that represents the kind/type of entity.
|
|
72
|
+
*
|
|
73
|
+
* @remarks
|
|
74
|
+
*
|
|
75
|
+
* This icon should ideally be easily recognizable as the kind of entity, and
|
|
76
|
+
* be used consistently throughout the Backstage interface. It can be rendered
|
|
77
|
+
* both in larger formats such as in a header, or in smaller formats such as
|
|
78
|
+
* inline with regular text, so bear in mind that the legibility should be
|
|
79
|
+
* high in both cases.
|
|
80
|
+
*
|
|
81
|
+
* A value of `false` here indicates the desire to not have an icon present
|
|
82
|
+
* for the given implementation. A value of `undefined` leaves it at the
|
|
83
|
+
* discretion of the display layer to choose what to do (such as for example
|
|
84
|
+
* showing a fallback icon).
|
|
85
|
+
*/
|
|
86
|
+
Icon?: IconComponent | undefined | false;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The visual presentation of an entity reference.
|
|
90
|
+
*
|
|
91
|
+
* @public
|
|
92
|
+
*/
|
|
93
|
+
interface EntityRefPresentation {
|
|
94
|
+
/**
|
|
95
|
+
* The representation that's suitable to use for this entity right now.
|
|
96
|
+
*/
|
|
97
|
+
snapshot: EntityRefPresentationSnapshot;
|
|
98
|
+
/**
|
|
99
|
+
* Some presentation implementations support emitting updated snapshots over
|
|
100
|
+
* time, for example after retrieving additional data from the catalog or
|
|
101
|
+
* elsewhere.
|
|
102
|
+
*/
|
|
103
|
+
update$?: Observable<EntityRefPresentationSnapshot>;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* An API that decides how to visually represent entities in the interface.
|
|
107
|
+
*
|
|
108
|
+
* @remarks
|
|
109
|
+
*
|
|
110
|
+
* Most consumers will want to use the {@link useEntityPresentation} hook
|
|
111
|
+
* instead of this interface directly.
|
|
112
|
+
*
|
|
113
|
+
* @public
|
|
114
|
+
*/
|
|
115
|
+
interface EntityPresentationApi {
|
|
116
|
+
/**
|
|
117
|
+
* Fetches the presentation for an entity.
|
|
118
|
+
*
|
|
119
|
+
* @param entityOrRef - Either an entity, or a string ref to it. If you pass
|
|
120
|
+
* in an entity, it is assumed that it is not a partial one - i.e. only pass
|
|
121
|
+
* in an entity if you know that it was fetched in such a way that it
|
|
122
|
+
* contains all of the fields that the representation renderer needs.
|
|
123
|
+
* @param context - Contextual information that may affect the presentation.
|
|
124
|
+
*/
|
|
125
|
+
forEntity(entityOrRef: Entity | string, context?: {
|
|
126
|
+
defaultKind?: string;
|
|
127
|
+
defaultNamespace?: string;
|
|
128
|
+
}): EntityRefPresentation;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* This returns the default representation of an entity.
|
|
133
|
+
*
|
|
134
|
+
* @public
|
|
135
|
+
* @param entityOrRef - Either an entity, or a ref to it.
|
|
136
|
+
* @param context - Contextual information that may affect the presentation.
|
|
137
|
+
*/
|
|
138
|
+
declare function defaultEntityPresentation(entityOrRef: Entity | CompoundEntityRef | string, context?: {
|
|
139
|
+
defaultKind?: string;
|
|
140
|
+
defaultNamespace?: string;
|
|
141
|
+
}): EntityRefPresentationSnapshot;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Returns information about how to represent an entity in the interface.
|
|
145
|
+
*
|
|
146
|
+
* @public
|
|
147
|
+
* @param entityOrRef - The entity to represent, or an entity ref to it. If you
|
|
148
|
+
* pass in an entity, it is assumed that it is NOT a partial one - i.e. only
|
|
149
|
+
* pass in an entity if you know that it was fetched in such a way that it
|
|
150
|
+
* contains all of the fields that the representation renderer needs.
|
|
151
|
+
* @param context - Optional context that control details of the presentation.
|
|
152
|
+
* @returns A snapshot of the entity presentation, which may change over time
|
|
153
|
+
*/
|
|
154
|
+
declare function useEntityPresentation(entityOrRef: Entity | CompoundEntityRef | string, context?: {
|
|
155
|
+
defaultKind?: string;
|
|
156
|
+
defaultNamespace?: string;
|
|
157
|
+
}): EntityRefPresentationSnapshot;
|
|
158
|
+
|
|
21
159
|
/**
|
|
22
160
|
* An API to store starred entities
|
|
23
161
|
*
|
|
@@ -107,6 +245,32 @@ type EntityOwnerPickerProps = {
|
|
|
107
245
|
/** @public */
|
|
108
246
|
declare const EntityOwnerPicker: (props?: EntityOwnerPickerProps) => React.JSX.Element | null;
|
|
109
247
|
|
|
248
|
+
/**
|
|
249
|
+
* The available style class keys for {@link EntityDisplayName}, under the name
|
|
250
|
+
* "CatalogReactEntityDisplayName".
|
|
251
|
+
*
|
|
252
|
+
* @public
|
|
253
|
+
*/
|
|
254
|
+
type CatalogReactEntityDisplayNameClassKey = 'root' | 'icon';
|
|
255
|
+
/**
|
|
256
|
+
* Props for {@link EntityDisplayName}.
|
|
257
|
+
*
|
|
258
|
+
* @public
|
|
259
|
+
*/
|
|
260
|
+
type EntityDisplayNameProps = {
|
|
261
|
+
entityRef: Entity | CompoundEntityRef | string;
|
|
262
|
+
noIcon?: boolean;
|
|
263
|
+
noTooltip?: boolean;
|
|
264
|
+
defaultKind?: string;
|
|
265
|
+
defaultNamespace?: string;
|
|
266
|
+
};
|
|
267
|
+
/**
|
|
268
|
+
* Shows a nice representation of a reference to an entity.
|
|
269
|
+
*
|
|
270
|
+
* @public
|
|
271
|
+
*/
|
|
272
|
+
declare const EntityDisplayName: (props: EntityDisplayNameProps) => JSX.Element;
|
|
273
|
+
|
|
110
274
|
/**
|
|
111
275
|
* Props for {@link EntityRefLink}.
|
|
112
276
|
*
|
|
@@ -115,6 +279,8 @@ declare const EntityOwnerPicker: (props?: EntityOwnerPickerProps) => React.JSX.E
|
|
|
115
279
|
type EntityRefLinkProps = {
|
|
116
280
|
entityRef: Entity | CompoundEntityRef | string;
|
|
117
281
|
defaultKind?: string;
|
|
282
|
+
defaultNamespace?: string;
|
|
283
|
+
/** @deprecated This option should no longer be used; presentation is requested through the {@link entityPresentationApiRef} instead */
|
|
118
284
|
title?: string;
|
|
119
285
|
children?: React.ReactNode;
|
|
120
286
|
} & Omit<LinkProps, 'to'>;
|
|
@@ -130,17 +296,14 @@ declare const EntityRefLink: (props: EntityRefLinkProps) => JSX.Element;
|
|
|
130
296
|
*
|
|
131
297
|
* @public
|
|
132
298
|
*/
|
|
133
|
-
type EntityRefLinksProps<TRef extends string | CompoundEntityRef | Entity> =
|
|
299
|
+
type EntityRefLinksProps<TRef extends string | CompoundEntityRef | Entity> = {
|
|
134
300
|
defaultKind?: string;
|
|
135
301
|
entityRefs: TRef[];
|
|
136
|
-
|
|
302
|
+
/** @deprecated This option is no longer used; presentation is handled by entityPresentationApiRef instead */
|
|
303
|
+
fetchEntities?: boolean;
|
|
304
|
+
/** @deprecated This option is no longer used; presentation is handled by entityPresentationApiRef instead */
|
|
137
305
|
getTitle?(entity: TRef): string | undefined;
|
|
138
|
-
}
|
|
139
|
-
defaultKind?: string;
|
|
140
|
-
entityRefs: TRef[];
|
|
141
|
-
fetchEntities: true;
|
|
142
|
-
getTitle(entity: Entity): string | undefined;
|
|
143
|
-
}) & Omit<LinkProps, 'to'>;
|
|
306
|
+
} & Omit<LinkProps, 'to'>;
|
|
144
307
|
/**
|
|
145
308
|
* Shows a list of clickable links to entities.
|
|
146
309
|
*
|
|
@@ -375,6 +538,7 @@ declare class EntityTagFilter implements EntityFilter {
|
|
|
375
538
|
readonly values: string[];
|
|
376
539
|
constructor(values: string[]);
|
|
377
540
|
filterEntity(entity: Entity): boolean;
|
|
541
|
+
getCatalogFilters(): Record<string, string | string[]>;
|
|
378
542
|
toQueryValue(): string[];
|
|
379
543
|
}
|
|
380
544
|
/**
|
|
@@ -396,6 +560,7 @@ declare class EntityTextFilter implements EntityFilter {
|
|
|
396
560
|
declare class EntityOwnerFilter implements EntityFilter {
|
|
397
561
|
readonly values: string[];
|
|
398
562
|
constructor(values: string[]);
|
|
563
|
+
getCatalogFilters(): Record<string, string | string[]>;
|
|
399
564
|
filterEntity(entity: Entity): boolean;
|
|
400
565
|
/**
|
|
401
566
|
* Get the URL query parameter value. May be a mix of full and humanized entity refs.
|
|
@@ -410,6 +575,7 @@ declare class EntityOwnerFilter implements EntityFilter {
|
|
|
410
575
|
declare class EntityLifecycleFilter implements EntityFilter {
|
|
411
576
|
readonly values: string[];
|
|
412
577
|
constructor(values: string[]);
|
|
578
|
+
getCatalogFilters(): Record<string, string | string[]>;
|
|
413
579
|
filterEntity(entity: Entity): boolean;
|
|
414
580
|
toQueryValue(): string[];
|
|
415
581
|
}
|
|
@@ -420,11 +586,27 @@ declare class EntityLifecycleFilter implements EntityFilter {
|
|
|
420
586
|
declare class EntityNamespaceFilter implements EntityFilter {
|
|
421
587
|
readonly values: string[];
|
|
422
588
|
constructor(values: string[]);
|
|
589
|
+
getCatalogFilters(): Record<string, string | string[]>;
|
|
423
590
|
filterEntity(entity: Entity): boolean;
|
|
424
591
|
toQueryValue(): string[];
|
|
425
592
|
}
|
|
593
|
+
/**
|
|
594
|
+
* @public
|
|
595
|
+
*/
|
|
596
|
+
declare class EntityUserFilter implements EntityFilter {
|
|
597
|
+
readonly value: UserListFilterKind;
|
|
598
|
+
readonly refs?: string[] | undefined;
|
|
599
|
+
private constructor();
|
|
600
|
+
static owned(ownershipEntityRefs: string[]): EntityUserFilter;
|
|
601
|
+
static all(): EntityUserFilter;
|
|
602
|
+
static starred(starredEntityRefs: string[]): EntityUserFilter;
|
|
603
|
+
getCatalogFilters(): Record<string, string[]>;
|
|
604
|
+
filterEntity(entity: Entity): boolean;
|
|
605
|
+
toQueryValue(): string;
|
|
606
|
+
}
|
|
426
607
|
/**
|
|
427
608
|
* Filters entities based on whatever the user has starred or owns them.
|
|
609
|
+
* @deprecated use EntityUserFilter
|
|
428
610
|
* @public
|
|
429
611
|
*/
|
|
430
612
|
declare class UserListFilter implements EntityFilter {
|
|
@@ -442,6 +624,7 @@ declare class UserListFilter implements EntityFilter {
|
|
|
442
624
|
declare class EntityOrphanFilter implements EntityFilter {
|
|
443
625
|
readonly value: boolean;
|
|
444
626
|
constructor(value: boolean);
|
|
627
|
+
getCatalogFilters(): Record<string, string | string[]>;
|
|
445
628
|
filterEntity(entity: Entity): boolean;
|
|
446
629
|
}
|
|
447
630
|
/**
|
|
@@ -458,7 +641,7 @@ declare class EntityErrorFilter implements EntityFilter {
|
|
|
458
641
|
type DefaultEntityFilters = {
|
|
459
642
|
kind?: EntityKindFilter;
|
|
460
643
|
type?: EntityTypeFilter;
|
|
461
|
-
user?: UserListFilter;
|
|
644
|
+
user?: UserListFilter | EntityUserFilter;
|
|
462
645
|
owners?: EntityOwnerFilter;
|
|
463
646
|
lifecycles?: EntityLifecycleFilter;
|
|
464
647
|
tags?: EntityTagFilter;
|
|
@@ -676,6 +859,7 @@ declare function MockEntityListContextProvider<T extends DefaultEntityFilters =
|
|
|
676
859
|
/** @public */
|
|
677
860
|
type CatalogReactComponentsNameToClassKey = {
|
|
678
861
|
CatalogReactUserListPicker: CatalogReactUserListPickerClassKey;
|
|
862
|
+
CatalogReactEntityDisplayName: CatalogReactEntityDisplayNameClassKey;
|
|
679
863
|
CatalogReactEntityLifecyclePicker: CatalogReactEntityLifecyclePickerClassKey;
|
|
680
864
|
CatalogReactEntitySearchBar: CatalogReactEntitySearchBarClassKey;
|
|
681
865
|
CatalogReactEntityTagPicker: CatalogReactEntityTagPickerClassKey;
|
|
@@ -704,4 +888,4 @@ type EntitySourceLocation = {
|
|
|
704
888
|
/** @public */
|
|
705
889
|
declare function getEntitySourceLocation(entity: Entity, scmIntegrationsApi: ScmIntegrationRegistry): EntitySourceLocation | undefined;
|
|
706
890
|
|
|
707
|
-
export { AllowedEntityFilters, AsyncEntityProvider, AsyncEntityProviderProps, BackstageOverrides, CatalogFilterLayout, CatalogReactComponentsNameToClassKey, CatalogReactEntityLifecyclePickerClassKey, CatalogReactEntityNamespacePickerClassKey, CatalogReactEntityOwnerPickerClassKey, CatalogReactEntityProcessingStatusPickerClassKey, CatalogReactEntitySearchBarClassKey, CatalogReactEntityTagPickerClassKey, CatalogReactUserListPickerClassKey, DefaultEntityFilters, EntityAutocompletePicker, EntityAutocompletePickerProps, EntityErrorFilter, EntityFilter, EntityKindFilter, EntityKindPicker, EntityKindPickerProps, EntityLifecycleFilter, EntityLifecyclePicker, EntityListContext, EntityListContextProps, EntityListProvider, EntityLoadingStatus, EntityNamespaceFilter, EntityNamespacePicker, EntityOrphanFilter, EntityOwnerFilter, EntityOwnerPicker, EntityOwnerPickerProps, EntityPeekAheadPopover, EntityPeekAheadPopoverProps, EntityProcessingStatusPicker, EntityProvider, EntityProviderProps, EntityRefLink, EntityRefLinkProps, EntityRefLinks, EntityRefLinksProps, EntitySearchBar, EntitySourceLocation, EntityTable, EntityTableProps, EntityTagFilter, EntityTagPicker, EntityTagPickerProps, EntityTextFilter, EntityTypeFilter, EntityTypePicker, EntityTypePickerProps, FavoriteEntity, FavoriteEntityProps, InspectEntityDialog, MockEntityListContextProvider, MockStarredEntitiesApi, StarredEntitiesApi, UnregisterEntityDialog, UnregisterEntityDialogProps, UserListFilter, UserListFilterKind, UserListPicker, UserListPickerProps, catalogApiRef, columnFactories, entityRouteParams, entityRouteRef, getEntityRelations, getEntitySourceLocation, humanizeEntityRef, starredEntitiesApiRef, useAsyncEntity, useEntity, useEntityList, useEntityOwnership, useEntityTypeFilter, useRelatedEntities, useStarredEntities, useStarredEntity };
|
|
891
|
+
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, 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 };
|