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

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 (136) hide show
  1. package/CHANGELOG.md +59 -5
  2. package/alpha/package.json +1 -1
  3. package/dist/alpha/api/FormFieldsApi.esm.js +40 -0
  4. package/dist/alpha/api/FormFieldsApi.esm.js.map +1 -0
  5. package/dist/alpha/api/ref.esm.js +8 -0
  6. package/dist/alpha/api/ref.esm.js.map +1 -0
  7. package/dist/alpha/api.esm.js +27 -0
  8. package/dist/alpha/api.esm.js.map +1 -0
  9. package/dist/{next → alpha/components}/TemplateEditorPage/CustomFieldExplorer.esm.js +1 -1
  10. package/dist/alpha/components/TemplateEditorPage/CustomFieldExplorer.esm.js.map +1 -0
  11. package/dist/alpha/components/TemplateEditorPage/CustomFieldPlaygroud.esm.js +167 -0
  12. package/dist/alpha/components/TemplateEditorPage/CustomFieldPlaygroud.esm.js.map +1 -0
  13. package/dist/alpha/components/TemplateEditorPage/CustomFieldsPage.esm.js +33 -0
  14. package/dist/alpha/components/TemplateEditorPage/CustomFieldsPage.esm.js.map +1 -0
  15. package/dist/{next → alpha/components}/TemplateEditorPage/DirectoryEditorContext.esm.js +4 -7
  16. package/dist/alpha/components/TemplateEditorPage/DirectoryEditorContext.esm.js.map +1 -0
  17. package/dist/alpha/components/TemplateEditorPage/DryRunContext.esm.js.map +1 -0
  18. package/dist/{next → alpha/components}/TemplateEditorPage/DryRunResults/DryRunResults.esm.js +1 -1
  19. package/dist/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.esm.js.map +1 -0
  20. package/dist/{next → alpha/components}/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js +2 -2
  21. package/dist/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js.map +1 -0
  22. package/dist/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.esm.js.map +1 -0
  23. package/dist/{next → alpha/components}/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js +2 -2
  24. package/dist/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js.map +1 -0
  25. package/dist/alpha/components/TemplateEditorPage/DryRunResults/IconLink.esm.js.map +1 -0
  26. package/dist/alpha/components/TemplateEditorPage/DryRunResults/TaskPageLinks.esm.js.map +1 -0
  27. package/dist/{next → alpha/components}/TemplateEditorPage/DryRunResults/TaskStatusStepper.esm.js +1 -1
  28. package/dist/alpha/components/TemplateEditorPage/DryRunResults/TaskStatusStepper.esm.js.map +1 -0
  29. package/dist/alpha/components/TemplateEditorPage/TemplateEditor.esm.js +94 -0
  30. package/dist/alpha/components/TemplateEditorPage/TemplateEditor.esm.js.map +1 -0
  31. package/dist/{next → alpha/components}/TemplateEditorPage/TemplateEditorBrowser.esm.js +36 -38
  32. package/dist/alpha/components/TemplateEditorPage/TemplateEditorBrowser.esm.js.map +1 -0
  33. package/dist/{next → alpha/components}/TemplateEditorPage/TemplateEditorForm.esm.js +12 -20
  34. package/dist/alpha/components/TemplateEditorPage/TemplateEditorForm.esm.js.map +1 -0
  35. package/dist/alpha/components/TemplateEditorPage/TemplateEditorIntro.esm.js +146 -0
  36. package/dist/alpha/components/TemplateEditorPage/TemplateEditorIntro.esm.js.map +1 -0
  37. package/dist/alpha/components/TemplateEditorPage/TemplateEditorPage.esm.js +53 -0
  38. package/dist/alpha/components/TemplateEditorPage/TemplateEditorPage.esm.js.map +1 -0
  39. package/dist/{next → alpha/components}/TemplateEditorPage/TemplateEditorTextArea.esm.js +36 -3
  40. package/dist/alpha/components/TemplateEditorPage/TemplateEditorTextArea.esm.js.map +1 -0
  41. package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbar.esm.js +98 -0
  42. package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbar.esm.js.map +1 -0
  43. package/dist/alpha/components/TemplateEditorPage/TemplateFormPage.esm.js +43 -0
  44. package/dist/alpha/components/TemplateEditorPage/TemplateFormPage.esm.js.map +1 -0
  45. package/dist/{next → alpha/components}/TemplateEditorPage/TemplateFormPreviewer.esm.js +77 -39
  46. package/dist/alpha/components/TemplateEditorPage/TemplateFormPreviewer.esm.js.map +1 -0
  47. package/dist/alpha/components/TemplateEditorPage/TemplatePage.esm.js +52 -0
  48. package/dist/alpha/components/TemplateEditorPage/TemplatePage.esm.js.map +1 -0
  49. package/dist/{next → alpha/components}/TemplateListPage/RegisterExistingButton.esm.js +1 -1
  50. package/dist/alpha/components/TemplateListPage/RegisterExistingButton.esm.js.map +1 -0
  51. package/dist/{next → alpha/components}/TemplateListPage/TemplateListPage.esm.js +2 -2
  52. package/dist/alpha/components/TemplateListPage/TemplateListPage.esm.js.map +1 -0
  53. package/dist/{next → alpha/components}/TemplateWizardPage/TemplateWizardPage.esm.js +2 -2
  54. package/dist/alpha/components/TemplateWizardPage/TemplateWizardPage.esm.js.map +1 -0
  55. package/dist/{next → alpha/components}/TemplateWizardPage/TemplateWizardPageContextMenu.esm.js +1 -1
  56. package/dist/alpha/components/TemplateWizardPage/TemplateWizardPageContextMenu.esm.js.map +1 -0
  57. package/dist/alpha/extensions.esm.js +30 -0
  58. package/dist/alpha/extensions.esm.js.map +1 -0
  59. package/dist/alpha/fields/RepoUrlPicker.esm.js +37 -0
  60. package/dist/alpha/fields/RepoUrlPicker.esm.js.map +1 -0
  61. package/dist/alpha/plugin.esm.js +32 -0
  62. package/dist/alpha/plugin.esm.js.map +1 -0
  63. package/dist/alpha.d.ts +80 -9
  64. package/dist/alpha.esm.js +1 -60
  65. package/dist/alpha.esm.js.map +1 -1
  66. package/dist/api.esm.js +19 -5
  67. package/dist/api.esm.js.map +1 -1
  68. package/dist/components/ActionsPage/ActionsPage.esm.js +30 -5
  69. package/dist/components/ActionsPage/ActionsPage.esm.js.map +1 -1
  70. package/dist/components/FileBrowser/FileBrowser.esm.js +4 -3
  71. package/dist/components/FileBrowser/FileBrowser.esm.js.map +1 -1
  72. package/dist/components/ListTasksPage/ListTasksPage.esm.js +17 -3
  73. package/dist/components/ListTasksPage/ListTasksPage.esm.js.map +1 -1
  74. package/dist/components/ListTasksPage/OwnerListPicker.esm.js +2 -2
  75. package/dist/components/ListTasksPage/OwnerListPicker.esm.js.map +1 -1
  76. package/dist/components/ListTasksPage/columns/CreatedAtColumn.esm.js +10 -5
  77. package/dist/components/ListTasksPage/columns/CreatedAtColumn.esm.js.map +1 -1
  78. package/dist/components/OngoingTask/ContextMenu.esm.js +15 -2
  79. package/dist/components/OngoingTask/ContextMenu.esm.js.map +1 -1
  80. package/dist/components/OngoingTask/OngoingTask.esm.js +24 -1
  81. package/dist/components/OngoingTask/OngoingTask.esm.js.map +1 -1
  82. package/dist/components/Router/Router.esm.js +35 -7
  83. package/dist/components/Router/Router.esm.js.map +1 -1
  84. package/dist/components/fields/EntityPicker/EntityPicker.esm.js +1 -1
  85. package/dist/components/fields/EntityPicker/EntityPicker.esm.js.map +1 -1
  86. package/dist/components/fields/MultiEntityPicker/MultiEntityPicker.esm.js +1 -0
  87. package/dist/components/fields/MultiEntityPicker/MultiEntityPicker.esm.js.map +1 -1
  88. package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js.map +1 -1
  89. package/dist/components/fields/RepoUrlPicker/schema.esm.js +5 -6
  90. package/dist/components/fields/RepoUrlPicker/schema.esm.js.map +1 -1
  91. package/dist/components/fields/utils.esm.js +2 -1
  92. package/dist/components/fields/utils.esm.js.map +1 -1
  93. package/dist/index.d.ts +13 -8
  94. package/dist/lib/filesystem/WebFileSystemAccess.esm.js +34 -1
  95. package/dist/lib/filesystem/WebFileSystemAccess.esm.js.map +1 -1
  96. package/dist/lib/filesystem/createExampleTemplate.esm.js +76 -0
  97. package/dist/lib/filesystem/createExampleTemplate.esm.js.map +1 -0
  98. package/dist/packages/opaque-internal/src/OpaqueType.esm.js +103 -0
  99. package/dist/packages/opaque-internal/src/OpaqueType.esm.js.map +1 -0
  100. package/dist/packages/scaffolder-internal/src/wiring/InternalFormField.esm.js +6 -0
  101. package/dist/packages/scaffolder-internal/src/wiring/InternalFormField.esm.js.map +1 -0
  102. package/dist/plugin.esm.js +5 -2
  103. package/dist/plugin.esm.js.map +1 -1
  104. package/dist/routes.esm.js +16 -1
  105. package/dist/routes.esm.js.map +1 -1
  106. package/dist/translation.esm.js +22 -3
  107. package/dist/translation.esm.js.map +1 -1
  108. package/package.json +34 -23
  109. package/dist/next/TemplateEditorPage/CustomFieldExplorer.esm.js.map +0 -1
  110. package/dist/next/TemplateEditorPage/DirectoryEditorContext.esm.js.map +0 -1
  111. package/dist/next/TemplateEditorPage/DryRunContext.esm.js.map +0 -1
  112. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResults.esm.js.map +0 -1
  113. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js.map +0 -1
  114. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.esm.js.map +0 -1
  115. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js.map +0 -1
  116. package/dist/next/TemplateEditorPage/DryRunResults/IconLink.esm.js.map +0 -1
  117. package/dist/next/TemplateEditorPage/DryRunResults/TaskPageLinks.esm.js.map +0 -1
  118. package/dist/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.esm.js.map +0 -1
  119. package/dist/next/TemplateEditorPage/TemplateEditor.esm.js +0 -56
  120. package/dist/next/TemplateEditorPage/TemplateEditor.esm.js.map +0 -1
  121. package/dist/next/TemplateEditorPage/TemplateEditorBrowser.esm.js.map +0 -1
  122. package/dist/next/TemplateEditorPage/TemplateEditorForm.esm.js.map +0 -1
  123. package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js +0 -91
  124. package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js.map +0 -1
  125. package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js +0 -87
  126. package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js.map +0 -1
  127. package/dist/next/TemplateEditorPage/TemplateEditorTextArea.esm.js.map +0 -1
  128. package/dist/next/TemplateEditorPage/TemplateFormPreviewer.esm.js.map +0 -1
  129. package/dist/next/TemplateListPage/RegisterExistingButton.esm.js.map +0 -1
  130. package/dist/next/TemplateListPage/TemplateListPage.esm.js.map +0 -1
  131. package/dist/next/TemplateWizardPage/TemplateWizardPage.esm.js.map +0 -1
  132. package/dist/next/TemplateWizardPage/TemplateWizardPageContextMenu.esm.js.map +0 -1
  133. /package/dist/{next → alpha/components}/TemplateEditorPage/DryRunContext.esm.js +0 -0
  134. /package/dist/{next → alpha/components}/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.esm.js +0 -0
  135. /package/dist/{next → alpha/components}/TemplateEditorPage/DryRunResults/IconLink.esm.js +0 -0
  136. /package/dist/{next → alpha/components}/TemplateEditorPage/DryRunResults/TaskPageLinks.esm.js +0 -0
