@backstage/plugin-catalog-react 0.0.0-nightly-20240827082736 → 0.0.0-nightly-20240829022758

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 CHANGED
@@ -1,13 +1,36 @@
1
1
  # @backstage/plugin-catalog-react
2
2
 
3
- ## 0.0.0-nightly-20240827082736
3
+ ## 0.0.0-nightly-20240829022758
4
4
 
5
5
  ### Patch Changes
6
6
 
7
+ - fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints.
7
8
  - 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130).
9
+ - ae9b6cb: Small internal fix to better work with recent `lodash` versions
8
10
  - Updated dependencies
9
- - @backstage/frontend-plugin-api@0.0.0-nightly-20240827082736
10
- - @backstage/core-compat-api@0.0.0-nightly-20240827082736
11
+ - @backstage/frontend-plugin-api@0.0.0-nightly-20240829022758
12
+ - @backstage/core-compat-api@0.0.0-nightly-20240829022758
13
+ - @backstage/catalog-client@0.0.0-nightly-20240829022758
14
+ - @backstage/catalog-model@1.6.0
15
+ - @backstage/core-components@0.14.10
16
+ - @backstage/core-plugin-api@1.9.3
17
+ - @backstage/errors@1.2.4
18
+ - @backstage/integration-react@1.1.30
19
+ - @backstage/types@1.1.1
20
+ - @backstage/version-bridge@1.0.8
21
+ - @backstage/plugin-catalog-common@1.0.26
22
+ - @backstage/plugin-permission-common@0.8.1
23
+ - @backstage/plugin-permission-react@0.4.25
24
+
25
+ ## 1.12.4-next.0
26
+
27
+ ### Patch Changes
28
+
29
+ - fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints.
30
+ - 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130).
31
+ - Updated dependencies
32
+ - @backstage/frontend-plugin-api@0.8.0-next.0
33
+ - @backstage/core-compat-api@0.2.9-next.0
11
34
  - @backstage/catalog-client@1.6.6
12
35
  - @backstage/catalog-model@1.6.0
13
36
  - @backstage/core-components@0.14.10
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-react__alpha",
3
- "version": "0.0.0-nightly-20240827082736",
3
+ "version": "0.0.0-nightly-20240829022758",
4
4
  "main": "../dist/alpha.esm.js",
5
5
  "module": "../dist/alpha.esm.js",
6
6
  "types": "../dist/alpha.d.ts"
