@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,50 +1,38 @@
1
1
  import React from 'react';
2
+ import { makeStyles } from '@material-ui/core/styles';
2
3
  import { Page, Header, Content } from '@backstage/core-components';
3
- import { WebFileSystemAccess, WebFileSystemStore } from '../../../lib/filesystem/WebFileSystemAccess.esm.js';
4
- import { TemplateEditorIntro } from './TemplateEditorIntro.esm.js';
5
- import { useNavigate } from 'react-router-dom';
6
4
  import { useRouteRef } from '@backstage/core-plugin-api';
7
- import { rootRouteRef, editorRouteRef, customFieldsRouteRef, templateFormRouteRef } from '../../../routes.esm.js';
8
5
  import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
9
6
  import { scaffolderTranslationRef } from '../../../translation.esm.js';
10
- import { createExampleTemplate } from '../../../lib/filesystem/createExampleTemplate.esm.js';
7
+ import { editRouteRef } from '../../../routes.esm.js';
8
+ import { TemplateEditor } from './TemplateEditor.esm.js';
11
9
 
12
- function TemplateEditorPage() {
13
- const navigate = useNavigate();
14
- const createLink = useRouteRef(rootRouteRef);
15
- const editorLink = useRouteRef(editorRouteRef);
16
- const customFieldsLink = useRouteRef(customFieldsRouteRef);
17
- const templateFormLink = useRouteRef(templateFormRouteRef);
10
+ const useStyles = makeStyles(
11
+ {
12
+ content: {
13
+ padding: 0
14
+ }
15
+ },
16
+ { name: "ScaffolderTemplateEditorToolbar" }
17
+ );
18
+ function TemplateEditorPage(props) {
19
+ const classes = useStyles();
20
+ const editLink = useRouteRef(editRouteRef);
18
21
  const { t } = useTranslationRef(scaffolderTranslationRef);
19
22
  return /* @__PURE__ */ React.createElement(Page, { themeId: "home" }, /* @__PURE__ */ React.createElement(
20
23
  Header,
21
24
  {
22
25
  title: t("templateEditorPage.title"),
23
- type: "Scaffolder",
24
- typeLink: createLink(),
25
- subtitle: t("templateEditorPage.subtitle")
26
+ subtitle: t("templateEditorPage.subtitle"),
27
+ type: t("templateIntroPage.title"),
28
+ typeLink: editLink()
26
29
  }
27
- ), /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(
28
- TemplateEditorIntro,
30
+ ), /* @__PURE__ */ React.createElement(Content, { className: classes.content }, /* @__PURE__ */ React.createElement(
31
+ TemplateEditor,
29
32
  {
30
- onSelect: (option) => {
31
- if (option === "local") {
32
- WebFileSystemAccess.requestDirectoryAccess().then((directory) => WebFileSystemStore.setDirectory(directory)).then(() => navigate(editorLink())).catch(() => {
33
- });
34
- } else if (option === "create-template") {
35
- WebFileSystemAccess.requestDirectoryAccess().then((directory) => {
36
- createExampleTemplate(directory).then(() => {
37
- WebFileSystemStore.setDirectory(directory);
38
- navigate(editorLink());
39
- });
40
- }).catch(() => {
41
- });
42
- } else if (option === "form") {
43
- navigate(templateFormLink());
44
- } else if (option === "field-explorer") {
45
- navigate(customFieldsLink());
46
- }
47
- }
33
+ layouts: props.layouts,
34
+ formProps: props.formProps,
35
+ fieldExtensions: props.fieldExtensions
48
36
  }
49
37
  )));
50
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateEditorPage.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorPage.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 from 'react';\nimport { Content, Header, Page } from '@backstage/core-components';\n\nimport { WebFileSystemAccess } from '../../../lib/filesystem';\n\nimport { TemplateEditorIntro } from './TemplateEditorIntro';\nimport { useNavigate } from 'react-router-dom';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport {\n editorRouteRef,\n customFieldsRouteRef,\n rootRouteRef,\n templateFormRouteRef,\n} from '../../../routes';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { WebFileSystemStore } from '../../../lib/filesystem/WebFileSystemAccess';\nimport { createExampleTemplate } from '../../../lib/filesystem/createExampleTemplate';\n\nexport function TemplateEditorPage() {\n const navigate = useNavigate();\n const createLink = useRouteRef(rootRouteRef);\n const editorLink = useRouteRef(editorRouteRef);\n const customFieldsLink = useRouteRef(customFieldsRouteRef);\n const templateFormLink = useRouteRef(templateFormRouteRef);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <Page themeId=\"home\">\n <Header\n title={t('templateEditorPage.title')}\n type=\"Scaffolder\"\n typeLink={createLink()}\n subtitle={t('templateEditorPage.subtitle')}\n />\n <Content>\n <TemplateEditorIntro\n onSelect={option => {\n if (option === 'local') {\n WebFileSystemAccess.requestDirectoryAccess()\n .then(directory => WebFileSystemStore.setDirectory(directory))\n .then(() => navigate(editorLink()))\n .catch(() => {});\n } else if (option === 'create-template') {\n WebFileSystemAccess.requestDirectoryAccess()\n .then(directory => {\n createExampleTemplate(directory).then(() => {\n WebFileSystemStore.setDirectory(directory);\n navigate(editorLink());\n });\n })\n .catch(() => {});\n } else if (option === 'form') {\n navigate(templateFormLink());\n } else if (option === 'field-explorer') {\n navigate(customFieldsLink());\n }\n }}\n />\n </Content>\n </Page>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAkCO,SAAS,kBAAqB,GAAA;AACnC,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;AAExD,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,0BAA0B,CAAA;AAAA,MACnC,IAAK,EAAA,YAAA;AAAA,MACL,UAAU,UAAW,EAAA;AAAA,MACrB,QAAA,EAAU,EAAE,6BAA6B,CAAA;AAAA,KAAA;AAAA,GAC3C,sCACC,OACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,mBAAA;AAAA,IAAA;AAAA,MACC,UAAU,CAAU,MAAA,KAAA;AAClB,QAAA,IAAI,WAAW,OAAS,EAAA;AACtB,UAAA,mBAAA,CAAoB,wBACjB,CAAA,IAAA,CAAK,CAAa,SAAA,KAAA,kBAAA,CAAmB,aAAa,SAAS,CAAC,CAC5D,CAAA,IAAA,CAAK,MAAM,QAAS,CAAA,UAAA,EAAY,CAAC,CAAA,CACjC,MAAM,MAAM;AAAA,WAAE,CAAA,CAAA;AAAA,SACnB,MAAA,IAAW,WAAW,iBAAmB,EAAA;AACvC,UAAoB,mBAAA,CAAA,sBAAA,EACjB,CAAA,IAAA,CAAK,CAAa,SAAA,KAAA;AACjB,YAAsB,qBAAA,CAAA,SAAS,CAAE,CAAA,IAAA,CAAK,MAAM;AAC1C,cAAA,kBAAA,CAAmB,aAAa,SAAS,CAAA,CAAA;AACzC,cAAA,QAAA,CAAS,YAAY,CAAA,CAAA;AAAA,aACtB,CAAA,CAAA;AAAA,WACF,CACA,CAAA,KAAA,CAAM,MAAM;AAAA,WAAE,CAAA,CAAA;AAAA,SACnB,MAAA,IAAW,WAAW,MAAQ,EAAA;AAC5B,UAAA,QAAA,CAAS,kBAAkB,CAAA,CAAA;AAAA,SAC7B,MAAA,IAAW,WAAW,gBAAkB,EAAA;AACtC,UAAA,QAAA,CAAS,kBAAkB,CAAA,CAAA;AAAA,SAC7B;AAAA,OACF;AAAA,KAAA;AAAA,GAEJ,CACF,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"TemplateEditorPage.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorPage.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { Content, Header, Page } from '@backstage/core-components';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport {\n FormProps,\n FieldExtensionOptions,\n type LayoutOptions,\n} from '@backstage/plugin-scaffolder-react';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { editRouteRef } from '../../../routes';\nimport { TemplateEditor } from './TemplateEditor';\n\nconst useStyles = makeStyles(\n {\n content: {\n padding: 0,\n },\n },\n { name: 'ScaffolderTemplateEditorToolbar' },\n);\n\ninterface TemplatePageProps {\n defaultPreviewTemplate?: string;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n}\n\nexport function TemplateEditorPage(props: TemplatePageProps) {\n const classes = useStyles();\n const editLink = useRouteRef(editRouteRef);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <Page themeId=\"home\">\n <Header\n title={t('templateEditorPage.title')}\n subtitle={t('templateEditorPage.subtitle')}\n type={t('templateIntroPage.title')}\n typeLink={editLink()}\n />\n <Content className={classes.content}>\n <TemplateEditor\n layouts={props.layouts}\n formProps={props.formProps}\n fieldExtensions={props.fieldExtensions}\n />\n </Content>\n </Page>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AA6BA,MAAM,SAAY,GAAA,UAAA;AAAA,EAChB;AAAA,IACE,OAAS,EAAA;AAAA,MACP,OAAS,EAAA,CAAA;AAAA,KACX;AAAA,GACF;AAAA,EACA,EAAE,MAAM,iCAAkC,EAAA;AAC5C,CAAA,CAAA;AASO,SAAS,mBAAmB,KAA0B,EAAA;AAC3D,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAM,MAAA,QAAA,GAAW,YAAY,YAAY,CAAA,CAAA;AACzC,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,wBAAwB,CAAA,CAAA;AAExD,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,0BAA0B,CAAA;AAAA,MACnC,QAAA,EAAU,EAAE,6BAA6B,CAAA;AAAA,MACzC,IAAA,EAAM,EAAE,yBAAyB,CAAA;AAAA,MACjC,UAAU,QAAS,EAAA;AAAA,KAAA;AAAA,GAErB,kBAAA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,SAAA,EAAW,QAAQ,OAC1B,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MACC,SAAS,KAAM,CAAA,OAAA;AAAA,MACf,WAAW,KAAM,CAAA,SAAA;AAAA,MACjB,iBAAiB,KAAM,CAAA,eAAA;AAAA,KAAA;AAAA,GAE3B,CACF,CAAA,CAAA;AAEJ;;;;"}
@@ -4,7 +4,6 @@ import { showPanel } from '@codemirror/view';
4
4
  import IconButton from '@material-ui/core/IconButton';
5
5
  import Paper from '@material-ui/core/Paper';
6
6
  import Tooltip from '@material-ui/core/Tooltip';
7
- import Link from '@material-ui/core/Link';
8
7
  import Typography from '@material-ui/core/Typography';
9
8
  import { makeStyles } from '@material-ui/core/styles';
10
9
  import RefreshIcon from '@material-ui/icons/Refresh';
@@ -29,11 +28,14 @@ const useStyles = makeStyles((theme) => ({
29
28
  verticalAlign: "top"
30
29
  },
31
30
  codeMirror: {
32
- position: "absolute",
33
- top: 0,
34
- bottom: 0,
35
- left: 0,
36
- right: 0
31
+ height: "100%",
32
+ [theme.breakpoints.up("md")]: {
33
+ position: "absolute",
34
+ top: 0,
35
+ bottom: 0,
36
+ left: 0,
37
+ right: 0
38
+ }
37
39
  },
38
40
  errorPanel: {
39
41
  color: theme.palette.error.main,
@@ -116,6 +118,7 @@ function TemplateEditorTextArea(props) {
116
118
  function TemplateEditorDirectoryEditorTextArea(props) {
117
119
  const classes = useStyles();
118
120
  const directoryEditor = useDirectoryEditor();
121
+ const { t } = useTranslationRef(scaffolderTranslationRef);
119
122
  if (!directoryEditor) {
120
123
  return /* @__PURE__ */ React.createElement(
121
124
  Typography,
@@ -124,20 +127,7 @@ function TemplateEditorDirectoryEditorTextArea(props) {
124
127
  color: "textSecondary",
125
128
  align: "center"
126
129
  },
127
- "Please",
128
- " ",
129
- /* @__PURE__ */ React.createElement(
130
- Link,
131
- {
132
- className: classes.button,
133
- component: "button",
134
- variant: "body1",
135
- onClick: props.onLoad
136
- },
137
- "load"
138
- ),
139
- " ",
140
- "a template directory."
130
+ t("templateEditorPage.templateEditorTextArea.emptyStateParagraph")
141
131
  );
142
132
  }
143
133
  const actions = directoryEditor?.selectedFile?.dirty ? {
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateEditorTextArea.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorTextArea.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 { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\nimport { showPanel } from '@codemirror/view';\nimport IconButton from '@material-ui/core/IconButton';\nimport Paper from '@material-ui/core/Paper';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Link from '@material-ui/core/Link';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport RefreshIcon from '@material-ui/icons/Refresh';\nimport SaveIcon from '@material-ui/icons/Save';\nimport { useKeyboardEvent } from '@react-hookz/web';\nimport CodeMirror from '@uiw/react-codemirror';\nimport React, { useMemo } from 'react';\nimport { useDirectoryEditor } from './DirectoryEditorContext';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\n\nconst useStyles = makeStyles(theme => ({\n container: {\n position: 'relative',\n width: '100%',\n height: '100%',\n },\n typography: {\n padding: theme.spacing(1.5),\n },\n button: {\n verticalAlign: 'top',\n },\n codeMirror: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n },\n errorPanel: {\n color: theme.palette.error.main,\n lineHeight: 2,\n margin: theme.spacing(0, 1),\n },\n floatingButtons: {\n position: 'absolute',\n top: theme.spacing(1),\n right: theme.spacing(3),\n },\n floatingButton: {\n padding: theme.spacing(1),\n },\n}));\n\n/** A wrapper around CodeMirror with an error panel and extra actions available */\nexport function TemplateEditorTextArea(props: {\n content?: string;\n onUpdate?: (content: string) => void;\n errorText?: string;\n onSave?: () => void;\n onReload?: () => void;\n}) {\n const { errorText } = props;\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const panelExtension = useMemo(() => {\n if (!errorText) {\n return showPanel.of(null);\n }\n\n const dom = document.createElement('div');\n dom.classList.add(classes.errorPanel);\n dom.textContent = errorText;\n return showPanel.of(() => ({ dom, bottom: true }));\n }, [classes, errorText]);\n\n useKeyboardEvent(\n e => e.key === 's' && (e.ctrlKey || e.metaKey),\n e => {\n e.preventDefault();\n if (props.onSave) {\n props.onSave();\n }\n },\n );\n\n return (\n <div className={classes.container}>\n <CodeMirror\n className={classes.codeMirror}\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport), panelExtension]}\n value={props.content}\n onChange={props.onUpdate}\n />\n {(props.onSave || props.onReload) && (\n <div className={classes.floatingButtons}>\n <Paper>\n {props.onSave && (\n <Tooltip\n title={t(\n 'templateEditorPage.templateEditorTextArea.saveIconTooltip',\n )}\n >\n <IconButton\n className={classes.floatingButton}\n onClick={() => props.onSave?.()}\n >\n <SaveIcon />\n </IconButton>\n </Tooltip>\n )}\n {props.onReload && (\n <Tooltip\n title={t(\n 'templateEditorPage.templateEditorTextArea.refreshIconTooltip',\n )}\n >\n <IconButton\n className={classes.floatingButton}\n onClick={() => props.onReload?.()}\n >\n <RefreshIcon />\n </IconButton>\n </Tooltip>\n )}\n </Paper>\n </div>\n )}\n </div>\n );\n}\n\n/** A version of the TemplateEditorTextArea that is connected to the DirectoryEditor context */\nexport function TemplateEditorDirectoryEditorTextArea(props: {\n errorText?: string;\n onLoad?: () => void;\n}) {\n const classes = useStyles();\n const directoryEditor = useDirectoryEditor();\n\n if (!directoryEditor) {\n return (\n <Typography\n className={classes.typography}\n color=\"textSecondary\"\n align=\"center\"\n >\n Please{' '}\n <Link\n className={classes.button}\n component=\"button\"\n variant=\"body1\"\n onClick={props.onLoad}\n >\n load\n </Link>{' '}\n a template directory.\n </Typography>\n );\n }\n\n const actions = directoryEditor?.selectedFile?.dirty\n ? {\n onSave: () => directoryEditor.save(),\n onReload: () => directoryEditor.reload(),\n }\n : {\n onReload: () => directoryEditor.reload(),\n };\n\n return (\n <TemplateEditorTextArea\n errorText={props.errorText}\n content={directoryEditor.selectedFile?.content}\n onUpdate={content =>\n directoryEditor?.selectedFile?.updateContent(content)\n }\n {...actions}\n />\n );\n}\n\nTemplateEditorTextArea.DirectoryEditor = TemplateEditorDirectoryEditorTextArea;\n"],"names":["yamlSupport"],"mappings":"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"}
1
+ {"version":3,"file":"TemplateEditorTextArea.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorTextArea.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 { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\nimport { showPanel } from '@codemirror/view';\nimport IconButton from '@material-ui/core/IconButton';\nimport Paper from '@material-ui/core/Paper';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport RefreshIcon from '@material-ui/icons/Refresh';\nimport SaveIcon from '@material-ui/icons/Save';\nimport { useKeyboardEvent } from '@react-hookz/web';\nimport CodeMirror from '@uiw/react-codemirror';\nimport React, { useMemo } from 'react';\nimport { useDirectoryEditor } from './DirectoryEditorContext';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\n\nconst useStyles = makeStyles(theme => ({\n container: {\n position: 'relative',\n width: '100%',\n height: '100%',\n },\n typography: {\n padding: theme.spacing(1.5),\n },\n button: {\n verticalAlign: 'top',\n },\n codeMirror: {\n height: '100%',\n [theme.breakpoints.up('md')]: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n },\n },\n errorPanel: {\n color: theme.palette.error.main,\n lineHeight: 2,\n margin: theme.spacing(0, 1),\n },\n floatingButtons: {\n position: 'absolute',\n top: theme.spacing(1),\n right: theme.spacing(3),\n },\n floatingButton: {\n padding: theme.spacing(1),\n },\n}));\n\n/** A wrapper around CodeMirror with an error panel and extra actions available */\nexport function TemplateEditorTextArea(props: {\n content?: string;\n onUpdate?: (content: string) => void;\n errorText?: string;\n onSave?: () => void;\n onReload?: () => void;\n}) {\n const { errorText } = props;\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const panelExtension = useMemo(() => {\n if (!errorText) {\n return showPanel.of(null);\n }\n\n const dom = document.createElement('div');\n dom.classList.add(classes.errorPanel);\n dom.textContent = errorText;\n return showPanel.of(() => ({ dom, bottom: true }));\n }, [classes, errorText]);\n\n useKeyboardEvent(\n e => e.key === 's' && (e.ctrlKey || e.metaKey),\n e => {\n e.preventDefault();\n if (props.onSave) {\n props.onSave();\n }\n },\n );\n\n return (\n <div className={classes.container}>\n <CodeMirror\n className={classes.codeMirror}\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport), panelExtension]}\n value={props.content}\n onChange={props.onUpdate}\n />\n {(props.onSave || props.onReload) && (\n <div className={classes.floatingButtons}>\n <Paper>\n {props.onSave && (\n <Tooltip\n title={t(\n 'templateEditorPage.templateEditorTextArea.saveIconTooltip',\n )}\n >\n <IconButton\n className={classes.floatingButton}\n onClick={() => props.onSave?.()}\n >\n <SaveIcon />\n </IconButton>\n </Tooltip>\n )}\n {props.onReload && (\n <Tooltip\n title={t(\n 'templateEditorPage.templateEditorTextArea.refreshIconTooltip',\n )}\n >\n <IconButton\n className={classes.floatingButton}\n onClick={() => props.onReload?.()}\n >\n <RefreshIcon />\n </IconButton>\n </Tooltip>\n )}\n </Paper>\n </div>\n )}\n </div>\n );\n}\n\n/** A version of the TemplateEditorTextArea that is connected to the DirectoryEditor context */\nexport function TemplateEditorDirectoryEditorTextArea(props: {\n errorText?: string;\n}) {\n const classes = useStyles();\n const directoryEditor = useDirectoryEditor();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n if (!directoryEditor) {\n return (\n <Typography\n className={classes.typography}\n color=\"textSecondary\"\n align=\"center\"\n >\n {t('templateEditorPage.templateEditorTextArea.emptyStateParagraph')}\n </Typography>\n );\n }\n\n const actions = directoryEditor?.selectedFile?.dirty\n ? {\n onSave: () => directoryEditor.save(),\n onReload: () => directoryEditor.reload(),\n }\n : {\n onReload: () => directoryEditor.reload(),\n };\n\n return (\n <TemplateEditorTextArea\n errorText={props.errorText}\n content={directoryEditor.selectedFile?.content}\n onUpdate={content =>\n directoryEditor?.selectedFile?.updateContent(content)\n }\n {...actions}\n />\n );\n}\n\nTemplateEditorTextArea.DirectoryEditor = TemplateEditorDirectoryEditorTextArea;\n"],"names":["yamlSupport"],"mappings":"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"}
@@ -13,16 +13,23 @@ import DialogContentText from '@material-ui/core/DialogContentText';
13
13
  import DialogActions from '@material-ui/core/DialogActions';
14
14
  import ExtensionIcon from '@material-ui/icons/Extension';
15
15
  import DescriptionIcon from '@material-ui/icons/Description';
16
- import { Link } from '@backstage/core-components';
16
+ import { useTranslationRef } from '@backstage/frontend-plugin-api';
17
17
  import { ActionPageContent } from '../../../components/ActionsPage/ActionsPage.esm.js';
18
+ import { scaffolderTranslationRef } from '../../../translation.esm.js';
18
19
  import { CustomFieldPlaygroud } from './CustomFieldPlaygroud.esm.js';
19
20
 
20
21
  const useStyles = makeStyles(
21
22
  (theme) => ({
22
23
  paper: {
23
- width: "40%",
24
+ width: "90%",
24
25
  padding: theme.spacing(2),
25
- backgroundColor: theme.palette.background.default
26
+ backgroundColor: theme.palette.background.default,
27
+ [theme.breakpoints.up("sm")]: {
28
+ width: "70%"
29
+ },
30
+ [theme.breakpoints.up("md")]: {
31
+ width: "50%"
32
+ }
26
33
  },
27
34
  appbar: {
28
35
  zIndex: 1
@@ -49,20 +56,25 @@ const useStyles = makeStyles(
49
56
  function TemplateEditorToolbar(props) {
50
57
  const { children, fieldExtensions } = props;
51
58
  const classes = useStyles();
59
+ const { t } = useTranslationRef(scaffolderTranslationRef);
52
60
  const [showFieldsDrawer, setShowFieldsDrawer] = useState(false);
53
61
  const [showActionsDrawer, setShowActionsDrawer] = useState(false);
54
62
  const [showPublishModal, setShowPublishModal] = useState(false);
55
- return /* @__PURE__ */ React.createElement(AppBar, { className: classes.appbar, position: "relative" }, /* @__PURE__ */ React.createElement(Toolbar, { className: classes.toolbar }, /* @__PURE__ */ React.createElement("div", { className: classes.toolbarCustomActions }, children), /* @__PURE__ */ React.createElement(
56
- ButtonGroup,
63
+ return /* @__PURE__ */ React.createElement(AppBar, { className: classes.appbar, position: "relative" }, /* @__PURE__ */ React.createElement(Toolbar, { className: classes.toolbar }, /* @__PURE__ */ React.createElement("div", { className: classes.toolbarCustomActions }, children), /* @__PURE__ */ React.createElement(ButtonGroup, { className: classes.toolbarDefaultActions, variant: "text" }, /* @__PURE__ */ React.createElement(
64
+ Tooltip,
57
65
  {
58
- className: classes.toolbarDefaultActions,
59
- variant: "outlined",
60
- color: "primary"
66
+ title: t("templateEditorToolbar.customFieldExplorerTooltip")
61
67
  },
62
- /* @__PURE__ */ React.createElement(Tooltip, { title: "Custom Fields Explorer" }, /* @__PURE__ */ React.createElement(Button, { onClick: () => setShowFieldsDrawer(true) }, /* @__PURE__ */ React.createElement(ExtensionIcon, null))),
63
- /* @__PURE__ */ React.createElement(Tooltip, { title: "Installed Actions Documentation" }, /* @__PURE__ */ React.createElement(Button, { onClick: () => setShowActionsDrawer(true) }, /* @__PURE__ */ React.createElement(DescriptionIcon, null))),
64
- /* @__PURE__ */ React.createElement(Button, { onClick: () => setShowPublishModal(true) }, "Publish")
68
+ /* @__PURE__ */ React.createElement(Button, { onClick: () => setShowFieldsDrawer(true) }, /* @__PURE__ */ React.createElement(ExtensionIcon, null))
65
69
  ), /* @__PURE__ */ React.createElement(
70
+ Tooltip,
71
+ {
72
+ title: t(
73
+ "templateEditorToolbar.installedActionsDocumentationTooltip"
74
+ )
75
+ },
76
+ /* @__PURE__ */ React.createElement(Button, { onClick: () => setShowActionsDrawer(true) }, /* @__PURE__ */ React.createElement(DescriptionIcon, null))
77
+ ), /* @__PURE__ */ React.createElement(Button, { onClick: () => setShowPublishModal(true) }, t("templateEditorToolbar.addToCatalogButton"))), /* @__PURE__ */ React.createElement(
66
78
  Drawer,
67
79
  {
68
80
  classes: { paper: classes.paper },
@@ -88,9 +100,25 @@ function TemplateEditorToolbar(props) {
88
100
  "aria-labelledby": "publish-dialog-title",
89
101
  "aria-describedby": "publish-dialog-description"
90
102
  },
91
- /* @__PURE__ */ React.createElement(DialogTitle, { id: "publish-dialog-title" }, "Publish changes"),
92
- /* @__PURE__ */ React.createElement(DialogContent, { dividers: true }, /* @__PURE__ */ React.createElement(DialogContentText, { id: "publish-dialog-slide-description" }, "Follow the instructions below to create or update a template:", /* @__PURE__ */ React.createElement("ol", null, /* @__PURE__ */ React.createElement("li", null, "Save the template files in a local directory"), /* @__PURE__ */ React.createElement("li", null, "Create a pull request to a new or existing git repository"), /* @__PURE__ */ React.createElement("li", null, "If the template already exists, the changes will be reflected in the software catalog once the pull request gets merged"), /* @__PURE__ */ React.createElement("li", null, "But if you are creating a new template, follow this", " ", /* @__PURE__ */ React.createElement(Link, { to: "https://backstage.io/docs/features/software-templates/adding-templates/" }, "documentation"), " ", "to register the new template repository in software catalog")))),
93
- /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(Button, { color: "primary", onClick: () => setShowPublishModal(false) }, "Close"))
103
+ /* @__PURE__ */ React.createElement(DialogTitle, { id: "publish-dialog-title" }, t("templateEditorToolbar.addToCatalogDialogTitle")),
104
+ /* @__PURE__ */ React.createElement(DialogContent, { dividers: true }, /* @__PURE__ */ React.createElement(DialogContentText, { id: "publish-dialog-slide-description" }, t(
105
+ "templateEditorToolbar.addToCatalogDialogContent.stepsIntroduction"
106
+ ), /* @__PURE__ */ React.createElement("ul", null, t(
107
+ "templateEditorToolbar.addToCatalogDialogContent.stepsListItems"
108
+ ).split("\n").map((step, index) => /* @__PURE__ */ React.createElement("li", { key: index }, step))))),
109
+ /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(
110
+ Button,
111
+ {
112
+ color: "primary",
113
+ href: t(
114
+ "templateEditorToolbar.addToCatalogDialogActions.documentationUrl"
115
+ ),
116
+ target: "_blank"
117
+ },
118
+ t(
119
+ "templateEditorToolbar.addToCatalogDialogActions.documentationButton"
120
+ )
121
+ ))
94
122
  )));
95
123
  }
96
124
 
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateEditorToolbar.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { ReactNode, useState } from 'react';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport AppBar from '@material-ui/core/AppBar';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport ButtonGroup from '@material-ui/core/ButtonGroup';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport ExtensionIcon from '@material-ui/icons/Extension';\nimport DescriptionIcon from '@material-ui/icons/Description';\n\nimport { Link } from '@backstage/core-components';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\n\nimport { ActionPageContent } from '../../../components/ActionsPage/ActionsPage';\nimport { CustomFieldPlaygroud } from './CustomFieldPlaygroud';\n\nconst useStyles = makeStyles(\n theme => ({\n paper: {\n width: '40%',\n padding: theme.spacing(2),\n backgroundColor: theme.palette.background.default,\n },\n appbar: {\n zIndex: 1,\n },\n toolbar: {\n display: 'grid',\n gridTemplateColumns: 'auto 1fr',\n gridGap: theme.spacing(1),\n padding: theme.spacing(0, 1),\n backgroundColor: theme.palette.background.paper,\n },\n toolbarCustomActions: {\n display: 'grid',\n alignItems: 'center',\n gridAutoFlow: 'Column',\n gridGap: theme.spacing(1),\n },\n toolbarDefaultActions: {\n justifySelf: 'end',\n },\n }),\n { name: 'ScaffolderTemplateEditorToolbar' },\n);\n\nexport function TemplateEditorToolbar(props: {\n children?: ReactNode;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n}) {\n const { children, fieldExtensions } = props;\n const classes = useStyles();\n const [showFieldsDrawer, setShowFieldsDrawer] = useState(false);\n const [showActionsDrawer, setShowActionsDrawer] = useState(false);\n const [showPublishModal, setShowPublishModal] = useState(false);\n\n return (\n <AppBar className={classes.appbar} position=\"relative\">\n <Toolbar className={classes.toolbar}>\n <div className={classes.toolbarCustomActions}>{children}</div>\n <ButtonGroup\n className={classes.toolbarDefaultActions}\n variant=\"outlined\"\n color=\"primary\"\n >\n <Tooltip title=\"Custom Fields Explorer\">\n <Button onClick={() => setShowFieldsDrawer(true)}>\n <ExtensionIcon />\n </Button>\n </Tooltip>\n <Tooltip title=\"Installed Actions Documentation\">\n <Button onClick={() => setShowActionsDrawer(true)}>\n <DescriptionIcon />\n </Button>\n </Tooltip>\n <Button onClick={() => setShowPublishModal(true)}>Publish</Button>\n </ButtonGroup>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={showFieldsDrawer}\n onClose={() => setShowFieldsDrawer(false)}\n >\n <CustomFieldPlaygroud fieldExtensions={fieldExtensions} />\n </Drawer>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={showActionsDrawer}\n onClose={() => setShowActionsDrawer(false)}\n >\n <ActionPageContent />\n </Drawer>\n <Dialog\n onClose={() => setShowPublishModal(false)}\n open={showPublishModal}\n aria-labelledby=\"publish-dialog-title\"\n aria-describedby=\"publish-dialog-description\"\n >\n <DialogTitle id=\"publish-dialog-title\">Publish changes</DialogTitle>\n <DialogContent dividers>\n <DialogContentText id=\"publish-dialog-slide-description\">\n Follow the instructions below to create or update a template:\n <ol>\n <li>Save the template files in a local directory</li>\n <li>\n Create a pull request to a new or existing git repository\n </li>\n <li>\n If the template already exists, the changes will be reflected\n in the software catalog once the pull request gets merged\n </li>\n <li>\n But if you are creating a new template, follow this{' '}\n <Link to=\"https://backstage.io/docs/features/software-templates/adding-templates/\">\n documentation\n </Link>{' '}\n to register the new template repository in software catalog\n </li>\n </ol>\n </DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button color=\"primary\" onClick={() => setShowPublishModal(false)}>\n Close\n </Button>\n </DialogActions>\n </Dialog>\n </Toolbar>\n </AppBar>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TemplateEditorToolbar.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { ReactNode, useState } from 'react';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport AppBar from '@material-ui/core/AppBar';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport ButtonGroup from '@material-ui/core/ButtonGroup';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport ExtensionIcon from '@material-ui/icons/Extension';\nimport DescriptionIcon from '@material-ui/icons/Description';\n\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\n\nimport { ActionPageContent } from '../../../components/ActionsPage/ActionsPage';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { CustomFieldPlaygroud } from './CustomFieldPlaygroud';\n\nconst useStyles = makeStyles(\n theme => ({\n paper: {\n width: '90%',\n padding: theme.spacing(2),\n backgroundColor: theme.palette.background.default,\n [theme.breakpoints.up('sm')]: {\n width: '70%',\n },\n [theme.breakpoints.up('md')]: {\n width: '50%',\n },\n },\n appbar: {\n zIndex: 1,\n },\n toolbar: {\n display: 'grid',\n gridTemplateColumns: 'auto 1fr',\n gridGap: theme.spacing(1),\n padding: theme.spacing(0, 1),\n backgroundColor: theme.palette.background.paper,\n },\n toolbarCustomActions: {\n display: 'grid',\n alignItems: 'center',\n gridAutoFlow: 'Column',\n gridGap: theme.spacing(1),\n },\n toolbarDefaultActions: {\n justifySelf: 'end',\n },\n }),\n { name: 'ScaffolderTemplateEditorToolbar' },\n);\n\nexport function TemplateEditorToolbar(props: {\n children?: ReactNode;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n}) {\n const { children, fieldExtensions } = props;\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const [showFieldsDrawer, setShowFieldsDrawer] = useState(false);\n const [showActionsDrawer, setShowActionsDrawer] = useState(false);\n const [showPublishModal, setShowPublishModal] = useState(false);\n\n return (\n <AppBar className={classes.appbar} position=\"relative\">\n <Toolbar className={classes.toolbar}>\n <div className={classes.toolbarCustomActions}>{children}</div>\n <ButtonGroup className={classes.toolbarDefaultActions} variant=\"text\">\n <Tooltip\n title={t('templateEditorToolbar.customFieldExplorerTooltip')}\n >\n <Button onClick={() => setShowFieldsDrawer(true)}>\n <ExtensionIcon />\n </Button>\n </Tooltip>\n <Tooltip\n title={t(\n 'templateEditorToolbar.installedActionsDocumentationTooltip',\n )}\n >\n <Button onClick={() => setShowActionsDrawer(true)}>\n <DescriptionIcon />\n </Button>\n </Tooltip>\n <Button onClick={() => setShowPublishModal(true)}>\n {t('templateEditorToolbar.addToCatalogButton')}\n </Button>\n </ButtonGroup>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={showFieldsDrawer}\n onClose={() => setShowFieldsDrawer(false)}\n >\n <CustomFieldPlaygroud fieldExtensions={fieldExtensions} />\n </Drawer>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={showActionsDrawer}\n onClose={() => setShowActionsDrawer(false)}\n >\n <ActionPageContent />\n </Drawer>\n <Dialog\n onClose={() => setShowPublishModal(false)}\n open={showPublishModal}\n aria-labelledby=\"publish-dialog-title\"\n aria-describedby=\"publish-dialog-description\"\n >\n <DialogTitle id=\"publish-dialog-title\">\n {t('templateEditorToolbar.addToCatalogDialogTitle')}\n </DialogTitle>\n <DialogContent dividers>\n <DialogContentText id=\"publish-dialog-slide-description\">\n {t(\n 'templateEditorToolbar.addToCatalogDialogContent.stepsIntroduction',\n )}\n <ul>\n {t(\n 'templateEditorToolbar.addToCatalogDialogContent.stepsListItems',\n )\n .split('\\n')\n .map((step, index) => (\n <li key={index}>{step}</li>\n ))}\n </ul>\n </DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button\n color=\"primary\"\n href={t(\n 'templateEditorToolbar.addToCatalogDialogActions.documentationUrl',\n )}\n target=\"_blank\"\n >\n {t(\n 'templateEditorToolbar.addToCatalogDialogActions.documentationButton',\n )}\n </Button>\n </DialogActions>\n </Dialog>\n </Toolbar>\n </AppBar>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import React, { useState, useCallback } from 'react';
2
+ import Button from '@material-ui/core/Button';
3
+ import Menu from '@material-ui/core/Menu';
4
+ import MenuItem from '@material-ui/core/MenuItem';
5
+ import { useTranslationRef } from '@backstage/frontend-plugin-api';
6
+ import { scaffolderTranslationRef } from '../../../translation.esm.js';
7
+
8
+ function TemplateEditorToolbarFileMenu(props) {
9
+ const { onOpenDirectory, onCreateDirectory, onCloseDirectory } = props;
10
+ const { t } = useTranslationRef(scaffolderTranslationRef);
11
+ const [anchorEl, setAnchorEl] = useState(null);
12
+ const handleOpenMenu = useCallback(
13
+ (event) => {
14
+ setAnchorEl(event.currentTarget);
15
+ },
16
+ [setAnchorEl]
17
+ );
18
+ const handleCloseMenu = useCallback(() => {
19
+ setAnchorEl(null);
20
+ }, [setAnchorEl]);
21
+ const handleOpenDirectory = useCallback(() => {
22
+ handleCloseMenu();
23
+ onOpenDirectory?.();
24
+ }, [handleCloseMenu, onOpenDirectory]);
25
+ const handleCreateDirectory = useCallback(() => {
26
+ handleCloseMenu();
27
+ onCreateDirectory?.();
28
+ }, [handleCloseMenu, onCreateDirectory]);
29
+ const handleCloseEditor = useCallback(() => {
30
+ handleCloseMenu();
31
+ onCloseDirectory?.();
32
+ }, [handleCloseMenu, onCloseDirectory]);
33
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
34
+ Button,
35
+ {
36
+ "aria-controls": "file-menu",
37
+ "aria-haspopup": "true",
38
+ onClick: handleOpenMenu
39
+ },
40
+ t("templateEditorToolbarFileMenu.button")
41
+ ), /* @__PURE__ */ React.createElement(
42
+ Menu,
43
+ {
44
+ id: "file-menu",
45
+ anchorEl,
46
+ open: Boolean(anchorEl),
47
+ onClose: handleCloseMenu,
48
+ getContentAnchorEl: null,
49
+ anchorOrigin: {
50
+ vertical: "bottom",
51
+ horizontal: "left"
52
+ },
53
+ transformOrigin: {
54
+ vertical: "top",
55
+ horizontal: "left"
56
+ }
57
+ },
58
+ /* @__PURE__ */ React.createElement(MenuItem, { onClick: handleOpenDirectory, disabled: !onOpenDirectory }, t("templateEditorToolbarFileMenu.options.openDirectory")),
59
+ /* @__PURE__ */ React.createElement(
60
+ MenuItem,
61
+ {
62
+ onClick: handleCreateDirectory,
63
+ disabled: !onCreateDirectory,
64
+ divider: true
65
+ },
66
+ t("templateEditorToolbarFileMenu.options.createDirectory")
67
+ ),
68
+ /* @__PURE__ */ React.createElement(MenuItem, { onClick: handleCloseEditor, disabled: !onCloseDirectory }, t("templateEditorToolbarFileMenu.options.closeEditor"))
69
+ ));
70
+ }
71
+
72
+ export { TemplateEditorToolbarFileMenu };
73
+ //# sourceMappingURL=TemplateEditorToolbarFileMenu.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateEditorToolbarFileMenu.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorToolbarFileMenu.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { MouseEvent, useCallback, useState } from 'react';\n\nimport Button from '@material-ui/core/Button';\nimport Menu from '@material-ui/core/Menu';\nimport MenuItem from '@material-ui/core/MenuItem';\n\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\n\nimport { scaffolderTranslationRef } from '../../../translation';\n\nexport function TemplateEditorToolbarFileMenu(props: {\n onOpenDirectory?: () => void;\n onCreateDirectory?: () => void;\n onCloseDirectory?: () => void;\n}) {\n const { onOpenDirectory, onCreateDirectory, onCloseDirectory } = props;\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n\n const handleOpenMenu = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n },\n [setAnchorEl],\n );\n\n const handleCloseMenu = useCallback(() => {\n setAnchorEl(null);\n }, [setAnchorEl]);\n\n const handleOpenDirectory = useCallback(() => {\n handleCloseMenu();\n onOpenDirectory?.();\n }, [handleCloseMenu, onOpenDirectory]);\n\n const handleCreateDirectory = useCallback(() => {\n handleCloseMenu();\n onCreateDirectory?.();\n }, [handleCloseMenu, onCreateDirectory]);\n\n const handleCloseEditor = useCallback(() => {\n handleCloseMenu();\n onCloseDirectory?.();\n }, [handleCloseMenu, onCloseDirectory]);\n\n return (\n <>\n <Button\n aria-controls=\"file-menu\"\n aria-haspopup=\"true\"\n onClick={handleOpenMenu}\n >\n {t('templateEditorToolbarFileMenu.button')}\n </Button>\n <Menu\n id=\"file-menu\"\n anchorEl={anchorEl}\n open={Boolean(anchorEl)}\n onClose={handleCloseMenu}\n getContentAnchorEl={null}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'left',\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'left',\n }}\n >\n <MenuItem onClick={handleOpenDirectory} disabled={!onOpenDirectory}>\n {t('templateEditorToolbarFileMenu.options.openDirectory')}\n </MenuItem>\n <MenuItem\n onClick={handleCreateDirectory}\n disabled={!onCreateDirectory}\n divider\n >\n {t('templateEditorToolbarFileMenu.options.createDirectory')}\n </MenuItem>\n <MenuItem onClick={handleCloseEditor} disabled={!onCloseDirectory}>\n {t('templateEditorToolbarFileMenu.options.closeEditor')}\n </MenuItem>\n </Menu>\n </>\n );\n}\n"],"names":[],"mappings":";;;;;;;AA0BO,SAAS,8BAA8B,KAI3C,EAAA;AACD,EAAA,MAAM,EAAE,eAAA,EAAiB,iBAAmB,EAAA,gBAAA,EAAqB,GAAA,KAAA,CAAA;AACjE,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,wBAAwB,CAAA,CAAA;AACxD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAA6B,IAAI,CAAA,CAAA;AAEjE,EAAA,MAAM,cAAiB,GAAA,WAAA;AAAA,IACrB,CAAC,KAAyC,KAAA;AACxC,MAAA,WAAA,CAAY,MAAM,aAAa,CAAA,CAAA;AAAA,KACjC;AAAA,IACA,CAAC,WAAW,CAAA;AAAA,GACd,CAAA;AAEA,EAAM,MAAA,eAAA,GAAkB,YAAY,MAAM;AACxC,IAAA,WAAA,CAAY,IAAI,CAAA,CAAA;AAAA,GAClB,EAAG,CAAC,WAAW,CAAC,CAAA,CAAA;AAEhB,EAAM,MAAA,mBAAA,GAAsB,YAAY,MAAM;AAC5C,IAAgB,eAAA,EAAA,CAAA;AAChB,IAAkB,eAAA,IAAA,CAAA;AAAA,GACjB,EAAA,CAAC,eAAiB,EAAA,eAAe,CAAC,CAAA,CAAA;AAErC,EAAM,MAAA,qBAAA,GAAwB,YAAY,MAAM;AAC9C,IAAgB,eAAA,EAAA,CAAA;AAChB,IAAoB,iBAAA,IAAA,CAAA;AAAA,GACnB,EAAA,CAAC,eAAiB,EAAA,iBAAiB,CAAC,CAAA,CAAA;AAEvC,EAAM,MAAA,iBAAA,GAAoB,YAAY,MAAM;AAC1C,IAAgB,eAAA,EAAA,CAAA;AAChB,IAAmB,gBAAA,IAAA,CAAA;AAAA,GAClB,EAAA,CAAC,eAAiB,EAAA,gBAAgB,CAAC,CAAA,CAAA;AAEtC,EAAA,uBAEI,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,eAAc,EAAA,WAAA;AAAA,MACd,eAAc,EAAA,MAAA;AAAA,MACd,OAAS,EAAA,cAAA;AAAA,KAAA;AAAA,IAER,EAAE,sCAAsC,CAAA;AAAA,GAE3C,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,EAAG,EAAA,WAAA;AAAA,MACH,QAAA;AAAA,MACA,IAAA,EAAM,QAAQ,QAAQ,CAAA;AAAA,MACtB,OAAS,EAAA,eAAA;AAAA,MACT,kBAAoB,EAAA,IAAA;AAAA,MACpB,YAAc,EAAA;AAAA,QACZ,QAAU,EAAA,QAAA;AAAA,QACV,UAAY,EAAA,MAAA;AAAA,OACd;AAAA,MACA,eAAiB,EAAA;AAAA,QACf,QAAU,EAAA,KAAA;AAAA,QACV,UAAY,EAAA,MAAA;AAAA,OACd;AAAA,KAAA;AAAA,oBAEA,KAAA,CAAA,aAAA,CAAC,YAAS,OAAS,EAAA,mBAAA,EAAqB,UAAU,CAAC,eAAA,EAAA,EAChD,CAAE,CAAA,qDAAqD,CAC1D,CAAA;AAAA,oBACA,KAAA,CAAA,aAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,OAAS,EAAA,qBAAA;AAAA,QACT,UAAU,CAAC,iBAAA;AAAA,QACX,OAAO,EAAA,IAAA;AAAA,OAAA;AAAA,MAEN,EAAE,uDAAuD,CAAA;AAAA,KAC5D;AAAA,oBACA,KAAA,CAAA,aAAA,CAAC,YAAS,OAAS,EAAA,iBAAA,EAAmB,UAAU,CAAC,gBAAA,EAAA,EAC9C,CAAE,CAAA,mDAAmD,CACxD,CAAA;AAAA,GAEJ,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,84 @@
1
+ import React, { useState, useCallback } from 'react';
2
+ import { makeStyles } from '@material-ui/core/styles';
3
+ import Button from '@material-ui/core/Button';
4
+ import Menu from '@material-ui/core/Menu';
5
+ import MenuItem from '@material-ui/core/MenuItem';
6
+ import { useTranslationRef } from '@backstage/frontend-plugin-api';
7
+ import { scaffolderTranslationRef } from '../../../translation.esm.js';
8
+
9
+ const ITEM_HEIGHT = 48;
10
+ const useStyles = makeStyles({
11
+ menu: {
12
+ maxHeight: ITEM_HEIGHT * 5
13
+ }
14
+ });
15
+ function TemplateEditorToolbarTemplatesMenu(props) {
16
+ const { options, selectedOption, onSelectOption } = props;
17
+ const classes = useStyles();
18
+ const [anchorEl, setAnchorEl] = useState(null);
19
+ const { t } = useTranslationRef(scaffolderTranslationRef);
20
+ const isSelectedOption = useCallback(
21
+ (option) => {
22
+ return !!selectedOption && selectedOption.value === option.value;
23
+ },
24
+ [selectedOption]
25
+ );
26
+ const handleOpenMenu = useCallback(
27
+ (event) => {
28
+ setAnchorEl(event.currentTarget);
29
+ },
30
+ [setAnchorEl]
31
+ );
32
+ const handleCloseMenu = useCallback(() => {
33
+ setAnchorEl(null);
34
+ }, [setAnchorEl]);
35
+ const handleSelectOption = useCallback(
36
+ (option) => {
37
+ handleCloseMenu();
38
+ onSelectOption(option);
39
+ },
40
+ [handleCloseMenu, onSelectOption]
41
+ );
42
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
43
+ Button,
44
+ {
45
+ "aria-controls": "templates-menu",
46
+ "aria-haspopup": "true",
47
+ onClick: handleOpenMenu
48
+ },
49
+ t("templateEditorToolbarTemplatesMenu.button")
50
+ ), /* @__PURE__ */ React.createElement(
51
+ Menu,
52
+ {
53
+ id: "templates-menu",
54
+ anchorEl,
55
+ open: Boolean(anchorEl),
56
+ onClose: handleCloseMenu,
57
+ getContentAnchorEl: null,
58
+ anchorOrigin: {
59
+ vertical: "bottom",
60
+ horizontal: "left"
61
+ },
62
+ transformOrigin: {
63
+ vertical: "top",
64
+ horizontal: "left"
65
+ },
66
+ PaperProps: {
67
+ className: classes.menu
68
+ }
69
+ },
70
+ options.map((option, index) => /* @__PURE__ */ React.createElement(
71
+ MenuItem,
72
+ {
73
+ key: index,
74
+ selected: isSelectedOption(option),
75
+ "aria-selected": isSelectedOption(option),
76
+ onClick: () => handleSelectOption(option)
77
+ },
78
+ option.label
79
+ ))
80
+ ));
81
+ }
82
+
83
+ export { TemplateEditorToolbarTemplatesMenu };
84
+ //# sourceMappingURL=TemplateEditorToolbarTemplatesMenu.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateEditorToolbarTemplatesMenu.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorToolbarTemplatesMenu.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { MouseEvent, useCallback, useState } from 'react';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Button from '@material-ui/core/Button';\nimport Menu from '@material-ui/core/Menu';\nimport MenuItem from '@material-ui/core/MenuItem';\n\nimport { Entity } from '@backstage/catalog-model';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { scaffolderTranslationRef } from '../../../translation';\n\nconst ITEM_HEIGHT = 48;\n\nconst useStyles = makeStyles({\n menu: {\n maxHeight: ITEM_HEIGHT * 5,\n },\n});\n\nexport type TemplateOption = {\n label: string;\n value: Entity;\n};\n\nexport function TemplateEditorToolbarTemplatesMenu(props: {\n options: TemplateOption[];\n selectedOption?: TemplateOption;\n onSelectOption: (option: TemplateOption) => void;\n}) {\n const { options, selectedOption, onSelectOption } = props;\n const classes = useStyles();\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const isSelectedOption = useCallback(\n (option: TemplateOption) => {\n return !!selectedOption && selectedOption.value === option.value;\n },\n [selectedOption],\n );\n\n const handleOpenMenu = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n setAnchorEl(event.currentTarget);\n },\n [setAnchorEl],\n );\n\n const handleCloseMenu = useCallback(() => {\n setAnchorEl(null);\n }, [setAnchorEl]);\n\n const handleSelectOption = useCallback(\n (option: TemplateOption) => {\n handleCloseMenu();\n onSelectOption(option);\n },\n [handleCloseMenu, onSelectOption],\n );\n\n return (\n <>\n <Button\n aria-controls=\"templates-menu\"\n aria-haspopup=\"true\"\n onClick={handleOpenMenu}\n >\n {t('templateEditorToolbarTemplatesMenu.button')}\n </Button>\n <Menu\n id=\"templates-menu\"\n anchorEl={anchorEl}\n open={Boolean(anchorEl)}\n onClose={handleCloseMenu}\n getContentAnchorEl={null}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'left',\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'left',\n }}\n PaperProps={{\n className: classes.menu,\n }}\n >\n {options.map((option, index) => (\n <MenuItem\n key={index}\n selected={isSelectedOption(option)}\n aria-selected={isSelectedOption(option)}\n onClick={() => handleSelectOption(option)}\n >\n {option.label}\n </MenuItem>\n ))}\n </Menu>\n </>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -25,7 +25,9 @@ function TemplateFormPage(props) {
25
25
  Header,
26
26
  {
27
27
  title: t("templateFormPage.title"),
28
- subtitle: t("templateFormPage.subtitle")
28
+ subtitle: t("templateFormPage.subtitle"),
29
+ type: t("templateIntroPage.title"),
30
+ typeLink: editLink()
29
31
  }
30
32
  ), /* @__PURE__ */ React.createElement(Content, { className: classes.root }, /* @__PURE__ */ React.createElement(
31
33
  TemplateFormPreviewer,
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateFormPage.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useCallback } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { Page, Header, Content } from '@backstage/core-components';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport {\n FormProps,\n LayoutOptions,\n FieldExtensionOptions,\n} from '@backstage/plugin-scaffolder-react';\n\nimport { editRouteRef } from '../../../routes';\nimport { scaffolderTranslationRef } from '../../../translation';\n\nimport { TemplateFormPreviewer } from './TemplateFormPreviewer';\n\nconst useStyles = makeStyles({\n root: {\n padding: 0,\n },\n});\n\ninterface TemplateFormPageProps {\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n defaultPreviewTemplate?: string;\n}\n\nexport function TemplateFormPage(props: TemplateFormPageProps) {\n const classes = useStyles();\n const navigate = useNavigate();\n const editLink = useRouteRef(editRouteRef);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const handleClose = useCallback(() => {\n navigate(editLink());\n }, [navigate, editLink]);\n\n return (\n <Page themeId=\"home\">\n <Header\n title={t('templateFormPage.title')}\n subtitle={t('templateFormPage.subtitle')}\n />\n <Content className={classes.root}>\n <TemplateFormPreviewer\n layouts={props.layouts}\n formProps={props.formProps}\n customFieldExtensions={props.fieldExtensions}\n defaultPreviewTemplate={props.defaultPreviewTemplate}\n onClose={handleClose}\n />\n </Content>\n </Page>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;AAmCA,MAAM,YAAY,UAAW,CAAA;AAAA,EAC3B,IAAM,EAAA;AAAA,IACJ,OAAS,EAAA,CAAA;AAAA,GACX;AACF,CAAC,CAAA,CAAA;AASM,SAAS,iBAAiB,KAA8B,EAAA;AAC7D,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,WAAW,WAAY,EAAA,CAAA;AAC7B,EAAM,MAAA,QAAA,GAAW,YAAY,YAAY,CAAA,CAAA;AACzC,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,wBAAwB,CAAA,CAAA;AAExD,EAAM,MAAA,WAAA,GAAc,YAAY,MAAM;AACpC,IAAA,QAAA,CAAS,UAAU,CAAA,CAAA;AAAA,GAClB,EAAA,CAAC,QAAU,EAAA,QAAQ,CAAC,CAAA,CAAA;AAEvB,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,wBAAwB,CAAA;AAAA,MACjC,QAAA,EAAU,EAAE,2BAA2B,CAAA;AAAA,KAAA;AAAA,GAEzC,kBAAA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,SAAA,EAAW,QAAQ,IAC1B,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,qBAAA;AAAA,IAAA;AAAA,MACC,SAAS,KAAM,CAAA,OAAA;AAAA,MACf,WAAW,KAAM,CAAA,SAAA;AAAA,MACjB,uBAAuB,KAAM,CAAA,eAAA;AAAA,MAC7B,wBAAwB,KAAM,CAAA,sBAAA;AAAA,MAC9B,OAAS,EAAA,WAAA;AAAA,KAAA;AAAA,GAEb,CACF,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"TemplateFormPage.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useCallback } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { Page, Header, Content } from '@backstage/core-components';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport {\n FormProps,\n LayoutOptions,\n FieldExtensionOptions,\n} from '@backstage/plugin-scaffolder-react';\n\nimport { editRouteRef } from '../../../routes';\nimport { scaffolderTranslationRef } from '../../../translation';\n\nimport { TemplateFormPreviewer } from './TemplateFormPreviewer';\n\nconst useStyles = makeStyles({\n root: {\n padding: 0,\n },\n});\n\ninterface TemplateFormPageProps {\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n defaultPreviewTemplate?: string;\n}\n\nexport function TemplateFormPage(props: TemplateFormPageProps) {\n const classes = useStyles();\n const navigate = useNavigate();\n const editLink = useRouteRef(editRouteRef);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const handleClose = useCallback(() => {\n navigate(editLink());\n }, [navigate, editLink]);\n\n return (\n <Page themeId=\"home\">\n <Header\n title={t('templateFormPage.title')}\n subtitle={t('templateFormPage.subtitle')}\n type={t('templateIntroPage.title')}\n typeLink={editLink()}\n />\n <Content className={classes.root}>\n <TemplateFormPreviewer\n layouts={props.layouts}\n formProps={props.formProps}\n customFieldExtensions={props.fieldExtensions}\n defaultPreviewTemplate={props.defaultPreviewTemplate}\n onClose={handleClose}\n />\n </Content>\n </Page>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;AAmCA,MAAM,YAAY,UAAW,CAAA;AAAA,EAC3B,IAAM,EAAA;AAAA,IACJ,OAAS,EAAA,CAAA;AAAA,GACX;AACF,CAAC,CAAA,CAAA;AASM,SAAS,iBAAiB,KAA8B,EAAA;AAC7D,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,WAAW,WAAY,EAAA,CAAA;AAC7B,EAAM,MAAA,QAAA,GAAW,YAAY,YAAY,CAAA,CAAA;AACzC,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,wBAAwB,CAAA,CAAA;AAExD,EAAM,MAAA,WAAA,GAAc,YAAY,MAAM;AACpC,IAAA,QAAA,CAAS,UAAU,CAAA,CAAA;AAAA,GAClB,EAAA,CAAC,QAAU,EAAA,QAAQ,CAAC,CAAA,CAAA;AAEvB,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,wBAAwB,CAAA;AAAA,MACjC,QAAA,EAAU,EAAE,2BAA2B,CAAA;AAAA,MACvC,IAAA,EAAM,EAAE,yBAAyB,CAAA;AAAA,MACjC,UAAU,QAAS,EAAA;AAAA,KAAA;AAAA,GAErB,kBAAA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,SAAA,EAAW,QAAQ,IAC1B,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,qBAAA;AAAA,IAAA;AAAA,MACC,SAAS,KAAM,CAAA,OAAA;AAAA,MACf,WAAW,KAAM,CAAA,SAAA;AAAA,MACjB,uBAAuB,KAAM,CAAA,eAAA;AAAA,MAC7B,wBAAwB,KAAM,CAAA,sBAAA;AAAA,MAC9B,OAAS,EAAA,WAAA;AAAA,KAAA;AAAA,GAEb,CACF,CAAA,CAAA;AAEJ;;;;"}