@backstage/plugin-scaffolder 1.39.0-next.2 → 1.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/alpha/components/TemplateEditorPage/TemplateEditorForm.esm.js +1 -1
  3. package/dist/alpha/components/TemplateEditorPage/TemplateEditorForm.esm.js.map +1 -1
  4. package/dist/alpha/components/TemplatesSubPage.esm.js +16 -2
  5. package/dist/alpha/components/TemplatesSubPage.esm.js.map +1 -1
  6. package/dist/alpha/extensions.esm.js +4 -1
  7. package/dist/alpha/extensions.esm.js.map +1 -1
  8. package/dist/alpha.d.ts +2 -0
  9. package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js +2 -2
  10. package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js.map +1 -1
  11. package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js +11 -9
  12. package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js.map +1 -1
  13. package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js +10 -8
  14. package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js.map +1 -1
  15. package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js +12 -5
  16. package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js.map +1 -1
  17. package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js +17 -9
  18. package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js.map +1 -1
  19. package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js +21 -9
  20. package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js.map +1 -1
  21. package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js +21 -10
  22. package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js.map +1 -1
  23. package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js +29 -7
  24. package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js.map +1 -1
  25. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js +83 -46
  26. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js.map +1 -1
  27. package/dist/components/fields/RepoUrlPicker/schema.esm.js +7 -0
  28. package/dist/components/fields/RepoUrlPicker/schema.esm.js.map +1 -1
  29. package/dist/index.d.ts +10 -0
  30. package/dist/plugins/scaffolder/package.json.esm.js +1 -1
  31. package/package.json +27 -27
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @backstage/plugin-scaffolder
2
2
 
3
+ ## 1.39.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1b99861: The `sub-page:scaffolder/templates` extension now accepts a `templateFilter` field that lets you filter which templates are shown on the template list page.
8
+ - e060bd4: Added new `ui:options` to `RepoUrlPicker` for per-template customization: `ownerLabel`, `ownerDescription`, `repoLabel`, `repoDescription` to override field labels, and `disableRepoAutocomplete` to render a plain text input instead of the autocomplete dropdown.
9
+ - 5ff93bf: Added functionality to register a Template Outputs Component in the new frontend system.
10
+
11
+ ### Patch Changes
12
+
13
+ - 736d84e: Use locale-insensitive Unicode casing for consistent string handling across environments.
14
+ - cfba1bc: Updated internal type definitions. No changes to runtime behavior or public API.
15
+ - Updated dependencies
16
+ - @backstage/core-components@0.18.14
17
+ - @backstage/integration@2.1.2
18
+ - @backstage/plugin-catalog-common@1.2.0
19
+ - @backstage/plugin-scaffolder-common@2.3.0
20
+ - @backstage/ui@0.18.0
21
+ - @backstage/catalog-client@1.16.2
22
+ - @backstage/catalog-model@1.10.1
23
+ - @backstage/filter-predicates@0.1.5
24
+ - @backstage/plugin-catalog-react@3.2.3
25
+ - @backstage/plugin-scaffolder-react@2.1.0
26
+ - @backstage/plugin-techdocs-react@1.3.15
27
+ - @backstage/frontend-plugin-api@0.18.1
28
+ - @backstage/core-plugin-api@1.12.10
29
+ - @backstage/integration-react@1.2.22
30
+ - @backstage/plugin-permission-react@0.5.5
31
+
3
32
  ## 1.39.0-next.2
4
33
 
5
34
  ### Patch Changes
@@ -69,7 +69,7 @@ function TemplateEditorForm(props) {
69
69
  }
70
70
  let rootObj = parsed;
