@backstage/plugin-scaffolder 1.34.0-next.3 → 1.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/alpha/api/FormDecoratorsApi.esm.js.map +1 -1
- package/dist/alpha/api/ref.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/CustomFieldExplorer.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/CustomFieldPlayground.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/CustomFieldsPage.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/DirectoryEditorContext.esm.js +1 -1
- package/dist/alpha/components/TemplateEditorPage/DirectoryEditorContext.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/DryRunContext.esm.js +1 -1
- package/dist/alpha/components/TemplateEditorPage/DryRunContext.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/DryRunResults/IconLink.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/DryRunResults/TaskPageLinks.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/DryRunResults/TaskStatusStepper.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditor.esm.js +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditor.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditorBrowser.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditorForm.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditorIntro.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditorLayout.esm.js +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditorLayout.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditorPage.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditorTextArea.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbar.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbarFileMenu.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbarTemplatesMenu.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateFormPage.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateFormPreviewer.esm.js +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateFormPreviewer.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/TemplateIntroPage.esm.js.map +1 -1
- package/dist/alpha/components/TemplateEditorPage/useTemplateDirectory.esm.js.map +1 -1
- package/dist/alpha/components/TemplateListPage/RegisterExistingButton.esm.js.map +1 -1
- package/dist/alpha/components/TemplateListPage/TemplateListPage.esm.js.map +1 -1
- package/dist/alpha/components/TemplateWizardPage/TemplateWizardPage.esm.js.map +1 -1
- package/dist/alpha/components/TemplateWizardPage/TemplateWizardPageContextMenu.esm.js.map +1 -1
- package/dist/alpha/extensions.esm.js +1 -1
- package/dist/alpha/extensions.esm.js.map +1 -1
- package/dist/alpha/fields/RepoUrlPicker.esm.js.map +1 -1
- package/dist/alpha/hooks/useFormDecorators.esm.js.map +1 -1
- package/dist/alpha/hooks/useScaffolderTemplateIconLinkProps.esm.js.map +1 -1
- package/dist/alpha/plugin.esm.js +1 -1
- package/dist/alpha/plugin.esm.js.map +1 -1
- package/dist/alpha.d.ts +1 -1
- package/dist/api.esm.js.map +1 -1
- package/dist/components/ActionsPage/ActionsPage.esm.js.map +1 -1
- package/dist/components/FileBrowser/FileBrowser.esm.js +0 -3
- package/dist/components/FileBrowser/FileBrowser.esm.js.map +1 -1
- package/dist/components/ListTasksPage/ListTasksPage.esm.js.map +1 -1
- package/dist/components/ListTasksPage/OwnerListPicker.esm.js.map +1 -1
- package/dist/components/ListTasksPage/columns/CreatedAtColumn.esm.js.map +1 -1
- package/dist/components/ListTasksPage/columns/OwnerEntityColumn.esm.js.map +1 -1
- package/dist/components/ListTasksPage/columns/TaskStatusColumn.esm.js.map +1 -1
- package/dist/components/ListTasksPage/columns/TemplateTitleColumn.esm.js.map +1 -1
- package/dist/components/OngoingTask/ContextMenu.esm.js +1 -1
- package/dist/components/OngoingTask/ContextMenu.esm.js.map +1 -1
- package/dist/components/OngoingTask/OngoingTask.esm.js.map +1 -1
- package/dist/components/RenderSchema/RenderSchema.esm.js +1 -1
- package/dist/components/RenderSchema/RenderSchema.esm.js.map +1 -1
- package/dist/components/Router/Router.esm.js +1 -1
- package/dist/components/Router/Router.esm.js.map +1 -1
- package/dist/components/ScaffolderUsageExamplesTable/ScaffolderUsageExamplesTable.esm.js.map +1 -1
- package/dist/components/TemplateTypePicker/TemplateTypePicker.esm.js.map +1 -1
- package/dist/components/TemplatingExtensionsPage/TemplateFilters.esm.js.map +1 -1
- package/dist/components/TemplatingExtensionsPage/TemplateGlobals.esm.js.map +1 -1
- package/dist/components/TemplatingExtensionsPage/TemplatingExtensionsPage.esm.js.map +1 -1
- package/dist/components/TemplatingExtensionsPage/functionArgs.esm.js.map +1 -1
- package/dist/components/TemplatingExtensionsPage/navigation.esm.js.map +1 -1
- package/dist/components/fields/EntityNamePicker/EntityNamePicker.esm.js.map +1 -1
- package/dist/components/fields/EntityNamePicker/schema.esm.js.map +1 -1
- package/dist/components/fields/EntityNamePicker/validation.esm.js.map +1 -1
- package/dist/components/fields/EntityPicker/EntityPicker.esm.js.map +1 -1
- package/dist/components/fields/EntityPicker/schema.esm.js.map +1 -1
- package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js.map +1 -1
- package/dist/components/fields/EntityTagsPicker/schema.esm.js.map +1 -1
- package/dist/components/fields/MultiEntityPicker/MultiEntityPicker.esm.js +1 -1
- package/dist/components/fields/MultiEntityPicker/MultiEntityPicker.esm.js.map +1 -1
- package/dist/components/fields/MultiEntityPicker/schema.esm.js.map +1 -1
- package/dist/components/fields/MyGroupsPicker/MyGroupsPicker.esm.js.map +1 -1
- package/dist/components/fields/MyGroupsPicker/schema.esm.js.map +1 -1
- package/dist/components/fields/OwnedEntityPicker/OwnedEntityPicker.esm.js.map +1 -1
- package/dist/components/fields/OwnedEntityPicker/schema.esm.js.map +1 -1
- package/dist/components/fields/OwnerPicker/OwnerPicker.esm.js.map +1 -1
- package/dist/components/fields/OwnerPicker/schema.esm.js.map +1 -1
- package/dist/components/fields/RepoBranchPicker/BitbucketRepoBranchPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoBranchPicker/DefaultRepoBranchPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoBranchPicker/GitHubRepoBranchPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoBranchPicker/RepoBranchPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoBranchPicker/schema.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/RepoUrlPickerHost.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/schema.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/utils.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/validation.esm.js.map +1 -1
- package/dist/components/fields/SecretInput/SecretInput.esm.js.map +1 -1
- package/dist/components/fields/VirtualizedListbox.esm.js.map +1 -1
- package/dist/components/fields/utils.esm.js.map +1 -1
- package/dist/deprecated.esm.js.map +1 -1
- package/dist/extensions/default.esm.js +1 -1
- package/dist/extensions/default.esm.js.map +1 -1
- package/dist/lib/download/helpers.esm.js.map +1 -1
- package/dist/lib/filesystem/WebFileSystemAccess.esm.js.map +1 -1
- package/dist/lib/filesystem/WebFileSystemStore.esm.js.map +1 -1
- package/dist/lib/filesystem/createExampleTemplate.esm.js.map +1 -1
- package/dist/packages/opaque-internal/src/OpaqueType.esm.js.map +1 -1
- package/dist/packages/scaffolder-internal/src/wiring/InternalFormDecorator.esm.js.map +1 -1
- package/dist/packages/scaffolder-internal/src/wiring/InternalFormField.esm.js.map +1 -1
- package/dist/plugin.esm.js +3 -3
- package/dist/plugin.esm.js.map +1 -1
- package/dist/plugins/scaffolder/package.json.esm.js +1 -1
- package/dist/routes.esm.js.map +1 -1
- package/dist/translation.esm.js.map +1 -1
- package/package.json +22 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder
|
|
2
2
|
|
|
3
|
+
## 1.34.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c08cbc4: Move Scaffolder API to OpenAPI
|
|
8
|
+
- b1c0696: Add resizable panels width for the editor and preview panels in the template editor and template form playground layouts. Users can now resize these panels by dragging the divider between the two areas.
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system.
|
|
13
|
+
- f2f133c: Internal update to use the new variant of `ApiBlueprint`.
|
|
14
|
+
- b0dc9b8: differentiate between entirely and partially composite schemas in schema rendering
|
|
15
|
+
- c4b7c50: Export `FormField` type from `/alpha` in `-react` package, and internal refactor.
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- @backstage/core-components@0.17.5
|
|
18
|
+
- @backstage/frontend-plugin-api@0.11.0
|
|
19
|
+
- @backstage/plugin-scaffolder-react@1.19.0
|
|
20
|
+
- @backstage/plugin-scaffolder-common@1.7.0
|
|
21
|
+
- @backstage/core-compat-api@0.5.0
|
|
22
|
+
- @backstage/plugin-catalog-react@1.20.0
|
|
23
|
+
- @backstage/catalog-client@1.11.0
|
|
24
|
+
|
|
3
25
|
## 1.34.0-next.3
|
|
4
26
|
|
|
5
27
|
### Minor Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormDecoratorsApi.esm.js","sources":["../../../src/alpha/api/FormDecoratorsApi.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 {\n ApiBlueprint,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport { ScaffolderFormDecoratorsApi } from './types';\nimport { ScaffolderFormDecorator } from '@backstage/plugin-scaffolder-react/alpha';\nimport { formDecoratorsApiRef } from './ref';\nimport { FormDecoratorBlueprint } from '@backstage/plugin-scaffolder-react/alpha';\n\n/** @alpha */\nexport class DefaultScaffolderFormDecoratorsApi\n implements ScaffolderFormDecoratorsApi\n{\n private constructor(\n private readonly options: {\n decorators: Array<ScaffolderFormDecorator>;\n },\n ) {}\n\n static create(options?: { decorators: ScaffolderFormDecorator[] }) {\n return new DefaultScaffolderFormDecoratorsApi(\n options ?? { decorators: [] },\n );\n }\n\n async getFormDecorators(): Promise<ScaffolderFormDecorator[]> {\n return this.options.decorators;\n }\n}\n\n/** @alpha */\nexport const formDecoratorsApi = ApiBlueprint.makeWithOverrides({\n name: 'form-decorators',\n inputs: {\n formDecorators: createExtensionInput([\n FormDecoratorBlueprint.dataRefs.formDecoratorLoader,\n ]),\n },\n factory(originalFactory, { inputs }) {\n const formDecorators = inputs.formDecorators.map(e =>\n e.get(FormDecoratorBlueprint.dataRefs.formDecoratorLoader),\n );\n\n return originalFactory(defineParams =>\n defineParams({\n api: formDecoratorsApiRef,\n deps: {},\n factory: () =>\n DefaultScaffolderFormDecoratorsApi.create({\n decorators: formDecorators,\n }),\n }),\n );\n },\n});\n"],"names":[],"mappings":";;;;AA0BO,MAAM,
|
|
1
|
+
{"version":3,"file":"FormDecoratorsApi.esm.js","sources":["../../../src/alpha/api/FormDecoratorsApi.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 {\n ApiBlueprint,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport { ScaffolderFormDecoratorsApi } from './types';\nimport { ScaffolderFormDecorator } from '@backstage/plugin-scaffolder-react/alpha';\nimport { formDecoratorsApiRef } from './ref';\nimport { FormDecoratorBlueprint } from '@backstage/plugin-scaffolder-react/alpha';\n\n/** @alpha */\nexport class DefaultScaffolderFormDecoratorsApi\n implements ScaffolderFormDecoratorsApi\n{\n private constructor(\n private readonly options: {\n decorators: Array<ScaffolderFormDecorator>;\n },\n ) {}\n\n static create(options?: { decorators: ScaffolderFormDecorator[] }) {\n return new DefaultScaffolderFormDecoratorsApi(\n options ?? { decorators: [] },\n );\n }\n\n async getFormDecorators(): Promise<ScaffolderFormDecorator[]> {\n return this.options.decorators;\n }\n}\n\n/** @alpha */\nexport const formDecoratorsApi = ApiBlueprint.makeWithOverrides({\n name: 'form-decorators',\n inputs: {\n formDecorators: createExtensionInput([\n FormDecoratorBlueprint.dataRefs.formDecoratorLoader,\n ]),\n },\n factory(originalFactory, { inputs }) {\n const formDecorators = inputs.formDecorators.map(e =>\n e.get(FormDecoratorBlueprint.dataRefs.formDecoratorLoader),\n );\n\n return originalFactory(defineParams =>\n defineParams({\n api: formDecoratorsApiRef,\n deps: {},\n factory: () =>\n DefaultScaffolderFormDecoratorsApi.create({\n decorators: formDecorators,\n }),\n }),\n );\n },\n});\n"],"names":[],"mappings":";;;;AA0BO,MAAM,kCAAA,CAEb;AAAA,EACU,YACW,OAAA,EAGjB;AAHiB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA,EAGhB;AAAA,EAEH,OAAO,OAAO,OAAA,EAAqD;AACjE,IAAA,OAAO,IAAI,kCAAA;AAAA,MACT,OAAA,IAAW,EAAE,UAAA,EAAY,EAAC;AAAE,KAC9B;AAAA,EACF;AAAA,EAEA,MAAM,iBAAA,GAAwD;AAC5D,IAAA,OAAO,KAAK,OAAA,CAAQ,UAAA;AAAA,EACtB;AACF;AAGO,MAAM,iBAAA,GAAoB,aAAa,iBAAA,CAAkB;AAAA,EAC9D,IAAA,EAAM,iBAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,gBAAgB,oBAAA,CAAqB;AAAA,MACnC,uBAAuB,QAAA,CAAS;AAAA,KACjC;AAAA,GACH;AAAA,EACA,OAAA,CAAQ,eAAA,EAAiB,EAAE,MAAA,EAAO,EAAG;AACnC,IAAA,MAAM,cAAA,GAAiB,OAAO,cAAA,CAAe,GAAA;AAAA,MAAI,CAAA,CAAA,KAC/C,CAAA,CAAE,GAAA,CAAI,sBAAA,CAAuB,SAAS,mBAAmB;AAAA,KAC3D;AAEA,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,oBAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,OAAA,EAAS,MACP,kCAAA,CAAmC,MAAA,CAAO;AAAA,UACxC,UAAA,EAAY;AAAA,SACb;AAAA,OACJ;AAAA,KACH;AAAA,EACF;AACF,CAAC;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ref.esm.js","sources":["../../../src/alpha/api/ref.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 { createApiRef } from '@backstage/frontend-plugin-api';\nimport { ScaffolderFormDecoratorsApi } from './types';\n\n/** @alpha */\nexport const formDecoratorsApiRef = createApiRef<ScaffolderFormDecoratorsApi>({\n id: 'plugin.scaffolder.form-decorators',\n});\n"],"names":[],"mappings":";;AAoBO,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"ref.esm.js","sources":["../../../src/alpha/api/ref.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 { createApiRef } from '@backstage/frontend-plugin-api';\nimport { ScaffolderFormDecoratorsApi } from './types';\n\n/** @alpha */\nexport const formDecoratorsApiRef = createApiRef<ScaffolderFormDecoratorsApi>({\n id: 'plugin.scaffolder.form-decorators',\n});\n"],"names":[],"mappings":";;AAoBO,MAAM,uBAAuB,YAAA,CAA0C;AAAA,EAC5E,EAAA,EAAI;AACN,CAAC;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomFieldExplorer.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/CustomFieldExplorer.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 { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\nimport Button from '@material-ui/core/Button';\nimport Card from '@material-ui/core/Card';\nimport CardContent from '@material-ui/core/CardContent';\nimport CardHeader from '@material-ui/core/CardHeader';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CodeMirror from '@uiw/react-codemirror';\nimport { useCallback, useMemo, useState } from 'react';\nimport yaml from 'yaml';\nimport { Form } from '@backstage/plugin-scaffolder-react/alpha';\nimport { TemplateEditorForm } from './TemplateEditorForm';\nimport validator from '@rjsf/validator-ajv8';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport InputAdornment from '@material-ui/core/InputAdornment';\nimport TextField from '@material-ui/core/TextField';\nimport SearchIcon from '@material-ui/icons/Search';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\n\n/** @public */\nexport type ScaffolderCustomFieldExplorerClassKey =\n | 'root'\n | 'controls'\n | 'fieldForm'\n | 'preview';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n gridArea: 'pageContent',\n display: 'grid',\n gridGap: theme.spacing(2),\n gridTemplateAreas: `\n \"controls\"\n \"fieldForm\"\n \"preview\"\n `,\n [theme.breakpoints.up('md')]: {\n gridTemplateAreas: `\n \"controls controls\"\n \"fieldForm preview\"\n `,\n gridTemplateRows: 'auto 1fr',\n gridTemplateColumns: '1fr 1fr',\n },\n },\n controls: {\n gridArea: 'controls',\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n },\n fieldForm: {\n gridArea: 'fieldForm',\n },\n preview: {\n gridArea: 'preview',\n display: 'grid',\n gridGap: theme.spacing(2),\n alignContent: 'start',\n },\n }),\n { name: 'ScaffolderCustomFieldExplorer' },\n);\n\nexport const CustomFieldExplorer = ({\n customFieldExtensions = [],\n}: {\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n}) => {\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const fieldOptions = customFieldExtensions.filter(field => !!field.schema);\n const [selectedField, setSelectedField] = useState(fieldOptions?.[0]);\n const [fieldFormState, setFieldFormState] = useState({});\n const [refreshKey, setRefreshKey] = useState(Date.now());\n const sampleFieldTemplate = useMemo(() => {\n if (!selectedField) {\n return '';\n }\n return yaml.stringify({\n parameters: [\n {\n title: `${selectedField.name} Example`,\n properties: {\n [selectedField.name]: {\n type: selectedField.schema?.returnValue?.type,\n 'ui:field': selectedField.name,\n 'ui:options': fieldFormState,\n },\n },\n },\n ],\n });\n }, [fieldFormState, selectedField]);\n\n const fieldComponents = useMemo(() => {\n return Object.fromEntries(\n customFieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [customFieldExtensions]);\n\n const handleSelectionChange = useCallback(\n (selection: FieldExtensionOptions) => {\n setSelectedField(selection);\n setFieldFormState({});\n },\n [setFieldFormState, setSelectedField],\n );\n\n const handleFieldConfigChange = useCallback(\n (state: {}) => {\n setFieldFormState(state);\n // Force TemplateEditorForm to re-render since some fields\n // may not be responsive to ui:option changes\n setRefreshKey(Date.now());\n },\n [setFieldFormState, setRefreshKey],\n );\n\n return (\n <main className={classes.root}>\n <div className={classes.controls}>\n <Autocomplete\n id=\"custom-fields-autocomplete\"\n value={selectedField}\n options={fieldOptions}\n getOptionLabel={option => option.name}\n renderInput={params => (\n <TextField\n {...params}\n aria-label={t(\n 'templateEditorPage.customFieldExplorer.selectFieldLabel',\n )}\n placeholder={t(\n 'templateEditorPage.customFieldExplorer.selectFieldLabel',\n )}\n variant=\"outlined\"\n InputProps={{\n ...params.InputProps,\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon />\n </InputAdornment>\n ),\n }}\n />\n )}\n onChange={(_event, option) => {\n if (option) {\n handleSelectionChange(option);\n }\n }}\n disableClearable\n fullWidth\n />\n </div>\n <div className={classes.fieldForm}>\n <Card>\n <CardHeader\n title={t('templateEditorPage.customFieldExplorer.fieldForm.title')}\n />\n <CardContent>\n <Form\n showErrorList={false}\n fields={{ ...fieldComponents }}\n noHtml5Validate\n formData={fieldFormState}\n formContext={{ fieldFormState }}\n onSubmit={e => handleFieldConfigChange(e.formData)}\n validator={validator}\n schema={selectedField?.schema?.uiOptions || {}}\n experimental_defaultFormStateBehavior={{\n allOf: 'populateDefaults',\n }}\n >\n <Button\n variant=\"contained\"\n color=\"primary\"\n type=\"submit\"\n disabled={!selectedField?.schema?.uiOptions}\n >\n {t(\n 'templateEditorPage.customFieldExplorer.fieldForm.applyButtonTitle',\n )}\n </Button>\n </Form>\n </CardContent>\n </Card>\n </div>\n <div className={classes.preview}>\n <Card>\n <CardHeader\n title={t('templateEditorPage.customFieldExplorer.preview.title')}\n />\n <CardContent>\n <CodeMirror\n readOnly\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n value={sampleFieldTemplate}\n />\n </CardContent>\n </Card>\n <TemplateEditorForm\n key={refreshKey}\n content={sampleFieldTemplate}\n contentIsSpec\n fieldExtensions={customFieldExtensions}\n setErrorText={() => null}\n />\n </div>\n </main>\n );\n};\n"],"names":["yamlSupport"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CustomFieldExplorer.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/CustomFieldExplorer.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 { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\nimport Button from '@material-ui/core/Button';\nimport Card from '@material-ui/core/Card';\nimport CardContent from '@material-ui/core/CardContent';\nimport CardHeader from '@material-ui/core/CardHeader';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CodeMirror from '@uiw/react-codemirror';\nimport { useCallback, useMemo, useState } from 'react';\nimport yaml from 'yaml';\nimport { Form } from '@backstage/plugin-scaffolder-react/alpha';\nimport { TemplateEditorForm } from './TemplateEditorForm';\nimport validator from '@rjsf/validator-ajv8';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport InputAdornment from '@material-ui/core/InputAdornment';\nimport TextField from '@material-ui/core/TextField';\nimport SearchIcon from '@material-ui/icons/Search';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\n\n/** @public */\nexport type ScaffolderCustomFieldExplorerClassKey =\n | 'root'\n | 'controls'\n | 'fieldForm'\n | 'preview';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n gridArea: 'pageContent',\n display: 'grid',\n gridGap: theme.spacing(2),\n gridTemplateAreas: `\n \"controls\"\n \"fieldForm\"\n \"preview\"\n `,\n [theme.breakpoints.up('md')]: {\n gridTemplateAreas: `\n \"controls controls\"\n \"fieldForm preview\"\n `,\n gridTemplateRows: 'auto 1fr',\n gridTemplateColumns: '1fr 1fr',\n },\n },\n controls: {\n gridArea: 'controls',\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n },\n fieldForm: {\n gridArea: 'fieldForm',\n },\n preview: {\n gridArea: 'preview',\n display: 'grid',\n gridGap: theme.spacing(2),\n alignContent: 'start',\n },\n }),\n { name: 'ScaffolderCustomFieldExplorer' },\n);\n\nexport const CustomFieldExplorer = ({\n customFieldExtensions = [],\n}: {\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n}) => {\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const fieldOptions = customFieldExtensions.filter(field => !!field.schema);\n const [selectedField, setSelectedField] = useState(fieldOptions?.[0]);\n const [fieldFormState, setFieldFormState] = useState({});\n const [refreshKey, setRefreshKey] = useState(Date.now());\n const sampleFieldTemplate = useMemo(() => {\n if (!selectedField) {\n return '';\n }\n return yaml.stringify({\n parameters: [\n {\n title: `${selectedField.name} Example`,\n properties: {\n [selectedField.name]: {\n type: selectedField.schema?.returnValue?.type,\n 'ui:field': selectedField.name,\n 'ui:options': fieldFormState,\n },\n },\n },\n ],\n });\n }, [fieldFormState, selectedField]);\n\n const fieldComponents = useMemo(() => {\n return Object.fromEntries(\n customFieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [customFieldExtensions]);\n\n const handleSelectionChange = useCallback(\n (selection: FieldExtensionOptions) => {\n setSelectedField(selection);\n setFieldFormState({});\n },\n [setFieldFormState, setSelectedField],\n );\n\n const handleFieldConfigChange = useCallback(\n (state: {}) => {\n setFieldFormState(state);\n // Force TemplateEditorForm to re-render since some fields\n // may not be responsive to ui:option changes\n setRefreshKey(Date.now());\n },\n [setFieldFormState, setRefreshKey],\n );\n\n return (\n <main className={classes.root}>\n <div className={classes.controls}>\n <Autocomplete\n id=\"custom-fields-autocomplete\"\n value={selectedField}\n options={fieldOptions}\n getOptionLabel={option => option.name}\n renderInput={params => (\n <TextField\n {...params}\n aria-label={t(\n 'templateEditorPage.customFieldExplorer.selectFieldLabel',\n )}\n placeholder={t(\n 'templateEditorPage.customFieldExplorer.selectFieldLabel',\n )}\n variant=\"outlined\"\n InputProps={{\n ...params.InputProps,\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon />\n </InputAdornment>\n ),\n }}\n />\n )}\n onChange={(_event, option) => {\n if (option) {\n handleSelectionChange(option);\n }\n }}\n disableClearable\n fullWidth\n />\n </div>\n <div className={classes.fieldForm}>\n <Card>\n <CardHeader\n title={t('templateEditorPage.customFieldExplorer.fieldForm.title')}\n />\n <CardContent>\n <Form\n showErrorList={false}\n fields={{ ...fieldComponents }}\n noHtml5Validate\n formData={fieldFormState}\n formContext={{ fieldFormState }}\n onSubmit={e => handleFieldConfigChange(e.formData)}\n validator={validator}\n schema={selectedField?.schema?.uiOptions || {}}\n experimental_defaultFormStateBehavior={{\n allOf: 'populateDefaults',\n }}\n >\n <Button\n variant=\"contained\"\n color=\"primary\"\n type=\"submit\"\n disabled={!selectedField?.schema?.uiOptions}\n >\n {t(\n 'templateEditorPage.customFieldExplorer.fieldForm.applyButtonTitle',\n )}\n </Button>\n </Form>\n </CardContent>\n </Card>\n </div>\n <div className={classes.preview}>\n <Card>\n <CardHeader\n title={t('templateEditorPage.customFieldExplorer.preview.title')}\n />\n <CardContent>\n <CodeMirror\n readOnly\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n value={sampleFieldTemplate}\n />\n </CardContent>\n </Card>\n <TemplateEditorForm\n key={refreshKey}\n content={sampleFieldTemplate}\n contentIsSpec\n fieldExtensions={customFieldExtensions}\n setErrorText={() => null}\n />\n </div>\n </main>\n );\n};\n"],"names":["yamlSupport"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomFieldPlayground.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/CustomFieldPlayground.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 { useCallback, useMemo, useState } from 'react';\nimport yaml from 'yaml';\nimport validator from '@rjsf/validator-ajv8';\nimport CodeMirror from '@uiw/react-codemirror';\nimport { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Accordion from '@material-ui/core/Accordion';\nimport AccordionSummary from '@material-ui/core/AccordionSummary';\nimport AccordionDetails from '@material-ui/core/AccordionDetails';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport TextField from '@material-ui/core/TextField';\nimport Button from '@material-ui/core/Button';\nimport InputAdornment from '@material-ui/core/InputAdornment';\nimport Typography from '@material-ui/core/Typography';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport SearchIcon from '@material-ui/icons/Search';\n\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { Form } from '@backstage/plugin-scaffolder-react/alpha';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\n\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { TemplateEditorForm } from './TemplateEditorForm';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateRows: 'auto 1fr',\n },\n controls: {\n marginBottom: theme.spacing(3),\n },\n code: {\n width: '100%',\n },\n }),\n { name: 'ScaffolderCustomFieldExtensionsPlaygroud' },\n);\n\nexport const CustomFieldPlayground = ({\n fieldExtensions = [],\n}: {\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n}) => {\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const fieldOptions = fieldExtensions.filter(field => !!field.schema);\n const [refreshKey, setRefreshKey] = useState(Date.now());\n const [fieldFormState, setFieldFormState] = useState({});\n const [selectedField, setSelectedField] = useState(fieldOptions[0]);\n const sampleFieldTemplate = useMemo(\n () =>\n yaml.stringify({\n parameters: [\n {\n title: `${selectedField.name} Example`,\n properties: {\n [selectedField.name]: {\n type: selectedField.schema?.returnValue?.type,\n 'ui:field': selectedField.name,\n 'ui:options': fieldFormState,\n },\n },\n },\n ],\n }),\n [fieldFormState, selectedField],\n );\n\n const fieldComponents = useMemo(() => {\n return Object.fromEntries(\n fieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [fieldExtensions]);\n\n const handleSelectionChange = useCallback(\n (selection: FieldExtensionOptions) => {\n setSelectedField(selection);\n setFieldFormState({});\n },\n [setFieldFormState, setSelectedField],\n );\n\n const handleFieldConfigChange = useCallback(\n (state: {}) => {\n setFieldFormState(state);\n // Force TemplateEditorForm to re-render since some fields\n // may not be responsive to ui:option changes\n setRefreshKey(Date.now());\n },\n [setFieldFormState, setRefreshKey],\n );\n\n return (\n <main className={classes.root}>\n <div className={classes.controls}>\n <Autocomplete\n id=\"custom-fields-autocomplete\"\n value={selectedField}\n options={fieldOptions}\n getOptionLabel={option => option.name}\n renderInput={params => (\n <TextField\n {...params}\n aria-label={t(\n 'templateEditorPage.customFieldExplorer.selectFieldLabel',\n )}\n placeholder={t(\n 'templateEditorPage.customFieldExplorer.selectFieldLabel',\n )}\n variant=\"outlined\"\n InputProps={{\n ...params.InputProps,\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon />\n </InputAdornment>\n ),\n }}\n />\n )}\n onChange={(_event, option) => {\n if (option) {\n handleSelectionChange(option);\n }\n }}\n disableClearable\n fullWidth\n />\n </div>\n <div>\n <Accordion defaultExpanded>\n <AccordionSummary\n expandIcon={<ExpandMoreIcon />}\n aria-controls=\"panel-code-content\"\n id=\"panel-code-header\"\n >\n <Typography variant=\"h6\">\n {t('templateEditorPage.customFieldExplorer.preview.title')}\n </Typography>\n </AccordionSummary>\n <AccordionDetails>\n <div className={classes.code}>\n <CodeMirror\n readOnly\n theme=\"dark\"\n height=\"100%\"\n width=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n value={sampleFieldTemplate}\n />\n </div>\n </AccordionDetails>\n </Accordion>\n <Accordion defaultExpanded>\n <AccordionSummary\n expandIcon={<ExpandMoreIcon />}\n aria-controls=\"panel-preview-content\"\n id=\"panel-preview-header\"\n >\n <Typography variant=\"h6\">\n {t('templateEditorPage.customFieldExplorer.fieldPreview.title')}\n </Typography>\n </AccordionSummary>\n <AccordionDetails>\n <TemplateEditorForm\n key={refreshKey}\n content={sampleFieldTemplate}\n contentIsSpec\n fieldExtensions={fieldExtensions}\n setErrorText={() => null}\n />\n </AccordionDetails>\n </Accordion>\n <Accordion defaultExpanded>\n <AccordionSummary\n expandIcon={<ExpandMoreIcon />}\n aria-controls=\"panel-options-content\"\n id=\"panel-options-header\"\n >\n <Typography variant=\"h6\">\n {t('templateEditorPage.customFieldExplorer.fieldForm.title')}\n </Typography>\n </AccordionSummary>\n <AccordionDetails>\n <Form\n showErrorList={false}\n fields={{ ...fieldComponents }}\n noHtml5Validate\n formData={fieldFormState}\n formContext={{ fieldFormState }}\n onSubmit={e => handleFieldConfigChange(e.formData)}\n validator={validator}\n schema={selectedField.schema?.uiOptions || {}}\n experimental_defaultFormStateBehavior={{\n allOf: 'populateDefaults',\n }}\n >\n <Button\n variant=\"contained\"\n color=\"primary\"\n type=\"submit\"\n disabled={!selectedField.schema?.uiOptions}\n >\n {t(\n 'templateEditorPage.customFieldExplorer.fieldForm.applyButtonTitle',\n )}\n </Button>\n </Form>\n </AccordionDetails>\n </Accordion>\n </div>\n </main>\n );\n};\n"],"names":["yamlSupport"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CustomFieldPlayground.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/CustomFieldPlayground.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 { useCallback, useMemo, useState } from 'react';\nimport yaml from 'yaml';\nimport validator from '@rjsf/validator-ajv8';\nimport CodeMirror from '@uiw/react-codemirror';\nimport { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Accordion from '@material-ui/core/Accordion';\nimport AccordionSummary from '@material-ui/core/AccordionSummary';\nimport AccordionDetails from '@material-ui/core/AccordionDetails';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport TextField from '@material-ui/core/TextField';\nimport Button from '@material-ui/core/Button';\nimport InputAdornment from '@material-ui/core/InputAdornment';\nimport Typography from '@material-ui/core/Typography';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport SearchIcon from '@material-ui/icons/Search';\n\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { Form } from '@backstage/plugin-scaffolder-react/alpha';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\n\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { TemplateEditorForm } from './TemplateEditorForm';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateRows: 'auto 1fr',\n },\n controls: {\n marginBottom: theme.spacing(3),\n },\n code: {\n width: '100%',\n },\n }),\n { name: 'ScaffolderCustomFieldExtensionsPlaygroud' },\n);\n\nexport const CustomFieldPlayground = ({\n fieldExtensions = [],\n}: {\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n}) => {\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const fieldOptions = fieldExtensions.filter(field => !!field.schema);\n const [refreshKey, setRefreshKey] = useState(Date.now());\n const [fieldFormState, setFieldFormState] = useState({});\n const [selectedField, setSelectedField] = useState(fieldOptions[0]);\n const sampleFieldTemplate = useMemo(\n () =>\n yaml.stringify({\n parameters: [\n {\n title: `${selectedField.name} Example`,\n properties: {\n [selectedField.name]: {\n type: selectedField.schema?.returnValue?.type,\n 'ui:field': selectedField.name,\n 'ui:options': fieldFormState,\n },\n },\n },\n ],\n }),\n [fieldFormState, selectedField],\n );\n\n const fieldComponents = useMemo(() => {\n return Object.fromEntries(\n fieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [fieldExtensions]);\n\n const handleSelectionChange = useCallback(\n (selection: FieldExtensionOptions) => {\n setSelectedField(selection);\n setFieldFormState({});\n },\n [setFieldFormState, setSelectedField],\n );\n\n const handleFieldConfigChange = useCallback(\n (state: {}) => {\n setFieldFormState(state);\n // Force TemplateEditorForm to re-render since some fields\n // may not be responsive to ui:option changes\n setRefreshKey(Date.now());\n },\n [setFieldFormState, setRefreshKey],\n );\n\n return (\n <main className={classes.root}>\n <div className={classes.controls}>\n <Autocomplete\n id=\"custom-fields-autocomplete\"\n value={selectedField}\n options={fieldOptions}\n getOptionLabel={option => option.name}\n renderInput={params => (\n <TextField\n {...params}\n aria-label={t(\n 'templateEditorPage.customFieldExplorer.selectFieldLabel',\n )}\n placeholder={t(\n 'templateEditorPage.customFieldExplorer.selectFieldLabel',\n )}\n variant=\"outlined\"\n InputProps={{\n ...params.InputProps,\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon />\n </InputAdornment>\n ),\n }}\n />\n )}\n onChange={(_event, option) => {\n if (option) {\n handleSelectionChange(option);\n }\n }}\n disableClearable\n fullWidth\n />\n </div>\n <div>\n <Accordion defaultExpanded>\n <AccordionSummary\n expandIcon={<ExpandMoreIcon />}\n aria-controls=\"panel-code-content\"\n id=\"panel-code-header\"\n >\n <Typography variant=\"h6\">\n {t('templateEditorPage.customFieldExplorer.preview.title')}\n </Typography>\n </AccordionSummary>\n <AccordionDetails>\n <div className={classes.code}>\n <CodeMirror\n readOnly\n theme=\"dark\"\n height=\"100%\"\n width=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n value={sampleFieldTemplate}\n />\n </div>\n </AccordionDetails>\n </Accordion>\n <Accordion defaultExpanded>\n <AccordionSummary\n expandIcon={<ExpandMoreIcon />}\n aria-controls=\"panel-preview-content\"\n id=\"panel-preview-header\"\n >\n <Typography variant=\"h6\">\n {t('templateEditorPage.customFieldExplorer.fieldPreview.title')}\n </Typography>\n </AccordionSummary>\n <AccordionDetails>\n <TemplateEditorForm\n key={refreshKey}\n content={sampleFieldTemplate}\n contentIsSpec\n fieldExtensions={fieldExtensions}\n setErrorText={() => null}\n />\n </AccordionDetails>\n </Accordion>\n <Accordion defaultExpanded>\n <AccordionSummary\n expandIcon={<ExpandMoreIcon />}\n aria-controls=\"panel-options-content\"\n id=\"panel-options-header\"\n >\n <Typography variant=\"h6\">\n {t('templateEditorPage.customFieldExplorer.fieldForm.title')}\n </Typography>\n </AccordionSummary>\n <AccordionDetails>\n <Form\n showErrorList={false}\n fields={{ ...fieldComponents }}\n noHtml5Validate\n formData={fieldFormState}\n formContext={{ fieldFormState }}\n onSubmit={e => handleFieldConfigChange(e.formData)}\n validator={validator}\n schema={selectedField.schema?.uiOptions || {}}\n experimental_defaultFormStateBehavior={{\n allOf: 'populateDefaults',\n }}\n >\n <Button\n variant=\"contained\"\n color=\"primary\"\n type=\"submit\"\n disabled={!selectedField.schema?.uiOptions}\n >\n {t(\n 'templateEditorPage.customFieldExplorer.fieldForm.applyButtonTitle',\n )}\n </Button>\n </Form>\n </AccordionDetails>\n </Accordion>\n </div>\n </main>\n );\n};\n"],"names":["yamlSupport"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomFieldsPage.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/CustomFieldsPage.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Page, Header, Content } from '@backstage/core-components';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\n\nimport { editRouteRef } from '../../../routes';\nimport { scaffolderTranslationRef } from '../../../translation';\n\nimport { CustomFieldExplorer } from './CustomFieldExplorer';\n\ninterface CustomFieldsPageProps {\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n}\n\nexport function CustomFieldsPage(props: CustomFieldsPageProps) {\n const editLink = useRouteRef(editRouteRef);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <Page themeId=\"home\">\n <Header\n title={t('templateCustomFieldPage.title')}\n subtitle={t('templateCustomFieldPage.subtitle')}\n type={t('templateIntroPage.title')}\n typeLink={editLink()}\n />\n <Content>\n <CustomFieldExplorer customFieldExtensions={props.fieldExtensions} />\n </Content>\n </Page>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AA8BO,SAAS,iBAAiB,
|
|
1
|
+
{"version":3,"file":"CustomFieldsPage.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/CustomFieldsPage.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Page, Header, Content } from '@backstage/core-components';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\n\nimport { editRouteRef } from '../../../routes';\nimport { scaffolderTranslationRef } from '../../../translation';\n\nimport { CustomFieldExplorer } from './CustomFieldExplorer';\n\ninterface CustomFieldsPageProps {\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n}\n\nexport function CustomFieldsPage(props: CustomFieldsPageProps) {\n const editLink = useRouteRef(editRouteRef);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <Page themeId=\"home\">\n <Header\n title={t('templateCustomFieldPage.title')}\n subtitle={t('templateCustomFieldPage.subtitle')}\n type={t('templateIntroPage.title')}\n typeLink={editLink()}\n />\n <Content>\n <CustomFieldExplorer customFieldExtensions={props.fieldExtensions} />\n </Content>\n </Page>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AA8BO,SAAS,iBAAiB,KAAA,EAA8B;AAC7D,EAAA,MAAM,QAAA,GAAW,YAAY,YAAY,CAAA;AACzC,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,wBAAwB,CAAA;AAExD,EAAA,uBACE,IAAA,CAAC,IAAA,EAAA,EAAK,OAAA,EAAQ,MAAA,EACZ,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,EAAE,+BAA+B,CAAA;AAAA,QACxC,QAAA,EAAU,EAAE,kCAAkC,CAAA;AAAA,QAC9C,IAAA,EAAM,EAAE,yBAAyB,CAAA;AAAA,QACjC,UAAU,QAAA;AAAS;AAAA,KACrB;AAAA,wBACC,OAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,uBAAoB,qBAAA,EAAuB,KAAA,CAAM,iBAAiB,CAAA,EACrE;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { ErrorPanel } from '@backstage/core-components';
|
|
3
3
|
import { useAsync, useRerender } from '@react-hookz/web';
|
|
4
|
-
import {
|
|
4
|
+
import { useEffect, createContext, useContext } from 'react';
|
|
5
5
|
|
|
6
6
|
const MAX_SIZE = 1024 * 1024;
|
|
7
7
|
const MAX_SIZE_MESSAGE = "This file is too large to be displayed";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DirectoryEditorContext.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/DirectoryEditorContext.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 { ErrorPanel } from '@backstage/core-components';\nimport { useAsync, useRerender } from '@react-hookz/web';\nimport { createContext, ReactNode, useContext, useEffect } from 'react';\nimport {\n TemplateDirectoryAccess,\n TemplateFileAccess,\n} from '../../../lib/filesystem';\n\nconst MAX_SIZE = 1024 * 1024;\nconst MAX_SIZE_MESSAGE = 'This file is too large to be displayed';\n\ninterface DirectoryEditorFile {\n /** The path of the file relative to the root directory */\n path: string;\n /** The staged content of the file */\n content: string;\n /** Whether the staged content matches what is on disk */\n dirty: boolean;\n\n /** Update the staged content of the file without saving */\n updateContent(content: string): void;\n /** Save the staged content of the file to disk */\n save(): Promise<void>;\n /** Reload the staged content of the file from disk */\n reload(): Promise<void>;\n}\n\ninterface DirectoryEditor {\n /** A list of all files in the edited directory */\n files: Array<DirectoryEditorFile>;\n\n /** The currently selected file */\n selectedFile: DirectoryEditorFile | undefined;\n /** Switch the selected file */\n setSelectedFile(path: string | undefined): void;\n\n /** Save all files to disk */\n save(): Promise<void>;\n /** Reload all files from disk */\n reload(): Promise<void>;\n\n subscribe(listener: () => void): () => void;\n}\n\nclass DirectoryEditorFileManager implements DirectoryEditorFile {\n readonly #access: TemplateFileAccess;\n readonly #signalUpdate: () => void;\n\n #content?: string;\n #savedContent?: string;\n\n constructor(access: TemplateFileAccess, signalUpdate: () => void) {\n this.#access = access;\n this.#signalUpdate = signalUpdate;\n }\n\n get path() {\n return this.#access.path;\n }\n\n get content() {\n return this.#content ?? MAX_SIZE_MESSAGE;\n }\n\n updateContent(content: string): void {\n if (this.#content === undefined) {\n return;\n }\n this.#content = content;\n this.#signalUpdate();\n }\n\n get dirty() {\n return this.#content !== this.#savedContent;\n }\n\n async save(): Promise<void> {\n if (this.#content !== undefined) {\n await this.#access.save(this.#content);\n this.#savedContent = this.#content;\n this.#signalUpdate();\n }\n }\n\n async reload(): Promise<void> {\n const file = await this.#access.file();\n if (file.size > MAX_SIZE) {\n if (this.#content !== undefined) {\n this.#content = undefined;\n this.#savedContent = undefined;\n this.#signalUpdate();\n }\n return;\n }\n\n const content = await file.text();\n if (this.#content !== content) {\n this.#content = content;\n this.#savedContent = content;\n this.#signalUpdate();\n }\n }\n}\n\nclass DirectoryEditorManager implements DirectoryEditor {\n readonly #access: TemplateDirectoryAccess;\n readonly #listeners = new Set<() => void>();\n\n #files: DirectoryEditorFile[] = [];\n #selectedFile: DirectoryEditorFile | undefined;\n\n constructor(access: TemplateDirectoryAccess) {\n this.#access = access;\n }\n\n get files() {\n return this.#files;\n }\n\n get selectedFile() {\n return this.#selectedFile;\n }\n\n setSelectedFile = (path: string | undefined): void => {\n const prev = this.#selectedFile;\n const next = this.#files.find(file => file.path === path);\n if (prev !== next) {\n this.#selectedFile = next;\n this.#signalUpdate();\n }\n };\n\n get dirty() {\n return this.#files.some(file => file.dirty);\n }\n\n async save(): Promise<void> {\n await Promise.all(this.#files.map(file => file.save()));\n }\n\n async reload(): Promise<void> {\n const selectedPath = this.#selectedFile?.path;\n\n const files = await this.#access.listFiles();\n const fileManagers = await Promise.all(\n files.map(async file => {\n const manager = new DirectoryEditorFileManager(\n file,\n this.#signalUpdate,\n );\n await manager.reload();\n return manager;\n }),\n );\n this.#files.length = 0;\n this.#files.push(...fileManagers);\n\n this.setSelectedFile(selectedPath);\n this.#signalUpdate();\n }\n\n subscribe(listener: () => void): () => void {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n }\n\n #signalUpdate = () => {\n this.#listeners.forEach(listener => listener());\n };\n}\n\nconst DirectoryEditorContext = createContext<DirectoryEditor | undefined>(\n undefined,\n);\n\nexport function useDirectoryEditor(): DirectoryEditor | undefined {\n const value = useContext(DirectoryEditorContext);\n const rerender = useRerender();\n\n useEffect(() => value?.subscribe(rerender), [value, rerender]);\n\n return value;\n}\n\ninterface DirectoryEditorProviderProps {\n directory?: TemplateDirectoryAccess;\n children?: ReactNode;\n}\n\nexport function DirectoryEditorProvider(props: DirectoryEditorProviderProps) {\n const { directory } = props;\n\n const [{ result, error }, { execute }] = useAsync(\n async (dir?: TemplateDirectoryAccess) => {\n if (!dir) {\n return undefined;\n }\n\n const manager = new DirectoryEditorManager(dir);\n await manager.reload();\n\n const firstYaml = manager.files.find(file => file.path.match(/\\.ya?ml$/));\n if (firstYaml) {\n manager.setSelectedFile(firstYaml.path);\n }\n\n return manager;\n },\n );\n\n useEffect(() => {\n execute(directory);\n }, [execute, directory]);\n\n if (error) {\n return <ErrorPanel error={error} />;\n }\n\n return (\n <DirectoryEditorContext.Provider value={result}>\n {props.children}\n </DirectoryEditorContext.Provider>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DirectoryEditorContext.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/DirectoryEditorContext.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 { ErrorPanel } from '@backstage/core-components';\nimport { useAsync, useRerender } from '@react-hookz/web';\nimport { createContext, ReactNode, useContext, useEffect } from 'react';\nimport {\n TemplateDirectoryAccess,\n TemplateFileAccess,\n} from '../../../lib/filesystem';\n\nconst MAX_SIZE = 1024 * 1024;\nconst MAX_SIZE_MESSAGE = 'This file is too large to be displayed';\n\ninterface DirectoryEditorFile {\n /** The path of the file relative to the root directory */\n path: string;\n /** The staged content of the file */\n content: string;\n /** Whether the staged content matches what is on disk */\n dirty: boolean;\n\n /** Update the staged content of the file without saving */\n updateContent(content: string): void;\n /** Save the staged content of the file to disk */\n save(): Promise<void>;\n /** Reload the staged content of the file from disk */\n reload(): Promise<void>;\n}\n\ninterface DirectoryEditor {\n /** A list of all files in the edited directory */\n files: Array<DirectoryEditorFile>;\n\n /** The currently selected file */\n selectedFile: DirectoryEditorFile | undefined;\n /** Switch the selected file */\n setSelectedFile(path: string | undefined): void;\n\n /** Save all files to disk */\n save(): Promise<void>;\n /** Reload all files from disk */\n reload(): Promise<void>;\n\n subscribe(listener: () => void): () => void;\n}\n\nclass DirectoryEditorFileManager implements DirectoryEditorFile {\n readonly #access: TemplateFileAccess;\n readonly #signalUpdate: () => void;\n\n #content?: string;\n #savedContent?: string;\n\n constructor(access: TemplateFileAccess, signalUpdate: () => void) {\n this.#access = access;\n this.#signalUpdate = signalUpdate;\n }\n\n get path() {\n return this.#access.path;\n }\n\n get content() {\n return this.#content ?? MAX_SIZE_MESSAGE;\n }\n\n updateContent(content: string): void {\n if (this.#content === undefined) {\n return;\n }\n this.#content = content;\n this.#signalUpdate();\n }\n\n get dirty() {\n return this.#content !== this.#savedContent;\n }\n\n async save(): Promise<void> {\n if (this.#content !== undefined) {\n await this.#access.save(this.#content);\n this.#savedContent = this.#content;\n this.#signalUpdate();\n }\n }\n\n async reload(): Promise<void> {\n const file = await this.#access.file();\n if (file.size > MAX_SIZE) {\n if (this.#content !== undefined) {\n this.#content = undefined;\n this.#savedContent = undefined;\n this.#signalUpdate();\n }\n return;\n }\n\n const content = await file.text();\n if (this.#content !== content) {\n this.#content = content;\n this.#savedContent = content;\n this.#signalUpdate();\n }\n }\n}\n\nclass DirectoryEditorManager implements DirectoryEditor {\n readonly #access: TemplateDirectoryAccess;\n readonly #listeners = new Set<() => void>();\n\n #files: DirectoryEditorFile[] = [];\n #selectedFile: DirectoryEditorFile | undefined;\n\n constructor(access: TemplateDirectoryAccess) {\n this.#access = access;\n }\n\n get files() {\n return this.#files;\n }\n\n get selectedFile() {\n return this.#selectedFile;\n }\n\n setSelectedFile = (path: string | undefined): void => {\n const prev = this.#selectedFile;\n const next = this.#files.find(file => file.path === path);\n if (prev !== next) {\n this.#selectedFile = next;\n this.#signalUpdate();\n }\n };\n\n get dirty() {\n return this.#files.some(file => file.dirty);\n }\n\n async save(): Promise<void> {\n await Promise.all(this.#files.map(file => file.save()));\n }\n\n async reload(): Promise<void> {\n const selectedPath = this.#selectedFile?.path;\n\n const files = await this.#access.listFiles();\n const fileManagers = await Promise.all(\n files.map(async file => {\n const manager = new DirectoryEditorFileManager(\n file,\n this.#signalUpdate,\n );\n await manager.reload();\n return manager;\n }),\n );\n this.#files.length = 0;\n this.#files.push(...fileManagers);\n\n this.setSelectedFile(selectedPath);\n this.#signalUpdate();\n }\n\n subscribe(listener: () => void): () => void {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n }\n\n #signalUpdate = () => {\n this.#listeners.forEach(listener => listener());\n };\n}\n\nconst DirectoryEditorContext = createContext<DirectoryEditor | undefined>(\n undefined,\n);\n\nexport function useDirectoryEditor(): DirectoryEditor | undefined {\n const value = useContext(DirectoryEditorContext);\n const rerender = useRerender();\n\n useEffect(() => value?.subscribe(rerender), [value, rerender]);\n\n return value;\n}\n\ninterface DirectoryEditorProviderProps {\n directory?: TemplateDirectoryAccess;\n children?: ReactNode;\n}\n\nexport function DirectoryEditorProvider(props: DirectoryEditorProviderProps) {\n const { directory } = props;\n\n const [{ result, error }, { execute }] = useAsync(\n async (dir?: TemplateDirectoryAccess) => {\n if (!dir) {\n return undefined;\n }\n\n const manager = new DirectoryEditorManager(dir);\n await manager.reload();\n\n const firstYaml = manager.files.find(file => file.path.match(/\\.ya?ml$/));\n if (firstYaml) {\n manager.setSelectedFile(firstYaml.path);\n }\n\n return manager;\n },\n );\n\n useEffect(() => {\n execute(directory);\n }, [execute, directory]);\n\n if (error) {\n return <ErrorPanel error={error} />;\n }\n\n return (\n <DirectoryEditorContext.Provider value={result}>\n {props.children}\n </DirectoryEditorContext.Provider>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import yaml from 'yaml';
|
|
3
3
|
import { useApi } from '@backstage/core-plugin-api';
|
|
4
|
-
import {
|
|
4
|
+
import { useState, useRef, useCallback, useMemo, createContext, useContext } from 'react';
|
|
5
5
|
import { scaffolderApiRef, useTemplateSecrets } from '@backstage/plugin-scaffolder-react';
|
|
6
6
|
import { useFormDecorators } from '../../hooks/useFormDecorators.esm.js';
|
|
7
7
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DryRunContext.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/DryRunContext.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 { useApi } from '@backstage/core-plugin-api';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport {\n createContext,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n scaffolderApiRef,\n ScaffolderDryRunResponse,\n useTemplateSecrets,\n} from '@backstage/plugin-scaffolder-react';\nimport { useFormDecorators } from '../../hooks/useFormDecorators';\n\nconst MAX_CONTENT_SIZE = 64 * 1024;\nconst CHUNK_SIZE = 32 * 1024;\n\ninterface DryRunOptions {\n templateContent: string;\n values: JsonObject;\n files: Array<{ path: string; content: string }>;\n}\n\nexport interface DryRunResult extends ScaffolderDryRunResponse {\n id: number;\n}\n\ninterface DryRun {\n results: DryRunResult[];\n selectedResult: DryRunResult | undefined;\n\n selectResult(id: number): void;\n deleteResult(id: number): void;\n execute(options: DryRunOptions): Promise<void>;\n}\n\nconst DryRunContext = createContext<DryRun | undefined>(undefined);\n\ninterface DryRunProviderProps {\n children: ReactNode;\n}\n\nexport function base64EncodeContent(content: string): string {\n if (content.length > MAX_CONTENT_SIZE) {\n return window.btoa('<file too large>');\n }\n\n try {\n return window.btoa(content);\n } catch {\n const decoder = new TextEncoder();\n const buffer = decoder.encode(content);\n\n const chunks = new Array<string>();\n for (let offset = 0; offset < buffer.length; offset += CHUNK_SIZE) {\n chunks.push(\n String.fromCharCode(...buffer.slice(offset, offset + CHUNK_SIZE)),\n );\n }\n return window.btoa(chunks.join(''));\n }\n}\n\nexport function DryRunProvider(props: DryRunProviderProps) {\n const decorators = useFormDecorators();\n const scaffolderApi = useApi(scaffolderApiRef);\n const { secrets: contextSecrets } = useTemplateSecrets();\n const [state, setState] = useState<\n Pick<DryRun, 'results' | 'selectedResult'>\n >({\n results: [],\n selectedResult: undefined,\n });\n const idRef = useRef(1);\n\n const selectResult = useCallback((id: number) => {\n setState(prevState => {\n const result = prevState.results.find(r => r.id === id);\n if (result === prevState.selectedResult) {\n return prevState;\n }\n return {\n results: prevState.results,\n selectedResult: result,\n };\n });\n }, []);\n\n const deleteResult = useCallback((id: number) => {\n setState(prevState => {\n const index = prevState.results.findIndex(r => r.id === id);\n if (index === -1) {\n return prevState;\n }\n const newResults = prevState.results.slice();\n const [deleted] = newResults.splice(index, 1);\n return {\n results: newResults,\n selectedResult:\n prevState.selectedResult?.id === deleted.id\n ? newResults[0]\n : prevState.selectedResult,\n };\n });\n }, []);\n\n const execute = useCallback(\n async (options: DryRunOptions) => {\n if (!scaffolderApi.dryRun) {\n throw new Error('Scaffolder API does not support dry-run');\n }\n\n const parsed = yaml.parse(options.templateContent);\n\n const { formState: values, secrets } = await decorators.run({\n formState: options.values as Record<string, JsonValue>,\n secrets: contextSecrets,\n manifest: parsed?.spec,\n });\n\n const response = await scaffolderApi.dryRun({\n template: parsed,\n values,\n secrets,\n directoryContents: options.files.map(file => ({\n path: file.path,\n base64Content: base64EncodeContent(file.content),\n })),\n });\n\n const result = {\n ...response,\n id: idRef.current++,\n };\n\n setState(prevState => ({\n results: [...prevState.results, result],\n selectedResult: prevState.selectedResult ?? result,\n }));\n },\n [scaffolderApi, decorators, contextSecrets],\n );\n\n const dryRun = useMemo(\n () => ({\n ...state,\n selectResult,\n deleteResult,\n execute,\n }),\n [state, selectResult, deleteResult, execute],\n );\n\n return (\n <DryRunContext.Provider value={dryRun}>\n {props.children}\n </DryRunContext.Provider>\n );\n}\n\nexport function useDryRun(): DryRun {\n const value = useContext(DryRunContext);\n if (!value) {\n throw new Error('must be used within a DryRunProvider');\n }\n return value;\n}\n"],"names":[],"mappings":";;;;;;;AAmCA,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"DryRunContext.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/DryRunContext.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 { useApi } from '@backstage/core-plugin-api';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport {\n createContext,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n scaffolderApiRef,\n ScaffolderDryRunResponse,\n useTemplateSecrets,\n} from '@backstage/plugin-scaffolder-react';\nimport { useFormDecorators } from '../../hooks/useFormDecorators';\n\nconst MAX_CONTENT_SIZE = 64 * 1024;\nconst CHUNK_SIZE = 32 * 1024;\n\ninterface DryRunOptions {\n templateContent: string;\n values: JsonObject;\n files: Array<{ path: string; content: string }>;\n}\n\nexport interface DryRunResult extends ScaffolderDryRunResponse {\n id: number;\n}\n\ninterface DryRun {\n results: DryRunResult[];\n selectedResult: DryRunResult | undefined;\n\n selectResult(id: number): void;\n deleteResult(id: number): void;\n execute(options: DryRunOptions): Promise<void>;\n}\n\nconst DryRunContext = createContext<DryRun | undefined>(undefined);\n\ninterface DryRunProviderProps {\n children: ReactNode;\n}\n\nexport function base64EncodeContent(content: string): string {\n if (content.length > MAX_CONTENT_SIZE) {\n return window.btoa('<file too large>');\n }\n\n try {\n return window.btoa(content);\n } catch {\n const decoder = new TextEncoder();\n const buffer = decoder.encode(content);\n\n const chunks = new Array<string>();\n for (let offset = 0; offset < buffer.length; offset += CHUNK_SIZE) {\n chunks.push(\n String.fromCharCode(...buffer.slice(offset, offset + CHUNK_SIZE)),\n );\n }\n return window.btoa(chunks.join(''));\n }\n}\n\nexport function DryRunProvider(props: DryRunProviderProps) {\n const decorators = useFormDecorators();\n const scaffolderApi = useApi(scaffolderApiRef);\n const { secrets: contextSecrets } = useTemplateSecrets();\n const [state, setState] = useState<\n Pick<DryRun, 'results' | 'selectedResult'>\n >({\n results: [],\n selectedResult: undefined,\n });\n const idRef = useRef(1);\n\n const selectResult = useCallback((id: number) => {\n setState(prevState => {\n const result = prevState.results.find(r => r.id === id);\n if (result === prevState.selectedResult) {\n return prevState;\n }\n return {\n results: prevState.results,\n selectedResult: result,\n };\n });\n }, []);\n\n const deleteResult = useCallback((id: number) => {\n setState(prevState => {\n const index = prevState.results.findIndex(r => r.id === id);\n if (index === -1) {\n return prevState;\n }\n const newResults = prevState.results.slice();\n const [deleted] = newResults.splice(index, 1);\n return {\n results: newResults,\n selectedResult:\n prevState.selectedResult?.id === deleted.id\n ? newResults[0]\n : prevState.selectedResult,\n };\n });\n }, []);\n\n const execute = useCallback(\n async (options: DryRunOptions) => {\n if (!scaffolderApi.dryRun) {\n throw new Error('Scaffolder API does not support dry-run');\n }\n\n const parsed = yaml.parse(options.templateContent);\n\n const { formState: values, secrets } = await decorators.run({\n formState: options.values as Record<string, JsonValue>,\n secrets: contextSecrets,\n manifest: parsed?.spec,\n });\n\n const response = await scaffolderApi.dryRun({\n template: parsed,\n values,\n secrets,\n directoryContents: options.files.map(file => ({\n path: file.path,\n base64Content: base64EncodeContent(file.content),\n })),\n });\n\n const result = {\n ...response,\n id: idRef.current++,\n };\n\n setState(prevState => ({\n results: [...prevState.results, result],\n selectedResult: prevState.selectedResult ?? result,\n }));\n },\n [scaffolderApi, decorators, contextSecrets],\n );\n\n const dryRun = useMemo(\n () => ({\n ...state,\n selectResult,\n deleteResult,\n execute,\n }),\n [state, selectResult, deleteResult, execute],\n );\n\n return (\n <DryRunContext.Provider value={dryRun}>\n {props.children}\n </DryRunContext.Provider>\n );\n}\n\nexport function useDryRun(): DryRun {\n const value = useContext(DryRunContext);\n if (!value) {\n throw new Error('must be used within a DryRunProvider');\n }\n return value;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DryRunResults.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.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 Accordion from '@material-ui/core/Accordion';\nimport AccordionDetails from '@material-ui/core/AccordionDetails';\nimport AccordionSummary from '@material-ui/core/AccordionSummary';\nimport Divider from '@material-ui/core/Divider';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandLess';\nimport { usePrevious } from '@react-hookz/web';\nimport { useEffect, useState } from 'react';\nimport { useDryRun } from '../DryRunContext';\nimport { DryRunResultsList } from './DryRunResultsList';\nimport { DryRunResultsView } from './DryRunResultsView';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../../translation';\n\nconst useStyles = makeStyles(theme => ({\n header: {\n height: 48,\n minHeight: 0,\n '&.Mui-expanded': {\n height: 48,\n minHeight: 0,\n },\n },\n content: {\n display: 'grid',\n background: theme.palette.background.default,\n gridTemplateColumns: '180px auto 1fr',\n gridTemplateRows: '1fr',\n padding: 0,\n height: 400,\n },\n}));\n\nexport function DryRunResults() {\n const classes = useStyles();\n const dryRun = useDryRun();\n const [expanded, setExpanded] = useState(false);\n const [hidden, setHidden] = useState(true);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const resultsLength = dryRun.results.length;\n const prevResultsLength = usePrevious(resultsLength);\n useEffect(() => {\n if (prevResultsLength === 0 && resultsLength === 1) {\n setHidden(false);\n setExpanded(true);\n } else if (prevResultsLength === 1 && resultsLength === 0) {\n setExpanded(false);\n }\n }, [prevResultsLength, resultsLength]);\n\n return (\n <>\n <Accordion\n variant=\"outlined\"\n expanded={expanded}\n hidden={resultsLength === 0 && hidden}\n onChange={(_, exp) => setExpanded(exp)}\n onTransitionEnd={() => resultsLength === 0 && setHidden(true)}\n >\n <AccordionSummary\n className={classes.header}\n expandIcon={<ExpandMoreIcon />}\n >\n <Typography>{t('templateEditorPage.dryRunResults.title')}</Typography>\n </AccordionSummary>\n <Divider orientation=\"horizontal\" />\n <AccordionDetails className={classes.content}>\n <DryRunResultsList />\n <Divider orientation=\"horizontal\" />\n <DryRunResultsView />\n </AccordionDetails>\n </Accordion>\n </>\n );\n}\n"],"names":["ExpandMoreIcon"],"mappings":";;;;;;;;;;;;;;;;AA+BA,MAAM,SAAA,GAAY,WAAW,
|
|
1
|
+
{"version":3,"file":"DryRunResults.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.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 Accordion from '@material-ui/core/Accordion';\nimport AccordionDetails from '@material-ui/core/AccordionDetails';\nimport AccordionSummary from '@material-ui/core/AccordionSummary';\nimport Divider from '@material-ui/core/Divider';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandLess';\nimport { usePrevious } from '@react-hookz/web';\nimport { useEffect, useState } from 'react';\nimport { useDryRun } from '../DryRunContext';\nimport { DryRunResultsList } from './DryRunResultsList';\nimport { DryRunResultsView } from './DryRunResultsView';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../../translation';\n\nconst useStyles = makeStyles(theme => ({\n header: {\n height: 48,\n minHeight: 0,\n '&.Mui-expanded': {\n height: 48,\n minHeight: 0,\n },\n },\n content: {\n display: 'grid',\n background: theme.palette.background.default,\n gridTemplateColumns: '180px auto 1fr',\n gridTemplateRows: '1fr',\n padding: 0,\n height: 400,\n },\n}));\n\nexport function DryRunResults() {\n const classes = useStyles();\n const dryRun = useDryRun();\n const [expanded, setExpanded] = useState(false);\n const [hidden, setHidden] = useState(true);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const resultsLength = dryRun.results.length;\n const prevResultsLength = usePrevious(resultsLength);\n useEffect(() => {\n if (prevResultsLength === 0 && resultsLength === 1) {\n setHidden(false);\n setExpanded(true);\n } else if (prevResultsLength === 1 && resultsLength === 0) {\n setExpanded(false);\n }\n }, [prevResultsLength, resultsLength]);\n\n return (\n <>\n <Accordion\n variant=\"outlined\"\n expanded={expanded}\n hidden={resultsLength === 0 && hidden}\n onChange={(_, exp) => setExpanded(exp)}\n onTransitionEnd={() => resultsLength === 0 && setHidden(true)}\n >\n <AccordionSummary\n className={classes.header}\n expandIcon={<ExpandMoreIcon />}\n >\n <Typography>{t('templateEditorPage.dryRunResults.title')}</Typography>\n </AccordionSummary>\n <Divider orientation=\"horizontal\" />\n <AccordionDetails className={classes.content}>\n <DryRunResultsList />\n <Divider orientation=\"horizontal\" />\n <DryRunResultsView />\n </AccordionDetails>\n </Accordion>\n </>\n );\n}\n"],"names":["ExpandMoreIcon"],"mappings":";;;;;;;;;;;;;;;;AA+BA,MAAM,SAAA,GAAY,WAAW,CAAA,KAAA,MAAU;AAAA,EACrC,MAAA,EAAQ;AAAA,IACN,MAAA,EAAQ,EAAA;AAAA,IACR,SAAA,EAAW,CAAA;AAAA,IACX,gBAAA,EAAkB;AAAA,MAChB,MAAA,EAAQ,EAAA;AAAA,MACR,SAAA,EAAW;AAAA;AACb,GACF;AAAA,EACA,OAAA,EAAS;AAAA,IACP,OAAA,EAAS,MAAA;AAAA,IACT,UAAA,EAAY,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW,OAAA;AAAA,IACrC,mBAAA,EAAqB,gBAAA;AAAA,IACrB,gBAAA,EAAkB,KAAA;AAAA,IAClB,OAAA,EAAS,CAAA;AAAA,IACT,MAAA,EAAQ;AAAA;AAEZ,CAAA,CAAE,CAAA;AAEK,SAAS,aAAA,GAAgB;AAC9B,EAAA,MAAM,UAAU,SAAA,EAAU;AAC1B,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAS,IAAI,CAAA;AACzC,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,wBAAwB,CAAA;AAExD,EAAA,MAAM,aAAA,GAAgB,OAAO,OAAA,CAAQ,MAAA;AACrC,EAAA,MAAM,iBAAA,GAAoB,YAAY,aAAa,CAAA;AACnD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,iBAAA,KAAsB,CAAA,IAAK,aAAA,KAAkB,CAAA,EAAG;AAClD,MAAA,SAAA,CAAU,KAAK,CAAA;AACf,MAAA,WAAA,CAAY,IAAI,CAAA;AAAA,IAClB,CAAA,MAAA,IAAW,iBAAA,KAAsB,CAAA,IAAK,aAAA,KAAkB,CAAA,EAAG;AACzD,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA,IACnB;AAAA,EACF,CAAA,EAAG,CAAC,iBAAA,EAAmB,aAAa,CAAC,CAAA;AAErC,EAAA,uBACE,GAAA,CAAA,QAAA,EAAA,EACE,QAAA,kBAAA,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,UAAA;AAAA,MACR,QAAA;AAAA,MACA,MAAA,EAAQ,kBAAkB,CAAA,IAAK,MAAA;AAAA,MAC/B,QAAA,EAAU,CAAC,CAAA,EAAG,GAAA,KAAQ,YAAY,GAAG,CAAA;AAAA,MACrC,eAAA,EAAiB,MAAM,aAAA,KAAkB,CAAA,IAAK,UAAU,IAAI,CAAA;AAAA,MAE5D,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,gBAAA;AAAA,UAAA;AAAA,YACC,WAAW,OAAA,CAAQ,MAAA;AAAA,YACnB,UAAA,sBAAaA,cAAA,EAAA,EAAe,CAAA;AAAA,YAE5B,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAY,QAAA,EAAA,CAAA,CAAE,wCAAwC,CAAA,EAAE;AAAA;AAAA,SAC3D;AAAA,wBACA,GAAA,CAAC,OAAA,EAAA,EAAQ,WAAA,EAAY,YAAA,EAAa,CAAA;AAAA,wBAClC,IAAA,CAAC,gBAAA,EAAA,EAAiB,SAAA,EAAW,OAAA,CAAQ,OAAA,EACnC,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,iBAAA,EAAA,EAAkB,CAAA;AAAA,0BACnB,GAAA,CAAC,OAAA,EAAA,EAAQ,WAAA,EAAY,YAAA,EAAa,CAAA;AAAA,8BACjC,iBAAA,EAAA,EAAkB;AAAA,SAAA,EACrB;AAAA;AAAA;AAAA,GACF,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DryRunResultsList.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.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 IconButton from '@material-ui/core/IconButton';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport CheckIcon from '@material-ui/icons/Check';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport DownloadIcon from '@material-ui/icons/GetApp';\nimport { useDryRun } from '../DryRunContext';\nimport { downloadBlob } from '../../../../lib/download';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../../translation';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n overflowY: 'auto',\n background: theme.palette.background.default,\n },\n iconSuccess: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.ok,\n },\n iconFailure: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.error,\n },\n}));\n\nexport function DryRunResultsList() {\n const classes = useStyles();\n const dryRun = useDryRun();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <List className={classes.root} dense>\n {dryRun.results.map(result => {\n const failed = result.log.some(l => l.body.status === 'failed');\n let isLoading = false;\n\n async function downloadResult() {\n isLoading = true;\n await downloadDirectoryContents(\n result.directoryContents,\n `dry-run-result-${result.id}.zip`,\n );\n isLoading = false;\n }\n\n return (\n <ListItem\n button\n key={result.id}\n selected={dryRun.selectedResult?.id === result.id}\n onClick={() => dryRun.selectResult(result.id)}\n >\n <ListItemIcon\n className={failed ? classes.iconFailure : classes.iconSuccess}\n >\n {failed ? <CancelIcon /> : <CheckIcon />}\n </ListItemIcon>\n <ListItemText\n primary={t('templateEditorPage.dryRunResultsList.title', {\n resultId: `${result.id}`,\n })}\n />\n <ListItemSecondaryAction>\n <IconButton\n edge=\"end\"\n aria-label=\"download\"\n title={t(\n 'templateEditorPage.dryRunResultsList.downloadButtonTitle',\n )}\n disabled={isLoading}\n onClick={() => downloadResult()}\n >\n <DownloadIcon />\n </IconButton>\n <IconButton\n edge=\"end\"\n aria-label=\"delete\"\n title={t(\n 'templateEditorPage.dryRunResultsList.deleteButtonTitle',\n )}\n onClick={() => dryRun.deleteResult(result.id)}\n >\n <DeleteIcon />\n </IconButton>\n </ListItemSecondaryAction>\n </ListItem>\n );\n })}\n </List>\n );\n}\n\nasync function downloadDirectoryContents(\n directoryContents: {\n path: string;\n base64Content: string;\n executable?: boolean;\n }[],\n name: string,\n) {\n const { default: JSZip } = await import('jszip');\n const zip = new JSZip();\n\n for (const d of directoryContents) {\n // Decode text content from base64 to ascii\n const converted = atob(d.base64Content);\n\n // add folder/file to zip\n await zip.file(d.path, converted);\n }\n\n const blob = await zip.generateAsync({ type: 'blob' });\n downloadBlob(blob, name);\n}\n"],"names":["CancelIcon"],"mappings":";;;;;;;;;;;;;;;;;AAgCA,MAAM,SAAA,GAAY,WAAW,
|
|
1
|
+
{"version":3,"file":"DryRunResultsList.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.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 IconButton from '@material-ui/core/IconButton';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport CheckIcon from '@material-ui/icons/Check';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport DownloadIcon from '@material-ui/icons/GetApp';\nimport { useDryRun } from '../DryRunContext';\nimport { downloadBlob } from '../../../../lib/download';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../../translation';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n overflowY: 'auto',\n background: theme.palette.background.default,\n },\n iconSuccess: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.ok,\n },\n iconFailure: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.error,\n },\n}));\n\nexport function DryRunResultsList() {\n const classes = useStyles();\n const dryRun = useDryRun();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <List className={classes.root} dense>\n {dryRun.results.map(result => {\n const failed = result.log.some(l => l.body.status === 'failed');\n let isLoading = false;\n\n async function downloadResult() {\n isLoading = true;\n await downloadDirectoryContents(\n result.directoryContents,\n `dry-run-result-${result.id}.zip`,\n );\n isLoading = false;\n }\n\n return (\n <ListItem\n button\n key={result.id}\n selected={dryRun.selectedResult?.id === result.id}\n onClick={() => dryRun.selectResult(result.id)}\n >\n <ListItemIcon\n className={failed ? classes.iconFailure : classes.iconSuccess}\n >\n {failed ? <CancelIcon /> : <CheckIcon />}\n </ListItemIcon>\n <ListItemText\n primary={t('templateEditorPage.dryRunResultsList.title', {\n resultId: `${result.id}`,\n })}\n />\n <ListItemSecondaryAction>\n <IconButton\n edge=\"end\"\n aria-label=\"download\"\n title={t(\n 'templateEditorPage.dryRunResultsList.downloadButtonTitle',\n )}\n disabled={isLoading}\n onClick={() => downloadResult()}\n >\n <DownloadIcon />\n </IconButton>\n <IconButton\n edge=\"end\"\n aria-label=\"delete\"\n title={t(\n 'templateEditorPage.dryRunResultsList.deleteButtonTitle',\n )}\n onClick={() => dryRun.deleteResult(result.id)}\n >\n <DeleteIcon />\n </IconButton>\n </ListItemSecondaryAction>\n </ListItem>\n );\n })}\n </List>\n );\n}\n\nasync function downloadDirectoryContents(\n directoryContents: {\n path: string;\n base64Content: string;\n executable?: boolean;\n }[],\n name: string,\n) {\n const { default: JSZip } = await import('jszip');\n const zip = new JSZip();\n\n for (const d of directoryContents) {\n // Decode text content from base64 to ascii\n const converted = atob(d.base64Content);\n\n // add folder/file to zip\n await zip.file(d.path, converted);\n }\n\n const blob = await zip.generateAsync({ type: 'blob' });\n downloadBlob(blob, name);\n}\n"],"names":["CancelIcon"],"mappings":";;;;;;;;;;;;;;;;;AAgCA,MAAM,SAAA,GAAY,WAAW,CAAA,KAAA,MAAU;AAAA,EACrC,IAAA,EAAM;AAAA,IACJ,SAAA,EAAW,MAAA;AAAA,IACX,UAAA,EAAY,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW;AAAA,GACvC;AAAA,EACA,WAAA,EAAa;AAAA,IACX,QAAA,EAAU,CAAA;AAAA,IACV,WAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC5B,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO;AAAA,GAC9B;AAAA,EACA,WAAA,EAAa;AAAA,IACX,QAAA,EAAU,CAAA;AAAA,IACV,WAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC5B,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO;AAAA;AAEhC,CAAA,CAAE,CAAA;AAEK,SAAS,iBAAA,GAAoB;AAClC,EAAA,MAAM,UAAU,SAAA,EAAU;AAC1B,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,wBAAwB,CAAA;AAExD,EAAA,uBACE,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAW,OAAA,CAAQ,IAAA,EAAM,OAAK,IAAA,EACjC,QAAA,EAAA,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,CAAA,MAAA,KAAU;AAC5B,IAAA,MAAM,MAAA,GAAS,OAAO,GAAA,CAAI,IAAA,CAAK,OAAK,CAAA,CAAE,IAAA,CAAK,WAAW,QAAQ,CAAA;AAC9D,IAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,IAAA,eAAe,cAAA,GAAiB;AAC9B,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,MAAM,yBAAA;AAAA,QACJ,MAAA,CAAO,iBAAA;AAAA,QACP,CAAA,eAAA,EAAkB,OAAO,EAAE,CAAA,IAAA;AAAA,OAC7B;AACA,MAAA,SAAA,GAAY,KAAA;AAAA,IACd;AAEA,IAAA,uBACE,IAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAM,IAAA;AAAA,QAEN,QAAA,EAAU,MAAA,CAAO,cAAA,EAAgB,EAAA,KAAO,MAAA,CAAO,EAAA;AAAA,QAC/C,OAAA,EAAS,MAAM,MAAA,CAAO,YAAA,CAAa,OAAO,EAAE,CAAA;AAAA,QAE5C,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,YAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,MAAA,GAAS,OAAA,CAAQ,WAAA,GAAc,OAAA,CAAQ,WAAA;AAAA,cAEjD,QAAA,EAAA,MAAA,mBAAS,GAAA,CAACA,MAAA,EAAA,EAAW,CAAA,uBAAM,SAAA,EAAA,EAAU;AAAA;AAAA,WACxC;AAAA,0BACA,GAAA;AAAA,YAAC,YAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,EAAE,4CAAA,EAA8C;AAAA,gBACvD,QAAA,EAAU,CAAA,EAAG,MAAA,CAAO,EAAE,CAAA;AAAA,eACvB;AAAA;AAAA,WACH;AAAA,+BACC,uBAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,UAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,KAAA;AAAA,gBACL,YAAA,EAAW,UAAA;AAAA,gBACX,KAAA,EAAO,CAAA;AAAA,kBACL;AAAA,iBACF;AAAA,gBACA,QAAA,EAAU,SAAA;AAAA,gBACV,OAAA,EAAS,MAAM,cAAA,EAAe;AAAA,gBAE9B,8BAAC,YAAA,EAAA,EAAa;AAAA;AAAA,aAChB;AAAA,4BACA,GAAA;AAAA,cAAC,UAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,KAAA;AAAA,gBACL,YAAA,EAAW,QAAA;AAAA,gBACX,KAAA,EAAO,CAAA;AAAA,kBACL;AAAA,iBACF;AAAA,gBACA,OAAA,EAAS,MAAM,MAAA,CAAO,YAAA,CAAa,OAAO,EAAE,CAAA;AAAA,gBAE5C,8BAAC,UAAA,EAAA,EAAW;AAAA;AAAA;AACd,WAAA,EACF;AAAA;AAAA,OAAA;AAAA,MApCK,MAAA,CAAO;AAAA,KAqCd;AAAA,EAEJ,CAAC,CAAA,EACH,CAAA;AAEJ;AAEA,eAAe,yBAAA,CACb,mBAKA,IAAA,EACA;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,MAAM,OAAO,OAAO,CAAA;AAC/C,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,EAAM;AAEtB,EAAA,KAAA,MAAW,KAAK,iBAAA,EAAmB;AAEjC,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,CAAA,CAAE,aAAa,CAAA;AAGtC,IAAA,MAAM,GAAA,CAAI,IAAA,CAAK,CAAA,CAAE,IAAA,EAAM,SAAS,CAAA;AAAA,EAClC;AAEA,EAAA,MAAM,OAAO,MAAM,GAAA,CAAI,cAAc,EAAE,IAAA,EAAM,QAAQ,CAAA;AACrD,EAAA,YAAA,CAAa,MAAM,IAAI,CAAA;AACzB;;;;"}
|
package/dist/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DryRunResultsSplitView.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.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 { makeStyles } from '@material-ui/core/styles';\nimport Divider from '@material-ui/core/Divider';\nimport { Children, ReactNode } from 'react';\nimport classNames from 'classnames';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n display: 'grid',\n gridTemplateColumns: '280px auto 3fr',\n gridTemplateRows: '1fr',\n },\n child: {\n overflowY: 'auto',\n height: '100%',\n minHeight: 0,\n },\n firstChild: {\n background: theme.palette.background.paper,\n },\n}));\n\nexport function DryRunResultsSplitView(props: { children: ReactNode }) {\n const classes = useStyles();\n const childArray = Children.toArray(props.children);\n\n if (childArray.length !== 2) {\n throw new Error('must have exactly 2 children');\n }\n\n return (\n <div className={classes.root}>\n <div className={classNames(classes.child, classes.firstChild)}>\n {childArray[0]}\n </div>\n <Divider orientation=\"horizontal\" />\n <div className={classes.child}>{childArray[1]}</div>\n </div>\n );\n}\n"],"names":[],"mappings":";;;;;;AAqBA,MAAM,SAAA,GAAY,WAAW,
|
|
1
|
+
{"version":3,"file":"DryRunResultsSplitView.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.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 { makeStyles } from '@material-ui/core/styles';\nimport Divider from '@material-ui/core/Divider';\nimport { Children, ReactNode } from 'react';\nimport classNames from 'classnames';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n display: 'grid',\n gridTemplateColumns: '280px auto 3fr',\n gridTemplateRows: '1fr',\n },\n child: {\n overflowY: 'auto',\n height: '100%',\n minHeight: 0,\n },\n firstChild: {\n background: theme.palette.background.paper,\n },\n}));\n\nexport function DryRunResultsSplitView(props: { children: ReactNode }) {\n const classes = useStyles();\n const childArray = Children.toArray(props.children);\n\n if (childArray.length !== 2) {\n throw new Error('must have exactly 2 children');\n }\n\n return (\n <div className={classes.root}>\n <div className={classNames(classes.child, classes.firstChild)}>\n {childArray[0]}\n </div>\n <Divider orientation=\"horizontal\" />\n <div className={classes.child}>{childArray[1]}</div>\n </div>\n );\n}\n"],"names":[],"mappings":";;;;;;AAqBA,MAAM,SAAA,GAAY,WAAW,CAAA,KAAA,MAAU;AAAA,EACrC,IAAA,EAAM;AAAA,IACJ,OAAA,EAAS,MAAA;AAAA,IACT,mBAAA,EAAqB,gBAAA;AAAA,IACrB,gBAAA,EAAkB;AAAA,GACpB;AAAA,EACA,KAAA,EAAO;AAAA,IACL,SAAA,EAAW,MAAA;AAAA,IACX,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW;AAAA,GACb;AAAA,EACA,UAAA,EAAY;AAAA,IACV,UAAA,EAAY,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW;AAAA;AAEzC,CAAA,CAAE,CAAA;AAEK,SAAS,uBAAuB,KAAA,EAAgC;AACrE,EAAA,MAAM,UAAU,SAAA,EAAU;AAC1B,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,OAAA,CAAQ,KAAA,CAAM,QAAQ,CAAA;AAElD,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAAA,EAChD;AAEA,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,IAAA,EACtB,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,UAAA,CAAW,OAAA,CAAQ,KAAA,EAAO,QAAQ,UAAU,CAAA,EACzD,QAAA,EAAA,UAAA,CAAW,CAAC,CAAA,EACf,CAAA;AAAA,oBACA,GAAA,CAAC,OAAA,EAAA,EAAQ,WAAA,EAAY,YAAA,EAAa,CAAA;AAAA,wBACjC,KAAA,EAAA,EAAI,SAAA,EAAW,QAAQ,KAAA,EAAQ,QAAA,EAAA,UAAA,CAAW,CAAC,CAAA,EAAE;AAAA,GAAA,EAChD,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DryRunResultsView.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.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 { LogViewer } from '@backstage/core-components';\nimport { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\nimport Box from '@material-ui/core/Box';\nimport Divider from '@material-ui/core/Divider';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Tab from '@material-ui/core/Tab';\nimport Tabs from '@material-ui/core/Tabs';\nimport CodeMirror from '@uiw/react-codemirror';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useDryRun } from '../DryRunContext';\nimport { DryRunResultsSplitView } from './DryRunResultsSplitView';\nimport { FileBrowser } from '../../../../components/FileBrowser';\nimport { TaskPageLinks } from './TaskPageLinks';\nimport { TaskStatusStepper } from './TaskStatusStepper';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../../translation';\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexFlow: 'column nowrap',\n },\n contentWrapper: {\n flex: 1,\n position: 'relative',\n },\n content: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n\n display: 'flex',\n '& > *': {\n flex: 1,\n },\n },\n codeMirror: {\n height: '100%',\n overflowY: 'auto',\n },\n});\n\nfunction FilesContent() {\n const classes = useStyles();\n const { selectedResult } = useDryRun();\n const [selectedPath, setSelectedPath] = useState<string>('');\n const selectedFile = selectedResult?.directoryContents.find(\n f => f.path === selectedPath,\n );\n\n useEffect(() => {\n if (selectedResult) {\n const [firstFile] = selectedResult.directoryContents;\n if (firstFile) {\n setSelectedPath(firstFile.path);\n } else {\n setSelectedPath('');\n }\n }\n return undefined;\n }, [selectedResult]);\n\n if (!selectedResult) {\n return null;\n }\n return (\n <DryRunResultsSplitView>\n <FileBrowser\n selected={selectedPath}\n onSelect={setSelectedPath}\n filePaths={selectedResult.directoryContents.map(file => file.path)}\n />\n <CodeMirror\n className={classes.codeMirror}\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n readOnly\n value={\n selectedFile?.base64Content ? atob(selectedFile.base64Content) : ''\n }\n />\n </DryRunResultsSplitView>\n );\n}\nfunction LogContent() {\n const { selectedResult } = useDryRun();\n const [currentStepId, setUserSelectedStepId] = useState<string>();\n\n const steps = useMemo(() => {\n if (!selectedResult) {\n return [];\n }\n return (\n selectedResult.steps.map(step => {\n const stepLog = selectedResult.log.filter(\n l => l.body.stepId === step.id,\n );\n return {\n id: step.id,\n name: step.name,\n logString: stepLog.map(l => l.body.message).join('\\n'),\n status: stepLog[stepLog.length - 1]?.body.status ?? 'completed',\n };\n }) ?? []\n );\n }, [selectedResult]);\n\n if (!selectedResult) {\n return null;\n }\n\n const selectedStep = steps.find(s => s.id === currentStepId) ?? steps[0];\n\n return (\n <DryRunResultsSplitView>\n <TaskStatusStepper\n steps={steps}\n currentStepId={selectedStep.id}\n onUserStepChange={setUserSelectedStepId}\n />\n <LogViewer text={selectedStep?.logString ?? ''} />\n </DryRunResultsSplitView>\n );\n}\n\nfunction OutputContent() {\n const classes = useStyles();\n const { selectedResult } = useDryRun();\n\n if (!selectedResult) {\n return null;\n }\n\n return (\n <DryRunResultsSplitView>\n <Box pt={2}>\n {selectedResult.output?.links?.length && (\n <TaskPageLinks output={selectedResult.output} />\n )}\n </Box>\n <CodeMirror\n className={classes.codeMirror}\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n readOnly\n value={JSON.stringify(selectedResult.output, null, 2)}\n />\n </DryRunResultsSplitView>\n );\n}\n\nexport function DryRunResultsView() {\n const classes = useStyles();\n const [selectedTab, setSelectedTab] = useState<'files' | 'log' | 'output'>(\n 'files',\n );\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <div className={classes.root}>\n <Tabs value={selectedTab} onChange={(_, v) => setSelectedTab(v)}>\n <Tab\n value=\"files\"\n label={t('templateEditorPage.dryRunResultsView.tab.files')}\n />\n <Tab\n value=\"log\"\n label={t('templateEditorPage.dryRunResultsView.tab.log')}\n />\n <Tab\n value=\"output\"\n label={t('templateEditorPage.dryRunResultsView.tab.output')}\n />\n </Tabs>\n <Divider />\n\n <div className={classes.contentWrapper}>\n <div className={classes.content}>\n {selectedTab === 'files' && <FilesContent />}\n {selectedTab === 'log' && <LogContent />}\n {selectedTab === 'output' && <OutputContent />}\n </div>\n </div>\n </div>\n );\n}\n"],"names":["yamlSupport"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DryRunResultsView.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.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 { LogViewer } from '@backstage/core-components';\nimport { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\nimport Box from '@material-ui/core/Box';\nimport Divider from '@material-ui/core/Divider';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Tab from '@material-ui/core/Tab';\nimport Tabs from '@material-ui/core/Tabs';\nimport CodeMirror from '@uiw/react-codemirror';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useDryRun } from '../DryRunContext';\nimport { DryRunResultsSplitView } from './DryRunResultsSplitView';\nimport { FileBrowser } from '../../../../components/FileBrowser';\nimport { TaskPageLinks } from './TaskPageLinks';\nimport { TaskStatusStepper } from './TaskStatusStepper';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../../translation';\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexFlow: 'column nowrap',\n },\n contentWrapper: {\n flex: 1,\n position: 'relative',\n },\n content: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n\n display: 'flex',\n '& > *': {\n flex: 1,\n },\n },\n codeMirror: {\n height: '100%',\n overflowY: 'auto',\n },\n});\n\nfunction FilesContent() {\n const classes = useStyles();\n const { selectedResult } = useDryRun();\n const [selectedPath, setSelectedPath] = useState<string>('');\n const selectedFile = selectedResult?.directoryContents.find(\n f => f.path === selectedPath,\n );\n\n useEffect(() => {\n if (selectedResult) {\n const [firstFile] = selectedResult.directoryContents;\n if (firstFile) {\n setSelectedPath(firstFile.path);\n } else {\n setSelectedPath('');\n }\n }\n return undefined;\n }, [selectedResult]);\n\n if (!selectedResult) {\n return null;\n }\n return (\n <DryRunResultsSplitView>\n <FileBrowser\n selected={selectedPath}\n onSelect={setSelectedPath}\n filePaths={selectedResult.directoryContents.map(file => file.path)}\n />\n <CodeMirror\n className={classes.codeMirror}\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n readOnly\n value={\n selectedFile?.base64Content ? atob(selectedFile.base64Content) : ''\n }\n />\n </DryRunResultsSplitView>\n );\n}\nfunction LogContent() {\n const { selectedResult } = useDryRun();\n const [currentStepId, setUserSelectedStepId] = useState<string>();\n\n const steps = useMemo(() => {\n if (!selectedResult) {\n return [];\n }\n return (\n selectedResult.steps.map(step => {\n const stepLog = selectedResult.log.filter(\n l => l.body.stepId === step.id,\n );\n return {\n id: step.id,\n name: step.name,\n logString: stepLog.map(l => l.body.message).join('\\n'),\n status: stepLog[stepLog.length - 1]?.body.status ?? 'completed',\n };\n }) ?? []\n );\n }, [selectedResult]);\n\n if (!selectedResult) {\n return null;\n }\n\n const selectedStep = steps.find(s => s.id === currentStepId) ?? steps[0];\n\n return (\n <DryRunResultsSplitView>\n <TaskStatusStepper\n steps={steps}\n currentStepId={selectedStep.id}\n onUserStepChange={setUserSelectedStepId}\n />\n <LogViewer text={selectedStep?.logString ?? ''} />\n </DryRunResultsSplitView>\n );\n}\n\nfunction OutputContent() {\n const classes = useStyles();\n const { selectedResult } = useDryRun();\n\n if (!selectedResult) {\n return null;\n }\n\n return (\n <DryRunResultsSplitView>\n <Box pt={2}>\n {selectedResult.output?.links?.length && (\n <TaskPageLinks output={selectedResult.output} />\n )}\n </Box>\n <CodeMirror\n className={classes.codeMirror}\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n readOnly\n value={JSON.stringify(selectedResult.output, null, 2)}\n />\n </DryRunResultsSplitView>\n );\n}\n\nexport function DryRunResultsView() {\n const classes = useStyles();\n const [selectedTab, setSelectedTab] = useState<'files' | 'log' | 'output'>(\n 'files',\n );\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <div className={classes.root}>\n <Tabs value={selectedTab} onChange={(_, v) => setSelectedTab(v)}>\n <Tab\n value=\"files\"\n label={t('templateEditorPage.dryRunResultsView.tab.files')}\n />\n <Tab\n value=\"log\"\n label={t('templateEditorPage.dryRunResultsView.tab.log')}\n />\n <Tab\n value=\"output\"\n label={t('templateEditorPage.dryRunResultsView.tab.output')}\n />\n </Tabs>\n <Divider />\n\n <div className={classes.contentWrapper}>\n <div className={classes.content}>\n {selectedTab === 'files' && <FilesContent />}\n {selectedTab === 'log' && <LogContent />}\n {selectedTab === 'output' && <OutputContent />}\n </div>\n </div>\n </div>\n );\n}\n"],"names":["yamlSupport"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconLink.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/IconLink.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport Grid from '@material-ui/core/Grid';\nimport { LinkProps } from '@material-ui/core/Link';\nimport LanguageIcon from '@material-ui/icons/Language';\n\nimport { IconComponent } from '@backstage/core-plugin-api';\nimport { Link } from '@backstage/core-components';\n\nconst useStyles = makeStyles({\n svgIcon: {\n display: 'inline-block',\n '& svg': {\n display: 'inline-block',\n fontSize: 'inherit',\n verticalAlign: 'baseline',\n },\n },\n});\n\nexport const IconLink = (\n props: {\n href: string;\n text?: string;\n Icon?: IconComponent;\n } & LinkProps,\n) => {\n const { href, text, Icon, ...linkProps } = props;\n\n const classes = useStyles();\n\n return (\n <Grid container direction=\"row\" spacing={1}>\n <Grid item>\n <Typography component=\"div\" className={classes.svgIcon}>\n {Icon ? <Icon /> : <LanguageIcon />}\n </Typography>\n </Grid>\n <Grid item>\n <Link to={href} {...linkProps}>\n {text || href}\n </Link>\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAwBA,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"IconLink.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/IconLink.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport Grid from '@material-ui/core/Grid';\nimport { LinkProps } from '@material-ui/core/Link';\nimport LanguageIcon from '@material-ui/icons/Language';\n\nimport { IconComponent } from '@backstage/core-plugin-api';\nimport { Link } from '@backstage/core-components';\n\nconst useStyles = makeStyles({\n svgIcon: {\n display: 'inline-block',\n '& svg': {\n display: 'inline-block',\n fontSize: 'inherit',\n verticalAlign: 'baseline',\n },\n },\n});\n\nexport const IconLink = (\n props: {\n href: string;\n text?: string;\n Icon?: IconComponent;\n } & LinkProps,\n) => {\n const { href, text, Icon, ...linkProps } = props;\n\n const classes = useStyles();\n\n return (\n <Grid container direction=\"row\" spacing={1}>\n <Grid item>\n <Typography component=\"div\" className={classes.svgIcon}>\n {Icon ? <Icon /> : <LanguageIcon />}\n </Typography>\n </Grid>\n <Grid item>\n <Link to={href} {...linkProps}>\n {text || href}\n </Link>\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAwBA,MAAM,YAAY,UAAA,CAAW;AAAA,EAC3B,OAAA,EAAS;AAAA,IACP,OAAA,EAAS,cAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,OAAA,EAAS,cAAA;AAAA,MACT,QAAA,EAAU,SAAA;AAAA,MACV,aAAA,EAAe;AAAA;AACjB;AAEJ,CAAC,CAAA;AAEM,MAAM,QAAA,GAAW,CACtB,KAAA,KAKG;AACH,EAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,GAAG,WAAU,GAAI,KAAA;AAE3C,EAAA,MAAM,UAAU,SAAA,EAAU;AAE1B,EAAA,4BACG,IAAA,EAAA,EAAK,SAAA,EAAS,MAAC,SAAA,EAAU,KAAA,EAAM,SAAS,CAAA,EACvC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,QAAK,IAAA,EAAI,IAAA,EACR,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,WAAU,KAAA,EAAM,SAAA,EAAW,OAAA,CAAQ,OAAA,EAC5C,iCAAO,GAAA,CAAC,IAAA,EAAA,EAAK,oBAAK,GAAA,CAAC,YAAA,EAAA,EAAa,GACnC,CAAA,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EACR,QAAA,kBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAI,IAAA,EAAO,GAAG,SAAA,EACjB,QAAA,EAAA,IAAA,IAAQ,IAAA,EACX,CAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskPageLinks.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport Box from '@material-ui/core/Box';\nimport LanguageIcon from '@material-ui/icons/Language';\nimport { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react';\nimport { IconLink } from './IconLink';\nimport { IconComponent, useApp, useRouteRef } from '@backstage/core-plugin-api';\n\ntype TaskPageLinksProps = {\n output: ScaffolderTaskOutput;\n};\n\nexport const TaskPageLinks = ({ output }: TaskPageLinksProps) => {\n const { links = [] } = output;\n const app = useApp();\n const entityRoute = useRouteRef(entityRouteRef);\n\n const iconResolver = (key?: string): IconComponent =>\n key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon;\n\n return (\n <Box px={3} pb={3}>\n {links\n .filter(({ url, entityRef }) => url || entityRef)\n .map(({ url, entityRef, title, icon }) => {\n if (entityRef) {\n const entityName = parseEntityRef(entityRef, {\n defaultKind: '<unknown>',\n defaultNamespace: '<unknown>',\n });\n const target = entityRoute(entityName);\n return { title, icon, url: target };\n }\n return { title, icon, url: url! };\n })\n .map(({ url, title, icon }, i) => (\n <IconLink\n key={`output-link-${i}`}\n href={url}\n text={title ?? url}\n Icon={iconResolver(icon)}\n target=\"_blank\"\n />\n ))}\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AA4BO,MAAM,
|
|
1
|
+
{"version":3,"file":"TaskPageLinks.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport Box from '@material-ui/core/Box';\nimport LanguageIcon from '@material-ui/icons/Language';\nimport { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react';\nimport { IconLink } from './IconLink';\nimport { IconComponent, useApp, useRouteRef } from '@backstage/core-plugin-api';\n\ntype TaskPageLinksProps = {\n output: ScaffolderTaskOutput;\n};\n\nexport const TaskPageLinks = ({ output }: TaskPageLinksProps) => {\n const { links = [] } = output;\n const app = useApp();\n const entityRoute = useRouteRef(entityRouteRef);\n\n const iconResolver = (key?: string): IconComponent =>\n key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon;\n\n return (\n <Box px={3} pb={3}>\n {links\n .filter(({ url, entityRef }) => url || entityRef)\n .map(({ url, entityRef, title, icon }) => {\n if (entityRef) {\n const entityName = parseEntityRef(entityRef, {\n defaultKind: '<unknown>',\n defaultNamespace: '<unknown>',\n });\n const target = entityRoute(entityName);\n return { title, icon, url: target };\n }\n return { title, icon, url: url! };\n })\n .map(({ url, title, icon }, i) => (\n <IconLink\n key={`output-link-${i}`}\n href={url}\n text={title ?? url}\n Icon={iconResolver(icon)}\n target=\"_blank\"\n />\n ))}\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AA4BO,MAAM,aAAA,GAAgB,CAAC,EAAE,MAAA,EAAO,KAA0B;AAC/D,EAAA,MAAM,EAAE,KAAA,GAAQ,EAAC,EAAE,GAAI,MAAA;AACvB,EAAA,MAAM,MAAM,MAAA,EAAO;AACnB,EAAA,MAAM,WAAA,GAAc,YAAY,cAAc,CAAA;AAE9C,EAAA,MAAM,YAAA,GAAe,CAAC,GAAA,KACpB,GAAA,GAAM,IAAI,aAAA,CAAc,GAAG,KAAK,YAAA,GAAe,YAAA;AAEjD,EAAA,uBACE,GAAA,CAAC,OAAI,EAAA,EAAI,CAAA,EAAG,IAAI,CAAA,EACb,QAAA,EAAA,KAAA,CACE,MAAA,CAAO,CAAC,EAAE,GAAA,EAAK,WAAU,KAAM,GAAA,IAAO,SAAS,CAAA,CAC/C,GAAA,CAAI,CAAC,EAAE,GAAA,EAAK,SAAA,EAAW,KAAA,EAAO,IAAA,EAAK,KAAM;AACxC,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,MAAM,UAAA,GAAa,eAAe,SAAA,EAAW;AAAA,QAC3C,WAAA,EAAa,WAAA;AAAA,QACb,gBAAA,EAAkB;AAAA,OACnB,CAAA;AACD,MAAA,MAAM,MAAA,GAAS,YAAY,UAAU,CAAA;AACrC,MAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,GAAA,EAAK,MAAA,EAAO;AAAA,IACpC;AACA,IAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,GAAA,EAAU;AAAA,EAClC,CAAC,EACA,GAAA,CAAI,CAAC,EAAE,GAAA,EAAK,KAAA,EAAO,IAAA,EAAK,EAAG,CAAA,qBAC1B,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MAEC,IAAA,EAAM,GAAA;AAAA,MACN,MAAM,KAAA,IAAS,GAAA;AAAA,MACf,IAAA,EAAM,aAAa,IAAI,CAAA;AAAA,MACvB,MAAA,EAAO;AAAA,KAAA;AAAA,IAJF,eAAe,CAAC,CAAA;AAAA,GAMxB,CAAA,EACL,CAAA;AAEJ;;;;"}
|