@backstage/plugin-scaffolder 1.26.0-next.1 → 1.26.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/alpha/package.json +1 -1
  3. package/dist/alpha/components/TemplateEditorPage/CustomFieldExplorer.esm.js +61 -29
  4. package/dist/alpha/components/TemplateEditorPage/CustomFieldExplorer.esm.js.map +1 -1
  5. package/dist/alpha/components/TemplateEditorPage/CustomFieldPlaygroud.esm.js +36 -13
  6. package/dist/alpha/components/TemplateEditorPage/CustomFieldPlaygroud.esm.js.map +1 -1
  7. package/dist/alpha/components/TemplateEditorPage/CustomFieldsPage.esm.js +6 -15
  8. package/dist/alpha/components/TemplateEditorPage/CustomFieldsPage.esm.js.map +1 -1
  9. package/dist/alpha/components/TemplateEditorPage/DirectoryEditorContext.esm.js +4 -3
  10. package/dist/alpha/components/TemplateEditorPage/DirectoryEditorContext.esm.js.map +1 -1
  11. package/dist/alpha/components/TemplateEditorPage/TemplateEditor.esm.js +35 -80
  12. package/dist/alpha/components/TemplateEditorPage/TemplateEditor.esm.js.map +1 -1
  13. package/dist/alpha/components/TemplateEditorPage/TemplateEditorBrowser.esm.js +9 -6
  14. package/dist/alpha/components/TemplateEditorPage/TemplateEditorBrowser.esm.js.map +1 -1
  15. package/dist/alpha/components/TemplateEditorPage/TemplateEditorForm.esm.js +5 -2
  16. package/dist/alpha/components/TemplateEditorPage/TemplateEditorForm.esm.js.map +1 -1
  17. package/dist/alpha/components/TemplateEditorPage/TemplateEditorIntro.esm.js +17 -16
  18. package/dist/alpha/components/TemplateEditorPage/TemplateEditorIntro.esm.js.map +1 -1
  19. package/dist/alpha/components/TemplateEditorPage/TemplateEditorLayout.esm.js +94 -0
  20. package/dist/alpha/components/TemplateEditorPage/TemplateEditorLayout.esm.js.map +1 -0
  21. package/dist/alpha/components/TemplateEditorPage/TemplateEditorPage.esm.js +22 -34
  22. package/dist/alpha/components/TemplateEditorPage/TemplateEditorPage.esm.js.map +1 -1
  23. package/dist/alpha/components/TemplateEditorPage/TemplateEditorTextArea.esm.js +10 -20
  24. package/dist/alpha/components/TemplateEditorPage/TemplateEditorTextArea.esm.js.map +1 -1
  25. package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbar.esm.js +42 -14
  26. package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbar.esm.js.map +1 -1
  27. package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbarFileMenu.esm.js +73 -0
  28. package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbarFileMenu.esm.js.map +1 -0
  29. package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbarTemplatesMenu.esm.js +84 -0
  30. package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbarTemplatesMenu.esm.js.map +1 -0
  31. package/dist/alpha/components/TemplateEditorPage/TemplateFormPage.esm.js +3 -1
  32. package/dist/alpha/components/TemplateEditorPage/TemplateFormPage.esm.js.map +1 -1
  33. package/dist/alpha/components/TemplateEditorPage/TemplateFormPreviewer.esm.js +58 -95
  34. package/dist/alpha/components/TemplateEditorPage/TemplateFormPreviewer.esm.js.map +1 -1
  35. package/dist/alpha/components/TemplateEditorPage/TemplateIntroPage.esm.js +54 -0
  36. package/dist/alpha/components/TemplateEditorPage/TemplateIntroPage.esm.js.map +1 -0
  37. package/dist/alpha/components/TemplateEditorPage/useTemplateDirectory.esm.js +33 -0
  38. package/dist/alpha/components/TemplateEditorPage/useTemplateDirectory.esm.js.map +1 -0
  39. package/dist/alpha.d.ts +25 -6
  40. package/dist/components/ActionsPage/ActionsPage.esm.js +42 -8
  41. package/dist/components/ActionsPage/ActionsPage.esm.js.map +1 -1
  42. package/dist/components/Router/Router.esm.js +4 -4
  43. package/dist/components/Router/Router.esm.js.map +1 -1
  44. package/dist/lib/filesystem/WebFileSystemAccess.esm.js +1 -13
  45. package/dist/lib/filesystem/WebFileSystemAccess.esm.js.map +1 -1
  46. package/dist/lib/filesystem/WebFileSystemStore.esm.js +15 -0
  47. package/dist/lib/filesystem/WebFileSystemStore.esm.js.map +1 -0
  48. package/dist/lib/filesystem/createExampleTemplate.esm.js +1 -0
  49. package/dist/lib/filesystem/createExampleTemplate.esm.js.map +1 -1
  50. package/dist/translation.esm.js +40 -5
  51. package/dist/translation.esm.js.map +1 -1
  52. package/package.json +14 -14
  53. package/dist/alpha/components/TemplateEditorPage/TemplatePage.esm.js +0 -52
  54. package/dist/alpha/components/TemplateEditorPage/TemplatePage.esm.js.map +0 -1
@@ -1,23 +1,17 @@
1
- import { useApi, alertApiRef } from '@backstage/core-plugin-api';
2
- import { catalogApiRef, humanizeEntityRef } from '@backstage/plugin-catalog-react';
3
- import LinearProgress from '@material-ui/core/LinearProgress';
4
- import Paper from '@material-ui/core/Paper';
5
- import FormControl from '@material-ui/core/FormControl';
6
- import Input from '@material-ui/core/Input';
7
- import Select from '@material-ui/core/Select';
8
- import Tooltip from '@material-ui/core/Tooltip';
9
- import IconButton from '@material-ui/core/IconButton';
10
- import MenuItem from '@material-ui/core/MenuItem';
11
- import { makeStyles } from '@material-ui/core/styles';
12
- import CloseIcon from '@material-ui/icons/Close';
1
+ import yaml from 'yaml';
13
2
  import React, { useState, useCallback } from 'react';
3
+ import { useNavigate } from 'react-router-dom';
14
4
  import useAsync from 'react-use/esm/useAsync';