@@ -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?:\n | typeof EntityCardBlueprint.dataRefs.filterFunction.T\n | typeof EntityCardBlueprint.dataRefs.filterExpression.T;\n },\n): ExtensionDefinition<any> {\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":";;;;;;;AAwBgB,SAAA,gCAAA,CACd,iBACA,SAM0B,EAAA;AAC1B,EAAM,MAAA,OAAA,uCAAW,eAAgB,EAAA,IAAA,CAAA,CAAA;AAEjC,EAAM,MAAA,OAAA,GAAU,gBAAyB,CAAA,OAAA,EAAS,oBAAoB,CAAA,CAAA;AACtE,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA,CAAA;AAAA,GACzC;AAEA,EAAM,MAAA,MAAA,GAAS,gBAAkC,CAAA,OAAA,EAAS,aAAa,CAAA,CAAA;AACvE,EAAM,MAAA,QAAA,GAAW,QAAQ,KAAM,EAAA,CAAA;AAE/B,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,KAAA,CAAM,kBAAkB,CAAA,CAAA;AAC9C,EAAM,MAAA,KAAA,GAAQ,KAAQ,GAAA,CAAC,CAAK,IAAA,OAAA,CAAA;AAE5B,EAAA,IAAI,IAA2B,GAAA,KAAA,CAAA;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,CAAA;AACjC,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,IAAA,GAAA,KAAA,CAAA,CAAA;AAAA,KACT;AAAA,GACF;AACA,EAAO,IAAA,GAAA,IAAA,IAAQ,UAAU,IAAI,CAAA,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,CAAA;AAAA,KAC3C;AAAA,GACD,CAAA,CAAA;AACH;;;;"}
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?:\n | typeof EntityCardBlueprint.dataRefs.filterFunction.T\n | typeof EntityCardBlueprint.dataRefs.filterExpression.T;\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":";;;;;;;AAwBgB,SAAA,gCAAA,CACd,iBACA,SAMqB,EAAA;AACrB,EAAM,MAAA,OAAA,uCAAW,eAAgB,EAAA,IAAA,CAAA,CAAA;AAEjC,EAAM,MAAA,OAAA,GAAU,gBAAyB,CAAA,OAAA,EAAS,oBAAoB,CAAA,CAAA;AACtE,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA,CAAA;AAAA,GACzC;AAEA,EAAM,MAAA,MAAA,GAAS,gBAAkC,CAAA,OAAA,EAAS,aAAa,CAAA,CAAA;AACvE,EAAM,MAAA,QAAA,GAAW,QAAQ,KAAM,EAAA,CAAA;AAE/B,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,KAAA,CAAM,kBAAkB,CAAA,CAAA;AAC9C,EAAM,MAAA,KAAA,GAAQ,KAAQ,GAAA,CAAC,CAAK,IAAA,OAAA,CAAA;AAE5B,EAAA,IAAI,IAA2B,GAAA,KAAA,CAAA;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,CAAA;AACjC,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,IAAA,GAAA,KAAA,CAAA,CAAA;AAAA,KACT;AAAA,GACF;AACA,EAAO,IAAA,GAAA,IAAA,IAAQ,UAAU,IAAI,CAAA,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,CAAA;AAAA,KAC3C;AAAA,GACD,CAAA,CAAA;AACH;;;;"}
@@ -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?:\n | typeof EntityContentBlueprint.dataRefs.filterFunction.T\n | typeof EntityContentBlueprint.dataRefs.filterExpression.T;\n defaultPath?: string;\n defaultTitle?: string;\n },\n): ExtensionDefinition<any> {\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":";;;;;;;;AAgCgB,SAAA,mCAAA,CACd,iBACA,SAQ0B,EAAA;AAC1B,EAAM,MAAA,OAAA,uCAAW,eAAgB,EAAA,IAAA,CAAA,CAAA;AAEjC,EAAM,MAAA,OAAA,GAAU,gBAAyB,CAAA,OAAA,EAAS,oBAAoB,CAAA,CAAA;AACtE,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA,CAAA;AAAA,GACzC;AAEA,EAAA,MAAM,UAAa,GAAA,gBAAA;AAAA,IACjB,OAAA;AAAA,IACA,iBAAA;AAAA,GACF,CAAA;AAEA,EAAM,MAAA,MAAA,GAAS,gBAAkC,CAAA,OAAA,EAAS,aAAa,CAAA,CAAA;AACvE,EAAM,MAAA,QAAA,GAAW,QAAQ,KAAM,EAAA,CAAA;AAE/B,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,KAAA,CAAM,qBAAqB,CAAA,CAAA;AACjD,EAAM,MAAA,KAAA,GAAQ,KAAQ,GAAA,CAAC,CAAK,IAAA,OAAA,CAAA;AAE5B,EAAA,IAAI,IAA2B,GAAA,KAAA,CAAA;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,CAAA;AACjC,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,IAAA,GAAA,KAAA,CAAA,CAAA;AAAA,KACT;AAAA,GACF;AACA,EAAO,IAAA,GAAA,IAAA,IAAQ,UAAU,IAAI,CAAA,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,CAAA;AAAA,KAC3C;AAAA,GACD,CAAA,CAAA;AACH;;;;"}
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?:\n | typeof EntityContentBlueprint.dataRefs.filterFunction.T\n | typeof EntityContentBlueprint.dataRefs.filterExpression.T;\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":";;;;;;;;AAgCgB,SAAA,mCAAA,CACd,iBACA,SAQqB,EAAA;AACrB,EAAM,MAAA,OAAA,uCAAW,eAAgB,EAAA,IAAA,CAAA,CAAA;AAEjC,EAAM,MAAA,OAAA,GAAU,gBAAyB,CAAA,OAAA,EAAS,oBAAoB,CAAA,CAAA;AACtE,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA,CAAA;AAAA,GACzC;AAEA,EAAA,MAAM,UAAa,GAAA,gBAAA;AAAA,IACjB,OAAA;AAAA,IACA,iBAAA;AAAA,GACF,CAAA;AAEA,EAAM,MAAA,MAAA,GAAS,gBAAkC,CAAA,OAAA,EAAS,aAAa,CAAA,CAAA;AACvE,EAAM,MAAA,QAAA,GAAW,QAAQ,KAAM,EAAA,CAAA;AAE/B,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,KAAA,CAAM,qBAAqB,CAAA,CAAA;AACjD,EAAM,MAAA,KAAA,GAAQ,KAAQ,GAAA,CAAC,CAAK,IAAA,OAAA,CAAA;AAE5B,EAAA,IAAI,IAA2B,GAAA,KAAA,CAAA;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,CAAA;AACjC,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,IAAA,GAAA,KAAA,CAAA,CAAA;AAAA,KACT;AAAA,GACF;AACA,EAAO,IAAA,GAAA,IAAA,IAAQ,UAAU,IAAI,CAAA,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,CAAA;AAAA,KAC3C;AAAA,GACD,CAAA,CAAA;AACH;;;;"}
package/dist/alpha.d.ts CHANGED
@@ -27,20 +27,26 @@ declare const EntityCardBlueprint: _backstage_frontend_plugin_api.ExtensionBluep
27
27
  kind: "entity-card";
28
28
  namespace: undefined;
29
29
  name: undefined;
30
- }, {
31
- loader: () => Promise<JSX.Element>;
32
- filter?: string | ((entity: _backstage_catalog_model.Entity) => boolean) | undefined;
33
- }, _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<React.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {
34
- optional: true;
35
- }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {
36
- optional: true;
37
- }>, {}, {
38
- filter: string | undefined;
39
- }, {
40
- filter?: string | undefined;
41
- }, {
42
- filterFunction: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {}>;
43
- filterExpression: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {}>;
30
+ params: {
31
+ loader: () => Promise<JSX.Element>;
32
+ filter?: string | ((entity: _backstage_catalog_model.Entity) => boolean) | undefined;
33
+ };
34
+ output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<React.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {
35
+ optional: true;
36
+ }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {
37
+ optional: true;
38
+ }>;
39
+ inputs: {};
40
+ config: {
41
+ filter: string | undefined;
42
+ };
43
+ configInput: {
44
+ filter?: string | undefined;
45
+ };
46
+ dataRefs: {
47
+ filterFunction: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {}>;
48
+ filterExpression: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {}>;
49
+ };
44
50
  }>;
