@backstage/plugin-catalog-react 0.0.0-nightly-20250408023830 → 0.0.0-nightly-20250410023923

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.
Files changed (94) hide show
  1. package/CHANGELOG.md +111 -8
  2. package/dist/alpha/blueprints/EntityContentLayoutBlueprint.esm.js.map +1 -1
  3. package/dist/alpha/blueprints/EntityContextMenuItemBlueprint.esm.js +40 -0
  4. package/dist/alpha/blueprints/EntityContextMenuItemBlueprint.esm.js.map +1 -0
  5. package/dist/alpha/converters/convertLegacyEntityCardExtension.esm.js +3 -2
  6. package/dist/alpha/converters/convertLegacyEntityCardExtension.esm.js.map +1 -1
  7. package/dist/alpha/converters/convertLegacyEntityContentExtension.esm.js +3 -2
  8. package/dist/alpha/converters/convertLegacyEntityContentExtension.esm.js.map +1 -1
  9. package/dist/alpha.d.ts +39 -12
  10. package/dist/alpha.esm.js +1 -0
  11. package/dist/alpha.esm.js.map +1 -1
  12. package/dist/components/CatalogAutocomplete/CatalogAutocomplete.esm.js +15 -12
  13. package/dist/components/CatalogAutocomplete/CatalogAutocomplete.esm.js.map +1 -1
  14. package/dist/components/CatalogFilterLayout/CatalogFilterLayout.esm.js +37 -30
  15. package/dist/components/CatalogFilterLayout/CatalogFilterLayout.esm.js.map +1 -1
  16. package/dist/components/DefaultFilters/DefaultFilters.esm.js +16 -7
  17. package/dist/components/DefaultFilters/DefaultFilters.esm.js.map +1 -1
  18. package/dist/components/EntityAutocompletePicker/EntityAutocompletePicker.esm.js +5 -4
  19. package/dist/components/EntityAutocompletePicker/EntityAutocompletePicker.esm.js.map +1 -1
  20. package/dist/components/EntityAutocompletePicker/EntityAutocompletePickerOption.esm.js +7 -6
  21. package/dist/components/EntityAutocompletePicker/EntityAutocompletePickerOption.esm.js.map +1 -1
  22. package/dist/components/EntityDisplayName/EntityDisplayName.esm.js +7 -4
  23. package/dist/components/EntityDisplayName/EntityDisplayName.esm.js.map +1 -1
  24. package/dist/components/EntityKindPicker/EntityKindPicker.esm.js +4 -3
  25. package/dist/components/EntityKindPicker/EntityKindPicker.esm.js.map +1 -1
  26. package/dist/components/EntityLifecyclePicker/EntityLifecyclePicker.esm.js +2 -2
  27. package/dist/components/EntityLifecyclePicker/EntityLifecyclePicker.esm.js.map +1 -1
  28. package/dist/components/EntityNamespacePicker/EntityNamespacePicker.esm.js +2 -2
  29. package/dist/components/EntityNamespacePicker/EntityNamespacePicker.esm.js.map +1 -1
  30. package/dist/components/EntityOwnerPicker/EntityOwnerPicker.esm.js +15 -10
  31. package/dist/components/EntityOwnerPicker/EntityOwnerPicker.esm.js.map +1 -1
  32. package/dist/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.esm.js +5 -5
  33. package/dist/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.esm.js.map +1 -1
  34. package/dist/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.esm.js +5 -5
  35. package/dist/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.esm.js.map +1 -1
  36. package/dist/components/EntityPeekAheadPopover/CardActionComponents/GroupCardActions.esm.js +2 -2
  37. package/dist/components/EntityPeekAheadPopover/CardActionComponents/GroupCardActions.esm.js.map +1 -1
  38. package/dist/components/EntityPeekAheadPopover/CardActionComponents/UserCardActions.esm.js +2 -2
  39. package/dist/components/EntityPeekAheadPopover/CardActionComponents/UserCardActions.esm.js.map +1 -1
  40. package/dist/components/EntityPeekAheadPopover/EntityPeekAheadPopover.esm.js +60 -35
  41. package/dist/components/EntityPeekAheadPopover/EntityPeekAheadPopover.esm.js.map +1 -1
  42. package/dist/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.esm.js +8 -7
  43. package/dist/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.esm.js.map +1 -1
  44. package/dist/components/EntityRefLink/EntityRefLink.esm.js +4 -3
  45. package/dist/components/EntityRefLink/EntityRefLink.esm.js.map +1 -1
  46. package/dist/components/EntityRefLink/EntityRefLinks.esm.js +8 -4
  47. package/dist/components/EntityRefLink/EntityRefLinks.esm.js.map +1 -1
  48. package/dist/components/EntitySearchBar/EntitySearchBar.esm.js +10 -9
  49. package/dist/components/EntitySearchBar/EntitySearchBar.esm.js.map +1 -1
  50. package/dist/components/EntityTable/EntityTable.esm.js +3 -3
  51. package/dist/components/EntityTable/EntityTable.esm.js.map +1 -1
  52. package/dist/components/EntityTable/columns.esm.js +4 -4
  53. package/dist/components/EntityTable/columns.esm.js.map +1 -1
  54. package/dist/components/EntityTagPicker/EntityTagPicker.esm.js +2 -2
  55. package/dist/components/EntityTagPicker/EntityTagPicker.esm.js.map +1 -1
  56. package/dist/components/EntityTypePicker/EntityTypePicker.esm.js +4 -3
  57. package/dist/components/EntityTypePicker/EntityTypePicker.esm.js.map +1 -1
  58. package/dist/components/FavoriteEntity/FavoriteEntity.esm.js +2 -2
  59. package/dist/components/FavoriteEntity/FavoriteEntity.esm.js.map +1 -1
  60. package/dist/components/InspectEntityDialog/InspectEntityDialog.esm.js +36 -26
  61. package/dist/components/InspectEntityDialog/InspectEntityDialog.esm.js.map +1 -1
  62. package/dist/components/InspectEntityDialog/components/AncestryPage.esm.js +67 -52
  63. package/dist/components/InspectEntityDialog/components/AncestryPage.esm.js.map +1 -1
  64. package/dist/components/InspectEntityDialog/components/ColocatedPage.esm.js +32 -21
  65. package/dist/components/InspectEntityDialog/components/ColocatedPage.esm.js.map +1 -1
  66. package/dist/components/InspectEntityDialog/components/EntityKindIcon.esm.js +2 -2
  67. package/dist/components/InspectEntityDialog/components/EntityKindIcon.esm.js.map +1 -1
  68. package/dist/components/InspectEntityDialog/components/JsonPage.esm.js +13 -9
  69. package/dist/components/InspectEntityDialog/components/JsonPage.esm.js.map +1 -1
  70. package/dist/components/InspectEntityDialog/components/OverviewPage.esm.js +76 -34
  71. package/dist/components/InspectEntityDialog/components/OverviewPage.esm.js.map +1 -1
  72. package/dist/components/InspectEntityDialog/components/YamlPage.esm.js +13 -9
  73. package/dist/components/InspectEntityDialog/components/YamlPage.esm.js.map +1 -1
  74. package/dist/components/InspectEntityDialog/components/common.esm.js +21 -12
  75. package/dist/components/InspectEntityDialog/components/common.esm.js.map +1 -1
  76. package/dist/components/MissingAnnotationEmptyState/MissingAnnotationEmptyState.esm.js +39 -13
  77. package/dist/components/MissingAnnotationEmptyState/MissingAnnotationEmptyState.esm.js.map +1 -1
  78. package/dist/components/UnregisterEntityDialog/UnregisterEntityDialog.esm.js +106 -70
  79. package/dist/components/UnregisterEntityDialog/UnregisterEntityDialog.esm.js.map +1 -1
  80. package/dist/components/UserListPicker/UserListPicker.esm.js +36 -27
  81. package/dist/components/UserListPicker/UserListPicker.esm.js.map +1 -1
  82. package/dist/deprecated.esm.js +3 -2
  83. package/dist/deprecated.esm.js.map +1 -1
  84. package/dist/hooks/useEntity.esm.js +7 -7
  85. package/dist/hooks/useEntity.esm.js.map +1 -1
  86. package/dist/hooks/useEntityContextMenu.esm.js +18 -0
  87. package/dist/hooks/useEntityContextMenu.esm.js.map +1 -0
  88. package/dist/hooks/useEntityListProvider.esm.js +3 -2
  89. package/dist/hooks/useEntityListProvider.esm.js.map +1 -1
  90. package/dist/index.d.ts +34 -32
  91. package/dist/testUtils/MockEntityListContextProvider.esm.js +3 -2
  92. package/dist/testUtils/MockEntityListContextProvider.esm.js.map +1 -1
  93. package/dist/testUtils.d.ts +3 -2
  94. package/package.json +11 -11
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @backstage/plugin-catalog-react
2
2
 
