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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @backstage/plugin-scaffolder
2
2
 
3
+ ## 1.36.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 297302e: Fixed the NFS custom field explorer so loaded form fields render field options and previews correctly.
8
+ - 864a799: Fix the display of the description in `GitlabRepoPicker`:
9
+
10
+ - Move `owner.description` helper text outside the `allowedOwners` conditional so it renders for both `Select` and `Autocomplete` modes.
11
+ - Update the `Autocomplete` label to use `fields.gitlabRepoPicker.owner.inputTitle` instead of `fields.gitlabRepoPicker.owner.title`.
12
+
13
+ - e5af44c: Replaced deprecated `humanizeEntityRef` usage with the Catalog Presentation API.
14
+ - 5d8112e: Migrated the actions page to use `@backstage/ui` list and search components. Actions are now presented in a sidebar list with a separate detail panel for the selected action, along with built-in search filtering. The selected action is also reflected in the URL hash, allowing deep-linking to a specific action.
15
+ - 4cc9af2: Fixed the layout of the scaffolder plugin in the new frontend system to use the new page layout.
16
+ - a7a14b7: Removed custom `IterableDirectoryHandle` and `WritableFileHandle` types in favor of the standard DOM `FileSystemDirectoryHandle` and `FileSystemFileHandle` types, which are now available through the `DOM.AsyncIterable` lib added to the shared TypeScript configuration.
17
+ - Updated dependencies
18
+ - @backstage/ui@0.14.0
19
+ - @backstage/errors@1.3.0
20
+ - @backstage/catalog-model@1.8.0
21
+ - @backstage/plugin-catalog-react@2.1.2
22
+ - @backstage/frontend-plugin-api@0.16.0
23
+ - @backstage/core-components@0.18.9
24
+ - @backstage/plugin-scaffolder-react@1.20.1
25
+ - @backstage/catalog-client@1.15.0
26
+ - @backstage/plugin-scaffolder-common@2.1.0
27
+ - @backstage/plugin-permission-react@0.5.0
28
+ - @backstage/integration@2.0.1
29
+ - @backstage/core-plugin-api@1.12.5
30
+ - @backstage/integration-react@1.2.17
31
+ - @backstage/plugin-catalog-common@1.1.9
32
+ - @backstage/plugin-techdocs-react@1.3.10
33
+
3
34
  ## 1.36.2-next.2
4
35
 
5
36
  ### Patch Changes
@@ -1,16 +1,23 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { useCallback } from 'react';
2
+ import { useAsync, useMountEffect } from '@react-hookz/web';
3
+ import { useMemo, useCallback } from 'react';
3
4
  import { Routes, Route, useNavigate } from 'react-router-dom';
4
5
  import { Content } from '@backstage/core-components';
6
+ import { useApi } from '@backstage/core-plugin-api';
5
7
  import { makeStyles } from '@material-ui/core/styles';
6
8
  import { RequirePermission } from '@backstage/plugin-permission-react';
7
9
  import { templateManagementPermission } from '@backstage/plugin-scaffolder-common/alpha';
8
10
  import { SecretsContextProvider } from '@backstage/plugin-scaffolder-react';