15
- import yaml from 'yaml';
5
+ import { makeStyles } from '@material-ui/core/styles';
6
+ import { useApi, alertApiRef, useRouteRef } from '@backstage/core-plugin-api';
7
+ import { catalogApiRef, humanizeEntityRef } from '@backstage/plugin-catalog-react';
8
+ import { editRouteRef } from '../../../routes.esm.js';
9
+ import { TemplateEditorLayout, TemplateEditorLayoutToolbar, TemplateEditorLayoutFiles, TemplateEditorLayoutPreview } from './TemplateEditorLayout.esm.js';
16
10
  import { TemplateEditorToolbar } from './TemplateEditorToolbar.esm.js';
11
+ import { TemplateEditorToolbarFileMenu } from './TemplateEditorToolbarFileMenu.esm.js';
12
+ import { TemplateEditorToolbarTemplatesMenu } from './TemplateEditorToolbarTemplatesMenu.esm.js';
17
13
  import { TemplateEditorForm } from './TemplateEditorForm.esm.js';
18
14
  import { TemplateEditorTextArea } from './TemplateEditorTextArea.esm.js';
19
- import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
20
- import { scaffolderTranslationRef } from '../../../translation.esm.js';
21
15
 
22
16
  const EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI
23
17
  parameters:
@@ -64,36 +58,21 @@ const useStyles = makeStyles(
64
58
  gridArea: "pageContent",
65
59
  display: "grid",
66
60
  gridTemplateAreas: `
61
+ "toolbar"
62
+ "textArea"
63
+ "preview"
64
+ `,
65
+ [theme.breakpoints.up("md")]: {
66
+ gridTemplateAreas: `
67
67
  "toolbar toolbar"
68
68
  "textArea preview"
69
69
  `,
70
- gridTemplateRows: "auto 1fr",
71
- gridTemplateColumns: "1fr 1fr"
72
- },
73
- toolbar: {
74
- gridArea: "toolbar"
75
- },
76
- textArea: {
77
- gridArea: "textArea",
78
- height: "100%"
79
- },
80
- preview: {
81
- gridArea: "preview",
82
- position: "relative",
83
- borderLeft: `1px solid ${theme.palette.divider}`,
84
- backgroundColor: theme.palette.background.default
85
- },
86
- scroll: {
87
- position: "absolute",
88
- top: 0,
89
- left: 0,
90
- right: 0,
91
- bottom: 0,
92
- padding: theme.spacing(1)
70
+ gridTemplateRows: "auto 1fr",
71
+ gridTemplateColumns: "1fr 1fr"
72
+ }
93
73
  },
94
- formControl: {
95
- minWidth: 120,
96
- maxWidth: 300
74
+ files: {
75
+ gridArea: "textArea"
97
76
  }
98
77
  }),
99
78
  { name: "ScaffolderTemplateFormPreviewer" }