3
- ## 0.0.0-nightly-20250408023830
3
+ ## 0.0.0-nightly-20250410023923
4
4
 
5
5
  ### Minor Changes
6
6
 
@@ -11,25 +11,128 @@
11
11
  - import { CatalogFilterBlueprint } from '@backstage/plugin-catalog/alpha';
12
12
  ```
13
13
 
14
+ - 09afd67: Adds `EntityContextMenuItemBlueprint` to enable extending the entity page's context menu with user defined items.
15
+
16
+ For example:
17
+
18
+ ```ts
19
+ import { EntityContextMenuItemBlueprint } from '@backstage/plugin-catalog-react/alpha';
20
+
21
+ const myCustomHref = EntityContextMenuItemBlueprint.make({
22
+ name: 'test-href',
23
+ params: {
24
+ icon: <span>Example Icon</span>,
25
+ useProps: () => ({
26
+ title: 'Example Href',
27
+ href: '/example-path',
28
+ disabled: false,
29
+ component: 'a',
30
+ }),
31
+ },
32
+ });
33
+
34
+ const myCustomOnClick = EntityContextMenuItemBlueprint.make({
35
+ name: 'test-click',
36
+ params: {
37
+ icon: <span>Test Icon</span>,
38
+ useProps: () => ({
39
+ title: 'Example onClick',
40
+ onClick: () => window.alert('Hello world!'),
41
+ disabled: false,
42
+ }),
43
+ },
44
+ });
45
+ ```
46
+
14
47
  ### Patch Changes
15
48
 
49
+ - a47fd39: Removes instances of default React imports, a necessary update for the upcoming React 19 migration.
50
+
51
+ <https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html>
52
+
16
53
  - 186d016: Add `operation` to alpha `defaultEntityContentGroups`.
17
54
  - 221ddba: Fix offset pagination to reset when updating filters in `useEntityList`
18
55
  - Updated dependencies
19
- - @backstage/core-components@0.0.0-nightly-20250408023830
20
- - @backstage/integration-react@0.0.0-nightly-20250408023830
21
- - @backstage/core-compat-api@0.0.0-nightly-20250408023830
56
+ - @backstage/frontend-plugin-api@0.0.0-nightly-20250410023923
57
+ - @backstage/frontend-test-utils@0.0.0-nightly-20250410023923
58
+ - @backstage/integration-react@0.0.0-nightly-20250410023923
59
+ - @backstage/core-compat-api@0.0.0-nightly-20250410023923
60
+ - @backstage/core-components@0.0.0-nightly-20250410023923
61
+ - @backstage/core-plugin-api@0.0.0-nightly-20250410023923
62
+ - @backstage/plugin-permission-react@0.0.0-nightly-20250410023923
63
+ - @backstage/catalog-client@1.9.1
64
+ - @backstage/catalog-model@1.7.3
65
+ - @backstage/errors@1.2.7
66
+ - @backstage/types@1.2.1
67
+ - @backstage/version-bridge@1.0.11
68
+ - @backstage/plugin-catalog-common@1.1.3
69
+ - @backstage/plugin-permission-common@0.8.4
70
+
71
+ ## 1.17.0-next.2
72
+
73
+ ### Minor Changes
74
+
75
+ - 61d350f: **BREAKING ALPHA**: `CatalogFilterBlueprint`, used in the new frontend system, is now exported under plugin-catalog-react instead of plugin-catalog.
76
+
77
+ ```diff
78
+ + import { CatalogFilterBlueprint } from '@backstage/plugin-catalog-react/alpha';
79
+ - import { CatalogFilterBlueprint } from '@backstage/plugin-catalog/alpha';
80
+ ```
81
+
82
+ - 09afd67: Adds `EntityContextMenuItemBlueprint` to enable extending the entity page's context menu with user defined items.
83
+
84
+ For example:
85
+
86
+ ```ts
87
+ import { EntityContextMenuItemBlueprint } from '@backstage/plugin-catalog-react/alpha';
88
+
89
+ const myCustomHref = EntityContextMenuItemBlueprint.make({
90
+ name: 'test-href',
91
+ params: {
92
+ icon: <span>Example Icon</span>,
93
+ useProps: () => ({
94
+ title: 'Example Href',
95
+ href: '/example-path',
96
+ disabled: false,
97
+ component: 'a',
98
+ }),
99
+ },
100
+ });
101
+
102
+ const myCustomOnClick = EntityContextMenuItemBlueprint.make({
103
+ name: 'test-click',
104
+ params: {
105
+ icon: <span>Test Icon</span>,
106
+ useProps: () => ({
107
+ title: 'Example onClick',
108
+ onClick: () => window.alert('Hello world!'),
109
+ disabled: false,
110
+ }),
111
+ },
112
+ });
113
+ ```
114
+
115
+ ### Patch Changes
116
+
117
+ - a47fd39: Removes instances of default React imports, a necessary update for the upcoming React 19 migration.
118
+
119
+ <https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html>
120
+
121
+ - Updated dependencies
122
+ - @backstage/frontend-plugin-api@0.10.1-next.1
123
+ - @backstage/frontend-test-utils@0.3.1-next.1
124
+ - @backstage/integration-react@1.2.6-next.1
125
+ - @backstage/core-compat-api@0.4.1-next.2
126
+ - @backstage/core-components@0.17.1-next.1
127
+ - @backstage/core-plugin-api@1.10.6-next.0
128
+ - @backstage/plugin-permission-react@0.4.33-next.0
22
129
  - @backstage/catalog-client@1.9.1
23
130
  - @backstage/catalog-model@1.7.3
24
- - @backstage/core-plugin-api@1.10.5
25
131
  - @backstage/errors@1.2.7
26
- - @backstage/frontend-plugin-api@0.0.0-nightly-20250408023830
27
- - @backstage/frontend-test-utils@0.0.0-nightly-20250408023830
28
132
  - @backstage/types@1.2.1
29
133
  - @backstage/version-bridge@1.0.11
30
134
  - @backstage/plugin-catalog-common@1.1.3
31
135
  - @backstage/plugin-permission-common@0.8.4
32
- - @backstage/plugin-permission-react@0.4.32
33
136
 
34
137
  ## 1.16.1-next.1
35
138
 
@@ -1 +1 @@
1
- {"version":3,"file":"EntityContentLayoutBlueprint.esm.js","sources":["../../../src/alpha/blueprints/EntityContentLayoutBlueprint.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createExtensionDataRef,\n createExtensionBlueprint,\n ExtensionBoundary,\n} from '@backstage/frontend-plugin-api';\nimport {\n entityFilterExpressionDataRef,\n entityFilterFunctionDataRef,\n EntityCardType,\n} from './extensionData';\nimport React from 'react';\nimport { EntityPredicate } from '../predicates';\nimport { resolveEntityFilterData } from './resolveEntityFilterData';\nimport { createEntityPredicateSchema } from '../predicates/createEntityPredicateSchema';\nimport { Entity } from '@backstage/catalog-model';\n\n/** @alpha */\nexport interface EntityContentLayoutProps {\n cards: Array<{\n type?: EntityCardType;\n element: React.JSX.Element;\n }>;\n}\n\nconst entityCardLayoutComponentDataRef = createExtensionDataRef<\n (props: EntityContentLayoutProps) => React.JSX.Element\n>().with({\n id: 'catalog.entity-content-layout.component',\n});\n\n/** @alpha */\nexport const EntityContentLayoutBlueprint = createExtensionBlueprint({\n kind: 'entity-content-layout',\n attachTo: { id: 'entity-content:catalog/overview', input: 'layouts' },\n output: [\n entityFilterFunctionDataRef.optional(),\n entityFilterExpressionDataRef.optional(),\n entityCardLayoutComponentDataRef,\n ],\n dataRefs: {\n filterFunction: entityFilterFunctionDataRef,\n filterExpression: entityFilterExpressionDataRef,\n component: entityCardLayoutComponentDataRef,\n },\n config: {\n schema: {\n type: z => z.string().optional(),\n filter: z =>\n z.union([z.string(), createEntityPredicateSchema(z)]).optional(),\n },\n },\n *factory(\n {\n loader,\n filter,\n }: {\n filter?: string | EntityPredicate | ((entity: Entity) => boolean);\n loader: () => Promise<\n (props: EntityContentLayoutProps) => React.JSX.Element\n >;\n },\n { node, config },\n ) {\n yield* resolveEntityFilterData(filter, config, node);\n\n yield entityCardLayoutComponentDataRef(\n ExtensionBoundary.lazyComponent(node, loader),\n );\n },\n});\n"],"names":[],"mappings":";;;;;AAwCA,MAAM,gCAAA,GAAmC,sBAEvC,EAAA,CAAE,IAAK,CAAA;AAAA,EACP,EAAI,EAAA;AACN,CAAC,CAAA;AAGM,MAAM,+BAA+B,wBAAyB,CAAA;AAAA,EACnE,IAAM,EAAA,uBAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,iCAAA,EAAmC,OAAO,SAAU,EAAA;AAAA,EACpE,MAAQ,EAAA;AAAA,IACN,4BAA4B,QAAS,EAAA;AAAA,IACrC,8BAA8B,QAAS,EAAA;AAAA,IACvC;AAAA,GACF;AAAA,EACA,QAAU,EAAA;AAAA,IACR,cAAgB,EAAA,2BAAA;AAAA,IAChB,gBAAkB,EAAA,6BAAA;AAAA,IAClB,SAAW,EAAA;AAAA,GACb;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA;AAAA,MACN,IAAM,EAAA,CAAA,CAAA,KAAK,CAAE,CAAA,MAAA,GAAS,QAAS,EAAA;AAAA,MAC/B,MAAQ,EAAA,CAAA,CAAA,KACN,CAAE,CAAA,KAAA,CAAM,CAAC,CAAA,CAAE,MAAO,EAAA,EAAG,2BAA4B,CAAA,CAAC,CAAC,CAAC,EAAE,QAAS;AAAA;AACnE,GACF;AAAA,EACA,CAAC,OACC,CAAA;AAAA,IACE,MAAA;AAAA,IACA;AAAA,GAOF,EAAA,EAAE,IAAM,EAAA,MAAA,EACR,EAAA;AACA,IAAO,OAAA,uBAAA,CAAwB,MAAQ,EAAA,MAAA,EAAQ,IAAI,CAAA;AAEnD,IAAM,MAAA,gCAAA;AAAA,MACJ,iBAAA,CAAkB,aAAc,CAAA,IAAA,EAAM,MAAM;AAAA,KAC9C;AAAA;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"EntityContentLayoutBlueprint.esm.js","sources":["../../../src/alpha/blueprints/EntityContentLayoutBlueprint.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createExtensionDataRef,\n createExtensionBlueprint,\n ExtensionBoundary,\n} from '@backstage/frontend-plugin-api';\nimport {\n entityFilterExpressionDataRef,\n entityFilterFunctionDataRef,\n EntityCardType,\n} from './extensionData';\nimport { JSX } from 'react';\nimport { EntityPredicate } from '../predicates';\nimport { resolveEntityFilterData } from './resolveEntityFilterData';\nimport { createEntityPredicateSchema } from '../predicates/createEntityPredicateSchema';\nimport { Entity } from '@backstage/catalog-model';\n\n/** @alpha */\nexport interface EntityContentLayoutProps {\n cards: Array<{\n type?: EntityCardType;\n element: JSX.Element;\n }>;\n}\n\nconst entityCardLayoutComponentDataRef = createExtensionDataRef<\n (props: EntityContentLayoutProps) => React.JSX.Element\n>().with({\n id: 'catalog.entity-content-layout.component',\n});\n\n/** @alpha */\nexport const EntityContentLayoutBlueprint = createExtensionBlueprint({\n kind: 'entity-content-layout',\n attachTo: { id: 'entity-content:catalog/overview', input: 'layouts' },\n output: [\n entityFilterFunctionDataRef.optional(),\n entityFilterExpressionDataRef.optional(),\n entityCardLayoutComponentDataRef,\n ],\n dataRefs: {\n filterFunction: entityFilterFunctionDataRef,\n filterExpression: entityFilterExpressionDataRef,\n component: entityCardLayoutComponentDataRef,\n },\n config: {\n schema: {\n type: z => z.string().optional(),\n filter: z =>\n z.union([z.string(), createEntityPredicateSchema(z)]).optional(),\n },\n },\n *factory(\n {\n loader,\n filter,\n }: {\n filter?: string | EntityPredicate | ((entity: Entity) => boolean);\n loader: () => Promise<(props: EntityContentLayoutProps) => JSX.Element>;\n },\n { node, config },\n ) {\n yield* resolveEntityFilterData(filter, config, node);\n\n yield entityCardLayoutComponentDataRef(\n ExtensionBoundary.lazyComponent(node, loader),\n );\n },\n});\n"],"names":[],"mappings":";;;;;AAwCA,MAAM,gCAAA,GAAmC,sBAEvC,EAAA,CAAE,IAAK,CAAA;AAAA,EACP,EAAI,EAAA;AACN,CAAC,CAAA;AAGM,MAAM,+BAA+B,wBAAyB,CAAA;AAAA,EACnE,IAAM,EAAA,uBAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,iCAAA,EAAmC,OAAO,SAAU,EAAA;AAAA,EACpE,MAAQ,EAAA;AAAA,IACN,4BAA4B,QAAS,EAAA;AAAA,IACrC,8BAA8B,QAAS,EAAA;AAAA,IACvC;AAAA,GACF;AAAA,EACA,QAAU,EAAA;AAAA,IACR,cAAgB,EAAA,2BAAA;AAAA,IAChB,gBAAkB,EAAA,6BAAA;AAAA,IAClB,SAAW,EAAA;AAAA,GACb;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA;AAAA,MACN,IAAM,EAAA,CAAA,CAAA,KAAK,CAAE,CAAA,MAAA,GAAS,QAAS,EAAA;AAAA,MAC/B,MAAQ,EAAA,CAAA,CAAA,KACN,CAAE,CAAA,KAAA,CAAM,CAAC,CAAA,CAAE,MAAO,EAAA,EAAG,2BAA4B,CAAA,CAAC,CAAC,CAAC,EAAE,QAAS;AAAA;AACnE,GACF;AAAA,EACA,CAAC,OACC,CAAA;AAAA,IACE,MAAA;AAAA,IACA;AAAA,GAKF,EAAA,EAAE,IAAM,EAAA,MAAA,EACR,EAAA;AACA,IAAO,OAAA,uBAAA,CAAwB,MAAQ,EAAA,MAAA,EAAQ,IAAI,CAAA;AAEnD,IAAM,MAAA,gCAAA;AAAA,MACJ,iBAAA,CAAkB,aAAc,CAAA,IAAA,EAAM,MAAM;AAAA,KAC9C;AAAA;AAEJ,CAAC;;;;"}
@@ -0,0 +1,40 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { createExtensionBlueprint, coreExtensionData, ExtensionBoundary } from '@backstage/frontend-plugin-api';
3
+ import MenuItem from '@material-ui/core/MenuItem';
4
+ import ListItemIcon from '@material-ui/core/ListItemIcon';
5
+ import ListItemText from '@material-ui/core/ListItemText';
6
+ import { useEntityContextMenu } from '../../hooks/useEntityContextMenu.esm.js';
7
+
8
+ const EntityContextMenuItemBlueprint = createExtensionBlueprint({
9
+ kind: "entity-context-menu-item",
10
+ attachTo: { id: "page:catalog/entity", input: "contextMenuItems" },
11
+ output: [coreExtensionData.reactElement],
12
+ *factory(params, { node }) {
13
+ const loader = async () => {
14
+ const Component = () => {
15
+ const { onMenuClose } = useEntityContextMenu();
16
+ const { title, ...menuItemProps } = params.useProps();
17
+ let handleClick = void 0;
18
+ if ("onClick" in menuItemProps) {
19
+ handleClick = () => {
20
+ const result = menuItemProps.onClick();
21
+ if (result && "then" in result) {
22
+ result.then(onMenuClose, onMenuClose);
23
+ } else {
24
+ onMenuClose();
25
+ }
26
+ };
27
+ }
28
+ return /* @__PURE__ */ jsxs(MenuItem, { ...menuItemProps, onClick: handleClick, children: [
29
+ /* @__PURE__ */ jsx(ListItemIcon, { children: params.icon }),
30
+ /* @__PURE__ */ jsx(ListItemText, { primary: title })
31
+ ] });
32
+ };
33
+ return /* @__PURE__ */ jsx(Component, {});
34
+ };
35
+ yield coreExtensionData.reactElement(ExtensionBoundary.lazy(node, loader));
36
+ }
37
+ });
38
+
39
+ export { EntityContextMenuItemBlueprint };
40
+ //# sourceMappingURL=EntityContextMenuItemBlueprint.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityContextMenuItemBlueprint.esm.js","sources":["../../../src/alpha/blueprints/EntityContextMenuItemBlueprint.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ReactNode, JSX } from 'react';\nimport {\n coreExtensionData,\n createExtensionBlueprint,\n ExtensionBoundary,\n} from '@backstage/frontend-plugin-api';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { useEntityContextMenu } from '../../hooks/useEntityContextMenu';\n\n/** @alpha */\nexport type UseProps = () =>\n | {\n title: ReactNode;\n href: string;\n disabled?: boolean;\n }\n | {\n title: ReactNode;\n onClick: () => void | Promise<void>;\n disabled?: boolean;\n };\n\n/** @alpha */\nexport type EntityContextMenuItemParams = {\n useProps: UseProps;\n icon: JSX.Element;\n};\n\n/** @alpha */\nexport const EntityContextMenuItemBlueprint = createExtensionBlueprint({\n kind: 'entity-context-menu-item',\n attachTo: { id: 'page:catalog/entity', input: 'contextMenuItems' },\n output: [coreExtensionData.reactElement],\n *factory(params: EntityContextMenuItemParams, { node }) {\n const loader = async () => {\n const Component = () => {\n const { onMenuClose } = useEntityContextMenu();\n const { title, ...menuItemProps } = params.useProps();\n let handleClick = undefined;\n\n if ('onClick' in menuItemProps) {\n handleClick = () => {\n const result = menuItemProps.onClick();\n if (result && 'then' in result) {\n result.then(onMenuClose, onMenuClose);\n } else {\n onMenuClose();\n }\n };\n }\n\n return (\n <MenuItem {...menuItemProps} onClick={handleClick}>\n <ListItemIcon>{params.icon}</ListItemIcon>\n <ListItemText primary={title} />\n </MenuItem>\n );\n };\n\n return <Component />;\n };\n\n yield coreExtensionData.reactElement(ExtensionBoundary.lazy(node, loader));\n },\n});\n"],"names":[],"mappings":";;;;;;;AA+CO,MAAM,iCAAiC,wBAAyB,CAAA;AAAA,EACrE,IAAM,EAAA,0BAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,qBAAA,EAAuB,OAAO,kBAAmB,EAAA;AAAA,EACjE,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,CAAC,OAAA,CAAQ,MAAqC,EAAA,EAAE,MAAQ,EAAA;AACtD,IAAA,MAAM,SAAS,YAAY;AACzB,MAAA,MAAM,YAAY,MAAM;AACtB,QAAM,MAAA,EAAE,WAAY,EAAA,GAAI,oBAAqB,EAAA;AAC7C,QAAA,MAAM,EAAE,KAAO,EAAA,GAAG,aAAc,EAAA,GAAI,OAAO,QAAS,EAAA;AACpD,QAAA,IAAI,WAAc,GAAA,KAAA,CAAA;AAElB,QAAA,IAAI,aAAa,aAAe,EAAA;AAC9B,UAAA,WAAA,GAAc,MAAM;AAClB,YAAM,MAAA,MAAA,GAAS,cAAc,OAAQ,EAAA;AACrC,YAAI,IAAA,MAAA,IAAU,UAAU,MAAQ,EAAA;AAC9B,cAAO,MAAA,CAAA,IAAA,CAAK,aAAa,WAAW,CAAA;AAAA,aAC/B,MAAA;AACL,cAAY,WAAA,EAAA;AAAA;AACd,WACF;AAAA;AAGF,QAAA,uBACG,IAAA,CAAA,QAAA,EAAA,EAAU,GAAG,aAAA,EAAe,SAAS,WACpC,EAAA,QAAA,EAAA;AAAA,0BAAC,GAAA,CAAA,YAAA,EAAA,EAAc,iBAAO,IAAK,EAAA,CAAA;AAAA,0BAC3B,GAAA,CAAC,YAAa,EAAA,EAAA,OAAA,EAAS,KAAO,EAAA;AAAA,SAChC,EAAA,CAAA;AAAA,OAEJ;AAEA,MAAA,2BAAQ,SAAU,EAAA,EAAA,CAAA;AAAA,KACpB;AAEA,IAAA,MAAM,kBAAkB,YAAa,CAAA,iBAAA,CAAkB,IAAK,CAAA,IAAA,EAAM,MAAM,CAAC,CAAA;AAAA;AAE7E,CAAC;;;;"}
@@ -1,16 +1,17 @@
1
+ import { jsx } from 'react/jsx-runtime';
1
2
  import { compatWrapper } from '@backstage/core-compat-api';
2
3
  import { getComponentData } from '@backstage/core-plugin-api';
3
- import React from 'react';
4
4
  import '../blueprints/CatalogFilterBlueprint.esm.js';
5
5
  import { EntityCardBlueprint } from '../blueprints/EntityCardBlueprint.esm.js';
6
6
  import '../blueprints/EntityContentBlueprint.esm.js';
7
7
  import '../blueprints/EntityContentLayoutBlueprint.esm.js';
8
8
  import '../blueprints/EntityHeaderBlueprint.esm.js';
9
9
  import '../blueprints/extensionData.esm.js';
10
+ import '../blueprints/EntityContextMenuItemBlueprint.esm.js';
10
11
  import kebabCase from 'lodash/kebabCase';
11
12
 
12
13
  function convertLegacyEntityCardExtension(LegacyExtension, overrides) {
13
- const element = /* @__PURE__ */ React.createElement(LegacyExtension, null);
14
+ const element = /* @__PURE__ */ jsx(LegacyExtension, {});
14
15
  const extName = getComponentData(element, "core.extensionName");
15
16
  if (!extName) {
16
17
  throw new Error("Extension has no name");
@@ -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';\nimport { EntityPredicate } from '../predicates';\nimport { Entity } from '@backstage/catalog-model';\n\n/** @alpha */\nexport function convertLegacyEntityCardExtension(\n LegacyExtension: ComponentType<{}>,\n overrides?: {\n name?: string;\n filter?: string | EntityPredicate | ((entity: Entity) => boolean);\n },\n): ExtensionDefinition {\n const element = <LegacyExtension />;\n\n const extName = getComponentData<string>(element, 'core.extensionName');\n if (!extName) {\n throw new Error('Extension has no name');\n }\n\n const plugin = getComponentData<BackstagePlugin>(element, 'core.plugin');\n const pluginId = plugin?.getId();\n\n const match = extName.match(/^Entity(.*)Card$/);\n const infix = match?.[1] ?? extName;\n\n let name: string | undefined = infix;\n if (\n pluginId &&\n name\n .toLocaleLowerCase('en-US')\n .startsWith(pluginId.toLocaleLowerCase('en-US'))\n ) {\n name = name.slice(pluginId.length);\n if (!name) {\n name = undefined;\n }\n }\n name = name && kebabCase(name);\n\n return EntityCardBlueprint.make({\n name: overrides?.name ?? name,\n params: {\n filter: overrides?.filter,\n loader: async () => compatWrapper(element),\n },\n });\n}\n"],"names":[],"mappings":";;;;;;;;;;;AA0BgB,SAAA,gCAAA,CACd,iBACA,SAIqB,EAAA;AACrB,EAAM,MAAA,OAAA,uCAAW,eAAgB,EAAA,IAAA,CAAA;AAEjC,EAAM,MAAA,OAAA,GAAU,gBAAyB,CAAA,OAAA,EAAS,oBAAoB,CAAA;AACtE,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA;AAAA;AAGzC,EAAM,MAAA,MAAA,GAAS,gBAAkC,CAAA,OAAA,EAAS,aAAa,CAAA;AACvE,EAAM,MAAA,QAAA,GAAW,QAAQ,KAAM,EAAA;AAE/B,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,KAAA,CAAM,kBAAkB,CAAA;AAC9C,EAAM,MAAA,KAAA,GAAQ,KAAQ,GAAA,CAAC,CAAK,IAAA,OAAA;AAE5B,EAAA,IAAI,IAA2B,GAAA,KAAA;AAC/B,EACE,IAAA,QAAA,IACA,IACG,CAAA,iBAAA,CAAkB,OAAO,CAAA,CACzB,WAAW,QAAS,CAAA,iBAAA,CAAkB,OAAO,CAAC,CACjD,EAAA;AACA,IAAO,IAAA,GAAA,IAAA,CAAK,KAAM,CAAA,QAAA,CAAS,MAAM,CAAA;AACjC,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,IAAA,GAAA,KAAA,CAAA;AAAA;AACT;AAEF,EAAO,IAAA,GAAA,IAAA,IAAQ,UAAU,IAAI,CAAA;AAE7B,EAAA,OAAO,oBAAoB,IAAK,CAAA;AAAA,IAC9B,IAAA,EAAM,WAAW,IAAQ,IAAA,IAAA;AAAA,IACzB,MAAQ,EAAA;AAAA,MACN,QAAQ,SAAW,EAAA,MAAA;AAAA,MACnB,MAAA,EAAQ,YAAY,aAAA,CAAc,OAAO;AAAA;AAC3C,GACD,CAAA;AACH;;;;"}
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 { ComponentType } from 'react';\nimport { EntityCardBlueprint } from '../blueprints';\nimport kebabCase from 'lodash/kebabCase';\nimport { EntityPredicate } from '../predicates';\nimport { Entity } from '@backstage/catalog-model';\n\n/** @alpha */\nexport function convertLegacyEntityCardExtension(\n LegacyExtension: ComponentType<{}>,\n overrides?: {\n name?: string;\n filter?: string | EntityPredicate | ((entity: Entity) => boolean);\n },\n): ExtensionDefinition {\n const element = <LegacyExtension />;\n\n const extName = getComponentData<string>(element, 'core.extensionName');\n if (!extName) {\n throw new Error('Extension has no name');\n }\n\n const plugin = getComponentData<BackstagePlugin>(element, 'core.plugin');\n const pluginId = plugin?.getId();\n\n const match = extName.match(/^Entity(.*)Card$/);\n const infix = match?.[1] ?? extName;\n\n let name: string | undefined = infix;\n if (\n pluginId &&\n name\n .toLocaleLowerCase('en-US')\n .startsWith(pluginId.toLocaleLowerCase('en-US'))\n ) {\n name = name.slice(pluginId.length);\n if (!name) {\n name = undefined;\n }\n }\n name = name && kebabCase(name);\n\n return EntityCardBlueprint.make({\n name: overrides?.name ?? name,\n params: {\n filter: overrides?.filter,\n loader: async () => compatWrapper(element),\n },\n });\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AA0BgB,SAAA,gCAAA,CACd,iBACA,SAIqB,EAAA;AACrB,EAAM,MAAA,OAAA,uBAAW,eAAgB,EAAA,EAAA,CAAA;AAEjC,EAAM,MAAA,OAAA,GAAU,gBAAyB,CAAA,OAAA,EAAS,oBAAoB,CAAA;AACtE,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA;AAAA;AAGzC,EAAM,MAAA,MAAA,GAAS,gBAAkC,CAAA,OAAA,EAAS,aAAa,CAAA;AACvE,EAAM,MAAA,QAAA,GAAW,QAAQ,KAAM,EAAA;AAE/B,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,KAAA,CAAM,kBAAkB,CAAA;AAC9C,EAAM,MAAA,KAAA,GAAQ,KAAQ,GAAA,CAAC,CAAK,IAAA,OAAA;AAE5B,EAAA,IAAI,IAA2B,GAAA,KAAA;AAC/B,EACE,IAAA,QAAA,IACA,IACG,CAAA,iBAAA,CAAkB,OAAO,CAAA,CACzB,WAAW,QAAS,CAAA,iBAAA,CAAkB,OAAO,CAAC,CACjD,EAAA;AACA,IAAO,IAAA,GAAA,IAAA,CAAK,KAAM,CAAA,QAAA,CAAS,MAAM,CAAA;AACjC,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,IAAA,GAAA,KAAA,CAAA;AAAA;AACT;AAEF,EAAO,IAAA,GAAA,IAAA,IAAQ,UAAU,IAAI,CAAA;AAE7B,EAAA,OAAO,oBAAoB,IAAK,CAAA;AAAA,IAC9B,IAAA,EAAM,WAAW,IAAQ,IAAA,IAAA;AAAA,IACzB,MAAQ,EAAA;AAAA,MACN,QAAQ,SAAW,EAAA,MAAA;AAAA,MACnB,MAAA,EAAQ,YAAY,aAAA,CAAc,OAAO;AAAA;AAC3C,GACD,CAAA;AACH;;;;"}
@@ -1,17 +1,18 @@
1
+ import { jsx } from 'react/jsx-runtime';
1
2
  import { convertLegacyRouteRef, compatWrapper } from '@backstage/core-compat-api';
2
3
  import { getComponentData } from '@backstage/core-plugin-api';
3
4
  import kebabCase from 'lodash/kebabCase';
4
5
  import startCase from 'lodash/startCase';
5
- import React from 'react';
6
6
  import '../blueprints/CatalogFilterBlueprint.esm.js';
7
7
  import '../blueprints/EntityCardBlueprint.esm.js';
8
8
  import { EntityContentBlueprint } from '../blueprints/EntityContentBlueprint.esm.js';
9
9
  import '../blueprints/EntityContentLayoutBlueprint.esm.js';
10
10
  import '../blueprints/EntityHeaderBlueprint.esm.js';
11
11
  import '../blueprints/extensionData.esm.js';
12
+ import '../blueprints/EntityContextMenuItemBlueprint.esm.js';
12
13
 
13
14
  function convertLegacyEntityContentExtension(LegacyExtension, overrides) {
14
- const element = /* @__PURE__ */ React.createElement(LegacyExtension, null);
15
+ const element = /* @__PURE__ */ jsx(LegacyExtension, {});
15
16
  const extName = getComponentData(element, "core.extensionName");
16
17
  if (!extName) {
17
18
  throw new Error("Extension has no name");
@@ -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';\nimport { EntityPredicate } from '../predicates';\nimport { Entity } from '@backstage/catalog-model';\n\n/** @alpha */\nexport function convertLegacyEntityContentExtension(\n LegacyExtension: ComponentType<{}>,\n overrides?: {\n name?: string;\n filter?: string | EntityPredicate | ((entity: Entity) => boolean);\n defaultPath?: string;\n defaultTitle?: string;\n },\n): ExtensionDefinition {\n const element = <LegacyExtension />;\n\n const extName = getComponentData<string>(element, 'core.extensionName');\n if (!extName) {\n throw new Error('Extension has no name');\n }\n\n const mountPoint = getComponentData<LegacyRouteRef>(\n element,\n 'core.mountPoint',\n );\n\n const plugin = getComponentData<BackstagePlugin>(element, 'core.plugin');\n const pluginId = plugin?.getId();\n\n const match = extName.match(/^Entity(.*)Content$/);\n const infix = match?.[1] ?? extName;\n\n let name: string | undefined = infix;\n if (\n pluginId &&\n name\n .toLocaleLowerCase('en-US')\n .startsWith(pluginId.toLocaleLowerCase('en-US'))\n ) {\n name = name.slice(pluginId.length);\n if (!name) {\n name = undefined;\n }\n }\n name = name && kebabCase(name);\n\n return EntityContentBlueprint.make({\n name: overrides?.name ?? name,\n params: {\n filter: overrides?.filter,\n defaultPath: overrides?.defaultPath ?? `/${kebabCase(infix)}`,\n defaultTitle: overrides?.defaultTitle ?? startCase(infix),\n routeRef: mountPoint && convertLegacyRouteRef(mountPoint),\n loader: async () => compatWrapper(element),\n },\n });\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAkCgB,SAAA,mCAAA,CACd,iBACA,SAMqB,EAAA;AACrB,EAAM,MAAA,OAAA,uCAAW,eAAgB,EAAA,IAAA,CAAA;AAEjC,EAAM,MAAA,OAAA,GAAU,gBAAyB,CAAA,OAAA,EAAS,oBAAoB,CAAA;AACtE,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA;AAAA;AAGzC,EAAA,MAAM,UAAa,GAAA,gBAAA;AAAA,IACjB,OAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAM,MAAA,MAAA,GAAS,gBAAkC,CAAA,OAAA,EAAS,aAAa,CAAA;AACvE,EAAM,MAAA,QAAA,GAAW,QAAQ,KAAM,EAAA;AAE/B,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,KAAA,CAAM,qBAAqB,CAAA;AACjD,EAAM,MAAA,KAAA,GAAQ,KAAQ,GAAA,CAAC,CAAK,IAAA,OAAA;AAE5B,EAAA,IAAI,IAA2B,GAAA,KAAA;AAC/B,EACE,IAAA,QAAA,IACA,IACG,CAAA,iBAAA,CAAkB,OAAO,CAAA,CACzB,WAAW,QAAS,CAAA,iBAAA,CAAkB,OAAO,CAAC,CACjD,EAAA;AACA,IAAO,IAAA,GAAA,IAAA,CAAK,KAAM,CAAA,QAAA,CAAS,MAAM,CAAA;AACjC,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,IAAA,GAAA,KAAA,CAAA;AAAA;AACT;AAEF,EAAO,IAAA,GAAA,IAAA,IAAQ,UAAU,IAAI,CAAA;AAE7B,EAAA,OAAO,uBAAuB,IAAK,CAAA;AAAA,IACjC,IAAA,EAAM,WAAW,IAAQ,IAAA,IAAA;AAAA,IACzB,MAAQ,EAAA;AAAA,MACN,QAAQ,SAAW,EAAA,MAAA;AAAA,MACnB,aAAa,SAAW,EAAA,WAAA,IAAe,CAAI,CAAA,EAAA,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA;AAAA,MAC3D,YAAc,EAAA,SAAA,EAAW,YAAgB,IAAA,SAAA,CAAU,KAAK,CAAA;AAAA,MACxD,QAAA,EAAU,UAAc,IAAA,qBAAA,CAAsB,UAAU,CAAA;AAAA,MACxD,MAAA,EAAQ,YAAY,aAAA,CAAc,OAAO;AAAA;AAC3C,GACD,CAAA;AACH;;;;"}
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 { ComponentType } from 'react';\nimport { EntityContentBlueprint } from '../blueprints';\nimport { EntityPredicate } from '../predicates';\nimport { Entity } from '@backstage/catalog-model';\n\n/** @alpha */\nexport function convertLegacyEntityContentExtension(\n LegacyExtension: ComponentType<{}>,\n overrides?: {\n name?: string;\n filter?: string | EntityPredicate | ((entity: Entity) => boolean);\n defaultPath?: string;\n defaultTitle?: string;\n },\n): ExtensionDefinition {\n const element = <LegacyExtension />;\n\n const extName = getComponentData<string>(element, 'core.extensionName');\n if (!extName) {\n throw new Error('Extension has no name');\n }\n\n const mountPoint = getComponentData<LegacyRouteRef>(\n element,\n 'core.mountPoint',\n );\n\n const plugin = getComponentData<BackstagePlugin>(element, 'core.plugin');\n const pluginId = plugin?.getId();\n\n const match = extName.match(/^Entity(.*)Content$/);\n const infix = match?.[1] ?? extName;\n\n let name: string | undefined = infix;\n if (\n pluginId &&\n name\n .toLocaleLowerCase('en-US')\n .startsWith(pluginId.toLocaleLowerCase('en-US'))\n ) {\n name = name.slice(pluginId.length);\n if (!name) {\n name = undefined;\n }\n }\n name = name && kebabCase(name);\n\n return EntityContentBlueprint.make({\n name: overrides?.name ?? name,\n params: {\n filter: overrides?.filter,\n defaultPath: overrides?.defaultPath ?? `/${kebabCase(infix)}`,\n defaultTitle: overrides?.defaultTitle ?? startCase(infix),\n routeRef: mountPoint && convertLegacyRouteRef(mountPoint),\n loader: async () => compatWrapper(element),\n },\n });\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;AAkCgB,SAAA,mCAAA,CACd,iBACA,SAMqB,EAAA;AACrB,EAAM,MAAA,OAAA,uBAAW,eAAgB,EAAA,EAAA,CAAA;AAEjC,EAAM,MAAA,OAAA,GAAU,gBAAyB,CAAA,OAAA,EAAS,oBAAoB,CAAA;AACtE,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA;AAAA;AAGzC,EAAA,MAAM,UAAa,GAAA,gBAAA;AAAA,IACjB,OAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAM,MAAA,MAAA,GAAS,gBAAkC,CAAA,OAAA,EAAS,aAAa,CAAA;AACvE,EAAM,MAAA,QAAA,GAAW,QAAQ,KAAM,EAAA;AAE/B,EAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,KAAA,CAAM,qBAAqB,CAAA;AACjD,EAAM,MAAA,KAAA,GAAQ,KAAQ,GAAA,CAAC,CAAK,IAAA,OAAA;AAE5B,EAAA,IAAI,IAA2B,GAAA,KAAA;AAC/B,EACE,IAAA,QAAA,IACA,IACG,CAAA,iBAAA,CAAkB,OAAO,CAAA,CACzB,WAAW,QAAS,CAAA,iBAAA,CAAkB,OAAO,CAAC,CACjD,EAAA;AACA,IAAO,IAAA,GAAA,IAAA,CAAK,KAAM,CAAA,QAAA,CAAS,MAAM,CAAA;AACjC,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,IAAA,GAAA,KAAA,CAAA;AAAA;AACT;AAEF,EAAO,IAAA,GAAA,IAAA,IAAQ,UAAU,IAAI,CAAA;AAE7B,EAAA,OAAO,uBAAuB,IAAK,CAAA;AAAA,IACjC,IAAA,EAAM,WAAW,IAAQ,IAAA,IAAA;AAAA,IACzB,MAAQ,EAAA;AAAA,MACN,QAAQ,SAAW,EAAA,MAAA;AAAA,MACnB,aAAa,SAAW,EAAA,WAAA,IAAe,CAAI,CAAA,EAAA,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA;AAAA,MAC3D,YAAc,EAAA,SAAA,EAAW,YAAgB,IAAA,SAAA,CAAU,KAAK,CAAA;AAAA,MACxD,QAAA,EAAU,UAAc,IAAA,qBAAA,CAAsB,UAAU,CAAA;AAAA,MACxD,MAAA,EAAQ,YAAY,aAAA,CAAc,OAAO;AAAA;AAC3C,GACD,CAAA;AACH;;;;"}
package/dist/alpha.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
2
2
  import { RouteRef, ExtensionDefinition } from '@backstage/frontend-plugin-api';
3
- import * as React from 'react';
4
- import React__default, { ComponentType } from 'react';
3
+ import * as react from 'react';
4
+ import { JSX as JSX$1, ReactNode, ComponentType } from 'react';
5
5
  import { Entity } from '@backstage/catalog-model';
6
6
  import { JsonValue } from '@backstage/types';
7
7
  import * as _backstage_core_plugin_api_alpha from '@backstage/core-plugin-api/alpha';
@@ -28,7 +28,7 @@ declare const CatalogFilterBlueprint: _backstage_frontend_plugin_api.ExtensionBl
28
28
  params: {
29
29
  loader: () => Promise<JSX.Element>;
30
30
  };
31
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<React.JSX.Element, "core.reactElement", {}>;
31
+ output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}>;
32
32
  inputs: {};
33
33
  config: {};
34
34
  configInput: {};
@@ -92,7 +92,7 @@ declare const EntityCardBlueprint: _backstage_frontend_plugin_api.ExtensionBluep
92
92
  filter?: string | EntityPredicate | ((entity: Entity) => boolean);
93
93
  type?: EntityCardType;
94
94
  };
95
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<React.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {
95
+ output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {
96
96
  optional: true;
97
97
  }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {
98
98
  optional: true;
@@ -130,7 +130,7 @@ declare const EntityContentBlueprint: _backstage_frontend_plugin_api.ExtensionBl
130
130
  routeRef?: RouteRef;
131
131
  filter?: string | EntityPredicate | ((entity: Entity) => boolean);
132
132
  };
133
- 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", {
133
+ 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", {
134
134
  optional: true;
135
135
  }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-content-title", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {
136
136
  optional: true;
@@ -164,7 +164,7 @@ declare const EntityContentBlueprint: _backstage_frontend_plugin_api.ExtensionBl
164
164
  interface EntityContentLayoutProps {
165
165
  cards: Array<{
166
166
  type?: EntityCardType;
167
- element: React__default.JSX.Element;
167
+ element: JSX$1.Element;
168
168
  }>;
169
169
  }
170
170
  /** @alpha */
@@ -173,13 +173,13 @@ declare const EntityContentLayoutBlueprint: _backstage_frontend_plugin_api.Exten
173
173
  name: undefined;
174
174
  params: {
175
175
  filter?: string | EntityPredicate | ((entity: Entity) => boolean);
176
- loader: () => Promise<(props: EntityContentLayoutProps) => React__default.JSX.Element>;
176
+ loader: () => Promise<(props: EntityContentLayoutProps) => JSX$1.Element>;
177
177
  };
178
178
  output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {
179
179
  optional: true;
180
180
  }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {
181
181
  optional: true;
182
- }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(props: EntityContentLayoutProps) => React__default.JSX.Element, "catalog.entity-content-layout.component", {}>;
182
+ }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(props: EntityContentLayoutProps) => React.JSX.Element, "catalog.entity-content-layout.component", {}>;
183
183
  inputs: {};
184
184
  config: {
185
185
  type: string | undefined;
@@ -192,7 +192,7 @@ declare const EntityContentLayoutBlueprint: _backstage_frontend_plugin_api.Exten
192
192
  dataRefs: {
193
193
  filterFunction: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {}>;
194
194
  filterExpression: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {}>;
195
- component: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(props: EntityContentLayoutProps) => React__default.JSX.Element, "catalog.entity-content-layout.component", {}>;
195
+ component: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(props: EntityContentLayoutProps) => React.JSX.Element, "catalog.entity-content-layout.component", {}>;
196
196
  };
197
197
  }>;
198
198
 
@@ -203,17 +203,44 @@ declare const EntityHeaderBlueprint: _backstage_frontend_plugin_api.ExtensionBlu
203
203
  params: {
204
204
  loader: () => Promise<JSX.Element>;
205
205
  };
206
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<React.JSX.Element, "core.reactElement", {
206
+ output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {
207
207
  optional: true;
208
208
  }>;
209
209
  inputs: {};
210
210
  config: {};
211
211
  configInput: {};
212
212
  dataRefs: {
213
- element: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<React.JSX.Element, "core.reactElement", {}>;
213
+ element: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}>;
214
214
  };
215
215
  }>;
216
216
 
217
+ /** @alpha */
218
+ type UseProps = () => {
219
+ title: ReactNode;
220
+ href: string;
221
+ disabled?: boolean;
222
+ } | {
223
+ title: ReactNode;
224
+ onClick: () => void | Promise<void>;
225
+ disabled?: boolean;
226
+ };
227
+ /** @alpha */
228
+ type EntityContextMenuItemParams = {
229
+ useProps: UseProps;
230
+ icon: JSX$1.Element;
231
+ };
232
+ /** @alpha */
233
+ declare const EntityContextMenuItemBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
234
+ kind: "entity-context-menu-item";
235
+ name: undefined;
236
+ params: EntityContextMenuItemParams;
237
+ output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<JSX$1.Element, "core.reactElement", {}>;
238
+ inputs: {};
239
+ config: {};
240
+ configInput: {};
241
+ dataRefs: never;
242
+ }>;
243
+
217
244
  /** @alpha */
218
245
  declare function convertLegacyEntityCardExtension(LegacyExtension: ComponentType<{}>, overrides?: {
219
246
  name?: string;
@@ -300,4 +327,4 @@ declare function useEntityPermission(permission: ResourcePermission<'catalog-ent
300
327
  error?: Error;
301
328
  };
302
329
 
303
- export { CatalogFilterBlueprint, EntityCardBlueprint, type EntityCardType, EntityContentBlueprint, EntityContentLayoutBlueprint, type EntityContentLayoutProps, EntityHeaderBlueprint, type EntityPredicate, type EntityPredicateExpression, type EntityPredicatePrimitive, type EntityPredicateValue, catalogReactTranslationRef, convertLegacyEntityCardExtension, convertLegacyEntityContentExtension, defaultEntityContentGroups, entityPredicateToFilterFunction, isOwnerOf, useEntityPermission };
330
+ export { CatalogFilterBlueprint, EntityCardBlueprint, type EntityCardType, EntityContentBlueprint, EntityContentLayoutBlueprint, type EntityContentLayoutProps, EntityContextMenuItemBlueprint, type EntityContextMenuItemParams, EntityHeaderBlueprint, type EntityPredicate, type EntityPredicateExpression, type EntityPredicatePrimitive, type EntityPredicateValue, type UseProps, catalogReactTranslationRef, convertLegacyEntityCardExtension, convertLegacyEntityContentExtension, defaultEntityContentGroups, entityPredicateToFilterFunction, isOwnerOf, useEntityPermission };
package/dist/alpha.esm.js CHANGED
@@ -4,6 +4,7 @@ export { EntityContentBlueprint } from './alpha/blueprints/EntityContentBlueprin
4
4
  export { EntityContentLayoutBlueprint } from './alpha/blueprints/EntityContentLayoutBlueprint.esm.js';
5
5
  export { EntityHeaderBlueprint } from './alpha/blueprints/EntityHeaderBlueprint.esm.js';
6
6
  export { defaultEntityContentGroups } from './alpha/blueprints/extensionData.esm.js';
7
+ export { EntityContextMenuItemBlueprint } from './alpha/blueprints/EntityContextMenuItemBlueprint.esm.js';
7
8
  export { convertLegacyEntityCardExtension } from './alpha/converters/convertLegacyEntityCardExtension.esm.js';
8
9
  export { convertLegacyEntityContentExtension } from './alpha/converters/convertLegacyEntityContentExtension.esm.js';
9
10
  export { entityPredicateToFilterFunction } from './alpha/predicates/entityPredicateToFilterFunction.esm.js';
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
1
+ {"version":3,"file":"alpha.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
@@ -1,3 +1,4 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
1
2
  import Box from '@material-ui/core/Box';
2
3
  import Typography from '@material-ui/core/Typography';
3
4
  import Paper from '@material-ui/core/Paper';
@@ -7,7 +8,7 @@ import Grow from '@material-ui/core/Grow';
7
8
  import { makeStyles, withStyles, createStyles } from '@material-ui/core/styles';
8
9
  import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
9
10
  import Autocomplete from '@material-ui/lab/Autocomplete';
10
- import React, { useCallback } from 'react';
11
+ import { useCallback } from 'react';
11
12
  import { merge } from 'lodash';
12
13
  import classNames from 'classnames';
13
14
 
@@ -83,36 +84,38 @@ const BootstrapAutocomplete = withStyles(
83
84
  }),
84
85
  { name: "BackstageAutocompleteBase" }
85
86
  )(Autocomplete);
86
- const PopperComponent = (props) => /* @__PURE__ */ React.createElement(Popper, { ...props, transition: true, placement: "bottom-start" }, ({ TransitionProps }) => /* @__PURE__ */ React.createElement(Grow, { ...TransitionProps, style: { transformOrigin: "0 0 0" } }, /* @__PURE__ */ React.createElement(Box, null, props.children)));
87
- const PaperComponent = (props) => /* @__PURE__ */ React.createElement(Paper, { ...props, elevation: 8 });
87
+ const PopperComponent = (props) => /* @__PURE__ */ jsx(Popper, { ...props, transition: true, placement: "bottom-start", children: ({ TransitionProps }) => /* @__PURE__ */ jsx(Grow, { ...TransitionProps, style: { transformOrigin: "0 0 0" }, children: /* @__PURE__ */ jsx(Box, { children: props.children }) }) });
88
+ const PaperComponent = (props) => /* @__PURE__ */ jsx(Paper, { ...props, elevation: 8 });
88
89
  function CatalogAutocomplete(props) {
89
90
  const { label, name, LabelProps, TextFieldProps, ...rest } = props;
90
91
  const classes = useStyles();
91
92
  const renderInput = useCallback(
92
- (params) => /* @__PURE__ */ React.createElement(TextField, { ...merge(params, TextFieldProps), variant: "outlined" }),
93
+ (params) => /* @__PURE__ */ jsx(TextField, { ...merge(params, TextFieldProps), variant: "outlined" }),
93
94
  [TextFieldProps]
94
95
  );
95
- const autocomplete = /* @__PURE__ */ React.createElement(
96
+ const autocomplete = /* @__PURE__ */ jsx(
96
97
  BootstrapAutocomplete,
97
98
  {
98
99
  size: "small",
99
100
  ...rest,
100
101
  renderInput: rest.renderInput ?? renderInput,
101
- popupIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, { "data-testid": `${name}-expand` }),
102
+ popupIcon: /* @__PURE__ */ jsx(ExpandMoreIcon, { "data-testid": `${name}-expand` }),
102
103
  PaperComponent,
103
104
  PopperComponent
104
105
  }
105
106
  );
106
- return /* @__PURE__ */ React.createElement(Box, { className: classes.root }, label ? /* @__PURE__ */ React.createElement(
107
+ return /* @__PURE__ */ jsx(Box, { className: classes.root, children: label ? /* @__PURE__ */ jsxs(
107
108
  Typography,
108
109
  {
109
110
  ...LabelProps,
110
111
  className: classNames(classes.label, LabelProps?.className),
111
- component: "label"
112
- },
113
- /* @__PURE__ */ React.createElement(Box, { component: "span" }, label),
114
- autocomplete
115
- ) : autocomplete);
112
+ component: "label",
113
+ children: [
114
+ /* @__PURE__ */ jsx(Box, { component: "span", children: label }),
115
+ autocomplete
116
+ ]
117
+ }
118
+ ) : autocomplete });
116
119
  }
117
120
 
118
121
  export { CatalogAutocomplete };
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogAutocomplete.esm.js","sources":["../../../src/components/CatalogAutocomplete/CatalogAutocomplete.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport Typography, { TypographyProps } from '@material-ui/core/Typography';\nimport Paper, { PaperProps } from '@material-ui/core/Paper';\nimport Popper, { PopperProps } from '@material-ui/core/Popper';\nimport TextField, { OutlinedTextFieldProps } from '@material-ui/core/TextField';\nimport Grow from '@material-ui/core/Grow';\nimport {\n createStyles,\n makeStyles,\n Theme,\n withStyles,\n} from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport Autocomplete, {\n AutocompleteProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab/Autocomplete';\nimport React, { ReactNode, useCallback } from 'react';\nimport { merge } from 'lodash';\nimport classNames from 'classnames';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n margin: theme.spacing(1, 0),\n },\n label: {\n position: 'relative',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '& > span': {\n top: 0,\n left: 0,\n position: 'absolute',\n },\n },\n }),\n { name: 'BackstageAutocomplete' },\n);\n\nconst BootstrapAutocomplete = withStyles(\n (theme: Theme) =>\n createStyles({\n root: {},\n paper: {\n margin: 0,\n },\n hasClearIcon: {},\n hasPopupIcon: {},\n focused: {},\n inputRoot: {\n marginTop: 24,\n backgroundColor: theme.palette.background.paper,\n '$root$hasClearIcon$hasPopupIcon &': {\n paddingBlock: theme.spacing(0.75),\n paddingInlineStart: theme.spacing(0.75),\n },\n '$root$focused &': {\n outline: 'none',\n },\n '$root &:hover > fieldset': {\n borderColor: '#ced4da',\n },\n '$root$focused & > fieldset': {\n borderWidth: 1,\n borderColor: theme.palette.primary.main,\n },\n },\n popupIndicator: {\n padding: 0,\n margin: 0,\n color: '#616161',\n '&:hover': {\n backgroundColor: 'unset',\n },\n '& [class*=\"MuiTouchRipple-root\"]': {\n display: 'none',\n },\n },\n endAdornment: {\n '$root$hasClearIcon$hasPopupIcon &': {\n right: 4,\n },\n },\n input: {\n '$root$hasClearIcon$hasPopupIcon &': {\n fontSize: theme.typography.body1.fontSize,\n paddingBlock: theme.spacing(0.8125),\n },\n },\n }),\n { name: 'BackstageAutocompleteBase' },\n)(Autocomplete) as typeof Autocomplete;\n\nconst PopperComponent = (props: PopperProps) => (\n <Popper {...props} transition placement=\"bottom-start\">\n {({ TransitionProps }) => (\n <Grow {...TransitionProps} style={{ transformOrigin: '0 0 0' }}>\n <Box>{props.children as ReactNode}</Box>\n </Grow>\n )}\n </Popper>\n);\n\nconst PaperComponent = (props: PaperProps) => (\n <Paper {...props} elevation={8} />\n);\n\n/**\n * Props for {@link CatalogAutocomplete}\n *\n * @public\n */\nexport type CatalogAutocompleteProps<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n> = Omit<\n AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>,\n 'PopperComponent' | 'PaperComponent' | 'popupIcon' | 'renderInput'\n> & {\n name: string;\n label?: string;\n LabelProps?: TypographyProps<'label'>;\n TextFieldProps?: Omit<OutlinedTextFieldProps, 'variant'>;\n renderInput?: AutocompleteProps<\n T,\n Multiple,\n DisableClearable,\n FreeSolo\n >['renderInput'];\n};\n\n/** @public */\nexport function CatalogAutocomplete<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n>(props: CatalogAutocompleteProps<T, Multiple, DisableClearable, FreeSolo>) {\n const { label, name, LabelProps, TextFieldProps, ...rest } = props;\n const classes = useStyles();\n const renderInput = useCallback(\n (params: AutocompleteRenderInputParams) => (\n <TextField {...merge(params, TextFieldProps)} variant=\"outlined\" />\n ),\n [TextFieldProps],\n );\n const autocomplete = (\n <BootstrapAutocomplete\n size=\"small\"\n {...rest}\n renderInput={rest.renderInput ?? renderInput}\n popupIcon={<ExpandMoreIcon data-testid={`${name}-expand`} />}\n PaperComponent={PaperComponent}\n PopperComponent={PopperComponent}\n />\n );\n\n return (\n <Box className={classes.root}>\n {label ? (\n <Typography\n {...LabelProps}\n className={classNames(classes.label, LabelProps?.className)}\n component=\"label\"\n >\n <Box component=\"span\">{label}</Box>\n {autocomplete}\n </Typography>\n ) : (\n autocomplete\n )}\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CatalogAutocomplete.esm.js","sources":["../../../src/components/CatalogAutocomplete/CatalogAutocomplete.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport Typography, { TypographyProps } from '@material-ui/core/Typography';\nimport Paper, { PaperProps } from '@material-ui/core/Paper';\nimport Popper, { PopperProps } from '@material-ui/core/Popper';\nimport TextField, { OutlinedTextFieldProps } from '@material-ui/core/TextField';\nimport Grow from '@material-ui/core/Grow';\nimport {\n createStyles,\n makeStyles,\n Theme,\n withStyles,\n} from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport Autocomplete, {\n AutocompleteProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab/Autocomplete';\nimport { ReactNode, useCallback } from 'react';\nimport { merge } from 'lodash';\nimport classNames from 'classnames';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n margin: theme.spacing(1, 0),\n },\n label: {\n position: 'relative',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '& > span': {\n top: 0,\n left: 0,\n position: 'absolute',\n },\n },\n }),\n { name: 'BackstageAutocomplete' },\n);\n\nconst BootstrapAutocomplete = withStyles(\n (theme: Theme) =>\n createStyles({\n root: {},\n paper: {\n margin: 0,\n },\n hasClearIcon: {},\n hasPopupIcon: {},\n focused: {},\n inputRoot: {\n marginTop: 24,\n backgroundColor: theme.palette.background.paper,\n '$root$hasClearIcon$hasPopupIcon &': {\n paddingBlock: theme.spacing(0.75),\n paddingInlineStart: theme.spacing(0.75),\n },\n '$root$focused &': {\n outline: 'none',\n },\n '$root &:hover > fieldset': {\n borderColor: '#ced4da',\n },\n '$root$focused & > fieldset': {\n borderWidth: 1,\n borderColor: theme.palette.primary.main,\n },\n },\n popupIndicator: {\n padding: 0,\n margin: 0,\n color: '#616161',\n '&:hover': {\n backgroundColor: 'unset',\n },\n '& [class*=\"MuiTouchRipple-root\"]': {\n display: 'none',\n },\n },\n endAdornment: {\n '$root$hasClearIcon$hasPopupIcon &': {\n right: 4,\n },\n },\n input: {\n '$root$hasClearIcon$hasPopupIcon &': {\n fontSize: theme.typography.body1.fontSize,\n paddingBlock: theme.spacing(0.8125),\n },\n },\n }),\n { name: 'BackstageAutocompleteBase' },\n)(Autocomplete) as typeof Autocomplete;\n\nconst PopperComponent = (props: PopperProps) => (\n <Popper {...props} transition placement=\"bottom-start\">\n {({ TransitionProps }) => (\n <Grow {...TransitionProps} style={{ transformOrigin: '0 0 0' }}>\n <Box>{props.children as ReactNode}</Box>\n </Grow>\n )}\n </Popper>\n);\n\nconst PaperComponent = (props: PaperProps) => (\n <Paper {...props} elevation={8} />\n);\n\n/**\n * Props for {@link CatalogAutocomplete}\n *\n * @public\n */\nexport type CatalogAutocompleteProps<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n> = Omit<\n AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>,\n 'PopperComponent' | 'PaperComponent' | 'popupIcon' | 'renderInput'\n> & {\n name: string;\n label?: string;\n LabelProps?: TypographyProps<'label'>;\n TextFieldProps?: Omit<OutlinedTextFieldProps, 'variant'>;\n renderInput?: AutocompleteProps<\n T,\n Multiple,\n DisableClearable,\n FreeSolo\n >['renderInput'];\n};\n\n/** @public */\nexport function CatalogAutocomplete<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n>(props: CatalogAutocompleteProps<T, Multiple, DisableClearable, FreeSolo>) {\n const { label, name, LabelProps, TextFieldProps, ...rest } = props;\n const classes = useStyles();\n const renderInput = useCallback(\n (params: AutocompleteRenderInputParams) => (\n <TextField {...merge(params, TextFieldProps)} variant=\"outlined\" />\n ),\n [TextFieldProps],\n );\n const autocomplete = (\n <BootstrapAutocomplete\n size=\"small\"\n {...rest}\n renderInput={rest.renderInput ?? renderInput}\n popupIcon={<ExpandMoreIcon data-testid={`${name}-expand`} />}\n PaperComponent={PaperComponent}\n PopperComponent={PopperComponent}\n />\n );\n\n return (\n <Box className={classes.root}>\n {label ? (\n <Typography\n {...LabelProps}\n className={classNames(classes.label, LabelProps?.className)}\n component=\"label\"\n >\n <Box component=\"span\">{label}</Box>\n {autocomplete}\n </Typography>\n ) : (\n autocomplete\n )}\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}