45
51
 
46
52
  /**
@@ -51,37 +57,43 @@ declare const EntityContentBlueprint: _backstage_frontend_plugin_api.ExtensionBl
51
57
  kind: "entity-content";
52
58
  namespace: undefined;
53
59
  name: undefined;
54
- }, {
55
- loader: () => Promise<JSX.Element>;
56
- defaultPath: string;
57
- defaultTitle: string;
58
- routeRef?: RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams> | undefined;
59
- filter?: string | ((entity: _backstage_catalog_model.Entity) => boolean) | undefined;
60
- }, _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", {
61
- optional: true;
62
- }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-content-title", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {
63
- optional: true;
64
- }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {
65
- optional: true;
66
- }>, {}, {
67
- path: string | undefined;
68
- title: string | undefined;
69
- filter: string | undefined;
70
- }, {
71
- filter?: string | undefined;
72
- title?: string | undefined;
73
- path?: string | undefined;
74
- }, {
75
- title: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-content-title", {}>;
76
- filterFunction: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {}>;
77
- filterExpression: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {}>;
60
+ params: {
61
+ loader: () => Promise<JSX.Element>;
62
+ defaultPath: string;
63
+ defaultTitle: string;
64
+ routeRef?: RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams> | undefined;
65
+ filter?: string | ((entity: _backstage_catalog_model.Entity) => boolean) | undefined;
66
+ };
67
+ 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", {
68
+ optional: true;
69
+ }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-content-title", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {
70
+ optional: true;
71
+ }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {
72
+ optional: true;
73
+ }>;
74
+ inputs: {};
75
+ config: {
76
+ path: string | undefined;
77
+ title: string | undefined;
78
+ filter: string | undefined;
79
+ };
80
+ configInput: {
81
+ filter?: string | undefined;
82
+ title?: string | undefined;
83
+ path?: string | undefined;
84
+ };
85
+ dataRefs: {
86
+ title: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-content-title", {}>;
87
+ filterFunction: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {}>;
88
+ filterExpression: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {}>;
89
+ };
78
90
  }>;
79
91
 
80
92
  /** @alpha */
