@backstage/plugin-scaffolder 1.36.2-next.0 → 1.36.2-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/dist/alpha/components/TemplateEditorPage/TemplateFormPreviewer.esm.js +12 -8
- package/dist/alpha/components/TemplateEditorPage/TemplateFormPreviewer.esm.js.map +1 -1
- package/dist/alpha/components/TemplatesSubPage.esm.js +1 -0
- package/dist/alpha/components/TemplatesSubPage.esm.js.map +1 -1
- package/dist/alpha/formFieldsApi.esm.js +1 -1
- package/dist/components/RenderSchema/RenderSchema.esm.js +1 -1
- package/dist/components/Router/Router.esm.js +1 -0
- package/dist/components/Router/Router.esm.js.map +1 -1
- package/dist/components/Router/index.esm.js +5 -1
- package/dist/components/Router/index.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js +25 -25
- package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js.map +1 -1
- package/dist/deprecated.esm.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/lib/filesystem/WebFileSystemAccess.esm.js +8 -2
- package/dist/lib/filesystem/WebFileSystemAccess.esm.js.map +1 -1
- package/dist/lib/filesystem/WebFileSystemStore.esm.js.map +1 -1
- package/dist/plugins/scaffolder/package.json.esm.js +1 -1
- package/package.json +24 -24
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder
|
|
2
2
|
|
|
3
|
+
## 1.36.2-next.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e5af44c: Replaced deprecated `humanizeEntityRef` usage with the Catalog Presentation API.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @backstage/ui@0.14.0-next.2
|
|
10
|
+
- @backstage/errors@1.3.0-next.0
|
|
11
|
+
- @backstage/core-components@0.18.9-next.1
|
|
12
|
+
- @backstage/plugin-catalog-react@2.1.2-next.2
|
|
13
|
+
- @backstage/integration@2.0.1-next.0
|
|
14
|
+
- @backstage/catalog-client@1.14.1-next.0
|
|
15
|
+
- @backstage/catalog-model@1.7.8-next.0
|
|
16
|
+
- @backstage/core-plugin-api@1.12.5-next.2
|
|
17
|
+
- @backstage/frontend-plugin-api@0.16.0-next.2
|
|
18
|
+
- @backstage/plugin-scaffolder-common@2.0.1-next.0
|
|
19
|
+
- @backstage/plugin-scaffolder-react@1.20.1-next.2
|
|
20
|
+
- @backstage/plugin-techdocs-react@1.3.10-next.2
|
|
21
|
+
- @backstage/integration-react@1.2.17-next.1
|
|
22
|
+
- @backstage/plugin-catalog-common@1.1.9-next.0
|
|
23
|
+
- @backstage/plugin-permission-react@0.4.42-next.1
|
|
24
|
+
|
|
25
|
+
## 1.36.2-next.1
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- 864a799: Fix the display of the description in `GitlabRepoPicker`:
|
|
30
|
+
|
|
31
|
+
- Move `owner.description` helper text outside the `allowedOwners` conditional so it renders for both `Select` and `Autocomplete` modes.
|
|
32
|
+
- Update the `Autocomplete` label to use `fields.gitlabRepoPicker.owner.inputTitle` instead of `fields.gitlabRepoPicker.owner.title`.
|
|
33
|
+
|
|
34
|
+
- a7a14b7: Removed custom `IterableDirectoryHandle` and `WritableFileHandle` types in favor of the standard DOM `FileSystemDirectoryHandle` and `FileSystemFileHandle` types, which are now available through the `DOM.AsyncIterable` lib added to the shared TypeScript configuration.
|
|
35
|
+
- Updated dependencies
|
|
36
|
+
- @backstage/ui@0.14.0-next.1
|
|
37
|
+
- @backstage/plugin-catalog-react@2.1.2-next.1
|
|
38
|
+
- @backstage/frontend-plugin-api@0.16.0-next.1
|
|
39
|
+
- @backstage/core-components@0.18.9-next.0
|
|
40
|
+
- @backstage/core-plugin-api@1.12.5-next.1
|
|
41
|
+
- @backstage/plugin-scaffolder-react@1.20.1-next.1
|
|
42
|
+
- @backstage/plugin-techdocs-react@1.3.10-next.1
|
|
43
|
+
|
|
3
44
|
## 1.36.2-next.0
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
|
@@ -5,7 +5,7 @@ import { useNavigate } from 'react-router-dom';
|
|
|
5
5
|
import useAsync from 'react-use/esm/useAsync';
|
|
6
6
|
import { makeStyles } from '@material-ui/core/styles';
|
|
7
7
|
import { useApi, alertApiRef, useRouteRef } from '@backstage/core-plugin-api';
|
|
8
|
-
import { catalogApiRef,
|
|
8
|
+
import { catalogApiRef, entityPresentationApiRef } from '@backstage/plugin-catalog-react';
|
|
9
9
|
import { editRouteRef } from '../../../routes.esm.js';
|
|
10
10
|
import { TemplateEditorLayout, TemplateEditorLayoutToolbar, TemplateEditorPanels, TemplateEditorLayoutPreview, TemplateEditorLayoutFiles } from './TemplateEditorLayout.esm.js';
|
|
11
11
|
import { TemplateEditorToolbar } from './TemplateEditorToolbar.esm.js';
|
|
@@ -87,6 +87,7 @@ const TemplateFormPreviewer = ({
|
|
|
87
87
|
const classes = useStyles();
|
|
88
88
|
const alertApi = useApi(alertApiRef);
|
|
89
89
|
const catalogApi = useApi(catalogApiRef);
|
|
90
|
+
const entityPresentationApi = useApi(entityPresentationApiRef);
|
|
90
91
|
const navigate = useNavigate();
|
|
91
92
|
const editLink = useRouteRef(editRouteRef);
|
|
92
93
|
const [errorText, setErrorText] = useState();
|
|
@@ -108,20 +109,23 @@ const TemplateFormPreviewer = ({
|
|
|
108
109
|
"spec.steps",
|
|
109
110
|
"spec.output"
|
|
110
111
|
]
|
|
111
|
-
}).then(
|
|
112
|
-
|
|
113
|
-
items.map((template) => ({
|
|
114
|
-
label:
|
|
112
|
+
}).then(async ({ items }) => {
|
|
113
|
+
const options = await Promise.all(
|
|
114
|
+
items.map(async (template) => ({
|
|
115
|
+
label: (await entityPresentationApi.forEntity(template, {
|
|
116
|
+
defaultKind: "template"
|
|
117
|
+
}).promise).primaryTitle,
|
|
115
118
|
value: template
|
|
116
119
|
}))
|
|
117
|
-
)
|
|
118
|
-
|
|
120
|
+
);
|
|
121
|
+
setTemplateOptions(options);
|
|
122
|
+
}).catch(
|
|
119
123
|
(e) => alertApi.post({
|
|
120
124
|
message: `Error loading existing templates: ${e.message}`,
|
|
121
125
|
severity: "error"
|
|
122
126
|
})
|
|
123
127
|
),
|
|
124
|
-
[catalogApi]
|
|
128
|
+
[catalogApi, entityPresentationApi, alertApi]
|
|
125
129
|
);
|
|
126
130
|
const handleSelectChange = useCallback(
|
|
127
131
|
// TODO(Rugvip): Afaik this should be Entity, but didn't want to make runtime changes while fixing types
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateFormPreviewer.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.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 yaml from 'yaml';\nimport { useCallback, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\n\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n humanizeEntityRef,\n} from '@backstage/plugin-catalog-react';\nimport {\n LayoutOptions,\n FieldExtensionOptions,\n FormProps,\n} from '@backstage/plugin-scaffolder-react';\n\nimport { editRouteRef } from '../../../routes';\n\nimport {\n TemplateEditorLayout,\n TemplateEditorLayoutToolbar,\n TemplateEditorLayoutFiles,\n TemplateEditorLayoutPreview,\n TemplateEditorPanels,\n} from './TemplateEditorLayout';\nimport { TemplateEditorToolbar } from './TemplateEditorToolbar';\nimport { TemplateEditorToolbarFileMenu } from './TemplateEditorToolbarFileMenu';\nimport {\n TemplateOption,\n TemplateEditorToolbarTemplatesMenu,\n} from './TemplateEditorToolbarTemplatesMenu';\nimport { TemplateEditorForm } from './TemplateEditorForm';\nimport { TemplateEditorTextArea } from './TemplateEditorTextArea';\n\nconst EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI\nparameters:\n - title: Fill in some steps\n required:\n - name\n properties:\n name:\n title: Name\n type: string\n description: Unique name of the component\n owner:\n title: Owner\n type: string\n description: Owner of the component\n ui:field: OwnerPicker\n ui:options:\n catalogFilter:\n kind: Group\n - title: Choose a location\n required:\n - repoUrl\n properties:\n repoUrl:\n title: Repository Location\n type: string\n ui:field: RepoUrlPicker\n ui:options:\n allowedHosts:\n - github.com\nsteps:\n - id: fetch-base\n name: Fetch Base\n action: fetch:template\n input:\n url: ./template\n values:\n name: \\${{parameters.name}}\n`;\n\n/** @public */\nexport type ScaffolderTemplateFormPreviewerClassKey =\n | 'root'\n | 'toolbar'\n | 'controls'\n | 'textArea'\n | 'preview';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n height: '100%',\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateAreas: `\n \"toolbar\"\n \"textArea\"\n \"preview\"\n `,\n [theme.breakpoints.up('md')]: {\n gridTemplateAreas: `\n \"toolbar toolbar\"\n \"textArea preview\"\n `,\n gridTemplateRows: 'auto 1fr',\n gridTemplateColumns: '1fr',\n },\n },\n files: {\n gridArea: 'textArea',\n },\n }),\n { name: 'ScaffolderTemplateFormPreviewer' },\n);\n\nexport const TemplateFormPreviewer = ({\n defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML,\n customFieldExtensions = [],\n layouts = [],\n formProps,\n}: {\n defaultPreviewTemplate?: string;\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n onClose?: () => void;\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n}) => {\n const classes = useStyles();\n const alertApi = useApi(alertApiRef);\n const catalogApi = useApi(catalogApiRef);\n const navigate = useNavigate();\n const editLink = useRouteRef(editRouteRef);\n\n const [errorText, setErrorText] = useState<string>();\n const [selectedTemplate, setSelectedTemplate] = useState<TemplateOption>();\n const [templateOptions, setTemplateOptions] = useState<TemplateOption[]>([]);\n const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate);\n\n const handleCloseDirectory = useCallback(() => {\n navigate(editLink());\n }, [navigate, editLink]);\n\n useAsync(\n () =>\n catalogApi\n .getEntities({\n filter: { kind: 'template' },\n fields: [\n 'kind',\n 'metadata.namespace',\n 'metadata.name',\n 'metadata.title',\n 'spec.parameters',\n 'spec.steps',\n 'spec.output',\n ],\n })\n .then(({ items }) =>\n setTemplateOptions(\n items.map(template => ({\n label:\n template.metadata.title ??\n humanizeEntityRef(template, { defaultKind: 'template' }),\n value: template,\n })),\n ),\n )\n .catch(e =>\n alertApi.post({\n message: `Error loading existing templates: ${e.message}`,\n severity: 'error',\n }),\n ),\n [catalogApi],\n );\n\n const handleSelectChange = useCallback(\n // TODO(Rugvip): Afaik this should be Entity, but didn't want to make runtime changes while fixing types\n (selected: TemplateOption) => {\n setSelectedTemplate(selected);\n setTemplateYaml(yaml.stringify(selected.value.spec));\n },\n [setSelectedTemplate, setTemplateYaml],\n );\n\n return (\n <TemplateEditorLayout classes={{ root: classes.root }}>\n <TemplateEditorLayoutToolbar>\n <TemplateEditorToolbar fieldExtensions={customFieldExtensions}>\n <TemplateEditorToolbarFileMenu\n onCloseDirectory={handleCloseDirectory}\n />\n <TemplateEditorToolbarTemplatesMenu\n options={templateOptions}\n selectedOption={selectedTemplate}\n onSelectOption={handleSelectChange}\n />\n </TemplateEditorToolbar>\n </TemplateEditorLayoutToolbar>\n <TemplateEditorPanels\n autoSaveId=\"template-form-previewer\"\n files={\n <TemplateEditorLayoutFiles classes={{ root: classes.files }}>\n <TemplateEditorTextArea\n content={templateYaml}\n onUpdate={setTemplateYaml}\n errorText={errorText}\n />\n </TemplateEditorLayoutFiles>\n }\n preview={\n <TemplateEditorLayoutPreview>\n <TemplateEditorForm\n content={templateYaml}\n contentIsSpec\n fieldExtensions={customFieldExtensions}\n setErrorText={setErrorText}\n layouts={layouts}\n formProps={formProps}\n />\n </TemplateEditorLayoutPreview>\n }\n />\n </TemplateEditorLayout>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TemplateFormPreviewer.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.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 yaml from 'yaml';\nimport { useCallback, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\n\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n entityPresentationApiRef,\n} from '@backstage/plugin-catalog-react';\nimport {\n LayoutOptions,\n FieldExtensionOptions,\n FormProps,\n} from '@backstage/plugin-scaffolder-react';\n\nimport { editRouteRef } from '../../../routes';\n\nimport {\n TemplateEditorLayout,\n TemplateEditorLayoutToolbar,\n TemplateEditorLayoutFiles,\n TemplateEditorLayoutPreview,\n TemplateEditorPanels,\n} from './TemplateEditorLayout';\nimport { TemplateEditorToolbar } from './TemplateEditorToolbar';\nimport { TemplateEditorToolbarFileMenu } from './TemplateEditorToolbarFileMenu';\nimport {\n TemplateOption,\n TemplateEditorToolbarTemplatesMenu,\n} from './TemplateEditorToolbarTemplatesMenu';\nimport { TemplateEditorForm } from './TemplateEditorForm';\nimport { TemplateEditorTextArea } from './TemplateEditorTextArea';\n\nconst EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI\nparameters:\n - title: Fill in some steps\n required:\n - name\n properties:\n name:\n title: Name\n type: string\n description: Unique name of the component\n owner:\n title: Owner\n type: string\n description: Owner of the component\n ui:field: OwnerPicker\n ui:options:\n catalogFilter:\n kind: Group\n - title: Choose a location\n required:\n - repoUrl\n properties:\n repoUrl:\n title: Repository Location\n type: string\n ui:field: RepoUrlPicker\n ui:options:\n allowedHosts:\n - github.com\nsteps:\n - id: fetch-base\n name: Fetch Base\n action: fetch:template\n input:\n url: ./template\n values:\n name: \\${{parameters.name}}\n`;\n\n/** @public */\nexport type ScaffolderTemplateFormPreviewerClassKey =\n | 'root'\n | 'toolbar'\n | 'controls'\n | 'textArea'\n | 'preview';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n height: '100%',\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateAreas: `\n \"toolbar\"\n \"textArea\"\n \"preview\"\n `,\n [theme.breakpoints.up('md')]: {\n gridTemplateAreas: `\n \"toolbar toolbar\"\n \"textArea preview\"\n `,\n gridTemplateRows: 'auto 1fr',\n gridTemplateColumns: '1fr',\n },\n },\n files: {\n gridArea: 'textArea',\n },\n }),\n { name: 'ScaffolderTemplateFormPreviewer' },\n);\n\nexport const TemplateFormPreviewer = ({\n defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML,\n customFieldExtensions = [],\n layouts = [],\n formProps,\n}: {\n defaultPreviewTemplate?: string;\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n onClose?: () => void;\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n}) => {\n const classes = useStyles();\n const alertApi = useApi(alertApiRef);\n const catalogApi = useApi(catalogApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n const navigate = useNavigate();\n const editLink = useRouteRef(editRouteRef);\n\n const [errorText, setErrorText] = useState<string>();\n const [selectedTemplate, setSelectedTemplate] = useState<TemplateOption>();\n const [templateOptions, setTemplateOptions] = useState<TemplateOption[]>([]);\n const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate);\n\n const handleCloseDirectory = useCallback(() => {\n navigate(editLink());\n }, [navigate, editLink]);\n\n useAsync(\n () =>\n catalogApi\n .getEntities({\n filter: { kind: 'template' },\n fields: [\n 'kind',\n 'metadata.namespace',\n 'metadata.name',\n 'metadata.title',\n 'spec.parameters',\n 'spec.steps',\n 'spec.output',\n ],\n })\n .then(async ({ items }) => {\n const options = await Promise.all(\n items.map(async template => ({\n label: (\n await entityPresentationApi.forEntity(template, {\n defaultKind: 'template',\n }).promise\n ).primaryTitle,\n value: template,\n })),\n );\n setTemplateOptions(options);\n })\n .catch(e =>\n alertApi.post({\n message: `Error loading existing templates: ${e.message}`,\n severity: 'error',\n }),\n ),\n [catalogApi, entityPresentationApi, alertApi],\n );\n\n const handleSelectChange = useCallback(\n // TODO(Rugvip): Afaik this should be Entity, but didn't want to make runtime changes while fixing types\n (selected: TemplateOption) => {\n setSelectedTemplate(selected);\n setTemplateYaml(yaml.stringify(selected.value.spec));\n },\n [setSelectedTemplate, setTemplateYaml],\n );\n\n return (\n <TemplateEditorLayout classes={{ root: classes.root }}>\n <TemplateEditorLayoutToolbar>\n <TemplateEditorToolbar fieldExtensions={customFieldExtensions}>\n <TemplateEditorToolbarFileMenu\n onCloseDirectory={handleCloseDirectory}\n />\n <TemplateEditorToolbarTemplatesMenu\n options={templateOptions}\n selectedOption={selectedTemplate}\n onSelectOption={handleSelectChange}\n />\n </TemplateEditorToolbar>\n </TemplateEditorLayoutToolbar>\n <TemplateEditorPanels\n autoSaveId=\"template-form-previewer\"\n files={\n <TemplateEditorLayoutFiles classes={{ root: classes.files }}>\n <TemplateEditorTextArea\n content={templateYaml}\n onUpdate={setTemplateYaml}\n errorText={errorText}\n />\n </TemplateEditorLayoutFiles>\n }\n preview={\n <TemplateEditorLayoutPreview>\n <TemplateEditorForm\n content={templateYaml}\n contentIsSpec\n fieldExtensions={customFieldExtensions}\n setErrorText={setErrorText}\n layouts={layouts}\n formProps={formProps}\n />\n </TemplateEditorLayoutPreview>\n }\n />\n </TemplateEditorLayout>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@ import { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../../extensions/default.es
|
|
|
16
16
|
import { buildTechDocsURL } from '@backstage/plugin-techdocs-react';
|
|
17
17
|
import { TECHDOCS_ANNOTATION, TECHDOCS_EXTERNAL_ANNOTATION } from '@backstage/plugin-techdocs-common';
|
|
18
18
|
import { OpaqueFormField } from '../../packages/scaffolder-internal/src/wiring/InternalFormField.esm.js';
|
|
19
|
+
import '../../packages/scaffolder-internal/src/wiring/InternalFormDecorator.esm.js';
|
|
19
20
|
|
|
20
21
|
function TemplateListContent() {
|
|
21
22
|
const registerComponentLink = useRouteRef(registerComponentRouteRef);
|
|
@@ -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 } from 'react';\nimport { Routes, Route, useNavigate } 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 {\n FieldExtensionOptions,\n SecretsContextProvider,\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 {\n TECHDOCS_ANNOTATION,\n TECHDOCS_EXTERNAL_ANNOTATION,\n} from '@backstage/plugin-techdocs-common';\n\nfunction TemplateListContent() {\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 = [\n {\n title: t('templateListPage.templateGroups.defaultTitle'),\n filter: () => true,\n },\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\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: { formFields?: Array<FormField> }) {\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 />} />\n <Route\n path=\":namespace/:templateName\"\n element={\n <SecretsContextProvider>\n <TemplateWizardPageContent\n customFieldExtensions={fieldExtensions}\n layouts={customLayouts}\n />\n </SecretsContextProvider>\n }\n />\n </Routes>\n );\n}\n"],"names":[],"mappings":"
|
|
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 } from 'react';\nimport { Routes, Route, useNavigate } 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 {\n FieldExtensionOptions,\n SecretsContextProvider,\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 {\n TECHDOCS_ANNOTATION,\n TECHDOCS_EXTERNAL_ANNOTATION,\n} from '@backstage/plugin-techdocs-common';\n\nfunction TemplateListContent() {\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 = [\n {\n title: t('templateListPage.templateGroups.defaultTitle'),\n filter: () => true,\n },\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\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: { formFields?: Array<FormField> }) {\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 />} />\n <Route\n path=\":namespace/:templateName\"\n element={\n <SecretsContextProvider>\n <TemplateWizardPageContent\n customFieldExtensions={fieldExtensions}\n layouts={customLayouts}\n />\n </SecretsContextProvider>\n }\n />\n </Routes>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApiBlueprint,
|
|
1
|
+
import { ApiBlueprint, appTreeApiRef, createExtensionInput } from '@backstage/frontend-plugin-api';
|
|
2
2
|
import { FormFieldBlueprint, formFieldsApiRef } from '@backstage/plugin-scaffolder-react/alpha';
|
|
3
3
|
export { formFieldsApiRef } from '@backstage/plugin-scaffolder-react/alpha';
|
|
4
4
|
import { OpaqueFormField } from '../packages/scaffolder-internal/src/wiring/InternalFormField.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { MarkdownContent } from '@backstage/core-components';
|
|
3
3
|
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
4
4
|
import Box from '@material-ui/core/Box';
|
|
@@ -17,6 +17,7 @@ import { templateManagementPermission } from '@backstage/plugin-scaffolder-commo
|
|
|
17
17
|
import { useApp } from '@backstage/core-plugin-api';
|
|
18
18
|
import { TemplatingExtensionsPage } from '../TemplatingExtensionsPage/TemplatingExtensionsPage.esm.js';
|
|
19
19
|
import { OpaqueFormField } from '../../packages/scaffolder-internal/src/wiring/InternalFormField.esm.js';
|
|
20
|
+
import '../../packages/scaffolder-internal/src/wiring/InternalFormDecorator.esm.js';
|
|
20
21
|
|
|
21
22
|
const InternalRouter = (props) => {
|
|
22
23
|
const {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Router.esm.js","sources":["../../../src/components/Router/Router.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 { ComponentType, PropsWithChildren } from 'react';\nimport { Routes, Route, useOutlet } from 'react-router-dom';\n\nimport {\n FieldExtensionOptions,\n FormProps,\n ReviewStepProps,\n TemplateGroupFilter,\n} from '@backstage/plugin-scaffolder-react';\nimport {\n ScaffolderTaskOutput,\n SecretsContextProvider,\n useCustomFieldExtensions,\n useCustomLayouts,\n} from '@backstage/plugin-scaffolder-react';\n\nimport { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../../extensions/default';\n\nimport {\n actionsRouteRef,\n editorRouteRef,\n customFieldsRouteRef,\n editRouteRef,\n scaffolderListTaskRouteRef,\n scaffolderTaskRouteRef,\n selectedTemplateRouteRef,\n templateFormRouteRef,\n templatingExtensionsRouteRef,\n} from '../../routes';\n\nimport { ActionsPage } from '../../components/ActionsPage';\nimport { ListTasksPage } from '../../components/ListTasksPage';\n\nimport {\n TemplateListPageProps,\n TemplateWizardPageProps,\n} from '@backstage/plugin-scaffolder/alpha';\nimport { TemplateListPage, TemplateWizardPage } from '../../alpha/components';\nimport { OngoingTask } from '../OngoingTask';\nimport {\n TemplateFormPage,\n TemplateIntroPage,\n TemplateEditorPage,\n CustomFieldsPage,\n} from '../../alpha/components/TemplateEditorPage';\nimport { RequirePermission } from '@backstage/plugin-permission-react';\nimport { templateManagementPermission } from '@backstage/plugin-scaffolder-common/alpha';\nimport { useApp } from '@backstage/core-plugin-api';\nimport { OpaqueFormField } from '@internal/scaffolder';\nimport { TemplatingExtensionsPage } from '../TemplatingExtensionsPage';\nimport { FormField } from '@backstage/plugin-scaffolder-react/alpha';\n\n/**\n * The Props for the Scaffolder Router\n *\n * @public\n */\nexport type RouterProps = {\n components?: {\n ReviewStepComponent?: ComponentType<ReviewStepProps>;\n TemplateCardComponent?: ComponentType<{\n template: TemplateEntityV1beta3;\n }>;\n TaskPageComponent?: ComponentType<PropsWithChildren<{}>>;\n EXPERIMENTAL_TemplateOutputsComponent?: ComponentType<{\n output?: ScaffolderTaskOutput;\n }>;\n EXPERIMENTAL_TemplateListPageComponent?: ComponentType<TemplateListPageProps>;\n EXPERIMENTAL_TemplateWizardPageComponent?: ComponentType<TemplateWizardPageProps>;\n };\n groups?: TemplateGroupFilter[];\n templateFilter?: (entity: TemplateEntityV1beta3) => boolean;\n headerOptions?: {\n pageTitleOverride?: string;\n title?: string;\n subtitle?: string;\n };\n defaultPreviewTemplate?: string;\n formProps?: FormProps;\n contextMenu?: {\n /** Whether to show a link to the template editor */\n editor?: boolean;\n /** Whether to show a link to the actions documentation */\n actions?: boolean;\n /** Whether to show a link to the tasks page */\n tasks?: boolean;\n /** Whether to show a link to the create page (on /create subroutes) */\n create?: boolean;\n /** Whether to show a link to the templating extensions page */\n templatingExtensions?: boolean;\n };\n};\n\n/**\n * Internal router with additional props that aren't available in the public API\n * for the old frontend system.\n *\n * @internal\n */\nexport const InternalRouter = (\n props: PropsWithChildren<\n RouterProps & {\n formFields?: Array<FormField>;\n }\n >,\n) => {\n const {\n components: {\n TemplateCardComponent,\n TaskPageComponent = OngoingTask,\n ReviewStepComponent,\n EXPERIMENTAL_TemplateOutputsComponent: TemplateOutputsComponent,\n EXPERIMENTAL_TemplateListPageComponent:\n TemplateListPageComponent = TemplateListPage,\n EXPERIMENTAL_TemplateWizardPageComponent:\n TemplateWizardPageComponent = TemplateWizardPage,\n } = {},\n } = props;\n const outlet = useOutlet() || props.children;\n const customFieldExtensions = useCustomFieldExtensions(outlet);\n\n const app = useApp();\n const { NotFoundErrorPage } = app.getComponents();\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 => customFieldExtension.name === name,\n ),\n ),\n ] as FieldExtensionOptions[];\n\n const customLayouts = useCustomLayouts(outlet);\n\n return (\n <Routes>\n <Route\n path=\"/\"\n element={\n <TemplateListPageComponent\n TemplateCardComponent={TemplateCardComponent}\n contextMenu={props.contextMenu}\n groups={props.groups}\n templateFilter={props.templateFilter}\n headerOptions={props.headerOptions}\n />\n }\n />\n <Route\n path={selectedTemplateRouteRef.path}\n element={\n <SecretsContextProvider>\n <TemplateWizardPageComponent\n headerOptions={props.headerOptions}\n customFieldExtensions={fieldExtensions}\n layouts={customLayouts}\n components={{ ReviewStepComponent }}\n formProps={props.formProps}\n />\n </SecretsContextProvider>\n }\n />\n <Route\n path={scaffolderTaskRouteRef.path}\n element={\n <TaskPageComponent\n TemplateOutputsComponent={TemplateOutputsComponent}\n />\n }\n />\n <Route\n path={editRouteRef.path}\n element={\n <RequirePermission permission={templateManagementPermission}>\n <SecretsContextProvider>\n <TemplateIntroPage />\n </SecretsContextProvider>\n </RequirePermission>\n }\n />\n <Route\n path={customFieldsRouteRef.path}\n element={\n <RequirePermission permission={templateManagementPermission}>\n <SecretsContextProvider>\n <CustomFieldsPage fieldExtensions={fieldExtensions} />\n </SecretsContextProvider>\n </RequirePermission>\n }\n />\n <Route\n path={templateFormRouteRef.path}\n element={\n <RequirePermission permission={templateManagementPermission}>\n <SecretsContextProvider>\n <TemplateFormPage\n layouts={customLayouts}\n formProps={props.formProps}\n fieldExtensions={fieldExtensions}\n />\n </SecretsContextProvider>\n </RequirePermission>\n }\n />\n\n <Route\n path={actionsRouteRef.path}\n element={<ActionsPage contextMenu={props.contextMenu} />}\n />\n <Route\n path={scaffolderListTaskRouteRef.path}\n element={<ListTasksPage contextMenu={props.contextMenu} />}\n />\n <Route\n path={editorRouteRef.path}\n element={\n <RequirePermission permission={templateManagementPermission}>\n <SecretsContextProvider>\n <TemplateEditorPage\n layouts={customLayouts}\n formProps={props.formProps}\n fieldExtensions={fieldExtensions}\n />\n </SecretsContextProvider>\n </RequirePermission>\n }\n />\n <Route\n path={templatingExtensionsRouteRef.path}\n element={<TemplatingExtensionsPage contextMenu={props.contextMenu} />}\n />\n <Route path=\"*\" element={<NotFoundErrorPage />} />\n </Routes>\n );\n};\n\n/**\n * The Scaffolder Router\n *\n * @public\n */\nexport const Router = (props: PropsWithChildren<RouterProps>) => {\n return <InternalRouter {...props} />;\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Router.esm.js","sources":["../../../src/components/Router/Router.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 { ComponentType, PropsWithChildren } from 'react';\nimport { Routes, Route, useOutlet } from 'react-router-dom';\n\nimport {\n FieldExtensionOptions,\n FormProps,\n ReviewStepProps,\n TemplateGroupFilter,\n} from '@backstage/plugin-scaffolder-react';\nimport {\n ScaffolderTaskOutput,\n SecretsContextProvider,\n useCustomFieldExtensions,\n useCustomLayouts,\n} from '@backstage/plugin-scaffolder-react';\n\nimport { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../../extensions/default';\n\nimport {\n actionsRouteRef,\n editorRouteRef,\n customFieldsRouteRef,\n editRouteRef,\n scaffolderListTaskRouteRef,\n scaffolderTaskRouteRef,\n selectedTemplateRouteRef,\n templateFormRouteRef,\n templatingExtensionsRouteRef,\n} from '../../routes';\n\nimport { ActionsPage } from '../../components/ActionsPage';\nimport { ListTasksPage } from '../../components/ListTasksPage';\n\nimport {\n TemplateListPageProps,\n TemplateWizardPageProps,\n} from '@backstage/plugin-scaffolder/alpha';\nimport { TemplateListPage, TemplateWizardPage } from '../../alpha/components';\nimport { OngoingTask } from '../OngoingTask';\nimport {\n TemplateFormPage,\n TemplateIntroPage,\n TemplateEditorPage,\n CustomFieldsPage,\n} from '../../alpha/components/TemplateEditorPage';\nimport { RequirePermission } from '@backstage/plugin-permission-react';\nimport { templateManagementPermission } from '@backstage/plugin-scaffolder-common/alpha';\nimport { useApp } from '@backstage/core-plugin-api';\nimport { OpaqueFormField } from '@internal/scaffolder';\nimport { TemplatingExtensionsPage } from '../TemplatingExtensionsPage';\nimport { FormField } from '@backstage/plugin-scaffolder-react/alpha';\n\n/**\n * The Props for the Scaffolder Router\n *\n * @public\n */\nexport type RouterProps = {\n components?: {\n ReviewStepComponent?: ComponentType<ReviewStepProps>;\n TemplateCardComponent?: ComponentType<{\n template: TemplateEntityV1beta3;\n }>;\n TaskPageComponent?: ComponentType<PropsWithChildren<{}>>;\n EXPERIMENTAL_TemplateOutputsComponent?: ComponentType<{\n output?: ScaffolderTaskOutput;\n }>;\n EXPERIMENTAL_TemplateListPageComponent?: ComponentType<TemplateListPageProps>;\n EXPERIMENTAL_TemplateWizardPageComponent?: ComponentType<TemplateWizardPageProps>;\n };\n groups?: TemplateGroupFilter[];\n templateFilter?: (entity: TemplateEntityV1beta3) => boolean;\n headerOptions?: {\n pageTitleOverride?: string;\n title?: string;\n subtitle?: string;\n };\n defaultPreviewTemplate?: string;\n formProps?: FormProps;\n contextMenu?: {\n /** Whether to show a link to the template editor */\n editor?: boolean;\n /** Whether to show a link to the actions documentation */\n actions?: boolean;\n /** Whether to show a link to the tasks page */\n tasks?: boolean;\n /** Whether to show a link to the create page (on /create subroutes) */\n create?: boolean;\n /** Whether to show a link to the templating extensions page */\n templatingExtensions?: boolean;\n };\n};\n\n/**\n * Internal router with additional props that aren't available in the public API\n * for the old frontend system.\n *\n * @internal\n */\nexport const InternalRouter = (\n props: PropsWithChildren<\n RouterProps & {\n formFields?: Array<FormField>;\n }\n >,\n) => {\n const {\n components: {\n TemplateCardComponent,\n TaskPageComponent = OngoingTask,\n ReviewStepComponent,\n EXPERIMENTAL_TemplateOutputsComponent: TemplateOutputsComponent,\n EXPERIMENTAL_TemplateListPageComponent:\n TemplateListPageComponent = TemplateListPage,\n EXPERIMENTAL_TemplateWizardPageComponent:\n TemplateWizardPageComponent = TemplateWizardPage,\n } = {},\n } = props;\n const outlet = useOutlet() || props.children;\n const customFieldExtensions = useCustomFieldExtensions(outlet);\n\n const app = useApp();\n const { NotFoundErrorPage } = app.getComponents();\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 => customFieldExtension.name === name,\n ),\n ),\n ] as FieldExtensionOptions[];\n\n const customLayouts = useCustomLayouts(outlet);\n\n return (\n <Routes>\n <Route\n path=\"/\"\n element={\n <TemplateListPageComponent\n TemplateCardComponent={TemplateCardComponent}\n contextMenu={props.contextMenu}\n groups={props.groups}\n templateFilter={props.templateFilter}\n headerOptions={props.headerOptions}\n />\n }\n />\n <Route\n path={selectedTemplateRouteRef.path}\n element={\n <SecretsContextProvider>\n <TemplateWizardPageComponent\n headerOptions={props.headerOptions}\n customFieldExtensions={fieldExtensions}\n layouts={customLayouts}\n components={{ ReviewStepComponent }}\n formProps={props.formProps}\n />\n </SecretsContextProvider>\n }\n />\n <Route\n path={scaffolderTaskRouteRef.path}\n element={\n <TaskPageComponent\n TemplateOutputsComponent={TemplateOutputsComponent}\n />\n }\n />\n <Route\n path={editRouteRef.path}\n element={\n <RequirePermission permission={templateManagementPermission}>\n <SecretsContextProvider>\n <TemplateIntroPage />\n </SecretsContextProvider>\n </RequirePermission>\n }\n />\n <Route\n path={customFieldsRouteRef.path}\n element={\n <RequirePermission permission={templateManagementPermission}>\n <SecretsContextProvider>\n <CustomFieldsPage fieldExtensions={fieldExtensions} />\n </SecretsContextProvider>\n </RequirePermission>\n }\n />\n <Route\n path={templateFormRouteRef.path}\n element={\n <RequirePermission permission={templateManagementPermission}>\n <SecretsContextProvider>\n <TemplateFormPage\n layouts={customLayouts}\n formProps={props.formProps}\n fieldExtensions={fieldExtensions}\n />\n </SecretsContextProvider>\n </RequirePermission>\n }\n />\n\n <Route\n path={actionsRouteRef.path}\n element={<ActionsPage contextMenu={props.contextMenu} />}\n />\n <Route\n path={scaffolderListTaskRouteRef.path}\n element={<ListTasksPage contextMenu={props.contextMenu} />}\n />\n <Route\n path={editorRouteRef.path}\n element={\n <RequirePermission permission={templateManagementPermission}>\n <SecretsContextProvider>\n <TemplateEditorPage\n layouts={customLayouts}\n formProps={props.formProps}\n fieldExtensions={fieldExtensions}\n />\n </SecretsContextProvider>\n </RequirePermission>\n }\n />\n <Route\n path={templatingExtensionsRouteRef.path}\n element={<TemplatingExtensionsPage contextMenu={props.contextMenu} />}\n />\n <Route path=\"*\" element={<NotFoundErrorPage />} />\n </Routes>\n );\n};\n\n/**\n * The Scaffolder Router\n *\n * @public\n */\nexport const Router = (props: PropsWithChildren<RouterProps>) => {\n return <InternalRouter {...props} />;\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAmHO,MAAM,cAAA,GAAiB,CAC5B,KAAA,KAKG;AACH,EAAA,MAAM;AAAA,IACJ,UAAA,EAAY;AAAA,MACV,qBAAA;AAAA,MACA,iBAAA,GAAoB,WAAA;AAAA,MACpB,mBAAA;AAAA,MACA,qCAAA,EAAuC,wBAAA;AAAA,MACvC,wCACE,yBAAA,GAA4B,gBAAA;AAAA,MAC9B,0CACE,2BAAA,GAA8B;AAAA,QAC9B;AAAC,GACP,GAAI,KAAA;AACJ,EAAA,MAAM,MAAA,GAAS,SAAA,EAAU,IAAK,KAAA,CAAM,QAAA;AACpC,EAAA,MAAM,qBAAA,GAAwB,yBAAyB,MAAM,CAAA;AAE7D,EAAA,MAAM,MAAM,MAAA,EAAO;AACnB,EAAA,MAAM,EAAE,iBAAA,EAAkB,GAAI,GAAA,CAAI,aAAA,EAAc;AAEhD,EAAA,MAAM,eAAA,GAAkB;AAAA,IACtB,GAAG,qBAAA;AAAA,IACH,GAAI,KAAA,CAAM,UAAA,EAAY,IAAI,eAAA,CAAgB,UAAU,KAAK,EAAC;AAAA,IAC1D,GAAG,mCAAA,CAAoC,MAAA;AAAA,MACrC,CAAC,EAAE,IAAA,EAAK,KACN,CAAC,qBAAA,CAAsB,IAAA;AAAA,QACrB,CAAA,oBAAA,KAAwB,qBAAqB,IAAA,KAAS;AAAA;AACxD;AACJ,GACF;AAEA,EAAA,MAAM,aAAA,GAAgB,iBAAiB,MAAM,CAAA;AAE7C,EAAA,4BACG,MAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,GAAA;AAAA,QACL,OAAA,kBACE,GAAA;AAAA,UAAC,yBAAA;AAAA,UAAA;AAAA,YACC,qBAAA;AAAA,YACA,aAAa,KAAA,CAAM,WAAA;AAAA,YACnB,QAAQ,KAAA,CAAM,MAAA;AAAA,YACd,gBAAgB,KAAA,CAAM,cAAA;AAAA,YACtB,eAAe,KAAA,CAAM;AAAA;AAAA;AACvB;AAAA,KAEJ;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAM,wBAAA,CAAyB,IAAA;AAAA,QAC/B,OAAA,sBACG,sBAAA,EAAA,EACC,QAAA,kBAAA,GAAA;AAAA,UAAC,2BAAA;AAAA,UAAA;AAAA,YACC,eAAe,KAAA,CAAM,aAAA;AAAA,YACrB,qBAAA,EAAuB,eAAA;AAAA,YACvB,OAAA,EAAS,aAAA;AAAA,YACT,UAAA,EAAY,EAAE,mBAAA,EAAoB;AAAA,YAClC,WAAW,KAAA,CAAM;AAAA;AAAA,SACnB,EACF;AAAA;AAAA,KAEJ;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAM,sBAAA,CAAuB,IAAA;AAAA,QAC7B,OAAA,kBACE,GAAA;AAAA,UAAC,iBAAA;AAAA,UAAA;AAAA,YACC;AAAA;AAAA;AACF;AAAA,KAEJ;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAM,YAAA,CAAa,IAAA;AAAA,QACnB,OAAA,kBACE,GAAA,CAAC,iBAAA,EAAA,EAAkB,UAAA,EAAY,4BAAA,EAC7B,8BAAC,sBAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,iBAAA,EAAA,EAAkB,CAAA,EACrB,CAAA,EACF;AAAA;AAAA,KAEJ;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAM,oBAAA,CAAqB,IAAA;AAAA,QAC3B,OAAA,kBACE,GAAA,CAAC,iBAAA,EAAA,EAAkB,UAAA,EAAY,4BAAA,EAC7B,QAAA,kBAAA,GAAA,CAAC,sBAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,eAAA,EAAkC,CAAA,EACtD,CAAA,EACF;AAAA;AAAA,KAEJ;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAM,oBAAA,CAAqB,IAAA;AAAA,QAC3B,yBACE,GAAA,CAAC,iBAAA,EAAA,EAAkB,UAAA,EAAY,4BAAA,EAC7B,8BAAC,sBAAA,EAAA,EACC,QAAA,kBAAA,GAAA;AAAA,UAAC,gBAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,aAAA;AAAA,YACT,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB;AAAA;AAAA,WAEJ,CAAA,EACF;AAAA;AAAA,KAEJ;AAAA,oBAEA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAM,eAAA,CAAgB,IAAA;AAAA,QACtB,OAAA,kBAAS,GAAA,CAAC,WAAA,EAAA,EAAY,WAAA,EAAa,MAAM,WAAA,EAAa;AAAA;AAAA,KACxD;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAM,0BAAA,CAA2B,IAAA;AAAA,QACjC,OAAA,kBAAS,GAAA,CAAC,aAAA,EAAA,EAAc,WAAA,EAAa,MAAM,WAAA,EAAa;AAAA;AAAA,KAC1D;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAM,cAAA,CAAe,IAAA;AAAA,QACrB,yBACE,GAAA,CAAC,iBAAA,EAAA,EAAkB,UAAA,EAAY,4BAAA,EAC7B,8BAAC,sBAAA,EAAA,EACC,QAAA,kBAAA,GAAA;AAAA,UAAC,kBAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,aAAA;AAAA,YACT,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB;AAAA;AAAA,WAEJ,CAAA,EACF;AAAA;AAAA,KAEJ;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,MAAM,4BAAA,CAA6B,IAAA;AAAA,QACnC,OAAA,kBAAS,GAAA,CAAC,wBAAA,EAAA,EAAyB,WAAA,EAAa,MAAM,WAAA,EAAa;AAAA;AAAA,KACrE;AAAA,wBACC,KAAA,EAAA,EAAM,IAAA,EAAK,KAAI,OAAA,kBAAS,GAAA,CAAC,qBAAkB,CAAA,EAAI;AAAA,GAAA,EAClD,CAAA;AAEJ;AAOO,MAAM,MAAA,GAAS,CAAC,KAAA,KAA0C;AAC/D,EAAA,uBAAO,GAAA,CAAC,cAAA,EAAA,EAAgB,GAAG,KAAA,EAAO,CAAA;AACpC;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -74,14 +74,14 @@ const GitlabRepoPicker = (props) => {
|
|
|
74
74
|
});
|
|
75
75
|
}, [scaffolderApi, accessToken, host, owner, onChange, availableGroups]);
|
|
76
76
|
useDebounce(updateAvailableRepositories, 500, [updateAvailableRepositories]);
|
|
77
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */
|
|
77
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
|
|
78
78
|
FormControl,
|
|
79
79
|
{
|
|
80
80
|
margin: "normal",
|
|
81
81
|
required: true,
|
|
82
82
|
error: rawErrors?.length > 0 && !owner,
|
|
83
|
-
children:
|
|
84
|
-
/* @__PURE__ */ jsx(
|
|
83
|
+
children: [
|
|
84
|
+
allowedOwners?.length ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
85
85
|
Select,
|
|
86
86
|
{
|
|
87
87
|
native: true,
|
|
@@ -95,30 +95,30 @@ const GitlabRepoPicker = (props) => {
|
|
|
95
95
|
selected: owner,
|
|
96
96
|
items: ownerItems
|
|
97
97
|
}
|
|
98
|
+
) }) : /* @__PURE__ */ jsx(
|
|
99
|
+
Autocomplete,
|
|
100
|
+
{
|
|
101
|
+
value: owner,
|
|
102
|
+
onChange: (_, newValue) => {
|
|
103
|
+
onChange({ owner: newValue || "" });
|
|
104
|
+
},
|
|
105
|
+
options: availableGroups.map((group) => group.title),
|
|
106
|
+
renderInput: (params) => /* @__PURE__ */ jsx(
|
|
107
|
+
TextField,
|
|
108
|
+
{
|
|
109
|
+
...params,
|
|
110
|
+
label: t("fields.gitlabRepoPicker.owner.inputTitle"),
|
|
111
|
+
disabled: isDisabled,
|
|
112
|
+
required: true
|
|
113
|
+
}
|
|
114
|
+
),
|
|
115
|
+
freeSolo: true,
|
|
116
|
+
disabled: isDisabled,
|
|
117
|
+
autoSelect: true
|
|
118
|
+
}
|
|
98
119
|
),
|
|
99
120
|
/* @__PURE__ */ jsx(FormHelperText, { children: t("fields.gitlabRepoPicker.owner.description") })
|
|
100
|
-
]
|
|
101
|
-
Autocomplete,
|
|
102
|
-
{
|
|
103
|
-
value: owner,
|
|
104
|
-
onChange: (_, newValue) => {
|
|
105
|
-
onChange({ owner: newValue || "" });
|
|
106
|
-
},
|
|
107
|
-
options: availableGroups.map((group) => group.title),
|
|
108
|
-
renderInput: (params) => /* @__PURE__ */ jsx(
|
|
109
|
-
TextField,
|
|
110
|
-
{
|
|
111
|
-
...params,
|
|
112
|
-
label: t("fields.gitlabRepoPicker.owner.title"),
|
|
113
|
-
disabled: isDisabled,
|
|
114
|
-
required: true
|
|
115
|
-
}
|
|
116
|
-
),
|
|
117
|
-
freeSolo: true,
|
|
118
|
-
disabled: isDisabled,
|
|
119
|
-
autoSelect: true
|
|
120
|
-
}
|
|
121
|
-
)
|
|
121
|
+
]
|
|
122
122
|
}
|
|
123
123
|
) });
|
|
124
124
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GitlabRepoPicker.esm.js","sources":["../../../../src/components/fields/RepoUrlPicker/GitlabRepoPicker.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 { Select, SelectItem } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderApiRef } from '@backstage/plugin-scaffolder-react';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport { useCallback, useState } from 'react';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { BaseRepoUrlPickerProps } from './types';\n\nexport const GitlabRepoPicker = (\n props: BaseRepoUrlPickerProps<{\n allowedOwners?: string[];\n allowedRepos?: string[];\n accessToken?: string;\n }>,\n) => {\n const {\n allowedOwners = [],\n state,\n onChange,\n rawErrors,\n accessToken,\n isDisabled,\n } = props;\n const [availableGroups, setAvailableGroups] = useState<\n { title: string; id: string }[]\n >([]);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const ownerItems: SelectItem[] = allowedOwners\n ? allowedOwners.map(i => ({ label: i, value: i }))\n : [{ label: 'Loading...', value: 'loading' }];\n\n const { owner, host } = state;\n\n const scaffolderApi = useApi(scaffolderApiRef);\n\n const updateAvailableGroups = useCallback(() => {\n if (!scaffolderApi.autocomplete || !accessToken || !host) {\n setAvailableGroups([]);\n return;\n }\n\n scaffolderApi\n .autocomplete({\n token: accessToken,\n resource: 'groups',\n provider: 'gitlab',\n context: { host },\n })\n .then(({ results }) => {\n setAvailableGroups(\n results.map(r => {\n return {\n title: r.title!,\n id: r.id,\n };\n }),\n );\n })\n .catch(() => {\n setAvailableGroups([]);\n });\n }, [scaffolderApi, accessToken, host]);\n\n useDebounce(updateAvailableGroups, 500, [updateAvailableGroups]);\n\n // Update available repositories when client is available and group changes\n const updateAvailableRepositories = useCallback(() => {\n if (!scaffolderApi.autocomplete || !accessToken || !host || !owner) {\n onChange({ availableRepos: [] });\n return;\n }\n\n const selectedGroup = availableGroups.find(group => group.title === owner);\n\n scaffolderApi\n .autocomplete({\n token: accessToken,\n resource: 'repositories',\n context: {\n id: selectedGroup?.id ?? '',\n host,\n },\n provider: 'gitlab',\n })\n .then(({ results }) => {\n onChange({\n availableRepos: results.map(r => {\n return { name: r.title!, id: r.id };\n }),\n });\n })\n .catch(() => {\n onChange({ availableRepos: [] });\n });\n }, [scaffolderApi, accessToken, host, owner, onChange, availableGroups]);\n\n useDebounce(updateAvailableRepositories, 500, [updateAvailableRepositories]);\n\n return (\n <>\n <FormControl\n margin=\"normal\"\n required\n error={rawErrors?.length > 0 && !owner}\n >\n {allowedOwners?.length ? (\n <>\n <Select\n native\n label={t('fields.gitlabRepoPicker.owner.title')}\n onChange={selected =>\n onChange({\n owner: String(\n Array.isArray(selected) ? selected[0] : selected,\n ),\n })\n }\n disabled={isDisabled || allowedOwners.length === 1}\n selected={owner}\n items={ownerItems}\n />\n
|
|
1
|
+
{"version":3,"file":"GitlabRepoPicker.esm.js","sources":["../../../../src/components/fields/RepoUrlPicker/GitlabRepoPicker.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 { Select, SelectItem } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderApiRef } from '@backstage/plugin-scaffolder-react';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport { useCallback, useState } from 'react';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { BaseRepoUrlPickerProps } from './types';\n\nexport const GitlabRepoPicker = (\n props: BaseRepoUrlPickerProps<{\n allowedOwners?: string[];\n allowedRepos?: string[];\n accessToken?: string;\n }>,\n) => {\n const {\n allowedOwners = [],\n state,\n onChange,\n rawErrors,\n accessToken,\n isDisabled,\n } = props;\n const [availableGroups, setAvailableGroups] = useState<\n { title: string; id: string }[]\n >([]);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const ownerItems: SelectItem[] = allowedOwners\n ? allowedOwners.map(i => ({ label: i, value: i }))\n : [{ label: 'Loading...', value: 'loading' }];\n\n const { owner, host } = state;\n\n const scaffolderApi = useApi(scaffolderApiRef);\n\n const updateAvailableGroups = useCallback(() => {\n if (!scaffolderApi.autocomplete || !accessToken || !host) {\n setAvailableGroups([]);\n return;\n }\n\n scaffolderApi\n .autocomplete({\n token: accessToken,\n resource: 'groups',\n provider: 'gitlab',\n context: { host },\n })\n .then(({ results }) => {\n setAvailableGroups(\n results.map(r => {\n return {\n title: r.title!,\n id: r.id,\n };\n }),\n );\n })\n .catch(() => {\n setAvailableGroups([]);\n });\n }, [scaffolderApi, accessToken, host]);\n\n useDebounce(updateAvailableGroups, 500, [updateAvailableGroups]);\n\n // Update available repositories when client is available and group changes\n const updateAvailableRepositories = useCallback(() => {\n if (!scaffolderApi.autocomplete || !accessToken || !host || !owner) {\n onChange({ availableRepos: [] });\n return;\n }\n\n const selectedGroup = availableGroups.find(group => group.title === owner);\n\n scaffolderApi\n .autocomplete({\n token: accessToken,\n resource: 'repositories',\n context: {\n id: selectedGroup?.id ?? '',\n host,\n },\n provider: 'gitlab',\n })\n .then(({ results }) => {\n onChange({\n availableRepos: results.map(r => {\n return { name: r.title!, id: r.id };\n }),\n });\n })\n .catch(() => {\n onChange({ availableRepos: [] });\n });\n }, [scaffolderApi, accessToken, host, owner, onChange, availableGroups]);\n\n useDebounce(updateAvailableRepositories, 500, [updateAvailableRepositories]);\n\n return (\n <>\n <FormControl\n margin=\"normal\"\n required\n error={rawErrors?.length > 0 && !owner}\n >\n {allowedOwners?.length ? (\n <>\n <Select\n native\n label={t('fields.gitlabRepoPicker.owner.title')}\n onChange={selected =>\n onChange({\n owner: String(\n Array.isArray(selected) ? selected[0] : selected,\n ),\n })\n }\n disabled={isDisabled || allowedOwners.length === 1}\n selected={owner}\n items={ownerItems}\n />\n </>\n ) : (\n <Autocomplete\n value={owner}\n onChange={(_, newValue) => {\n onChange({ owner: newValue || '' });\n }}\n options={availableGroups.map(group => group.title)}\n renderInput={params => (\n <TextField\n {...params}\n label={t('fields.gitlabRepoPicker.owner.inputTitle')}\n disabled={isDisabled}\n required\n />\n )}\n freeSolo\n disabled={isDisabled}\n autoSelect\n />\n )}\n <FormHelperText>\n {t('fields.gitlabRepoPicker.owner.description')}\n </FormHelperText>\n </FormControl>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
package/dist/deprecated.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ScaffolderFieldExtensions as ScaffolderFieldExtensions$1, ScaffolderLayouts as ScaffolderLayouts$1, createScaffolderFieldExtension as createScaffolderFieldExtension$1, createScaffolderLayout as createScaffolderLayout$1, scaffolderApiRef as scaffolderApiRef$1, useTemplateSecrets as useTemplateSecrets$1 } from '@backstage/plugin-scaffolder-react';
|
|
2
2
|
import { rootRouteRef as rootRouteRef$1 } from './routes.esm.js';
|
|
3
3
|
|
|
4
4
|
const rootRouteRef = rootRouteRef$1;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ScaffolderClient as ScaffolderClient$1, TemplateEntityV1beta3,
|
|
1
|
+
import { ScaffolderClient as ScaffolderClient$1, TemplateEntityV1beta3, ListActionsResponse as ListActionsResponse$1, LogEvent as LogEvent$1, ScaffolderApi as ScaffolderApi$1, ScaffolderDryRunOptions as ScaffolderDryRunOptions$1, ScaffolderDryRunResponse as ScaffolderDryRunResponse$1, ScaffolderGetIntegrationsListOptions as ScaffolderGetIntegrationsListOptions$1, ScaffolderGetIntegrationsListResponse as ScaffolderGetIntegrationsListResponse$1, ScaffolderOutputLink, ScaffolderScaffoldOptions as ScaffolderScaffoldOptions$1, ScaffolderScaffoldResponse as ScaffolderScaffoldResponse$1, ScaffolderStreamLogsOptions as ScaffolderStreamLogsOptions$1, ScaffolderTask as ScaffolderTask$1, ScaffolderTaskOutput as ScaffolderTaskOutput$2, ScaffolderTaskStatus as ScaffolderTaskStatus$1, TemplateParameterSchema as TemplateParameterSchema$1 } from '@backstage/plugin-scaffolder-common';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { ComponentType, PropsWithChildren } from 'react';
|
|
5
5
|
import * as _backstage_plugin_scaffolder_react from '@backstage/plugin-scaffolder-react';
|
|
6
|
-
import { FieldSchema as FieldSchema$1, ReviewStepProps, ScaffolderTaskOutput as ScaffolderTaskOutput$1, TemplateGroupFilter, FormProps,
|
|
6
|
+
import { FieldSchema as FieldSchema$1, ReviewStepProps, ScaffolderTaskOutput as ScaffolderTaskOutput$1, TemplateGroupFilter, FormProps, CustomFieldExtensionSchema as CustomFieldExtensionSchema$1, CustomFieldValidator as CustomFieldValidator$1, FieldExtensionComponent as FieldExtensionComponent$1, FieldExtensionComponentProps as FieldExtensionComponentProps$1, FieldExtensionOptions as FieldExtensionOptions$1, LayoutOptions as LayoutOptions$1, LayoutTemplate as LayoutTemplate$1, ScaffolderUseTemplateSecrets as ScaffolderUseTemplateSecrets$1, createScaffolderFieldExtension as createScaffolderFieldExtension$1, createScaffolderLayout as createScaffolderLayout$1 } from '@backstage/plugin-scaffolder-react';
|
|
7
7
|
export { ReviewStepProps } from '@backstage/plugin-scaffolder-react';
|
|
8
8
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
9
9
|
import { ApiHolder } from '@backstage/core-plugin-api';
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
function isFileHandle(handle) {
|
|
2
|
+
return handle.kind === "file";
|
|
3
|
+
}
|
|
4
|
+
function isDirectoryHandle(handle) {
|
|
5
|
+
return handle.kind === "directory";
|
|
6
|
+
}
|
|
1
7
|
const showDirectoryPicker = window.showDirectoryPicker;
|
|
2
8
|
class WebFileAccess {
|
|
3
9
|
path;
|
|
@@ -29,9 +35,9 @@ class WebDirectoryAccess {
|
|
|
29
35
|
}
|
|
30
36
|
async *listDirectoryContents(dirHandle, basePath = []) {
|
|
31
37
|
for await (const handle of dirHandle.values()) {
|
|
32
|
-
if (handle
|
|
38
|
+
if (isFileHandle(handle)) {
|
|
33
39
|
yield new WebFileAccess([...basePath, handle.name].join("/"), handle);
|
|
34
|
-
} else if (handle
|
|
40
|
+
} else if (isDirectoryHandle(handle)) {
|
|
35
41
|
if (handle.name === ".git") {
|
|
36
42
|
continue;
|
|
37
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebFileSystemAccess.esm.js","sources":["../../../src/lib/filesystem/WebFileSystemAccess.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TemplateDirectoryAccess, TemplateFileAccess } from './types';\n\
|
|
1
|
+
{"version":3,"file":"WebFileSystemAccess.esm.js","sources":["../../../src/lib/filesystem/WebFileSystemAccess.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TemplateDirectoryAccess, TemplateFileAccess } from './types';\n\nfunction isFileHandle(\n handle: FileSystemHandle,\n): handle is FileSystemFileHandle {\n return handle.kind === 'file';\n}\n\nfunction isDirectoryHandle(\n handle: FileSystemHandle,\n): handle is FileSystemDirectoryHandle {\n return handle.kind === 'directory';\n}\n\nconst showDirectoryPicker = (window as any).showDirectoryPicker as\n | (() => Promise<FileSystemDirectoryHandle>)\n | undefined;\n\nclass WebFileAccess implements TemplateFileAccess {\n readonly path: string;\n private readonly handle: FileSystemFileHandle;\n\n constructor(path: string, handle: FileSystemFileHandle) {\n this.path = path;\n this.handle = handle;\n }\n\n file(): Promise<File> {\n return this.handle.getFile();\n }\n\n async save(data: string | Blob | BufferSource): Promise<void> {\n const writable = await this.handle.createWritable();\n await writable.write(data);\n await writable.close();\n }\n}\n\n/** @internal */\nexport class WebDirectoryAccess implements TemplateDirectoryAccess {\n private readonly handle: FileSystemDirectoryHandle;\n\n constructor(handle: FileSystemDirectoryHandle) {\n this.handle = handle;\n }\n\n async listFiles(): Promise<TemplateFileAccess[]> {\n const content = [];\n for await (const entry of this.listDirectoryContents(this.handle)) {\n content.push(entry);\n }\n return content;\n }\n\n private async *listDirectoryContents(\n dirHandle: FileSystemDirectoryHandle,\n basePath: string[] = [],\n ): AsyncIterable<TemplateFileAccess> {\n for await (const handle of dirHandle.values()) {\n if (isFileHandle(handle)) {\n yield new WebFileAccess([...basePath, handle.name].join('/'), handle);\n } else if (isDirectoryHandle(handle)) {\n // Skip git storage directory\n if (handle.name === '.git') {\n continue;\n }\n yield* this.listDirectoryContents(handle, [...basePath, handle.name]);\n }\n }\n }\n\n async createFile(options: { name: string; data: string }): Promise<void> {\n const { name, data } = options;\n let file: FileSystemFileHandle;\n\n // Current create template does not require support for nested directories\n if (name.includes('/')) {\n const [dir, path] = name.split('/');\n const handle = await this.handle.getDirectoryHandle(dir, {\n create: true,\n });\n file = await handle.getFileHandle(path, { create: true });\n } else {\n file = await this.handle.getFileHandle(name, {\n create: true,\n });\n }\n const writable = await file.createWritable();\n await writable.write(data);\n await writable.close();\n }\n}\n\n/** @internal */\nexport class WebFileSystemAccess {\n static isSupported(): boolean {\n return Boolean(showDirectoryPicker);\n }\n\n static fromHandle(handle: FileSystemDirectoryHandle) {\n return new WebDirectoryAccess(handle);\n }\n\n static async requestDirectoryAccess(): Promise<TemplateDirectoryAccess> {\n if (!showDirectoryPicker) {\n throw new Error('File system access is not supported');\n }\n const handle = await showDirectoryPicker();\n return new WebDirectoryAccess(handle);\n }\n\n private constructor() {}\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebFileSystemStore.esm.js","sources":["../../../src/lib/filesystem/WebFileSystemStore.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { get, set } from 'idb-keyval';\nimport { TemplateDirectoryAccess } from './types';\
|
|
1
|
+
{"version":3,"file":"WebFileSystemStore.esm.js","sources":["../../../src/lib/filesystem/WebFileSystemStore.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { get, set } from 'idb-keyval';\nimport { TemplateDirectoryAccess } from './types';\n\nexport class WebFileSystemStore {\n private static readonly key = 'scalfolder-template-editor-directory';\n\n static async getDirectory(): Promise<FileSystemDirectoryHandle | undefined> {\n const directory = await get(WebFileSystemStore.key);\n return directory.handle;\n }\n\n static async setDirectory(directory: TemplateDirectoryAccess | undefined) {\n return set(WebFileSystemStore.key, directory);\n }\n}\n"],"names":[],"mappings":";;AAmBO,MAAM,kBAAA,CAAmB;AAAA,EAC9B,OAAwB,GAAA,GAAM,sCAAA;AAAA,EAE9B,aAAa,YAAA,GAA+D;AAC1E,IAAA,MAAM,SAAA,GAAY,MAAM,GAAA,CAAI,kBAAA,CAAmB,GAAG,CAAA;AAClD,IAAA,OAAO,SAAA,CAAU,MAAA;AAAA,EACnB;AAAA,EAEA,aAAa,aAAa,SAAA,EAAgD;AACxE,IAAA,OAAO,GAAA,CAAI,kBAAA,CAAmB,GAAA,EAAK,SAAS,CAAA;AAAA,EAC9C;AACF;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-scaffolder",
|
|
3
|
-
"version": "1.36.2-next.
|
|
3
|
+
"version": "1.36.2-next.2",
|
|
4
4
|
"description": "The Backstage plugin that helps you create new things",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "frontend-plugin",
|
|
@@ -70,23 +70,23 @@
|
|
|
70
70
|
"test": "backstage-cli package test"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@backstage/catalog-client": "1.14.0",
|
|
74
|
-
"@backstage/catalog-model": "1.7.
|
|
75
|
-
"@backstage/core-components": "0.18.9-next.
|
|
76
|
-
"@backstage/core-plugin-api": "1.12.5-next.
|
|
77
|
-
"@backstage/errors": "1.
|
|
78
|
-
"@backstage/frontend-plugin-api": "0.
|
|
79
|
-
"@backstage/integration": "2.0.0",
|
|
80
|
-
"@backstage/integration-react": "1.2.17-next.
|
|
81
|
-
"@backstage/plugin-catalog-common": "1.1.
|
|
82
|
-
"@backstage/plugin-catalog-react": "2.1.
|
|
83
|
-
"@backstage/plugin-permission-react": "0.4.42-next.
|
|
84
|
-
"@backstage/plugin-scaffolder-common": "2.0.0",
|
|
85
|
-
"@backstage/plugin-scaffolder-react": "1.20.1-next.
|
|
73
|
+
"@backstage/catalog-client": "1.14.1-next.0",
|
|
74
|
+
"@backstage/catalog-model": "1.7.8-next.0",
|
|
75
|
+
"@backstage/core-components": "0.18.9-next.1",
|
|
76
|
+
"@backstage/core-plugin-api": "1.12.5-next.2",
|
|
77
|
+
"@backstage/errors": "1.3.0-next.0",
|
|
78
|
+
"@backstage/frontend-plugin-api": "0.16.0-next.2",
|
|
79
|
+
"@backstage/integration": "2.0.1-next.0",
|
|
80
|
+
"@backstage/integration-react": "1.2.17-next.1",
|
|
81
|
+
"@backstage/plugin-catalog-common": "1.1.9-next.0",
|
|
82
|
+
"@backstage/plugin-catalog-react": "2.1.2-next.2",
|
|
83
|
+
"@backstage/plugin-permission-react": "0.4.42-next.1",
|
|
84
|
+
"@backstage/plugin-scaffolder-common": "2.0.1-next.0",
|
|
85
|
+
"@backstage/plugin-scaffolder-react": "1.20.1-next.2",
|
|
86
86
|
"@backstage/plugin-techdocs-common": "0.1.1",
|
|
87
|
-
"@backstage/plugin-techdocs-react": "1.3.10-next.
|
|
87
|
+
"@backstage/plugin-techdocs-react": "1.3.10-next.2",
|
|
88
88
|
"@backstage/types": "1.2.2",
|
|
89
|
-
"@backstage/ui": "0.14.0-next.
|
|
89
|
+
"@backstage/ui": "0.14.0-next.2",
|
|
90
90
|
"@codemirror/language": "^6.0.0",
|
|
91
91
|
"@codemirror/legacy-modes": "^6.1.0",
|
|
92
92
|
"@codemirror/view": "^6.0.0",
|
|
@@ -119,14 +119,14 @@
|
|
|
119
119
|
"zod-to-json-schema": "^3.25.1"
|
|
120
120
|
},
|
|
121
121
|
"devDependencies": {
|
|
122
|
-
"@backstage/cli": "0.36.1-next.
|
|
123
|
-
"@backstage/core-app-api": "1.
|
|
124
|
-
"@backstage/dev-utils": "1.1.22-next.
|
|
125
|
-
"@backstage/frontend-test-utils": "0.5.2-next.
|
|
126
|
-
"@backstage/plugin-catalog": "2.0.2-next.
|
|
127
|
-
"@backstage/plugin-permission-common": "0.9.
|
|
128
|
-
"@backstage/plugin-techdocs": "1.17.3-next.
|
|
129
|
-
"@backstage/test-utils": "1.7.17-next.
|
|
122
|
+
"@backstage/cli": "0.36.1-next.2",
|
|
123
|
+
"@backstage/core-app-api": "1.20.0-next.2",
|
|
124
|
+
"@backstage/dev-utils": "1.1.22-next.2",
|
|
125
|
+
"@backstage/frontend-test-utils": "0.5.2-next.2",
|
|
126
|
+
"@backstage/plugin-catalog": "2.0.2-next.2",
|
|
127
|
+
"@backstage/plugin-permission-common": "0.9.8-next.0",
|
|
128
|
+
"@backstage/plugin-techdocs": "1.17.3-next.2",
|
|
129
|
+
"@backstage/test-utils": "1.7.17-next.2",
|
|
130
130
|
"@testing-library/dom": "^10.0.0",
|
|
131
131
|
"@testing-library/jest-dom": "^6.0.0",
|
|
132
132
|
"@testing-library/react": "^16.0.0",
|