71
71
  if (!contentIsSpec) {
72
- const isTemplate = String(parsed.kind).toLocaleLowerCase("en-US") === "template";
72
+ const isTemplate = String(parsed.kind).toLowerCase() === "template";
73
73
  if (!isTemplate) {
74
74
  setSteps(void 0);
75
75
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateEditorForm.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorForm.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Paper from '@material-ui/core/Paper';\nimport Typography from '@material-ui/core/Typography';\nimport { Component, ReactNode, useMemo, useState } from 'react';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport yaml from 'yaml';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport {\n LayoutOptions,\n TemplateParameterSchema,\n FieldExtensionOptions,\n FormProps,\n} from '@backstage/plugin-scaffolder-react';\nimport {\n Stepper,\n createAsyncValidators,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { useDryRun } from './DryRunContext';\nimport { useDirectoryEditor } from './DirectoryEditorContext';\n\nimport { scaffolderTranslationRef } from '../../../translation';\n\nconst useStyles = makeStyles({\n containerWrapper: {\n width: '100%',\n },\n});\n\ninterface ErrorBoundaryProps {\n invalidator: unknown;\n setErrorText(errorText: string | undefined): void;\n children: ReactNode;\n}\n\ninterface ErrorBoundaryState {\n shouldRender: boolean;\n}\n\nclass ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state = {\n shouldRender: true,\n };\n\n componentDidUpdate(prevProps: { invalidator: unknown }) {\n if (prevProps.invalidator !== this.props.invalidator) {\n this.setState({ shouldRender: true });\n }\n }\n\n componentDidCatch(error: Error) {\n this.props.setErrorText(error.message);\n this.setState({ shouldRender: false });\n }\n\n render() {\n return this.state.shouldRender ? this.props.children : null;\n }\n}\n\ninterface TemplateEditorFormProps {\n content?: string;\n /** Setting this to true will cause the content to be parsed as if it is the template entity spec */\n contentIsSpec?: boolean;\n setErrorText: (errorText?: string) => void;\n\n onDryRun?: (data: JsonObject) => Promise<void>;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n}\n\nfunction isJsonObject(value: JsonValue | undefined): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Shows the a template form that is parsed from the provided content */\nexport function TemplateEditorForm(props: TemplateEditorFormProps) {\n const {\n content,\n contentIsSpec,\n onDryRun,\n setErrorText,\n fieldExtensions = [],\n layouts = [],\n } = props;\n const classes = useStyles();\n const apiHolder = useApiHolder();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const [steps, setSteps] = useState<TemplateParameterSchema['steps']>();\n\n const fields = useMemo(() => {\n return Object.fromEntries(\n fieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [fieldExtensions]);\n\n useDebounce(\n () => {\n try {\n if (!content) {\n setSteps(undefined);\n return;\n }\n const parsed: JsonValue = yaml\n .parseAllDocuments(content)\n .filter(c => c)\n .map(c => c.toJSON())[0];\n\n if (!isJsonObject(parsed)) {\n setSteps(undefined);\n return;\n }\n\n let rootObj = parsed;\n if (!contentIsSpec) {\n const isTemplate =\n String(parsed.kind).toLocaleLowerCase('en-US') === 'template';\n if (!isTemplate) {\n setSteps(undefined);\n return;\n }\n\n rootObj = isJsonObject(parsed.spec) ? parsed.spec : {};\n }\n\n const { parameters } = rootObj;\n\n if (!Array.isArray(parameters)) {\n setErrorText('Template parameters must be an array');\n setSteps(undefined);\n return;\n }\n\n const fieldValidators = Object.fromEntries(\n fieldExtensions.map(({ name, validation }) => [name, validation]),\n );\n\n setErrorText();\n setSteps(\n parameters.flatMap(param =>\n isJsonObject(param)\n ? [\n {\n title: String(param.title),\n schema: param,\n validate: createAsyncValidators(param, fieldValidators, {\n apiHolder,\n }),\n },\n ]\n : [],\n ),\n );\n } catch (e) {\n setErrorText(e.message);\n }\n },\n 250,\n [contentIsSpec, content, apiHolder],\n );\n\n return (\n <div className={classes.containerWrapper}>\n {steps ? (\n <Paper variant=\"outlined\">\n <ErrorBoundary invalidator={steps} setErrorText={setErrorText}>\n <Stepper\n manifest={{ steps, title: 'Template Editor' }}\n extensions={fieldExtensions}\n components={fields}\n onCreate={async options => {\n await onDryRun?.(options);\n }}\n layouts={layouts}\n formProps={props.formProps}\n />\n </ErrorBoundary>\n </Paper>\n ) : (\n <Typography variant=\"body1\" color=\"textSecondary\">\n {t('templateEditorForm.stepper.emptyText')}\n </Typography>\n )}\n </div>\n );\n}\n\n/** A version of the TemplateEditorForm that is connected to the DirectoryEditor and DryRun contexts */\nexport function TemplateEditorFormDirectoryEditorDryRun(\n props: Pick<\n TemplateEditorFormProps,\n 'setErrorText' | 'fieldExtensions' | 'layouts' | 'formProps'\n >,\n) {\n const { setErrorText, fieldExtensions = [], layouts } = props;\n const dryRun = useDryRun();\n\n const directoryEditor = useDirectoryEditor();\n const { selectedFile } = directoryEditor ?? {};\n\n const handleDryRun = async (data: JsonObject) => {\n if (!selectedFile) {\n return;\n }\n\n try {\n await dryRun.execute({\n templateContent: selectedFile.content,\n values: data,\n files: directoryEditor?.files ?? [],\n });\n setErrorText();\n } catch (e) {\n setErrorText(String(e.cause || e));\n throw e;\n }\n };\n\n const content =\n selectedFile && selectedFile.path.match(/\\.ya?ml$/)\n ? selectedFile.content\n : undefined;\n\n if (!directoryEditor) {\n return null;\n }\n\n return (\n <TemplateEditorForm\n onDryRun={handleDryRun}\n fieldExtensions={fieldExtensions}\n setErrorText={setErrorText}\n content={content}\n layouts={layouts}\n formProps={props.formProps}\n />\n );\n}\n\nTemplateEditorForm.DirectoryEditorDryRun =\n TemplateEditorFormDirectoryEditorDryRun;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TemplateEditorForm.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorForm.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Paper from '@material-ui/core/Paper';\nimport Typography from '@material-ui/core/Typography';\nimport { Component, ReactNode, useMemo, useState } from 'react';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport yaml from 'yaml';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport {\n LayoutOptions,\n TemplateParameterSchema,\n FieldExtensionOptions,\n FormProps,\n} from '@backstage/plugin-scaffolder-react';\nimport {\n Stepper,\n createAsyncValidators,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { useDryRun } from './DryRunContext';\nimport { useDirectoryEditor } from './DirectoryEditorContext';\n\nimport { scaffolderTranslationRef } from '../../../translation';\n\nconst useStyles = makeStyles({\n containerWrapper: {\n width: '100%',\n },\n});\n\ninterface ErrorBoundaryProps {\n invalidator: unknown;\n setErrorText(errorText: string | undefined): void;\n children: ReactNode;\n}\n\ninterface ErrorBoundaryState {\n shouldRender: boolean;\n}\n\nclass ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state = {\n shouldRender: true,\n };\n\n componentDidUpdate(prevProps: { invalidator: unknown }) {\n if (prevProps.invalidator !== this.props.invalidator) {\n this.setState({ shouldRender: true });\n }\n }\n\n componentDidCatch(error: Error) {\n this.props.setErrorText(error.message);\n this.setState({ shouldRender: false });\n }\n\n render() {\n return this.state.shouldRender ? this.props.children : null;\n }\n}\n\ninterface TemplateEditorFormProps {\n content?: string;\n /** Setting this to true will cause the content to be parsed as if it is the template entity spec */\n contentIsSpec?: boolean;\n setErrorText: (errorText?: string) => void;\n\n onDryRun?: (data: JsonObject) => Promise<void>;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n}\n\nfunction isJsonObject(value: JsonValue | undefined): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Shows the a template form that is parsed from the provided content */\nexport function TemplateEditorForm(props: TemplateEditorFormProps) {\n const {\n content,\n contentIsSpec,\n onDryRun,\n setErrorText,\n fieldExtensions = [],\n layouts = [],\n } = props;\n const classes = useStyles();\n const apiHolder = useApiHolder();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const [steps, setSteps] = useState<TemplateParameterSchema['steps']>();\n\n const fields = useMemo(() => {\n return Object.fromEntries(\n fieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [fieldExtensions]);\n\n useDebounce(\n () => {\n try {\n if (!content) {\n setSteps(undefined);\n return;\n }\n const parsed: JsonValue = yaml\n .parseAllDocuments(content)\n .filter(c => c)\n .map(c => c.toJSON())[0];\n\n if (!isJsonObject(parsed)) {\n setSteps(undefined);\n return;\n }\n\n let rootObj = parsed;\n if (!contentIsSpec) {\n const isTemplate = String(parsed.kind).toLowerCase() === 'template';\n if (!isTemplate) {\n setSteps(undefined);\n return;\n }\n\n rootObj = isJsonObject(parsed.spec) ? parsed.spec : {};\n }\n\n const { parameters } = rootObj;\n\n if (!Array.isArray(parameters)) {\n setErrorText('Template parameters must be an array');\n setSteps(undefined);\n return;\n }\n\n const fieldValidators = Object.fromEntries(\n fieldExtensions.map(({ name, validation }) => [name, validation]),\n );\n\n setErrorText();\n setSteps(\n parameters.flatMap(param =>\n isJsonObject(param)\n ? [\n {\n title: String(param.title),\n schema: param,\n validate: createAsyncValidators(param, fieldValidators, {\n apiHolder,\n }),\n },\n ]\n : [],\n ),\n );\n } catch (e) {\n setErrorText(e.message);\n }\n },\n 250,\n [contentIsSpec, content, apiHolder],\n );\n\n return (\n <div className={classes.containerWrapper}>\n {steps ? (\n <Paper variant=\"outlined\">\n <ErrorBoundary invalidator={steps} setErrorText={setErrorText}>\n <Stepper\n manifest={{ steps, title: 'Template Editor' }}\n extensions={fieldExtensions}\n components={fields}\n onCreate={async options => {\n await onDryRun?.(options);\n }}\n layouts={layouts}\n formProps={props.formProps}\n />\n </ErrorBoundary>\n </Paper>\n ) : (\n <Typography variant=\"body1\" color=\"textSecondary\">\n {t('templateEditorForm.stepper.emptyText')}\n </Typography>\n )}\n </div>\n );\n}\n\n/** A version of the TemplateEditorForm that is connected to the DirectoryEditor and DryRun contexts */\nexport function TemplateEditorFormDirectoryEditorDryRun(\n props: Pick<\n TemplateEditorFormProps,\n 'setErrorText' | 'fieldExtensions' | 'layouts' | 'formProps'\n >,\n) {\n const { setErrorText, fieldExtensions = [], layouts } = props;\n const dryRun = useDryRun();\n\n const directoryEditor = useDirectoryEditor();\n const { selectedFile } = directoryEditor ?? {};\n\n const handleDryRun = async (data: JsonObject) => {\n if (!selectedFile) {\n return;\n }\n\n try {\n await dryRun.execute({\n templateContent: selectedFile.content,\n values: data,\n files: directoryEditor?.files ?? [],\n });\n setErrorText();\n } catch (e) {\n setErrorText(String(e.cause || e));\n throw e;\n }\n };\n\n const content =\n selectedFile && selectedFile.path.match(/\\.ya?ml$/)\n ? selectedFile.content\n : undefined;\n\n if (!directoryEditor) {\n return null;\n }\n\n return (\n <TemplateEditorForm\n onDryRun={handleDryRun}\n fieldExtensions={fieldExtensions}\n setErrorText={setErrorText}\n content={content}\n layouts={layouts}\n formProps={props.formProps}\n />\n );\n}\n\nTemplateEditorForm.DirectoryEditorDryRun =\n TemplateEditorFormDirectoryEditorDryRun;\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAuCA,MAAM,YAAY,UAAA,CAAW;AAAA,EAC3B,gBAAA,EAAkB;AAAA,IAChB,KAAA,EAAO;AAAA;AAEX,CAAC,CAAA;AAYD,MAAM,sBAAsB,SAAA,CAAkD;AAAA,EAC5E,KAAA,GAAQ;AAAA,IACN,YAAA,EAAc;AAAA,GAChB;AAAA,EAEA,mBAAmB,SAAA,EAAqC;AACtD,IAAA,IAAI,SAAA,CAAU,WAAA,KAAgB,IAAA,CAAK,KAAA,CAAM,WAAA,EAAa;AACpD,MAAA,IAAA,CAAK,QAAA,CAAS,EAAE,YAAA,EAAc,IAAA,EAAM,CAAA;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,kBAAkB,KAAA,EAAc;AAC9B,IAAA,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,KAAA,CAAM,OAAO,CAAA;AACrC,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,YAAA,EAAc,KAAA,EAAO,CAAA;AAAA,EACvC;AAAA,EAEA,MAAA,GAAS;AACP,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,YAAA,GAAe,IAAA,CAAK,MAAM,QAAA,GAAW,IAAA;AAAA,EACzD;AACF;AAcA,SAAS,aAAa,KAAA,EAAmD;AACvE,EAAA,OAAO,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;AAGO,SAAS,mBAAmB,KAAA,EAAgC;AACjE,EAAA,MAAM;AAAA,IACJ,OAAA;AAAA,IACA,aAAA;AAAA,IACA,QAAA;AAAA,IACA,YAAA;AAAA,IACA,kBAAkB,EAAC;AAAA,IACnB,UAAU;AAAC,GACb,GAAI,KAAA;AACJ,EAAA,MAAM,UAAU,SAAA,EAAU;AAC1B,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,wBAAwB,CAAA;AAExD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAA,EAA2C;AAErE,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAM;AAC3B,IAAA,OAAO,MAAA,CAAO,WAAA;AAAA,MACZ,eAAA,CAAgB,GAAA,CAAI,CAAC,EAAE,IAAA,EAAM,WAAU,KAAM,CAAC,IAAA,EAAM,SAAS,CAAC;AAAA,KAChE;AAAA,EACF,CAAA,EAAG,CAAC,eAAe,CAAC,CAAA;AAEpB,EAAA,WAAA;AAAA,IACE,MAAM;AACJ,MAAA,IAAI;AACF,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,QAAA,CAAS,KAAA,CAAS,CAAA;AAClB,UAAA;AAAA,QACF;AACA,QAAA,MAAM,MAAA,GAAoB,IAAA,CACvB,iBAAA,CAAkB,OAAO,EACzB,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,CAAA,CACb,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,MAAA,EAAQ,EAAE,CAAC,CAAA;AAEzB,QAAA,IAAI,CAAC,YAAA,CAAa,MAAM,CAAA,EAAG;AACzB,UAAA,QAAA,CAAS,KAAA,CAAS,CAAA;AAClB,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,OAAA,GAAU,MAAA;AACd,QAAA,IAAI,CAAC,aAAA,EAAe;AAClB,UAAA,MAAM,aAAa,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,CAAE,aAAY,KAAM,UAAA;AACzD,UAAA,IAAI,CAAC,UAAA,EAAY;AACf,YAAA,QAAA,CAAS,KAAA,CAAS,CAAA;AAClB,YAAA;AAAA,UACF;AAEA,UAAA,OAAA,GAAU,aAAa,MAAA,CAAO,IAAI,CAAA,GAAI,MAAA,CAAO,OAAO,EAAC;AAAA,QACvD;AAEA,QAAA,MAAM,EAAE,YAAW,GAAI,OAAA;AAEvB,QAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,EAAG;AAC9B,UAAA,YAAA,CAAa,sCAAsC,CAAA;AACnD,UAAA,QAAA,CAAS,KAAA,CAAS,CAAA;AAClB,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,kBAAkB,MAAA,CAAO,WAAA;AAAA,UAC7B,eAAA,CAAgB,GAAA,CAAI,CAAC,EAAE,IAAA,EAAM,YAAW,KAAM,CAAC,IAAA,EAAM,UAAU,CAAC;AAAA,SAClE;AAEA,QAAA,YAAA,EAAa;AACb,QAAA,QAAA;AAAA,UACE,UAAA,CAAW,OAAA;AAAA,YAAQ,CAAA,KAAA,KACjB,YAAA,CAAa,KAAK,CAAA,GACd;AAAA,cACE;AAAA,gBACE,KAAA,EAAO,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA;AAAA,gBACzB,MAAA,EAAQ,KAAA;AAAA,gBACR,QAAA,EAAU,qBAAA,CAAsB,KAAA,EAAO,eAAA,EAAiB;AAAA,kBACtD;AAAA,iBACD;AAAA;AACH,gBAEF;AAAC;AACP,SACF;AAAA,MACF,SAAS,CAAA,EAAG;AACV,QAAA,YAAA,CAAa,EAAE,OAAO,CAAA;AAAA,MACxB;AAAA,IACF,CAAA;AAAA,IACA,GAAA;AAAA,IACA,CAAC,aAAA,EAAe,OAAA,EAAS,SAAS;AAAA,GACpC;AAEA,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,kBACrB,QAAA,EAAA,KAAA,mBACC,GAAA,CAAC,KAAA,EAAA,EAAM,OAAA,EAAQ,UAAA,EACb,QAAA,kBAAA,GAAA,CAAC,aAAA,EAAA,EAAc,WAAA,EAAa,OAAO,YAAA,EACjC,QAAA,kBAAA,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,QAAA,EAAU,EAAE,KAAA,EAAO,KAAA,EAAO,iBAAA,EAAkB;AAAA,MAC5C,UAAA,EAAY,eAAA;AAAA,MACZ,UAAA,EAAY,MAAA;AAAA,MACZ,QAAA,EAAU,OAAM,OAAA,KAAW;AACzB,QAAA,MAAM,WAAW,OAAO,CAAA;AAAA,MAC1B,CAAA;AAAA,MACA,OAAA;AAAA,MACA,WAAW,KAAA,CAAM;AAAA;AAAA,GACnB,EACF,CAAA,EACF,CAAA,mBAEA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,KAAA,EAAM,eAAA,EAC/B,QAAA,EAAA,CAAA,CAAE,sCAAsC,CAAA,EAC3C,CAAA,EAEJ,CAAA;AAEJ;AAGO,SAAS,wCACd,KAAA,EAIA;AACA,EAAA,MAAM,EAAE,YAAA,EAAc,eAAA,GAAkB,EAAC,EAAG,SAAQ,GAAI,KAAA;AACxD,EAAA,MAAM,SAAS,SAAA,EAAU;AAEzB,EAAA,MAAM,kBAAkB,kBAAA,EAAmB;AAC3C,EAAA,MAAM,EAAE,YAAA,EAAa,GAAI,eAAA,IAAmB,EAAC;AAE7C,EAAA,MAAM,YAAA,GAAe,OAAO,IAAA,KAAqB;AAC/C,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,OAAA,CAAQ;AAAA,QACnB,iBAAiB,YAAA,CAAa,OAAA;AAAA,QAC9B,MAAA,EAAQ,IAAA;AAAA,QACR,KAAA,EAAO,eAAA,EAAiB,KAAA,IAAS;AAAC,OACnC,CAAA;AACD,MAAA,YAAA,EAAa;AAAA,IACf,SAAS,CAAA,EAAG;AACV,MAAA,YAAA,CAAa,MAAA,CAAO,CAAA,CAAE,KAAA,IAAS,CAAC,CAAC,CAAA;AACjC,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,OAAA,GACJ,gBAAgB,YAAA,CAAa,IAAA,CAAK,MAAM,UAAU,CAAA,GAC9C,aAAa,OAAA,GACb,MAAA;AAEN,EAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,kBAAA;AAAA,IAAA;AAAA,MACC,QAAA,EAAU,YAAA;AAAA,MACV,eAAA;AAAA,MACA,YAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAA;AAAA,MACA,WAAW,KAAA,CAAM;AAAA;AAAA,GACnB;AAEJ;AAEA,kBAAA,CAAmB,qBAAA,GACjB,uCAAA;;;;"}
@@ -21,7 +21,8 @@ import { OpaqueFormField } from '../../packages/scaffolder-internal/src/wiring/I
21
21
  import '../../packages/scaffolder-internal/src/wiring/InternalFormDecorator.esm.js';
22
22
 
23
23
  function TemplateListContent({
24
- groups: configuredGroups
24
+ groups: configuredGroups,
25
+ templateFilter
25
26
  }) {
26
27
  const registerComponentLink = useRouteRef(registerComponentRouteRef);
27
28
  const viewTechDocsLink = useRouteRef(viewTechDocRouteRef);
@@ -98,6 +99,7 @@ function TemplateListContent({
98
99
  TemplateGroups,
99
100
  {
100
101
  groups,
102
+ templateFilter,
101
103
  onTemplateSelected,
102
104
  additionalLinksForEntity
103
105
  }
@@ -129,7 +131,19 @@ function TemplatesSubPage(props) {
129
131
  )
130
132
  ];
131
133
  return /* @__PURE__ */ jsxs(Routes, { children: [
132
- /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(TemplateListContent, { groups: props.groups }) }),
134
+ /* @__PURE__ */ jsx(
135
+ Route,
136
+ {
137
+ index: true,
138
+ element: /* @__PURE__ */ jsx(
139
+ TemplateListContent,
140
+ {
141
+ groups: props.groups,
142
+ templateFilter: props.templateFilter
143
+ }
144
+ )
145
+ }
146
+ ),
133
147
  /* @__PURE__ */ jsx(
134
148
  Route,
135
149
  {
@@ -1 +1 @@
1
- {"version":3,"file":"TemplatesSubPage.esm.js","sources":["../../../src/alpha/components/TemplatesSubPage.tsx"],"sourcesContent":["/*\n * Copyright 2026 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 { useCallback, useMemo } from 'react';\nimport { Routes, Route, useNavigate, useParams } from 'react-router-dom';\nimport {\n Content,\n ContentHeader,\n DocsIcon,\n SupportButton,\n} from '@backstage/core-components';\nimport { useApp, useRouteRef } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport {\n EntityKindPicker,\n EntityListProvider,\n EntitySearchBar,\n EntityTagPicker,\n CatalogFilterLayout,\n UserListPicker,\n EntityOwnerPicker,\n} from '@backstage/plugin-catalog-react';\nimport {\n TemplateCategoryPicker,\n TemplateGroups,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { createGroupsWithOther } from '../lib/createGroupsWithOther';\nimport {\n FieldExtensionOptions,\n FormProps,\n type LayoutOptions,\n SecretsContextProvider,\n TemplateGroupFilter,\n useCustomFieldExtensions,\n useCustomLayouts,\n} from '@backstage/plugin-scaffolder-react';\nimport { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { FormField } from '@backstage/plugin-scaffolder-react/alpha';\nimport { OpaqueFormField } from '@internal/scaffolder';\nimport { RegisterExistingButton } from './TemplateListPage/RegisterExistingButton';\nimport { TemplateWizardPageContent } from './TemplateWizardPage';\nimport {\n registerComponentRouteRef,\n selectedTemplateRouteRef,\n viewTechDocRouteRef,\n} from '../../routes';\nimport { scaffolderTranslationRef } from '../../translation';\nimport { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../../extensions/default';\nimport { buildTechDocsURL } from '@backstage/plugin-techdocs-react';\nimport { BreadcrumbEntry } from '@backstage/frontend-plugin-api';\nimport {\n TECHDOCS_ANNOTATION,\n TECHDOCS_EXTERNAL_ANNOTATION,\n} from '@backstage/plugin-techdocs-common';\n\nfunction TemplateListContent({\n groups: configuredGroups,\n}: {\n groups?: TemplateGroupFilter[];\n}) {\n const registerComponentLink = useRouteRef(registerComponentRouteRef);\n const viewTechDocsLink = useRouteRef(viewTechDocRouteRef);\n const templateRoute = useRouteRef(selectedTemplateRouteRef);\n const navigate = useNavigate();\n const app = useApp();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const groups = useMemo(\n () =>\n configuredGroups?.length\n ? createGroupsWithOther(\n configuredGroups,\n t('templateListPage.templateGroups.otherTitle'),\n )\n : [\n {\n title: t('templateListPage.templateGroups.defaultTitle'),\n filter: () => true,\n },\n ],\n [configuredGroups, t],\n );\n\n const additionalLinksForEntity = useCallback(\n (template: TemplateEntityV1beta3) => {\n if (\n !(\n template.metadata.annotations?.[TECHDOCS_ANNOTATION] ||\n template.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]\n ) ||\n !viewTechDocsLink\n ) {\n return [];\n }\n\n const url = buildTechDocsURL(template, viewTechDocsLink);\n return url\n ? [\n {\n icon: app.getSystemIcon('docs') ?? DocsIcon,\n text: t(\n 'templateListPage.additionalLinksForEntity.viewTechDocsTitle',\n ),\n url,\n },\n ]\n : [];\n },\n [app, viewTechDocsLink, t],\n );\n\n const onTemplateSelected = useCallback(\n (template: TemplateEntityV1beta3) => {\n const { namespace, name } = parseEntityRef(stringifyEntityRef(template));\n navigate(templateRoute({ namespace, templateName: name }));\n },\n [navigate, templateRoute],\n );\n\n return (\n <EntityListProvider>\n <Content>\n <ContentHeader>\n <RegisterExistingButton\n title={t(\n 'templateListPage.contentHeader.registerExistingButtonTitle',\n )}\n to={registerComponentLink && registerComponentLink()}\n />\n <SupportButton>\n {t('templateListPage.contentHeader.supportButtonTitle')}\n </SupportButton>\n </ContentHeader>\n\n <CatalogFilterLayout>\n <CatalogFilterLayout.Filters>\n <EntitySearchBar />\n <EntityKindPicker initialFilter=\"template\" hidden />\n <UserListPicker\n initialFilter=\"all\"\n availableFilters={['all', 'starred']}\n />\n <TemplateCategoryPicker />\n <EntityTagPicker />\n <EntityOwnerPicker />\n </CatalogFilterLayout.Filters>\n <CatalogFilterLayout.Content>\n <TemplateGroups\n groups={groups}\n onTemplateSelected={onTemplateSelected}\n additionalLinksForEntity={additionalLinksForEntity}\n />\n </CatalogFilterLayout.Content>\n </CatalogFilterLayout>\n </Content>\n </EntityListProvider>\n );\n}\n\nfunction TemplateWizardWithBreadcrumb(props: {\n customFieldExtensions: FieldExtensionOptions[];\n layouts: LayoutOptions[];\n formProps?: FormProps;\n}) {\n const { templateName } = useParams<{ templateName: string }>();\n return (\n <BreadcrumbEntry entry={{ label: templateName ?? 'Template', href: '.' }}>\n <SecretsContextProvider>\n <TemplateWizardPageContent\n customFieldExtensions={props.customFieldExtensions}\n layouts={props.layouts}\n formProps={props.formProps}\n />\n </SecretsContextProvider>\n </BreadcrumbEntry>\n );\n}\n\n/**\n * Sub-page for the templates tab. Renders the template list at the index route\n * and the template wizard at the parameterized route.\n *\n * @internal\n */\nexport function TemplatesSubPage(props: {\n formFields?: Array<FormField>;\n formProps?: FormProps;\n groups?: TemplateGroupFilter[];\n}) {\n const customFieldExtensions = useCustomFieldExtensions(undefined);\n const customLayouts = useCustomLayouts(undefined);\n\n const fieldExtensions = [\n ...customFieldExtensions,\n ...(props.formFields?.map(OpaqueFormField.toInternal) ?? []),\n ...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(\n ({ name }) =>\n !customFieldExtensions.some(\n (customFieldExtension: FieldExtensionOptions) =>\n customFieldExtension.name === name,\n ),\n ),\n ] as FieldExtensionOptions[];\n\n return (\n <Routes>\n <Route index element={<TemplateListContent groups={props.groups} />} />\n <Route\n path=\":namespace/:templateName\"\n element={\n <TemplateWizardWithBreadcrumb\n customFieldExtensions={fieldExtensions}\n layouts={customLayouts}\n formProps={props.formProps}\n />\n }\n />\n </Routes>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TemplatesSubPage.esm.js","sources":["../../../src/alpha/components/TemplatesSubPage.tsx"],"sourcesContent":["/*\n * Copyright 2026 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 { useCallback, useMemo } from 'react';\nimport { Routes, Route, useNavigate, useParams } from 'react-router-dom';\nimport {\n Content,\n ContentHeader,\n DocsIcon,\n SupportButton,\n} from '@backstage/core-components';\nimport { useApp, useRouteRef } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport {\n EntityKindPicker,\n EntityListProvider,\n EntitySearchBar,\n EntityTagPicker,\n CatalogFilterLayout,\n UserListPicker,\n EntityOwnerPicker,\n} from '@backstage/plugin-catalog-react';\nimport {\n TemplateCategoryPicker,\n TemplateGroups,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { createGroupsWithOther } from '../lib/createGroupsWithOther';\nimport {\n FieldExtensionOptions,\n FormProps,\n type LayoutOptions,\n SecretsContextProvider,\n TemplateGroupFilter,\n useCustomFieldExtensions,\n useCustomLayouts,\n} from '@backstage/plugin-scaffolder-react';\nimport { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { FormField } from '@backstage/plugin-scaffolder-react/alpha';\nimport { OpaqueFormField } from '@internal/scaffolder';\nimport { RegisterExistingButton } from './TemplateListPage/RegisterExistingButton';\nimport { TemplateWizardPageContent } from './TemplateWizardPage';\nimport {\n registerComponentRouteRef,\n selectedTemplateRouteRef,\n viewTechDocRouteRef,\n} from '../../routes';\nimport { scaffolderTranslationRef } from '../../translation';\nimport { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../../extensions/default';\nimport { buildTechDocsURL } from '@backstage/plugin-techdocs-react';\nimport { BreadcrumbEntry } from '@backstage/frontend-plugin-api';\nimport {\n TECHDOCS_ANNOTATION,\n TECHDOCS_EXTERNAL_ANNOTATION,\n} from '@backstage/plugin-techdocs-common';\n\nfunction TemplateListContent({\n groups: configuredGroups,\n templateFilter,\n}: {\n groups?: TemplateGroupFilter[];\n templateFilter?: (entity: TemplateEntityV1beta3) => boolean;\n}) {\n const registerComponentLink = useRouteRef(registerComponentRouteRef);\n const viewTechDocsLink = useRouteRef(viewTechDocRouteRef);\n const templateRoute = useRouteRef(selectedTemplateRouteRef);\n const navigate = useNavigate();\n const app = useApp();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const groups = useMemo(\n () =>\n configuredGroups?.length\n ? createGroupsWithOther(\n configuredGroups,\n t('templateListPage.templateGroups.otherTitle'),\n )\n : [\n {\n title: t('templateListPage.templateGroups.defaultTitle'),\n filter: () => true,\n },\n ],\n [configuredGroups, t],\n );\n\n const additionalLinksForEntity = useCallback(\n (template: TemplateEntityV1beta3) => {\n if (\n !(\n template.metadata.annotations?.[TECHDOCS_ANNOTATION] ||\n template.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]\n ) ||\n !viewTechDocsLink\n ) {\n return [];\n }\n\n const url = buildTechDocsURL(template, viewTechDocsLink);\n return url\n ? [\n {\n icon: app.getSystemIcon('docs') ?? DocsIcon,\n text: t(\n 'templateListPage.additionalLinksForEntity.viewTechDocsTitle',\n ),\n url,\n },\n ]\n : [];\n },\n [app, viewTechDocsLink, t],\n );\n\n const onTemplateSelected = useCallback(\n (template: TemplateEntityV1beta3) => {\n const { namespace, name } = parseEntityRef(stringifyEntityRef(template));\n navigate(templateRoute({ namespace, templateName: name }));\n },\n [navigate, templateRoute],\n );\n\n return (\n <EntityListProvider>\n <Content>\n <ContentHeader>\n <RegisterExistingButton\n title={t(\n 'templateListPage.contentHeader.registerExistingButtonTitle',\n )}\n to={registerComponentLink && registerComponentLink()}\n />\n <SupportButton>\n {t('templateListPage.contentHeader.supportButtonTitle')}\n </SupportButton>\n </ContentHeader>\n\n <CatalogFilterLayout>\n <CatalogFilterLayout.Filters>\n <EntitySearchBar />\n <EntityKindPicker initialFilter=\"template\" hidden />\n <UserListPicker\n initialFilter=\"all\"\n availableFilters={['all', 'starred']}\n />\n <TemplateCategoryPicker />\n <EntityTagPicker />\n <EntityOwnerPicker />\n </CatalogFilterLayout.Filters>\n <CatalogFilterLayout.Content>\n <TemplateGroups\n groups={groups}\n templateFilter={templateFilter}\n onTemplateSelected={onTemplateSelected}\n additionalLinksForEntity={additionalLinksForEntity}\n />\n </CatalogFilterLayout.Content>\n </CatalogFilterLayout>\n </Content>\n </EntityListProvider>\n );\n}\n\nfunction TemplateWizardWithBreadcrumb(props: {\n customFieldExtensions: FieldExtensionOptions[];\n layouts: LayoutOptions[];\n formProps?: FormProps;\n}) {\n const { templateName } = useParams<{ templateName: string }>();\n return (\n <BreadcrumbEntry entry={{ label: templateName ?? 'Template', href: '.' }}>\n <SecretsContextProvider>\n <TemplateWizardPageContent\n customFieldExtensions={props.customFieldExtensions}\n layouts={props.layouts}\n formProps={props.formProps}\n />\n </SecretsContextProvider>\n </BreadcrumbEntry>\n );\n}\n\n/**\n * Sub-page for the templates tab. Renders the template list at the index route\n * and the template wizard at the parameterized route.\n *\n * @internal\n */\nexport function TemplatesSubPage(props: {\n formFields?: Array<FormField>;\n formProps?: FormProps;\n groups?: TemplateGroupFilter[];\n templateFilter?: (entity: TemplateEntityV1beta3) => boolean;\n}) {\n const customFieldExtensions = useCustomFieldExtensions(undefined);\n const customLayouts = useCustomLayouts(undefined);\n\n const fieldExtensions = [\n ...customFieldExtensions,\n ...(props.formFields?.map(OpaqueFormField.toInternal) ?? []),\n ...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(\n ({ name }) =>\n !customFieldExtensions.some(\n (customFieldExtension: FieldExtensionOptions) =>\n customFieldExtension.name === name,\n ),\n ),\n ] as FieldExtensionOptions[];\n\n return (\n <Routes>\n <Route\n index\n element={\n <TemplateListContent\n groups={props.groups}\n templateFilter={props.templateFilter}\n />\n }\n />\n <Route\n path=\":namespace/:templateName\"\n element={\n <TemplateWizardWithBreadcrumb\n customFieldExtensions={fieldExtensions}\n layouts={customLayouts}\n formProps={props.formProps}\n />\n }\n />\n </Routes>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -33,7 +33,8 @@ const scaffolderTemplatesSubPage = SubPageBlueprint.makeWithOverrides({
33
33
  title: z.string(),
34
34
  filter: createZodV4FilterPredicateSchema()
35
35
  })
36
- ).optional()
36
+ ).optional(),
37
+ templateFilter: createZodV4FilterPredicateSchema().optional()
37
38
  },
38
39
  factory(originalFactory, { apis, config }) {
39
40
  const formFieldsApi = apis.get(formFieldsApiRef);
@@ -43,6 +44,7 @@ const scaffolderTemplatesSubPage = SubPageBlueprint.makeWithOverrides({
43
44
  filter: filterPredicateToFilterFunction(group.filter)
44
45
  })
45
46
  );
47
+ const templateFilter = config.templateFilter === void 0 ? void 0 : filterPredicateToFilterFunction(config.templateFilter);
46
48
  return originalFactory({
47
49
  path: "templates",
48
50
  title: "Templates",
@@ -53,6 +55,7 @@ const scaffolderTemplatesSubPage = SubPageBlueprint.makeWithOverrides({
53
55
  {
54
56
  formFields,
55
57
  groups,
58
+ templateFilter,
56
59
  formProps: {
57
60
  EXPERIMENTAL_theme: config.enableBackstageUi ? "bui" : "mui"
58
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"extensions.esm.js","sources":["../../src/alpha/extensions.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ApiBlueprint,\n createExtensionInput,\n discoveryApiRef,\n fetchApiRef,\n identityApiRef,\n PageBlueprint,\n SubPageBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { z } from 'zod/v4';\nimport {\n createZodV4FilterPredicateSchema,\n filterPredicateToFilterFunction,\n} from '@backstage/filter-predicates';\nimport { rootRouteRef } from '../routes';\nimport CreateComponentIcon from '@material-ui/icons/AddCircleOutline';\nimport {\n FormFieldBlueprint,\n formFieldsApiRef,\n scaffolderTemplateOutputsComponentRef,\n scaffolderTemplateOutputTemplateRefsRef,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { scmIntegrationsApiRef } from '@backstage/integration-react';\nimport {\n scaffolderApiRef,\n TemplateGroupFilter,\n} from '@backstage/plugin-scaffolder-react';\nimport { ScaffolderClient } from '../api';\n\nexport const scaffolderPage = PageBlueprint.makeWithOverrides({\n inputs: {\n formFields: createExtensionInput([\n FormFieldBlueprint.dataRefs.formFieldLoader,\n ]),\n },\n factory(originalFactory) {\n return originalFactory({\n routeRef: rootRouteRef,\n path: '/create',\n title: 'Create',\n icon: <CreateComponentIcon fontSize=\"inherit\" />,\n });\n },\n});\n\nexport const scaffolderTemplatesSubPage = SubPageBlueprint.makeWithOverrides({\n name: 'templates',\n configSchema: {\n enableBackstageUi: z.boolean().optional().default(false),\n groups: z\n .array(\n z.object({\n title: z.string(),\n filter: createZodV4FilterPredicateSchema(),\n }),\n )\n .optional(),\n },\n factory(originalFactory, { apis, config }) {\n const formFieldsApi = apis.get(formFieldsApiRef);\n\n const groups: TemplateGroupFilter[] | undefined = config.groups?.map(\n group => ({\n title: group.title,\n filter: filterPredicateToFilterFunction(group.filter),\n }),\n );\n\n return originalFactory({\n path: 'templates',\n title: 'Templates',\n loader: async () => {\n const formFields = (await formFieldsApi?.loadFormFields()) ?? [];\n\n return import('./components/TemplatesSubPage').then(m => (\n <m.TemplatesSubPage\n formFields={formFields}\n groups={groups}\n formProps={{\n EXPERIMENTAL_theme: config.enableBackstageUi ? 'bui' : 'mui',\n }}\n />\n ));\n },\n });\n },\n});\n\nexport const scaffolderTasksSubPage = SubPageBlueprint.makeWithOverrides({\n name: 'tasks',\n inputs: {\n templateOutputsComponents: createExtensionInput(\n [\n scaffolderTemplateOutputsComponentRef,\n scaffolderTemplateOutputTemplateRefsRef,\n ],\n { optional: true },\n ),\n },\n factory(originalFactory, { inputs }) {\n return originalFactory({\n path: 'tasks',\n title: 'Tasks',\n loader: async () => {\n const templateOutputsComponents = inputs.templateOutputsComponents?.map(\n input => ({\n component: input.get(scaffolderTemplateOutputsComponentRef),\n templateRefs: input.get(scaffolderTemplateOutputTemplateRefsRef),\n }),\n );\n return import('./components/TasksSubPage').then(m => (\n <m.TasksSubPage\n templateOutputsComponents={templateOutputsComponents}\n />\n ));\n },\n });\n },\n});\n\nexport const scaffolderActionsSubPage = SubPageBlueprint.make({\n name: 'actions',\n params: {\n path: 'actions',\n title: 'Actions',\n loader: () =>\n Promise.all([\n import('../components/ActionsPage'),\n import('@backstage/core-components'),\n ]).then(([m, { Content }]) => (\n <Content>\n <m.ActionPageContent />\n </Content>\n )),\n },\n});\n\nexport const scaffolderEditorSubPage = SubPageBlueprint.make({\n name: 'editor',\n params: {\n path: 'edit',\n title: 'Template Editor',\n loader: () =>\n import('./components/EditorSubPage').then(m => <m.EditorSubPage />),\n },\n});\n\nexport const scaffolderTemplatingExtensionsSubPage = SubPageBlueprint.make({\n name: 'templating-extensions',\n params: {\n path: 'templating-extensions',\n title: 'Templating Extensions',\n loader: () =>\n Promise.all([\n import('../components/TemplatingExtensionsPage'),\n import('@backstage/core-components'),\n ]).then(([m, { Content }]) => (\n <Content>\n <m.TemplatingExtensionsPageContent linkLocal />\n </Content>\n )),\n },\n});\n\nexport const repoUrlPickerFormField = FormFieldBlueprint.make({\n name: 'repo-url-picker',\n params: {\n field: () => import('./fields/RepoUrlPicker').then(m => m.RepoUrlPicker),\n },\n});\n\nexport const entityNamePickerFormField = FormFieldBlueprint.make({\n name: 'entity-name-picker',\n params: {\n field: () =>\n import('./fields/EntityNamePicker').then(m => m.EntityNamePicker),\n },\n});\n\nexport const entityPickerFormField = FormFieldBlueprint.make({\n name: 'entity-picker',\n params: {\n field: () => import('./fields/EntityPicker').then(m => m.EntityPicker),\n },\n});\n\nexport const ownerPickerFormField = FormFieldBlueprint.make({\n name: 'owner-picker',\n params: {\n field: () => import('./fields/OwnerPicker').then(m => m.OwnerPicker),\n },\n});\n\nexport const entityTagsPickerFormField = FormFieldBlueprint.make({\n name: 'entity-tags-picker',\n params: {\n field: () =>\n import('./fields/EntityTagsPicker').then(m => m.EntityTagsPicker),\n },\n});\n\nexport const multiEntityPickerFormField = FormFieldBlueprint.make({\n name: 'multi-entity-picker',\n params: {\n field: () =>\n import('./fields/MultiEntityPicker').then(m => m.MultiEntityPicker),\n },\n});\n\nexport const myGroupsPickerFormField = FormFieldBlueprint.make({\n name: 'my-groups-picker',\n params: {\n field: () => import('./fields/MyGroupsPicker').then(m => m.MyGroupsPicker),\n },\n});\n\nexport const ownedEntityPickerFormField = FormFieldBlueprint.make({\n name: 'owned-entity-picker',\n params: {\n field: () =>\n import('./fields/OwnedEntityPicker').then(m => m.OwnedEntityPicker),\n },\n});\n\nexport const repoBranchPickerFormField = FormFieldBlueprint.make({\n name: 'repo-branch-picker',\n params: {\n field: () =>\n import('./fields/RepoBranchPicker').then(m => m.RepoBranchPicker),\n },\n});\n\nexport const repoOwnerPickerFormField = FormFieldBlueprint.make({\n name: 'repo-owner-picker',\n params: {\n field: () =>\n import('./fields/RepoOwnerPicker').then(m => m.RepoOwnerPicker),\n },\n});\n\nexport const scaffolderApi = ApiBlueprint.make({\n params: defineParams =>\n defineParams({\n api: scaffolderApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n scmIntegrationsApi: scmIntegrationsApiRef,\n fetchApi: fetchApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ discoveryApi, scmIntegrationsApi, fetchApi, identityApi }) =>\n new ScaffolderClient({\n discoveryApi,\n scmIntegrationsApi,\n fetchApi,\n identityApi,\n }),\n }),\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extensions.esm.js","sources":["../../src/alpha/extensions.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ApiBlueprint,\n createExtensionInput,\n discoveryApiRef,\n fetchApiRef,\n identityApiRef,\n PageBlueprint,\n SubPageBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { z } from 'zod/v4';\nimport {\n createZodV4FilterPredicateSchema,\n filterPredicateToFilterFunction,\n} from '@backstage/filter-predicates';\nimport { rootRouteRef } from '../routes';\nimport CreateComponentIcon from '@material-ui/icons/AddCircleOutline';\nimport {\n FormFieldBlueprint,\n formFieldsApiRef,\n scaffolderTemplateOutputsComponentRef,\n scaffolderTemplateOutputTemplateRefsRef,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { scmIntegrationsApiRef } from '@backstage/integration-react';\nimport {\n scaffolderApiRef,\n TemplateGroupFilter,\n} from '@backstage/plugin-scaffolder-react';\nimport { ScaffolderClient } from '../api';\n\nexport const scaffolderPage = PageBlueprint.makeWithOverrides({\n inputs: {\n formFields: createExtensionInput([\n FormFieldBlueprint.dataRefs.formFieldLoader,\n ]),\n },\n factory(originalFactory) {\n return originalFactory({\n routeRef: rootRouteRef,\n path: '/create',\n title: 'Create',\n icon: <CreateComponentIcon fontSize=\"inherit\" />,\n });\n },\n});\n\nexport const scaffolderTemplatesSubPage = SubPageBlueprint.makeWithOverrides({\n name: 'templates',\n configSchema: {\n enableBackstageUi: z.boolean().optional().default(false),\n groups: z\n .array(\n z.object({\n title: z.string(),\n filter: createZodV4FilterPredicateSchema(),\n }),\n )\n .optional(),\n templateFilter: createZodV4FilterPredicateSchema().optional(),\n },\n factory(originalFactory, { apis, config }) {\n const formFieldsApi = apis.get(formFieldsApiRef);\n\n const groups: TemplateGroupFilter[] | undefined = config.groups?.map(\n group => ({\n title: group.title,\n filter: filterPredicateToFilterFunction(group.filter),\n }),\n );\n const templateFilter =\n config.templateFilter === undefined\n ? undefined\n : filterPredicateToFilterFunction(config.templateFilter);\n\n return originalFactory({\n path: 'templates',\n title: 'Templates',\n loader: async () => {\n const formFields = (await formFieldsApi?.loadFormFields()) ?? [];\n\n return import('./components/TemplatesSubPage').then(m => (\n <m.TemplatesSubPage\n formFields={formFields}\n groups={groups}\n templateFilter={templateFilter}\n formProps={{\n EXPERIMENTAL_theme: config.enableBackstageUi ? 'bui' : 'mui',\n }}\n />\n ));\n },\n });\n },\n});\n\nexport const scaffolderTasksSubPage = SubPageBlueprint.makeWithOverrides({\n name: 'tasks',\n inputs: {\n templateOutputsComponents: createExtensionInput(\n [\n scaffolderTemplateOutputsComponentRef,\n scaffolderTemplateOutputTemplateRefsRef,\n ],\n { optional: true },\n ),\n },\n factory(originalFactory, { inputs }) {\n return originalFactory({\n path: 'tasks',\n title: 'Tasks',\n loader: async () => {\n const templateOutputsComponents = inputs.templateOutputsComponents?.map(\n input => ({\n component: input.get(scaffolderTemplateOutputsComponentRef),\n templateRefs: input.get(scaffolderTemplateOutputTemplateRefsRef),\n }),\n );\n return import('./components/TasksSubPage').then(m => (\n <m.TasksSubPage\n templateOutputsComponents={templateOutputsComponents}\n />\n ));\n },\n });\n },\n});\n\nexport const scaffolderActionsSubPage = SubPageBlueprint.make({\n name: 'actions',\n params: {\n path: 'actions',\n title: 'Actions',\n loader: () =>\n Promise.all([\n import('../components/ActionsPage'),\n import('@backstage/core-components'),\n ]).then(([m, { Content }]) => (\n <Content>\n <m.ActionPageContent />\n </Content>\n )),\n },\n});\n\nexport const scaffolderEditorSubPage = SubPageBlueprint.make({\n name: 'editor',\n params: {\n path: 'edit',\n title: 'Template Editor',\n loader: () =>\n import('./components/EditorSubPage').then(m => <m.EditorSubPage />),\n },\n});\n\nexport const scaffolderTemplatingExtensionsSubPage = SubPageBlueprint.make({\n name: 'templating-extensions',\n params: {\n path: 'templating-extensions',\n title: 'Templating Extensions',\n loader: () =>\n Promise.all([\n import('../components/TemplatingExtensionsPage'),\n import('@backstage/core-components'),\n ]).then(([m, { Content }]) => (\n <Content>\n <m.TemplatingExtensionsPageContent linkLocal />\n </Content>\n )),\n },\n});\n\nexport const repoUrlPickerFormField = FormFieldBlueprint.make({\n name: 'repo-url-picker',\n params: {\n field: () => import('./fields/RepoUrlPicker').then(m => m.RepoUrlPicker),\n },\n});\n\nexport const entityNamePickerFormField = FormFieldBlueprint.make({\n name: 'entity-name-picker',\n params: {\n field: () =>\n import('./fields/EntityNamePicker').then(m => m.EntityNamePicker),\n },\n});\n\nexport const entityPickerFormField = FormFieldBlueprint.make({\n name: 'entity-picker',\n params: {\n field: () => import('./fields/EntityPicker').then(m => m.EntityPicker),\n },\n});\n\nexport const ownerPickerFormField = FormFieldBlueprint.make({\n name: 'owner-picker',\n params: {\n field: () => import('./fields/OwnerPicker').then(m => m.OwnerPicker),\n },\n});\n\nexport const entityTagsPickerFormField = FormFieldBlueprint.make({\n name: 'entity-tags-picker',\n params: {\n field: () =>\n import('./fields/EntityTagsPicker').then(m => m.EntityTagsPicker),\n },\n});\n\nexport const multiEntityPickerFormField = FormFieldBlueprint.make({\n name: 'multi-entity-picker',\n params: {\n field: () =>\n import('./fields/MultiEntityPicker').then(m => m.MultiEntityPicker),\n },\n});\n\nexport const myGroupsPickerFormField = FormFieldBlueprint.make({\n name: 'my-groups-picker',\n params: {\n field: () => import('./fields/MyGroupsPicker').then(m => m.MyGroupsPicker),\n },\n});\n\nexport const ownedEntityPickerFormField = FormFieldBlueprint.make({\n name: 'owned-entity-picker',\n params: {\n field: () =>\n import('./fields/OwnedEntityPicker').then(m => m.OwnedEntityPicker),\n },\n});\n\nexport const repoBranchPickerFormField = FormFieldBlueprint.make({\n name: 'repo-branch-picker',\n params: {\n field: () =>\n import('./fields/RepoBranchPicker').then(m => m.RepoBranchPicker),\n },\n});\n\nexport const repoOwnerPickerFormField = FormFieldBlueprint.make({\n name: 'repo-owner-picker',\n params: {\n field: () =>\n import('./fields/RepoOwnerPicker').then(m => m.RepoOwnerPicker),\n },\n});\n\nexport const scaffolderApi = ApiBlueprint.make({\n params: defineParams =>\n defineParams({\n api: scaffolderApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n scmIntegrationsApi: scmIntegrationsApiRef,\n fetchApi: fetchApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ discoveryApi, scmIntegrationsApi, fetchApi, identityApi }) =>\n new ScaffolderClient({\n discoveryApi,\n scmIntegrationsApi,\n fetchApi,\n identityApi,\n }),\n }),\n});\n"],"names":[],"mappings":"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"}
package/dist/alpha.d.ts CHANGED
@@ -433,6 +433,7 @@ declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin
433
433
  title: string;
434
434
  filter: _backstage_filter_predicates.FilterPredicate;
435
435
  }[] | undefined;
436
+ templateFilter: _backstage_filter_predicates.FilterPredicate | undefined;
436
437
  path: string | undefined;
437
438
  title: string | undefined;
438
439
  };
@@ -442,6 +443,7 @@ declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin
442
443
  title: string;
443
444
  filter: _backstage_filter_predicates.FilterPredicate;
444
445
  }[] | undefined;
446
+ templateFilter?: _backstage_filter_predicates.FilterPredicate | undefined;
445
447
  path?: string | undefined;
446
448
  title?: string | undefined;
447
449
  };
@@ -60,7 +60,7 @@ const EntityTagsPicker = (props) => {
60
60
  let addDuplicate = false;
61
61
  const currentTags = formData || [];
62
62
  if (values?.length && currentTags.length < values.length) {
63
- const newTag = values[values.length - 1] = values[values.length - 1].toLocaleLowerCase("en-US").trim();
63
+ const newTag = values[values.length - 1] = values[values.length - 1].toLowerCase().trim();
64
64
  hasError = !tagValidator(newTag);
65
65
  addDuplicate = currentTags.indexOf(newTag) !== -1;
66
66
  }
@@ -94,7 +94,7 @@ const EntityTagsPicker = (props) => {
94
94
  setInputValue("");
95
95
  setInputError(false);
96
96
  } else if (inputValue) {
97
- const newTag = inputValue.toLocaleLowerCase("en-US").trim();
97
+ const newTag = inputValue.toLowerCase().trim();
98
98
  const isValid = tagValidator(newTag);
99
99
  const isDuplicate = selectedTags.includes(newTag);
100
100
  setInputError(!isValid);
@@ -1 +1 @@
1
- {"version":3,"file":"EntityTagsPicker.esm.js","sources":["../../../../src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { type Key, ChangeEvent, useCallback, useMemo, useState } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport useEffectOnce from 'react-use/esm/useEffectOnce';\nimport { GetEntityFacetsRequest } from '@backstage/catalog-client';\nimport { makeValidator } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport { EntityTagsPickerProps } from './schema';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport {\n ScaffolderField,\n useScaffolderTheme,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { Autocomplete as BuiAutocomplete } from '../Autocomplete';\nimport { chipStyle, chipRemoveStyle } from '../buiChipStyles';\n\nexport { EntityTagsPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `EntityTagsPicker`\n * field extension.\n *\n * @public\n */\nexport const EntityTagsPicker = (props: EntityTagsPickerProps) => {\n const theme = useScaffolderTheme();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const {\n formData,\n onChange,\n schema: {\n title = t('fields.entityTagsPicker.title'),\n description = t('fields.entityTagsPicker.description'),\n },\n uiSchema,\n rawErrors,\n required,\n errors,\n } = props;\n const catalogApi = useApi(catalogApiRef);\n const [tagOptions, setTagOptions] = useState<string[]>([]);\n const [inputValue, setInputValue] = useState('');\n const [inputError, setInputError] = useState(false);\n const tagValidator = makeValidator().isValidTag;\n const kinds = uiSchema['ui:options']?.kinds;\n const showCounts = uiSchema['ui:options']?.showCounts;\n const helperText = uiSchema['ui:options']?.helperText;\n const isDisabled = uiSchema?.['ui:disabled'] ?? false;\n\n const { loading, value: existingTags } = useAsync(async () => {\n const facet = 'metadata.tags';\n const tagsRequest: GetEntityFacetsRequest = { facets: [facet] };\n if (kinds) {\n tagsRequest.filter = { kind: kinds };\n }\n\n const { facets } = await catalogApi.getEntityFacets(tagsRequest);\n\n const tagFacets = Object.fromEntries(\n facets[facet].map(({ value, count }) => [value, count]),\n );\n\n setTagOptions(\n Object.keys(tagFacets).sort((a, b) =>\n showCounts ? tagFacets[b] - tagFacets[a] : a.localeCompare(b),\n ),\n );\n\n return tagFacets;\n });\n\n const setTags = (_: ChangeEvent<{}>, values: string[] | null) => {\n // Reset error state in case all tags were removed\n let hasError = false;\n let addDuplicate = false;\n const currentTags = formData || [];\n\n // If adding a new tag\n if (values?.length && currentTags.length < values.length) {\n const newTag = (values[values.length - 1] = values[values.length - 1]\n .toLocaleLowerCase('en-US')\n .trim());\n hasError = !tagValidator(newTag);\n addDuplicate = currentTags.indexOf(newTag) !== -1;\n }\n\n setInputError(hasError);\n setInputValue(!hasError ? '' : inputValue);\n if (!hasError && !addDuplicate) {\n onChange(values || []);\n }\n };\n\n // BUI: computed tag options\n const buiTagOptions = useMemo(() => {\n if (!existingTags) return [];\n return Object.keys(existingTags).sort((a, b) =>\n showCounts ? existingTags[b] - existingTags[a] : a.localeCompare(b),\n );\n }, [existingTags, showCounts]);\n\n const selectedTags = useMemo(() => formData || [], [formData]);\n const availableOptions = useMemo(\n () =>\n buiTagOptions\n .filter(tag => !selectedTags.includes(tag))\n .map(tag => ({\n value: tag,\n label:\n showCounts && existingTags ? `${tag} (${existingTags[tag]})` : tag,\n })),\n [buiTagOptions, selectedTags, showCounts, existingTags],\n );\n\n const handleSelectionChange = useCallback(\n (key: Key | null) => {\n if (key !== null) {\n const tag = String(key);\n if (!selectedTags.includes(tag)) {\n onChange([...selectedTags, tag]);\n }\n setInputValue('');\n setInputError(false);\n } else if (inputValue) {\n const newTag = inputValue.toLocaleLowerCase('en-US').trim();\n const isValid = tagValidator(newTag);\n const isDuplicate = selectedTags.includes(newTag);\n setInputError(!isValid);\n\n if (isValid && !isDuplicate) {\n onChange([...selectedTags, newTag]);\n setInputValue('');\n }\n }\n },\n [selectedTags, onChange, inputValue, tagValidator],\n );\n\n const handleRemove = useCallback(\n (tag: string) => {\n onChange(selectedTags.filter(item => item !== tag));\n },\n [selectedTags, onChange],\n );\n\n // Initialize field to always return an array\n useEffectOnce(() => onChange(formData || []));\n\n if (theme === 'bui') {\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={\n (helperText as string) ?? uiSchema['ui:description'] ?? description\n }\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <div>\n {selectedTags.length > 0 && (\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: 'var(--bui-space-1)',\n marginBottom: 'var(--bui-space-2)',\n }}\n >\n {selectedTags.map(tag => (\n <span key={tag} style={chipStyle}>\n {tag}\n {!isDisabled && (\n <button\n type=\"button\"\n onClick={() => handleRemove(tag)}\n style={chipRemoveStyle}\n aria-label={`Remove ${tag}`}\n >\n &times;\n </button>\n )}\n </span>\n ))}\n </div>\n )}\n <BuiAutocomplete\n label={title}\n isRequired={required}\n isDisabled={isDisabled}\n selectedKey={null}\n inputValue={inputValue}\n onInputChange={setInputValue}\n onSelectionChange={handleSelectionChange}\n isLoading={loading}\n options={availableOptions}\n allowsCustomValue\n isInvalid={inputError || (rawErrors && rawErrors.length > 0)}\n />\n </div>\n </ScaffolderField>\n );\n }\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={helperText ?? uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <Autocomplete\n multiple\n freeSolo\n filterSelectedOptions\n onChange={setTags}\n disabled={isDisabled}\n value={formData || []}\n inputValue={inputValue}\n loading={loading}\n options={tagOptions}\n ChipProps={{ size: 'small' }}\n renderOption={option =>\n showCounts ? `${option} (${existingTags?.[option]})` : option\n }\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n disabled={isDisabled}\n onChange={e => setInputValue(e.target.value)}\n error={inputError}\n FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }}\n />\n )}\n />\n </ScaffolderField>\n );\n};\n"],"names":["BuiAutocomplete","Autocomplete","TextField"],"mappings":"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"}
1
+ {"version":3,"file":"EntityTagsPicker.esm.js","sources":["../../../../src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { type Key, ChangeEvent, useCallback, useMemo, useState } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport useEffectOnce from 'react-use/esm/useEffectOnce';\nimport { GetEntityFacetsRequest } from '@backstage/catalog-client';\nimport { makeValidator } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport { EntityTagsPickerProps } from './schema';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport {\n ScaffolderField,\n useScaffolderTheme,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { Autocomplete as BuiAutocomplete } from '../Autocomplete';\nimport { chipStyle, chipRemoveStyle } from '../buiChipStyles';\n\nexport { EntityTagsPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `EntityTagsPicker`\n * field extension.\n *\n * @public\n */\nexport const EntityTagsPicker = (props: EntityTagsPickerProps) => {\n const theme = useScaffolderTheme();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const {\n formData,\n onChange,\n schema: {\n title = t('fields.entityTagsPicker.title'),\n description = t('fields.entityTagsPicker.description'),\n },\n uiSchema,\n rawErrors,\n required,\n errors,\n } = props;\n const catalogApi = useApi(catalogApiRef);\n const [tagOptions, setTagOptions] = useState<string[]>([]);\n const [inputValue, setInputValue] = useState('');\n const [inputError, setInputError] = useState(false);\n const tagValidator = makeValidator().isValidTag;\n const kinds = uiSchema['ui:options']?.kinds;\n const showCounts = uiSchema['ui:options']?.showCounts;\n const helperText = uiSchema['ui:options']?.helperText;\n const isDisabled = uiSchema?.['ui:disabled'] ?? false;\n\n const { loading, value: existingTags } = useAsync(async () => {\n const facet = 'metadata.tags';\n const tagsRequest: GetEntityFacetsRequest = { facets: [facet] };\n if (kinds) {\n tagsRequest.filter = { kind: kinds };\n }\n\n const { facets } = await catalogApi.getEntityFacets(tagsRequest);\n\n const tagFacets = Object.fromEntries(\n facets[facet].map(({ value, count }) => [value, count]),\n );\n\n setTagOptions(\n Object.keys(tagFacets).sort((a, b) =>\n showCounts ? tagFacets[b] - tagFacets[a] : a.localeCompare(b),\n ),\n );\n\n return tagFacets;\n });\n\n const setTags = (_: ChangeEvent<{}>, values: string[] | null) => {\n // Reset error state in case all tags were removed\n let hasError = false;\n let addDuplicate = false;\n const currentTags = formData || [];\n\n // If adding a new tag\n if (values?.length && currentTags.length < values.length) {\n const newTag = (values[values.length - 1] = values[values.length - 1]\n .toLowerCase()\n .trim());\n hasError = !tagValidator(newTag);\n addDuplicate = currentTags.indexOf(newTag) !== -1;\n }\n\n setInputError(hasError);\n setInputValue(!hasError ? '' : inputValue);\n if (!hasError && !addDuplicate) {\n onChange(values || []);\n }\n };\n\n // BUI: computed tag options\n const buiTagOptions = useMemo(() => {\n if (!existingTags) return [];\n return Object.keys(existingTags).sort((a, b) =>\n showCounts ? existingTags[b] - existingTags[a] : a.localeCompare(b),\n );\n }, [existingTags, showCounts]);\n\n const selectedTags = useMemo(() => formData || [], [formData]);\n const availableOptions = useMemo(\n () =>\n buiTagOptions\n .filter(tag => !selectedTags.includes(tag))\n .map(tag => ({\n value: tag,\n label:\n showCounts && existingTags ? `${tag} (${existingTags[tag]})` : tag,\n })),\n [buiTagOptions, selectedTags, showCounts, existingTags],\n );\n\n const handleSelectionChange = useCallback(\n (key: Key | null) => {\n if (key !== null) {\n const tag = String(key);\n if (!selectedTags.includes(tag)) {\n onChange([...selectedTags, tag]);\n }\n setInputValue('');\n setInputError(false);\n } else if (inputValue) {\n const newTag = inputValue.toLowerCase().trim();\n const isValid = tagValidator(newTag);\n const isDuplicate = selectedTags.includes(newTag);\n setInputError(!isValid);\n\n if (isValid && !isDuplicate) {\n onChange([...selectedTags, newTag]);\n setInputValue('');\n }\n }\n },\n [selectedTags, onChange, inputValue, tagValidator],\n );\n\n const handleRemove = useCallback(\n (tag: string) => {\n onChange(selectedTags.filter(item => item !== tag));\n },\n [selectedTags, onChange],\n );\n\n // Initialize field to always return an array\n useEffectOnce(() => onChange(formData || []));\n\n if (theme === 'bui') {\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={\n (helperText as string) ?? uiSchema['ui:description'] ?? description\n }\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <div>\n {selectedTags.length > 0 && (\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: 'var(--bui-space-1)',\n marginBottom: 'var(--bui-space-2)',\n }}\n >\n {selectedTags.map(tag => (\n <span key={tag} style={chipStyle}>\n {tag}\n {!isDisabled && (\n <button\n type=\"button\"\n onClick={() => handleRemove(tag)}\n style={chipRemoveStyle}\n aria-label={`Remove ${tag}`}\n >\n &times;\n </button>\n )}\n </span>\n ))}\n </div>\n )}\n <BuiAutocomplete\n label={title}\n isRequired={required}\n isDisabled={isDisabled}\n selectedKey={null}\n inputValue={inputValue}\n onInputChange={setInputValue}\n onSelectionChange={handleSelectionChange}\n isLoading={loading}\n options={availableOptions}\n allowsCustomValue\n isInvalid={inputError || (rawErrors && rawErrors.length > 0)}\n />\n </div>\n </ScaffolderField>\n );\n }\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={helperText ?? uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <Autocomplete\n multiple\n freeSolo\n filterSelectedOptions\n onChange={setTags}\n disabled={isDisabled}\n value={formData || []}\n inputValue={inputValue}\n loading={loading}\n options={tagOptions}\n ChipProps={{ size: 'small' }}\n renderOption={option =>\n showCounts ? `${option} (${existingTags?.[option]})` : option\n }\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n disabled={isDisabled}\n onChange={e => setInputValue(e.target.value)}\n error={inputError}\n FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }}\n />\n )}\n />\n </ScaffolderField>\n );\n};\n"],"names":["BuiAutocomplete","Autocomplete","TextField"],"mappings":"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"}
@@ -17,7 +17,9 @@ const AzureRepoPicker = (props) => {
17
17
  rawErrors,
18
18
  state,
19
19
  onChange,
20
- isDisabled
20
+ isDisabled,
21
+ ownerLabel,
22
+ ownerDescription
21
23
  } = props;
22
24
  const { t } = useTranslationRef(scaffolderTranslationRef);
23
25
  const { organization, project } = state;
@@ -32,8 +34,8 @@ const AzureRepoPicker = (props) => {
32
34
  Select$1,
33
35
  {
34
36
  className: overrides.select,
35
- label: t("fields.azureRepoPicker.organization.title"),
36
- description: t("fields.azureRepoPicker.organization.description"),
37
+ label: ownerLabel ?? t("fields.azureRepoPicker.organization.title"),
38
+ description: ownerDescription ?? t("fields.azureRepoPicker.organization.description"),
37
39
  isDisabled: isDisabled || allowedOrganizations.length === 1,
38
40
  isInvalid: rawErrors?.length > 0 && !organization,
39
41
  selectedKey: organization ?? null,
@@ -48,8 +50,8 @@ const AzureRepoPicker = (props) => {
48
50
  return /* @__PURE__ */ jsx(
49
51
  TextField,
50
52
  {
51
- label: t("fields.azureRepoPicker.organization.title"),
52
- description: t("fields.azureRepoPicker.organization.description"),
53
+ label: ownerLabel ?? t("fields.azureRepoPicker.organization.title"),
54
+ description: ownerDescription ?? t("fields.azureRepoPicker.organization.description"),
53
55
  onChange: (value) => onChange({ organization: value }),
54
56
  isDisabled,
55
57
  value: organization ?? "",
@@ -113,21 +115,21 @@ const AzureRepoPicker = (props) => {
113
115
  Select,
114
116
  {
115
117
  native: true,
116
- label: t("fields.azureRepoPicker.organization.title"),
118
+ label: ownerLabel ?? t("fields.azureRepoPicker.organization.title"),
117
119
  onChange: (s) => onChange({ organization: String(Array.isArray(s) ? s[0] : s) }),
118
120
  disabled: isDisabled || allowedOrganizations.length === 1,
119
121
  selected: organization,
120
122
  items: organizationItems
121
123
  }
122
124
  ),
123
- /* @__PURE__ */ jsx(FormHelperText, { children: t("fields.azureRepoPicker.organization.description") })
125
+ /* @__PURE__ */ jsx(FormHelperText, { children: ownerDescription ?? t("fields.azureRepoPicker.organization.description") })
124
126
  ] }) : /* @__PURE__ */ jsx(
125
127
  MuiTextField,
126
128
  {
127
129
  id: "orgInput",
128
- label: t("fields.azureRepoPicker.organization.title"),
130
+ label: ownerLabel ?? t("fields.azureRepoPicker.organization.title"),
129
131
  onChange: (e) => onChange({ organization: e.target.value }),
130
- helperText: t("fields.azureRepoPicker.organization.description"),
132
+ helperText: ownerDescription ?? t("fields.azureRepoPicker.organization.description"),
131
133
  disabled: isDisabled,
132
134
  value: organization
133
135
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AzureRepoPicker.esm.js","sources":["../../../../src/components/fields/RepoUrlPicker/AzureRepoPicker.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport FormControl from '@material-ui/core/FormControl';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport MuiTextField from '@material-ui/core/TextField';\nimport { BaseRepoUrlPickerProps } from './types';\nimport { Select as MuiSelect, SelectItem } from '@backstage/core-components';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { useScaffolderTheme } from '@backstage/plugin-scaffolder-react/alpha';\nimport { TextField as BuiTextField, Select as BuiSelect } from '@backstage/ui';\nimport overrides from '../scaffolderFieldOverrides.module.css';\nimport type { Key } from 'react-aria-components';\n\nexport const AzureRepoPicker = (\n props: BaseRepoUrlPickerProps<{\n allowedOrganizations?: string[];\n allowedProject?: string[];\n }>,\n) => {\n const theme = useScaffolderTheme();\n const {\n allowedOrganizations = [],\n allowedProject = [],\n rawErrors,\n state,\n onChange,\n isDisabled,\n } = props;\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const { organization, project } = state;\n\n if (theme === 'bui') {\n const renderOrganizationPicker = () => {\n if (allowedOrganizations?.length) {\n const organizationItems = allowedOrganizations.map(i => ({\n label: i,\n value: i,\n }));\n\n return (\n <BuiSelect\n className={overrides.select}\n label={t('fields.azureRepoPicker.organization.title')}\n description={t('fields.azureRepoPicker.organization.description')}\n isDisabled={isDisabled || allowedOrganizations.length === 1}\n isInvalid={rawErrors?.length > 0 && !organization}\n selectedKey={organization ?? null}\n onSelectionChange={(key: Key | null) => {\n if (key !== null) onChange({ organization: String(key) });\n }}\n options={organizationItems}\n isRequired\n />\n );\n }\n\n return (\n <BuiTextField\n label={t('fields.azureRepoPicker.organization.title')}\n description={t('fields.azureRepoPicker.organization.description')}\n onChange={value => onChange({ organization: value })}\n isDisabled={isDisabled}\n value={organization ?? ''}\n isInvalid={rawErrors?.length > 0 && !organization}\n isRequired\n />\n );\n };\n\n const renderProjectPicker = () => {\n if (allowedProject?.length) {\n const projectItems = allowedProject.map(i => ({\n label: i,\n value: i,\n }));\n\n return (\n <BuiSelect\n className={overrides.select}\n label={t('fields.azureRepoPicker.project.title')}\n description={t('fields.azureRepoPicker.project.description')}\n isDisabled={isDisabled || allowedProject.length === 1}\n isInvalid={rawErrors?.length > 0 && !project}\n selectedKey={project ?? null}\n onSelectionChange={(key: Key | null) => {\n if (key !== null) onChange({ project: String(key) });\n }}\n options={projectItems}\n isRequired\n />\n );\n }\n\n return (\n <BuiTextField\n label={t('fields.azureRepoPicker.project.title')}\n description={t('fields.azureRepoPicker.project.description')}\n onChange={value => onChange({ project: value })}\n value={project ?? ''}\n isDisabled={isDisabled}\n isInvalid={rawErrors?.length > 0 && !project}\n isRequired\n />\n );\n };\n\n return (\n <>\n {renderOrganizationPicker()}\n {renderProjectPicker()}\n </>\n );\n }\n\n const organizationItems: SelectItem[] = allowedOrganizations\n ? allowedOrganizations.map(i => ({ label: i, value: i }))\n : [{ label: 'Loading...', value: 'loading' }];\n\n const projectItems: SelectItem[] = allowedProject\n ? allowedProject.map(i => ({ label: i, value: i }))\n : [{ label: 'Loading...', value: 'loading' }];\n\n return (\n <>\n <FormControl\n margin=\"normal\"\n required\n error={rawErrors?.length > 0 && !organization}\n >\n {allowedOrganizations?.length ? (\n <>\n <MuiSelect\n native\n label={t('fields.azureRepoPicker.organization.title')}\n onChange={s =>\n onChange({ organization: String(Array.isArray(s) ? s[0] : s) })\n }\n disabled={isDisabled || allowedOrganizations.length === 1}\n selected={organization}\n items={organizationItems}\n />\n <FormHelperText>\n {t('fields.azureRepoPicker.organization.description')}\n </FormHelperText>\n </>\n ) : (\n <MuiTextField\n id=\"orgInput\"\n label={t('fields.azureRepoPicker.organization.title')}\n onChange={e => onChange({ organization: e.target.value })}\n helperText={t('fields.azureRepoPicker.organization.description')}\n disabled={isDisabled}\n value={organization}\n />\n )}\n </FormControl>\n <FormControl\n margin=\"normal\"\n required\n error={rawErrors?.length > 0 && !project}\n >\n {allowedProject?.length ? (\n <>\n <MuiSelect\n native\n label={t('fields.azureRepoPicker.project.title')}\n onChange={s =>\n onChange({ project: String(Array.isArray(s) ? s[0] : s) })\n }\n disabled={isDisabled || allowedProject.length === 1}\n selected={project}\n items={projectItems}\n />\n <FormHelperText>\n {t('fields.azureRepoPicker.project.description')}\n </FormHelperText>\n </>\n ) : (\n <MuiTextField\n id=\"projectInput\"\n label={t('fields.azureRepoPicker.project.title')}\n onChange={e => onChange({ project: e.target.value })}\n value={project}\n disabled={isDisabled}\n helperText={t('fields.azureRepoPicker.project.description')}\n />\n )}\n </FormControl>\n </>\n );\n};\n"],"names":["organizationItems","BuiSelect","BuiTextField","projectItems","MuiSelect"],"mappings":"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"}
1
+ {"version":3,"file":"AzureRepoPicker.esm.js","sources":["../../../../src/components/fields/RepoUrlPicker/AzureRepoPicker.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport FormControl from '@material-ui/core/FormControl';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport MuiTextField from '@material-ui/core/TextField';\nimport { BaseRepoUrlPickerProps } from './types';\nimport { Select as MuiSelect, SelectItem } from '@backstage/core-components';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { useScaffolderTheme } from '@backstage/plugin-scaffolder-react/alpha';\nimport { TextField as BuiTextField, Select as BuiSelect } from '@backstage/ui';\nimport overrides from '../scaffolderFieldOverrides.module.css';\nimport type { Key } from 'react-aria-components';\n\nexport const AzureRepoPicker = (\n props: BaseRepoUrlPickerProps<{\n allowedOrganizations?: string[];\n allowedProject?: string[];\n ownerLabel?: string;\n ownerDescription?: string;\n }>,\n) => {\n const theme = useScaffolderTheme();\n const {\n allowedOrganizations = [],\n allowedProject = [],\n rawErrors,\n state,\n onChange,\n isDisabled,\n ownerLabel,\n ownerDescription,\n } = props;\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const { organization, project } = state;\n\n if (theme === 'bui') {\n const renderOrganizationPicker = () => {\n if (allowedOrganizations?.length) {\n const organizationItems = allowedOrganizations.map(i => ({\n label: i,\n value: i,\n }));\n\n return (\n <BuiSelect\n className={overrides.select}\n label={ownerLabel ?? t('fields.azureRepoPicker.organization.title')}\n description={\n ownerDescription ??\n t('fields.azureRepoPicker.organization.description')\n }\n isDisabled={isDisabled || allowedOrganizations.length === 1}\n isInvalid={rawErrors?.length > 0 && !organization}\n selectedKey={organization ?? null}\n onSelectionChange={(key: Key | null) => {\n if (key !== null) onChange({ organization: String(key) });\n }}\n options={organizationItems}\n isRequired\n />\n );\n }\n\n return (\n <BuiTextField\n label={ownerLabel ?? t('fields.azureRepoPicker.organization.title')}\n description={\n ownerDescription ??\n t('fields.azureRepoPicker.organization.description')\n }\n onChange={value => onChange({ organization: value })}\n isDisabled={isDisabled}\n value={organization ?? ''}\n isInvalid={rawErrors?.length > 0 && !organization}\n isRequired\n />\n );\n };\n\n const renderProjectPicker = () => {\n if (allowedProject?.length) {\n const projectItems = allowedProject.map(i => ({\n label: i,\n value: i,\n }));\n\n return (\n <BuiSelect\n className={overrides.select}\n label={t('fields.azureRepoPicker.project.title')}\n description={t('fields.azureRepoPicker.project.description')}\n isDisabled={isDisabled || allowedProject.length === 1}\n isInvalid={rawErrors?.length > 0 && !project}\n selectedKey={project ?? null}\n onSelectionChange={(key: Key | null) => {\n if (key !== null) onChange({ project: String(key) });\n }}\n options={projectItems}\n isRequired\n />\n );\n }\n\n return (\n <BuiTextField\n label={t('fields.azureRepoPicker.project.title')}\n description={t('fields.azureRepoPicker.project.description')}\n onChange={value => onChange({ project: value })}\n value={project ?? ''}\n isDisabled={isDisabled}\n isInvalid={rawErrors?.length > 0 && !project}\n isRequired\n />\n );\n };\n\n return (\n <>\n {renderOrganizationPicker()}\n {renderProjectPicker()}\n </>\n );\n }\n\n const organizationItems: SelectItem[] = allowedOrganizations\n ? allowedOrganizations.map(i => ({ label: i, value: i }))\n : [{ label: 'Loading...', value: 'loading' }];\n\n const projectItems: SelectItem[] = allowedProject\n ? allowedProject.map(i => ({ label: i, value: i }))\n : [{ label: 'Loading...', value: 'loading' }];\n\n return (\n <>\n <FormControl\n margin=\"normal\"\n required\n error={rawErrors?.length > 0 && !organization}\n >\n {allowedOrganizations?.length ? (\n <>\n <MuiSelect\n native\n label={\n ownerLabel ?? t('fields.azureRepoPicker.organization.title')\n }\n onChange={s =>\n onChange({ organization: String(Array.isArray(s) ? s[0] : s) })\n }\n disabled={isDisabled || allowedOrganizations.length === 1}\n selected={organization}\n items={organizationItems}\n />\n <FormHelperText>\n {ownerDescription ??\n t('fields.azureRepoPicker.organization.description')}\n </FormHelperText>\n </>\n ) : (\n <MuiTextField\n id=\"orgInput\"\n label={ownerLabel ?? t('fields.azureRepoPicker.organization.title')}\n onChange={e => onChange({ organization: e.target.value })}\n helperText={\n ownerDescription ??\n t('fields.azureRepoPicker.organization.description')\n }\n disabled={isDisabled}\n value={organization}\n />\n )}\n </FormControl>\n <FormControl\n margin=\"normal\"\n required\n error={rawErrors?.length > 0 && !project}\n >\n {allowedProject?.length ? (\n <>\n <MuiSelect\n native\n label={t('fields.azureRepoPicker.project.title')}\n onChange={s =>\n onChange({ project: String(Array.isArray(s) ? s[0] : s) })\n }\n disabled={isDisabled || allowedProject.length === 1}\n selected={project}\n items={projectItems}\n />\n <FormHelperText>\n {t('fields.azureRepoPicker.project.description')}\n </FormHelperText>\n </>\n ) : (\n <MuiTextField\n id=\"projectInput\"\n label={t('fields.azureRepoPicker.project.title')}\n onChange={e => onChange({ project: e.target.value })}\n value={project}\n disabled={isDisabled}\n helperText={t('fields.azureRepoPicker.project.description')}\n />\n )}\n </FormControl>\n </>\n );\n};\n"],"names":["organizationItems","BuiSelect","BuiTextField","projectItems","MuiSelect"],"mappings":"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"}
@@ -24,7 +24,9 @@ const BitbucketRepoPicker = (props) => {
24
24
  rawErrors,
25
25
  state,
26
26
  accessToken,
27
- isDisabled
27
+ isDisabled,
28
+ ownerLabel,
29
+ ownerDescription
28
30
  } = props;
29
31
  const { t } = useTranslationRef(scaffolderTranslationRef);
30
32
  const { host, workspace, project } = state;
@@ -98,8 +100,8 @@ const BitbucketRepoPicker = (props) => {
98
100
  Select$1,
99
101
  {
100
102
  className: overrides.select,
101
- label: t("fields.bitbucketRepoPicker.workspaces.title"),
102
- description: t("fields.bitbucketRepoPicker.workspaces.description"),
103
+ label: ownerLabel ?? t("fields.bitbucketRepoPicker.workspaces.title"),
104
+ description: ownerDescription ?? t("fields.bitbucketRepoPicker.workspaces.description"),
103
105
  isDisabled: isDisabled || allowedOwners.length === 1,
104
106
  isInvalid: rawErrors?.length > 0 && !workspace,
105
107
  selectedKey: workspace ?? null,
@@ -118,8 +120,8 @@ const BitbucketRepoPicker = (props) => {
118
120
  return /* @__PURE__ */ jsx(
119
121
  Autocomplete,
120
122
  {
121
- label: t("fields.bitbucketRepoPicker.workspaces.inputTitle"),
122
- description: t("fields.bitbucketRepoPicker.workspaces.description"),
123
+ label: ownerLabel ?? t("fields.bitbucketRepoPicker.workspaces.inputTitle"),
124
+ description: ownerDescription ?? t("fields.bitbucketRepoPicker.workspaces.description"),
123
125
  inputValue: workspace ?? "",
124
126
  onInputChange: (value) => onChange({ workspace: value }),
125
127
  onSelectionChange: (key) => {
@@ -196,7 +198,7 @@ const BitbucketRepoPicker = (props) => {
196
198
  Select,
197
199
  {
198
200
  native: true,
199
- label: t("fields.bitbucketRepoPicker.workspaces.title"),
201
+ label: ownerLabel ?? t("fields.bitbucketRepoPicker.workspaces.title"),
200
202
  onChange: (s) => onChange({ workspace: String(Array.isArray(s) ? s[0] : s) }),
201
203
  disabled: isDisabled || allowedOwners.length === 1,
202
204
  selected: workspace,
@@ -214,7 +216,7 @@ const BitbucketRepoPicker = (props) => {
214
216
  MuiTextField,
215
217
  {
216
218
  ...params,
217
- label: t("fields.bitbucketRepoPicker.workspaces.inputTitle"),
219
+ label: ownerLabel ?? t("fields.bitbucketRepoPicker.workspaces.inputTitle"),
218
220
  disabled: isDisabled,
219
221
  required: true
220
222
  }
@@ -224,7 +226,7 @@ const BitbucketRepoPicker = (props) => {
224
226
  autoSelect: true
225
227
  }
226
228
  ),
227
- /* @__PURE__ */ jsx(FormHelperText, { children: t("fields.bitbucketRepoPicker.workspaces.description") })
229
+ /* @__PURE__ */ jsx(FormHelperText, { children: ownerDescription ?? t("fields.bitbucketRepoPicker.workspaces.description") })
228
230
  ]
229
231
  }
230
232
  ),