@backstage/plugin-catalog-react 1.16.0-next.0 → 1.16.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -5
- package/dist/alpha/blueprints/EntityCardBlueprint.esm.js +4 -8
- package/dist/alpha/blueprints/EntityCardBlueprint.esm.js.map +1 -1
- package/dist/alpha/blueprints/EntityContentBlueprint.esm.js +4 -8
- package/dist/alpha/blueprints/EntityContentBlueprint.esm.js.map +1 -1
- package/dist/alpha/blueprints/EntityContentLayoutBlueprint.esm.js +4 -8
- package/dist/alpha/blueprints/EntityContentLayoutBlueprint.esm.js.map +1 -1
- package/dist/alpha/blueprints/EntityHeaderBlueprint.esm.js +21 -0
- package/dist/alpha/blueprints/EntityHeaderBlueprint.esm.js.map +1 -0
- package/dist/alpha/blueprints/extensionData.esm.js +2 -2
- package/dist/alpha/blueprints/extensionData.esm.js.map +1 -1
- package/dist/alpha/blueprints/resolveEntityFilterData.esm.js +27 -0
- package/dist/alpha/blueprints/resolveEntityFilterData.esm.js.map +1 -0
- package/dist/alpha/converters/convertLegacyEntityCardExtension.esm.js +1 -0
- package/dist/alpha/converters/convertLegacyEntityCardExtension.esm.js.map +1 -1
- package/dist/alpha/converters/convertLegacyEntityContentExtension.esm.js +1 -0
- package/dist/alpha/converters/convertLegacyEntityContentExtension.esm.js.map +1 -1
- package/dist/alpha/predicates/createEntityPredicateSchema.esm.js +27 -0
- package/dist/alpha/predicates/createEntityPredicateSchema.esm.js.map +1 -0
- package/dist/alpha/predicates/entityPredicateToFilterFunction.esm.js +73 -0
- package/dist/alpha/predicates/entityPredicateToFilterFunction.esm.js.map +1 -0
- package/dist/alpha/predicates/valueAtPath.esm.js +31 -0
- package/dist/alpha/predicates/valueAtPath.esm.js.map +1 -0
- package/dist/alpha.d.ts +74 -26
- package/dist/alpha.esm.js +2 -0
- package/dist/alpha.esm.js.map +1 -1
- package/dist/components/CatalogAutocomplete/CatalogAutocomplete.esm.js.map +1 -1
- package/dist/components/EntityAutocompletePicker/EntityAutocompletePicker.esm.js +10 -1
- package/dist/components/EntityAutocompletePicker/EntityAutocompletePicker.esm.js.map +1 -1
- package/dist/index.d.ts +42 -26
- package/dist/index.esm.js +1 -0
- package/dist/index.esm.js.map +1 -1
- package/package.json +13 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-react
|
|
2
2
|
|
|
3
|
+
## 1.16.0-next.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 7f57365: Add support for a new entity predicate syntax when defining `filter`s related to the blueprints exported via `/alpha` for the new frontend system. For more information, see the [entity filters documentation](https://backstage.io/docs/features/software-catalog/catalog-customization#advanced-customization#entity-filters).
|
|
8
|
+
- 247a40b: Introduces a new `EntityHeaderBlueprint` that allows you to override the default entity page header.
|
|
9
|
+
|
|
10
|
+
```jsx
|
|
11
|
+
import { EntityHeaderBlueprint } from '@backstage/plugin-catalog-react/alpha';
|
|
12
|
+
|
|
13
|
+
EntityHeaderBlueprint.make({
|
|
14
|
+
name: 'my-default-header',
|
|
15
|
+
params: {
|
|
16
|
+
loader: () =>
|
|
17
|
+
import('./MyDefaultHeader').then(m => <m.MyDefaultHeader />),
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Updated dependencies
|
|
25
|
+
- @backstage/frontend-plugin-api@0.10.0-next.2
|
|
26
|
+
- @backstage/frontend-test-utils@0.3.0-next.2
|
|
27
|
+
- @backstage/core-compat-api@0.4.0-next.2
|
|
28
|
+
- @backstage/core-components@0.16.5-next.1
|
|
29
|
+
- @backstage/catalog-client@1.9.1
|
|
30
|
+
- @backstage/catalog-model@1.7.3
|
|
31
|
+
- @backstage/core-plugin-api@1.10.4
|
|
32
|
+
- @backstage/errors@1.2.7
|
|
33
|
+
- @backstage/integration-react@1.2.5-next.0
|
|
34
|
+
- @backstage/types@1.2.1
|
|
35
|
+
- @backstage/version-bridge@1.0.11
|
|
36
|
+
- @backstage/plugin-catalog-common@1.1.3
|
|
37
|
+
- @backstage/plugin-permission-common@0.8.4
|
|
38
|
+
- @backstage/plugin-permission-react@0.4.31
|
|
39
|
+
|
|
40
|
+
## 1.16.0-next.1
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- bec1e15: update EntityAutocompletePicker selected options when filter value is changed externally
|
|
45
|
+
- 75a3551: Export CatalogAutocomplete so it can be used externally
|
|
46
|
+
- Updated dependencies
|
|
47
|
+
- @backstage/core-components@0.16.5-next.0
|
|
48
|
+
- @backstage/core-compat-api@0.3.7-next.1
|
|
49
|
+
- @backstage/catalog-client@1.9.1
|
|
50
|
+
- @backstage/catalog-model@1.7.3
|
|
51
|
+
- @backstage/core-plugin-api@1.10.4
|
|
52
|
+
- @backstage/errors@1.2.7
|
|
53
|
+
- @backstage/frontend-plugin-api@0.9.6-next.1
|
|
54
|
+
- @backstage/frontend-test-utils@0.2.7-next.1
|
|
55
|
+
- @backstage/integration-react@1.2.4
|
|
56
|
+
- @backstage/types@1.2.1
|
|
57
|
+
- @backstage/version-bridge@1.0.11
|
|
58
|
+
- @backstage/plugin-catalog-common@1.1.3
|
|
59
|
+
- @backstage/plugin-permission-common@0.8.4
|
|
60
|
+
- @backstage/plugin-permission-react@0.4.31
|
|
61
|
+
|
|
3
62
|
## 1.16.0-next.0
|
|
4
63
|
|
|
5
64
|
### Minor Changes
|
|
@@ -56,7 +115,7 @@
|
|
|
56
115
|
The layout components receive card elements and can render them as they see fit. Cards is an array of objects with the following properties:
|
|
57
116
|
|
|
58
117
|
- element: `JSx.Element`;
|
|
59
|
-
- type: `"
|
|
118
|
+
- type: `"summary" | "info" | "content" | undefined`;
|
|
60
119
|
|
|
61
120
|
### Usage example
|
|
62
121
|
|
|
@@ -93,14 +152,14 @@
|
|
|
93
152
|
<Grid xs={12} md={8} item>
|
|
94
153
|
<Grid container spacing={3}>
|
|
95
154
|
{cards
|
|
96
|
-
.filter(card => card.type === '
|
|
155
|
+
.filter(card => card.type === 'summary')
|
|
97
156
|
.map((card, index) => (
|
|
98
157
|
<Grid key={index} className={classes.card} xs={12} md={6} item>
|
|
99
158
|
{card.element}
|
|
100
159
|
</Grid>
|
|
101
160
|
))}
|
|
102
161
|
{cards
|
|
103
|
-
.filter(card => !card.type || card.type === '
|
|
162
|
+
.filter(card => !card.type || card.type === 'content')
|
|
104
163
|
.map((card, index) => (
|
|
105
164
|
<Grid key={index} className={classes.card} xs={12} md={6} item>
|
|
106
165
|
{card.element}
|
|
@@ -154,9 +213,9 @@
|
|
|
154
213
|
|
|
155
214
|
Initially the following three types are supported:
|
|
156
215
|
|
|
157
|
-
- `
|
|
216
|
+
- `summary`: small vertical cards that provide information at a glance, for example recent builds, deployments, and service health.
|
|
158
217
|
- `info`: medium size cards with high priority and frequently used information such as common actions, entity metadata, and links.
|
|
159
|
-
- `
|
|
218
|
+
- `content`: Large cards that are more feature rich with more information, typically used by plugins that don't quite need the content content view and want to show a card instead.
|
|
160
219
|
|
|
161
220
|
### Usage examples
|
|
162
221
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createExtensionBlueprint, coreExtensionData, ExtensionBoundary } from '@backstage/frontend-plugin-api';
|
|
2
2
|
import { entityFilterFunctionDataRef, entityFilterExpressionDataRef, entityCardTypeDataRef, entityCardTypes } from './extensionData.esm.js';
|
|
3
|
+
import { createEntityPredicateSchema } from '../predicates/createEntityPredicateSchema.esm.js';
|
|
4
|
+
import { resolveEntityFilterData } from './resolveEntityFilterData.esm.js';
|
|
3
5
|
|
|
4
6
|
const EntityCardBlueprint = createExtensionBlueprint({
|
|
5
7
|
kind: "entity-card",
|
|
@@ -17,7 +19,7 @@ const EntityCardBlueprint = createExtensionBlueprint({
|
|
|
17
19
|
},
|
|
18
20
|
config: {
|
|
19
21
|
schema: {
|
|
20
|
-
filter: (z) => z.string().optional(),
|
|
22
|
+
filter: (z) => z.union([z.string(), createEntityPredicateSchema(z)]).optional(),
|
|
21
23
|
type: (z) => z.enum(entityCardTypes).optional()
|
|
22
24
|
}
|
|
23
25
|
},
|
|
@@ -27,13 +29,7 @@ const EntityCardBlueprint = createExtensionBlueprint({
|
|
|
27
29
|
type
|
|
28
30
|
}, { node, config }) {
|
|
29
31
|
yield coreExtensionData.reactElement(ExtensionBoundary.lazy(node, loader));
|
|
30
|
-
|
|
31
|
-
yield entityFilterExpressionDataRef(config.filter);
|
|
32
|
-
} else if (typeof filter === "string") {
|
|
33
|
-
yield entityFilterExpressionDataRef(filter);
|
|
34
|
-
} else if (typeof filter === "function") {
|
|
35
|
-
yield entityFilterFunctionDataRef(filter);
|
|
36
|
-
}
|
|
32
|
+
yield* resolveEntityFilterData(filter, config, node);
|
|
37
33
|
const finalType = config.type ?? type;
|
|
38
34
|
if (finalType) {
|
|
39
35
|
yield entityCardTypeDataRef(finalType);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityCardBlueprint.esm.js","sources":["../../../src/alpha/blueprints/EntityCardBlueprint.ts"],"sourcesContent":["/*\n * Copyright 2024 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 ExtensionBoundary,\n coreExtensionData,\n createExtensionBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport {\n entityFilterFunctionDataRef,\n entityFilterExpressionDataRef,\n entityCardTypeDataRef,\n entityCardTypes,\n EntityCardType,\n} from './extensionData';\n\n/**\n * @alpha\n * A blueprint for creating cards for the entity pages in the catalog.\n */\nexport const EntityCardBlueprint = createExtensionBlueprint({\n kind: 'entity-card',\n attachTo: { id: 'entity-content:catalog/overview', input: 'cards' },\n output: [\n coreExtensionData.reactElement,\n entityFilterFunctionDataRef.optional(),\n entityFilterExpressionDataRef.optional(),\n entityCardTypeDataRef.optional(),\n ],\n dataRefs: {\n filterFunction: entityFilterFunctionDataRef,\n filterExpression: entityFilterExpressionDataRef,\n type: entityCardTypeDataRef,\n },\n config: {\n schema: {\n filter: z
|
|
1
|
+
{"version":3,"file":"EntityCardBlueprint.esm.js","sources":["../../../src/alpha/blueprints/EntityCardBlueprint.ts"],"sourcesContent":["/*\n * Copyright 2024 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 ExtensionBoundary,\n coreExtensionData,\n createExtensionBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport {\n entityFilterFunctionDataRef,\n entityFilterExpressionDataRef,\n entityCardTypeDataRef,\n entityCardTypes,\n EntityCardType,\n} from './extensionData';\nimport { createEntityPredicateSchema } from '../predicates/createEntityPredicateSchema';\nimport { EntityPredicate } from '../predicates';\nimport { resolveEntityFilterData } from './resolveEntityFilterData';\nimport { Entity } from '@backstage/catalog-model';\n\n/**\n * @alpha\n * A blueprint for creating cards for the entity pages in the catalog.\n */\nexport const EntityCardBlueprint = createExtensionBlueprint({\n kind: 'entity-card',\n attachTo: { id: 'entity-content:catalog/overview', input: 'cards' },\n output: [\n coreExtensionData.reactElement,\n entityFilterFunctionDataRef.optional(),\n entityFilterExpressionDataRef.optional(),\n entityCardTypeDataRef.optional(),\n ],\n dataRefs: {\n filterFunction: entityFilterFunctionDataRef,\n filterExpression: entityFilterExpressionDataRef,\n type: entityCardTypeDataRef,\n },\n config: {\n schema: {\n filter: z =>\n z.union([z.string(), createEntityPredicateSchema(z)]).optional(),\n type: z => z.enum(entityCardTypes).optional(),\n },\n },\n *factory(\n {\n loader,\n filter,\n type,\n }: {\n loader: () => Promise<JSX.Element>;\n filter?: string | EntityPredicate | ((entity: Entity) => boolean);\n type?: EntityCardType;\n },\n { node, config },\n ) {\n yield coreExtensionData.reactElement(ExtensionBoundary.lazy(node, loader));\n\n yield* resolveEntityFilterData(filter, config, node);\n\n const finalType = config.type ?? type;\n if (finalType) {\n yield entityCardTypeDataRef(finalType);\n } else {\n // eslint-disable-next-line no-console\n console.warn(\n `DEPRECATION WARNING: Not providing type for entity cards is deprecated. Missing from '${node.spec.id}'`,\n );\n }\n },\n});\n"],"names":[],"mappings":";;;;;AAqCO,MAAM,sBAAsB,wBAAyB,CAAA;AAAA,EAC1D,IAAM,EAAA,aAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,iCAAA,EAAmC,OAAO,OAAQ,EAAA;AAAA,EAClE,MAAQ,EAAA;AAAA,IACN,iBAAkB,CAAA,YAAA;AAAA,IAClB,4BAA4B,QAAS,EAAA;AAAA,IACrC,8BAA8B,QAAS,EAAA;AAAA,IACvC,sBAAsB,QAAS;AAAA,GACjC;AAAA,EACA,QAAU,EAAA;AAAA,IACR,cAAgB,EAAA,2BAAA;AAAA,IAChB,gBAAkB,EAAA,6BAAA;AAAA,IAClB,IAAM,EAAA;AAAA,GACR;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA;AAAA,MACN,MAAQ,EAAA,CAAA,CAAA,KACN,CAAE,CAAA,KAAA,CAAM,CAAC,CAAA,CAAE,MAAO,EAAA,EAAG,2BAA4B,CAAA,CAAC,CAAC,CAAC,EAAE,QAAS,EAAA;AAAA,MACjE,MAAM,CAAK,CAAA,KAAA,CAAA,CAAE,IAAK,CAAA,eAAe,EAAE,QAAS;AAAA;AAC9C,GACF;AAAA,EACA,CAAC,OACC,CAAA;AAAA,IACE,MAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GAMF,EAAA,EAAE,IAAM,EAAA,MAAA,EACR,EAAA;AACA,IAAA,MAAM,kBAAkB,YAAa,CAAA,iBAAA,CAAkB,IAAK,CAAA,IAAA,EAAM,MAAM,CAAC,CAAA;AAEzE,IAAO,OAAA,uBAAA,CAAwB,MAAQ,EAAA,MAAA,EAAQ,IAAI,CAAA;AAEnD,IAAM,MAAA,SAAA,GAAY,OAAO,IAAQ,IAAA,IAAA;AACjC,IAAA,IAAI,SAAW,EAAA;AACb,MAAA,MAAM,sBAAsB,SAAS,CAAA;AAAA,KAChC,MAAA;AAEL,MAAQ,OAAA,CAAA,IAAA;AAAA,QACN,CAAA,sFAAA,EAAyF,IAAK,CAAA,IAAA,CAAK,EAAE,CAAA,CAAA;AAAA,OACvG;AAAA;AACF;AAEJ,CAAC;;;;"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createExtensionBlueprint, coreExtensionData, ExtensionBoundary } from '@backstage/frontend-plugin-api';
|
|
2
2
|
import { entityContentTitleDataRef, entityFilterFunctionDataRef, entityFilterExpressionDataRef, entityContentGroupDataRef } from './extensionData.esm.js';
|
|
3
|
+
import { resolveEntityFilterData } from './resolveEntityFilterData.esm.js';
|
|
4
|
+
import { createEntityPredicateSchema } from '../predicates/createEntityPredicateSchema.esm.js';
|
|
3
5
|
|
|
4
6
|
const EntityContentBlueprint = createExtensionBlueprint({
|
|
5
7
|
kind: "entity-content",
|
|
@@ -23,7 +25,7 @@ const EntityContentBlueprint = createExtensionBlueprint({
|
|
|
23
25
|
schema: {
|
|
24
26
|
path: (z) => z.string().optional(),
|
|
25
27
|
title: (z) => z.string().optional(),
|
|
26
|
-
filter: (z) => z.string().optional(),
|
|
28
|
+
filter: (z) => z.union([z.string(), createEntityPredicateSchema(z)]).optional(),
|
|
27
29
|
group: (z) => z.literal(false).or(z.string()).optional()
|
|
28
30
|
}
|
|
29
31
|
},
|
|
@@ -44,13 +46,7 @@ const EntityContentBlueprint = createExtensionBlueprint({
|
|
|
44
46
|
if (routeRef) {
|
|
45
47
|
yield coreExtensionData.routeRef(routeRef);
|
|
46
48
|
}
|
|
47
|
-
|
|
48
|
-
yield entityFilterExpressionDataRef(config.filter);
|
|
49
|
-
} else if (typeof filter === "string") {
|
|
50
|
-
yield entityFilterExpressionDataRef(filter);
|
|
51
|
-
} else if (typeof filter === "function") {
|
|
52
|
-
yield entityFilterFunctionDataRef(filter);
|
|
53
|
-
}
|
|
49
|
+
yield* resolveEntityFilterData(filter, config, node);
|
|
54
50
|
if (group) {
|
|
55
51
|
yield entityContentGroupDataRef(group);
|
|
56
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityContentBlueprint.esm.js","sources":["../../../src/alpha/blueprints/EntityContentBlueprint.ts"],"sourcesContent":["/*\n * Copyright 2024 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 coreExtensionData,\n createExtensionBlueprint,\n ExtensionBoundary,\n RouteRef,\n} from '@backstage/frontend-plugin-api';\nimport {\n entityContentTitleDataRef,\n entityFilterFunctionDataRef,\n entityFilterExpressionDataRef,\n entityContentGroupDataRef,\n defaultEntityContentGroups,\n} from './extensionData';\n\n/**\n * @alpha\n * Creates an EntityContent extension.\n */\nexport const EntityContentBlueprint = createExtensionBlueprint({\n kind: 'entity-content',\n attachTo: { id: 'page:catalog/entity', input: 'contents' },\n output: [\n coreExtensionData.reactElement,\n coreExtensionData.routePath,\n entityContentTitleDataRef,\n coreExtensionData.routeRef.optional(),\n entityFilterFunctionDataRef.optional(),\n entityFilterExpressionDataRef.optional(),\n entityContentGroupDataRef.optional(),\n ],\n dataRefs: {\n title: entityContentTitleDataRef,\n filterFunction: entityFilterFunctionDataRef,\n filterExpression: entityFilterExpressionDataRef,\n group: entityContentGroupDataRef,\n },\n config: {\n schema: {\n path: z => z.string().optional(),\n title: z => z.string().optional(),\n filter: z
|
|
1
|
+
{"version":3,"file":"EntityContentBlueprint.esm.js","sources":["../../../src/alpha/blueprints/EntityContentBlueprint.ts"],"sourcesContent":["/*\n * Copyright 2024 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 coreExtensionData,\n createExtensionBlueprint,\n ExtensionBoundary,\n RouteRef,\n} from '@backstage/frontend-plugin-api';\nimport {\n entityContentTitleDataRef,\n entityFilterFunctionDataRef,\n entityFilterExpressionDataRef,\n entityContentGroupDataRef,\n defaultEntityContentGroups,\n} from './extensionData';\nimport { EntityPredicate } from '../predicates';\nimport { resolveEntityFilterData } from './resolveEntityFilterData';\nimport { createEntityPredicateSchema } from '../predicates/createEntityPredicateSchema';\nimport { Entity } from '@backstage/catalog-model';\n\n/**\n * @alpha\n * Creates an EntityContent extension.\n */\nexport const EntityContentBlueprint = createExtensionBlueprint({\n kind: 'entity-content',\n attachTo: { id: 'page:catalog/entity', input: 'contents' },\n output: [\n coreExtensionData.reactElement,\n coreExtensionData.routePath,\n entityContentTitleDataRef,\n coreExtensionData.routeRef.optional(),\n entityFilterFunctionDataRef.optional(),\n entityFilterExpressionDataRef.optional(),\n entityContentGroupDataRef.optional(),\n ],\n dataRefs: {\n title: entityContentTitleDataRef,\n filterFunction: entityFilterFunctionDataRef,\n filterExpression: entityFilterExpressionDataRef,\n group: entityContentGroupDataRef,\n },\n config: {\n schema: {\n path: z => z.string().optional(),\n title: z => z.string().optional(),\n filter: z =>\n z.union([z.string(), createEntityPredicateSchema(z)]).optional(),\n group: z => z.literal(false).or(z.string()).optional(),\n },\n },\n *factory(\n {\n loader,\n defaultPath,\n defaultTitle,\n defaultGroup,\n filter,\n routeRef,\n }: {\n loader: () => Promise<JSX.Element>;\n defaultPath: string;\n defaultTitle: string;\n defaultGroup?: keyof typeof defaultEntityContentGroups | (string & {});\n routeRef?: RouteRef;\n filter?: string | EntityPredicate | ((entity: Entity) => boolean);\n },\n { node, config },\n ) {\n const path = config.path ?? defaultPath;\n const title = config.title ?? defaultTitle;\n const group = config.group ?? defaultGroup;\n\n yield coreExtensionData.reactElement(ExtensionBoundary.lazy(node, loader));\n\n yield coreExtensionData.routePath(path);\n\n yield entityContentTitleDataRef(title);\n\n if (routeRef) {\n yield coreExtensionData.routeRef(routeRef);\n }\n\n yield* resolveEntityFilterData(filter, config, node);\n\n if (group) {\n yield entityContentGroupDataRef(group);\n }\n },\n});\n"],"names":[],"mappings":";;;;;AAsCO,MAAM,yBAAyB,wBAAyB,CAAA;AAAA,EAC7D,IAAM,EAAA,gBAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,qBAAA,EAAuB,OAAO,UAAW,EAAA;AAAA,EACzD,MAAQ,EAAA;AAAA,IACN,iBAAkB,CAAA,YAAA;AAAA,IAClB,iBAAkB,CAAA,SAAA;AAAA,IAClB,yBAAA;AAAA,IACA,iBAAA,CAAkB,SAAS,QAAS,EAAA;AAAA,IACpC,4BAA4B,QAAS,EAAA;AAAA,IACrC,8BAA8B,QAAS,EAAA;AAAA,IACvC,0BAA0B,QAAS;AAAA,GACrC;AAAA,EACA,QAAU,EAAA;AAAA,IACR,KAAO,EAAA,yBAAA;AAAA,IACP,cAAgB,EAAA,2BAAA;AAAA,IAChB,gBAAkB,EAAA,6BAAA;AAAA,IAClB,KAAO,EAAA;AAAA,GACT;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA;AAAA,MACN,IAAM,EAAA,CAAA,CAAA,KAAK,CAAE,CAAA,MAAA,GAAS,QAAS,EAAA;AAAA,MAC/B,KAAO,EAAA,CAAA,CAAA,KAAK,CAAE,CAAA,MAAA,GAAS,QAAS,EAAA;AAAA,MAChC,MAAQ,EAAA,CAAA,CAAA,KACN,CAAE,CAAA,KAAA,CAAM,CAAC,CAAA,CAAE,MAAO,EAAA,EAAG,2BAA4B,CAAA,CAAC,CAAC,CAAC,EAAE,QAAS,EAAA;AAAA,MACjE,KAAA,EAAO,CAAK,CAAA,KAAA,CAAA,CAAE,OAAQ,CAAA,KAAK,CAAE,CAAA,EAAA,CAAG,CAAE,CAAA,MAAA,EAAQ,CAAA,CAAE,QAAS;AAAA;AACvD,GACF;AAAA,EACA,CAAC,OACC,CAAA;AAAA,IACE,MAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,YAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GASF,EAAA,EAAE,IAAM,EAAA,MAAA,EACR,EAAA;AACA,IAAM,MAAA,IAAA,GAAO,OAAO,IAAQ,IAAA,WAAA;AAC5B,IAAM,MAAA,KAAA,GAAQ,OAAO,KAAS,IAAA,YAAA;AAC9B,IAAM,MAAA,KAAA,GAAQ,OAAO,KAAS,IAAA,YAAA;AAE9B,IAAA,MAAM,kBAAkB,YAAa,CAAA,iBAAA,CAAkB,IAAK,CAAA,IAAA,EAAM,MAAM,CAAC,CAAA;AAEzE,IAAM,MAAA,iBAAA,CAAkB,UAAU,IAAI,CAAA;AAEtC,IAAA,MAAM,0BAA0B,KAAK,CAAA;AAErC,IAAA,IAAI,QAAU,EAAA;AACZ,MAAM,MAAA,iBAAA,CAAkB,SAAS,QAAQ,CAAA;AAAA;AAG3C,IAAO,OAAA,uBAAA,CAAwB,MAAQ,EAAA,MAAA,EAAQ,IAAI,CAAA;AAEnD,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,MAAM,0BAA0B,KAAK,CAAA;AAAA;AACvC;AAEJ,CAAC;;;;"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createExtensionDataRef, createExtensionBlueprint, ExtensionBoundary } from '@backstage/frontend-plugin-api';
|
|
2
2
|
import { entityFilterFunctionDataRef, entityFilterExpressionDataRef } from './extensionData.esm.js';
|
|
3
|
+
import { resolveEntityFilterData } from './resolveEntityFilterData.esm.js';
|
|
4
|
+
import { createEntityPredicateSchema } from '../predicates/createEntityPredicateSchema.esm.js';
|
|
3
5
|
|
|
4
6
|
const entityCardLayoutComponentDataRef = createExtensionDataRef().with({
|
|
5
7
|
id: "catalog.entity-content-layout.component"
|
|
@@ -20,20 +22,14 @@ const EntityContentLayoutBlueprint = createExtensionBlueprint({
|
|
|
20
22
|
config: {
|
|
21
23
|
schema: {
|
|
22
24
|
type: (z) => z.string().optional(),
|
|
23
|
-
filter: (z) => z.string().optional()
|
|
25
|
+
filter: (z) => z.union([z.string(), createEntityPredicateSchema(z)]).optional()
|
|
24
26
|
}
|
|
25
27
|
},
|
|
26
28
|
*factory({
|
|
27
29
|
loader,
|
|
28
30
|
filter
|
|
29
31
|
}, { node, config }) {
|
|
30
|
-
|
|
31
|
-
yield entityFilterExpressionDataRef(config.filter);
|
|
32
|
-
} else if (typeof filter === "string") {
|
|
33
|
-
yield entityFilterExpressionDataRef(filter);
|
|
34
|
-
} else if (typeof filter === "function") {
|
|
35
|
-
yield entityFilterFunctionDataRef(filter);
|
|
36
|
-
}
|
|
32
|
+
yield* resolveEntityFilterData(filter, config, node);
|
|
37
33
|
yield entityCardLayoutComponentDataRef(
|
|
38
34
|
ExtensionBoundary.lazyComponent(node, loader)
|
|
39
35
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityContentLayoutBlueprint.esm.js","sources":["../../../src/alpha/blueprints/EntityContentLayoutBlueprint.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 createExtensionDataRef,\n createExtensionBlueprint,\n ExtensionBoundary,\n} from '@backstage/frontend-plugin-api';\nimport {\n entityFilterExpressionDataRef,\n entityFilterFunctionDataRef,\n EntityCardType,\n} from './extensionData';\nimport React from 'react';\n\n/** @alpha */\nexport interface EntityContentLayoutProps {\n cards: Array<{\n type?: EntityCardType;\n element: React.JSX.Element;\n }>;\n}\n\nconst entityCardLayoutComponentDataRef = createExtensionDataRef<\n (props: EntityContentLayoutProps) => React.JSX.Element\n>().with({\n id: 'catalog.entity-content-layout.component',\n});\n\n/** @alpha */\nexport const EntityContentLayoutBlueprint = createExtensionBlueprint({\n kind: 'entity-content-layout',\n attachTo: { id: 'entity-content:catalog/overview', input: 'layouts' },\n output: [\n entityFilterFunctionDataRef.optional(),\n entityFilterExpressionDataRef.optional(),\n entityCardLayoutComponentDataRef,\n ],\n dataRefs: {\n filterFunction: entityFilterFunctionDataRef,\n filterExpression: entityFilterExpressionDataRef,\n component: entityCardLayoutComponentDataRef,\n },\n config: {\n schema: {\n type: z => z.string().optional(),\n filter: z
|
|
1
|
+
{"version":3,"file":"EntityContentLayoutBlueprint.esm.js","sources":["../../../src/alpha/blueprints/EntityContentLayoutBlueprint.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 createExtensionDataRef,\n createExtensionBlueprint,\n ExtensionBoundary,\n} from '@backstage/frontend-plugin-api';\nimport {\n entityFilterExpressionDataRef,\n entityFilterFunctionDataRef,\n EntityCardType,\n} from './extensionData';\nimport React from 'react';\nimport { EntityPredicate } from '../predicates';\nimport { resolveEntityFilterData } from './resolveEntityFilterData';\nimport { createEntityPredicateSchema } from '../predicates/createEntityPredicateSchema';\nimport { Entity } from '@backstage/catalog-model';\n\n/** @alpha */\nexport interface EntityContentLayoutProps {\n cards: Array<{\n type?: EntityCardType;\n element: React.JSX.Element;\n }>;\n}\n\nconst entityCardLayoutComponentDataRef = createExtensionDataRef<\n (props: EntityContentLayoutProps) => React.JSX.Element\n>().with({\n id: 'catalog.entity-content-layout.component',\n});\n\n/** @alpha */\nexport const EntityContentLayoutBlueprint = createExtensionBlueprint({\n kind: 'entity-content-layout',\n attachTo: { id: 'entity-content:catalog/overview', input: 'layouts' },\n output: [\n entityFilterFunctionDataRef.optional(),\n entityFilterExpressionDataRef.optional(),\n entityCardLayoutComponentDataRef,\n ],\n dataRefs: {\n filterFunction: entityFilterFunctionDataRef,\n filterExpression: entityFilterExpressionDataRef,\n component: entityCardLayoutComponentDataRef,\n },\n config: {\n schema: {\n type: z => z.string().optional(),\n filter: z =>\n z.union([z.string(), createEntityPredicateSchema(z)]).optional(),\n },\n },\n *factory(\n {\n loader,\n filter,\n }: {\n filter?: string | EntityPredicate | ((entity: Entity) => boolean);\n loader: () => Promise<\n (props: EntityContentLayoutProps) => React.JSX.Element\n >;\n },\n { node, config },\n ) {\n yield* resolveEntityFilterData(filter, config, node);\n\n yield entityCardLayoutComponentDataRef(\n ExtensionBoundary.lazyComponent(node, loader),\n );\n },\n});\n"],"names":[],"mappings":";;;;;AAwCA,MAAM,gCAAA,GAAmC,sBAEvC,EAAA,CAAE,IAAK,CAAA;AAAA,EACP,EAAI,EAAA;AACN,CAAC,CAAA;AAGM,MAAM,+BAA+B,wBAAyB,CAAA;AAAA,EACnE,IAAM,EAAA,uBAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,iCAAA,EAAmC,OAAO,SAAU,EAAA;AAAA,EACpE,MAAQ,EAAA;AAAA,IACN,4BAA4B,QAAS,EAAA;AAAA,IACrC,8BAA8B,QAAS,EAAA;AAAA,IACvC;AAAA,GACF;AAAA,EACA,QAAU,EAAA;AAAA,IACR,cAAgB,EAAA,2BAAA;AAAA,IAChB,gBAAkB,EAAA,6BAAA;AAAA,IAClB,SAAW,EAAA;AAAA,GACb;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA;AAAA,MACN,IAAM,EAAA,CAAA,CAAA,KAAK,CAAE,CAAA,MAAA,GAAS,QAAS,EAAA;AAAA,MAC/B,MAAQ,EAAA,CAAA,CAAA,KACN,CAAE,CAAA,KAAA,CAAM,CAAC,CAAA,CAAE,MAAO,EAAA,EAAG,2BAA4B,CAAA,CAAC,CAAC,CAAC,EAAE,QAAS;AAAA;AACnE,GACF;AAAA,EACA,CAAC,OACC,CAAA;AAAA,IACE,MAAA;AAAA,IACA;AAAA,GAOF,EAAA,EAAE,IAAM,EAAA,MAAA,EACR,EAAA;AACA,IAAO,OAAA,uBAAA,CAAwB,MAAQ,EAAA,MAAA,EAAQ,IAAI,CAAA;AAEnD,IAAM,MAAA,gCAAA;AAAA,MACJ,iBAAA,CAAkB,aAAc,CAAA,IAAA,EAAM,MAAM;AAAA,KAC9C;AAAA;AAEJ,CAAC;;;;"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createExtensionBlueprint, coreExtensionData, ExtensionBoundary } from '@backstage/frontend-plugin-api';
|
|
2
|
+
|
|
3
|
+
const EntityHeaderBlueprint = createExtensionBlueprint({
|
|
4
|
+
kind: "entity-header",
|
|
5
|
+
attachTo: { id: "page:catalog/entity", input: "header" },
|
|
6
|
+
dataRefs: {
|
|
7
|
+
element: coreExtensionData.reactElement
|
|
8
|
+
},
|
|
9
|
+
output: [coreExtensionData.reactElement.optional()],
|
|
10
|
+
*factory(params, { node }) {
|
|
11
|
+
const { loader } = params;
|
|
12
|
+
if (loader) {
|
|
13
|
+
yield coreExtensionData.reactElement(
|
|
14
|
+
ExtensionBoundary.lazy(node, loader)
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export { EntityHeaderBlueprint };
|
|
21
|
+
//# sourceMappingURL=EntityHeaderBlueprint.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntityHeaderBlueprint.esm.js","sources":["../../../src/alpha/blueprints/EntityHeaderBlueprint.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 createExtensionBlueprint,\n coreExtensionData,\n ExtensionBoundary,\n} from '@backstage/frontend-plugin-api';\n\n/** @alpha */\nexport const EntityHeaderBlueprint = createExtensionBlueprint({\n kind: 'entity-header',\n attachTo: { id: 'page:catalog/entity', input: 'header' },\n dataRefs: {\n element: coreExtensionData.reactElement,\n },\n output: [coreExtensionData.reactElement.optional()],\n *factory(\n params: {\n loader: () => Promise<JSX.Element>;\n },\n { node },\n ) {\n const { loader } = params;\n if (loader) {\n yield coreExtensionData.reactElement(\n ExtensionBoundary.lazy(node, loader),\n );\n }\n },\n});\n"],"names":[],"mappings":";;AAuBO,MAAM,wBAAwB,wBAAyB,CAAA;AAAA,EAC5D,IAAM,EAAA,eAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,qBAAA,EAAuB,OAAO,QAAS,EAAA;AAAA,EACvD,QAAU,EAAA;AAAA,IACR,SAAS,iBAAkB,CAAA;AAAA,GAC7B;AAAA,EACA,MAAQ,EAAA,CAAC,iBAAkB,CAAA,YAAA,CAAa,UAAU,CAAA;AAAA,EAClD,CAAC,OAAA,CACC,MAGA,EAAA,EAAE,MACF,EAAA;AACA,IAAM,MAAA,EAAE,QAAW,GAAA,MAAA;AACnB,IAAA,IAAI,MAAQ,EAAA;AACV,MAAA,MAAM,iBAAkB,CAAA,YAAA;AAAA,QACtB,iBAAA,CAAkB,IAAK,CAAA,IAAA,EAAM,MAAM;AAAA,OACrC;AAAA;AACF;AAEJ,CAAC;;;;"}
|
|
@@ -17,9 +17,9 @@ const entityContentGroupDataRef = createExtensionDataRef().with({
|
|
|
17
17
|
id: "catalog.entity-content-group"
|
|
18
18
|
});
|
|
19
19
|
const entityCardTypes = [
|
|
20
|
-
"
|
|
20
|
+
"summary",
|
|
21
21
|
"info",
|
|
22
|
-
"
|
|
22
|
+
"content"
|
|
23
23
|
];
|
|
24
24
|
const entityCardTypeDataRef = createExtensionDataRef().with({
|
|
25
25
|
id: "catalog.entity-card-type"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensionData.esm.js","sources":["../../../src/alpha/blueprints/extensionData.tsx"],"sourcesContent":["/*\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 { Entity } from '@backstage/catalog-model';\nimport { createExtensionDataRef } from '@backstage/frontend-plugin-api';\n\n/** @internal */\nexport const entityContentTitleDataRef = createExtensionDataRef<string>().with({\n id: 'catalog.entity-content-title',\n});\n\n/** @internal */\nexport const entityFilterFunctionDataRef = createExtensionDataRef<\n (entity: Entity) => boolean\n>().with({ id: 'catalog.entity-filter-function' });\n\n/** @internal */\nexport const entityFilterExpressionDataRef =\n createExtensionDataRef<string>().with({\n id: 'catalog.entity-filter-expression',\n });\n\n/**\n * @alpha\n * Default entity content groups.\n */\nexport const defaultEntityContentGroups = {\n documentation: 'Documentation',\n development: 'Development',\n deployment: 'Deployment',\n observability: 'Observability',\n};\n\n/** @internal */\nexport const entityContentGroupDataRef = createExtensionDataRef<string>().with({\n id: 'catalog.entity-content-group',\n});\n\n/**\n * @internal\n * Available entity card types\n */\nexport const entityCardTypes = [\n '
|
|
1
|
+
{"version":3,"file":"extensionData.esm.js","sources":["../../../src/alpha/blueprints/extensionData.tsx"],"sourcesContent":["/*\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 { Entity } from '@backstage/catalog-model';\nimport { createExtensionDataRef } from '@backstage/frontend-plugin-api';\n\n/** @internal */\nexport const entityContentTitleDataRef = createExtensionDataRef<string>().with({\n id: 'catalog.entity-content-title',\n});\n\n/** @internal */\nexport const entityFilterFunctionDataRef = createExtensionDataRef<\n (entity: Entity) => boolean\n>().with({ id: 'catalog.entity-filter-function' });\n\n/** @internal */\nexport const entityFilterExpressionDataRef =\n createExtensionDataRef<string>().with({\n id: 'catalog.entity-filter-expression',\n });\n\n/**\n * @alpha\n * Default entity content groups.\n */\nexport const defaultEntityContentGroups = {\n documentation: 'Documentation',\n development: 'Development',\n deployment: 'Deployment',\n observability: 'Observability',\n};\n\n/** @internal */\nexport const entityContentGroupDataRef = createExtensionDataRef<string>().with({\n id: 'catalog.entity-content-group',\n});\n\n/**\n * @internal\n * Available entity card types\n */\nexport const entityCardTypes = [\n 'summary',\n 'info',\n 'content',\n] as const satisfies readonly EntityCardType[];\n\n/** @alpha */\nexport type EntityCardType = 'summary' | 'info' | 'content';\n\n/** @internal */\nexport const entityCardTypeDataRef =\n createExtensionDataRef<EntityCardType>().with({\n id: 'catalog.entity-card-type',\n });\n"],"names":[],"mappings":";;AAoBa,MAAA,yBAAA,GAA4B,sBAA+B,EAAA,CAAE,IAAK,CAAA;AAAA,EAC7E,EAAI,EAAA;AACN,CAAC;AAGM,MAAM,8BAA8B,sBAEzC,EAAA,CAAE,KAAK,EAAE,EAAA,EAAI,kCAAkC;AAGpC,MAAA,6BAAA,GACX,sBAA+B,EAAA,CAAE,IAAK,CAAA;AAAA,EACpC,EAAI,EAAA;AACN,CAAC;AAMI,MAAM,0BAA6B,GAAA;AAAA,EACxC,aAAe,EAAA,eAAA;AAAA,EACf,WAAa,EAAA,aAAA;AAAA,EACb,UAAY,EAAA,YAAA;AAAA,EACZ,aAAe,EAAA;AACjB;AAGa,MAAA,yBAAA,GAA4B,sBAA+B,EAAA,CAAE,IAAK,CAAA;AAAA,EAC7E,EAAI,EAAA;AACN,CAAC;AAMM,MAAM,eAAkB,GAAA;AAAA,EAC7B,SAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF;AAMa,MAAA,qBAAA,GACX,sBAAuC,EAAA,CAAE,IAAK,CAAA;AAAA,EAC5C,EAAI,EAAA;AACN,CAAC;;;;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { entityFilterExpressionDataRef, entityFilterFunctionDataRef } from './extensionData.esm.js';
|
|
2
|
+
import { entityPredicateToFilterFunction } from '../predicates/entityPredicateToFilterFunction.esm.js';
|
|
3
|
+
|
|
4
|
+
function* resolveEntityFilterData(filter, config, node) {
|
|
5
|
+
if (typeof config.filter === "string") {
|
|
6
|
+
console.warn(
|
|
7
|
+
`DEPRECATION WARNING: Using a string-based filter in the configuration for '${node.spec.id}' is deprecated. Use an entity predicate object instead.`
|
|
8
|
+
);
|
|
9
|
+
yield entityFilterExpressionDataRef(config.filter);
|
|
10
|
+
} else if (config.filter) {
|
|
11
|
+
yield entityFilterFunctionDataRef(
|
|
12
|
+
entityPredicateToFilterFunction(config.filter)
|
|
13
|
+
);
|
|
14
|
+
} else if (typeof filter === "function") {
|
|
15
|
+
yield entityFilterFunctionDataRef(filter);
|
|
16
|
+
} else if (typeof filter === "string") {
|
|
17
|
+
console.warn(
|
|
18
|
+
`DEPRECATION WARNING: Using a string as the default filter for '${node.spec.id}' is deprecated. Use an entity predicate object instead.`
|
|
19
|
+
);
|
|
20
|
+
yield entityFilterExpressionDataRef(filter);
|
|
21
|
+
} else if (filter) {
|
|
22
|
+
yield entityFilterFunctionDataRef(entityPredicateToFilterFunction(filter));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { resolveEntityFilterData };
|
|
27
|
+
//# sourceMappingURL=resolveEntityFilterData.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveEntityFilterData.esm.js","sources":["../../../src/alpha/blueprints/resolveEntityFilterData.ts"],"sourcesContent":["/*\n * Copyright 2025 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 entityFilterExpressionDataRef,\n entityFilterFunctionDataRef,\n} from './extensionData';\nimport {\n EntityPredicate,\n entityPredicateToFilterFunction,\n} from '../predicates';\nimport { Entity } from '@backstage/catalog-model';\nimport { AppNode } from '@backstage/frontend-plugin-api';\n\nexport function* resolveEntityFilterData(\n filter: ((entity: Entity) => boolean) | EntityPredicate | string | undefined,\n config: { filter?: EntityPredicate | string },\n node: AppNode,\n) {\n if (typeof config.filter === 'string') {\n // eslint-disable-next-line no-console\n console.warn(\n `DEPRECATION WARNING: Using a string-based filter in the configuration for '${node.spec.id}' is deprecated. Use an entity predicate object instead.`,\n );\n yield entityFilterExpressionDataRef(config.filter);\n } else if (config.filter) {\n yield entityFilterFunctionDataRef(\n entityPredicateToFilterFunction(config.filter),\n );\n } else if (typeof filter === 'function') {\n yield entityFilterFunctionDataRef(filter);\n } else if (typeof filter === 'string') {\n // eslint-disable-next-line no-console\n console.warn(\n `DEPRECATION WARNING: Using a string as the default filter for '${node.spec.id}' is deprecated. Use an entity predicate object instead.`,\n );\n yield entityFilterExpressionDataRef(filter);\n } else if (filter) {\n yield entityFilterFunctionDataRef(entityPredicateToFilterFunction(filter));\n }\n}\n"],"names":[],"mappings":";;;AA2BiB,UAAA,uBAAA,CACf,MACA,EAAA,MAAA,EACA,IACA,EAAA;AACA,EAAI,IAAA,OAAO,MAAO,CAAA,MAAA,KAAW,QAAU,EAAA;AAErC,IAAQ,OAAA,CAAA,IAAA;AAAA,MACN,CAAA,2EAAA,EAA8E,IAAK,CAAA,IAAA,CAAK,EAAE,CAAA,wDAAA;AAAA,KAC5F;AACA,IAAM,MAAA,6BAAA,CAA8B,OAAO,MAAM,CAAA;AAAA,GACnD,MAAA,IAAW,OAAO,MAAQ,EAAA;AACxB,IAAM,MAAA,2BAAA;AAAA,MACJ,+BAAA,CAAgC,OAAO,MAAM;AAAA,KAC/C;AAAA,GACF,MAAA,IAAW,OAAO,MAAA,KAAW,UAAY,EAAA;AACvC,IAAA,MAAM,4BAA4B,MAAM,CAAA;AAAA,GAC1C,MAAA,IAAW,OAAO,MAAA,KAAW,QAAU,EAAA;AAErC,IAAQ,OAAA,CAAA,IAAA;AAAA,MACN,CAAA,+DAAA,EAAkE,IAAK,CAAA,IAAA,CAAK,EAAE,CAAA,wDAAA;AAAA,KAChF;AACA,IAAA,MAAM,8BAA8B,MAAM,CAAA;AAAA,aACjC,MAAQ,EAAA;AACjB,IAAM,MAAA,2BAAA,CAA4B,+BAAgC,CAAA,MAAM,CAAC,CAAA;AAAA;AAE7E;;;;"}
|
|
@@ -4,6 +4,7 @@ import React from 'react';
|
|
|
4
4
|
import { EntityCardBlueprint } from '../blueprints/EntityCardBlueprint.esm.js';
|
|
5
5
|
import '../blueprints/EntityContentBlueprint.esm.js';
|
|
6
6
|
import '../blueprints/EntityContentLayoutBlueprint.esm.js';
|
|
7
|
+
import '../blueprints/EntityHeaderBlueprint.esm.js';
|
|
7
8
|
import '../blueprints/extensionData.esm.js';
|
|
8
9
|
import kebabCase from 'lodash/kebabCase';
|
|
9
10
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertLegacyEntityCardExtension.esm.js","sources":["../../../src/alpha/converters/convertLegacyEntityCardExtension.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 { compatWrapper } from '@backstage/core-compat-api';\nimport { BackstagePlugin, getComponentData } from '@backstage/core-plugin-api';\nimport { ExtensionDefinition } from '@backstage/frontend-plugin-api';\nimport React, { ComponentType } from 'react';\nimport { EntityCardBlueprint } from '../blueprints';\nimport kebabCase from 'lodash/kebabCase';\n\n/** @alpha */\nexport function convertLegacyEntityCardExtension(\n LegacyExtension: ComponentType<{}>,\n overrides?: {\n name?: string;\n filter
|
|
1
|
+
{"version":3,"file":"convertLegacyEntityCardExtension.esm.js","sources":["../../../src/alpha/converters/convertLegacyEntityCardExtension.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 { compatWrapper } from '@backstage/core-compat-api';\nimport { BackstagePlugin, getComponentData } from '@backstage/core-plugin-api';\nimport { ExtensionDefinition } from '@backstage/frontend-plugin-api';\nimport React, { ComponentType } from 'react';\nimport { EntityCardBlueprint } from '../blueprints';\nimport kebabCase from 'lodash/kebabCase';\nimport { EntityPredicate } from '../predicates';\nimport { Entity } from '@backstage/catalog-model';\n\n/** @alpha */\nexport function convertLegacyEntityCardExtension(\n LegacyExtension: ComponentType<{}>,\n overrides?: {\n name?: string;\n filter?: string | EntityPredicate | ((entity: Entity) => boolean);\n },\n): ExtensionDefinition {\n const element = <LegacyExtension />;\n\n const extName = getComponentData<string>(element, 'core.extensionName');\n if (!extName) {\n throw new Error('Extension has no name');\n }\n\n const plugin = getComponentData<BackstagePlugin>(element, 'core.plugin');\n const pluginId = plugin?.getId();\n\n const match = extName.match(/^Entity(.*)Card$/);\n const infix = match?.[1] ?? extName;\n\n let name: string | undefined = infix;\n if (\n pluginId &&\n name\n .toLocaleLowerCase('en-US')\n .startsWith(pluginId.toLocaleLowerCase('en-US'))\n ) {\n name = name.slice(pluginId.length);\n if (!name) {\n name = undefined;\n }\n }\n name = name && kebabCase(name);\n\n return EntityCardBlueprint.make({\n name: overrides?.name ?? name,\n params: {\n filter: overrides?.filter,\n loader: async () => compatWrapper(element),\n },\n });\n}\n"],"names":[],"mappings":";;;;;;;;;;AA0BgB,SAAA,gCAAA,CACd,iBACA,SAIqB,EAAA;AACrB,EAAM,MAAA,OAAA,uCAAW,eAAgB,EAAA,IAAA,CAAA;AAEjC,EAAM,MAAA,OAAA,GAAU,gBAAyB,CAAA,OAAA,EAAS,oBAAoB,CAAA;AACtE,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA;AAAA;AAGzC,EAAM,MAAA,MAAA,GAAS,gBAAkC,CAAA,OAAA,EAAS,aAAa,CAAA;AACvE,EAAM,MAAA,QAAA,GAAW,QAAQ,KAAM,EAAA;AAE/B,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,KAAA,CAAM,kBAAkB,CAAA;AAC9C,EAAM,MAAA,KAAA,GAAQ,KAAQ,GAAA,CAAC,CAAK,IAAA,OAAA;AAE5B,EAAA,IAAI,IAA2B,GAAA,KAAA;AAC/B,EACE,IAAA,QAAA,IACA,IACG,CAAA,iBAAA,CAAkB,OAAO,CAAA,CACzB,WAAW,QAAS,CAAA,iBAAA,CAAkB,OAAO,CAAC,CACjD,EAAA;AACA,IAAO,IAAA,GAAA,IAAA,CAAK,KAAM,CAAA,QAAA,CAAS,MAAM,CAAA;AACjC,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,IAAA,GAAA,KAAA,CAAA;AAAA;AACT;AAEF,EAAO,IAAA,GAAA,IAAA,IAAQ,UAAU,IAAI,CAAA;AAE7B,EAAA,OAAO,oBAAoB,IAAK,CAAA;AAAA,IAC9B,IAAA,EAAM,WAAW,IAAQ,IAAA,IAAA;AAAA,IACzB,MAAQ,EAAA;AAAA,MACN,QAAQ,SAAW,EAAA,MAAA;AAAA,MACnB,MAAA,EAAQ,YAAY,aAAA,CAAc,OAAO;AAAA;AAC3C,GACD,CAAA;AACH;;;;"}
|
|
@@ -6,6 +6,7 @@ import React from 'react';
|
|
|
6
6
|
import '../blueprints/EntityCardBlueprint.esm.js';
|
|
7
7
|
import { EntityContentBlueprint } from '../blueprints/EntityContentBlueprint.esm.js';
|
|
8
8
|
import '../blueprints/EntityContentLayoutBlueprint.esm.js';
|
|
9
|
+
import '../blueprints/EntityHeaderBlueprint.esm.js';
|
|
9
10
|
import '../blueprints/extensionData.esm.js';
|
|
10
11
|
|
|
11
12
|
function convertLegacyEntityContentExtension(LegacyExtension, overrides) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertLegacyEntityContentExtension.esm.js","sources":["../../../src/alpha/converters/convertLegacyEntityContentExtension.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 compatWrapper,\n convertLegacyRouteRef,\n} from '@backstage/core-compat-api';\nimport {\n BackstagePlugin,\n getComponentData,\n RouteRef as LegacyRouteRef,\n} from '@backstage/core-plugin-api';\nimport { ExtensionDefinition } from '@backstage/frontend-plugin-api';\nimport kebabCase from 'lodash/kebabCase';\nimport startCase from 'lodash/startCase';\nimport React, { ComponentType } from 'react';\nimport { EntityContentBlueprint } from '../blueprints';\n\n/** @alpha */\nexport function convertLegacyEntityContentExtension(\n LegacyExtension: ComponentType<{}>,\n overrides?: {\n name?: string;\n filter
|
|
1
|
+
{"version":3,"file":"convertLegacyEntityContentExtension.esm.js","sources":["../../../src/alpha/converters/convertLegacyEntityContentExtension.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 compatWrapper,\n convertLegacyRouteRef,\n} from '@backstage/core-compat-api';\nimport {\n BackstagePlugin,\n getComponentData,\n RouteRef as LegacyRouteRef,\n} from '@backstage/core-plugin-api';\nimport { ExtensionDefinition } from '@backstage/frontend-plugin-api';\nimport kebabCase from 'lodash/kebabCase';\nimport startCase from 'lodash/startCase';\nimport React, { ComponentType } from 'react';\nimport { EntityContentBlueprint } from '../blueprints';\nimport { EntityPredicate } from '../predicates';\nimport { Entity } from '@backstage/catalog-model';\n\n/** @alpha */\nexport function convertLegacyEntityContentExtension(\n LegacyExtension: ComponentType<{}>,\n overrides?: {\n name?: string;\n filter?: string | EntityPredicate | ((entity: Entity) => boolean);\n defaultPath?: string;\n defaultTitle?: string;\n },\n): ExtensionDefinition {\n const element = <LegacyExtension />;\n\n const extName = getComponentData<string>(element, 'core.extensionName');\n if (!extName) {\n throw new Error('Extension has no name');\n }\n\n const mountPoint = getComponentData<LegacyRouteRef>(\n element,\n 'core.mountPoint',\n );\n\n const plugin = getComponentData<BackstagePlugin>(element, 'core.plugin');\n const pluginId = plugin?.getId();\n\n const match = extName.match(/^Entity(.*)Content$/);\n const infix = match?.[1] ?? extName;\n\n let name: string | undefined = infix;\n if (\n pluginId &&\n name\n .toLocaleLowerCase('en-US')\n .startsWith(pluginId.toLocaleLowerCase('en-US'))\n ) {\n name = name.slice(pluginId.length);\n if (!name) {\n name = undefined;\n }\n }\n name = name && kebabCase(name);\n\n return EntityContentBlueprint.make({\n name: overrides?.name ?? name,\n params: {\n filter: overrides?.filter,\n defaultPath: overrides?.defaultPath ?? `/${kebabCase(infix)}`,\n defaultTitle: overrides?.defaultTitle ?? startCase(infix),\n routeRef: mountPoint && convertLegacyRouteRef(mountPoint),\n loader: async () => compatWrapper(element),\n },\n });\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAkCgB,SAAA,mCAAA,CACd,iBACA,SAMqB,EAAA;AACrB,EAAM,MAAA,OAAA,uCAAW,eAAgB,EAAA,IAAA,CAAA;AAEjC,EAAM,MAAA,OAAA,GAAU,gBAAyB,CAAA,OAAA,EAAS,oBAAoB,CAAA;AACtE,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA;AAAA;AAGzC,EAAA,MAAM,UAAa,GAAA,gBAAA;AAAA,IACjB,OAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAM,MAAA,MAAA,GAAS,gBAAkC,CAAA,OAAA,EAAS,aAAa,CAAA;AACvE,EAAM,MAAA,QAAA,GAAW,QAAQ,KAAM,EAAA;AAE/B,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,KAAA,CAAM,qBAAqB,CAAA;AACjD,EAAM,MAAA,KAAA,GAAQ,KAAQ,GAAA,CAAC,CAAK,IAAA,OAAA;AAE5B,EAAA,IAAI,IAA2B,GAAA,KAAA;AAC/B,EACE,IAAA,QAAA,IACA,IACG,CAAA,iBAAA,CAAkB,OAAO,CAAA,CACzB,WAAW,QAAS,CAAA,iBAAA,CAAkB,OAAO,CAAC,CACjD,EAAA;AACA,IAAO,IAAA,GAAA,IAAA,CAAK,KAAM,CAAA,QAAA,CAAS,MAAM,CAAA;AACjC,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,IAAA,GAAA,KAAA,CAAA;AAAA;AACT;AAEF,EAAO,IAAA,GAAA,IAAA,IAAQ,UAAU,IAAI,CAAA;AAE7B,EAAA,OAAO,uBAAuB,IAAK,CAAA;AAAA,IACjC,IAAA,EAAM,WAAW,IAAQ,IAAA,IAAA;AAAA,IACzB,MAAQ,EAAA;AAAA,MACN,QAAQ,SAAW,EAAA,MAAA;AAAA,MACnB,aAAa,SAAW,EAAA,WAAA,IAAe,CAAI,CAAA,EAAA,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA;AAAA,MAC3D,YAAc,EAAA,SAAA,EAAW,YAAgB,IAAA,SAAA,CAAU,KAAK,CAAA;AAAA,MACxD,QAAA,EAAU,UAAc,IAAA,qBAAA,CAAsB,UAAU,CAAA;AAAA,MACxD,MAAA,EAAQ,YAAY,aAAA,CAAc,OAAO;AAAA;AAC3C,GACD,CAAA;AACH;;;;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function createEntityPredicateSchema(z) {
|
|
2
|
+
const primitiveSchema = z.union([z.string(), z.number(), z.boolean()]);
|
|
3
|
+
const comparableValueSchema = z.union([
|
|
4
|
+
primitiveSchema,
|
|
5
|
+
z.array(primitiveSchema)
|
|
6
|
+
]);
|
|
7
|
+
let valuePredicateSchema;
|
|
8
|
+
const predicateSchema = z.lazy(
|
|
9
|
+
() => z.union([
|
|
10
|
+
comparableValueSchema,
|
|
11
|
+
z.object({ $all: z.array(predicateSchema) }),
|
|
12
|
+
z.object({ $any: z.array(predicateSchema) }),
|
|
13
|
+
z.object({ $not: predicateSchema }),
|
|
14
|
+
z.record(z.string().regex(/^(?!\$).*$/), valuePredicateSchema)
|
|
15
|
+
])
|
|
16
|
+
);
|
|
17
|
+
valuePredicateSchema = z.union([
|
|
18
|
+
comparableValueSchema,
|
|
19
|
+
z.object({ $exists: z.boolean() }),
|
|
20
|
+
z.object({ $in: z.array(primitiveSchema) }),
|
|
21
|
+
z.object({ $contains: predicateSchema })
|
|
22
|
+
]);
|
|
23
|
+
return predicateSchema;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { createEntityPredicateSchema };
|
|
27
|
+
//# sourceMappingURL=createEntityPredicateSchema.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createEntityPredicateSchema.esm.js","sources":["../../../src/alpha/predicates/createEntityPredicateSchema.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { EntityPredicate, EntityPredicateValue } from '.';\nimport type { z as zImpl, ZodType } from 'zod';\n\n/** @internal */\nexport function createEntityPredicateSchema(z: typeof zImpl) {\n const primitiveSchema = z.union([z.string(), z.number(), z.boolean()]);\n\n const comparableValueSchema = z.union([\n primitiveSchema,\n z.array(primitiveSchema),\n ]);\n\n // eslint-disable-next-line prefer-const\n let valuePredicateSchema: ZodType<EntityPredicateValue>;\n\n const predicateSchema = z.lazy(() =>\n z.union([\n comparableValueSchema,\n z.object({ $all: z.array(predicateSchema) }),\n z.object({ $any: z.array(predicateSchema) }),\n z.object({ $not: predicateSchema }),\n z.record(z.string().regex(/^(?!\\$).*$/), valuePredicateSchema),\n ]),\n ) as ZodType<EntityPredicate>;\n\n valuePredicateSchema = z.union([\n comparableValueSchema,\n z.object({ $exists: z.boolean() }),\n z.object({ $in: z.array(primitiveSchema) }),\n z.object({ $contains: predicateSchema }),\n ]) as ZodType<EntityPredicateValue>;\n\n return predicateSchema;\n}\n"],"names":[],"mappings":"AAoBO,SAAS,4BAA4B,CAAiB,EAAA;AAC3D,EAAA,MAAM,eAAkB,GAAA,CAAA,CAAE,KAAM,CAAA,CAAC,CAAE,CAAA,MAAA,EAAU,EAAA,CAAA,CAAE,MAAO,EAAA,EAAG,CAAE,CAAA,OAAA,EAAS,CAAC,CAAA;AAErE,EAAM,MAAA,qBAAA,GAAwB,EAAE,KAAM,CAAA;AAAA,IACpC,eAAA;AAAA,IACA,CAAA,CAAE,MAAM,eAAe;AAAA,GACxB,CAAA;AAGD,EAAI,IAAA,oBAAA;AAEJ,EAAA,MAAM,kBAAkB,CAAE,CAAA,IAAA;AAAA,IAAK,MAC7B,EAAE,KAAM,CAAA;AAAA,MACN,qBAAA;AAAA,MACA,CAAA,CAAE,OAAO,EAAE,IAAA,EAAM,EAAE,KAAM,CAAA,eAAe,GAAG,CAAA;AAAA,MAC3C,CAAA,CAAE,OAAO,EAAE,IAAA,EAAM,EAAE,KAAM,CAAA,eAAe,GAAG,CAAA;AAAA,MAC3C,CAAE,CAAA,MAAA,CAAO,EAAE,IAAA,EAAM,iBAAiB,CAAA;AAAA,MAClC,CAAA,CAAE,OAAO,CAAE,CAAA,MAAA,GAAS,KAAM,CAAA,YAAY,GAAG,oBAAoB;AAAA,KAC9D;AAAA,GACH;AAEA,EAAA,oBAAA,GAAuB,EAAE,KAAM,CAAA;AAAA,IAC7B,qBAAA;AAAA,IACA,EAAE,MAAO,CAAA,EAAE,SAAS,CAAE,CAAA,OAAA,IAAW,CAAA;AAAA,IACjC,CAAA,CAAE,OAAO,EAAE,GAAA,EAAK,EAAE,KAAM,CAAA,eAAe,GAAG,CAAA;AAAA,IAC1C,CAAE,CAAA,MAAA,CAAO,EAAE,SAAA,EAAW,iBAAiB;AAAA,GACxC,CAAA;AAED,EAAO,OAAA,eAAA;AACT;;;;"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { valueAtPath } from './valueAtPath.esm.js';
|
|
2
|
+
|
|
3
|
+
function entityPredicateToFilterFunction(entityPredicate) {
|
|
4
|
+
return (value) => evaluateEntityPredicate(entityPredicate, value);
|
|
5
|
+
}
|
|
6
|
+
function evaluateEntityPredicate(filter, value) {
|
|
7
|
+
if (typeof filter !== "object" || filter === null || Array.isArray(filter)) {
|
|
8
|
+
return valuesAreEqual(value, filter);
|
|
9
|
+
}
|
|
10
|
+
if ("$all" in filter) {
|
|
11
|
+
return filter.$all.every((f) => evaluateEntityPredicate(f, value));
|
|
12
|
+
}
|
|
13
|
+
if ("$any" in filter) {
|
|
14
|
+
return filter.$any.some((f) => evaluateEntityPredicate(f, value));
|
|
15
|
+
}
|
|
16
|
+
if ("$not" in filter) {
|
|
17
|
+
return !evaluateEntityPredicate(filter.$not, value);
|
|
18
|
+
}
|
|
19
|
+
for (const filterKey in filter) {
|
|
20
|
+
if (!Object.hasOwn(filter, filterKey)) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (filterKey.startsWith("$")) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
if (!evaluatePredicateValue(filter[filterKey], valueAtPath(value, filterKey))) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
function evaluatePredicateValue(filter, value) {
|
|
33
|
+
if (typeof filter !== "object" || filter === null || Array.isArray(filter)) {
|
|
34
|
+
return valuesAreEqual(value, filter);
|
|
35
|
+
}
|
|
36
|
+
if ("$contains" in filter) {
|
|
37
|
+
if (!Array.isArray(value)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return value.some((v) => evaluateEntityPredicate(filter.$contains, v));
|
|
41
|
+
}
|
|
42
|
+
if ("$in" in filter) {
|
|
43
|
+
return filter.$in.includes(value);
|
|
44
|
+
}
|
|
45
|
+
if ("$exists" in filter) {
|
|
46
|
+
if (filter.$exists === true) {
|
|
47
|
+
return value !== void 0;
|
|
48
|
+
}
|
|
49
|
+
return value === void 0;
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
function valuesAreEqual(a, b) {
|
|
54
|
+
if (a === null || b === null) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
if (a === b) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
if (typeof a === "string" && typeof b === "string") {
|
|
61
|
+
return a.toLocaleUpperCase("en-US") === b.toLocaleUpperCase("en-US");
|
|
62
|
+
}
|
|
63
|
+
if (typeof a === "number" || typeof b === "number") {
|
|
64
|
+
return String(a) === String(b);
|
|
65
|
+
}
|
|
66
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
67
|
+
return a.length === b.length && a.every((v, i) => valuesAreEqual(v, b[i]));
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { entityPredicateToFilterFunction };
|
|
73
|
+
//# sourceMappingURL=entityPredicateToFilterFunction.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entityPredicateToFilterFunction.esm.js","sources":["../../../src/alpha/predicates/entityPredicateToFilterFunction.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { JsonValue } from '@backstage/types';\nimport {\n EntityPredicate,\n EntityPredicatePrimitive,\n EntityPredicateValue,\n} from './types';\nimport { valueAtPath } from './valueAtPath';\n\n/**\n * Convert an entity predicate to a filter function that can be used to filter entities.\n * @alpha\n */\nexport function entityPredicateToFilterFunction<T extends JsonValue>(\n entityPredicate: EntityPredicate,\n): (value: T) => boolean {\n return value => evaluateEntityPredicate(entityPredicate, value);\n}\n\n/**\n * Evaluate a entity predicate against a value, typically an entity.\n *\n * @internal\n */\nfunction evaluateEntityPredicate(\n filter: EntityPredicate,\n value: JsonValue,\n): boolean {\n if (typeof filter !== 'object' || filter === null || Array.isArray(filter)) {\n return valuesAreEqual(value, filter);\n }\n\n if ('$all' in filter) {\n return filter.$all.every(f => evaluateEntityPredicate(f, value));\n }\n if ('$any' in filter) {\n return filter.$any.some(f => evaluateEntityPredicate(f, value));\n }\n if ('$not' in filter) {\n return !evaluateEntityPredicate(filter.$not, value);\n }\n\n for (const filterKey in filter) {\n if (!Object.hasOwn(filter, filterKey)) {\n continue;\n }\n if (filterKey.startsWith('$')) {\n return false;\n }\n if (\n !evaluatePredicateValue(filter[filterKey], valueAtPath(value, filterKey))\n ) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Evaluate a single value against a predicate value.\n *\n * @internal\n */\nfunction evaluatePredicateValue(\n filter: EntityPredicateValue,\n value: JsonValue | undefined,\n): boolean {\n if (typeof filter !== 'object' || filter === null || Array.isArray(filter)) {\n return valuesAreEqual(value, filter);\n }\n\n if ('$contains' in filter) {\n if (!Array.isArray(value)) {\n return false;\n }\n return value.some(v => evaluateEntityPredicate(filter.$contains, v));\n }\n if ('$in' in filter) {\n return filter.$in.includes(value as EntityPredicatePrimitive);\n }\n if ('$exists' in filter) {\n if (filter.$exists === true) {\n return value !== undefined;\n }\n return value === undefined;\n }\n\n return false;\n}\n\nfunction valuesAreEqual(\n a: JsonValue | undefined,\n b: JsonValue | undefined,\n): boolean {\n if (a === null || b === null) {\n return false;\n }\n if (a === b) {\n return true;\n }\n if (typeof a === 'string' && typeof b === 'string') {\n return a.toLocaleUpperCase('en-US') === b.toLocaleUpperCase('en-US');\n }\n if (typeof a === 'number' || typeof b === 'number') {\n return String(a) === String(b);\n }\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((v, i) => valuesAreEqual(v, b[i]));\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function valueAtPath(value, path) {
|
|
2
|
+
if (!path) {
|
|
3
|
+
return void 0;
|
|
4
|
+
}
|
|
5
|
+
if (value === void 0 || value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
6
|
+
return void 0;
|
|
7
|
+
}
|
|
8
|
+
for (const valueKey in value) {
|
|
9
|
+
if (!Object.hasOwn(value, valueKey)) {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
if (valueKey === path) {
|
|
13
|
+
if (value[valueKey] !== void 0) {
|
|
14
|
+
return value[valueKey];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (path.startsWith(`${valueKey}.`)) {
|
|
18
|
+
const found = valueAtPath(
|
|
19
|
+
value[valueKey],
|
|
20
|
+
path.slice(valueKey.length + 1)
|
|
21
|
+
);
|
|
22
|
+
if (found !== void 0) {
|
|
23
|
+
return found;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return void 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { valueAtPath };
|
|
31
|
+
//# sourceMappingURL=valueAtPath.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"valueAtPath.esm.js","sources":["../../../src/alpha/predicates/valueAtPath.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { JsonValue } from '@backstage/types';\n\n/**\n * Looks up a value by path in a nested object structure.\n *\n * @remarks\n *\n * The path should be a dot-separated string of keys to traverse. The traversal\n * will tolerate object keys containing dots, and will keep searching until a\n * value has been found or all matching keys have been traversed.\n *\n * This lookup does not traverse into arrays, returning `undefined` instead.\n *\n * @internal\n */\nexport function valueAtPath(\n value: JsonValue | undefined,\n path: string,\n): JsonValue | undefined {\n if (!path) {\n return undefined;\n }\n if (\n value === undefined ||\n value === null ||\n typeof value !== 'object' ||\n Array.isArray(value)\n ) {\n return undefined;\n }\n\n for (const valueKey in value) {\n if (!Object.hasOwn(value, valueKey)) {\n continue;\n }\n if (valueKey === path) {\n if (value[valueKey] !== undefined) {\n return value[valueKey];\n }\n }\n if (path.startsWith(`${valueKey}.`)) {\n const found = valueAtPath(\n value[valueKey],\n path.slice(valueKey.length + 1),\n );\n if (found !== undefined) {\n return found;\n }\n }\n }\n\n return undefined;\n}\n"],"names":[],"mappings":"AA+BgB,SAAA,WAAA,CACd,OACA,IACuB,EAAA;AACvB,EAAA,IAAI,CAAC,IAAM,EAAA;AACT,IAAO,OAAA,KAAA,CAAA;AAAA;AAET,EACE,IAAA,KAAA,KAAU,KACV,CAAA,IAAA,KAAA,KAAU,IACV,IAAA,OAAO,UAAU,QACjB,IAAA,KAAA,CAAM,OAAQ,CAAA,KAAK,CACnB,EAAA;AACA,IAAO,OAAA,KAAA,CAAA;AAAA;AAGT,EAAA,KAAA,MAAW,YAAY,KAAO,EAAA;AAC5B,IAAA,IAAI,CAAC,MAAA,CAAO,MAAO,CAAA,KAAA,EAAO,QAAQ,CAAG,EAAA;AACnC,MAAA;AAAA;AAEF,IAAA,IAAI,aAAa,IAAM,EAAA;AACrB,MAAI,IAAA,KAAA,CAAM,QAAQ,CAAA,KAAM,KAAW,CAAA,EAAA;AACjC,QAAA,OAAO,MAAM,QAAQ,CAAA;AAAA;AACvB;AAEF,IAAA,IAAI,IAAK,CAAA,UAAA,CAAW,CAAG,EAAA,QAAQ,GAAG,CAAG,EAAA;AACnC,MAAA,MAAM,KAAQ,GAAA,WAAA;AAAA,QACZ,MAAM,QAAQ,CAAA;AAAA,QACd,IAAK,CAAA,KAAA,CAAM,QAAS,CAAA,MAAA,GAAS,CAAC;AAAA,OAChC;AACA,MAAA,IAAI,UAAU,KAAW,CAAA,EAAA;AACvB,QAAO,OAAA,KAAA;AAAA;AACT;AACF;AAGF,EAAO,OAAA,KAAA,CAAA;AACT;;;;"}
|
package/dist/alpha.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
3
2
|
import { RouteRef, ExtensionDefinition } from '@backstage/frontend-plugin-api';
|
|
4
3
|
import * as React from 'react';
|
|
5
4
|
import React__default, { ComponentType } from 'react';
|
|
6
|
-
import * as _backstage_catalog_model from '@backstage/catalog-model';
|
|
7
5
|
import { Entity } from '@backstage/catalog-model';
|
|
6
|
+
import { JsonValue } from '@backstage/types';
|
|
8
7
|
import * as _backstage_core_plugin_api_alpha from '@backstage/core-plugin-api/alpha';
|
|
9
8
|
import { ResourcePermission } from '@backstage/plugin-permission-common';
|
|
10
9
|
|
|
@@ -30,7 +29,38 @@ declare const defaultEntityContentGroups: {
|
|
|
30
29
|
observability: string;
|
|
31
30
|
};
|
|
32
31
|
/** @alpha */
|
|
33
|
-
type EntityCardType = '
|
|
32
|
+
type EntityCardType = 'summary' | 'info' | 'content';
|
|
33
|
+
|
|
34
|
+
/** @alpha */
|
|
35
|
+
type EntityPredicate = EntityPredicateExpression | EntityPredicatePrimitive | {
|
|
36
|
+
$all: EntityPredicate[];
|
|
37
|
+
} | {
|
|
38
|
+
$any: EntityPredicate[];
|
|
39
|
+
} | {
|
|
40
|
+
$not: EntityPredicate;
|
|
41
|
+
};
|
|
42
|
+
/** @alpha */
|
|
43
|
+
type EntityPredicateExpression = {
|
|
44
|
+
[KPath in string]: EntityPredicateValue;
|
|
45
|
+
} & {
|
|
46
|
+
[KPath in `$${string}`]: never;
|
|
47
|
+
};
|
|
48
|
+
/** @alpha */
|
|
49
|
+
type EntityPredicateValue = EntityPredicatePrimitive | {
|
|
50
|
+
$exists: boolean;
|
|
51
|
+
} | {
|
|
52
|
+
$in: EntityPredicatePrimitive[];
|
|
53
|
+
} | {
|
|
54
|
+
$contains: EntityPredicateExpression;
|
|
55
|
+
};
|
|
56
|
+
/** @alpha */
|
|
57
|
+
type EntityPredicatePrimitive = string | number | boolean;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Convert an entity predicate to a filter function that can be used to filter entities.
|
|
61
|
+
* @alpha
|
|
62
|
+
*/
|
|
63
|
+
declare function entityPredicateToFilterFunction<T extends JsonValue>(entityPredicate: EntityPredicate): (value: T) => boolean;
|
|
34
64
|
|
|
35
65
|
/**
|
|
36
66
|
* @alpha
|
|
@@ -41,10 +71,10 @@ declare const EntityCardBlueprint: _backstage_frontend_plugin_api.ExtensionBluep
|
|
|
41
71
|
name: undefined;
|
|
42
72
|
params: {
|
|
43
73
|
loader: () => Promise<JSX.Element>;
|
|
44
|
-
filter?: string | ((entity:
|
|
45
|
-
type?: EntityCardType
|
|
74
|
+
filter?: string | EntityPredicate | ((entity: Entity) => boolean);
|
|
75
|
+
type?: EntityCardType;
|
|
46
76
|
};
|
|
47
|
-
output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<React.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity:
|
|
77
|
+
output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<React.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {
|
|
48
78
|
optional: true;
|
|
49
79
|
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {
|
|
50
80
|
optional: true;
|
|
@@ -53,15 +83,15 @@ declare const EntityCardBlueprint: _backstage_frontend_plugin_api.ExtensionBluep
|
|
|
53
83
|
}>;
|
|
54
84
|
inputs: {};
|
|
55
85
|
config: {
|
|
56
|
-
filter:
|
|
57
|
-
type: "
|
|
86
|
+
filter: EntityPredicate | undefined;
|
|
87
|
+
type: "content" | "summary" | "info" | undefined;
|
|
58
88
|
};
|
|
59
89
|
configInput: {
|
|
60
|
-
filter?:
|
|
61
|
-
type?: "
|
|
90
|
+
filter?: EntityPredicate | undefined;
|
|
91
|
+
type?: "content" | "summary" | "info" | undefined;
|
|
62
92
|
};
|
|
63
93
|
dataRefs: {
|
|
64
|
-
filterFunction: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity:
|
|
94
|
+
filterFunction: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {}>;
|
|
65
95
|
filterExpression: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {}>;
|
|
66
96
|
type: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<EntityCardType, "catalog.entity-card-type", {}>;
|
|
67
97
|
};
|
|
@@ -78,13 +108,13 @@ declare const EntityContentBlueprint: _backstage_frontend_plugin_api.ExtensionBl
|
|
|
78
108
|
loader: () => Promise<JSX.Element>;
|
|
79
109
|
defaultPath: string;
|
|
80
110
|
defaultTitle: string;
|
|
81
|
-
defaultGroup?: (string & {})
|
|
82
|
-
routeRef?: RouteRef
|
|
83
|
-
filter?: string | ((entity:
|
|
111
|
+
defaultGroup?: keyof typeof defaultEntityContentGroups | (string & {});
|
|
112
|
+
routeRef?: RouteRef;
|
|
113
|
+
filter?: string | EntityPredicate | ((entity: Entity) => boolean);
|
|
84
114
|
};
|
|
85
115
|
output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<React.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
86
116
|
optional: true;
|
|
87
|
-
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-content-title", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity:
|
|
117
|
+
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-content-title", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {
|
|
88
118
|
optional: true;
|
|
89
119
|
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {
|
|
90
120
|
optional: true;
|
|
@@ -95,18 +125,18 @@ declare const EntityContentBlueprint: _backstage_frontend_plugin_api.ExtensionBl
|
|
|
95
125
|
config: {
|
|
96
126
|
path: string | undefined;
|
|
97
127
|
title: string | undefined;
|
|
98
|
-
filter:
|
|
128
|
+
filter: EntityPredicate | undefined;
|
|
99
129
|
group: string | false | undefined;
|
|
100
130
|
};
|
|
101
131
|
configInput: {
|
|
102
|
-
filter?:
|
|
132
|
+
filter?: EntityPredicate | undefined;
|
|
103
133
|
title?: string | undefined;
|
|
104
134
|
path?: string | undefined;
|
|
105
135
|
group?: string | false | undefined;
|
|
106
136
|
};
|
|
107
137
|
dataRefs: {
|
|
108
138
|
title: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-content-title", {}>;
|
|
109
|
-
filterFunction: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity:
|
|
139
|
+
filterFunction: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {}>;
|
|
110
140
|
filterExpression: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {}>;
|
|
111
141
|
group: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-content-group", {}>;
|
|
112
142
|
};
|
|
@@ -124,10 +154,10 @@ declare const EntityContentLayoutBlueprint: _backstage_frontend_plugin_api.Exten
|
|
|
124
154
|
kind: "entity-content-layout";
|
|
125
155
|
name: undefined;
|
|
126
156
|
params: {
|
|
127
|
-
filter?: string | ((entity:
|
|
157
|
+
filter?: string | EntityPredicate | ((entity: Entity) => boolean);
|
|
128
158
|
loader: () => Promise<(props: EntityContentLayoutProps) => React__default.JSX.Element>;
|
|
129
159
|
};
|
|
130
|
-
output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity:
|
|
160
|
+
output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {
|
|
131
161
|
optional: true;
|
|
132
162
|
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {
|
|
133
163
|
optional: true;
|
|
@@ -135,29 +165,47 @@ declare const EntityContentLayoutBlueprint: _backstage_frontend_plugin_api.Exten
|
|
|
135
165
|
inputs: {};
|
|
136
166
|
config: {
|
|
137
167
|
type: string | undefined;
|
|
138
|
-
filter:
|
|
168
|
+
filter: EntityPredicate | undefined;
|
|
139
169
|
};
|
|
140
170
|
configInput: {
|
|
141
|
-
filter?:
|
|
171
|
+
filter?: EntityPredicate | undefined;
|
|
142
172
|
type?: string | undefined;
|
|
143
173
|
};
|
|
144
174
|
dataRefs: {
|
|
145
|
-
filterFunction: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity:
|
|
175
|
+
filterFunction: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {}>;
|
|
146
176
|
filterExpression: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {}>;
|
|
147
177
|
component: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(props: EntityContentLayoutProps) => React__default.JSX.Element, "catalog.entity-content-layout.component", {}>;
|
|
148
178
|
};
|
|
149
179
|
}>;
|
|
150
180
|
|
|
181
|
+
/** @alpha */
|
|
182
|
+
declare const EntityHeaderBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
|
|
183
|
+
kind: "entity-header";
|
|
184
|
+
name: undefined;
|
|
185
|
+
params: {
|
|
186
|
+
loader: () => Promise<JSX.Element>;
|
|
187
|
+
};
|
|
188
|
+
output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<React.JSX.Element, "core.reactElement", {
|
|
189
|
+
optional: true;
|
|
190
|
+
}>;
|
|
191
|
+
inputs: {};
|
|
192
|
+
config: {};
|
|
193
|
+
configInput: {};
|
|
194
|
+
dataRefs: {
|
|
195
|
+
element: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<React.JSX.Element, "core.reactElement", {}>;
|
|
196
|
+
};
|
|
197
|
+
}>;
|
|
198
|
+
|
|
151
199
|
/** @alpha */
|
|
152
200
|
declare function convertLegacyEntityCardExtension(LegacyExtension: ComponentType<{}>, overrides?: {
|
|
153
201
|
name?: string;
|
|
154
|
-
filter?:
|
|
202
|
+
filter?: string | EntityPredicate | ((entity: Entity) => boolean);
|
|
155
203
|
}): ExtensionDefinition;
|
|
156
204
|
|
|
157
205
|
/** @alpha */
|
|
158
206
|
declare function convertLegacyEntityContentExtension(LegacyExtension: ComponentType<{}>, overrides?: {
|
|
159
207
|
name?: string;
|
|
160
|
-
filter?:
|
|
208
|
+
filter?: string | EntityPredicate | ((entity: Entity) => boolean);
|
|
161
209
|
defaultPath?: string;
|
|
162
210
|
defaultTitle?: string;
|
|
163
211
|
}): ExtensionDefinition;
|
|
@@ -234,4 +282,4 @@ declare function useEntityPermission(permission: ResourcePermission<'catalog-ent
|
|
|
234
282
|
error?: Error;
|
|
235
283
|
};
|
|
236
284
|
|
|
237
|
-
export { EntityCardBlueprint, type EntityCardType, EntityContentBlueprint, EntityContentLayoutBlueprint, type EntityContentLayoutProps, catalogReactTranslationRef, convertLegacyEntityCardExtension, convertLegacyEntityContentExtension, defaultEntityContentGroups, isOwnerOf, useEntityPermission };
|
|
285
|
+
export { EntityCardBlueprint, type EntityCardType, EntityContentBlueprint, EntityContentLayoutBlueprint, type EntityContentLayoutProps, EntityHeaderBlueprint, type EntityPredicate, type EntityPredicateExpression, type EntityPredicatePrimitive, type EntityPredicateValue, catalogReactTranslationRef, convertLegacyEntityCardExtension, convertLegacyEntityContentExtension, defaultEntityContentGroups, entityPredicateToFilterFunction, isOwnerOf, useEntityPermission };
|
package/dist/alpha.esm.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export { EntityCardBlueprint } from './alpha/blueprints/EntityCardBlueprint.esm.js';
|
|
2
2
|
export { EntityContentBlueprint } from './alpha/blueprints/EntityContentBlueprint.esm.js';
|
|
3
3
|
export { EntityContentLayoutBlueprint } from './alpha/blueprints/EntityContentLayoutBlueprint.esm.js';
|
|
4
|
+
export { EntityHeaderBlueprint } from './alpha/blueprints/EntityHeaderBlueprint.esm.js';
|
|
4
5
|
export { defaultEntityContentGroups } from './alpha/blueprints/extensionData.esm.js';
|
|
5
6
|
export { convertLegacyEntityCardExtension } from './alpha/converters/convertLegacyEntityCardExtension.esm.js';
|
|
6
7
|
export { convertLegacyEntityContentExtension } from './alpha/converters/convertLegacyEntityContentExtension.esm.js';
|
|
8
|
+
export { entityPredicateToFilterFunction } from './alpha/predicates/entityPredicateToFilterFunction.esm.js';
|
|
7
9
|
export { catalogReactTranslationRef } from './translation.esm.js';
|
|
8
10
|
export { isOwnerOf } from './utils/isOwnerOf.esm.js';
|
|
9
11
|
export { useEntityPermission } from './hooks/useEntityPermission.esm.js';
|
package/dist/alpha.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alpha.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"alpha.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogAutocomplete.esm.js","sources":["../../../src/components/CatalogAutocomplete/CatalogAutocomplete.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 Box from '@material-ui/core/Box';\nimport Typography, { TypographyProps } from '@material-ui/core/Typography';\nimport Paper, { PaperProps } from '@material-ui/core/Paper';\nimport Popper, { PopperProps } from '@material-ui/core/Popper';\nimport TextField, { OutlinedTextFieldProps } from '@material-ui/core/TextField';\nimport Grow from '@material-ui/core/Grow';\nimport {\n createStyles,\n makeStyles,\n Theme,\n withStyles,\n} from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport Autocomplete, {\n AutocompleteProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab/Autocomplete';\nimport React, { ReactNode, useCallback } from 'react';\nimport { merge } from 'lodash';\nimport classNames from 'classnames';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n margin: theme.spacing(1, 0),\n },\n label: {\n position: 'relative',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '& > span': {\n top: 0,\n left: 0,\n position: 'absolute',\n },\n },\n }),\n { name: 'BackstageAutocomplete' },\n);\n\nconst BootstrapAutocomplete = withStyles(\n (theme: Theme) =>\n createStyles({\n root: {},\n paper: {\n margin: 0,\n },\n hasClearIcon: {},\n hasPopupIcon: {},\n focused: {},\n inputRoot: {\n marginTop: 24,\n backgroundColor: theme.palette.background.paper,\n '$root$hasClearIcon$hasPopupIcon &': {\n paddingBlock: theme.spacing(0.75),\n paddingInlineStart: theme.spacing(0.75),\n },\n '$root$focused &': {\n outline: 'none',\n },\n '$root &:hover > fieldset': {\n borderColor: '#ced4da',\n },\n '$root$focused & > fieldset': {\n borderWidth: 1,\n borderColor: theme.palette.primary.main,\n },\n },\n popupIndicator: {\n padding: 0,\n margin: 0,\n color: '#616161',\n '&:hover': {\n backgroundColor: 'unset',\n },\n '& [class*=\"MuiTouchRipple-root\"]': {\n display: 'none',\n },\n },\n endAdornment: {\n '$root$hasClearIcon$hasPopupIcon &': {\n right: 4,\n },\n },\n input: {\n '$root$hasClearIcon$hasPopupIcon &': {\n fontSize: theme.typography.body1.fontSize,\n paddingBlock: theme.spacing(0.8125),\n },\n },\n }),\n { name: 'BackstageAutocompleteBase' },\n)(Autocomplete) as typeof Autocomplete;\n\nconst PopperComponent = (props: PopperProps) => (\n <Popper {...props} transition placement=\"bottom-start\">\n {({ TransitionProps }) => (\n <Grow {...TransitionProps} style={{ transformOrigin: '0 0 0' }}>\n <Box>{props.children as ReactNode}</Box>\n </Grow>\n )}\n </Popper>\n);\n\nconst PaperComponent = (props: PaperProps) => (\n <Paper {...props} elevation={8} />\n);\n\nexport type CatalogAutocompleteProps<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n> = Omit<\n AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>,\n 'PopperComponent' | 'PaperComponent' | 'popupIcon' | 'renderInput'\n> & {\n name: string;\n label?: string;\n LabelProps?: TypographyProps<'label'>;\n TextFieldProps?: Omit<OutlinedTextFieldProps, 'variant'>;\n renderInput?: AutocompleteProps<\n T,\n Multiple,\n DisableClearable,\n FreeSolo\n >['renderInput'];\n};\n\nexport function CatalogAutocomplete<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n>(props: CatalogAutocompleteProps<T, Multiple, DisableClearable, FreeSolo>) {\n const { label, name, LabelProps, TextFieldProps, ...rest } = props;\n const classes = useStyles();\n const renderInput = useCallback(\n (params: AutocompleteRenderInputParams) => (\n <TextField {...merge(params, TextFieldProps)} variant=\"outlined\" />\n ),\n [TextFieldProps],\n );\n const autocomplete = (\n <BootstrapAutocomplete\n size=\"small\"\n {...rest}\n renderInput={rest.renderInput ?? renderInput}\n popupIcon={<ExpandMoreIcon data-testid={`${name}-expand`} />}\n PaperComponent={PaperComponent}\n PopperComponent={PopperComponent}\n />\n );\n\n return (\n <Box className={classes.root}>\n {label ? (\n <Typography\n {...LabelProps}\n className={classNames(classes.label, LabelProps?.className)}\n component=\"label\"\n >\n <Box component=\"span\">{label}</Box>\n {autocomplete}\n </Typography>\n ) : (\n autocomplete\n )}\n </Box>\n );\n}\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"CatalogAutocomplete.esm.js","sources":["../../../src/components/CatalogAutocomplete/CatalogAutocomplete.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 Box from '@material-ui/core/Box';\nimport Typography, { TypographyProps } from '@material-ui/core/Typography';\nimport Paper, { PaperProps } from '@material-ui/core/Paper';\nimport Popper, { PopperProps } from '@material-ui/core/Popper';\nimport TextField, { OutlinedTextFieldProps } from '@material-ui/core/TextField';\nimport Grow from '@material-ui/core/Grow';\nimport {\n createStyles,\n makeStyles,\n Theme,\n withStyles,\n} from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport Autocomplete, {\n AutocompleteProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab/Autocomplete';\nimport React, { ReactNode, useCallback } from 'react';\nimport { merge } from 'lodash';\nimport classNames from 'classnames';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n margin: theme.spacing(1, 0),\n },\n label: {\n position: 'relative',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '& > span': {\n top: 0,\n left: 0,\n position: 'absolute',\n },\n },\n }),\n { name: 'BackstageAutocomplete' },\n);\n\nconst BootstrapAutocomplete = withStyles(\n (theme: Theme) =>\n createStyles({\n root: {},\n paper: {\n margin: 0,\n },\n hasClearIcon: {},\n hasPopupIcon: {},\n focused: {},\n inputRoot: {\n marginTop: 24,\n backgroundColor: theme.palette.background.paper,\n '$root$hasClearIcon$hasPopupIcon &': {\n paddingBlock: theme.spacing(0.75),\n paddingInlineStart: theme.spacing(0.75),\n },\n '$root$focused &': {\n outline: 'none',\n },\n '$root &:hover > fieldset': {\n borderColor: '#ced4da',\n },\n '$root$focused & > fieldset': {\n borderWidth: 1,\n borderColor: theme.palette.primary.main,\n },\n },\n popupIndicator: {\n padding: 0,\n margin: 0,\n color: '#616161',\n '&:hover': {\n backgroundColor: 'unset',\n },\n '& [class*=\"MuiTouchRipple-root\"]': {\n display: 'none',\n },\n },\n endAdornment: {\n '$root$hasClearIcon$hasPopupIcon &': {\n right: 4,\n },\n },\n input: {\n '$root$hasClearIcon$hasPopupIcon &': {\n fontSize: theme.typography.body1.fontSize,\n paddingBlock: theme.spacing(0.8125),\n },\n },\n }),\n { name: 'BackstageAutocompleteBase' },\n)(Autocomplete) as typeof Autocomplete;\n\nconst PopperComponent = (props: PopperProps) => (\n <Popper {...props} transition placement=\"bottom-start\">\n {({ TransitionProps }) => (\n <Grow {...TransitionProps} style={{ transformOrigin: '0 0 0' }}>\n <Box>{props.children as ReactNode}</Box>\n </Grow>\n )}\n </Popper>\n);\n\nconst PaperComponent = (props: PaperProps) => (\n <Paper {...props} elevation={8} />\n);\n\n/**\n * Props for {@link CatalogAutocomplete}\n *\n * @public\n */\nexport type CatalogAutocompleteProps<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n> = Omit<\n AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>,\n 'PopperComponent' | 'PaperComponent' | 'popupIcon' | 'renderInput'\n> & {\n name: string;\n label?: string;\n LabelProps?: TypographyProps<'label'>;\n TextFieldProps?: Omit<OutlinedTextFieldProps, 'variant'>;\n renderInput?: AutocompleteProps<\n T,\n Multiple,\n DisableClearable,\n FreeSolo\n >['renderInput'];\n};\n\n/** @public */\nexport function CatalogAutocomplete<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n>(props: CatalogAutocompleteProps<T, Multiple, DisableClearable, FreeSolo>) {\n const { label, name, LabelProps, TextFieldProps, ...rest } = props;\n const classes = useStyles();\n const renderInput = useCallback(\n (params: AutocompleteRenderInputParams) => (\n <TextField {...merge(params, TextFieldProps)} variant=\"outlined\" />\n ),\n [TextFieldProps],\n );\n const autocomplete = (\n <BootstrapAutocomplete\n size=\"small\"\n {...rest}\n renderInput={rest.renderInput ?? renderInput}\n popupIcon={<ExpandMoreIcon data-testid={`${name}-expand`} />}\n PaperComponent={PaperComponent}\n PopperComponent={PopperComponent}\n />\n );\n\n return (\n <Box className={classes.root}>\n {label ? (\n <Typography\n {...LabelProps}\n className={classNames(classes.label, LabelProps?.className)}\n component=\"label\"\n >\n <Box component=\"span\">{label}</Box>\n {autocomplete}\n </Typography>\n ) : (\n autocomplete\n )}\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ import { EntityAutocompletePickerOption } from './EntityAutocompletePickerOption
|
|
|
8
8
|
import { useEntityList } from '../../hooks/useEntityListProvider.esm.js';
|
|
9
9
|
import { reduceBackendCatalogFilters } from '../../utils/filters.esm.js';
|
|
10
10
|
import { CatalogAutocomplete } from '../CatalogAutocomplete/CatalogAutocomplete.esm.js';
|
|
11
|
+
import { isEqual } from 'lodash';
|
|
11
12
|
|
|
12
13
|
const useStyles = makeStyles(
|
|
13
14
|
{
|
|
@@ -57,8 +58,9 @@ function EntityAutocompletePicker(props) {
|
|
|
57
58
|
() => [queryParameter].flat().filter(Boolean),
|
|
58
59
|
[queryParameter]
|
|
59
60
|
);
|
|
61
|
+
const filteredOptions = filters[name]?.values;
|
|
60
62
|
const [selectedOptions, setSelectedOptions] = useState(
|
|
61
|
-
queryParameters.length ? queryParameters :
|
|
63
|
+
queryParameters.length ? queryParameters : filteredOptions ?? initialSelectedOptions
|
|
62
64
|
);
|
|
63
65
|
useEffect(() => {
|
|
64
66
|
if (queryParameters.length) {
|
|
@@ -72,6 +74,13 @@ function EntityAutocompletePicker(props) {
|
|
|
72
74
|
[name]: shouldAddFilter ? new Filter(selectedOptions) : void 0
|
|
73
75
|
});
|
|
74
76
|
}, [name, shouldAddFilter, selectedOptions, Filter, updateFilters]);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
if (!shouldAddFilter) return;
|
|
79
|
+
const newSelectedOptions = filteredOptions ?? [];
|
|
80
|
+
if (!isEqual(newSelectedOptions, selectedOptions)) {
|
|
81
|
+
setSelectedOptions(newSelectedOptions);
|
|
82
|
+
}
|
|
83
|
+
}, [filteredOptions]);
|
|
75
84
|
const filter = filters[name];
|
|
76
85
|
if (filter && typeof filter === "object" && !("values" in filter) || !availableOptions.length) {
|
|
77
86
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityAutocompletePicker.esm.js","sources":["../../../src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 Box from '@material-ui/core/Box';\nimport { TextFieldProps } from '@material-ui/core/TextField';\nimport { makeStyles } from '@material-ui/core/styles';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { EntityAutocompletePickerOption } from './EntityAutocompletePickerOption';\nimport {\n DefaultEntityFilters,\n useEntityList,\n} from '../../hooks/useEntityListProvider';\nimport { EntityFilter } from '../../types';\nimport { reduceBackendCatalogFilters } from '../../utils/filters';\nimport { CatalogAutocomplete } from '../CatalogAutocomplete';\n\n/** @public */\nexport type AllowedEntityFilters<T extends DefaultEntityFilters> = {\n [K in keyof T]-?: NonNullable<T[K]> extends EntityFilter & {\n values: string[];\n }\n ? K\n : never;\n}[keyof T];\n\n/** @public */\nexport type EntityAutocompletePickerProps<\n T extends DefaultEntityFilters = DefaultEntityFilters,\n Name extends AllowedEntityFilters<T> = AllowedEntityFilters<T>,\n> = {\n label: string;\n name: Name;\n path: string;\n showCounts?: boolean;\n Filter: { new (values: string[]): NonNullable<T[Name]> };\n InputProps?: TextFieldProps;\n initialSelectedOptions?: string[];\n filtersForAvailableValues?: Array<keyof T>;\n hidden?: boolean;\n};\n\n/** @public */\nexport type CatalogReactEntityAutocompletePickerClassKey = 'root' | 'label';\n\nconst useStyles = makeStyles(\n {\n root: {},\n label: {\n textTransform: 'none',\n fontWeight: 'bold',\n },\n },\n { name: 'CatalogReactEntityAutocompletePicker' },\n);\n\n/** @public */\nexport function EntityAutocompletePicker<\n T extends DefaultEntityFilters = DefaultEntityFilters,\n Name extends AllowedEntityFilters<T> = AllowedEntityFilters<T>,\n>(props: EntityAutocompletePickerProps<T, Name>) {\n const {\n label,\n name,\n path,\n showCounts,\n Filter,\n InputProps,\n initialSelectedOptions = [],\n filtersForAvailableValues = ['kind'],\n hidden,\n } = props;\n const classes = useStyles();\n\n const {\n updateFilters,\n filters,\n queryParameters: { [name]: queryParameter },\n } = useEntityList<T>();\n\n const catalogApi = useApi(catalogApiRef);\n const availableValuesFilters = filtersForAvailableValues.map(\n f => filters[f] as EntityFilter | undefined,\n );\n const { value: availableValues } = useAsync(async () => {\n const facet = path;\n const { facets } = await catalogApi.getEntityFacets({\n facets: [facet],\n filter: reduceBackendCatalogFilters(\n availableValuesFilters.filter(Boolean) as EntityFilter[],\n ),\n });\n\n return Object.fromEntries(\n facets[facet].map(({ value, count }) => [value, count]),\n );\n }, [...availableValuesFilters]);\n\n const queryParameters = useMemo(\n () => [queryParameter].flat().filter(Boolean) as string[],\n [queryParameter],\n );\n\n const [selectedOptions, setSelectedOptions] = useState(\n queryParameters.length\n ? queryParameters\n :
|
|
1
|
+
{"version":3,"file":"EntityAutocompletePicker.esm.js","sources":["../../../src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 Box from '@material-ui/core/Box';\nimport { TextFieldProps } from '@material-ui/core/TextField';\nimport { makeStyles } from '@material-ui/core/styles';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { EntityAutocompletePickerOption } from './EntityAutocompletePickerOption';\nimport {\n DefaultEntityFilters,\n useEntityList,\n} from '../../hooks/useEntityListProvider';\nimport { EntityFilter } from '../../types';\nimport { reduceBackendCatalogFilters } from '../../utils/filters';\nimport { CatalogAutocomplete } from '../CatalogAutocomplete';\nimport { isEqual } from 'lodash';\n\n/** @public */\nexport type AllowedEntityFilters<T extends DefaultEntityFilters> = {\n [K in keyof T]-?: NonNullable<T[K]> extends EntityFilter & {\n values: string[];\n }\n ? K\n : never;\n}[keyof T];\n\n/** @public */\nexport type EntityAutocompletePickerProps<\n T extends DefaultEntityFilters = DefaultEntityFilters,\n Name extends AllowedEntityFilters<T> = AllowedEntityFilters<T>,\n> = {\n label: string;\n name: Name;\n path: string;\n showCounts?: boolean;\n Filter: { new (values: string[]): NonNullable<T[Name]> };\n InputProps?: TextFieldProps;\n initialSelectedOptions?: string[];\n filtersForAvailableValues?: Array<keyof T>;\n hidden?: boolean;\n};\n\n/** @public */\nexport type CatalogReactEntityAutocompletePickerClassKey = 'root' | 'label';\n\nconst useStyles = makeStyles(\n {\n root: {},\n label: {\n textTransform: 'none',\n fontWeight: 'bold',\n },\n },\n { name: 'CatalogReactEntityAutocompletePicker' },\n);\n\n/** @public */\nexport function EntityAutocompletePicker<\n T extends DefaultEntityFilters = DefaultEntityFilters,\n Name extends AllowedEntityFilters<T> = AllowedEntityFilters<T>,\n>(props: EntityAutocompletePickerProps<T, Name>) {\n const {\n label,\n name,\n path,\n showCounts,\n Filter,\n InputProps,\n initialSelectedOptions = [],\n filtersForAvailableValues = ['kind'],\n hidden,\n } = props;\n const classes = useStyles();\n\n const {\n updateFilters,\n filters,\n queryParameters: { [name]: queryParameter },\n } = useEntityList<T>();\n\n const catalogApi = useApi(catalogApiRef);\n const availableValuesFilters = filtersForAvailableValues.map(\n f => filters[f] as EntityFilter | undefined,\n );\n const { value: availableValues } = useAsync(async () => {\n const facet = path;\n const { facets } = await catalogApi.getEntityFacets({\n facets: [facet],\n filter: reduceBackendCatalogFilters(\n availableValuesFilters.filter(Boolean) as EntityFilter[],\n ),\n });\n\n return Object.fromEntries(\n facets[facet].map(({ value, count }) => [value, count]),\n );\n }, [...availableValuesFilters]);\n\n const queryParameters = useMemo(\n () => [queryParameter].flat().filter(Boolean) as string[],\n [queryParameter],\n );\n\n const filteredOptions = (filters[name] as unknown as { values: string[] })\n ?.values;\n\n const [selectedOptions, setSelectedOptions] = useState(\n queryParameters.length\n ? queryParameters\n : filteredOptions ?? initialSelectedOptions,\n );\n\n // Set selected options on query parameter updates; this happens at initial page load and from\n // external updates to the page location\n useEffect(() => {\n if (queryParameters.length) {\n setSelectedOptions(queryParameters);\n }\n }, [queryParameters]);\n\n const availableOptions = Object.keys(availableValues ?? {});\n const shouldAddFilter = selectedOptions.length && availableOptions.length;\n\n // Update filter value when selectedOptions change\n useEffect(() => {\n updateFilters({\n [name]: shouldAddFilter ? new Filter(selectedOptions) : undefined,\n } as Partial<T>);\n }, [name, shouldAddFilter, selectedOptions, Filter, updateFilters]);\n\n // Update selected options when filter value changes\n useEffect(() => {\n if (!shouldAddFilter) return;\n\n const newSelectedOptions = filteredOptions ?? [];\n\n // Check value is actually different (not just a different reference) to prevent selectedOptions <> filters loop\n if (!isEqual(newSelectedOptions, selectedOptions)) {\n setSelectedOptions(newSelectedOptions);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Don't re-set filter value when selectedOptions changes\n }, [filteredOptions]);\n\n const filter = filters[name];\n if (\n (filter && typeof filter === 'object' && !('values' in filter)) ||\n !availableOptions.length\n ) {\n return null;\n }\n\n return hidden ? null : (\n <Box className={classes.root} pb={1} pt={1}>\n <CatalogAutocomplete<string, true>\n multiple\n disableCloseOnSelect\n label={label}\n name={`${String(name)}-picker`}\n options={availableOptions}\n value={selectedOptions}\n TextFieldProps={InputProps}\n onChange={(_event: object, options: string[]) =>\n setSelectedOptions(options)\n }\n renderOption={(option, { selected }) => (\n <EntityAutocompletePickerOption\n selected={selected}\n value={option}\n availableOptions={availableValues}\n showCounts={!!showCounts}\n />\n )}\n />\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { CatalogApi } from '@backstage/catalog-client';
|
|
3
2
|
export { CATALOG_FILTER_EXISTS, CatalogApi } from '@backstage/catalog-client';
|
|
4
3
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
@@ -6,10 +5,12 @@ import { ApiRef, IconComponent } from '@backstage/core-plugin-api';
|
|
|
6
5
|
import * as _backstage_catalog_model from '@backstage/catalog-model';
|
|
7
6
|
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
|
|
8
7
|
import { Observable } from '@backstage/types';
|
|
8
|
+
import { TypographyProps } from '@material-ui/core/Typography';
|
|
9
|
+
import { OutlinedTextFieldProps, TextFieldProps } from '@material-ui/core/TextField';
|
|
10
|
+
import { AutocompleteProps } from '@material-ui/lab/Autocomplete';
|
|
9
11
|
import React__default, { PropsWithChildren, ReactNode, ComponentProps } from 'react';
|
|
10
12
|
import { LinkProps, InfoCardVariants, TableColumn, TableOptions } from '@backstage/core-components';
|
|
11
13
|
import IconButton from '@material-ui/core/IconButton';
|
|
12
|
-
import { TextFieldProps } from '@material-ui/core/TextField';
|
|
13
14
|
import { Overrides } from '@material-ui/core/styles/overrides';
|
|
14
15
|
import { StyleRules } from '@material-ui/core/styles/withStyles';
|
|
15
16
|
import { scmIntegrationsApiRef } from '@backstage/integration-react';
|
|
@@ -198,6 +199,21 @@ declare class MockStarredEntitiesApi implements StarredEntitiesApi {
|
|
|
198
199
|
starredEntitie$(): Observable<Set<string>>;
|
|
199
200
|
}
|
|
200
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Props for {@link CatalogAutocomplete}
|
|
204
|
+
*
|
|
205
|
+
* @public
|
|
206
|
+
*/
|
|
207
|
+
type CatalogAutocompleteProps<T, Multiple extends boolean | undefined = undefined, DisableClearable extends boolean | undefined = undefined, FreeSolo extends boolean | undefined = undefined> = Omit<AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>, 'PopperComponent' | 'PaperComponent' | 'popupIcon' | 'renderInput'> & {
|
|
208
|
+
name: string;
|
|
209
|
+
label?: string;
|
|
210
|
+
LabelProps?: TypographyProps<'label'>;
|
|
211
|
+
TextFieldProps?: Omit<OutlinedTextFieldProps, 'variant'>;
|
|
212
|
+
renderInput?: AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>['renderInput'];
|
|
213
|
+
};
|
|
214
|
+
/** @public */
|
|
215
|
+
declare function CatalogAutocomplete<T, Multiple extends boolean | undefined = undefined, DisableClearable extends boolean | undefined = undefined, FreeSolo extends boolean | undefined = undefined>(props: CatalogAutocompleteProps<T, Multiple, DisableClearable, FreeSolo>): React__default.JSX.Element;
|
|
216
|
+
|
|
201
217
|
/** @public */
|
|
202
218
|
declare const CatalogFilterLayout: {
|
|
203
219
|
(props: {
|
|
@@ -206,8 +222,8 @@ declare const CatalogFilterLayout: {
|
|
|
206
222
|
Filters: (props: {
|
|
207
223
|
children: React__default.ReactNode;
|
|
208
224
|
options?: {
|
|
209
|
-
drawerBreakpoint?:
|
|
210
|
-
drawerAnchor?:
|
|
225
|
+
drawerBreakpoint?: "xs" | "sm" | "md" | "lg" | "xl" | number;
|
|
226
|
+
drawerAnchor?: "left" | "right" | "top" | "bottom";
|
|
211
227
|
};
|
|
212
228
|
}) => React__default.JSX.Element;
|
|
213
229
|
Content: (props: {
|
|
@@ -426,23 +442,23 @@ interface EntityTableProps<T extends Entity> {
|
|
|
426
442
|
declare const EntityTable: {
|
|
427
443
|
<T extends Entity>(props: EntityTableProps<T>): React__default.JSX.Element;
|
|
428
444
|
columns: Readonly<{
|
|
429
|
-
createEntityRefColumn<
|
|
430
|
-
defaultKind?: string
|
|
431
|
-
}): TableColumn<
|
|
432
|
-
createEntityRelationColumn<
|
|
445
|
+
createEntityRefColumn<T extends Entity>(options: {
|
|
446
|
+
defaultKind?: string;
|
|
447
|
+
}): TableColumn<T>;
|
|
448
|
+
createEntityRelationColumn<T extends Entity>(options: {
|
|
433
449
|
title: string;
|
|
434
450
|
relation: string;
|
|
435
|
-
defaultKind?: string
|
|
451
|
+
defaultKind?: string;
|
|
436
452
|
filter?: {
|
|
437
453
|
kind: string;
|
|
438
|
-
}
|
|
439
|
-
}): TableColumn<
|
|
440
|
-
createOwnerColumn<
|
|
441
|
-
createDomainColumn<
|
|
442
|
-
createSystemColumn<
|
|
443
|
-
createMetadataDescriptionColumn<
|
|
444
|
-
createSpecLifecycleColumn<
|
|
445
|
-
createSpecTypeColumn<
|
|
454
|
+
};
|
|
455
|
+
}): TableColumn<T>;
|
|
456
|
+
createOwnerColumn<T extends Entity>(): TableColumn<T>;
|
|
457
|
+
createDomainColumn<T extends Entity>(): TableColumn<T>;
|
|
458
|
+
createSystemColumn<T extends Entity>(): TableColumn<T>;
|
|
459
|
+
createMetadataDescriptionColumn<T extends Entity>(): TableColumn<T>;
|
|
460
|
+
createSpecLifecycleColumn<T extends Entity>(): TableColumn<T>;
|
|
461
|
+
createSpecTypeColumn<T extends Entity>(): TableColumn<T>;
|
|
446
462
|
}>;
|
|
447
463
|
systemEntityColumns: TableColumn<_backstage_catalog_model.SystemEntity>[];
|
|
448
464
|
componentEntityColumns: TableColumn<_backstage_catalog_model.ComponentEntity>[];
|
|
@@ -453,20 +469,20 @@ declare const columnFactories: Readonly<{
|
|
|
453
469
|
createEntityRefColumn<T extends Entity>(options: {
|
|
454
470
|
defaultKind?: string;
|
|
455
471
|
}): TableColumn<T>;
|
|
456
|
-
createEntityRelationColumn<
|
|
472
|
+
createEntityRelationColumn<T extends Entity>(options: {
|
|
457
473
|
title: string;
|
|
458
474
|
relation: string;
|
|
459
475
|
defaultKind?: string;
|
|
460
476
|
filter?: {
|
|
461
477
|
kind: string;
|
|
462
478
|
};
|
|
463
|
-
}): TableColumn<
|
|
464
|
-
createOwnerColumn<
|
|
465
|
-
createDomainColumn<
|
|
466
|
-
createSystemColumn<
|
|
467
|
-
createMetadataDescriptionColumn<
|
|
468
|
-
createSpecLifecycleColumn<
|
|
469
|
-
createSpecTypeColumn<
|
|
479
|
+
}): TableColumn<T>;
|
|
480
|
+
createOwnerColumn<T extends Entity>(): TableColumn<T>;
|
|
481
|
+
createDomainColumn<T extends Entity>(): TableColumn<T>;
|
|
482
|
+
createSystemColumn<T extends Entity>(): TableColumn<T>;
|
|
483
|
+
createMetadataDescriptionColumn<T extends Entity>(): TableColumn<T>;
|
|
484
|
+
createSpecLifecycleColumn<T extends Entity>(): TableColumn<T>;
|
|
485
|
+
createSpecTypeColumn<T extends Entity>(): TableColumn<T>;
|
|
470
486
|
}>;
|
|
471
487
|
|
|
472
488
|
/** @public */
|
|
@@ -984,4 +1000,4 @@ declare function MockEntityListContextProvider<T extends DefaultEntityFilters =
|
|
|
984
1000
|
value?: Partial<EntityListContextProps<T>>;
|
|
985
1001
|
}>): React__default.JSX.Element;
|
|
986
1002
|
|
|
987
|
-
export { type AllowedEntityFilters, AsyncEntityProvider, type AsyncEntityProviderProps, type BackstageOverrides, CatalogFilterLayout, type CatalogReactComponentsNameToClassKey, type CatalogReactEntityAutocompletePickerClassKey, type CatalogReactEntityDisplayNameClassKey, type CatalogReactEntityLifecyclePickerClassKey, type CatalogReactEntityNamespacePickerClassKey, type CatalogReactEntityOwnerPickerClassKey, type CatalogReactEntityProcessingStatusPickerClassKey, type CatalogReactEntitySearchBarClassKey, type CatalogReactEntityTagPickerClassKey, type CatalogReactUserListPickerClassKey, type DefaultEntityFilters, DefaultFilters, type DefaultFiltersProps, EntityAutocompletePicker, type EntityAutocompletePickerProps, EntityDisplayName, type EntityDisplayNameProps, EntityErrorFilter, type EntityFilter, EntityKindFilter, EntityKindPicker, type EntityKindPickerProps, EntityLifecycleFilter, EntityLifecyclePicker, EntityListContext, type EntityListContextProps, type EntityListPagination, EntityListProvider, type EntityListProviderProps, type EntityLoadingStatus, EntityNamespaceFilter, EntityNamespacePicker, type EntityNamespacePickerProps, EntityOrphanFilter, EntityOwnerFilter, EntityOwnerPicker, type EntityOwnerPickerProps, EntityPeekAheadPopover, type EntityPeekAheadPopoverProps, type EntityPresentationApi, EntityProcessingStatusPicker, EntityProvider, type EntityProviderProps, EntityRefLink, type EntityRefLinkProps, EntityRefLinks, type EntityRefLinksProps, type EntityRefPresentation, type EntityRefPresentationSnapshot, EntitySearchBar, type EntitySourceLocation, EntityTable, type EntityTableProps, EntityTagFilter, EntityTagPicker, type EntityTagPickerProps, EntityTextFilter, EntityTypeFilter, EntityTypePicker, type EntityTypePickerProps, EntityUserFilter, FavoriteEntity, type FavoriteEntityProps, type FixedWidthFormControlLabelClassKey, InspectEntityDialog, MissingAnnotationEmptyState, type MissingAnnotationEmptyStateClassKey, MockEntityListContextProvider, MockStarredEntitiesApi, type PaginationMode, type StarredEntitiesApi, UnregisterEntityDialog, type UnregisterEntityDialogProps, UserListFilter, type UserListFilterKind, UserListPicker, type UserListPickerProps, catalogApiRef, columnFactories, defaultEntityPresentation, entityPresentationApiRef, entityRouteParams, entityRouteRef, getEntityRelations, getEntitySourceLocation, humanizeEntityRef, starredEntitiesApiRef, useAsyncEntity, useEntity, useEntityList, useEntityOwnership, useEntityPresentation, useEntityTypeFilter, useRelatedEntities, useStarredEntities, useStarredEntity };
|
|
1003
|
+
export { type AllowedEntityFilters, AsyncEntityProvider, type AsyncEntityProviderProps, type BackstageOverrides, CatalogAutocomplete, type CatalogAutocompleteProps, CatalogFilterLayout, type CatalogReactComponentsNameToClassKey, type CatalogReactEntityAutocompletePickerClassKey, type CatalogReactEntityDisplayNameClassKey, type CatalogReactEntityLifecyclePickerClassKey, type CatalogReactEntityNamespacePickerClassKey, type CatalogReactEntityOwnerPickerClassKey, type CatalogReactEntityProcessingStatusPickerClassKey, type CatalogReactEntitySearchBarClassKey, type CatalogReactEntityTagPickerClassKey, type CatalogReactUserListPickerClassKey, type DefaultEntityFilters, DefaultFilters, type DefaultFiltersProps, EntityAutocompletePicker, type EntityAutocompletePickerProps, EntityDisplayName, type EntityDisplayNameProps, EntityErrorFilter, type EntityFilter, EntityKindFilter, EntityKindPicker, type EntityKindPickerProps, EntityLifecycleFilter, EntityLifecyclePicker, EntityListContext, type EntityListContextProps, type EntityListPagination, EntityListProvider, type EntityListProviderProps, type EntityLoadingStatus, EntityNamespaceFilter, EntityNamespacePicker, type EntityNamespacePickerProps, EntityOrphanFilter, EntityOwnerFilter, EntityOwnerPicker, type EntityOwnerPickerProps, EntityPeekAheadPopover, type EntityPeekAheadPopoverProps, type EntityPresentationApi, EntityProcessingStatusPicker, EntityProvider, type EntityProviderProps, EntityRefLink, type EntityRefLinkProps, EntityRefLinks, type EntityRefLinksProps, type EntityRefPresentation, type EntityRefPresentationSnapshot, EntitySearchBar, type EntitySourceLocation, EntityTable, type EntityTableProps, EntityTagFilter, EntityTagPicker, type EntityTagPickerProps, EntityTextFilter, EntityTypeFilter, EntityTypePicker, type EntityTypePickerProps, EntityUserFilter, FavoriteEntity, type FavoriteEntityProps, type FixedWidthFormControlLabelClassKey, InspectEntityDialog, MissingAnnotationEmptyState, type MissingAnnotationEmptyStateClassKey, MockEntityListContextProvider, MockStarredEntitiesApi, type PaginationMode, type StarredEntitiesApi, UnregisterEntityDialog, type UnregisterEntityDialogProps, UserListFilter, type UserListFilterKind, UserListPicker, type 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
|
@@ -5,6 +5,7 @@ export { defaultEntityPresentation } from './apis/EntityPresentationApi/defaultE
|
|
|
5
5
|
export { useEntityPresentation } from './apis/EntityPresentationApi/useEntityPresentation.esm.js';
|
|
6
6
|
export { starredEntitiesApiRef } from './apis/StarredEntitiesApi/StarredEntitiesApi.esm.js';
|
|
7
7
|
export { MockStarredEntitiesApi } from './apis/StarredEntitiesApi/MockStarredEntitiesApi.esm.js';
|
|
8
|
+
export { CatalogAutocomplete } from './components/CatalogAutocomplete/CatalogAutocomplete.esm.js';
|
|
8
9
|
export { CatalogFilterLayout } from './components/CatalogFilterLayout/CatalogFilterLayout.esm.js';
|
|
9
10
|
export { DefaultFilters } from './components/DefaultFilters/DefaultFilters.esm.js';
|
|
10
11
|
export { EntityKindPicker } from './components/EntityKindPicker/EntityKindPicker.esm.js';
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-catalog-react",
|
|
3
|
-
"version": "1.16.0-next.
|
|
3
|
+
"version": "1.16.0-next.2",
|
|
4
4
|
"description": "A frontend library that helps other Backstage plugins interact with the catalog",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "web-library",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"types": "./dist/index.d.ts",
|
|
50
50
|
"typesVersions": {
|
|
51
51
|
"*": {
|
|
52
|
-
"
|
|
52
|
+
"*": [
|
|
53
53
|
"dist/index.d.ts"
|
|
54
54
|
],
|
|
55
55
|
"alpha": [
|
|
@@ -75,13 +75,13 @@
|
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@backstage/catalog-client": "1.9.1",
|
|
77
77
|
"@backstage/catalog-model": "1.7.3",
|
|
78
|
-
"@backstage/core-compat-api": "0.
|
|
79
|
-
"@backstage/core-components": "0.16.
|
|
78
|
+
"@backstage/core-compat-api": "0.4.0-next.2",
|
|
79
|
+
"@backstage/core-components": "0.16.5-next.1",
|
|
80
80
|
"@backstage/core-plugin-api": "1.10.4",
|
|
81
81
|
"@backstage/errors": "1.2.7",
|
|
82
|
-
"@backstage/frontend-plugin-api": "0.
|
|
83
|
-
"@backstage/frontend-test-utils": "0.
|
|
84
|
-
"@backstage/integration-react": "1.2.
|
|
82
|
+
"@backstage/frontend-plugin-api": "0.10.0-next.2",
|
|
83
|
+
"@backstage/frontend-test-utils": "0.3.0-next.2",
|
|
84
|
+
"@backstage/integration-react": "1.2.5-next.0",
|
|
85
85
|
"@backstage/plugin-catalog-common": "1.1.3",
|
|
86
86
|
"@backstage/plugin-permission-common": "0.8.4",
|
|
87
87
|
"@backstage/plugin-permission-react": "0.4.31",
|
|
@@ -100,11 +100,11 @@
|
|
|
100
100
|
"zen-observable": "^0.10.0"
|
|
101
101
|
},
|
|
102
102
|
"devDependencies": {
|
|
103
|
-
"@backstage/cli": "0.
|
|
104
|
-
"@backstage/core-app-api": "1.
|
|
103
|
+
"@backstage/cli": "0.31.0-next.1",
|
|
104
|
+
"@backstage/core-app-api": "1.16.0-next.0",
|
|
105
105
|
"@backstage/plugin-catalog-common": "1.1.3",
|
|
106
|
-
"@backstage/plugin-scaffolder-common": "1.5.
|
|
107
|
-
"@backstage/test-utils": "1.7.
|
|
106
|
+
"@backstage/plugin-scaffolder-common": "1.5.10-next.0",
|
|
107
|
+
"@backstage/test-utils": "1.7.6-next.0",
|
|
108
108
|
"@testing-library/dom": "^10.0.0",
|
|
109
109
|
"@testing-library/jest-dom": "^6.0.0",
|
|
110
110
|
"@testing-library/react": "^16.0.0",
|
|
@@ -114,7 +114,8 @@
|
|
|
114
114
|
"react": "^18.0.2",
|
|
115
115
|
"react-dom": "^18.0.2",
|
|
116
116
|
"react-router-dom": "^6.3.0",
|
|
117
|
-
"react-test-renderer": "^16.13.1"
|
|
117
|
+
"react-test-renderer": "^16.13.1",
|
|
118
|
+
"zod": "^3.22.4"
|
|
118
119
|
},
|
|
119
120
|
"peerDependencies": {
|
|
120
121
|
"@types/react": "^17.0.0 || ^18.0.0",
|