@@ -101,19 +80,22 @@ const useStyles = makeStyles(
101
80
  const TemplateFormPreviewer = ({
102
81
  defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML,
103
82
  customFieldExtensions = [],
104
- onClose,
105
83
  layouts = [],
106
84
  formProps
107
85
  }) => {
108
86
  const classes = useStyles();
109
- const { t } = useTranslationRef(scaffolderTranslationRef);
110
87
  const alertApi = useApi(alertApiRef);
111
88
  const catalogApi = useApi(catalogApiRef);
89
+ const navigate = useNavigate();
90
+ const editLink = useRouteRef(editRouteRef);
112
91
  const [errorText, setErrorText] = useState();
113
- const [selectedTemplate, setSelectedTemplate] = useState(null);
92
+ const [selectedTemplate, setSelectedTemplate] = useState();
114
93
  const [templateOptions, setTemplateOptions] = useState([]);
115
94
  const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate);
116
- const { loading } = useAsync(
95
+ const handleCloseDirectory = useCallback(() => {
96
+ navigate(editLink());
97
+ }, [navigate, editLink]);
98
+ useAsync(
117
99
  () => catalogApi.getEntities({
118
100
  filter: { kind: "template" },
119
101
  fields: [
@@ -144,59 +126,40 @@ const TemplateFormPreviewer = ({
144
126
  // TODO(Rugvip): Afaik this should be Entity, but didn't want to make runtime changes while fixing types
145
127
  (selected) => {
146
128
  setSelectedTemplate(selected);
147
- setTemplateYaml(yaml.stringify(selected.spec));
129
+ setTemplateYaml(yaml.stringify(selected.value.spec));
148
130
  },
149
- [setTemplateYaml]
131
+ [setSelectedTemplate, setTemplateYaml]
150
132
  );
151
- return /* @__PURE__ */ React.createElement(React.Fragment, null, loading && /* @__PURE__ */ React.createElement(LinearProgress, null), /* @__PURE__ */ React.createElement(
152
- Paper,
133
+ return /* @__PURE__ */ React.createElement(TemplateEditorLayout, { classes: { root: classes.root } }, /* @__PURE__ */ React.createElement(TemplateEditorLayoutToolbar, null, /* @__PURE__ */ React.createElement(TemplateEditorToolbar, { fieldExtensions: customFieldExtensions }, /* @__PURE__ */ React.createElement(
134
+ TemplateEditorToolbarFileMenu,
153
135
  {
154
- className: classes.root,
155
- component: "main",
156
- variant: "outlined",
157
- square: true
158
- },
159
- /* @__PURE__ */ React.createElement("div", { className: classes.toolbar }, /* @__PURE__ */ React.createElement(TemplateEditorToolbar, { fieldExtensions: customFieldExtensions }, /* @__PURE__ */ React.createElement(Tooltip, { title: "Close editor" }, /* @__PURE__ */ React.createElement(IconButton, { onClick: onClose }, /* @__PURE__ */ React.createElement(CloseIcon, null))), /* @__PURE__ */ React.createElement(FormControl, { className: classes.formControl }, /* @__PURE__ */ React.createElement(
160
- Select,
161
- {
162
- displayEmpty: true,
163
- value: selectedTemplate,
164
- onChange: (e) => handleSelectChange(e.target.value),
165
- input: /* @__PURE__ */ React.createElement(Input, null),
166
- renderValue: (selected) => {
167
- if (!selected) {
168
- return t("templateEditorPage.templateFormPreviewer.title");
169
- }
170
- return selected.metadata.title;
171
- },
172
- inputProps: {
173
- "aria-label": t(
174
- "templateEditorPage.templateFormPreviewer.title"
175
- )
176
- }
177
- },
178
- templateOptions.map((option, index) => /* @__PURE__ */ React.createElement(MenuItem, { key: index, value: option.value }, option.label))
179
- )))),
180
- /* @__PURE__ */ React.createElement("div", { className: classes.textArea }, /* @__PURE__ */ React.createElement(
181
- TemplateEditorTextArea,
182
- {
183
- content: templateYaml,
184
- onUpdate: setTemplateYaml,
185
- errorText
186
- }
187
- )),
188
- /* @__PURE__ */ React.createElement("div", { className: classes.preview }, /* @__PURE__ */ React.createElement("div", { className: classes.scroll }, /* @__PURE__ */ React.createElement(
189
- TemplateEditorForm,
190
- {
191
- content: templateYaml,
192
- contentIsSpec: true,
193
- fieldExtensions: customFieldExtensions,
194
- setErrorText,
195
- layouts,
196
- formProps
197
- }
198
- )))
199
- ));
136
+ onCloseDirectory: handleCloseDirectory
137
+ }
138
+ ), /* @__PURE__ */ React.createElement(
139
+ TemplateEditorToolbarTemplatesMenu,
140
+ {
141
+ options: templateOptions,
142
+ selectedOption: selectedTemplate,
143
+ onSelectOption: handleSelectChange
144
+ }
145
+ ))), /* @__PURE__ */ React.createElement(TemplateEditorLayoutFiles, { classes: { root: classes.files } }, /* @__PURE__ */ React.createElement(
146
+ TemplateEditorTextArea,
147
+ {
148
+ content: templateYaml,
149
+ onUpdate: setTemplateYaml,
150
+ errorText
151
+ }
152
+ )), /* @__PURE__ */ React.createElement(TemplateEditorLayoutPreview, null, /* @__PURE__ */ React.createElement(
153
+ TemplateEditorForm,
154
+ {
155
+ content: templateYaml,
156
+ contentIsSpec: true,
157
+ fieldExtensions: customFieldExtensions,
158
+ setErrorText,
159
+ layouts,
160
+ formProps
161
+ }
162
+ )));
200
163
  };
201
164
 
202
165
  export { TemplateFormPreviewer };
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateFormPreviewer.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n humanizeEntityRef,\n} from '@backstage/plugin-catalog-react';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport Paper from '@material-ui/core/Paper';\nimport FormControl from '@material-ui/core/FormControl';\nimport Input from '@material-ui/core/Input';\nimport Select from '@material-ui/core/Select';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport IconButton from '@material-ui/core/IconButton';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CloseIcon from '@material-ui/icons/Close';\nimport React, { useCallback, useState } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport yaml from 'yaml';\nimport {\n LayoutOptions,\n FieldExtensionOptions,\n FormProps,\n} from '@backstage/plugin-scaffolder-react';\nimport { TemplateEditorToolbar } from './TemplateEditorToolbar';\nimport { TemplateEditorForm } from './TemplateEditorForm';\nimport { TemplateEditorTextArea } from './TemplateEditorTextArea';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\n\nconst EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI\nparameters:\n - title: Fill in some steps\n required:\n - name\n properties:\n name:\n title: Name\n type: string\n description: Unique name of the component\n owner:\n title: Owner\n type: string\n description: Owner of the component\n ui:field: OwnerPicker\n ui:options:\n catalogFilter:\n kind: Group\n - title: Choose a location\n required:\n - repoUrl\n properties:\n repoUrl:\n title: Repository Location\n type: string\n ui:field: RepoUrlPicker\n ui:options:\n allowedHosts:\n - github.com\nsteps:\n - id: fetch-base\n name: Fetch Base\n action: fetch:template\n input:\n url: ./template\n values:\n name: \\${{parameters.name}}\n`;\n\ntype TemplateOption = {\n label: string;\n value: Entity;\n};\n\n/** @public */\nexport type ScaffolderTemplateFormPreviewerClassKey =\n | 'root'\n | 'controls'\n | 'textArea'\n | 'preview';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n height: '100%',\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateAreas: `\n \"toolbar toolbar\"\n \"textArea preview\"\n `,\n gridTemplateRows: 'auto 1fr',\n gridTemplateColumns: '1fr 1fr',\n },\n toolbar: {\n gridArea: 'toolbar',\n },\n textArea: {\n gridArea: 'textArea',\n height: '100%',\n },\n preview: {\n gridArea: 'preview',\n position: 'relative',\n borderLeft: `1px solid ${theme.palette.divider}`,\n backgroundColor: theme.palette.background.default,\n },\n scroll: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n padding: theme.spacing(1),\n },\n formControl: {\n minWidth: 120,\n maxWidth: 300,\n },\n }),\n { name: 'ScaffolderTemplateFormPreviewer' },\n);\n\nexport const TemplateFormPreviewer = ({\n defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML,\n customFieldExtensions = [],\n onClose,\n layouts = [],\n formProps,\n}: {\n defaultPreviewTemplate?: string;\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n onClose?: () => void;\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n}) => {\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const alertApi = useApi(alertApiRef);\n const catalogApi = useApi(catalogApiRef);\n const [errorText, setErrorText] = useState<string>();\n const [selectedTemplate, setSelectedTemplate] =\n useState<TemplateOption | null>(null);\n const [templateOptions, setTemplateOptions] = useState<TemplateOption[]>([]);\n const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate);\n\n const { loading } = useAsync(\n () =>\n catalogApi\n .getEntities({\n filter: { kind: 'template' },\n fields: [\n 'kind',\n 'metadata.namespace',\n 'metadata.name',\n 'metadata.title',\n 'spec.parameters',\n 'spec.steps',\n 'spec.output',\n ],\n })\n .then(({ items }) =>\n setTemplateOptions(\n items.map(template => ({\n label:\n template.metadata.title ??\n humanizeEntityRef(template, { defaultKind: 'template' }),\n value: template,\n })),\n ),\n )\n .catch(e =>\n alertApi.post({\n message: `Error loading exisiting templates: ${e.message}`,\n severity: 'error',\n }),\n ),\n [catalogApi],\n );\n\n const handleSelectChange = useCallback(\n // TODO(Rugvip): Afaik this should be Entity, but didn't want to make runtime changes while fixing types\n (selected: any) => {\n setSelectedTemplate(selected);\n setTemplateYaml(yaml.stringify(selected.spec));\n },\n [setTemplateYaml],\n );\n\n return (\n <>\n {loading && <LinearProgress />}\n <Paper\n className={classes.root}\n component=\"main\"\n variant=\"outlined\"\n square\n >\n <div className={classes.toolbar}>\n <TemplateEditorToolbar fieldExtensions={customFieldExtensions}>\n <Tooltip title=\"Close editor\">\n <IconButton onClick={onClose}>\n <CloseIcon />\n </IconButton>\n </Tooltip>\n <FormControl className={classes.formControl}>\n <Select\n displayEmpty\n value={selectedTemplate}\n onChange={e => handleSelectChange(e.target.value)}\n input={<Input />}\n renderValue={selected => {\n if (!selected) {\n return t('templateEditorPage.templateFormPreviewer.title');\n }\n return (selected as Entity).metadata.title;\n }}\n inputProps={{\n 'aria-label': t(\n 'templateEditorPage.templateFormPreviewer.title',\n ),\n }}\n >\n {templateOptions.map((option, index) => (\n <MenuItem key={index} value={option.value as any}>\n {option.label}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </TemplateEditorToolbar>\n </div>\n <div className={classes.textArea}>\n <TemplateEditorTextArea\n content={templateYaml}\n onUpdate={setTemplateYaml}\n errorText={errorText}\n />\n </div>\n <div className={classes.preview}>\n <div className={classes.scroll}>\n <TemplateEditorForm\n content={templateYaml}\n contentIsSpec\n fieldExtensions={customFieldExtensions}\n setErrorText={setErrorText}\n layouts={layouts}\n formProps={formProps}\n />\n </div>\n </div>\n </Paper>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TemplateFormPreviewer.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport yaml from 'yaml';\nimport React, { useCallback, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\n\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n humanizeEntityRef,\n} from '@backstage/plugin-catalog-react';\nimport {\n LayoutOptions,\n FieldExtensionOptions,\n FormProps,\n} from '@backstage/plugin-scaffolder-react';\n\nimport { editRouteRef } from '../../../routes';\n\nimport {\n TemplateEditorLayout,\n TemplateEditorLayoutToolbar,\n TemplateEditorLayoutFiles,\n TemplateEditorLayoutPreview,\n} from './TemplateEditorLayout';\nimport { TemplateEditorToolbar } from './TemplateEditorToolbar';\nimport { TemplateEditorToolbarFileMenu } from './TemplateEditorToolbarFileMenu';\nimport {\n TemplateOption,\n TemplateEditorToolbarTemplatesMenu,\n} from './TemplateEditorToolbarTemplatesMenu';\nimport { TemplateEditorForm } from './TemplateEditorForm';\nimport { TemplateEditorTextArea } from './TemplateEditorTextArea';\n\nconst EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI\nparameters:\n - title: Fill in some steps\n required:\n - name\n properties:\n name:\n title: Name\n type: string\n description: Unique name of the component\n owner:\n title: Owner\n type: string\n description: Owner of the component\n ui:field: OwnerPicker\n ui:options:\n catalogFilter:\n kind: Group\n - title: Choose a location\n required:\n - repoUrl\n properties:\n repoUrl:\n title: Repository Location\n type: string\n ui:field: RepoUrlPicker\n ui:options:\n allowedHosts:\n - github.com\nsteps:\n - id: fetch-base\n name: Fetch Base\n action: fetch:template\n input:\n url: ./template\n values:\n name: \\${{parameters.name}}\n`;\n\n/** @public */\nexport type ScaffolderTemplateFormPreviewerClassKey =\n | 'root'\n | 'toolbar'\n | 'controls'\n | 'textArea'\n | 'preview';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n height: '100%',\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateAreas: `\n \"toolbar\"\n \"textArea\"\n \"preview\"\n `,\n [theme.breakpoints.up('md')]: {\n gridTemplateAreas: `\n \"toolbar toolbar\"\n \"textArea preview\"\n `,\n gridTemplateRows: 'auto 1fr',\n gridTemplateColumns: '1fr 1fr',\n },\n },\n files: {\n gridArea: 'textArea',\n },\n }),\n { name: 'ScaffolderTemplateFormPreviewer' },\n);\n\nexport const TemplateFormPreviewer = ({\n defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML,\n customFieldExtensions = [],\n layouts = [],\n formProps,\n}: {\n defaultPreviewTemplate?: string;\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n onClose?: () => void;\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n}) => {\n const classes = useStyles();\n const alertApi = useApi(alertApiRef);\n const catalogApi = useApi(catalogApiRef);\n const navigate = useNavigate();\n const editLink = useRouteRef(editRouteRef);\n\n const [errorText, setErrorText] = useState<string>();\n const [selectedTemplate, setSelectedTemplate] = useState<TemplateOption>();\n const [templateOptions, setTemplateOptions] = useState<TemplateOption[]>([]);\n const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate);\n\n const handleCloseDirectory = useCallback(() => {\n navigate(editLink());\n }, [navigate, editLink]);\n\n useAsync(\n () =>\n catalogApi\n .getEntities({\n filter: { kind: 'template' },\n fields: [\n 'kind',\n 'metadata.namespace',\n 'metadata.name',\n 'metadata.title',\n 'spec.parameters',\n 'spec.steps',\n 'spec.output',\n ],\n })\n .then(({ items }) =>\n setTemplateOptions(\n items.map(template => ({\n label:\n template.metadata.title ??\n humanizeEntityRef(template, { defaultKind: 'template' }),\n value: template,\n })),\n ),\n )\n .catch(e =>\n alertApi.post({\n message: `Error loading exisiting templates: ${e.message}`,\n severity: 'error',\n }),\n ),\n [catalogApi],\n );\n\n const handleSelectChange = useCallback(\n // TODO(Rugvip): Afaik this should be Entity, but didn't want to make runtime changes while fixing types\n (selected: TemplateOption) => {\n setSelectedTemplate(selected);\n setTemplateYaml(yaml.stringify(selected.value.spec));\n },\n [setSelectedTemplate, setTemplateYaml],\n );\n\n return (\n <TemplateEditorLayout classes={{ root: classes.root }}>\n <TemplateEditorLayoutToolbar>\n <TemplateEditorToolbar fieldExtensions={customFieldExtensions}>\n <TemplateEditorToolbarFileMenu\n onCloseDirectory={handleCloseDirectory}\n />\n <TemplateEditorToolbarTemplatesMenu\n options={templateOptions}\n selectedOption={selectedTemplate}\n onSelectOption={handleSelectChange}\n />\n </TemplateEditorToolbar>\n </TemplateEditorLayoutToolbar>\n <TemplateEditorLayoutFiles classes={{ root: classes.files }}>\n <TemplateEditorTextArea\n content={templateYaml}\n onUpdate={setTemplateYaml}\n errorText={errorText}\n />\n </TemplateEditorLayoutFiles>\n <TemplateEditorLayoutPreview>\n <TemplateEditorForm\n content={templateYaml}\n contentIsSpec\n fieldExtensions={customFieldExtensions}\n setErrorText={setErrorText}\n layouts={layouts}\n formProps={formProps}\n />\n </TemplateEditorLayoutPreview>\n </TemplateEditorLayout>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import React, { useCallback } from 'react';
2
+ import { Page, Header, Content } from '@backstage/core-components';
3
+ import { TemplateEditorIntro } from './TemplateEditorIntro.esm.js';
4
+ import { useNavigate } from 'react-router-dom';
5
+ import { useRouteRef } from '@backstage/core-plugin-api';
6
+ import { rootRouteRef, editorRouteRef, templateFormRouteRef, customFieldsRouteRef } from '../../../routes.esm.js';
7
+ import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
8
+ import { scaffolderTranslationRef } from '../../../translation.esm.js';
9
+ import { useTemplateDirectory } from './useTemplateDirectory.esm.js';
10
+
11
+ function TemplateIntroPage() {
12
+ const navigate = useNavigate();
13
+ const createLink = useRouteRef(rootRouteRef);
14
+ const editorLink = useRouteRef(editorRouteRef);
15
+ const templateFormLink = useRouteRef(templateFormRouteRef);
16
+ const customFieldsLink = useRouteRef(customFieldsRouteRef);
17
+ const { t } = useTranslationRef(scaffolderTranslationRef);
18
+ const { openDirectory, createDirectory } = useTemplateDirectory();
19
+ const handleSelect = useCallback(
20
+ (option) => {
21
+ if (option === "local") {
22
+ openDirectory().then(() => navigate(editorLink())).catch(() => {
23
+ });
24
+ } else if (option === "create-template") {
25
+ createDirectory().then(() => navigate(editorLink())).catch(() => {
26
+ });
27
+ } else if (option === "form") {
28
+ navigate(templateFormLink());
29
+ } else if (option === "field-explorer") {
30
+ navigate(customFieldsLink());
31
+ }
32
+ },
33
+ [
34
+ openDirectory,
35
+ createDirectory,
36
+ navigate,
37
+ editorLink,
38
+ templateFormLink,
39
+ customFieldsLink
40
+ ]
41
+ );
42
+ return /* @__PURE__ */ React.createElement(Page, { themeId: "home" }, /* @__PURE__ */ React.createElement(
43
+ Header,
44
+ {
45
+ title: t("templateIntroPage.title"),
46
+ type: "Scaffolder",
47
+ typeLink: createLink(),
48
+ subtitle: t("templateIntroPage.subtitle")
49
+ }
50
+ ), /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(TemplateEditorIntro, { onSelect: handleSelect })));
51
+ }
52
+
53
+ export { TemplateIntroPage };
54
+ //# sourceMappingURL=TemplateIntroPage.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateIntroPage.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateIntroPage.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 React, { useCallback } from 'react';\nimport { Content, Header, Page } from '@backstage/core-components';\n\nimport { TemplateEditorIntro } from './TemplateEditorIntro';\nimport { useNavigate } from 'react-router-dom';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport {\n rootRouteRef,\n editorRouteRef,\n templateFormRouteRef,\n customFieldsRouteRef,\n} from '../../../routes';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { useTemplateDirectory } from './useTemplateDirectory';\n\nexport function TemplateIntroPage() {\n const navigate = useNavigate();\n const createLink = useRouteRef(rootRouteRef);\n const editorLink = useRouteRef(editorRouteRef);\n const templateFormLink = useRouteRef(templateFormRouteRef);\n const customFieldsLink = useRouteRef(customFieldsRouteRef);\n const { t } = useTranslationRef(scaffolderTranslationRef);\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(editorLink()))\n .catch(() => {});\n } else if (option === 'create-template') {\n createDirectory()\n .then(() => navigate(editorLink()))\n .catch(() => {});\n } else if (option === 'form') {\n navigate(templateFormLink());\n } else if (option === 'field-explorer') {\n navigate(customFieldsLink());\n }\n },\n [\n openDirectory,\n createDirectory,\n navigate,\n editorLink,\n templateFormLink,\n customFieldsLink,\n ],\n );\n\n return (\n <Page themeId=\"home\">\n <Header\n title={t('templateIntroPage.title')}\n type=\"Scaffolder\"\n typeLink={createLink()}\n subtitle={t('templateIntroPage.subtitle')}\n />\n <Content>\n <TemplateEditorIntro onSelect={handleSelect} />\n </Content>\n </Page>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;AA+BO,SAAS,iBAAoB,GAAA;AAClC,EAAA,MAAM,WAAW,WAAY,EAAA,CAAA;AAC7B,EAAM,MAAA,UAAA,GAAa,YAAY,YAAY,CAAA,CAAA;AAC3C,EAAM,MAAA,UAAA,GAAa,YAAY,cAAc,CAAA,CAAA;AAC7C,EAAM,MAAA,gBAAA,GAAmB,YAAY,oBAAoB,CAAA,CAAA;AACzD,EAAM,MAAA,gBAAA,GAAmB,YAAY,oBAAoB,CAAA,CAAA;AACzD,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,wBAAwB,CAAA,CAAA;AACxD,EAAA,MAAM,EAAE,aAAA,EAAe,eAAgB,EAAA,GAAI,oBAAqB,EAAA,CAAA;AAEhE,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAAC,MAAoE,KAAA;AACnE,MAAA,IAAI,WAAW,OAAS,EAAA;AACtB,QAAc,aAAA,EAAA,CACX,KAAK,MAAM,QAAA,CAAS,YAAY,CAAC,CACjC,CAAA,KAAA,CAAM,MAAM;AAAA,SAAE,CAAA,CAAA;AAAA,OACnB,MAAA,IAAW,WAAW,iBAAmB,EAAA;AACvC,QAAgB,eAAA,EAAA,CACb,KAAK,MAAM,QAAA,CAAS,YAAY,CAAC,CACjC,CAAA,KAAA,CAAM,MAAM;AAAA,SAAE,CAAA,CAAA;AAAA,OACnB,MAAA,IAAW,WAAW,MAAQ,EAAA;AAC5B,QAAA,QAAA,CAAS,kBAAkB,CAAA,CAAA;AAAA,OAC7B,MAAA,IAAW,WAAW,gBAAkB,EAAA;AACtC,QAAA,QAAA,CAAS,kBAAkB,CAAA,CAAA;AAAA,OAC7B;AAAA,KACF;AAAA,IACA;AAAA,MACE,aAAA;AAAA,MACA,eAAA;AAAA,MACA,QAAA;AAAA,MACA,UAAA;AAAA,MACA,gBAAA;AAAA,MACA,gBAAA;AAAA,KACF;AAAA,GACF,CAAA;AAEA,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,OAAA,EAAQ,MACZ,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,EAAE,yBAAyB,CAAA;AAAA,MAClC,IAAK,EAAA,YAAA;AAAA,MACL,UAAU,UAAW,EAAA;AAAA,MACrB,QAAA,EAAU,EAAE,4BAA4B,CAAA;AAAA,KAAA;AAAA,GAC1C,sCACC,OACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,uBAAoB,QAAU,EAAA,YAAA,EAAc,CAC/C,CACF,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,33 @@
1
+ import { useCallback } from 'react';
2
+ import useAsyncRetry from 'react-use/esm/useAsyncRetry';
3
+ import { createExampleTemplate } from '../../../lib/filesystem/createExampleTemplate.esm.js';
4
+ import { WebFileSystemStore } from '../../../lib/filesystem/WebFileSystemStore.esm.js';
5
+ import { WebFileSystemAccess } from '../../../lib/filesystem/WebFileSystemAccess.esm.js';
6
+
7
+ function useTemplateDirectory() {
8
+ const { value, loading, error, retry } = useAsyncRetry(async () => {
9
+ const directory = await WebFileSystemStore.getDirectory();
10
+ if (!directory) return void 0;
11
+ return WebFileSystemAccess.fromHandle(directory);
12
+ }, []);
13
+ const openDirectory = useCallback(() => {
14
+ return WebFileSystemAccess.requestDirectoryAccess().then(WebFileSystemStore.setDirectory).then(retry);
15
+ }, [retry]);
16
+ const createDirectory = useCallback(() => {
17
+ return WebFileSystemAccess.requestDirectoryAccess().then(createExampleTemplate).then(WebFileSystemStore.setDirectory).then(retry);
18
+ }, [retry]);
19
+ const closeDirectory = useCallback(() => {
20
+ return WebFileSystemStore.setDirectory(void 0).then(retry);
21
+ }, [retry]);
22
+ return {
23
+ directory: value,
24
+ loading,
25
+ error,
26
+ openDirectory,
27
+ createDirectory,
28
+ closeDirectory
29
+ };
30
+ }
31
+
32
+ export { useTemplateDirectory };
33
+ //# sourceMappingURL=useTemplateDirectory.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTemplateDirectory.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/useTemplateDirectory.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 { useCallback } from 'react';\nimport useAsyncRetry from 'react-use/esm/useAsyncRetry';\n\nimport {\n WebFileSystemStore,\n WebFileSystemAccess,\n WebDirectoryAccess,\n createExampleTemplate,\n} from '../../../lib/filesystem';\n\nexport function useTemplateDirectory(): {\n directory?: WebDirectoryAccess;\n loading: boolean;\n error?: Error;\n openDirectory: () => Promise<void>;\n createDirectory: () => Promise<void>;\n closeDirectory: () => Promise<void>;\n} {\n const { value, loading, error, retry } = useAsyncRetry(async () => {\n const directory = await WebFileSystemStore.getDirectory();\n if (!directory) return undefined;\n return WebFileSystemAccess.fromHandle(directory);\n }, []);\n\n const openDirectory = useCallback(() => {\n return WebFileSystemAccess.requestDirectoryAccess()\n .then(WebFileSystemStore.setDirectory)\n .then(retry);\n }, [retry]);\n\n const createDirectory = useCallback(() => {\n return WebFileSystemAccess.requestDirectoryAccess()\n .then(createExampleTemplate)\n .then(WebFileSystemStore.setDirectory)\n .then(retry);\n }, [retry]);\n\n const closeDirectory = useCallback(() => {\n return WebFileSystemStore.setDirectory(undefined).then(retry);\n }, [retry]);\n\n return {\n directory: value,\n loading,\n error,\n openDirectory,\n createDirectory,\n closeDirectory,\n };\n}\n"],"names":[],"mappings":";;;;;;AA0BO,SAAS,oBAOd,GAAA;AACA,EAAA,MAAM,EAAE,KAAO,EAAA,OAAA,EAAS,OAAO,KAAM,EAAA,GAAI,cAAc,YAAY;AACjE,IAAM,MAAA,SAAA,GAAY,MAAM,kBAAA,CAAmB,YAAa,EAAA,CAAA;AACxD,IAAI,IAAA,CAAC,WAAkB,OAAA,KAAA,CAAA,CAAA;AACvB,IAAO,OAAA,mBAAA,CAAoB,WAAW,SAAS,CAAA,CAAA;AAAA,GACjD,EAAG,EAAE,CAAA,CAAA;AAEL,EAAM,MAAA,aAAA,GAAgB,YAAY,MAAM;AACtC,IAAO,OAAA,mBAAA,CAAoB,wBACxB,CAAA,IAAA,CAAK,mBAAmB,YAAY,CAAA,CACpC,KAAK,KAAK,CAAA,CAAA;AAAA,GACf,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AAEV,EAAM,MAAA,eAAA,GAAkB,YAAY,MAAM;AACxC,IAAO,OAAA,mBAAA,CAAoB,sBAAuB,EAAA,CAC/C,IAAK,CAAA,qBAAqB,CAC1B,CAAA,IAAA,CAAK,kBAAmB,CAAA,YAAY,CACpC,CAAA,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,GACf,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AAEV,EAAM,MAAA,cAAA,GAAiB,YAAY,MAAM;AACvC,IAAA,OAAO,kBAAmB,CAAA,YAAA,CAAa,KAAS,CAAA,CAAA,CAAE,KAAK,KAAK,CAAA,CAAA;AAAA,GAC9D,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AAEV,EAAO,OAAA;AAAA,IACL,SAAW,EAAA,KAAA;AAAA,IACX,OAAA;AAAA,IACA,KAAA;AAAA,IACA,aAAA;AAAA,IACA,eAAA;AAAA,IACA,cAAA;AAAA,GACF,CAAA;AACF;;;;"}
package/dist/alpha.d.ts CHANGED
@@ -12,10 +12,10 @@ import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api'
12
12
  type ScaffolderCustomFieldExplorerClassKey = 'root' | 'controls' | 'fieldForm' | 'preview';
13
13
 
14
14
  /** @public */
15
- type ScaffolderTemplateEditorClassKey = 'root' | 'browser' | 'editor' | 'preview' | 'results';
15
+ type ScaffolderTemplateEditorClassKey = 'root' | 'toolbar' | 'browser' | 'editor' | 'preview' | 'results';
16
16
 
17
17
  /** @public */
18
- type ScaffolderTemplateFormPreviewerClassKey = 'root' | 'controls' | 'textArea' | 'preview';
18
+ type ScaffolderTemplateFormPreviewerClassKey = 'root' | 'toolbar' | 'controls' | 'textArea' | 'preview';
19
19
 
20
20
  /**
21
21
  * @alpha
@@ -117,6 +117,7 @@ declare const scaffolderTranslationRef: _backstage_core_plugin_api_alpha.Transla
117
117
  readonly "actionsPage.content.tableCell.name": "Name";
118
118
  readonly "actionsPage.content.tableCell.title": "Title";
119
119
  readonly "actionsPage.content.tableCell.description": "Description";
120
+ readonly "actionsPage.content.searchFieldPlaceholder": "Search for an action";
120
121
  readonly "actionsPage.content.noRowsDescription": "No schema defined";
121
122
  readonly "actionsPage.title": "Installed actions";
122
123
  readonly "actionsPage.action.input": "Input";
@@ -156,9 +157,13 @@ declare const scaffolderTranslationRef: _backstage_core_plugin_api_alpha.Transla
156
157
  readonly "ongoingTask.showLogsButtonTitle": "Show Logs";
157
158
  readonly "templateEditorForm.stepper.emptyText": "There are no spec parameters in the template to preview.";
158
159
  readonly "templateTypePicker.title": "Categories";
159
- readonly "templateFormPage.title": "Template Form Playground";
160
- readonly "templateFormPage.subtitle": "Edit, preview, and try out templates and template forms";
161
- readonly "templateEditorPage.title": "Manage Templates";
160
+ readonly "templateIntroPage.title": "Manage Templates";
161
+ readonly "templateIntroPage.subtitle": "Edit, preview, and try out templates, forms, and custom fields";
162
+ readonly "templateFormPage.title": "Template Editor";
163
+ readonly "templateFormPage.subtitle": "Edit, preview, and try out templates forms";
164
+ readonly "templateCustomFieldPage.title": "Custom Field Explorer";
165
+ readonly "templateCustomFieldPage.subtitle": "Edit, preview, and try out custom fields";
166
+ readonly "templateEditorPage.title": "Template Editor";
162
167
  readonly "templateEditorPage.subtitle": "Edit, preview, and try out templates and template forms";
163
168
  readonly "templateEditorPage.dryRunResults.title": "Dry-run results";
164
169
  readonly "templateEditorPage.dryRunResultsList.title": "Result {{resultId}}";
@@ -184,12 +189,13 @@ declare const scaffolderTranslationRef: _backstage_core_plugin_api_alpha.Transla
184
189
  readonly "templateEditorPage.templateEditorIntro.createLocal.title": "Create New Template";
185
190
  readonly "templateEditorPage.templateEditorIntro.createLocal.description": "Create a local template directory, allowing you to both edit and try executing your own template.";
186
191
  readonly "templateEditorPage.templateEditorIntro.createLocal.unsupportedTooltip": "Only supported in some Chromium-based browsers";
187
- readonly "templateEditorPage.templateEditorIntro.formEditor.title": "Template playground";
192
+ readonly "templateEditorPage.templateEditorIntro.formEditor.title": "Template Form Playground";
188
193
  readonly "templateEditorPage.templateEditorIntro.formEditor.description": "Preview and edit a template form, either using a sample template or by loading a template from the catalog.";
189
194
  readonly "templateEditorPage.templateEditorIntro.fieldExplorer.title": "Custom Field Explorer";
190
195
  readonly "templateEditorPage.templateEditorIntro.fieldExplorer.description": "View and play around with available installed custom field extensions.";
191
196
  readonly "templateEditorPage.templateEditorTextArea.saveIconTooltip": "Save file";
192
197
  readonly "templateEditorPage.templateEditorTextArea.refreshIconTooltip": "Reload file";
198
+ readonly "templateEditorPage.templateEditorTextArea.emptyStateParagraph": "Please select an action on the file menu.";
193
199
  readonly "templateEditorPage.templateFormPreviewer.title": "Load Existing Template";
194
200
  readonly "templateListPage.title": "Create a new component";
195
201
  readonly "templateListPage.subtitle": "Create new software components using standard templates in your organization";
@@ -203,6 +209,19 @@ declare const scaffolderTranslationRef: _backstage_core_plugin_api_alpha.Transla
203
209
  readonly "templateWizardPage.subtitle": "Create new software components using standard templates in your organization";
204
210
  readonly "templateWizardPage.pageTitle": "Create a new component";
205
211
  readonly "templateWizardPage.pageContextMenu.editConfigurationTitle": "Edit Configuration";
212
+ readonly "templateEditorToolbar.customFieldExplorerTooltip": "Custom Fields Explorer";
213
+ readonly "templateEditorToolbar.installedActionsDocumentationTooltip": "Installed Actions Documentation";
214
+ readonly "templateEditorToolbar.addToCatalogButton": "Publish";
215
+ readonly "templateEditorToolbar.addToCatalogDialogTitle": "Publish changes";
216
+ readonly "templateEditorToolbar.addToCatalogDialogContent.stepsIntroduction": "Follow the instructions below to create or update a template:";
217
+ readonly "templateEditorToolbar.addToCatalogDialogContent.stepsListItems": "Save the template files in a local directory\nCreate a pull request to a new or existing git repository\nIf the template already exists, the changes will be reflected in the software catalog once the pull request gets merged\nBut if you are creating a new template, follow the documentation linked below to register the new template repository in software catalog";
218
+ readonly "templateEditorToolbar.addToCatalogDialogActions.documentationUrl": "https://backstage.io/docs/features/software-templates/adding-templates/";
219
+ readonly "templateEditorToolbar.addToCatalogDialogActions.documentationButton": "Go to the documentation";
220
+ readonly "templateEditorToolbarFileMenu.button": "File";
221
+ readonly "templateEditorToolbarFileMenu.options.openDirectory": "Open template directory";
222
+ readonly "templateEditorToolbarFileMenu.options.createDirectory": "Create template directory";
223
+ readonly "templateEditorToolbarFileMenu.options.closeEditor": "Close template editor";
224
+ readonly "templateEditorToolbarTemplatesMenu.button": "Templates";
206
225
  }>;
207
226
 
208
227
  /*
@@ -20,6 +20,10 @@ import classNames from 'classnames';
20
20
  import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
21
21
  import ExpandLessIcon from '@material-ui/icons/ExpandLess';
22
22
  import LinkIcon from '@material-ui/icons/Link';
23
+ import Autocomplete from '@material-ui/lab/Autocomplete';
24
+ import TextField from '@material-ui/core/TextField';
25
+ import InputAdornment from '@material-ui/core/InputAdornment';
26
+ import SearchIcon from '@material-ui/icons/Search';
23
27
  import { useRouteRef, useApi } from '@backstage/core-plugin-api';
24
28
  import { Page, Header, Content, Progress, ErrorPanel, EmptyState, Link, MarkdownContent, CodeSnippet } from '@backstage/core-components';
25
29
  import Chip from '@material-ui/core/Chip';
@@ -70,12 +74,17 @@ const ActionPageContent = () => {
70
74
  const api = useApi(scaffolderApiRef);
71
75
  const { t } = useTranslationRef(scaffolderTranslationRef);
72
76
  const classes = useStyles();
73
- const { loading, value, error } = useAsync(async () => {
77
+ const {
78
+ loading,
79
+ value = [],
80
+ error
81
+ } = useAsync(async () => {
74
82
  return api.listActions();
75
83
  }, [api]);
84
+ const [selectedAction, setSelectedAction] = useState(null);
76
85
  const [isExpanded, setIsExpanded] = useState({});
77
86
  useEffect(() => {
78
- if (value && window.location.hash) {
87
+ if (value.length && window.location.hash) {
79
88
  document.querySelector(window.location.hash)?.scrollIntoView();
80
89
  }
81
90
  }, [value]);
@@ -155,7 +164,32 @@ const ActionPageContent = () => {
155
164
  formatRows(`${id}.${index}`, i)
156
165
  ))));
157
166
  };
158
- return value?.map((action) => {
167
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { pb: 3 }, /* @__PURE__ */ React.createElement(
168
+ Autocomplete,
169
+ {
170
+ id: "actions-autocomplete",
171
+ options: value,
172
+ loading,
173
+ getOptionLabel: (option) => option.id,
174
+ renderInput: (params) => /* @__PURE__ */ React.createElement(
175
+ TextField,
176
+ {
177
+ ...params,
178
+ "aria-label": t("actionsPage.content.searchFieldPlaceholder"),
179
+ placeholder: t("actionsPage.content.searchFieldPlaceholder"),
180
+ variant: "outlined",
181
+ InputProps: {
182
+ ...params.InputProps,
183
+ startAdornment: /* @__PURE__ */ React.createElement(InputAdornment, { position: "start" }, /* @__PURE__ */ React.createElement(SearchIcon, null))
184
+ }
185
+ }
186
+ ),
187
+ onChange: (_event, option) => {
188
+ setSelectedAction(option);
189
+ },
190
+ fullWidth: true
191
+ }
192
+ )), (selectedAction ? [selectedAction] : value).map((action) => {
159
193
  if (action.id.startsWith("legacy:")) {
160
194
  return void 0;
161
195
  }
@@ -164,11 +198,11 @@ const ActionPageContent = () => {
164
198
  `${action.id}.input`,
165
199
  action.schema?.input?.oneOf
166
200
  );
167
- return /* @__PURE__ */ React.createElement(Box, { pb: 4, key: action.id }, /* @__PURE__ */ React.createElement(
201
+ return /* @__PURE__ */ React.createElement(Box, { pb: 3, key: action.id }, /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(
168
202
  Typography,
169
203
  {
170
204
  id: action.id.replaceAll(":", "-"),
171
- variant: "h4",
205
+ variant: "h5",
172
206
  component: "h2",
173
207
  className: classes.code
174
208
  },
@@ -180,12 +214,12 @@ const ActionPageContent = () => {
180
214
  to: `#${action.id.replaceAll(":", "-")}`
181
215
  },
182
216
  /* @__PURE__ */ React.createElement(LinkIcon, null)
183
- ), action.description && /* @__PURE__ */ React.createElement(MarkdownContent, { content: action.description }), action.schema?.input && /* @__PURE__ */ React.createElement(Box, { pb: 2 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5", component: "h3" }, t("actionsPage.action.input")), renderTable(
217
+ )), action.description && /* @__PURE__ */ React.createElement(MarkdownContent, { content: action.description }), action.schema?.input && /* @__PURE__ */ React.createElement(Box, { pb: 2 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6", component: "h3" }, t("actionsPage.action.input")), renderTable(
184
218
  formatRows(`${action.id}.input`, action?.schema?.input)
185
219
  ), oneOf), action.schema?.output && /* @__PURE__ */ React.createElement(Box, { pb: 2 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5", component: "h3" }, t("actionsPage.action.output")), renderTable(
186
220
  formatRows(`${action.id}.output`, action?.schema?.output)
187
- )), action.examples && /* @__PURE__ */ React.createElement(Accordion, null, /* @__PURE__ */ React.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5", component: "h3" }, t("actionsPage.action.examples"))), /* @__PURE__ */ React.createElement(AccordionDetails, null, /* @__PURE__ */ React.createElement(Box, { pb: 2 }, /* @__PURE__ */ React.createElement(ExamplesTable, { examples: action.examples })))));
188
- });
221
+ )), action.examples && /* @__PURE__ */ React.createElement(Accordion, null, /* @__PURE__ */ React.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6", component: "h3" }, t("actionsPage.action.examples"))), /* @__PURE__ */ React.createElement(AccordionDetails, null, /* @__PURE__ */ React.createElement(Box, { pb: 2 }, /* @__PURE__ */ React.createElement(ExamplesTable, { examples: action.examples })))));
222
+ }));
189
223
  };
190
224
  const ActionsPage = () => {
191
225
  const navigate = useNavigate();