81
93
  declare function convertLegacyEntityCardExtension(LegacyExtension: ComponentType<{}>, overrides?: {
82
94
  name?: string;
83
95
  filter?: typeof EntityCardBlueprint.dataRefs.filterFunction.T | typeof EntityCardBlueprint.dataRefs.filterExpression.T;
84
- }): ExtensionDefinition<any>;
96
+ }): ExtensionDefinition;
85
97
 
86
98
  /** @alpha */
87
99
  declare function convertLegacyEntityContentExtension(LegacyExtension: ComponentType<{}>, overrides?: {
@@ -89,7 +101,7 @@ declare function convertLegacyEntityContentExtension(LegacyExtension: ComponentT
89
101
  filter?: typeof EntityContentBlueprint.dataRefs.filterFunction.T | typeof EntityContentBlueprint.dataRefs.filterExpression.T;
90
102
  defaultPath?: string;
91
103
  defaultTitle?: string;
92
- }): ExtensionDefinition<any>;
104
+ }): ExtensionDefinition;
93
105
 
94
106
  /** @alpha */
95
107
  declare const catalogReactTranslationRef: _backstage_core_plugin_api_alpha.TranslationRef<"catalog-react", {
@@ -25,6 +25,7 @@ function defaultEntityPresentation(entityOrRef, context) {
25
25
  // leave it up to the presentation API to handle
26
26
  };
27
27
  }
28
+ const isString = (value) => Boolean(value) && typeof value === "string";
28
29
  function getParts(entityOrRef) {
29
30
  if (typeof entityOrRef === "string") {
30
31
  let colonI = entityOrRef.indexOf(":");
@@ -38,29 +39,23 @@ function getParts(entityOrRef) {
38
39
  return { kind, namespace, name };
39
40
  }
40
41
  if (typeof entityOrRef === "object" && entityOrRef !== null) {
41
- const kind = [get(entityOrRef, "kind")].find(
42
- (candidate) => candidate && typeof candidate === "string"
43
- );
42
+ const kind = [get(entityOrRef, "kind")].find(isString);
44
43
  const namespace = [
45
44
  get(entityOrRef, "metadata.namespace"),
46
45
  get(entityOrRef, "namespace")
47
- ].find((candidate) => candidate && typeof candidate === "string");
46
+ ].find(isString);
48
47
  const name = [
49
48
  get(entityOrRef, "metadata.name"),
50
49
  get(entityOrRef, "name")
51
- ].find((candidate) => candidate && typeof candidate === "string");
52
- const title = [get(entityOrRef, "metadata.title")].find(
53
- (candidate) => candidate && typeof candidate === "string"
54
- );
50
+ ].find(isString);
51
+ const title = [get(entityOrRef, "metadata.title")].find(isString);
55
52
  const description = [get(entityOrRef, "metadata.description")].find(
56
- (candidate) => candidate && typeof candidate === "string"
53
+ isString
57
54
  );
58
55
  const displayName = [get(entityOrRef, "spec.profile.displayName")].find(
59
- (candidate) => candidate && typeof candidate === "string"
60
- );
61
- const type = [get(entityOrRef, "spec.type")].find(
62
- (candidate) => candidate && typeof candidate === "string"
56
+ isString
63
57
  );
58
+ const type = [get(entityOrRef, "spec.type")].find(isString);
64
59
  return { kind, namespace, name, title, description, displayName, type };
65
60
  }
66
61
  return {};