@@ -10,11 +10,11 @@ import CodeMirror from '@uiw/react-codemirror';
10
10
  import React, { useState, useEffect, useMemo } from 'react';
11
11
  import { useDryRun } from '../DryRunContext.esm.js';
12
12
  import { DryRunResultsSplitView } from './DryRunResultsSplitView.esm.js';
13
- import { FileBrowser } from '../../../components/FileBrowser/FileBrowser.esm.js';
13
+ import { FileBrowser } from '../../../../components/FileBrowser/FileBrowser.esm.js';
14
14
  import { TaskPageLinks } from './TaskPageLinks.esm.js';
15
15
  import { TaskStatusStepper } from './TaskStatusStepper.esm.js';
16
16
  import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
17
- import { scaffolderTranslationRef } from '../../../translation.esm.js';
17
+ import { scaffolderTranslationRef } from '../../../../translation.esm.js';
18
18
 
19
19
  const useStyles = makeStyles({
20
20
  root: {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DryRunResultsView.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LogViewer } from '@backstage/core-components';\nimport { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\nimport Box from '@material-ui/core/Box';\nimport Divider from '@material-ui/core/Divider';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Tab from '@material-ui/core/Tab';\nimport Tabs from '@material-ui/core/Tabs';\nimport CodeMirror from '@uiw/react-codemirror';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { useDryRun } from '../DryRunContext';\nimport { DryRunResultsSplitView } from './DryRunResultsSplitView';\nimport { FileBrowser } from '../../../../components/FileBrowser';\nimport { TaskPageLinks } from './TaskPageLinks';\nimport { TaskStatusStepper } from './TaskStatusStepper';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../../translation';\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexFlow: 'column nowrap',\n },\n contentWrapper: {\n flex: 1,\n position: 'relative',\n },\n content: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n\n display: 'flex',\n '& > *': {\n flex: 1,\n },\n },\n codeMirror: {\n height: '100%',\n overflowY: 'auto',\n },\n});\n\nfunction FilesContent() {\n const classes = useStyles();\n const { selectedResult } = useDryRun();\n const [selectedPath, setSelectedPath] = useState<string>('');\n const selectedFile = selectedResult?.directoryContents.find(\n f => f.path === selectedPath,\n );\n\n useEffect(() => {\n if (selectedResult) {\n const [firstFile] = selectedResult.directoryContents;\n if (firstFile) {\n setSelectedPath(firstFile.path);\n } else {\n setSelectedPath('');\n }\n }\n return undefined;\n }, [selectedResult]);\n\n if (!selectedResult) {\n return null;\n }\n return (\n <DryRunResultsSplitView>\n <FileBrowser\n selected={selectedPath}\n onSelect={setSelectedPath}\n filePaths={selectedResult.directoryContents.map(file => file.path)}\n />\n <CodeMirror\n className={classes.codeMirror}\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n readOnly\n value={\n selectedFile?.base64Content ? atob(selectedFile.base64Content) : ''\n }\n />\n </DryRunResultsSplitView>\n );\n}\nfunction LogContent() {\n const { selectedResult } = useDryRun();\n const [currentStepId, setUserSelectedStepId] = useState<string>();\n\n const steps = useMemo(() => {\n if (!selectedResult) {\n return [];\n }\n return (\n selectedResult.steps.map(step => {\n const stepLog = selectedResult.log.filter(\n l => l.body.stepId === step.id,\n );\n return {\n id: step.id,\n name: step.name,\n logString: stepLog.map(l => l.body.message).join('\\n'),\n status: stepLog[stepLog.length - 1]?.body.status ?? 'completed',\n };\n }) ?? []\n );\n }, [selectedResult]);\n\n if (!selectedResult) {\n return null;\n }\n\n const selectedStep = steps.find(s => s.id === currentStepId) ?? steps[0];\n\n return (\n <DryRunResultsSplitView>\n <TaskStatusStepper\n steps={steps}\n currentStepId={selectedStep.id}\n onUserStepChange={setUserSelectedStepId}\n />\n <LogViewer text={selectedStep?.logString ?? ''} />\n </DryRunResultsSplitView>\n );\n}\n\nfunction OutputContent() {\n const classes = useStyles();\n const { selectedResult } = useDryRun();\n\n if (!selectedResult) {\n return null;\n }\n\n return (\n <DryRunResultsSplitView>\n <Box pt={2}>\n {selectedResult.output?.links?.length && (\n <TaskPageLinks output={selectedResult.output} />\n )}\n </Box>\n <CodeMirror\n className={classes.codeMirror}\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n readOnly\n value={JSON.stringify(selectedResult.output, null, 2)}\n />\n </DryRunResultsSplitView>\n );\n}\n\nexport function DryRunResultsView() {\n const classes = useStyles();\n const [selectedTab, setSelectedTab] = useState<'files' | 'log' | 'output'>(\n 'files',\n );\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <div className={classes.root}>\n <Tabs value={selectedTab} onChange={(_, v) => setSelectedTab(v)}>\n <Tab\n value=\"files\"\n label={t('templateEditorPage.dryRunResultsView.tab.files')}\n />\n <Tab\n value=\"log\"\n label={t('templateEditorPage.dryRunResultsView.tab.log')}\n />\n <Tab\n value=\"output\"\n label={t('templateEditorPage.dryRunResultsView.tab.output')}\n />\n </Tabs>\n <Divider />\n\n <div className={classes.contentWrapper}>\n <div className={classes.content}>\n {selectedTab === 'files' && <FilesContent />}\n {selectedTab === 'log' && <LogContent />}\n {selectedTab === 'output' && <OutputContent />}\n </div>\n </div>\n </div>\n );\n}\n"],"names":["yamlSupport"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IconLink.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/IconLink.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport Grid from '@material-ui/core/Grid';\nimport { LinkProps } from '@material-ui/core/Link';\nimport LanguageIcon from '@material-ui/icons/Language';\n\nimport { IconComponent } from '@backstage/core-plugin-api';\nimport { Link } from '@backstage/core-components';\n\nconst useStyles = makeStyles({\n svgIcon: {\n display: 'inline-block',\n '& svg': {\n display: 'inline-block',\n fontSize: 'inherit',\n verticalAlign: 'baseline',\n },\n },\n});\n\nexport const IconLink = (\n props: {\n href: string;\n text?: string;\n Icon?: IconComponent;\n } & LinkProps,\n) => {\n const { href, text, Icon, ...linkProps } = props;\n\n const classes = useStyles();\n\n return (\n <Grid container direction=\"row\" spacing={1}>\n <Grid item>\n <Typography component=\"div\" className={classes.svgIcon}>\n {Icon ? <Icon /> : <LanguageIcon />}\n </Typography>\n </Grid>\n <Grid item>\n <Link to={href} {...linkProps}>\n {text || href}\n </Link>\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAyBA,MAAM,YAAY,UAAW,CAAA;AAAA,EAC3B,OAAS,EAAA;AAAA,IACP,OAAS,EAAA,cAAA;AAAA,IACT,OAAS,EAAA;AAAA,MACP,OAAS,EAAA,cAAA;AAAA,MACT,QAAU,EAAA,SAAA;AAAA,MACV,aAAe,EAAA,UAAA;AAAA,KACjB;AAAA,GACF;AACF,CAAC,CAAA,CAAA;AAEY,MAAA,QAAA,GAAW,CACtB,KAKG,KAAA;AACH,EAAA,MAAM,EAAE,IAAM,EAAA,IAAA,EAAM,IAAM,EAAA,GAAG,WAAc,GAAA,KAAA,CAAA;AAE3C,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAE1B,EAAA,2CACG,IAAK,EAAA,EAAA,SAAA,EAAS,MAAC,SAAU,EAAA,KAAA,EAAM,SAAS,CACvC,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAI,wBACP,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,WAAU,KAAM,EAAA,SAAA,EAAW,QAAQ,OAC5C,EAAA,EAAA,IAAA,mBAAQ,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAK,oBAAM,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,IAAa,CACnC,CACF,CAAA,sCACC,IAAK,EAAA,EAAA,IAAA,EAAI,wBACP,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,IAAI,IAAO,EAAA,GAAG,aACjB,IAAQ,IAAA,IACX,CACF,CACF,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskPageLinks.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport Box from '@material-ui/core/Box';\nimport LanguageIcon from '@material-ui/icons/Language';\nimport React from 'react';\nimport { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react';\nimport { IconLink } from './IconLink';\nimport { IconComponent, useApp, useRouteRef } from '@backstage/core-plugin-api';\n\ntype TaskPageLinksProps = {\n output: ScaffolderTaskOutput;\n};\n\nexport const TaskPageLinks = ({ output }: TaskPageLinksProps) => {\n const { links = [] } = output;\n const app = useApp();\n const entityRoute = useRouteRef(entityRouteRef);\n\n const iconResolver = (key?: string): IconComponent =>\n key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon;\n\n return (\n <Box px={3} pb={3}>\n {links\n .filter(({ url, entityRef }) => url || entityRef)\n .map(({ url, entityRef, title, icon }) => {\n if (entityRef) {\n const entityName = parseEntityRef(entityRef, {\n defaultKind: '<unknown>',\n defaultNamespace: '<unknown>',\n });\n const target = entityRoute(entityName);\n return { title, icon, url: target };\n }\n return { title, icon, url: url! };\n })\n .map(({ url, title, icon }, i) => (\n <IconLink\n key={`output-link-${i}`}\n href={url}\n text={title ?? url}\n Icon={iconResolver(icon)}\n target=\"_blank\"\n />\n ))}\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AA6BO,MAAM,aAAgB,GAAA,CAAC,EAAE,MAAA,EAAiC,KAAA;AAC/D,EAAA,MAAM,EAAE,KAAA,GAAQ,EAAC,EAAM,GAAA,MAAA,CAAA;AACvB,EAAA,MAAM,MAAM,MAAO,EAAA,CAAA;AACnB,EAAM,MAAA,WAAA,GAAc,YAAY,cAAc,CAAA,CAAA;AAE9C,EAAM,MAAA,YAAA,GAAe,CAAC,GACpB,KAAA,GAAA,GAAM,IAAI,aAAc,CAAA,GAAG,KAAK,YAAe,GAAA,YAAA,CAAA;AAEjD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,OAAI,EAAI,EAAA,CAAA,EAAG,IAAI,CACb,EAAA,EAAA,KAAA,CACE,MAAO,CAAA,CAAC,EAAE,GAAA,EAAK,WAAgB,KAAA,GAAA,IAAO,SAAS,CAAA,CAC/C,GAAI,CAAA,CAAC,EAAE,GAAK,EAAA,SAAA,EAAW,KAAO,EAAA,IAAA,EAAW,KAAA;AACxC,IAAA,IAAI,SAAW,EAAA;AACb,MAAM,MAAA,UAAA,GAAa,eAAe,SAAW,EAAA;AAAA,QAC3C,WAAa,EAAA,WAAA;AAAA,QACb,gBAAkB,EAAA,WAAA;AAAA,OACnB,CAAA,CAAA;AACD,MAAM,MAAA,MAAA,GAAS,YAAY,UAAU,CAAA,CAAA;AACrC,MAAA,OAAO,EAAE,KAAA,EAAO,IAAM,EAAA,GAAA,EAAK,MAAO,EAAA,CAAA;AAAA,KACpC;AACA,IAAO,OAAA,EAAE,KAAO,EAAA,IAAA,EAAM,GAAU,EAAA,CAAA;AAAA,GACjC,EACA,GAAI,CAAA,CAAC,EAAE,GAAK,EAAA,KAAA,EAAO,IAAK,EAAA,EAAG,CAC1B,qBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,eAAe,CAAC,CAAA,CAAA;AAAA,MACrB,IAAM,EAAA,GAAA;AAAA,MACN,MAAM,KAAS,IAAA,GAAA;AAAA,MACf,IAAA,EAAM,aAAa,IAAI,CAAA;AAAA,MACvB,MAAO,EAAA,QAAA;AAAA,KAAA;AAAA,GAEV,CACL,CAAA,CAAA;AAEJ;;;;"}
@@ -14,7 +14,7 @@ import useInterval from 'react-use/esm/useInterval';
14
14
  import humanizeDuration from 'humanize-duration';
15
15
  import classNames from 'classnames';
16
16
  import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
17
- import { scaffolderTranslationRef } from '../../../translation.esm.js';
17
+ import { scaffolderTranslationRef } from '../../../../translation.esm.js';
18
18
 
19
19
  const useStyles = makeStyles(
20
20
  (theme) => createStyles({
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskStatusStepper.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/TaskStatusStepper.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, { useState } from 'react';\nimport { makeStyles, createStyles, Theme } from '@material-ui/core/styles';\nimport { memo } from 'react';\nimport Step from '@material-ui/core/Step';\nimport StepLabel from '@material-ui/core/StepLabel';\nimport Stepper from '@material-ui/core/Stepper';\nimport { ScaffolderTaskStatus } from '@backstage/plugin-scaffolder-react';\nimport StepButton from '@material-ui/core/StepButton';\nimport { StepIconProps } from '@material-ui/core/StepIcon';\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport Cancel from '@material-ui/icons/Cancel';\nimport Check from '@material-ui/icons/Check';\nimport FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord';\nimport Typography from '@material-ui/core/Typography';\nimport { DateTime, Interval } from 'luxon';\nimport useInterval from 'react-use/esm/useInterval';\nimport humanizeDuration from 'humanize-duration';\nimport classNames from 'classnames';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../../translation';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n root: {\n width: '100%',\n },\n button: {\n marginBottom: theme.spacing(2),\n marginLeft: theme.spacing(2),\n },\n actionsContainer: {\n marginBottom: theme.spacing(2),\n },\n resetContainer: {\n padding: theme.spacing(3),\n },\n labelWrapper: {\n display: 'flex',\n flex: 1,\n flexDirection: 'row',\n justifyContent: 'space-between',\n },\n stepWrapper: {\n width: '100%',\n },\n }),\n);\n\ntype TaskStep = {\n id: string;\n name: string;\n status: ScaffolderTaskStatus;\n startedAt?: string;\n endedAt?: string;\n};\n\nconst useStepIconStyles = makeStyles(theme =>\n createStyles({\n root: {\n color: theme.palette.text.disabled,\n display: 'flex',\n height: 22,\n alignItems: 'center',\n },\n completed: {\n color: theme.palette.status.ok,\n },\n error: {\n color: theme.palette.status.error,\n },\n }),\n);\n\nconst StepTimeTicker = ({ step }: { step: TaskStep }) => {\n const [time, setTime] = useState('');\n\n useInterval(() => {\n if (!step.startedAt) {\n setTime('');\n return;\n }\n\n const end = step.endedAt\n ? DateTime.fromISO(step.endedAt)\n : DateTime.local();\n\n const startedAt = DateTime.fromISO(step.startedAt);\n const formatted = Interval.fromDateTimes(startedAt, end)\n .toDuration()\n .valueOf();\n\n setTime(humanizeDuration(formatted, { round: true }));\n }, 1000);\n\n return <Typography variant=\"caption\">{time}</Typography>;\n};\n\nfunction TaskStepIconComponent(props: StepIconProps) {\n const classes = useStepIconStyles();\n const { active, completed, error } = props;\n\n const getMiddle = () => {\n if (active) {\n return <CircularProgress size=\"24px\" />;\n }\n if (completed) {\n return <Check />;\n }\n if (error) {\n return <Cancel />;\n }\n return <FiberManualRecordIcon />;\n };\n\n return (\n <div\n className={classNames(classes.root, {\n [classes.completed]: completed,\n [classes.error]: error,\n })}\n >\n {getMiddle()}\n </div>\n );\n}\n\nexport const TaskStatusStepper = memo(\n (props: {\n steps: TaskStep[];\n currentStepId: string | undefined;\n onUserStepChange: (id: string) => void;\n classes?: {\n root?: string;\n };\n }) => {\n const { steps, currentStepId, onUserStepChange } = props;\n const classes = useStyles(props);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <div className={classes.root}>\n <Stepper\n activeStep={steps.findIndex(s => s.id === currentStepId)}\n orientation=\"vertical\"\n nonLinear\n >\n {steps.map((step, index) => {\n const isCancelled = step.status === 'cancelled';\n const isActive = step.status === 'processing';\n const isCompleted = step.status === 'completed';\n const isFailed = step.status === 'failed';\n const isSkipped = step.status === 'skipped';\n\n return (\n <Step key={String(index)} expanded>\n <StepButton onClick={() => onUserStepChange(step.id)}>\n <StepLabel\n StepIconProps={{\n completed: isCompleted,\n error: isFailed || isCancelled,\n active: isActive,\n }}\n StepIconComponent={TaskStepIconComponent}\n className={classes.stepWrapper}\n >\n <div className={classes.labelWrapper}>\n <Typography variant=\"subtitle2\">{step.name}</Typography>\n {isSkipped ? (\n <Typography variant=\"caption\">\n {t(\n 'templateEditorPage.taskStatusStepper.skippedStepTitle',\n )}\n </Typography>\n ) : (\n <StepTimeTicker step={step} />\n )}\n </div>\n </StepLabel>\n </StepButton>\n </Step>\n );\n })}\n </Stepper>\n </div>\n );\n },\n);\n"],"names":["Check"],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ import { makeStyles } from '@material-ui/core/styles';
2
+ import React, { useState } from 'react';
3
+ import Paper from '@material-ui/core/Paper';
4
+ import { DirectoryEditorProvider } from './DirectoryEditorContext.esm.js';
5
+ import { TemplateEditorToolbar } from './TemplateEditorToolbar.esm.js';
6
+ import { TemplateEditorBrowser } from './TemplateEditorBrowser.esm.js';
7
+ import { DryRunProvider } from './DryRunContext.esm.js';
8
+ import { TemplateEditorTextArea } from './TemplateEditorTextArea.esm.js';
9
+ import { TemplateEditorForm } from './TemplateEditorForm.esm.js';
10
+ import { DryRunResults } from './DryRunResults/DryRunResults.esm.js';
11
+
12
+ const useStyles = makeStyles(
13
+ (theme) => ({
14
+ // Reset and fix sizing to make sure scrolling behaves correctly
15
+ root: {
16
+ height: "100%",
17
+ gridArea: "pageContent",
18
+ display: "grid",
19
+ gridTemplateAreas: `
20
+ "toolbar toolbar toolbar"
21
+ "browser editor preview"
22
+ "results results results"
23
+ `,
24
+ gridTemplateColumns: "1fr 3fr 2fr",
25
+ gridTemplateRows: "auto 1fr auto"
26
+ },
27
+ toolbar: {
28
+ gridArea: "toolbar"
29
+ },
30
+ browser: {
31
+ gridArea: "browser",
32
+ overflow: "auto"
33
+ },
34
+ editor: {
35
+ gridArea: "editor",
36
+ overflow: "auto",
37
+ borderLeft: `1px solid ${theme.palette.divider}`
38
+ },
39
+ preview: {
40
+ gridArea: "preview",
41
+ position: "relative",
42
+ borderLeft: `1px solid ${theme.palette.divider}`,
43
+ backgroundColor: theme.palette.background.default
44
+ },
45
+ scroll: {
46
+ position: "absolute",
47
+ top: 0,
48
+ left: 0,
49
+ right: 0,
50
+ bottom: 0,
51
+ padding: theme.spacing(1),
52
+ overflow: "auto"
53
+ },
54
+ results: {
55
+ gridArea: "results"
56
+ }
57
+ }),
58
+ { name: "ScaffolderTemplateEditor" }
59
+ );
60
+ const TemplateEditor = (props) => {
61
+ const classes = useStyles();
62
+ const [errorText, setErrorText] = useState();
63
+ return /* @__PURE__ */ React.createElement(DirectoryEditorProvider, { directory: props.directory }, /* @__PURE__ */ React.createElement(DryRunProvider, null, /* @__PURE__ */ React.createElement(
64
+ Paper,
65
+ {
66
+ className: classes.root,
67
+ component: "main",
68
+ variant: "outlined",
69
+ square: true
70
+ },
71
+ /* @__PURE__ */ React.createElement("section", { className: classes.toolbar }, /* @__PURE__ */ React.createElement(TemplateEditorToolbar, { fieldExtensions: props.fieldExtensions })),
72
+ /* @__PURE__ */ React.createElement("section", { className: classes.browser }, /* @__PURE__ */ React.createElement(TemplateEditorBrowser, { onClose: props.onClose })),
73
+ /* @__PURE__ */ React.createElement("section", { className: classes.editor }, /* @__PURE__ */ React.createElement(
74
+ TemplateEditorTextArea.DirectoryEditor,
75
+ {
76
+ errorText,
77
+ onLoad: props.onLoad
78
+ }
79
+ )),
80
+ /* @__PURE__ */ React.createElement("section", { className: classes.preview }, /* @__PURE__ */ React.createElement("div", { className: classes.scroll }, /* @__PURE__ */ React.createElement(
81
+ TemplateEditorForm.DirectoryEditorDryRun,
82
+ {
83
+ setErrorText,
84
+ fieldExtensions: props.fieldExtensions,
85
+ layouts: props.layouts,
86
+ formProps: props.formProps
87
+ }
88
+ ))),
89
+ /* @__PURE__ */ React.createElement("section", { className: classes.results }, /* @__PURE__ */ React.createElement(DryRunResults, null))
90
+ )));
91
+ };
92
+
93
+ export { TemplateEditor };
94
+ //# sourceMappingURL=TemplateEditor.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateEditor.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditor.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 { makeStyles } from '@material-ui/core/styles';\nimport React, { useState } from 'react';\nimport Paper from '@material-ui/core/Paper';\nimport type {\n FormProps,\n LayoutOptions,\n} from '@backstage/plugin-scaffolder-react';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\nimport { TemplateDirectoryAccess } from '../../../lib/filesystem';\nimport { DirectoryEditorProvider } from './DirectoryEditorContext';\nimport { TemplateEditorToolbar } from './TemplateEditorToolbar';\nimport { TemplateEditorBrowser } from './TemplateEditorBrowser';\nimport { DryRunProvider } from './DryRunContext';\nimport { TemplateEditorTextArea } from './TemplateEditorTextArea';\nimport { TemplateEditorForm } from './TemplateEditorForm';\nimport { DryRunResults } from './DryRunResults';\n\n/** @public */\nexport type ScaffolderTemplateEditorClassKey =\n | 'root'\n | 'browser'\n | 'editor'\n | 'preview'\n | 'results';\n\nconst useStyles = makeStyles(\n theme => ({\n // Reset and fix sizing to make sure scrolling behaves correctly\n root: {\n height: '100%',\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateAreas: `\n \"toolbar toolbar toolbar\"\n \"browser editor preview\"\n \"results results results\"\n `,\n gridTemplateColumns: '1fr 3fr 2fr',\n gridTemplateRows: 'auto 1fr auto',\n },\n toolbar: {\n gridArea: 'toolbar',\n },\n browser: {\n gridArea: 'browser',\n overflow: 'auto',\n },\n editor: {\n gridArea: 'editor',\n overflow: 'auto',\n borderLeft: `1px solid ${theme.palette.divider}`,\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 overflow: 'auto',\n },\n results: {\n gridArea: 'results',\n },\n }),\n { name: 'ScaffolderTemplateEditor' },\n);\n\nexport const TemplateEditor = (props: {\n directory?: TemplateDirectoryAccess;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n layouts?: LayoutOptions[];\n onClose?: () => void;\n formProps?: FormProps;\n onLoad?: () => void;\n}) => {\n const classes = useStyles();\n const [errorText, setErrorText] = useState<string>();\n\n return (\n <DirectoryEditorProvider directory={props.directory}>\n <DryRunProvider>\n <Paper\n className={classes.root}\n component=\"main\"\n variant=\"outlined\"\n square\n >\n <section className={classes.toolbar}>\n <TemplateEditorToolbar fieldExtensions={props.fieldExtensions} />\n </section>\n <section className={classes.browser}>\n <TemplateEditorBrowser onClose={props.onClose} />\n </section>\n <section className={classes.editor}>\n <TemplateEditorTextArea.DirectoryEditor\n errorText={errorText}\n onLoad={props.onLoad}\n />\n </section>\n <section className={classes.preview}>\n <div className={classes.scroll}>\n <TemplateEditorForm.DirectoryEditorDryRun\n setErrorText={setErrorText}\n fieldExtensions={props.fieldExtensions}\n layouts={props.layouts}\n formProps={props.formProps}\n />\n </div>\n </section>\n <section className={classes.results}>\n <DryRunResults />\n </section>\n </Paper>\n </DryRunProvider>\n </DirectoryEditorProvider>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import Grid from '@material-ui/core/Grid';
1
2
  import Divider from '@material-ui/core/Divider';
2
3
  import IconButton from '@material-ui/core/IconButton';
3
4
  import Tooltip from '@material-ui/core/Tooltip';
@@ -7,37 +8,33 @@ import RefreshIcon from '@material-ui/icons/Refresh';
7
8
  import SaveIcon from '@material-ui/icons/Save';
8
9
  import React from 'react';
9
10
  import { useDirectoryEditor } from './DirectoryEditorContext.esm.js';
10
- import { FileBrowser } from '../../components/FileBrowser/FileBrowser.esm.js';
11
+ import { FileBrowser } from '../../../components/FileBrowser/FileBrowser.esm.js';
11
12
  import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
12
- import { scaffolderTranslationRef } from '../../translation.esm.js';
13
+ import { scaffolderTranslationRef } from '../../../translation.esm.js';
13
14
 
14
- const useStyles = makeStyles((theme) => ({
15
- button: {
16
- padding: theme.spacing(1)
17
- },
18
- buttons: {
19
- display: "flex",
20
- flexFlow: "row nowrap",
21
- alignItems: "center",
22
- justifyContent: "flex-start"
23
- },
24
- buttonsGap: {
25
- flex: "1 1 auto"
26
- },
27
- buttonsDivider: {
28
- marginBottom: theme.spacing(1)
29
- }
30
- }));
15
+ const useStyles = makeStyles(
16
+ (theme) => ({
17
+ grid: {
18
+ "& svg": {
19
+ margin: theme.spacing(1)
20
+ }
21
+ },
22
+ closeButton: {
23
+ marginLeft: "auto"
24
+ }
25
+ }),
26
+ { name: "ScaffolderTemplateEditorBrowser" }
27
+ );
31
28
  function TemplateEditorBrowser(props) {
32
29
  const classes = useStyles();
33
30
  const directoryEditor = useDirectoryEditor();
34
- const changedFiles = directoryEditor.files.filter((file) => file.dirty);
31
+ const changedFiles = directoryEditor?.files.filter((file) => file.dirty);
35
32
  const { t } = useTranslationRef(scaffolderTranslationRef);
36
33
  const handleClose = () => {
37
34
  if (!props.onClose) {
38
35
  return;
39
36
  }
40
- if (changedFiles.length > 0) {
37
+ if (changedFiles?.length) {
41
38
  const accepted = window.confirm(
42
39
  t("templateEditorPage.templateEditorBrowser.closeConfirmMessage")
43
40
  );
@@ -47,7 +44,7 @@ function TemplateEditorBrowser(props) {
47
44
  }
48
45
  props.onClose();
49
46
  };
50
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: classes.buttons }, /* @__PURE__ */ React.createElement(
47
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Grid, { className: classes.grid, container: true, spacing: 0, alignItems: "center" }, /* @__PURE__ */ React.createElement(
51
48
  Tooltip,
52
49
  {
53
50
  title: t("templateEditorPage.templateEditorBrowser.saveIconTooltip")
@@ -55,9 +52,9 @@ function TemplateEditorBrowser(props) {
55
52
  /* @__PURE__ */ React.createElement(
56
53
  IconButton,
57
54
  {
58
- className: classes.button,
59
- disabled: directoryEditor.files.every((file) => !file.dirty),
60
- onClick: () => directoryEditor.save()
55
+ size: "small",
56
+ disabled: directoryEditor?.files.every((file) => !file.dirty),
57
+ onClick: () => directoryEditor?.save()
61
58
  },
62
59
  /* @__PURE__ */ React.createElement(SaveIcon, null)
63
60
  )
@@ -68,26 +65,27 @@ function TemplateEditorBrowser(props) {
68
65
  "templateEditorPage.templateEditorBrowser.reloadIconTooltip"
69
66
  )
70
67
  },
68
+ /* @__PURE__ */ React.createElement(IconButton, { size: "small", onClick: () => directoryEditor?.reload() }, /* @__PURE__ */ React.createElement(RefreshIcon, null))
69
+ ), /* @__PURE__ */ React.createElement(
70
+ Tooltip,
71
+ {
72
+ title: t("templateEditorPage.templateEditorBrowser.closeIconTooltip")
73
+ },
71
74
  /* @__PURE__ */ React.createElement(
72
75
  IconButton,
73
76
  {
74
- className: classes.button,
75
- onClick: () => directoryEditor.reload()
77
+ size: "small",
78
+ className: classes.closeButton,
79
+ onClick: handleClose
76
80
  },
77
- /* @__PURE__ */ React.createElement(RefreshIcon, null)
81
+ /* @__PURE__ */ React.createElement(CloseIcon, null)
78
82
  )
79
- ), /* @__PURE__ */ React.createElement("div", { className: classes.buttonsGap }), /* @__PURE__ */ React.createElement(
80
- Tooltip,
81
- {
82
- title: t("templateEditorPage.templateEditorBrowser.closeIconTooltip")
83
- },
84
- /* @__PURE__ */ React.createElement(IconButton, { className: classes.button, onClick: handleClose }, /* @__PURE__ */ React.createElement(CloseIcon, null))
85
- )), /* @__PURE__ */ React.createElement(Divider, { className: classes.buttonsDivider }), /* @__PURE__ */ React.createElement(
83
+ )), /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(
86
84
  FileBrowser,
87
85
  {
88
- selected: directoryEditor.selectedFile?.path ?? "",
89
- onSelect: directoryEditor.setSelectedFile,
90
- filePaths: directoryEditor.files.map((file) => file.path)
86
+ selected: directoryEditor?.selectedFile?.path ?? "",
87
+ onSelect: directoryEditor?.setSelectedFile,
88
+ filePaths: directoryEditor?.files.map((file) => file.path) ?? []
91
89
  }
92
90
  ));
93
91
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateEditorBrowser.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.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 Grid from '@material-ui/core/Grid';\nimport Divider from '@material-ui/core/Divider';\nimport IconButton from '@material-ui/core/IconButton';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CloseIcon from '@material-ui/icons/Close';\nimport RefreshIcon from '@material-ui/icons/Refresh';\nimport SaveIcon from '@material-ui/icons/Save';\nimport React from 'react';\nimport { useDirectoryEditor } from './DirectoryEditorContext';\nimport { FileBrowser } from '../../../components/FileBrowser';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\n\nconst useStyles = makeStyles(\n theme => ({\n grid: {\n '& svg': {\n margin: theme.spacing(1),\n },\n },\n closeButton: {\n marginLeft: 'auto',\n },\n }),\n { name: 'ScaffolderTemplateEditorBrowser' },\n);\n\n/** The local file browser for the template editor */\nexport function TemplateEditorBrowser(props: { onClose?: () => void }) {\n const classes = useStyles();\n const directoryEditor = useDirectoryEditor();\n const changedFiles = directoryEditor?.files.filter(file => file.dirty);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const handleClose = () => {\n if (!props.onClose) {\n return;\n }\n if (changedFiles?.length) {\n // eslint-disable-next-line no-alert\n const accepted = window.confirm(\n t('templateEditorPage.templateEditorBrowser.closeConfirmMessage'),\n );\n if (!accepted) {\n return;\n }\n }\n props.onClose();\n };\n\n return (\n <>\n <Grid className={classes.grid} container spacing={0} alignItems=\"center\">\n <Tooltip\n title={t('templateEditorPage.templateEditorBrowser.saveIconTooltip')}\n >\n <IconButton\n size=\"small\"\n disabled={directoryEditor?.files.every(file => !file.dirty)}\n onClick={() => directoryEditor?.save()}\n >\n <SaveIcon />\n </IconButton>\n </Tooltip>\n <Tooltip\n title={t(\n 'templateEditorPage.templateEditorBrowser.reloadIconTooltip',\n )}\n >\n <IconButton size=\"small\" onClick={() => directoryEditor?.reload()}>\n <RefreshIcon />\n </IconButton>\n </Tooltip>\n <Tooltip\n title={t('templateEditorPage.templateEditorBrowser.closeIconTooltip')}\n >\n <IconButton\n size=\"small\"\n className={classes.closeButton}\n onClick={handleClose}\n >\n <CloseIcon />\n </IconButton>\n </Tooltip>\n </Grid>\n <Divider />\n <FileBrowser\n selected={directoryEditor?.selectedFile?.path ?? ''}\n onSelect={directoryEditor?.setSelectedFile}\n filePaths={directoryEditor?.files.map(file => file.path) ?? []}\n />\n </>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -1,25 +1,19 @@
1
1
  import { useApiHolder } from '@backstage/core-plugin-api';
2
2
  import { makeStyles } from '@material-ui/core/styles';
3
+ import Paper from '@material-ui/core/Paper';
4
+ import Typography from '@material-ui/core/Typography';
3
5
  import React, { useState, useMemo, Component } from 'react';
4
6
  import useDebounce from 'react-use/esm/useDebounce';
5
7
  import yaml from 'yaml';
8
+ import { useTranslationRef } from '@backstage/frontend-plugin-api';
6
9
  import { createAsyncValidators, Stepper } from '@backstage/plugin-scaffolder-react/alpha';
7
10
  import { useDryRun } from './DryRunContext.esm.js';
8
11
  import { useDirectoryEditor } from './DirectoryEditorContext.esm.js';
12
+ import { scaffolderTranslationRef } from '../../../translation.esm.js';
9
13
 
10
14
  const useStyles = makeStyles({
11
15
  containerWrapper: {
12
- position: "relative",
13
- width: "100%",
14
- height: "100%"
15
- },
16
- container: {
17
- position: "absolute",
18
- top: 0,
19
- bottom: 0,
20
- left: 0,
21
- right: 0,
22
- overflow: "auto"
16
+ width: "100%"
23
17
  }
24
18
  });
25
19
  class ErrorBoundary extends Component {
@@ -53,6 +47,7 @@ function TemplateEditorForm(props) {
53
47
  } = props;
54
48
  const classes = useStyles();
55
49
  const apiHolder = useApiHolder();
50
+ const { t } = useTranslationRef(scaffolderTranslationRef);
56
51
  const [steps, setSteps] = useState();
57
52
  const fields = useMemo(() => {
58
53
  return Object.fromEntries(
@@ -110,10 +105,7 @@ function TemplateEditorForm(props) {
110
105
  250,
111
106
  [contentIsSpec, content, apiHolder]
112
107
  );
113
- if (!steps) {
114
- return null;
115
- }
116
- return /* @__PURE__ */ React.createElement("div", { className: classes.containerWrapper }, /* @__PURE__ */ React.createElement("div", { className: classes.container }, /* @__PURE__ */ React.createElement(ErrorBoundary, { invalidator: steps, setErrorText }, /* @__PURE__ */ React.createElement(
108
+ return /* @__PURE__ */ React.createElement("div", { className: classes.containerWrapper }, steps ? /* @__PURE__ */ React.createElement(Paper, { variant: "outlined" }, /* @__PURE__ */ React.createElement(ErrorBoundary, { invalidator: steps, setErrorText }, /* @__PURE__ */ React.createElement(
117
109
  Stepper,
118
110
  {
119
111
  manifest: { steps, title: "Template Editor" },
@@ -125,13 +117,13 @@ function TemplateEditorForm(props) {
125
117
  layouts,
126
118
  formProps: props.formProps
127
119
  }
128
- ))));
120
+ ))) : /* @__PURE__ */ React.createElement(Typography, { variant: "body1", color: "textSecondary" }, t("templateEditorForm.stepper.emptyText")));
129
121
  }
130
122
  function TemplateEditorFormDirectoryEditorDryRun(props) {
131
123
  const { setErrorText, fieldExtensions = [], layouts } = props;
132
124
  const dryRun = useDryRun();
133
125
  const directoryEditor = useDirectoryEditor();
134
- const { selectedFile } = directoryEditor;
126
+ const { selectedFile } = directoryEditor ?? {};
135
127
  const handleDryRun = async (data) => {
136
128
  if (!selectedFile) {
137
129
  return;
@@ -140,7 +132,7 @@ function TemplateEditorFormDirectoryEditorDryRun(props) {
140
132
  await dryRun.execute({
141
133
  templateContent: selectedFile.content,
142
134
  values: data,
143
- files: directoryEditor.files
135
+ files: directoryEditor?.files ?? []
144
136
  });
145
137
  setErrorText();
146
138
  } catch (e) {
@@ -149,7 +141,7 @@ function TemplateEditorFormDirectoryEditorDryRun(props) {
149
141
  }
150
142
  };
151
143
  const content = selectedFile && selectedFile.path.match(/\.ya?ml$/) ? selectedFile.content : void 0;
152
- return /* @__PURE__ */ React.createElement(
144
+ return directoryEditor ? /* @__PURE__ */ React.createElement(
153
145
  TemplateEditorForm,
154
146
  {
155
147
  onDryRun: handleDryRun,
@@ -159,7 +151,7 @@ function TemplateEditorFormDirectoryEditorDryRun(props) {
159
151
  layouts,
160
152
  formProps: props.formProps
161
153
  }
162
- );
154
+ ) : null;
163
155
  }
164
156
  TemplateEditorForm.DirectoryEditorDryRun = TemplateEditorFormDirectoryEditorDryRun;
165
157
 
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateEditorForm.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorForm.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 { useApiHolder } from '@backstage/core-plugin-api';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Paper from '@material-ui/core/Paper';\nimport Typography from '@material-ui/core/Typography';\nimport React, { Component, ReactNode, useMemo, useState } from 'react';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport yaml from 'yaml';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport {\n LayoutOptions,\n TemplateParameterSchema,\n FieldExtensionOptions,\n FormProps,\n} from '@backstage/plugin-scaffolder-react';\nimport {\n Stepper,\n createAsyncValidators,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { useDryRun } from './DryRunContext';\nimport { useDirectoryEditor } from './DirectoryEditorContext';\n\nimport { scaffolderTranslationRef } from '../../../translation';\n\nconst useStyles = makeStyles({\n containerWrapper: {\n width: '100%',\n },\n});\n\ninterface ErrorBoundaryProps {\n invalidator: unknown;\n setErrorText(errorText: string | undefined): void;\n children: ReactNode;\n}\n\ninterface ErrorBoundaryState {\n shouldRender: boolean;\n}\n\nclass ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state = {\n shouldRender: true,\n };\n\n componentDidUpdate(prevProps: { invalidator: unknown }) {\n if (prevProps.invalidator !== this.props.invalidator) {\n this.setState({ shouldRender: true });\n }\n }\n\n componentDidCatch(error: Error) {\n this.props.setErrorText(error.message);\n this.setState({ shouldRender: false });\n }\n\n render() {\n return this.state.shouldRender ? this.props.children : null;\n }\n}\n\ninterface TemplateEditorFormProps {\n content?: string;\n /** Setting this to true will cause the content to be parsed as if it is the template entity spec */\n contentIsSpec?: boolean;\n setErrorText: (errorText?: string) => void;\n\n onDryRun?: (data: JsonObject) => Promise<void>;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n}\n\nfunction isJsonObject(value: JsonValue | undefined): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Shows the a template form that is parsed from the provided content */\nexport function TemplateEditorForm(props: TemplateEditorFormProps) {\n const {\n content,\n contentIsSpec,\n onDryRun,\n setErrorText,\n fieldExtensions = [],\n layouts = [],\n } = props;\n const classes = useStyles();\n const apiHolder = useApiHolder();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const [steps, setSteps] = useState<TemplateParameterSchema['steps']>();\n\n const fields = useMemo(() => {\n return Object.fromEntries(\n fieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [fieldExtensions]);\n\n useDebounce(\n () => {\n try {\n if (!content) {\n setSteps(undefined);\n return;\n }\n const parsed: JsonValue = yaml\n .parseAllDocuments(content)\n .filter(c => c)\n .map(c => c.toJSON())[0];\n\n if (!isJsonObject(parsed)) {\n setSteps(undefined);\n return;\n }\n\n let rootObj = parsed;\n if (!contentIsSpec) {\n const isTemplate =\n String(parsed.kind).toLocaleLowerCase('en-US') === 'template';\n if (!isTemplate) {\n setSteps(undefined);\n return;\n }\n\n rootObj = isJsonObject(parsed.spec) ? parsed.spec : {};\n }\n\n const { parameters } = rootObj;\n\n if (!Array.isArray(parameters)) {\n setErrorText('Template parameters must be an array');\n setSteps(undefined);\n return;\n }\n\n const fieldValidators = Object.fromEntries(\n fieldExtensions.map(({ name, validation }) => [name, validation]),\n );\n\n setErrorText();\n setSteps(\n parameters.flatMap(param =>\n isJsonObject(param)\n ? [\n {\n title: String(param.title),\n schema: param,\n validate: createAsyncValidators(param, fieldValidators, {\n apiHolder,\n }),\n },\n ]\n : [],\n ),\n );\n } catch (e) {\n setErrorText(e.message);\n }\n },\n 250,\n [contentIsSpec, content, apiHolder],\n );\n\n return (\n <div className={classes.containerWrapper}>\n {steps ? (\n <Paper variant=\"outlined\">\n <ErrorBoundary invalidator={steps} setErrorText={setErrorText}>\n <Stepper\n manifest={{ steps, title: 'Template Editor' }}\n extensions={fieldExtensions}\n components={fields}\n onCreate={async options => {\n await onDryRun?.(options);\n }}\n layouts={layouts}\n formProps={props.formProps}\n />\n </ErrorBoundary>\n </Paper>\n ) : (\n <Typography variant=\"body1\" color=\"textSecondary\">\n {t('templateEditorForm.stepper.emptyText')}\n </Typography>\n )}\n </div>\n );\n}\n\n/** A version of the TemplateEditorForm that is connected to the DirectoryEditor and DryRun contexts */\nexport function TemplateEditorFormDirectoryEditorDryRun(\n props: Pick<\n TemplateEditorFormProps,\n 'setErrorText' | 'fieldExtensions' | 'layouts' | 'formProps'\n >,\n) {\n const { setErrorText, fieldExtensions = [], layouts } = props;\n const dryRun = useDryRun();\n\n const directoryEditor = useDirectoryEditor();\n const { selectedFile } = directoryEditor ?? {};\n\n const handleDryRun = async (data: JsonObject) => {\n if (!selectedFile) {\n return;\n }\n\n try {\n await dryRun.execute({\n templateContent: selectedFile.content,\n values: data,\n files: directoryEditor?.files ?? [],\n });\n setErrorText();\n } catch (e) {\n setErrorText(String(e.cause || e));\n throw e;\n }\n };\n\n const content =\n selectedFile && selectedFile.path.match(/\\.ya?ml$/)\n ? selectedFile.content\n : undefined;\n\n return directoryEditor ? (\n <TemplateEditorForm\n onDryRun={handleDryRun}\n fieldExtensions={fieldExtensions}\n setErrorText={setErrorText}\n content={content}\n layouts={layouts}\n formProps={props.formProps}\n />\n ) : null;\n}\n\nTemplateEditorForm.DirectoryEditorDryRun =\n TemplateEditorFormDirectoryEditorDryRun;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ import React from 'react';
2
+ import Card from '@material-ui/core/Card';
3
+ import CardActionArea from '@material-ui/core/CardActionArea';
4
+ import CardContent from '@material-ui/core/CardContent';
5
+ import Typography from '@material-ui/core/Typography';
6
+ import { makeStyles } from '@material-ui/core/styles';
7
+ import { WebFileSystemAccess } from '../../../lib/filesystem/WebFileSystemAccess.esm.js';
8
+ import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
9
+ import { scaffolderTranslationRef } from '../../../translation.esm.js';
10
+ import CreateNewFolderIcon from '@material-ui/icons/CreateNewFolder';
11
+ import ListAltIcon from '@material-ui/icons/ListAlt';
12
+ import FormatListBulletedIcon from '@material-ui/icons/FormatListBulleted';
13
+ import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined';
14
+ import CardMedia from '@material-ui/core/CardMedia';
15
+ import PublishIcon from '@material-ui/icons/Publish';
16
+ import Tooltip from '@material-ui/core/Tooltip';
17
+
18
+ const useStyles = makeStyles((theme) => ({
19
+ gridRoot: {
20
+ display: "flex",
21
+ flex: 1,
22
+ alignItems: "center",
23
+ justifyContent: "center"
24
+ },
25
+ cardGrid: {
26
+ display: "grid",
27
+ maxWidth: 1e3,
28
+ gridTemplateColumns: "1fr 1fr",
29
+ gridAutoRows: "1fr 1fr",
30
+ gap: "1rem",
31
+ [theme.breakpoints.down("sm")]: {
32
+ gridAutoFlow: "row"
33
+ }
34
+ },
35
+ card: {
36
+ display: "grid",
37
+ gridTemplateColumns: "auto 1fr",
38
+ gridTemplateRows: "1fr",
39
+ alignItems: "center",
40
+ margin: theme.spacing(0, 1),
41
+ marginTop: theme.spacing(2),
42
+ padding: theme.spacing(2)
43
+ },
44
+ icon: {
45
+ justifySelf: "center",
46
+ paddingTop: theme.spacing(1),
47
+ fontSize: 48
48
+ },
49
+ introText: {
50
+ textAlign: "center",
51
+ marginTop: theme.spacing(2)
52
+ },
53
+ infoIcon: {
54
+ position: "absolute",
55
+ top: theme.spacing(1),
56
+ right: theme.spacing(1)
57
+ },
58
+ cardContent: {
59
+ padding: theme.spacing(1)
60
+ }
61
+ }));
62
+ function ActionCard(props) {
63
+ const supportsLoad = props.requireLoad ? WebFileSystemAccess.isSupported() : true;
64
+ const { t } = useTranslationRef(scaffolderTranslationRef);
65
+ const classes = useStyles();
66
+ const { Icon, title, description, action } = props;
67
+ return /* @__PURE__ */ React.createElement(Card, { className: classes.card }, !supportsLoad && /* @__PURE__ */ React.createElement(
68
+ Tooltip,
69
+ {
70
+ placement: "top",
71
+ title: t(
72
+ "templateEditorPage.templateEditorIntro.loadLocal.unsupportedTooltip"
73
+ )
74
+ },
75
+ /* @__PURE__ */ React.createElement(InfoOutlinedIcon, null)
76
+ ), /* @__PURE__ */ React.createElement(CardActionArea, { onClick: action }, /* @__PURE__ */ React.createElement(CardMedia, null, /* @__PURE__ */ React.createElement(
77
+ Icon,
78
+ {
79
+ className: classes.icon,
80
+ color: supportsLoad ? void 0 : "disabled"
81
+ }
82
+ )), /* @__PURE__ */ React.createElement(CardContent, { className: classes.cardContent }, /* @__PURE__ */ React.createElement(
83
+ Typography,
84
+ {
85
+ gutterBottom: true,
86
+ variant: "h5",
87
+ component: "h2",
88
+ color: supportsLoad ? void 0 : "textSecondary"
89
+ },
90
+ title
91
+ ), /* @__PURE__ */ React.createElement(Typography, { variant: "body2", color: "textSecondary", component: "p" }, description))));
92
+ }
93
+ function TemplateEditorIntro(props) {
94
+ const classes = useStyles();
95
+ const { t } = useTranslationRef(scaffolderTranslationRef);
96
+ return /* @__PURE__ */ React.createElement("div", { style: props.style }, /* @__PURE__ */ React.createElement(Typography, { variant: "h4", component: "h2", className: classes.introText }, t("templateEditorPage.templateEditorIntro.title")), /* @__PURE__ */ React.createElement("div", { className: classes.gridRoot }, /* @__PURE__ */ React.createElement("div", { className: classes.cardGrid }, /* @__PURE__ */ React.createElement(
97
+ ActionCard,
98
+ {
99
+ title: t("templateEditorPage.templateEditorIntro.loadLocal.title"),
100
+ description: t(
101
+ "templateEditorPage.templateEditorIntro.loadLocal.description"
102
+ ),
103
+ requireLoad: true,
104
+ Icon: PublishIcon,
105
+ action: () => props.onSelect?.("local")
106
+ }
107
+ ), /* @__PURE__ */ React.createElement(
108
+ ActionCard,
109
+ {
110
+ title: t(
111
+ "templateEditorPage.templateEditorIntro.createLocal.title"
112
+ ),
113
+ description: t(
114
+ "templateEditorPage.templateEditorIntro.createLocal.description"
115
+ ),
116
+ requireLoad: true,
117
+ action: () => props.onSelect?.("create-template"),
118
+ Icon: CreateNewFolderIcon
119
+ }
120
+ ), /* @__PURE__ */ React.createElement(
121
+ ActionCard,
122
+ {
123
+ title: t(
124
+ "templateEditorPage.templateEditorIntro.fieldExplorer.title"
125
+ ),
126
+ description: t(
127
+ "templateEditorPage.templateEditorIntro.fieldExplorer.description"
128
+ ),
129
+ Icon: FormatListBulletedIcon,
130
+ action: () => props.onSelect?.("field-explorer")
131
+ }
132
+ ), /* @__PURE__ */ React.createElement(
133
+ ActionCard,
134
+ {
135
+ title: t("templateEditorPage.templateEditorIntro.formEditor.title"),
136
+ description: t(
137
+ "templateEditorPage.templateEditorIntro.formEditor.description"
138
+ ),
139
+ Icon: ListAltIcon,
140
+ action: () => props.onSelect?.("form")
141
+ }
142
+ ))));
143
+ }
144
+
145
+ export { TemplateEditorIntro };
146
+ //# sourceMappingURL=TemplateEditorIntro.esm.js.map