11
+ import { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../../extensions/default.esm.js';
12
+ import '../formFieldsApi.esm.js';
9
13
  import { TemplateEditorIntro } from './TemplateEditorPage/TemplateEditorIntro.esm.js';
10
14
  import { TemplateEditor } from './TemplateEditorPage/TemplateEditor.esm.js';
11
15
  import { TemplateFormPreviewer } from './TemplateEditorPage/TemplateFormPreviewer.esm.js';
12
16
  import { CustomFieldExplorer } from './TemplateEditorPage/CustomFieldExplorer.esm.js';
13
17
  import { useTemplateDirectory } from './TemplateEditorPage/useTemplateDirectory.esm.js';
18
+ import { OpaqueFormField } from '../../packages/scaffolder-internal/src/wiring/InternalFormField.esm.js';
19
+ import '../../packages/scaffolder-internal/src/wiring/InternalFormDecorator.esm.js';
20
+ import { formFieldsApiRef } from '@backstage/plugin-scaffolder-react/alpha';
14
21
 
15
22
  const useEditorStyles = makeStyles({
16
23
  editorContent: {
@@ -43,29 +50,80 @@ function EditorIntroContent() {
43
50
  );
44
51
  return /* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsx(TemplateEditorIntro, { onSelect: handleSelect }) });
45
52
  }
46
- function EditorContent() {
53
+ function buildEditorFieldExtensions(formFields = []) {
54
+ return [
55
+ ...formFields,
56
+ ...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(
57
+ ({ name }) => !formFields.some((formField) => formField.name === name)
58
+ )
59
+ ];
60
+ }
61
+ function toFieldExtensionOptions(formField) {
62
+ const internal = OpaqueFormField.toInternal(formField);
63
+ return {
64
+ ...internal,
65
+ schema: internal.schema?.schema ?? internal.schema
66
+ };
67
+ }
68
+ function EditorContent(props) {
47
69
  const classes = useEditorStyles();
48
- return /* @__PURE__ */ jsx(Content, { className: classes.editorContent, children: /* @__PURE__ */ jsx(TemplateEditor, {}) });
70
+ return /* @__PURE__ */ jsx(Content, { className: classes.editorContent, children: /* @__PURE__ */ jsx(TemplateEditor, { fieldExtensions: props.fieldExtensions }) });
49
71
  }
50
- function FormPreviewContent() {
72
+ function FormPreviewContent(props) {
51
73
  const classes = useEditorStyles();
52
74
  const navigate = useNavigate();
53
75
  const handleClose = useCallback(() => {
54
76
  navigate("..");
55
77
  }, [navigate]);
56
- return /* @__PURE__ */ jsx(Content, { className: classes.formContent, children: /* @__PURE__ */ jsx(TemplateFormPreviewer, { onClose: handleClose }) });
78
+ return /* @__PURE__ */ jsx(Content, { className: classes.formContent, children: /* @__PURE__ */ jsx(
79
+ TemplateFormPreviewer,
80
+ {
81
+ customFieldExtensions: props.fieldExtensions,
82
+ onClose: handleClose
83
+ }
84
+ ) });
57
85
  }
58
- function CustomFieldsContent() {
59
- return /* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsx(CustomFieldExplorer, {}) });
86
+ function CustomFieldsContent(props) {
87
+ return /* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsx(CustomFieldExplorer, { customFieldExtensions: props.fieldExtensions }) });
60
88
  }
61
89
  function EditorSubPage() {
90
+ const formFieldsApi = useApi(formFieldsApiRef);
91
+ const [{ result: customFieldExtensions = [] }, { execute }] = useAsync(
92
+ async () => {
93
+ const formFields = await formFieldsApi.loadFormFields();
94
+ return formFields.map(toFieldExtensionOptions);
95
+ }
96
+ );
97
+ useMountEffect(execute);
98
+ const fieldExtensions = useMemo(
99
+ () => buildEditorFieldExtensions(customFieldExtensions),
100
+ [customFieldExtensions]
101
+ );
62
102
  return /* @__PURE__ */ jsx(RequirePermission, { permission: templateManagementPermission, children: /* @__PURE__ */ jsx(SecretsContextProvider, { children: /* @__PURE__ */ jsxs(Routes, { children: [
63
103
  /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(EditorIntroContent, {}) }),
64
- /* @__PURE__ */ jsx(Route, { path: "template", element: /* @__PURE__ */ jsx(EditorContent, {}) }),
65
- /* @__PURE__ */ jsx(Route, { path: "template-form", element: /* @__PURE__ */ jsx(FormPreviewContent, {}) }),
66
- /* @__PURE__ */ jsx(Route, { path: "custom-fields", element: /* @__PURE__ */ jsx(CustomFieldsContent, {}) })
104
+ /* @__PURE__ */ jsx(
105
+ Route,
106
+ {
107
+ path: "template",
108
+ element: /* @__PURE__ */ jsx(EditorContent, { fieldExtensions })
109
+ }
110
+ ),
111
+ /* @__PURE__ */ jsx(
112
+ Route,
113
+ {
114
+ path: "template-form",
115
+ element: /* @__PURE__ */ jsx(FormPreviewContent, { fieldExtensions })
116
+ }
117
+ ),
118
+ /* @__PURE__ */ jsx(
119
+ Route,
120
+ {
121
+ path: "custom-fields",
122
+ element: /* @__PURE__ */ jsx(CustomFieldsContent, { fieldExtensions })
123
+ }
124
+ )
67
125
  ] }) }) });
68
126
  }
69
127
 
70
- export { EditorSubPage };
128
+ export { EditorSubPage, buildEditorFieldExtensions, toFieldExtensionOptions };
71
129
  //# sourceMappingURL=EditorSubPage.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EditorSubPage.esm.js","sources":["../../../src/alpha/components/EditorSubPage.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback } from 'react';\nimport { Routes, Route, useNavigate } from 'react-router-dom';\nimport { Content } from '@backstage/core-components';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { RequirePermission } from '@backstage/plugin-permission-react';\nimport { templateManagementPermission } from '@backstage/plugin-scaffolder-common/alpha';\nimport { SecretsContextProvider } from '@backstage/plugin-scaffolder-react';\nimport { TemplateEditorIntro } from './TemplateEditorPage/TemplateEditorIntro';\nimport { TemplateEditor } from './TemplateEditorPage/TemplateEditor';\nimport { TemplateFormPreviewer } from './TemplateEditorPage/TemplateFormPreviewer';\nimport { CustomFieldExplorer } from './TemplateEditorPage/CustomFieldExplorer';\nimport { useTemplateDirectory } from './TemplateEditorPage/useTemplateDirectory';\n\nconst useEditorStyles = makeStyles({\n editorContent: {\n padding: 0,\n height: 'calc(100dvh - var(--bui-header-height, 0px))',\n },\n formContent: {\n padding: 0,\n height: 'calc(100dvh - var(--bui-header-height, 0px))',\n },\n});\n\nfunction EditorIntroContent() {\n const navigate = useNavigate();\n const { openDirectory, createDirectory } = useTemplateDirectory();\n\n const handleSelect = useCallback(\n (option: 'create-template' | 'local' | 'form' | 'field-explorer') => {\n if (option === 'local') {\n openDirectory()\n .then(() => navigate('template'))\n .catch(() => {});\n } else if (option === 'create-template') {\n createDirectory()\n .then(() => navigate('template'))\n .catch(() => {});\n } else if (option === 'form') {\n navigate('template-form');\n } else if (option === 'field-explorer') {\n navigate('custom-fields');\n }\n },\n [openDirectory, createDirectory, navigate],\n );\n\n return (\n <Content>\n <TemplateEditorIntro onSelect={handleSelect} />\n </Content>\n );\n}\n\nfunction EditorContent() {\n const classes = useEditorStyles();\n return (\n <Content className={classes.editorContent}>\n <TemplateEditor />\n </Content>\n );\n}\n\nfunction FormPreviewContent() {\n const classes = useEditorStyles();\n const navigate = useNavigate();\n\n const handleClose = useCallback(() => {\n navigate('..');\n }, [navigate]);\n\n return (\n <Content className={classes.formContent}>\n <TemplateFormPreviewer onClose={handleClose} />\n </Content>\n );\n}\n\nfunction CustomFieldsContent() {\n return (\n <Content>\n <CustomFieldExplorer />\n </Content>\n );\n}\n\n/**\n * Sub-page for the template editor tab. Renders the editor intro at the index,\n * with sub-routes for the full editor, form previewer, and custom fields explorer.\n *\n * @internal\n */\nexport function EditorSubPage() {\n return (\n <RequirePermission permission={templateManagementPermission}>\n <SecretsContextProvider>\n <Routes>\n <Route index element={<EditorIntroContent />} />\n <Route path=\"template\" element={<EditorContent />} />\n <Route path=\"template-form\" element={<FormPreviewContent />} />\n <Route path=\"custom-fields\" element={<CustomFieldsContent />} />\n </Routes>\n </SecretsContextProvider>\n </RequirePermission>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EditorSubPage.esm.js","sources":["../../../src/alpha/components/EditorSubPage.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useAsync, useMountEffect } from '@react-hookz/web';\nimport { useCallback, useMemo } from 'react';\nimport { Routes, Route, useNavigate } from 'react-router-dom';\nimport { Content } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { RequirePermission } from '@backstage/plugin-permission-react';\nimport { templateManagementPermission } from '@backstage/plugin-scaffolder-common/alpha';\nimport {\n type FieldExtensionOptions,\n SecretsContextProvider,\n} from '@backstage/plugin-scaffolder-react';\nimport type { FormField } from '@backstage/plugin-scaffolder-react/alpha';\nimport { OpaqueFormField } from '@internal/scaffolder';\nimport { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../../extensions/default';\nimport { formFieldsApiRef } from '../formFieldsApi';\nimport { TemplateEditorIntro } from './TemplateEditorPage/TemplateEditorIntro';\nimport { TemplateEditor } from './TemplateEditorPage/TemplateEditor';\nimport { TemplateFormPreviewer } from './TemplateEditorPage/TemplateFormPreviewer';\nimport { CustomFieldExplorer } from './TemplateEditorPage/CustomFieldExplorer';\nimport { useTemplateDirectory } from './TemplateEditorPage/useTemplateDirectory';\n\nconst useEditorStyles = makeStyles({\n editorContent: {\n padding: 0,\n height: 'calc(100dvh - var(--bui-header-height, 0px))',\n },\n formContent: {\n padding: 0,\n height: 'calc(100dvh - var(--bui-header-height, 0px))',\n },\n});\n\nfunction EditorIntroContent() {\n const navigate = useNavigate();\n const { openDirectory, createDirectory } = useTemplateDirectory();\n\n const handleSelect = useCallback(\n (option: 'create-template' | 'local' | 'form' | 'field-explorer') => {\n if (option === 'local') {\n openDirectory()\n .then(() => navigate('template'))\n .catch(() => {});\n } else if (option === 'create-template') {\n createDirectory()\n .then(() => navigate('template'))\n .catch(() => {});\n } else if (option === 'form') {\n navigate('template-form');\n } else if (option === 'field-explorer') {\n navigate('custom-fields');\n }\n },\n [openDirectory, createDirectory, navigate],\n );\n\n return (\n <Content>\n <TemplateEditorIntro onSelect={handleSelect} />\n </Content>\n );\n}\n\nexport function buildEditorFieldExtensions(\n formFields: FieldExtensionOptions[] = [],\n): FieldExtensionOptions[] {\n return [\n ...formFields,\n ...(DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(\n ({ name }) => !formFields.some(formField => formField.name === name),\n ) as FieldExtensionOptions[]),\n ];\n}\n\nexport function toFieldExtensionOptions(\n formField: FormField,\n): FieldExtensionOptions {\n const internal = OpaqueFormField.toInternal(formField);\n\n return {\n ...internal,\n schema: internal.schema?.schema ?? internal.schema,\n } as FieldExtensionOptions;\n}\n\nfunction EditorContent(props: { fieldExtensions: FieldExtensionOptions[] }) {\n const classes = useEditorStyles();\n return (\n <Content className={classes.editorContent}>\n <TemplateEditor fieldExtensions={props.fieldExtensions} />\n </Content>\n );\n}\n\nfunction FormPreviewContent(props: {\n fieldExtensions: FieldExtensionOptions[];\n}) {\n const classes = useEditorStyles();\n const navigate = useNavigate();\n\n const handleClose = useCallback(() => {\n navigate('..');\n }, [navigate]);\n\n return (\n <Content className={classes.formContent}>\n <TemplateFormPreviewer\n customFieldExtensions={props.fieldExtensions}\n onClose={handleClose}\n />\n </Content>\n );\n}\n\nfunction CustomFieldsContent(props: {\n fieldExtensions: FieldExtensionOptions[];\n}) {\n return (\n <Content>\n <CustomFieldExplorer customFieldExtensions={props.fieldExtensions} />\n </Content>\n );\n}\n\n/**\n * Sub-page for the template editor tab. Renders the editor intro at the index,\n * with sub-routes for the full editor, form previewer, and custom fields explorer.\n *\n * @internal\n */\nexport function EditorSubPage() {\n const formFieldsApi = useApi(formFieldsApiRef);\n const [{ result: customFieldExtensions = [] }, { execute }] = useAsync(\n async () => {\n const formFields = await formFieldsApi.loadFormFields();\n return formFields.map(toFieldExtensionOptions);\n },\n );\n\n useMountEffect(execute);\n\n const fieldExtensions = useMemo(\n () => buildEditorFieldExtensions(customFieldExtensions),\n [customFieldExtensions],\n );\n\n return (\n <RequirePermission permission={templateManagementPermission}>\n <SecretsContextProvider>\n <Routes>\n <Route index element={<EditorIntroContent />} />\n <Route\n path=\"template\"\n element={<EditorContent fieldExtensions={fieldExtensions} />}\n />\n <Route\n path=\"template-form\"\n element={<FormPreviewContent fieldExtensions={fieldExtensions} />}\n />\n <Route\n path=\"custom-fields\"\n element={<CustomFieldsContent fieldExtensions={fieldExtensions} />}\n />\n </Routes>\n </SecretsContextProvider>\n </RequirePermission>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -46,8 +46,11 @@ const CustomFieldPlayground = ({
46
46
  const [refreshKey, setRefreshKey] = useState(Date.now());
47
47
  const [fieldFormState, setFieldFormState] = useState({});
48
48
  const [selectedField, setSelectedField] = useState(fieldOptions[0]);
49
- const sampleFieldTemplate = useMemo(
50
- () => yaml.stringify({
49
+ const sampleFieldTemplate = useMemo(() => {
50
+ if (!selectedField) {
51
+ return "";
52
+ }
53
+ return yaml.stringify({
51
54
  parameters: [
52
55
  {
53
56
  title: `${selectedField.name} Example`,
@@ -60,9 +63,8 @@ const CustomFieldPlayground = ({
60
63
  }
61
64
  }
62
65
  ]
63
- }),
64
- [fieldFormState, selectedField]
65
- );
66
+ });
67
+ }, [fieldFormState, selectedField]);
66
68
  const fieldComponents = useMemo(() => {
67
69
  return Object.fromEntries(
68
70
  fieldExtensions.map(({ name, component }) => [name, component])
@@ -73,15 +75,12 @@ const CustomFieldPlayground = ({
73
75
  setSelectedField(selection);
74
76
  setFieldFormState({});
75
77
  },
76
- [setFieldFormState, setSelectedField]
77
- );
78
- const handleFieldConfigChange = useCallback(
79
- (state) => {
80
- setFieldFormState(state);
81
- setRefreshKey(Date.now());
82
- },
83
- [setFieldFormState, setRefreshKey]
78
+ []
84
79
  );
80
+ const handleFieldConfigChange = useCallback((state) => {
81
+ setFieldFormState(state);
82
+ setRefreshKey(Date.now());
83
+ }, []);
85
84
  return /* @__PURE__ */ jsxs("main", { className: classes.root, children: [
86
85
  /* @__PURE__ */ jsx("div", { className: classes.controls, children: /* @__PURE__ */ jsx(
87
86
  Autocomplete,
@@ -180,7 +179,7 @@ const CustomFieldPlayground = ({
180
179
  formContext: { fieldFormState },
181
180
  onSubmit: (e) => handleFieldConfigChange(e.formData),
182
181
  validator,
183
- schema: selectedField.schema?.uiOptions || {},
182
+ schema: selectedField?.schema?.uiOptions || {},
184
183
  experimental_defaultFormStateBehavior: {
185
184
  allOf: "populateDefaults"
186
185
  },
@@ -190,7 +189,7 @@ const CustomFieldPlayground = ({
190
189
  variant: "contained",
191
190
  color: "primary",
192
191
  type: "submit",
193
- disabled: !selectedField.schema?.uiOptions,
192
+ disabled: !selectedField?.schema?.uiOptions,
194
193
  children: t(
195
194
  "templateEditorPage.customFieldExplorer.fieldForm.applyButtonTitle"
196
195
  )
@@ -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 if (!selectedField) {\n return '';\n }\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 fieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [fieldExtensions]);\n\n const handleSelectionChange = useCallback(\n (selection: FieldExtensionOptions) => {\n setSelectedField(selection);\n setFieldFormState({});\n },\n [],\n );\n\n const handleFieldConfigChange = useCallback((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\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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"}
@@ -5,7 +5,7 @@ import AccordionSummary from '@material-ui/core/AccordionSummary';
5
5
  import Divider from '@material-ui/core/Divider';
6
6
  import { makeStyles } from '@material-ui/core/styles';
7
7
  import Typography from '@material-ui/core/Typography';
8
- import ExpandLessIcon from '@material-ui/icons/ExpandLess';
8
+ import ExpandMoreIcon from '@material-ui/icons/ExpandLess';
9
9
  import { usePrevious } from '@react-hookz/web';
10
10
  import { useState, useEffect } from 'react';
11
11
  import { useDryRun } from '../DryRunContext.esm.js';
@@ -61,7 +61,7 @@ function DryRunResults() {
61
61
  AccordionSummary,
62
62
  {
63
63
  className: classes.header,
64
- expandIcon: /* @__PURE__ */ jsx(ExpandLessIcon, {}),
64
+ expandIcon: /* @__PURE__ */ jsx(ExpandMoreIcon, {}),
65
65
  children: /* @__PURE__ */ jsx(Typography, { children: t("templateEditorPage.dryRunResults.title") })
66
66
  }
67
67
  ),
@@ -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,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
+ {"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":[],"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,sBAAa,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;;;;"}
package/dist/alpha.d.ts CHANGED
@@ -583,6 +583,7 @@ declare const scaffolderTranslationRef: _backstage_frontend_plugin_api.Translati
583
583
  readonly "renderSchema.undefined": "No schema defined";
584
584
  readonly "renderSchema.tableCell.name": "Name";
585
585
  readonly "renderSchema.tableCell.type": "Type";
586
+ readonly "renderSchema.tableCell.value": "Value";
586
587
  readonly "renderSchema.tableCell.title": "Title";
587
588
  readonly "renderSchema.tableCell.description": "Description";
588
589
  readonly "templatingExtensions.content.values.title": "Values";