diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/TemplateFormPreviewer.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/TemplateFormPreviewer.tsx index bff515d13b..d59362a1cc 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/TemplateFormPreviewer.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/TemplateFormPreviewer.tsx @@ -13,23 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useCallback, useState } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import useDebounce from 'react-use/lib/useDebounce'; import { Entity } from '@backstage/catalog-model'; -import { InfoCard } from '@backstage/core-components'; -import { alertApiRef, useApi, useApiHolder } from '@backstage/core-plugin-api'; +import { alertApiRef, useApi } from '@backstage/core-plugin-api'; import { catalogApiRef, humanizeEntityRef, } from '@backstage/plugin-catalog-react'; -import { JsonObject } from '@backstage/types'; -import { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml'; -import { showPanel } from '@codemirror/view'; -import { StreamLanguage } from '@codemirror/language'; import { FormControl, - Grid, IconButton, InputLabel, LinearProgress, @@ -38,13 +29,12 @@ import { Select, } from '@material-ui/core'; import CloseIcon from '@material-ui/icons/Close'; -import { IChangeEvent } from '@rjsf/core'; -import CodeMirror from '@uiw/react-codemirror'; +import React, { useCallback, useState } from 'react'; +import useAsync from 'react-use/lib/useAsync'; import yaml from 'yaml'; import { FieldExtensionOptions } from '../../extensions'; -import { TemplateParameterSchema } from '../../types'; -import { MultistepJsonForm } from '../MultistepJsonForm'; -import { createValidator } from '../TemplatePage'; +import { TemplateEditorForm } from './TemplateEditor/TemplateEditorForm'; +import { TemplateEditorTextArea } from './TemplateEditor/TemplateEditorTextArea'; const EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI parameters: @@ -91,17 +81,28 @@ type TemplateOption = { }; const useStyles = makeStyles(theme => ({ + root: { + gridArea: 'pageContent', + display: 'grid', + gridTemplateAreas: ` + "controls controls" + "textArea preview" + `, + gridTemplateRows: 'auto 1fr', + gridTemplateColumns: '1fr 1fr', + }, controls: { + gridArea: 'controls', display: 'flex', flexFlow: 'row nowrap', alignItems: 'center', - marginBottom: theme.spacing(1), + margin: theme.spacing(1), }, - grid: { - height: '100%', + textArea: { + gridArea: 'textArea', }, - codeMirror: { - height: '95%', + preview: { + gridArea: 'preview', }, })); @@ -117,12 +118,8 @@ export const TemplateFormPreviewer = ({ const classes = useStyles(); const alertApi = useApi(alertApiRef); const catalogApi = useApi(catalogApiRef); - const apiHolder = useApiHolder(); const [selectedTemplate, setSelectedTemplate] = useState(''); - const [schema, setSchema] = useState({ - title: '', - steps: [], - }); + const [errorText, setErrorText] = useState(); const [templateOptions, setTemplateOptions] = useState([]); const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate); const [formState, setFormState] = useState({}); @@ -161,30 +158,6 @@ export const TemplateFormPreviewer = ({ [catalogApi], ); - const errorPanel = document.createElement('div'); - errorPanel.style.color = 'red'; - - useDebounce( - () => { - try { - const parsedTemplate = yaml.parse(templateYaml); - - setSchema({ - title: 'Preview', - steps: parsedTemplate.parameters.map((param: JsonObject) => ({ - title: param.title, - schema: param, - })), - }); - setFormState({}); - } catch (e) { - errorPanel.textContent = e.message; - } - }, - 250, - [setFormState, setSchema, templateYaml], - ); - const handleSelectChange = useCallback( selected => { setSelectedTemplate(selected); @@ -193,90 +166,51 @@ export const TemplateFormPreviewer = ({ [setTemplateYaml], ); - const handleFormReset = () => setFormState({}); - const handleFormChange = useCallback( - (e: IChangeEvent) => setFormState(e.formData), - [setFormState], - ); - - const handleCodeChange = useCallback( - (code: string) => { - setTemplateYaml(code); - }, - [setTemplateYaml], - ); - - const customFieldComponents = Object.fromEntries( - customFieldExtensions.map(({ name, component }) => [name, component]), - ); - - const customFieldValidators = Object.fromEntries( - customFieldExtensions.map(({ name, validation }) => [name, validation]), - ); - return ( <> {loading && } - - -
- - - Load Existing Template - - - +
+
+ + + Load Existing Template + + + - - - -
- ({ dom: errorPanel, top: true })), - ]} - onChange={handleCodeChange} + + + +
+
+ - - - {schema && ( - - { - return { - ...step, - validate: createValidator( - step.schema, - customFieldValidators, - { apiHolder }, - ), - }; - })} - /> - - )} - - +
+
+ +
+ ); };