@@ -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\nconst isString = (value: unknown): value is string =>\n Boolean(value) && typeof value === 'string';\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(isString);\n\n const namespace = [\n get(entityOrRef, 'metadata.namespace'),\n get(entityOrRef, 'namespace'),\n ].find(isString);\n\n const name = [\n get(entityOrRef, 'metadata.name'),\n get(entityOrRef, 'name'),\n ].find(isString);\n\n const title = [get(entityOrRef, 'metadata.title')].find(isString);\n\n const description = [get(entityOrRef, 'metadata.description')].find(\n isString,\n );\n\n const displayName = [get(entityOrRef, 'spec.profile.displayName')].find(\n isString,\n );\n\n const type = [get(entityOrRef, 'spec.type')].find(isString);\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,6 +4,7 @@ import { catalogApiRef } from '../../api.esm.js';
4
4
  import { useState } from 'react';
5
5
  import get from 'lodash/get';
6
6
 
7
+ const maybeString = (value) => typeof value === "string" ? value : void 0;
7
8
  function useFacetsEntities({ enabled }) {
8
9
  const catalogApi = useApi(catalogApiRef);
9
10
  const [facetsPromise] = useState(async () => {
@@ -20,8 +21,8 @@ function useFacetsEntities({ enabled }) {
20
21
  (a, b) => (a.metadata.namespace || "").localeCompare(
21
22
  b.metadata.namespace || "",
22
23
  "en-US"
23
- ) || (get(a, "spec.profile.displayName") || a.metadata.title || a.metadata.name).localeCompare(
24
- get(b, "spec.profile.displayName") || b.metadata.title || b.metadata.name,
24
+ ) || (maybeString(get(a, "spec.profile.displayName")) || a.metadata.title || a.metadata.name).localeCompare(
25
+ maybeString(get(b, "spec.profile.displayName")) || b.metadata.title || b.metadata.name,
25
26
  "en-US"
26
27
  ) || a.kind.localeCompare(b.kind, "en-US")
27
28
  )
@@ -1 +1 @@
1
- {"version":3,"file":"useFacetsEntities.esm.js","sources":["../../../src/components/EntityOwnerPicker/useFacetsEntities.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 */\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport { catalogApiRef } from '../../api';\nimport { useState } from 'react';\nimport { Entity } from '@backstage/catalog-model';\nimport get from 'lodash/get';\n\ntype FacetsCursor = {\n start: number;\n text: string;\n};\n\ntype FacetsEntitiesResponse = {\n items: Entity[];\n cursor?: string;\n};\n\ntype FacetsInitialRequest = {\n text: string;\n};\n\n/**\n * This hook asynchronously loads the entity owners using the facets endpoint.\n * EntityOwnerPicker uses this hook when mode=\"owners-only\" is passed as prop.\n * All the owners are kept internally in memory and rendered in batches once requested\n * by the frontend. The values returned by this hook are compatible with `useQueryEntities`\n * hook, which is also used by EntityOwnerPicker.\n */\nexport function useFacetsEntities({ enabled }: { enabled: boolean }) {\n const catalogApi = useApi(catalogApiRef);\n\n const [facetsPromise] = useState(async () => {\n if (!enabled) {\n return [];\n }\n const facet = 'relations.ownedBy';\n const facetsResponse = await catalogApi.getEntityFacets({\n facets: [facet],\n });\n const entityRefs = facetsResponse.facets[facet]?.map(e => e.value) ?? [];\n\n return catalogApi\n .getEntitiesByRefs({ entityRefs })\n .then(resp =>\n resp.items\n .filter(entity => entity !== undefined)\n .map(entity => entity as Entity)\n .sort(\n (a, b) =>\n (a.metadata.namespace || '').localeCompare(\n b.metadata.namespace || '',\n 'en-US',\n ) ||\n (\n get(a, 'spec.profile.displayName') ||\n a.metadata.title ||\n a.metadata.name\n ).localeCompare(\n get(b, 'spec.profile.displayName') ||\n b.metadata.title ||\n b.metadata.name,\n 'en-US',\n ) ||\n a.kind.localeCompare(b.kind, 'en-US'),\n ),\n )\n .then(entities => entities)\n .catch(() => []);\n });\n\n return useAsyncFn<\n (\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n options?: { limit?: number },\n ) => Promise<FacetsEntitiesResponse>\n >(\n async (request, options) => {\n const facets = await facetsPromise;\n\n if (!facets) {\n return {\n items: [],\n };\n }\n\n const limit = options?.limit ?? 20;\n\n const { text, start } = decodeCursor(request);\n const filteredRefs = facets.filter(e => filterEntity(text, e));\n const end = start + limit;\n return {\n items: filteredRefs.slice(0, end),\n ...encodeCursor({\n entities: filteredRefs,\n limit: end,\n payload: {\n text,\n start: end,\n },\n }),\n };\n },\n [facetsPromise],\n { loading: true, value: { items: [] } },\n );\n}\n\nfunction decodeCursor(\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n): FacetsCursor {\n if (isFacetsResponse(request) && request.cursor) {\n return JSON.parse(atob(request.cursor));\n }\n return {\n text: (request as FacetsInitialRequest).text || '',\n start: 0,\n };\n}\n\nfunction isFacetsResponse(\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n): request is FacetsEntitiesResponse {\n return !!(request as FacetsEntitiesResponse).cursor;\n}\n\nfunction encodeCursor({\n entities,\n limit,\n payload,\n}: {\n entities: Entity[];\n limit: number;\n payload: { text: string; start: number };\n}) {\n if (entities.length > limit) {\n return { cursor: btoa(JSON.stringify(payload)) };\n }\n return {};\n}\n\nfunction filterEntity(text: string, entity: Entity) {\n const normalizedText = text.trim();\n return (\n entity.kind.includes(normalizedText) ||\n entity.metadata.namespace?.includes(normalizedText) ||\n entity.metadata.name.includes(normalizedText) ||\n entity.metadata.title?.includes(normalizedText) ||\n (get(entity, 'spec.profile.displayName') as unknown as string)?.includes(\n normalizedText,\n )\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useFacetsEntities.esm.js","sources":["../../../src/components/EntityOwnerPicker/useFacetsEntities.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 */\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport { catalogApiRef } from '../../api';\nimport { useState } from 'react';\nimport { Entity } from '@backstage/catalog-model';\nimport get from 'lodash/get';\n\ntype FacetsCursor = {\n start: number;\n text: string;\n};\n\ntype FacetsEntitiesResponse = {\n items: Entity[];\n cursor?: string;\n};\n\ntype FacetsInitialRequest = {\n text: string;\n};\n\nconst maybeString = (value: unknown): string | undefined =>\n typeof value === 'string' ? value : undefined;\n\n/**\n * This hook asynchronously loads the entity owners using the facets endpoint.\n * EntityOwnerPicker uses this hook when mode=\"owners-only\" is passed as prop.\n * All the owners are kept internally in memory and rendered in batches once requested\n * by the frontend. The values returned by this hook are compatible with `useQueryEntities`\n * hook, which is also used by EntityOwnerPicker.\n */\nexport function useFacetsEntities({ enabled }: { enabled: boolean }) {\n const catalogApi = useApi(catalogApiRef);\n\n const [facetsPromise] = useState(async () => {\n if (!enabled) {\n return [];\n }\n const facet = 'relations.ownedBy';\n const facetsResponse = await catalogApi.getEntityFacets({\n facets: [facet],\n });\n const entityRefs = facetsResponse.facets[facet]?.map(e => e.value) ?? [];\n\n return catalogApi\n .getEntitiesByRefs({ entityRefs })\n .then(resp =>\n resp.items\n .filter(entity => entity !== undefined)\n .map(entity => entity as Entity)\n .sort(\n (a, b) =>\n (a.metadata.namespace || '').localeCompare(\n b.metadata.namespace || '',\n 'en-US',\n ) ||\n (\n maybeString(get(a, 'spec.profile.displayName')) ||\n a.metadata.title ||\n a.metadata.name\n ).localeCompare(\n maybeString(get(b, 'spec.profile.displayName')) ||\n b.metadata.title ||\n b.metadata.name,\n 'en-US',\n ) ||\n a.kind.localeCompare(b.kind, 'en-US'),\n ),\n )\n .then(entities => entities)\n .catch(() => []);\n });\n\n return useAsyncFn<\n (\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n options?: { limit?: number },\n ) => Promise<FacetsEntitiesResponse>\n >(\n async (request, options) => {\n const facets = await facetsPromise;\n\n if (!facets) {\n return {\n items: [],\n };\n }\n\n const limit = options?.limit ?? 20;\n\n const { text, start } = decodeCursor(request);\n const filteredRefs = facets.filter(e => filterEntity(text, e));\n const end = start + limit;\n return {\n items: filteredRefs.slice(0, end),\n ...encodeCursor({\n entities: filteredRefs,\n limit: end,\n payload: {\n text,\n start: end,\n },\n }),\n };\n },\n [facetsPromise],\n { loading: true, value: { items: [] } },\n );\n}\n\nfunction decodeCursor(\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n): FacetsCursor {\n if (isFacetsResponse(request) && request.cursor) {\n return JSON.parse(atob(request.cursor));\n }\n return {\n text: (request as FacetsInitialRequest).text || '',\n start: 0,\n };\n}\n\nfunction isFacetsResponse(\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n): request is FacetsEntitiesResponse {\n return !!(request as FacetsEntitiesResponse).cursor;\n}\n\nfunction encodeCursor({\n entities,\n limit,\n payload,\n}: {\n entities: Entity[];\n limit: number;\n payload: { text: string; start: number };\n}) {\n if (entities.length > limit) {\n return { cursor: btoa(JSON.stringify(payload)) };\n }\n return {};\n}\n\nfunction filterEntity(text: string, entity: Entity) {\n const normalizedText = text.trim();\n return (\n entity.kind.includes(normalizedText) ||\n entity.metadata.namespace?.includes(normalizedText) ||\n entity.metadata.name.includes(normalizedText) ||\n entity.metadata.title?.includes(normalizedText) ||\n (get(entity, 'spec.profile.displayName') as unknown as string)?.includes(\n normalizedText,\n )\n );\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-react",
3
- "version": "0.0.0-nightly-20240827082736",
3
+ "version": "0.0.0-nightly-20240829022758",
4
4
  "description": "A frontend library that helps other Backstage plugins interact with the catalog",
5
5
  "backstage": {
6
6
  "role": "web-library",
@@ -56,13 +56,13 @@
56
56
  "test": "backstage-cli package test"
57
57
  },
58
58
  "dependencies": {
59
- "@backstage/catalog-client": "^1.6.6",
59
+ "@backstage/catalog-client": "^0.0.0-nightly-20240829022758",
60
60
  "@backstage/catalog-model": "^1.6.0",
61
- "@backstage/core-compat-api": "^0.0.0-nightly-20240827082736",
61
+ "@backstage/core-compat-api": "^0.0.0-nightly-20240829022758",
62
62
  "@backstage/core-components": "^0.14.10",
63
63
  "@backstage/core-plugin-api": "^1.9.3",
64
64
  "@backstage/errors": "^1.2.4",
65
- "@backstage/frontend-plugin-api": "^0.0.0-nightly-20240827082736",
65
+ "@backstage/frontend-plugin-api": "^0.0.0-nightly-20240829022758",
66
66
  "@backstage/integration-react": "^1.1.30",
67
67
  "@backstage/plugin-catalog-common": "^1.0.26",
68
68
  "@backstage/plugin-permission-common": "^0.8.1",
@@ -83,12 +83,12 @@
83
83
  "zen-observable": "^0.10.0"
84
84
  },
85
85
  "devDependencies": {
86
- "@backstage/cli": "^0.0.0-nightly-20240827082736",
86
+ "@backstage/cli": "^0.0.0-nightly-20240829022758",
87
87
  "@backstage/core-app-api": "^1.14.2",
88
- "@backstage/frontend-test-utils": "^0.0.0-nightly-20240827082736",
88
+ "@backstage/frontend-test-utils": "^0.0.0-nightly-20240829022758",
89
89
  "@backstage/plugin-catalog-common": "^1.0.26",
90
90
  "@backstage/plugin-scaffolder-common": "^1.5.5",
91
- "@backstage/test-utils": "^0.0.0-nightly-20240827082736",
91
+ "@backstage/test-utils": "^0.0.0-nightly-20240829022758",
92
92
  "@testing-library/dom": "^10.0.0",
93
93
  "@testing-library/jest-dom": "^6.0.0",
94
94
  "@testing-library/react": "^15.0.0",