@backstage/plugin-catalog-react 1.12.0-next.2 → 1.12.1-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -2
- package/alpha/package.json +1 -1
- package/dist/alpha.esm.js +4 -6
- package/dist/alpha.esm.js.map +1 -1
- package/dist/apis/EntityPresentationApi/defaultEntityPresentation.esm.js +3 -4
- package/dist/apis/EntityPresentationApi/defaultEntityPresentation.esm.js.map +1 -1
- package/dist/apis/EntityPresentationApi/useUpdatingObservable.esm.js +3 -3
- package/dist/apis/EntityPresentationApi/useUpdatingObservable.esm.js.map +1 -1
- package/dist/apis/StarredEntitiesApi/MockStarredEntitiesApi.esm.js +9 -17
- package/dist/apis/StarredEntitiesApi/MockStarredEntitiesApi.esm.js.map +1 -1
- package/dist/components/CatalogFilterLayout/CatalogFilterLayout.esm.js +2 -6
- package/dist/components/CatalogFilterLayout/CatalogFilterLayout.esm.js.map +1 -1
- package/dist/components/EntityAutocompletePicker/EntityAutocompletePicker.esm.js +2 -3
- package/dist/components/EntityAutocompletePicker/EntityAutocompletePicker.esm.js.map +1 -1
- package/dist/components/EntityAutocompletePicker/EntityAutocompletePickerOption.esm.js +1 -1
- package/dist/components/EntityAutocompletePicker/EntityAutocompletePickerOption.esm.js.map +1 -1
- package/dist/components/EntityKindPicker/EntityKindPicker.esm.js +4 -6
- package/dist/components/EntityKindPicker/EntityKindPicker.esm.js.map +1 -1
- package/dist/components/EntityKindPicker/kindFilterUtils.esm.js +2 -5
- package/dist/components/EntityKindPicker/kindFilterUtils.esm.js.map +1 -1
- package/dist/components/EntityOwnerPicker/EntityOwnerPicker.esm.js +4 -5
- package/dist/components/EntityOwnerPicker/EntityOwnerPicker.esm.js.map +1 -1
- package/dist/components/EntityOwnerPicker/useFacetsEntities.esm.js +2 -4
- package/dist/components/EntityOwnerPicker/useFacetsEntities.esm.js.map +1 -1
- package/dist/components/EntityOwnerPicker/useQueryEntities.esm.js +1 -2
- package/dist/components/EntityOwnerPicker/useQueryEntities.esm.js.map +1 -1
- package/dist/components/EntityPeekAheadPopover/CardActionComponents/GroupCardActions.esm.js +1 -2
- package/dist/components/EntityPeekAheadPopover/CardActionComponents/GroupCardActions.esm.js.map +1 -1
- package/dist/components/EntityPeekAheadPopover/CardActionComponents/UserCardActions.esm.js +1 -2
- package/dist/components/EntityPeekAheadPopover/CardActionComponents/UserCardActions.esm.js.map +1 -1
- package/dist/components/EntityPeekAheadPopover/EntityPeekAheadPopover.esm.js +2 -3
- package/dist/components/EntityPeekAheadPopover/EntityPeekAheadPopover.esm.js.map +1 -1
- package/dist/components/EntityRefLink/EntityRefLink.esm.js +2 -4
- package/dist/components/EntityRefLink/EntityRefLink.esm.js.map +1 -1
- package/dist/components/EntityRefLink/humanize.esm.js +3 -3
- package/dist/components/EntityRefLink/humanize.esm.js.map +1 -1
- package/dist/components/EntitySearchBar/EntitySearchBar.esm.js +1 -1
- package/dist/components/EntitySearchBar/EntitySearchBar.esm.js.map +1 -1
- package/dist/components/EntityTable/columns.esm.js +9 -13
- package/dist/components/EntityTable/columns.esm.js.map +1 -1
- package/dist/components/EntityTypePicker/EntityTypePicker.esm.js +1 -2
- package/dist/components/EntityTypePicker/EntityTypePicker.esm.js.map +1 -1
- package/dist/components/InspectEntityDialog/components/AncestryPage.esm.js +2 -2
- package/dist/components/InspectEntityDialog/components/AncestryPage.esm.js.map +1 -1
- package/dist/components/InspectEntityDialog/components/ColocatedPage.esm.js +6 -13
- package/dist/components/InspectEntityDialog/components/ColocatedPage.esm.js.map +1 -1
- package/dist/components/InspectEntityDialog/components/OverviewPage.esm.js +4 -5
- package/dist/components/InspectEntityDialog/components/OverviewPage.esm.js.map +1 -1
- package/dist/components/MissingAnnotationEmptyState/MissingAnnotationEmptyState.esm.js +5 -6
- package/dist/components/MissingAnnotationEmptyState/MissingAnnotationEmptyState.esm.js.map +1 -1
- package/dist/components/UnregisterEntityDialog/UnregisterEntityDialog.esm.js +2 -4
- package/dist/components/UnregisterEntityDialog/UnregisterEntityDialog.esm.js.map +1 -1
- package/dist/components/UnregisterEntityDialog/useUnregisterEntityDialogState.esm.js +1 -2
- package/dist/components/UnregisterEntityDialog/useUnregisterEntityDialogState.esm.js.map +1 -1
- package/dist/components/UserListPicker/UserListPicker.esm.js +21 -25
- package/dist/components/UserListPicker/UserListPicker.esm.js.map +1 -1
- package/dist/components/UserListPicker/useOwnedEntitiesCount.esm.js +2 -3
- package/dist/components/UserListPicker/useOwnedEntitiesCount.esm.js.map +1 -1
- package/dist/filters.esm.js +10 -26
- package/dist/filters.esm.js.map +1 -1
- package/dist/hooks/useEntityListProvider.esm.js +5 -8
- package/dist/hooks/useEntityListProvider.esm.js.map +1 -1
- package/dist/hooks/useEntityOwnership.esm.js +1 -1
- package/dist/hooks/useEntityOwnership.esm.js.map +1 -1
- package/dist/hooks/useEntityTypeFilter.esm.js +2 -3
- package/dist/hooks/useEntityTypeFilter.esm.js.map +1 -1
- package/dist/hooks/useRelatedEntities.esm.js +4 -6
- package/dist/hooks/useRelatedEntities.esm.js.map +1 -1
- package/dist/routes.esm.js +1 -2
- package/dist/routes.esm.js.map +1 -1
- package/dist/testUtils/providers.esm.js +11 -15
- package/dist/testUtils/providers.esm.js.map +1 -1
- package/dist/utils/filters.esm.js +2 -4
- package/dist/utils/filters.esm.js.map +1 -1
- package/dist/utils/getEntityRelations.esm.js +2 -3
- package/dist/utils/getEntityRelations.esm.js.map +1 -1
- package/dist/utils/getEntitySourceLocation.esm.js +2 -3
- package/dist/utils/getEntitySourceLocation.esm.js.map +1 -1
- package/package.json +12 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-react
|
|
2
2
|
|
|
3
|
+
## 1.12.1-next.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/core-components@0.14.8-next.0
|
|
9
|
+
- @backstage/catalog-client@1.6.5
|
|
10
|
+
- @backstage/catalog-model@1.5.0
|
|
11
|
+
- @backstage/core-plugin-api@1.9.2
|
|
12
|
+
- @backstage/errors@1.2.4
|
|
13
|
+
- @backstage/frontend-plugin-api@0.6.6-next.0
|
|
14
|
+
- @backstage/integration-react@1.1.27
|
|
15
|
+
- @backstage/types@1.1.1
|
|
16
|
+
- @backstage/version-bridge@1.0.8
|
|
17
|
+
- @backstage/plugin-catalog-common@1.0.23
|
|
18
|
+
- @backstage/plugin-permission-common@0.7.13
|
|
19
|
+
- @backstage/plugin-permission-react@0.4.22
|
|
20
|
+
|
|
21
|
+
## 1.12.0
|
|
22
|
+
|
|
23
|
+
### Minor Changes
|
|
24
|
+
|
|
25
|
+
- 8834daf: Updated the presentation API to return a promise, in addition to the snapshot and observable that were there before. This makes it much easier to consume the API in a non-React context.
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- Updated dependencies
|
|
30
|
+
- @backstage/core-components@0.14.7
|
|
31
|
+
- @backstage/catalog-model@1.5.0
|
|
32
|
+
- @backstage/catalog-client@1.6.5
|
|
33
|
+
- @backstage/frontend-plugin-api@0.6.5
|
|
34
|
+
- @backstage/integration-react@1.1.27
|
|
35
|
+
- @backstage/plugin-catalog-common@1.0.23
|
|
36
|
+
|
|
3
37
|
## 1.12.0-next.2
|
|
4
38
|
|
|
5
39
|
### Minor Changes
|
|
@@ -2945,8 +2979,7 @@
|
|
|
2945
2979
|
`CatalogPage` component in your `App.tsx` routing allows you to adjust the
|
|
2946
2980
|
layout, header, and which filters are available.
|
|
2947
2981
|
|
|
2948
|
-
See the documentation added on [Catalog
|
|
2949
|
-
Customization](https://backstage.io/docs/features/software-catalog/catalog-customization)
|
|
2982
|
+
See the documentation added on [Catalog Customization](https://backstage.io/docs/features/software-catalog/catalog-customization)
|
|
2950
2983
|
for instructions.
|
|
2951
2984
|
|
|
2952
2985
|
### Patch Changes
|
package/alpha/package.json
CHANGED
package/dist/alpha.esm.js
CHANGED
|
@@ -16,7 +16,6 @@ const catalogExtensionData = {
|
|
|
16
16
|
)
|
|
17
17
|
};
|
|
18
18
|
function createEntityCardExtension(options) {
|
|
19
|
-
var _a, _b;
|
|
20
19
|
const configSchema = "configSchema" in options ? options.configSchema : createSchemaFromZod(
|
|
21
20
|
(z) => z.object({
|
|
22
21
|
filter: z.string().optional()
|
|
@@ -26,11 +25,11 @@ function createEntityCardExtension(options) {
|
|
|
26
25
|
kind: "entity-card",
|
|
27
26
|
namespace: options.namespace,
|
|
28
27
|
name: options.name,
|
|
29
|
-
attachTo:
|
|
28
|
+
attachTo: options.attachTo ?? {
|
|
30
29
|
id: "entity-content:catalog/overview",
|
|
31
30
|
input: "cards"
|
|
32
31
|
},
|
|
33
|
-
disabled:
|
|
32
|
+
disabled: options.disabled ?? true,
|
|
34
33
|
output: {
|
|
35
34
|
element: coreExtensionData.reactElement,
|
|
36
35
|
filterFunction: catalogExtensionData.entityFilterFunction.optional(),
|
|
@@ -50,16 +49,15 @@ function createEntityCardExtension(options) {
|
|
|
50
49
|
});
|
|
51
50
|
}
|
|
52
51
|
function createEntityContentExtension(options) {
|
|
53
|
-
var _a, _b;
|
|
54
52
|
return createExtension({
|
|
55
53
|
kind: "entity-content",
|
|
56
54
|
namespace: options.namespace,
|
|
57
55
|
name: options.name,
|
|
58
|
-
attachTo:
|
|
56
|
+
attachTo: options.attachTo ?? {
|
|
59
57
|
id: "page:catalog/entity",
|
|
60
58
|
input: "contents"
|
|
61
59
|
},
|
|
62
|
-
disabled:
|
|
60
|
+
disabled: options.disabled ?? true,
|
|
63
61
|
output: {
|
|
64
62
|
element: coreExtensionData.reactElement,
|
|
65
63
|
path: coreExtensionData.routePath,
|
package/dist/alpha.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alpha.esm.js","sources":["../src/alpha.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 {\n AnyExtensionInputMap,\n ExtensionBoundary,\n PortableSchema,\n ResolvedExtensionInputs,\n RouteRef,\n coreExtensionData,\n createExtension,\n createExtensionDataRef,\n createSchemaFromZod,\n} from '@backstage/frontend-plugin-api';\nimport React, { lazy } from 'react';\nimport { Entity } from '@backstage/catalog-model';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { Expand } from '../../../packages/frontend-plugin-api/src/types';\n\nexport { useEntityPermission } from './hooks/useEntityPermission';\nexport { isOwnerOf } from './utils';\n\n/** @alpha */\nexport const catalogExtensionData = {\n entityContentTitle: createExtensionDataRef<string>(\n 'catalog.entity-content-title',\n ),\n entityFilterFunction: createExtensionDataRef<(entity: Entity) => boolean>(\n 'catalog.entity-filter-function',\n ),\n entityFilterExpression: createExtensionDataRef<string>(\n 'catalog.entity-filter-expression',\n ),\n};\n\n// TODO: Figure out how to merge with provided config schema\n/** @alpha */\nexport function createEntityCardExtension<\n TConfig extends { filter?: string },\n TInputs extends AnyExtensionInputMap,\n>(options: {\n namespace?: string;\n name?: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n configSchema?: PortableSchema<TConfig>;\n filter?:\n | typeof catalogExtensionData.entityFilterFunction.T\n | typeof catalogExtensionData.entityFilterExpression.T;\n loader: (options: {\n config: TConfig;\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }) => Promise<JSX.Element>;\n}) {\n const configSchema =\n 'configSchema' in options\n ? options.configSchema\n : (createSchemaFromZod(z =>\n z.object({\n filter: z.string().optional(),\n }),\n ) as PortableSchema<TConfig>);\n return createExtension({\n kind: 'entity-card',\n namespace: options.namespace,\n name: options.name,\n attachTo: options.attachTo ?? {\n id: 'entity-content:catalog/overview',\n input: 'cards',\n },\n disabled: options.disabled ?? true,\n output: {\n element: coreExtensionData.reactElement,\n filterFunction: catalogExtensionData.entityFilterFunction.optional(),\n filterExpression: catalogExtensionData.entityFilterExpression.optional(),\n },\n inputs: options.inputs,\n configSchema,\n factory({ config, inputs, node }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ inputs, config })\n .then(element => ({ default: () => element })),\n );\n\n return {\n element: (\n <ExtensionBoundary node={node}>\n <ExtensionComponent />\n </ExtensionBoundary>\n ),\n ...mergeFilters({ config, options }),\n };\n },\n });\n}\n\n/** @alpha */\nexport function createEntityContentExtension<\n TInputs extends AnyExtensionInputMap,\n>(options: {\n namespace?: string;\n name?: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n routeRef?: RouteRef;\n defaultPath: string;\n defaultTitle: string;\n filter?:\n | typeof catalogExtensionData.entityFilterFunction.T\n | typeof catalogExtensionData.entityFilterExpression.T;\n loader: (options: {\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }) => Promise<JSX.Element>;\n}) {\n return createExtension({\n kind: 'entity-content',\n namespace: options.namespace,\n name: options.name,\n attachTo: options.attachTo ?? {\n id: 'page:catalog/entity',\n input: 'contents',\n },\n disabled: options.disabled ?? true,\n output: {\n element: coreExtensionData.reactElement,\n path: coreExtensionData.routePath,\n routeRef: coreExtensionData.routeRef.optional(),\n title: catalogExtensionData.entityContentTitle,\n filterFunction: catalogExtensionData.entityFilterFunction.optional(),\n filterExpression: catalogExtensionData.entityFilterExpression.optional(),\n },\n inputs: options.inputs,\n configSchema: createSchemaFromZod(z =>\n z.object({\n path: z.string().default(options.defaultPath),\n title: z.string().default(options.defaultTitle),\n filter: z.string().optional(),\n }),\n ),\n factory({ config, inputs, node }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ inputs })\n .then(element => ({ default: () => element })),\n );\n\n return {\n path: config.path,\n title: config.title,\n routeRef: options.routeRef,\n element: (\n <ExtensionBoundary node={node} routable>\n <ExtensionComponent />\n </ExtensionBoundary>\n ),\n ...mergeFilters({ config, options }),\n };\n },\n });\n}\n\n/**\n * Decides what filter outputs to produce, given some options and config\n */\nfunction mergeFilters(inputs: {\n options: {\n filter?:\n | typeof catalogExtensionData.entityFilterFunction.T\n | typeof catalogExtensionData.entityFilterExpression.T;\n };\n config: {\n filter?: string;\n };\n}): {\n filterFunction?: typeof catalogExtensionData.entityFilterFunction.T;\n filterExpression?: typeof catalogExtensionData.entityFilterExpression.T;\n} {\n const { options, config } = inputs;\n if (config.filter) {\n return { filterExpression: config.filter };\n } else if (typeof options.filter === 'string') {\n return { filterExpression: options.filter };\n } else if (typeof options.filter === 'function') {\n return { filterFunction: options.filter };\n }\n return {};\n}\n"],"names":[],"mappings":";;;;;;AAoCO,MAAM,oBAAuB,GAAA;AAAA,EAClC,kBAAoB,EAAA,sBAAA;AAAA,IAClB,8BAAA;AAAA,GACF;AAAA,EACA,oBAAsB,EAAA,sBAAA;AAAA,IACpB,gCAAA;AAAA,GACF;AAAA,EACA,sBAAwB,EAAA,sBAAA;AAAA,IACtB,kCAAA;AAAA,GACF;AACF,EAAA;AAIO,SAAS,0BAGd,OAcC,EAAA;
|
|
1
|
+
{"version":3,"file":"alpha.esm.js","sources":["../src/alpha.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 {\n AnyExtensionInputMap,\n ExtensionBoundary,\n PortableSchema,\n ResolvedExtensionInputs,\n RouteRef,\n coreExtensionData,\n createExtension,\n createExtensionDataRef,\n createSchemaFromZod,\n} from '@backstage/frontend-plugin-api';\nimport React, { lazy } from 'react';\nimport { Entity } from '@backstage/catalog-model';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { Expand } from '../../../packages/frontend-plugin-api/src/types';\n\nexport { useEntityPermission } from './hooks/useEntityPermission';\nexport { isOwnerOf } from './utils';\n\n/** @alpha */\nexport const catalogExtensionData = {\n entityContentTitle: createExtensionDataRef<string>(\n 'catalog.entity-content-title',\n ),\n entityFilterFunction: createExtensionDataRef<(entity: Entity) => boolean>(\n 'catalog.entity-filter-function',\n ),\n entityFilterExpression: createExtensionDataRef<string>(\n 'catalog.entity-filter-expression',\n ),\n};\n\n// TODO: Figure out how to merge with provided config schema\n/** @alpha */\nexport function createEntityCardExtension<\n TConfig extends { filter?: string },\n TInputs extends AnyExtensionInputMap,\n>(options: {\n namespace?: string;\n name?: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n configSchema?: PortableSchema<TConfig>;\n filter?:\n | typeof catalogExtensionData.entityFilterFunction.T\n | typeof catalogExtensionData.entityFilterExpression.T;\n loader: (options: {\n config: TConfig;\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }) => Promise<JSX.Element>;\n}) {\n const configSchema =\n 'configSchema' in options\n ? options.configSchema\n : (createSchemaFromZod(z =>\n z.object({\n filter: z.string().optional(),\n }),\n ) as PortableSchema<TConfig>);\n return createExtension({\n kind: 'entity-card',\n namespace: options.namespace,\n name: options.name,\n attachTo: options.attachTo ?? {\n id: 'entity-content:catalog/overview',\n input: 'cards',\n },\n disabled: options.disabled ?? true,\n output: {\n element: coreExtensionData.reactElement,\n filterFunction: catalogExtensionData.entityFilterFunction.optional(),\n filterExpression: catalogExtensionData.entityFilterExpression.optional(),\n },\n inputs: options.inputs,\n configSchema,\n factory({ config, inputs, node }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ inputs, config })\n .then(element => ({ default: () => element })),\n );\n\n return {\n element: (\n <ExtensionBoundary node={node}>\n <ExtensionComponent />\n </ExtensionBoundary>\n ),\n ...mergeFilters({ config, options }),\n };\n },\n });\n}\n\n/** @alpha */\nexport function createEntityContentExtension<\n TInputs extends AnyExtensionInputMap,\n>(options: {\n namespace?: string;\n name?: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n routeRef?: RouteRef;\n defaultPath: string;\n defaultTitle: string;\n filter?:\n | typeof catalogExtensionData.entityFilterFunction.T\n | typeof catalogExtensionData.entityFilterExpression.T;\n loader: (options: {\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }) => Promise<JSX.Element>;\n}) {\n return createExtension({\n kind: 'entity-content',\n namespace: options.namespace,\n name: options.name,\n attachTo: options.attachTo ?? {\n id: 'page:catalog/entity',\n input: 'contents',\n },\n disabled: options.disabled ?? true,\n output: {\n element: coreExtensionData.reactElement,\n path: coreExtensionData.routePath,\n routeRef: coreExtensionData.routeRef.optional(),\n title: catalogExtensionData.entityContentTitle,\n filterFunction: catalogExtensionData.entityFilterFunction.optional(),\n filterExpression: catalogExtensionData.entityFilterExpression.optional(),\n },\n inputs: options.inputs,\n configSchema: createSchemaFromZod(z =>\n z.object({\n path: z.string().default(options.defaultPath),\n title: z.string().default(options.defaultTitle),\n filter: z.string().optional(),\n }),\n ),\n factory({ config, inputs, node }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ inputs })\n .then(element => ({ default: () => element })),\n );\n\n return {\n path: config.path,\n title: config.title,\n routeRef: options.routeRef,\n element: (\n <ExtensionBoundary node={node} routable>\n <ExtensionComponent />\n </ExtensionBoundary>\n ),\n ...mergeFilters({ config, options }),\n };\n },\n });\n}\n\n/**\n * Decides what filter outputs to produce, given some options and config\n */\nfunction mergeFilters(inputs: {\n options: {\n filter?:\n | typeof catalogExtensionData.entityFilterFunction.T\n | typeof catalogExtensionData.entityFilterExpression.T;\n };\n config: {\n filter?: string;\n };\n}): {\n filterFunction?: typeof catalogExtensionData.entityFilterFunction.T;\n filterExpression?: typeof catalogExtensionData.entityFilterExpression.T;\n} {\n const { options, config } = inputs;\n if (config.filter) {\n return { filterExpression: config.filter };\n } else if (typeof options.filter === 'string') {\n return { filterExpression: options.filter };\n } else if (typeof options.filter === 'function') {\n return { filterFunction: options.filter };\n }\n return {};\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -66,12 +66,11 @@ function getParts(entityOrRef) {
|
|
|
66
66
|
return {};
|
|
67
67
|
}
|
|
68
68
|
function getShortRef(options) {
|
|
69
|
-
|
|
70
|
-
const kind = ((_a = options.kind) == null ? void 0 : _a.toLocaleLowerCase("en-US")) || "unknown";
|
|
69
|
+
const kind = options.kind?.toLocaleLowerCase("en-US") || "unknown";
|
|
71
70
|
const namespace = options.namespace || DEFAULT_NAMESPACE;
|
|
72
71
|
const name = options.name || "unknown";
|
|
73
|
-
const defaultKindLower =
|
|
74
|
-
const defaultNamespaceLower =
|
|
72
|
+
const defaultKindLower = options.context?.defaultKind?.toLocaleLowerCase("en-US");
|
|
73
|
+
const defaultNamespaceLower = options.context?.defaultNamespace?.toLocaleLowerCase("en-US");
|
|
75
74
|
let result = name;
|
|
76
75
|
if (defaultNamespaceLower && namespace.toLocaleLowerCase("en-US") !== defaultNamespaceLower || namespace !== DEFAULT_NAMESPACE) {
|
|
77
76
|
result = `${namespace}/${result}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultEntityPresentation.esm.js","sources":["../../../src/apis/EntityPresentationApi/defaultEntityPresentation.ts"],"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 {\n CompoundEntityRef,\n DEFAULT_NAMESPACE,\n Entity,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport get from 'lodash/get';\nimport { EntityRefPresentationSnapshot } from './EntityPresentationApi';\n\n/**\n * This returns the default representation of an entity.\n *\n * @public\n * @param entityOrRef - Either an entity, or a ref to it.\n * @param context - Contextual information that may affect the presentation.\n */\nexport function defaultEntityPresentation(\n entityOrRef: Entity | CompoundEntityRef | string,\n context?: {\n defaultKind?: string;\n defaultNamespace?: string;\n },\n): EntityRefPresentationSnapshot {\n // NOTE(freben): This code may look convoluted, but it tries its very best to\n // be defensive and handling any type of malformed input and still producing\n // some form of result without crashing.\n const { kind, namespace, name, title, description, displayName, type } =\n getParts(entityOrRef);\n\n const entityRef: string = stringifyEntityRef({\n kind: kind || 'unknown',\n namespace: namespace || DEFAULT_NAMESPACE,\n name: name || 'unknown',\n });\n\n const shortRef = getShortRef({ kind, namespace, name, context });\n\n const primary = [displayName, title, shortRef].find(\n candidate => candidate && typeof candidate === 'string',\n )!;\n\n const secondary = [\n primary !== entityRef ? entityRef : undefined,\n type,\n description,\n ]\n .filter(candidate => candidate && typeof candidate === 'string')\n .join(' | ');\n\n return {\n entityRef,\n primaryTitle: primary,\n secondaryTitle: secondary || undefined,\n Icon: undefined, // leave it up to the presentation API to handle\n };\n}\n\n// Try to extract display-worthy parts of an entity or ref as best we can, without throwing\nfunction getParts(entityOrRef: Entity | CompoundEntityRef | string): {\n kind?: string;\n namespace?: string;\n name?: string;\n title?: string;\n description?: string;\n displayName?: string;\n type?: string;\n} {\n if (typeof entityOrRef === 'string') {\n let colonI = entityOrRef.indexOf(':');\n const slashI = entityOrRef.indexOf('/');\n\n // If the / is ahead of the :, treat the rest as the name\n if (slashI !== -1 && slashI < colonI) {\n colonI = -1;\n }\n\n const kind = colonI === -1 ? undefined : entityOrRef.slice(0, colonI);\n const namespace =\n slashI === -1 ? undefined : entityOrRef.slice(colonI + 1, slashI);\n const name = entityOrRef.slice(Math.max(colonI + 1, slashI + 1));\n\n return { kind, namespace, name };\n }\n\n if (typeof entityOrRef === 'object' && entityOrRef !== null) {\n const kind = [get(entityOrRef, 'kind')].find(\n candidate => candidate && typeof candidate === 'string',\n );\n\n const namespace = [\n get(entityOrRef, 'metadata.namespace'),\n get(entityOrRef, 'namespace'),\n ].find(candidate => candidate && typeof candidate === 'string');\n\n const name = [\n get(entityOrRef, 'metadata.name'),\n get(entityOrRef, 'name'),\n ].find(candidate => candidate && typeof candidate === 'string');\n\n const title = [get(entityOrRef, 'metadata.title')].find(\n candidate => candidate && typeof candidate === 'string',\n );\n\n const description = [get(entityOrRef, 'metadata.description')].find(\n candidate => candidate && typeof candidate === 'string',\n );\n\n const displayName = [get(entityOrRef, 'spec.profile.displayName')].find(\n candidate => candidate && typeof candidate === 'string',\n );\n\n const type = [get(entityOrRef, 'spec.type')].find(\n candidate => candidate && typeof candidate === 'string',\n );\n\n return { kind, namespace, name, title, description, displayName, type };\n }\n\n return {};\n}\n\nfunction getShortRef(options: {\n kind?: string;\n namespace?: string;\n name?: string;\n context?: { defaultKind?: string; defaultNamespace?: string };\n}): string {\n const kind = options.kind?.toLocaleLowerCase('en-US') || 'unknown';\n const namespace = options.namespace || DEFAULT_NAMESPACE;\n const name = options.name || 'unknown';\n const defaultKindLower =\n options.context?.defaultKind?.toLocaleLowerCase('en-US');\n const defaultNamespaceLower =\n options.context?.defaultNamespace?.toLocaleLowerCase('en-US');\n\n let result = name;\n\n if (\n (defaultNamespaceLower &&\n namespace.toLocaleLowerCase('en-US') !== defaultNamespaceLower) ||\n namespace !== DEFAULT_NAMESPACE\n ) {\n result = `${namespace}/${result}`;\n }\n\n if (\n defaultKindLower &&\n kind.toLocaleLowerCase('en-US') !== defaultKindLower\n ) {\n result = `${kind}:${result}`;\n }\n\n return result;\n}\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"defaultEntityPresentation.esm.js","sources":["../../../src/apis/EntityPresentationApi/defaultEntityPresentation.ts"],"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 {\n CompoundEntityRef,\n DEFAULT_NAMESPACE,\n Entity,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport get from 'lodash/get';\nimport { EntityRefPresentationSnapshot } from './EntityPresentationApi';\n\n/**\n * This returns the default representation of an entity.\n *\n * @public\n * @param entityOrRef - Either an entity, or a ref to it.\n * @param context - Contextual information that may affect the presentation.\n */\nexport function defaultEntityPresentation(\n entityOrRef: Entity | CompoundEntityRef | string,\n context?: {\n defaultKind?: string;\n defaultNamespace?: string;\n },\n): EntityRefPresentationSnapshot {\n // NOTE(freben): This code may look convoluted, but it tries its very best to\n // be defensive and handling any type of malformed input and still producing\n // some form of result without crashing.\n const { kind, namespace, name, title, description, displayName, type } =\n getParts(entityOrRef);\n\n const entityRef: string = stringifyEntityRef({\n kind: kind || 'unknown',\n namespace: namespace || DEFAULT_NAMESPACE,\n name: name || 'unknown',\n });\n\n const shortRef = getShortRef({ kind, namespace, name, context });\n\n const primary = [displayName, title, shortRef].find(\n candidate => candidate && typeof candidate === 'string',\n )!;\n\n const secondary = [\n primary !== entityRef ? entityRef : undefined,\n type,\n description,\n ]\n .filter(candidate => candidate && typeof candidate === 'string')\n .join(' | ');\n\n return {\n entityRef,\n primaryTitle: primary,\n secondaryTitle: secondary || undefined,\n Icon: undefined, // leave it up to the presentation API to handle\n };\n}\n\n// Try to extract display-worthy parts of an entity or ref as best we can, without throwing\nfunction getParts(entityOrRef: Entity | CompoundEntityRef | string): {\n kind?: string;\n namespace?: string;\n name?: string;\n title?: string;\n description?: string;\n displayName?: string;\n type?: string;\n} {\n if (typeof entityOrRef === 'string') {\n let colonI = entityOrRef.indexOf(':');\n const slashI = entityOrRef.indexOf('/');\n\n // If the / is ahead of the :, treat the rest as the name\n if (slashI !== -1 && slashI < colonI) {\n colonI = -1;\n }\n\n const kind = colonI === -1 ? undefined : entityOrRef.slice(0, colonI);\n const namespace =\n slashI === -1 ? undefined : entityOrRef.slice(colonI + 1, slashI);\n const name = entityOrRef.slice(Math.max(colonI + 1, slashI + 1));\n\n return { kind, namespace, name };\n }\n\n if (typeof entityOrRef === 'object' && entityOrRef !== null) {\n const kind = [get(entityOrRef, 'kind')].find(\n candidate => candidate && typeof candidate === 'string',\n );\n\n const namespace = [\n get(entityOrRef, 'metadata.namespace'),\n get(entityOrRef, 'namespace'),\n ].find(candidate => candidate && typeof candidate === 'string');\n\n const name = [\n get(entityOrRef, 'metadata.name'),\n get(entityOrRef, 'name'),\n ].find(candidate => candidate && typeof candidate === 'string');\n\n const title = [get(entityOrRef, 'metadata.title')].find(\n candidate => candidate && typeof candidate === 'string',\n );\n\n const description = [get(entityOrRef, 'metadata.description')].find(\n candidate => candidate && typeof candidate === 'string',\n );\n\n const displayName = [get(entityOrRef, 'spec.profile.displayName')].find(\n candidate => candidate && typeof candidate === 'string',\n );\n\n const type = [get(entityOrRef, 'spec.type')].find(\n candidate => candidate && typeof candidate === 'string',\n );\n\n return { kind, namespace, name, title, description, displayName, type };\n }\n\n return {};\n}\n\nfunction getShortRef(options: {\n kind?: string;\n namespace?: string;\n name?: string;\n context?: { defaultKind?: string; defaultNamespace?: string };\n}): string {\n const kind = options.kind?.toLocaleLowerCase('en-US') || 'unknown';\n const namespace = options.namespace || DEFAULT_NAMESPACE;\n const name = options.name || 'unknown';\n const defaultKindLower =\n options.context?.defaultKind?.toLocaleLowerCase('en-US');\n const defaultNamespaceLower =\n options.context?.defaultNamespace?.toLocaleLowerCase('en-US');\n\n let result = name;\n\n if (\n (defaultNamespaceLower &&\n namespace.toLocaleLowerCase('en-US') !== defaultNamespaceLower) ||\n namespace !== DEFAULT_NAMESPACE\n ) {\n result = `${namespace}/${result}`;\n }\n\n if (\n defaultKindLower &&\n kind.toLocaleLowerCase('en-US') !== defaultKindLower\n ) {\n result = `${kind}:${result}`;\n }\n\n return result;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -4,16 +4,16 @@ function useUpdatingObservable(value, observable, deps) {
|
|
|
4
4
|
const [snapshot, setSnapshot] = useState(value);
|
|
5
5
|
useEffect(() => {
|
|
6
6
|
setSnapshot(value);
|
|
7
|
-
const subscription = observable
|
|
7
|
+
const subscription = observable?.subscribe({
|
|
8
8
|
next: (updatedValue) => {
|
|
9
9
|
setSnapshot(updatedValue);
|
|
10
10
|
},
|
|
11
11
|
complete: () => {
|
|
12
|
-
subscription
|
|
12
|
+
subscription?.unsubscribe();
|
|
13
13
|
}
|
|
14
14
|
});
|
|
15
15
|
return () => {
|
|
16
|
-
subscription
|
|
16
|
+
subscription?.unsubscribe();
|
|
17
17
|
};
|
|
18
18
|
}, deps);
|
|
19
19
|
return snapshot;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUpdatingObservable.esm.js","sources":["../../../src/apis/EntityPresentationApi/useUpdatingObservable.ts"],"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 { Observable } from '@backstage/types';\nimport { DependencyList, useEffect, useState } from 'react';\n\n/**\n * Subscribe to an observable and return the latest value from it.\n *\n * @remarks\n *\n * This implementation differs in a few important ways from the plain\n * useObservable from the react-use library. That hook does not support a\n * dependencies array, and also it only subscribes once to the initially passed\n * in observable and won't properly react when either initial value or the\n * actual observable changes.\n *\n * This hook will ensure to resubscribe and reconsider the initial value,\n * whenever the dependencies change.\n */\nexport function useUpdatingObservable<T>(\n value: T,\n observable: Observable<T> | undefined,\n deps: DependencyList,\n): T {\n const [snapshot, setSnapshot] = useState(value);\n\n useEffect(() => {\n setSnapshot(value);\n\n const subscription = observable?.subscribe({\n next: updatedValue => {\n setSnapshot(updatedValue);\n },\n complete: () => {\n subscription?.unsubscribe();\n },\n });\n\n return () => {\n subscription?.unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n return snapshot;\n}\n"],"names":[],"mappings":";;AAiCgB,SAAA,qBAAA,CACd,KACA,EAAA,UAAA,EACA,IACG,EAAA;AACH,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA,CAAA;AAE9C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,WAAA,CAAY,KAAK,CAAA,CAAA;AAEjB,IAAM,MAAA,YAAA,GAAe,
|
|
1
|
+
{"version":3,"file":"useUpdatingObservable.esm.js","sources":["../../../src/apis/EntityPresentationApi/useUpdatingObservable.ts"],"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 { Observable } from '@backstage/types';\nimport { DependencyList, useEffect, useState } from 'react';\n\n/**\n * Subscribe to an observable and return the latest value from it.\n *\n * @remarks\n *\n * This implementation differs in a few important ways from the plain\n * useObservable from the react-use library. That hook does not support a\n * dependencies array, and also it only subscribes once to the initially passed\n * in observable and won't properly react when either initial value or the\n * actual observable changes.\n *\n * This hook will ensure to resubscribe and reconsider the initial value,\n * whenever the dependencies change.\n */\nexport function useUpdatingObservable<T>(\n value: T,\n observable: Observable<T> | undefined,\n deps: DependencyList,\n): T {\n const [snapshot, setSnapshot] = useState(value);\n\n useEffect(() => {\n setSnapshot(value);\n\n const subscription = observable?.subscribe({\n next: updatedValue => {\n setSnapshot(updatedValue);\n },\n complete: () => {\n subscription?.unsubscribe();\n },\n });\n\n return () => {\n subscription?.unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n return snapshot;\n}\n"],"names":[],"mappings":";;AAiCgB,SAAA,qBAAA,CACd,KACA,EAAA,UAAA,EACA,IACG,EAAA;AACH,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA,CAAA;AAE9C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,WAAA,CAAY,KAAK,CAAA,CAAA;AAEjB,IAAM,MAAA,YAAA,GAAe,YAAY,SAAU,CAAA;AAAA,MACzC,MAAM,CAAgB,YAAA,KAAA;AACpB,QAAA,WAAA,CAAY,YAAY,CAAA,CAAA;AAAA,OAC1B;AAAA,MACA,UAAU,MAAM;AACd,QAAA,YAAA,EAAc,WAAY,EAAA,CAAA;AAAA,OAC5B;AAAA,KACD,CAAA,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,YAAA,EAAc,WAAY,EAAA,CAAA;AAAA,KAC5B,CAAA;AAAA,KAEC,IAAI,CAAA,CAAA;AAEP,EAAO,OAAA,QAAA,CAAA;AACT;;;;"}
|
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
import ObservableImpl from 'zen-observable';
|
|
2
2
|
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
-
var __publicField = (obj, key, value) => {
|
|
6
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
7
|
-
return value;
|
|
8
|
-
};
|
|
9
3
|
class MockStarredEntitiesApi {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}));
|
|
20
|
-
}
|
|
4
|
+
starredEntities = /* @__PURE__ */ new Set();
|
|
5
|
+
subscribers = /* @__PURE__ */ new Set();
|
|
6
|
+
observable = new ObservableImpl((subscriber) => {
|
|
7
|
+
subscriber.next(new Set(this.starredEntities));
|
|
8
|
+
this.subscribers.add(subscriber);
|
|
9
|
+
return () => {
|
|
10
|
+
this.subscribers.delete(subscriber);
|
|
11
|
+
};
|
|
12
|
+
});
|
|
21
13
|
async toggleStarred(entityRef) {
|
|
22
14
|
if (!this.starredEntities.delete(entityRef)) {
|
|
23
15
|
this.starredEntities.add(entityRef);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MockStarredEntitiesApi.esm.js","sources":["../../../src/apis/StarredEntitiesApi/MockStarredEntitiesApi.ts"],"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 { Observable } from '@backstage/types';\nimport ObservableImpl from 'zen-observable';\nimport { StarredEntitiesApi } from './StarredEntitiesApi';\n\n/**\n * An in-memory mock implementation of the StarredEntitiesApi.\n *\n * @public\n */\nexport class MockStarredEntitiesApi implements StarredEntitiesApi {\n private readonly starredEntities = new Set<string>();\n private readonly subscribers = new Set<\n ZenObservable.SubscriptionObserver<Set<string>>\n >();\n\n private readonly observable = new ObservableImpl<Set<string>>(subscriber => {\n subscriber.next(new Set(this.starredEntities));\n\n this.subscribers.add(subscriber);\n return () => {\n this.subscribers.delete(subscriber);\n };\n });\n\n async toggleStarred(entityRef: string): Promise<void> {\n if (!this.starredEntities.delete(entityRef)) {\n this.starredEntities.add(entityRef);\n }\n\n for (const subscription of this.subscribers) {\n subscription.next(new Set(this.starredEntities));\n }\n }\n\n starredEntitie$(): Observable<Set<string>> {\n return this.observable;\n }\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MockStarredEntitiesApi.esm.js","sources":["../../../src/apis/StarredEntitiesApi/MockStarredEntitiesApi.ts"],"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 { Observable } from '@backstage/types';\nimport ObservableImpl from 'zen-observable';\nimport { StarredEntitiesApi } from './StarredEntitiesApi';\n\n/**\n * An in-memory mock implementation of the StarredEntitiesApi.\n *\n * @public\n */\nexport class MockStarredEntitiesApi implements StarredEntitiesApi {\n private readonly starredEntities = new Set<string>();\n private readonly subscribers = new Set<\n ZenObservable.SubscriptionObserver<Set<string>>\n >();\n\n private readonly observable = new ObservableImpl<Set<string>>(subscriber => {\n subscriber.next(new Set(this.starredEntities));\n\n this.subscribers.add(subscriber);\n return () => {\n this.subscribers.delete(subscriber);\n };\n });\n\n async toggleStarred(entityRef: string): Promise<void> {\n if (!this.starredEntities.delete(entityRef)) {\n this.starredEntities.add(entityRef);\n }\n\n for (const subscription of this.subscribers) {\n subscription.next(new Set(this.starredEntities));\n }\n }\n\n starredEntitie$(): Observable<Set<string>> {\n return this.observable;\n }\n}\n"],"names":[],"mappings":";;AAyBO,MAAM,sBAAqD,CAAA;AAAA,EAC/C,eAAA,uBAAsB,GAAY,EAAA,CAAA;AAAA,EAClC,WAAA,uBAAkB,GAEjC,EAAA,CAAA;AAAA,EAEe,UAAA,GAAa,IAAI,cAAA,CAA4B,CAAc,UAAA,KAAA;AAC1E,IAAA,UAAA,CAAW,IAAK,CAAA,IAAI,GAAI,CAAA,IAAA,CAAK,eAAe,CAAC,CAAA,CAAA;AAE7C,IAAK,IAAA,CAAA,WAAA,CAAY,IAAI,UAAU,CAAA,CAAA;AAC/B,IAAA,OAAO,MAAM;AACX,MAAK,IAAA,CAAA,WAAA,CAAY,OAAO,UAAU,CAAA,CAAA;AAAA,KACpC,CAAA;AAAA,GACD,CAAA,CAAA;AAAA,EAED,MAAM,cAAc,SAAkC,EAAA;AACpD,IAAA,IAAI,CAAC,IAAA,CAAK,eAAgB,CAAA,MAAA,CAAO,SAAS,CAAG,EAAA;AAC3C,MAAK,IAAA,CAAA,eAAA,CAAgB,IAAI,SAAS,CAAA,CAAA;AAAA,KACpC;AAEA,IAAW,KAAA,MAAA,YAAA,IAAgB,KAAK,WAAa,EAAA;AAC3C,MAAA,YAAA,CAAa,IAAK,CAAA,IAAI,GAAI,CAAA,IAAA,CAAK,eAAe,CAAC,CAAA,CAAA;AAAA,KACjD;AAAA,GACF;AAAA,EAEA,eAA2C,GAAA;AACzC,IAAA,OAAO,IAAK,CAAA,UAAA,CAAA;AAAA,GACd;AACF;;;;"}
|
|
@@ -9,12 +9,8 @@ import { useTheme } from '@material-ui/core/styles';
|
|
|
9
9
|
import FilterListIcon from '@material-ui/icons/FilterList';
|
|
10
10
|
|
|
11
11
|
const Filters = (props) => {
|
|
12
|
-
var _a, _b;
|
|
13
12
|
const isScreenSmallerThanBreakpoint = useMediaQuery(
|
|
14
|
-
(theme2) =>
|
|
15
|
-
var _a2, _b2;
|
|
16
|
-
return theme2.breakpoints.down((_b2 = (_a2 = props.options) == null ? void 0 : _a2.drawerBreakpoint) != null ? _b2 : "md");
|
|
17
|
-
}
|
|
13
|
+
(theme2) => theme2.breakpoints.down(props.options?.drawerBreakpoint ?? "md")
|
|
18
14
|
);
|
|
19
15
|
const theme = useTheme();
|
|
20
16
|
const [filterDrawerOpen, setFilterDrawerOpen] = useState(false);
|
|
@@ -31,7 +27,7 @@ const Filters = (props) => {
|
|
|
31
27
|
{
|
|
32
28
|
open: filterDrawerOpen,
|
|
33
29
|
onClose: () => setFilterDrawerOpen(false),
|
|
34
|
-
anchor:
|
|
30
|
+
anchor: props.options?.drawerAnchor ?? "left",
|
|
35
31
|
disableAutoFocus: true,
|
|
36
32
|
keepMounted: true,
|
|
37
33
|
variant: "temporary"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogFilterLayout.esm.js","sources":["../../../src/components/CatalogFilterLayout/CatalogFilterLayout.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 React, { useState } from 'react';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { Theme, useTheme } from '@material-ui/core/styles';\nimport FilterListIcon from '@material-ui/icons/FilterList';\n\n/** @public */\nexport const Filters = (props: {\n children: React.ReactNode;\n options?: {\n drawerBreakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number;\n drawerAnchor?: 'left' | 'right' | 'top' | 'bottom';\n };\n}) => {\n const isScreenSmallerThanBreakpoint = useMediaQuery((theme: Theme) =>\n theme.breakpoints.down(props.options?.drawerBreakpoint ?? 'md'),\n );\n const theme = useTheme();\n const [filterDrawerOpen, setFilterDrawerOpen] = useState<boolean>(false);\n\n return isScreenSmallerThanBreakpoint ? (\n <>\n <Button\n style={{ marginTop: theme.spacing(1), marginLeft: theme.spacing(1) }}\n onClick={() => setFilterDrawerOpen(true)}\n startIcon={<FilterListIcon />}\n >\n Filters\n </Button>\n <Drawer\n open={filterDrawerOpen}\n onClose={() => setFilterDrawerOpen(false)}\n anchor={props.options?.drawerAnchor ?? 'left'}\n disableAutoFocus\n keepMounted\n variant=\"temporary\"\n >\n <Box m={2}>\n <Typography\n variant=\"h6\"\n component=\"h2\"\n style={{ marginBottom: theme.spacing(1) }}\n >\n Filters\n </Typography>\n {props.children}\n </Box>\n </Drawer>\n </>\n ) : (\n <Grid item lg={2}>\n {props.children}\n </Grid>\n );\n};\n\n/** @public */\nexport const Content = (props: { children: React.ReactNode }) => {\n return (\n <Grid item xs={12} lg={10}>\n {props.children}\n </Grid>\n );\n};\n\n/** @public */\nexport const CatalogFilterLayout = (props: { children: React.ReactNode }) => {\n return (\n <Grid container style={{ position: 'relative' }}>\n {props.children}\n </Grid>\n );\n};\n\nCatalogFilterLayout.Filters = Filters;\nCatalogFilterLayout.Content = Content;\n"],"names":["theme"
|
|
1
|
+
{"version":3,"file":"CatalogFilterLayout.esm.js","sources":["../../../src/components/CatalogFilterLayout/CatalogFilterLayout.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 React, { useState } from 'react';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { Theme, useTheme } from '@material-ui/core/styles';\nimport FilterListIcon from '@material-ui/icons/FilterList';\n\n/** @public */\nexport const Filters = (props: {\n children: React.ReactNode;\n options?: {\n drawerBreakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number;\n drawerAnchor?: 'left' | 'right' | 'top' | 'bottom';\n };\n}) => {\n const isScreenSmallerThanBreakpoint = useMediaQuery((theme: Theme) =>\n theme.breakpoints.down(props.options?.drawerBreakpoint ?? 'md'),\n );\n const theme = useTheme();\n const [filterDrawerOpen, setFilterDrawerOpen] = useState<boolean>(false);\n\n return isScreenSmallerThanBreakpoint ? (\n <>\n <Button\n style={{ marginTop: theme.spacing(1), marginLeft: theme.spacing(1) }}\n onClick={() => setFilterDrawerOpen(true)}\n startIcon={<FilterListIcon />}\n >\n Filters\n </Button>\n <Drawer\n open={filterDrawerOpen}\n onClose={() => setFilterDrawerOpen(false)}\n anchor={props.options?.drawerAnchor ?? 'left'}\n disableAutoFocus\n keepMounted\n variant=\"temporary\"\n >\n <Box m={2}>\n <Typography\n variant=\"h6\"\n component=\"h2\"\n style={{ marginBottom: theme.spacing(1) }}\n >\n Filters\n </Typography>\n {props.children}\n </Box>\n </Drawer>\n </>\n ) : (\n <Grid item lg={2}>\n {props.children}\n </Grid>\n );\n};\n\n/** @public */\nexport const Content = (props: { children: React.ReactNode }) => {\n return (\n <Grid item xs={12} lg={10}>\n {props.children}\n </Grid>\n );\n};\n\n/** @public */\nexport const CatalogFilterLayout = (props: { children: React.ReactNode }) => {\n return (\n <Grid container style={{ position: 'relative' }}>\n {props.children}\n </Grid>\n );\n};\n\nCatalogFilterLayout.Filters = Filters;\nCatalogFilterLayout.Content = Content;\n"],"names":["theme"],"mappings":";;;;;;;;;;AA2Ba,MAAA,OAAA,GAAU,CAAC,KAMlB,KAAA;AACJ,EAAA,MAAM,6BAAgC,GAAA,aAAA;AAAA,IAAc,CAACA,WACnDA,MAAM,CAAA,WAAA,CAAY,KAAK,KAAM,CAAA,OAAA,EAAS,oBAAoB,IAAI,CAAA;AAAA,GAChE,CAAA;AACA,EAAA,MAAM,QAAQ,QAAS,EAAA,CAAA;AACvB,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAAkB,KAAK,CAAA,CAAA;AAEvE,EAAA,OAAO,gDAEH,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,EAAE,SAAA,EAAW,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA,EAAG,UAAY,EAAA,KAAA,CAAM,OAAQ,CAAA,CAAC,CAAE,EAAA;AAAA,MACnE,OAAA,EAAS,MAAM,mBAAA,CAAoB,IAAI,CAAA;AAAA,MACvC,SAAA,sCAAY,cAAe,EAAA,IAAA,CAAA;AAAA,KAAA;AAAA,IAC5B,SAAA;AAAA,GAGD,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,IAAM,EAAA,gBAAA;AAAA,MACN,OAAA,EAAS,MAAM,mBAAA,CAAoB,KAAK,CAAA;AAAA,MACxC,MAAA,EAAQ,KAAM,CAAA,OAAA,EAAS,YAAgB,IAAA,MAAA;AAAA,MACvC,gBAAgB,EAAA,IAAA;AAAA,MAChB,WAAW,EAAA,IAAA;AAAA,MACX,OAAQ,EAAA,WAAA;AAAA,KAAA;AAAA,oBAER,KAAA,CAAA,aAAA,CAAC,GAAI,EAAA,EAAA,CAAA,EAAG,CACN,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,OAAQ,EAAA,IAAA;AAAA,QACR,SAAU,EAAA,IAAA;AAAA,QACV,OAAO,EAAE,YAAA,EAAc,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAE,EAAA;AAAA,OAAA;AAAA,MACzC,SAAA;AAAA,KAED,EACC,MAAM,QACT,CAAA;AAAA,GAEJ,oBAEC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,MAAI,IAAC,EAAA,EAAA,EAAI,CACZ,EAAA,EAAA,KAAA,CAAM,QACT,CAAA,CAAA;AAEJ,EAAA;AAGa,MAAA,OAAA,GAAU,CAAC,KAAyC,KAAA;AAC/D,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,QAAK,IAAI,EAAA,IAAA,EAAC,IAAI,EAAI,EAAA,EAAA,EAAI,EACpB,EAAA,EAAA,KAAA,CAAM,QACT,CAAA,CAAA;AAEJ,EAAA;AAGa,MAAA,mBAAA,GAAsB,CAAC,KAAyC,KAAA;AAC3E,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAS,IAAC,EAAA,KAAA,EAAO,EAAE,QAAU,EAAA,UAAA,EAChC,EAAA,EAAA,KAAA,CAAM,QACT,CAAA,CAAA;AAEJ,EAAA;AAEA,mBAAA,CAAoB,OAAU,GAAA,OAAA,CAAA;AAC9B,mBAAA,CAAoB,OAAU,GAAA,OAAA;;;;"}
|
|
@@ -21,7 +21,6 @@ const useStyles = makeStyles(
|
|
|
21
21
|
{ name: "CatalogReactEntityAutocompletePicker" }
|
|
22
22
|
);
|
|
23
23
|
function EntityAutocompletePicker(props) {
|
|
24
|
-
var _a, _b;
|
|
25
24
|
const {
|
|
26
25
|
label,
|
|
27
26
|
name,
|
|
@@ -59,14 +58,14 @@ function EntityAutocompletePicker(props) {
|
|
|
59
58
|
[queryParameter]
|
|
60
59
|
);
|
|
61
60
|
const [selectedOptions, setSelectedOptions] = useState(
|
|
62
|
-
queryParameters.length ? queryParameters :
|
|
61
|
+
queryParameters.length ? queryParameters : filters[name]?.values ?? initialSelectedOptions
|
|
63
62
|
);
|
|
64
63
|
useEffect(() => {
|
|
65
64
|
if (queryParameters.length) {
|
|
66
65
|
setSelectedOptions(queryParameters);
|
|
67
66
|
}
|
|
68
67
|
}, [queryParameters]);
|
|
69
|
-
const availableOptions = Object.keys(availableValues
|
|
68
|
+
const availableOptions = Object.keys(availableValues ?? {});
|
|
70
69
|
const shouldAddFilter = selectedOptions.length && availableOptions.length;
|
|
71
70
|
useEffect(() => {
|
|
72
71
|
updateFilters({
|
|
@@ -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 Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\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 { EntityAutocompletePickerInput } from './EntityAutocompletePickerInput';\nimport {\n DefaultEntityFilters,\n useEntityList,\n} from '../../hooks/useEntityListProvider';\nimport { EntityFilter } from '../../types';\nimport { reduceBackendCatalogFilters } from '../../utils';\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};\n\n/** @public */\nexport type CatalogReactEntityAutocompletePickerClassKey = 'root' | 'label';\n\nconst useStyles = makeStyles(\n {\n root: {},\n label: {},\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 } = props;\n\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 : (filters[name] as unknown as { values: string[] })?.values ??\n 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 useEffect(() => {\n updateFilters({\n [name]: shouldAddFilter ? new Filter(selectedOptions) : undefined,\n } as Partial<T>);\n }, [name, shouldAddFilter, selectedOptions, Filter, updateFilters]);\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 (\n <Box className={classes.root} pb={1} pt={1}>\n <Typography className={classes.label} variant=\"button\" component=\"label\">\n {label}\n <Autocomplete<string, true>\n multiple\n disableCloseOnSelect\n options={availableOptions}\n value={selectedOptions}\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 size=\"small\"\n popupIcon={\n <ExpandMoreIcon data-testid={`${String(name)}-picker-expand`} />\n }\n renderInput={params => (\n <EntityAutocompletePickerInput {...params} {...InputProps} />\n )}\n />\n </Typography>\n </Box>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA8DA,MAAM,SAAY,GAAA,UAAA;AAAA,EAChB;AAAA,IACE,MAAM,EAAC;AAAA,IACP,OAAO,EAAC;AAAA,GACV;AAAA,EACA,EAAE,MAAM,sCAAuC,EAAA;AACjD,CAAA,CAAA;AAGO,SAAS,yBAGd,KAA+C,EAAA;
|
|
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 Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\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 { EntityAutocompletePickerInput } from './EntityAutocompletePickerInput';\nimport {\n DefaultEntityFilters,\n useEntityList,\n} from '../../hooks/useEntityListProvider';\nimport { EntityFilter } from '../../types';\nimport { reduceBackendCatalogFilters } from '../../utils';\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};\n\n/** @public */\nexport type CatalogReactEntityAutocompletePickerClassKey = 'root' | 'label';\n\nconst useStyles = makeStyles(\n {\n root: {},\n label: {},\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 } = props;\n\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 : (filters[name] as unknown as { values: string[] })?.values ??\n 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 useEffect(() => {\n updateFilters({\n [name]: shouldAddFilter ? new Filter(selectedOptions) : undefined,\n } as Partial<T>);\n }, [name, shouldAddFilter, selectedOptions, Filter, updateFilters]);\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 (\n <Box className={classes.root} pb={1} pt={1}>\n <Typography className={classes.label} variant=\"button\" component=\"label\">\n {label}\n <Autocomplete<string, true>\n multiple\n disableCloseOnSelect\n options={availableOptions}\n value={selectedOptions}\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 size=\"small\"\n popupIcon={\n <ExpandMoreIcon data-testid={`${String(name)}-picker-expand`} />\n }\n renderInput={params => (\n <EntityAutocompletePickerInput {...params} {...InputProps} />\n )}\n />\n </Typography>\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ function OptionCheckbox({ selected }) {
|
|
|
11
11
|
}
|
|
12
12
|
const EntityAutocompletePickerOption = memo((props) => {
|
|
13
13
|
const { selected, value, availableOptions, showCounts } = props;
|
|
14
|
-
const label = showCounts ? `${value} (${availableOptions
|
|
14
|
+
const label = showCounts ? `${value} (${availableOptions?.[value]})` : value;
|
|
15
15
|
return /* @__PURE__ */ React.createElement(
|
|
16
16
|
FormControlLabel,
|
|
17
17
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityAutocompletePickerOption.esm.js","sources":["../../../src/components/EntityAutocompletePicker/EntityAutocompletePickerOption.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport CheckBoxIcon from '@material-ui/icons/CheckBox';\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';\nimport React, { memo } from 'react';\n\ninterface Props {\n selected: boolean;\n value: string;\n availableOptions?: Record<string, number>;\n showCounts: boolean;\n}\n\nconst icon = <CheckBoxOutlineBlankIcon fontSize=\"small\" />;\nconst checkedIcon = <CheckBoxIcon fontSize=\"small\" />;\n\nfunction OptionCheckbox({ selected }: { selected: boolean }) {\n return <Checkbox icon={icon} checkedIcon={checkedIcon} checked={selected} />;\n}\n\nexport const EntityAutocompletePickerOption = memo((props: Props) => {\n const { selected, value, availableOptions, showCounts } = props;\n const label = showCounts ? `${value} (${availableOptions?.[value]})` : value;\n\n return (\n <FormControlLabel\n control={<OptionCheckbox selected={selected} />}\n label={label}\n onClick={event => event.preventDefault()}\n />\n );\n});\n"],"names":[],"mappings":";;;;;;AA4BA,MAAM,IAAO,mBAAA,KAAA,CAAA,aAAA,CAAC,wBAAyB,EAAA,EAAA,QAAA,EAAS,OAAQ,EAAA,CAAA,CAAA;AACxD,MAAM,WAAc,mBAAA,KAAA,CAAA,aAAA,CAAC,YAAa,EAAA,EAAA,QAAA,EAAS,OAAQ,EAAA,CAAA,CAAA;AAEnD,SAAS,cAAA,CAAe,EAAE,QAAA,EAAmC,EAAA;AAC3D,EAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EAAS,IAAY,EAAA,WAAA,EAA0B,SAAS,QAAU,EAAA,CAAA,CAAA;AAC5E,CAAA;AAEa,MAAA,8BAAA,GAAiC,IAAK,CAAA,CAAC,KAAiB,KAAA;AACnE,EAAA,MAAM,EAAE,QAAA,EAAU,KAAO,EAAA,gBAAA,EAAkB,YAAe,GAAA,KAAA,CAAA;AAC1D,
|
|
1
|
+
{"version":3,"file":"EntityAutocompletePickerOption.esm.js","sources":["../../../src/components/EntityAutocompletePicker/EntityAutocompletePickerOption.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport CheckBoxIcon from '@material-ui/icons/CheckBox';\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';\nimport React, { memo } from 'react';\n\ninterface Props {\n selected: boolean;\n value: string;\n availableOptions?: Record<string, number>;\n showCounts: boolean;\n}\n\nconst icon = <CheckBoxOutlineBlankIcon fontSize=\"small\" />;\nconst checkedIcon = <CheckBoxIcon fontSize=\"small\" />;\n\nfunction OptionCheckbox({ selected }: { selected: boolean }) {\n return <Checkbox icon={icon} checkedIcon={checkedIcon} checked={selected} />;\n}\n\nexport const EntityAutocompletePickerOption = memo((props: Props) => {\n const { selected, value, availableOptions, showCounts } = props;\n const label = showCounts ? `${value} (${availableOptions?.[value]})` : value;\n\n return (\n <FormControlLabel\n control={<OptionCheckbox selected={selected} />}\n label={label}\n onClick={event => event.preventDefault()}\n />\n );\n});\n"],"names":[],"mappings":";;;;;;AA4BA,MAAM,IAAO,mBAAA,KAAA,CAAA,aAAA,CAAC,wBAAyB,EAAA,EAAA,QAAA,EAAS,OAAQ,EAAA,CAAA,CAAA;AACxD,MAAM,WAAc,mBAAA,KAAA,CAAA,aAAA,CAAC,YAAa,EAAA,EAAA,QAAA,EAAS,OAAQ,EAAA,CAAA,CAAA;AAEnD,SAAS,cAAA,CAAe,EAAE,QAAA,EAAmC,EAAA;AAC3D,EAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EAAS,IAAY,EAAA,WAAA,EAA0B,SAAS,QAAU,EAAA,CAAA,CAAA;AAC5E,CAAA;AAEa,MAAA,8BAAA,GAAiC,IAAK,CAAA,CAAC,KAAiB,KAAA;AACnE,EAAA,MAAM,EAAE,QAAA,EAAU,KAAO,EAAA,gBAAA,EAAkB,YAAe,GAAA,KAAA,CAAA;AAC1D,EAAM,MAAA,KAAA,GAAQ,aAAa,CAAG,EAAA,KAAK,KAAK,gBAAmB,GAAA,KAAK,CAAC,CAAM,CAAA,CAAA,GAAA,KAAA,CAAA;AAEvE,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,gBAAA;AAAA,IAAA;AAAA,MACC,OAAA,kBAAU,KAAA,CAAA,aAAA,CAAA,cAAA,EAAA,EAAe,QAAoB,EAAA,CAAA;AAAA,MAC7C,KAAA;AAAA,MACA,OAAA,EAAS,CAAS,KAAA,KAAA,KAAA,CAAM,cAAe,EAAA;AAAA,KAAA;AAAA,GACzC,CAAA;AAEJ,CAAC;;;;"}
|
|
@@ -18,7 +18,6 @@ import 'zen-observable';
|
|
|
18
18
|
import { filterKinds, useAllKinds } from './kindFilterUtils.esm.js';
|
|
19
19
|
|
|
20
20
|
function useEntityKindFilter(opts) {
|
|
21
|
-
var _a, _b;
|
|
22
21
|
const {
|
|
23
22
|
filters,
|
|
24
23
|
queryParameters: { kind: kindParameter },
|
|
@@ -29,7 +28,7 @@ function useEntityKindFilter(opts) {
|
|
|
29
28
|
[kindParameter]
|
|
30
29
|
);
|
|
31
30
|
const [selectedKind, setSelectedKind] = useState(
|
|
32
|
-
|
|
31
|
+
queryParamKind ?? filters.kind?.value ?? opts.initialFilter
|
|
33
32
|
);
|
|
34
33
|
useEffect(() => {
|
|
35
34
|
if (queryParamKind) {
|
|
@@ -37,9 +36,8 @@ function useEntityKindFilter(opts) {
|
|
|
37
36
|
}
|
|
38
37
|
}, [queryParamKind]);
|
|
39
38
|
useEffect(() => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
setSelectedKind((_b2 = filters.kind) == null ? void 0 : _b2.value);
|
|
39
|
+
if (filters.kind?.value) {
|
|
40
|
+
setSelectedKind(filters.kind?.value);
|
|
43
41
|
}
|
|
44
42
|
}, [filters.kind]);
|
|
45
43
|
useEffect(() => {
|
|
@@ -51,7 +49,7 @@ function useEntityKindFilter(opts) {
|
|
|
51
49
|
return {
|
|
52
50
|
loading,
|
|
53
51
|
error,
|
|
54
|
-
allKinds: allKinds
|
|
52
|
+
allKinds: allKinds ?? [],
|
|
55
53
|
selectedKind,
|
|
56
54
|
setSelectedKind
|
|
57
55
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityKindPicker.esm.js","sources":["../../../src/components/EntityKindPicker/EntityKindPicker.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 { Select } from '@backstage/core-components';\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport Box from '@material-ui/core/Box';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { EntityKindFilter } from '../../filters';\nimport { useEntityList } from '../../hooks';\nimport { filterKinds, useAllKinds } from './kindFilterUtils';\n\nfunction useEntityKindFilter(opts: { initialFilter: string }): {\n loading: boolean;\n error?: Error;\n allKinds: string[];\n selectedKind: string;\n setSelectedKind: (kind: string) => void;\n} {\n const {\n filters,\n queryParameters: { kind: kindParameter },\n updateFilters,\n } = useEntityList();\n\n const queryParamKind = useMemo(\n () => [kindParameter].flat()[0],\n [kindParameter],\n );\n\n const [selectedKind, setSelectedKind] = useState(\n queryParamKind ?? filters.kind?.value ?? opts.initialFilter,\n );\n\n // Set selected kinds on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (queryParamKind) {\n setSelectedKind(queryParamKind);\n }\n }, [queryParamKind]);\n\n // Set selected kind from filters; this happens when the kind filter is\n // updated from another component\n useEffect(() => {\n if (filters.kind?.value) {\n setSelectedKind(filters.kind?.value);\n }\n }, [filters.kind]);\n\n useEffect(() => {\n updateFilters({\n kind: selectedKind ? new EntityKindFilter(selectedKind) : undefined,\n });\n }, [selectedKind, updateFilters]);\n\n const { allKinds, loading, error } = useAllKinds();\n\n return {\n loading,\n error,\n allKinds: allKinds ?? [],\n selectedKind,\n setSelectedKind,\n };\n}\n\n/**\n * Props for {@link EntityKindPicker}.\n *\n * @public\n */\nexport interface EntityKindPickerProps {\n /**\n * Entity kinds to show in the dropdown; by default all kinds are fetched from the catalog and\n * displayed.\n */\n allowedKinds?: string[];\n initialFilter?: string;\n hidden?: boolean;\n}\n\n/** @public */\nexport const EntityKindPicker = (props: EntityKindPickerProps) => {\n const { allowedKinds, hidden, initialFilter = 'component' } = props;\n\n const alertApi = useApi(alertApiRef);\n\n const { error, allKinds, selectedKind, setSelectedKind } =\n useEntityKindFilter({\n initialFilter: initialFilter,\n });\n\n useEffect(() => {\n if (error) {\n alertApi.post({\n message: `Failed to load entity kinds`,\n severity: 'error',\n });\n }\n }, [error, alertApi]);\n\n if (error) return null;\n\n const options = filterKinds(allKinds, allowedKinds, selectedKind);\n\n const items = Object.keys(options).map(key => ({\n value: key,\n label: options[key],\n }));\n\n return hidden ? null : (\n <Box pb={1} pt={1}>\n <Select\n label=\"Kind\"\n items={items}\n selected={selectedKind.toLocaleLowerCase('en-US')}\n onChange={value => setSelectedKind(String(value))}\n />\n </Box>\n );\n};\n"],"names":[
|
|
1
|
+
{"version":3,"file":"EntityKindPicker.esm.js","sources":["../../../src/components/EntityKindPicker/EntityKindPicker.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 { Select } from '@backstage/core-components';\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport Box from '@material-ui/core/Box';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { EntityKindFilter } from '../../filters';\nimport { useEntityList } from '../../hooks';\nimport { filterKinds, useAllKinds } from './kindFilterUtils';\n\nfunction useEntityKindFilter(opts: { initialFilter: string }): {\n loading: boolean;\n error?: Error;\n allKinds: string[];\n selectedKind: string;\n setSelectedKind: (kind: string) => void;\n} {\n const {\n filters,\n queryParameters: { kind: kindParameter },\n updateFilters,\n } = useEntityList();\n\n const queryParamKind = useMemo(\n () => [kindParameter].flat()[0],\n [kindParameter],\n );\n\n const [selectedKind, setSelectedKind] = useState(\n queryParamKind ?? filters.kind?.value ?? opts.initialFilter,\n );\n\n // Set selected kinds on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (queryParamKind) {\n setSelectedKind(queryParamKind);\n }\n }, [queryParamKind]);\n\n // Set selected kind from filters; this happens when the kind filter is\n // updated from another component\n useEffect(() => {\n if (filters.kind?.value) {\n setSelectedKind(filters.kind?.value);\n }\n }, [filters.kind]);\n\n useEffect(() => {\n updateFilters({\n kind: selectedKind ? new EntityKindFilter(selectedKind) : undefined,\n });\n }, [selectedKind, updateFilters]);\n\n const { allKinds, loading, error } = useAllKinds();\n\n return {\n loading,\n error,\n allKinds: allKinds ?? [],\n selectedKind,\n setSelectedKind,\n };\n}\n\n/**\n * Props for {@link EntityKindPicker}.\n *\n * @public\n */\nexport interface EntityKindPickerProps {\n /**\n * Entity kinds to show in the dropdown; by default all kinds are fetched from the catalog and\n * displayed.\n */\n allowedKinds?: string[];\n initialFilter?: string;\n hidden?: boolean;\n}\n\n/** @public */\nexport const EntityKindPicker = (props: EntityKindPickerProps) => {\n const { allowedKinds, hidden, initialFilter = 'component' } = props;\n\n const alertApi = useApi(alertApiRef);\n\n const { error, allKinds, selectedKind, setSelectedKind } =\n useEntityKindFilter({\n initialFilter: initialFilter,\n });\n\n useEffect(() => {\n if (error) {\n alertApi.post({\n message: `Failed to load entity kinds`,\n severity: 'error',\n });\n }\n }, [error, alertApi]);\n\n if (error) return null;\n\n const options = filterKinds(allKinds, allowedKinds, selectedKind);\n\n const items = Object.keys(options).map(key => ({\n value: key,\n label: options[key],\n }));\n\n return hidden ? null : (\n <Box pb={1} pt={1}>\n <Select\n label=\"Kind\"\n items={items}\n selected={selectedKind.toLocaleLowerCase('en-US')}\n onChange={value => setSelectedKind(String(value))}\n />\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -9,13 +9,10 @@ function useAllKinds() {
|
|
|
9
9
|
loading,
|
|
10
10
|
value: allKinds
|
|
11
11
|
} = useAsync(async () => {
|
|
12
|
-
const items = await catalogApi.getEntityFacets({ facets: ["kind"] }).then((response) =>
|
|
13
|
-
var _a;
|
|
14
|
-
return ((_a = response.facets.kind) == null ? void 0 : _a.map((f) => f.value).sort()) || [];
|
|
15
|
-
});
|
|
12
|
+
const items = await catalogApi.getEntityFacets({ facets: ["kind"] }).then((response) => response.facets.kind?.map((f) => f.value).sort() || []);
|
|
16
13
|
return items;
|
|
17
14
|
}, [catalogApi]);
|
|
18
|
-
return { loading, error, allKinds: allKinds
|
|
15
|
+
return { loading, error, allKinds: allKinds ?? [] };
|
|
19
16
|
}
|
|
20
17
|
function filterKinds(allKinds, allowedKinds, forcedKinds) {
|
|
21
18
|
let availableKinds = allKinds;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kindFilterUtils.esm.js","sources":["../../../src/components/EntityKindPicker/kindFilterUtils.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\n\n/**\n * Fetch and return all availible kinds.\n */\nexport function useAllKinds(): {\n loading: boolean;\n error?: Error;\n allKinds: string[];\n} {\n const catalogApi = useApi(catalogApiRef);\n\n const {\n error,\n loading,\n value: allKinds,\n } = useAsync(async () => {\n const items = await catalogApi\n .getEntityFacets({ facets: ['kind'] })\n .then(response => response.facets.kind?.map(f => f.value).sort() || []);\n return items;\n }, [catalogApi]);\n\n return { loading, error, allKinds: allKinds ?? [] };\n}\n\n/**\n * Filter and capitalize accessible kinds.\n */\nexport function filterKinds(\n allKinds: string[],\n allowedKinds?: string[],\n forcedKinds?: string,\n): Record<string, string> {\n // Before allKinds is loaded, or when a kind is entered manually in the URL, selectedKind may not\n // be present in allKinds. It should still be shown in the dropdown, but may not have the nice\n // enforced casing from the catalog-backend. This makes a key/value record for the Select options,\n // including selectedKind if it's unknown - but allows the selectedKind to get clobbered by the\n // more proper catalog kind if it exists.\n let availableKinds = allKinds;\n if (allowedKinds) {\n availableKinds = availableKinds.filter(k =>\n allowedKinds.some(\n a => a.toLocaleLowerCase('en-US') === k.toLocaleLowerCase('en-US'),\n ),\n );\n }\n if (\n forcedKinds &&\n !allKinds.some(\n a =>\n a.toLocaleLowerCase('en-US') === forcedKinds.toLocaleLowerCase('en-US'),\n )\n ) {\n availableKinds = availableKinds.concat([forcedKinds]);\n }\n\n const kindsMap = availableKinds.sort().reduce((acc, kind) => {\n acc[kind.toLocaleLowerCase('en-US')] = kind;\n return acc;\n }, {} as Record<string, string>);\n\n return kindsMap;\n}\n"],"names":[],"mappings":";;;;AAuBO,SAAS,WAId,GAAA;AACA,EAAM,MAAA,UAAA,GAAa,OAAO,aAAa,CAAA,CAAA;AAEvC,EAAM,MAAA;AAAA,IACJ,KAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAO,EAAA,QAAA;AAAA,GACT,GAAI,SAAS,YAAY;AACvB,
|
|
1
|
+
{"version":3,"file":"kindFilterUtils.esm.js","sources":["../../../src/components/EntityKindPicker/kindFilterUtils.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\n\n/**\n * Fetch and return all availible kinds.\n */\nexport function useAllKinds(): {\n loading: boolean;\n error?: Error;\n allKinds: string[];\n} {\n const catalogApi = useApi(catalogApiRef);\n\n const {\n error,\n loading,\n value: allKinds,\n } = useAsync(async () => {\n const items = await catalogApi\n .getEntityFacets({ facets: ['kind'] })\n .then(response => response.facets.kind?.map(f => f.value).sort() || []);\n return items;\n }, [catalogApi]);\n\n return { loading, error, allKinds: allKinds ?? [] };\n}\n\n/**\n * Filter and capitalize accessible kinds.\n */\nexport function filterKinds(\n allKinds: string[],\n allowedKinds?: string[],\n forcedKinds?: string,\n): Record<string, string> {\n // Before allKinds is loaded, or when a kind is entered manually in the URL, selectedKind may not\n // be present in allKinds. It should still be shown in the dropdown, but may not have the nice\n // enforced casing from the catalog-backend. This makes a key/value record for the Select options,\n // including selectedKind if it's unknown - but allows the selectedKind to get clobbered by the\n // more proper catalog kind if it exists.\n let availableKinds = allKinds;\n if (allowedKinds) {\n availableKinds = availableKinds.filter(k =>\n allowedKinds.some(\n a => a.toLocaleLowerCase('en-US') === k.toLocaleLowerCase('en-US'),\n ),\n );\n }\n if (\n forcedKinds &&\n !allKinds.some(\n a =>\n a.toLocaleLowerCase('en-US') === forcedKinds.toLocaleLowerCase('en-US'),\n )\n ) {\n availableKinds = availableKinds.concat([forcedKinds]);\n }\n\n const kindsMap = availableKinds.sort().reduce((acc, kind) => {\n acc[kind.toLocaleLowerCase('en-US')] = kind;\n return acc;\n }, {} as Record<string, string>);\n\n return kindsMap;\n}\n"],"names":[],"mappings":";;;;AAuBO,SAAS,WAId,GAAA;AACA,EAAM,MAAA,UAAA,GAAa,OAAO,aAAa,CAAA,CAAA;AAEvC,EAAM,MAAA;AAAA,IACJ,KAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAO,EAAA,QAAA;AAAA,GACT,GAAI,SAAS,YAAY;AACvB,IAAM,MAAA,KAAA,GAAQ,MAAM,UAAA,CACjB,eAAgB,CAAA,EAAE,QAAQ,CAAC,MAAM,CAAE,EAAC,CACpC,CAAA,IAAA,CAAK,cAAY,QAAS,CAAA,MAAA,CAAO,IAAM,EAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,KAAK,CAAE,CAAA,IAAA,EAAU,IAAA,EAAE,CAAA,CAAA;AACxE,IAAO,OAAA,KAAA,CAAA;AAAA,GACT,EAAG,CAAC,UAAU,CAAC,CAAA,CAAA;AAEf,EAAA,OAAO,EAAE,OAAS,EAAA,KAAA,EAAO,QAAU,EAAA,QAAA,IAAY,EAAG,EAAA,CAAA;AACpD,CAAA;AAKgB,SAAA,WAAA,CACd,QACA,EAAA,YAAA,EACA,WACwB,EAAA;AAMxB,EAAA,IAAI,cAAiB,GAAA,QAAA,CAAA;AACrB,EAAA,IAAI,YAAc,EAAA;AAChB,IAAA,cAAA,GAAiB,cAAe,CAAA,MAAA;AAAA,MAAO,OACrC,YAAa,CAAA,IAAA;AAAA,QACX,OAAK,CAAE,CAAA,iBAAA,CAAkB,OAAO,CAAM,KAAA,CAAA,CAAE,kBAAkB,OAAO,CAAA;AAAA,OACnE;AAAA,KACF,CAAA;AAAA,GACF;AACA,EACE,IAAA,WAAA,IACA,CAAC,QAAS,CAAA,IAAA;AAAA,IACR,OACE,CAAE,CAAA,iBAAA,CAAkB,OAAO,CAAM,KAAA,WAAA,CAAY,kBAAkB,OAAO,CAAA;AAAA,GAE1E,EAAA;AACA,IAAA,cAAA,GAAiB,cAAe,CAAA,MAAA,CAAO,CAAC,WAAW,CAAC,CAAA,CAAA;AAAA,GACtD;AAEA,EAAA,MAAM,WAAW,cAAe,CAAA,IAAA,GAAO,MAAO,CAAA,CAAC,KAAK,IAAS,KAAA;AAC3D,IAAA,GAAA,CAAI,IAAK,CAAA,iBAAA,CAAkB,OAAO,CAAC,CAAI,GAAA,IAAA,CAAA;AACvC,IAAO,OAAA,GAAA,CAAA;AAAA,GACT,EAAG,EAA4B,CAAA,CAAA;AAE/B,EAAO,OAAA,QAAA,CAAA;AACT;;;;"}
|