@backstage/plugin-scaffolder 1.24.0-next.3 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/alpha/package.json +1 -1
- package/dist/alpha.d.ts +157 -2
- package/dist/alpha.esm.js +32 -25
- package/dist/alpha.esm.js.map +1 -1
- package/dist/components/ActionsPage/ActionsPage.esm.js +14 -10
- package/dist/components/ActionsPage/ActionsPage.esm.js.map +1 -1
- package/dist/components/ListTasksPage/ListTasksPage.esm.js +15 -11
- package/dist/components/ListTasksPage/ListTasksPage.esm.js.map +1 -1
- package/dist/components/ListTasksPage/OwnerListPicker.esm.js +8 -5
- package/dist/components/ListTasksPage/OwnerListPicker.esm.js.map +1 -1
- package/dist/components/OngoingTask/ContextMenu.esm.js +12 -4
- package/dist/components/OngoingTask/ContextMenu.esm.js.map +1 -1
- package/dist/components/OngoingTask/OngoingTask.esm.js +10 -7
- package/dist/components/OngoingTask/OngoingTask.esm.js.map +1 -1
- package/dist/components/TemplateTypePicker/TemplateTypePicker.esm.js +4 -1
- package/dist/components/TemplateTypePicker/TemplateTypePicker.esm.js.map +1 -1
- package/dist/components/fields/EntityNamePicker/EntityNamePicker.esm.js +7 -1
- package/dist/components/fields/EntityNamePicker/EntityNamePicker.esm.js.map +1 -1
- package/dist/components/fields/EntityPicker/EntityPicker.esm.js +7 -1
- package/dist/components/fields/EntityPicker/EntityPicker.esm.js.map +1 -1
- package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js +5 -2
- package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js.map +1 -1
- package/dist/components/fields/MyGroupsPicker/MyGroupsPicker.esm.js +7 -1
- package/dist/components/fields/MyGroupsPicker/MyGroupsPicker.esm.js.map +1 -1
- package/dist/components/fields/OwnedEntityPicker/OwnedEntityPicker.esm.js +7 -1
- package/dist/components/fields/OwnedEntityPicker/OwnedEntityPicker.esm.js.map +1 -1
- package/dist/components/fields/OwnerPicker/OwnerPicker.esm.js +7 -1
- package/dist/components/fields/OwnerPicker/OwnerPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoBranchPicker/DefaultRepoBranchPicker.esm.js +3 -4
- package/dist/components/fields/RepoBranchPicker/DefaultRepoBranchPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js +19 -15
- package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js +23 -6
- package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js +14 -11
- package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js +14 -9
- package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js +11 -8
- package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js +14 -9
- package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/RepoUrlPickerHost.esm.js +5 -2
- package/dist/components/fields/RepoUrlPicker/RepoUrlPickerHost.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js +13 -3
- package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js.map +1 -1
- package/dist/next/TemplateEditorPage/CustomFieldExplorer.esm.js +20 -5
- package/dist/next/TemplateEditorPage/CustomFieldExplorer.esm.js.map +1 -1
- package/dist/next/TemplateEditorPage/DryRunResults/DryRunResults.esm.js +4 -1
- package/dist/next/TemplateEditorPage/DryRunResults/DryRunResults.esm.js.map +1 -1
- package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js +17 -3
- package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js.map +1 -1
- package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js +22 -1
- package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js.map +1 -1
- package/dist/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.esm.js +6 -1
- package/dist/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.esm.js.map +1 -1
- package/dist/next/TemplateEditorPage/TemplateEditorBrowser.esm.js +36 -13
- package/dist/next/TemplateEditorPage/TemplateEditorBrowser.esm.js.map +1 -1
- package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js +13 -6
- package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js.map +1 -1
- package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js +5 -2
- package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js.map +1 -1
- package/dist/next/TemplateEditorPage/TemplateEditorTextArea.esm.js +30 -11
- package/dist/next/TemplateEditorPage/TemplateEditorTextArea.esm.js.map +1 -1
- package/dist/next/TemplateEditorPage/TemplateFormPreviewer.esm.js +5 -2
- package/dist/next/TemplateEditorPage/TemplateFormPreviewer.esm.js.map +1 -1
- package/dist/next/TemplateListPage/TemplateListPage.esm.js +23 -15
- package/dist/next/TemplateListPage/TemplateListPage.esm.js.map +1 -1
- package/dist/next/TemplateWizardPage/TemplateWizardPage.esm.js +6 -3
- package/dist/next/TemplateWizardPage/TemplateWizardPage.esm.js.map +1 -1
- package/dist/next/TemplateWizardPage/TemplateWizardPageContextMenu.esm.js +11 -1
- package/dist/next/TemplateWizardPage/TemplateWizardPageContextMenu.esm.js.map +1 -1
- package/dist/translation.esm.js +258 -0
- package/dist/translation.esm.js.map +1 -0
- package/package.json +19 -19
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DryRunResultsList.esm.js","sources":["../../../../src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.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 IconButton from '@material-ui/core/IconButton';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport CheckIcon from '@material-ui/icons/Check';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport DownloadIcon from '@material-ui/icons/GetApp';\nimport React from 'react';\nimport { useDryRun } from '../DryRunContext';\nimport { downloadBlob } from '../../../lib/download';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n overflowY: 'auto',\n background: theme.palette.background.default,\n },\n iconSuccess: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.ok,\n },\n iconFailure: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.error,\n },\n}));\n\nexport function DryRunResultsList() {\n const classes = useStyles();\n const dryRun = useDryRun();\n\n return (\n <List className={classes.root} dense>\n {dryRun.results.map(result => {\n const failed = result.log.some(l => l.body.status === 'failed');\n let isLoading = false;\n\n async function downloadResult() {\n isLoading = true;\n await downloadDirectoryContents(\n result.directoryContents,\n `dry-run-result-${result.id}.zip`,\n );\n isLoading = false;\n }\n\n return (\n <ListItem\n button\n key={result.id}\n selected={dryRun.selectedResult?.id === result.id}\n onClick={() => dryRun.selectResult(result.id)}\n >\n <ListItemIcon\n className={failed ? classes.iconFailure : classes.iconSuccess}\n >\n {failed ? <CancelIcon /> : <CheckIcon />}\n </ListItemIcon>\n <ListItemText
|
|
1
|
+
{"version":3,"file":"DryRunResultsList.esm.js","sources":["../../../../src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.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 IconButton from '@material-ui/core/IconButton';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport CheckIcon from '@material-ui/icons/Check';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport DownloadIcon from '@material-ui/icons/GetApp';\nimport React from 'react';\nimport { useDryRun } from '../DryRunContext';\nimport { downloadBlob } from '../../../lib/download';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n overflowY: 'auto',\n background: theme.palette.background.default,\n },\n iconSuccess: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.ok,\n },\n iconFailure: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.error,\n },\n}));\n\nexport function DryRunResultsList() {\n const classes = useStyles();\n const dryRun = useDryRun();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <List className={classes.root} dense>\n {dryRun.results.map(result => {\n const failed = result.log.some(l => l.body.status === 'failed');\n let isLoading = false;\n\n async function downloadResult() {\n isLoading = true;\n await downloadDirectoryContents(\n result.directoryContents,\n `dry-run-result-${result.id}.zip`,\n );\n isLoading = false;\n }\n\n return (\n <ListItem\n button\n key={result.id}\n selected={dryRun.selectedResult?.id === result.id}\n onClick={() => dryRun.selectResult(result.id)}\n >\n <ListItemIcon\n className={failed ? classes.iconFailure : classes.iconSuccess}\n >\n {failed ? <CancelIcon /> : <CheckIcon />}\n </ListItemIcon>\n <ListItemText\n primary={t('templateEditorPage.dryRunResultsList.title', {\n resultId: `${result.id}`,\n })}\n />\n <ListItemSecondaryAction>\n <IconButton\n edge=\"end\"\n aria-label=\"download\"\n title={t(\n 'templateEditorPage.dryRunResultsList.downloadButtonTitle',\n )}\n disabled={isLoading}\n onClick={() => downloadResult()}\n >\n <DownloadIcon />\n </IconButton>\n <IconButton\n edge=\"end\"\n aria-label=\"delete\"\n title={t(\n 'templateEditorPage.dryRunResultsList.deleteButtonTitle',\n )}\n onClick={() => dryRun.deleteResult(result.id)}\n >\n <DeleteIcon />\n </IconButton>\n </ListItemSecondaryAction>\n </ListItem>\n );\n })}\n </List>\n );\n}\n\nasync function downloadDirectoryContents(\n directoryContents: {\n path: string;\n base64Content: string;\n executable: boolean;\n }[],\n name: string,\n) {\n const { default: JSZip } = await import('jszip');\n const zip = new JSZip();\n\n for (const d of directoryContents) {\n // Decode text content from base64 to ascii\n const converted = atob(d.base64Content);\n\n // add folder/file to zip\n await zip.file(d.path, converted);\n }\n\n const blob = await zip.generateAsync({ type: 'blob' });\n downloadBlob(blob, name);\n}\n"],"names":["CancelIcon"],"mappings":"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"}
|
|
@@ -13,6 +13,8 @@ import { DryRunResultsSplitView } from './DryRunResultsSplitView.esm.js';
|
|
|
13
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
|
+
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
17
|
+
import { scaffolderTranslationRef } from '../../../translation.esm.js';
|
|
16
18
|
|
|
17
19
|
const useStyles = makeStyles({
|
|
18
20
|
root: {
|
|
@@ -134,7 +136,26 @@ function DryRunResultsView() {
|
|
|
134
136
|
const [selectedTab, setSelectedTab] = useState(
|
|
135
137
|
"files"
|
|
136
138
|
);
|
|
137
|
-
|
|
139
|
+
const { t } = useTranslationRef(scaffolderTranslationRef);
|
|
140
|
+
return /* @__PURE__ */ React.createElement("div", { className: classes.root }, /* @__PURE__ */ React.createElement(Tabs, { value: selectedTab, onChange: (_, v) => setSelectedTab(v) }, /* @__PURE__ */ React.createElement(
|
|
141
|
+
Tab,
|
|
142
|
+
{
|
|
143
|
+
value: "files",
|
|
144
|
+
label: t("templateEditorPage.dryRunResultsView.tab.files")
|
|
145
|
+
}
|
|
146
|
+
), /* @__PURE__ */ React.createElement(
|
|
147
|
+
Tab,
|
|
148
|
+
{
|
|
149
|
+
value: "log",
|
|
150
|
+
label: t("templateEditorPage.dryRunResultsView.tab.log")
|
|
151
|
+
}
|
|
152
|
+
), /* @__PURE__ */ React.createElement(
|
|
153
|
+
Tab,
|
|
154
|
+
{
|
|
155
|
+
value: "output",
|
|
156
|
+
label: t("templateEditorPage.dryRunResultsView.tab.output")
|
|
157
|
+
}
|
|
158
|
+
)), /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement("div", { className: classes.contentWrapper }, /* @__PURE__ */ React.createElement("div", { className: classes.content }, selectedTab === "files" && /* @__PURE__ */ React.createElement(FilesContent, null), selectedTab === "log" && /* @__PURE__ */ React.createElement(LogContent, null), selectedTab === "output" && /* @__PURE__ */ React.createElement(OutputContent, null))));
|
|
138
159
|
}
|
|
139
160
|
|
|
140
161
|
export { DryRunResultsView };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DryRunResultsView.esm.js","sources":["../../../../src/next/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';\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\n return (\n <div className={classes.root}>\n <Tabs value={selectedTab} onChange={(_, v) => setSelectedTab(v)}>\n <Tab value=\"files\" label=\"Files\" />\n <Tab value=\"log\" label=\"Log\" />\n <Tab value=\"output\" label=\"Output\" />\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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"}
|
|
1
|
+
{"version":3,"file":"DryRunResultsView.esm.js","sources":["../../../../src/next/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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"}
|
|
@@ -13,6 +13,8 @@ import { DateTime, Interval } from 'luxon';
|
|
|
13
13
|
import useInterval from 'react-use/esm/useInterval';
|
|
14
14
|
import humanizeDuration from 'humanize-duration';
|
|
15
15
|
import classNames from 'classnames';
|
|
16
|
+
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
17
|
+
import { scaffolderTranslationRef } from '../../../translation.esm.js';
|
|
16
18
|
|
|
17
19
|
const useStyles = makeStyles(
|
|
18
20
|
(theme) => createStyles({
|
|
@@ -100,6 +102,7 @@ const TaskStatusStepper = memo(
|
|
|
100
102
|
(props) => {
|
|
101
103
|
const { steps, currentStepId, onUserStepChange } = props;
|
|
102
104
|
const classes = useStyles(props);
|
|
105
|
+
const { t } = useTranslationRef(scaffolderTranslationRef);
|
|
103
106
|
return /* @__PURE__ */ React.createElement("div", { className: classes.root }, /* @__PURE__ */ React.createElement(
|
|
104
107
|
Stepper,
|
|
105
108
|
{
|
|
@@ -124,7 +127,9 @@ const TaskStatusStepper = memo(
|
|
|
124
127
|
StepIconComponent: TaskStepIconComponent,
|
|
125
128
|
className: classes.stepWrapper
|
|
126
129
|
},
|
|
127
|
-
/* @__PURE__ */ React.createElement("div", { className: classes.labelWrapper }, /* @__PURE__ */ React.createElement(Typography, { variant: "subtitle2" }, step.name), isSkipped ? /* @__PURE__ */ React.createElement(Typography, { variant: "caption" },
|
|
130
|
+
/* @__PURE__ */ React.createElement("div", { className: classes.labelWrapper }, /* @__PURE__ */ React.createElement(Typography, { variant: "subtitle2" }, step.name), isSkipped ? /* @__PURE__ */ React.createElement(Typography, { variant: "caption" }, t(
|
|
131
|
+
"templateEditorPage.taskStatusStepper.skippedStepTitle"
|
|
132
|
+
)) : /* @__PURE__ */ React.createElement(StepTimeTicker, { step }))
|
|
128
133
|
)));
|
|
129
134
|
})
|
|
130
135
|
));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskStatusStepper.esm.js","sources":["../../../../src/next/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';\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\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\">Skipped</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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"}
|
|
1
|
+
{"version":3,"file":"TaskStatusStepper.esm.js","sources":["../../../../src/next/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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"}
|
|
@@ -8,6 +8,8 @@ import SaveIcon from '@material-ui/icons/Save';
|
|
|
8
8
|
import React from 'react';
|
|
9
9
|
import { useDirectoryEditor } from './DirectoryEditorContext.esm.js';
|
|
10
10
|
import { FileBrowser } from '../../components/FileBrowser/FileBrowser.esm.js';
|
|
11
|
+
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
12
|
+
import { scaffolderTranslationRef } from '../../translation.esm.js';
|
|
11
13
|
|
|
12
14
|
const useStyles = makeStyles((theme) => ({
|
|
13
15
|
button: {
|
|
@@ -30,13 +32,14 @@ function TemplateEditorBrowser(props) {
|
|
|
30
32
|
const classes = useStyles();
|
|
31
33
|
const directoryEditor = useDirectoryEditor();
|
|
32
34
|
const changedFiles = directoryEditor.files.filter((file) => file.dirty);
|
|
35
|
+
const { t } = useTranslationRef(scaffolderTranslationRef);
|
|
33
36
|
const handleClose = () => {
|
|
34
37
|
if (!props.onClose) {
|
|
35
38
|
return;
|
|
36
39
|
}
|
|
37
40
|
if (changedFiles.length > 0) {
|
|
38
41
|
const accepted = window.confirm(
|
|
39
|
-
"
|
|
42
|
+
t("templateEditorPage.templateEditorBrowser.closeConfirmMessage")
|
|
40
43
|
);
|
|
41
44
|
if (!accepted) {
|
|
42
45
|
return;
|
|
@@ -44,22 +47,42 @@ function TemplateEditorBrowser(props) {
|
|
|
44
47
|
}
|
|
45
48
|
props.onClose();
|
|
46
49
|
};
|
|
47
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: classes.buttons }, /* @__PURE__ */ React.createElement(
|
|
48
|
-
|
|
50
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: classes.buttons }, /* @__PURE__ */ React.createElement(
|
|
51
|
+
Tooltip,
|
|
49
52
|
{
|
|
50
|
-
|
|
51
|
-
disabled: directoryEditor.files.every((file) => !file.dirty),
|
|
52
|
-
onClick: () => directoryEditor.save()
|
|
53
|
+
title: t("templateEditorPage.templateEditorBrowser.saveIconTooltip")
|
|
53
54
|
},
|
|
54
|
-
/* @__PURE__ */ React.createElement(
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
/* @__PURE__ */ React.createElement(
|
|
56
|
+
IconButton,
|
|
57
|
+
{
|
|
58
|
+
className: classes.button,
|
|
59
|
+
disabled: directoryEditor.files.every((file) => !file.dirty),
|
|
60
|
+
onClick: () => directoryEditor.save()
|
|
61
|
+
},
|
|
62
|
+
/* @__PURE__ */ React.createElement(SaveIcon, null)
|
|
63
|
+
)
|
|
64
|
+
), /* @__PURE__ */ React.createElement(
|
|
65
|
+
Tooltip,
|
|
57
66
|
{
|
|
58
|
-
|
|
59
|
-
|
|
67
|
+
title: t(
|
|
68
|
+
"templateEditorPage.templateEditorBrowser.reloadIconTooltip"
|
|
69
|
+
)
|
|
60
70
|
},
|
|
61
|
-
/* @__PURE__ */ React.createElement(
|
|
62
|
-
|
|
71
|
+
/* @__PURE__ */ React.createElement(
|
|
72
|
+
IconButton,
|
|
73
|
+
{
|
|
74
|
+
className: classes.button,
|
|
75
|
+
onClick: () => directoryEditor.reload()
|
|
76
|
+
},
|
|
77
|
+
/* @__PURE__ */ React.createElement(RefreshIcon, null)
|
|
78
|
+
)
|
|
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(
|
|
63
86
|
FileBrowser,
|
|
64
87
|
{
|
|
65
88
|
selected: directoryEditor.selectedFile?.path ?? "",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateEditorBrowser.esm.js","sources":["../../../src/next/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 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';\n\nconst useStyles = makeStyles(theme => ({\n button: {\n padding: theme.spacing(1),\n },\n buttons: {\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n justifyContent: 'flex-start',\n },\n buttonsGap: {\n flex: '1 1 auto',\n },\n buttonsDivider: {\n marginBottom: theme.spacing(1),\n },\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\n const handleClose = () => {\n if (!props.onClose) {\n return;\n }\n if (changedFiles.length > 0) {\n // eslint-disable-next-line no-alert\n const accepted = window.confirm(\n '
|
|
1
|
+
{"version":3,"file":"TemplateEditorBrowser.esm.js","sources":["../../../src/next/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 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(theme => ({\n button: {\n padding: theme.spacing(1),\n },\n buttons: {\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n justifyContent: 'flex-start',\n },\n buttonsGap: {\n flex: '1 1 auto',\n },\n buttonsDivider: {\n marginBottom: theme.spacing(1),\n },\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 > 0) {\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 <div className={classes.buttons}>\n <Tooltip\n title={t('templateEditorPage.templateEditorBrowser.saveIconTooltip')}\n >\n <IconButton\n className={classes.button}\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\n className={classes.button}\n onClick={() => directoryEditor.reload()}\n >\n <RefreshIcon />\n </IconButton>\n </Tooltip>\n <div className={classes.buttonsGap} />\n <Tooltip\n title={t('templateEditorPage.templateEditorBrowser.closeIconTooltip')}\n >\n <IconButton className={classes.button} onClick={handleClose}>\n <CloseIcon />\n </IconButton>\n </Tooltip>\n </div>\n <Divider className={classes.buttonsDivider} />\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":";;;;;;;;;;;;;AA4BA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,MAAQ,EAAA;AAAA,IACN,OAAA,EAAS,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,GAC1B;AAAA,EACA,OAAS,EAAA;AAAA,IACP,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,YAAA;AAAA,IACV,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,YAAA;AAAA,GAClB;AAAA,EACA,UAAY,EAAA;AAAA,IACV,IAAM,EAAA,UAAA;AAAA,GACR;AAAA,EACA,cAAgB,EAAA;AAAA,IACd,YAAA,EAAc,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,GAC/B;AACF,CAAE,CAAA,CAAA,CAAA;AAGK,SAAS,sBAAsB,KAAiC,EAAA;AACrE,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,kBAAkB,kBAAmB,EAAA,CAAA;AAC3C,EAAA,MAAM,eAAe,eAAgB,CAAA,KAAA,CAAM,MAAO,CAAA,CAAA,IAAA,KAAQ,KAAK,KAAK,CAAA,CAAA;AACpE,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,wBAAwB,CAAA,CAAA;AAExD,EAAA,MAAM,cAAc,MAAM;AACxB,IAAI,IAAA,CAAC,MAAM,OAAS,EAAA;AAClB,MAAA,OAAA;AAAA,KACF;AACA,IAAI,IAAA,YAAA,CAAa,SAAS,CAAG,EAAA;AAE3B,MAAA,MAAM,WAAW,MAAO,CAAA,OAAA;AAAA,QACtB,EAAE,8DAA8D,CAAA;AAAA,OAClE,CAAA;AACA,MAAA,IAAI,CAAC,QAAU,EAAA;AACb,QAAA,OAAA;AAAA,OACF;AAAA,KACF;AACA,IAAA,KAAA,CAAM,OAAQ,EAAA,CAAA;AAAA,GAChB,CAAA;AAEA,EAAA,uBAEI,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAW,QAAQ,OACtB,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,EAAE,0DAA0D,CAAA;AAAA,KAAA;AAAA,oBAEnE,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,WAAW,OAAQ,CAAA,MAAA;AAAA,QACnB,UAAU,eAAgB,CAAA,KAAA,CAAM,MAAM,CAAQ,IAAA,KAAA,CAAC,KAAK,KAAK,CAAA;AAAA,QACzD,OAAA,EAAS,MAAM,eAAA,CAAgB,IAAK,EAAA;AAAA,OAAA;AAAA,0CAEnC,QAAS,EAAA,IAAA,CAAA;AAAA,KACZ;AAAA,GAEF,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,KAAO,EAAA,CAAA;AAAA,QACL,4DAAA;AAAA,OACF;AAAA,KAAA;AAAA,oBAEA,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,WAAW,OAAQ,CAAA,MAAA;AAAA,QACnB,OAAA,EAAS,MAAM,eAAA,CAAgB,MAAO,EAAA;AAAA,OAAA;AAAA,0CAErC,WAAY,EAAA,IAAA,CAAA;AAAA,KACf;AAAA,qBAED,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,OAAA,CAAQ,YAAY,CACpC,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,EAAE,2DAA2D,CAAA;AAAA,KAAA;AAAA,oBAEpE,KAAA,CAAA,aAAA,CAAC,cAAW,SAAW,EAAA,OAAA,CAAQ,QAAQ,OAAS,EAAA,WAAA,EAAA,kBAC7C,KAAA,CAAA,aAAA,CAAA,SAAA,EAAA,IAAU,CACb,CAAA;AAAA,GAEJ,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,WAAQ,SAAW,EAAA,OAAA,CAAQ,gBAAgB,CAC5C,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,QAAA,EAAU,eAAgB,CAAA,YAAA,EAAc,IAAQ,IAAA,EAAA;AAAA,MAChD,UAAU,eAAgB,CAAA,eAAA;AAAA,MAC1B,WAAW,eAAgB,CAAA,KAAA,CAAM,GAAI,CAAA,CAAA,IAAA,KAAQ,KAAK,IAAI,CAAA;AAAA,KAAA;AAAA,GAE1D,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -7,6 +7,8 @@ import Typography from '@material-ui/core/Typography';
|
|
|
7
7
|
import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined';
|
|
8
8
|
import { makeStyles } from '@material-ui/core/styles';
|
|
9
9
|
import { WebFileSystemAccess } from '../../lib/filesystem/WebFileSystemAccess.esm.js';
|
|
10
|
+
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
11
|
+
import { scaffolderTranslationRef } from '../../translation.esm.js';
|
|
10
12
|
|
|
11
13
|
const useStyles = makeStyles((theme) => ({
|
|
12
14
|
introText: {
|
|
@@ -28,6 +30,7 @@ const useStyles = makeStyles((theme) => ({
|
|
|
28
30
|
function TemplateEditorIntro(props) {
|
|
29
31
|
const classes = useStyles();
|
|
30
32
|
const supportsLoad = WebFileSystemAccess.isSupported();
|
|
33
|
+
const { t } = useTranslationRef(scaffolderTranslationRef);
|
|
31
34
|
const cardLoadLocal = /* @__PURE__ */ React.createElement(Card, { className: classes.card, elevation: 4 }, /* @__PURE__ */ React.createElement(
|
|
32
35
|
CardActionArea,
|
|
33
36
|
{
|
|
@@ -43,26 +46,30 @@ function TemplateEditorIntro(props) {
|
|
|
43
46
|
color: supportsLoad ? void 0 : "textSecondary",
|
|
44
47
|
style: { display: "flex", flexFlow: "row nowrap" }
|
|
45
48
|
},
|
|
46
|
-
"
|
|
49
|
+
t("templateEditorPage.templateEditorIntro.loadLocal.title")
|
|
47
50
|
), /* @__PURE__ */ React.createElement(
|
|
48
51
|
Typography,
|
|
49
52
|
{
|
|
50
53
|
variant: "body1",
|
|
51
54
|
color: supportsLoad ? void 0 : "textSecondary"
|
|
52
55
|
},
|
|
53
|
-
"
|
|
56
|
+
t("templateEditorPage.templateEditorIntro.loadLocal.description")
|
|
54
57
|
))
|
|
55
58
|
), !supportsLoad && /* @__PURE__ */ React.createElement("div", { className: classes.infoIcon }, /* @__PURE__ */ React.createElement(
|
|
56
59
|
Tooltip,
|
|
57
60
|
{
|
|
58
61
|
placement: "top",
|
|
59
|
-
title:
|
|
62
|
+
title: t(
|
|
63
|
+
"templateEditorPage.templateEditorIntro.loadLocal.unsupportedTooltip"
|
|
64
|
+
)
|
|
60
65
|
},
|
|
61
66
|
/* @__PURE__ */ React.createElement(InfoOutlinedIcon, null)
|
|
62
67
|
)));
|
|
63
|
-
const cardFormEditor = /* @__PURE__ */ React.createElement(Card, { className: classes.card, elevation: 4 }, /* @__PURE__ */ React.createElement(CardActionArea, { onClick: () => props.onSelect?.("form") }, /* @__PURE__ */ React.createElement(CardContent, null, /* @__PURE__ */ React.createElement(Typography, { variant: "h4", component: "h3", gutterBottom: true }, "
|
|
64
|
-
const cardFieldExplorer = /* @__PURE__ */ React.createElement(Card, { className: classes.card, elevation: 4 }, /* @__PURE__ */ React.createElement(CardActionArea, { onClick: () => props.onSelect?.("field-explorer") }, /* @__PURE__ */ React.createElement(CardContent, null, /* @__PURE__ */ React.createElement(Typography, { variant: "h4", component: "h3", gutterBottom: true }, "
|
|
65
|
-
|
|
68
|
+
const cardFormEditor = /* @__PURE__ */ React.createElement(Card, { className: classes.card, elevation: 4 }, /* @__PURE__ */ React.createElement(CardActionArea, { onClick: () => props.onSelect?.("form") }, /* @__PURE__ */ React.createElement(CardContent, null, /* @__PURE__ */ React.createElement(Typography, { variant: "h4", component: "h3", gutterBottom: true }, t("templateEditorPage.templateEditorIntro.formEditor.title")), /* @__PURE__ */ React.createElement(Typography, { variant: "body1" }, t("templateEditorPage.templateEditorIntro.formEditor.description")))));
|
|
69
|
+
const cardFieldExplorer = /* @__PURE__ */ React.createElement(Card, { className: classes.card, elevation: 4 }, /* @__PURE__ */ React.createElement(CardActionArea, { onClick: () => props.onSelect?.("field-explorer") }, /* @__PURE__ */ React.createElement(CardContent, null, /* @__PURE__ */ React.createElement(Typography, { variant: "h4", component: "h3", gutterBottom: true }, t("templateEditorPage.templateEditorIntro.fieldExplorer.title")), /* @__PURE__ */ React.createElement(Typography, { variant: "body1" }, t(
|
|
70
|
+
"templateEditorPage.templateEditorIntro.fieldExplorer.description"
|
|
71
|
+
)))));
|
|
72
|
+
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(
|
|
66
73
|
"div",
|
|
67
74
|
{
|
|
68
75
|
style: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateEditorIntro.esm.js","sources":["../../../src/next/TemplateEditorPage/TemplateEditorIntro.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 React from 'react';\nimport Card from '@material-ui/core/Card';\nimport CardActionArea from '@material-ui/core/CardActionArea';\nimport CardContent from '@material-ui/core/CardContent';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport InfoOutlinedIcon from '@material-ui/icons/InfoOutlined';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { WebFileSystemAccess } from '../../lib/filesystem';\n\nconst useStyles = makeStyles(theme => ({\n introText: {\n textAlign: 'center',\n marginTop: theme.spacing(2),\n },\n card: {\n position: 'relative',\n maxWidth: 340,\n marginTop: theme.spacing(4),\n margin: theme.spacing(0, 2),\n },\n infoIcon: {\n position: 'absolute',\n top: theme.spacing(1),\n right: theme.spacing(1),\n },\n}));\n\ninterface EditorIntroProps {\n style?: JSX.IntrinsicElements['div']['style'];\n onSelect?: (option: 'local' | 'form' | 'field-explorer') => void;\n}\n\nexport function TemplateEditorIntro(props: EditorIntroProps) {\n const classes = useStyles();\n const supportsLoad = WebFileSystemAccess.isSupported();\n\n const cardLoadLocal = (\n <Card className={classes.card} elevation={4}>\n <CardActionArea\n disabled={!supportsLoad}\n onClick={() => props.onSelect?.('local')}\n >\n <CardContent>\n <Typography\n variant=\"h4\"\n component=\"h3\"\n gutterBottom\n color={supportsLoad ? undefined : 'textSecondary'}\n style={{ display: 'flex', flexFlow: 'row nowrap' }}\n >\n
|
|
1
|
+
{"version":3,"file":"TemplateEditorIntro.esm.js","sources":["../../../src/next/TemplateEditorPage/TemplateEditorIntro.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 React from 'react';\nimport Card from '@material-ui/core/Card';\nimport CardActionArea from '@material-ui/core/CardActionArea';\nimport CardContent from '@material-ui/core/CardContent';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport InfoOutlinedIcon from '@material-ui/icons/InfoOutlined';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { WebFileSystemAccess } from '../../lib/filesystem';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../translation';\n\nconst useStyles = makeStyles(theme => ({\n introText: {\n textAlign: 'center',\n marginTop: theme.spacing(2),\n },\n card: {\n position: 'relative',\n maxWidth: 340,\n marginTop: theme.spacing(4),\n margin: theme.spacing(0, 2),\n },\n infoIcon: {\n position: 'absolute',\n top: theme.spacing(1),\n right: theme.spacing(1),\n },\n}));\n\ninterface EditorIntroProps {\n style?: JSX.IntrinsicElements['div']['style'];\n onSelect?: (option: 'local' | 'form' | 'field-explorer') => void;\n}\n\nexport function TemplateEditorIntro(props: EditorIntroProps) {\n const classes = useStyles();\n const supportsLoad = WebFileSystemAccess.isSupported();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const cardLoadLocal = (\n <Card className={classes.card} elevation={4}>\n <CardActionArea\n disabled={!supportsLoad}\n onClick={() => props.onSelect?.('local')}\n >\n <CardContent>\n <Typography\n variant=\"h4\"\n component=\"h3\"\n gutterBottom\n color={supportsLoad ? undefined : 'textSecondary'}\n style={{ display: 'flex', flexFlow: 'row nowrap' }}\n >\n {t('templateEditorPage.templateEditorIntro.loadLocal.title')}\n </Typography>\n <Typography\n variant=\"body1\"\n color={supportsLoad ? undefined : 'textSecondary'}\n >\n {t('templateEditorPage.templateEditorIntro.loadLocal.description')}\n </Typography>\n </CardContent>\n </CardActionArea>\n {!supportsLoad && (\n <div className={classes.infoIcon}>\n <Tooltip\n placement=\"top\"\n title={t(\n 'templateEditorPage.templateEditorIntro.loadLocal.unsupportedTooltip',\n )}\n >\n <InfoOutlinedIcon />\n </Tooltip>\n </div>\n )}\n </Card>\n );\n\n const cardFormEditor = (\n <Card className={classes.card} elevation={4}>\n <CardActionArea onClick={() => props.onSelect?.('form')}>\n <CardContent>\n <Typography variant=\"h4\" component=\"h3\" gutterBottom>\n {t('templateEditorPage.templateEditorIntro.formEditor.title')}\n </Typography>\n <Typography variant=\"body1\">\n {t('templateEditorPage.templateEditorIntro.formEditor.description')}\n </Typography>\n </CardContent>\n </CardActionArea>\n </Card>\n );\n\n const cardFieldExplorer = (\n <Card className={classes.card} elevation={4}>\n <CardActionArea onClick={() => props.onSelect?.('field-explorer')}>\n <CardContent>\n <Typography variant=\"h4\" component=\"h3\" gutterBottom>\n {t('templateEditorPage.templateEditorIntro.fieldExplorer.title')}\n </Typography>\n <Typography variant=\"body1\">\n {t(\n 'templateEditorPage.templateEditorIntro.fieldExplorer.description',\n )}\n </Typography>\n </CardContent>\n </CardActionArea>\n </Card>\n );\n\n return (\n <div style={props.style}>\n <Typography variant=\"h4\" component=\"h2\" className={classes.introText}>\n {t('templateEditorPage.templateEditorIntro.title')}\n </Typography>\n <div\n style={{\n display: 'flex',\n flexFlow: 'row wrap',\n alignItems: 'flex-start',\n justifyContent: 'center',\n alignContent: 'flex-start',\n }}\n >\n {supportsLoad && cardLoadLocal}\n {cardFormEditor}\n {!supportsLoad && cardLoadLocal}\n {cardFieldExplorer}\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AA4BA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,SAAW,EAAA;AAAA,IACT,SAAW,EAAA,QAAA;AAAA,IACX,SAAA,EAAW,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,GAC5B;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,QAAU,EAAA,UAAA;AAAA,IACV,QAAU,EAAA,GAAA;AAAA,IACV,SAAA,EAAW,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC1B,MAAQ,EAAA,KAAA,CAAM,OAAQ,CAAA,CAAA,EAAG,CAAC,CAAA;AAAA,GAC5B;AAAA,EACA,QAAU,EAAA;AAAA,IACR,QAAU,EAAA,UAAA;AAAA,IACV,GAAA,EAAK,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACpB,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,GACxB;AACF,CAAE,CAAA,CAAA,CAAA;AAOK,SAAS,oBAAoB,KAAyB,EAAA;AAC3D,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAM,MAAA,YAAA,GAAe,oBAAoB,WAAY,EAAA,CAAA;AACrD,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,wBAAwB,CAAA,CAAA;AAExD,EAAA,MAAM,gCACH,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,WAAW,OAAQ,CAAA,IAAA,EAAM,WAAW,CACxC,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MACC,UAAU,CAAC,YAAA;AAAA,MACX,OAAS,EAAA,MAAM,KAAM,CAAA,QAAA,GAAW,OAAO,CAAA;AAAA,KAAA;AAAA,wCAEtC,WACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,OAAQ,EAAA,IAAA;AAAA,QACR,SAAU,EAAA,IAAA;AAAA,QACV,YAAY,EAAA,IAAA;AAAA,QACZ,KAAA,EAAO,eAAe,KAAY,CAAA,GAAA,eAAA;AAAA,QAClC,KAAO,EAAA,EAAE,OAAS,EAAA,MAAA,EAAQ,UAAU,YAAa,EAAA;AAAA,OAAA;AAAA,MAEhD,EAAE,wDAAwD,CAAA;AAAA,KAE7D,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,OAAQ,EAAA,OAAA;AAAA,QACR,KAAA,EAAO,eAAe,KAAY,CAAA,GAAA,eAAA;AAAA,OAAA;AAAA,MAEjC,EAAE,8DAA8D,CAAA;AAAA,KAErE,CAAA;AAAA,KAED,CAAC,YAAA,wCACC,KAAI,EAAA,EAAA,SAAA,EAAW,QAAQ,QACtB,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,SAAU,EAAA,KAAA;AAAA,MACV,KAAO,EAAA,CAAA;AAAA,QACL,qEAAA;AAAA,OACF;AAAA,KAAA;AAAA,wCAEC,gBAAiB,EAAA,IAAA,CAAA;AAAA,GAEtB,CAEJ,CAAA,CAAA;AAGF,EAAA,MAAM,iCACH,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,SAAW,EAAA,OAAA,CAAQ,MAAM,SAAW,EAAA,CAAA,EAAA,kBACvC,KAAA,CAAA,aAAA,CAAA,cAAA,EAAA,EAAe,SAAS,MAAM,KAAA,CAAM,WAAW,MAAM,CAAA,EAAA,sCACnD,WACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,UAAW,EAAA,EAAA,OAAA,EAAQ,MAAK,SAAU,EAAA,IAAA,EAAK,cAAY,IACjD,EAAA,EAAA,CAAA,CAAE,yDAAyD,CAC9D,CAAA,kBACC,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,SAAQ,OACjB,EAAA,EAAA,CAAA,CAAE,+DAA+D,CACpE,CACF,CACF,CACF,CAAA,CAAA;AAGF,EAAA,MAAM,iBACJ,mBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAW,QAAQ,IAAM,EAAA,SAAA,EAAW,CACxC,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAe,EAAA,EAAA,OAAA,EAAS,MAAM,KAAA,CAAM,WAAW,gBAAgB,CAAA,EAAA,kBAC7D,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA,IAAA,kBACE,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,IAAA,EAAK,WAAU,IAAK,EAAA,YAAA,EAAY,IACjD,EAAA,EAAA,CAAA,CAAE,4DAA4D,CACjE,CAAA,kBACC,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,SAAQ,OACjB,EAAA,EAAA,CAAA;AAAA,IACC,kEAAA;AAAA,GAEJ,CACF,CACF,CACF,CAAA,CAAA;AAGF,EAAA,2CACG,KAAI,EAAA,EAAA,KAAA,EAAO,KAAM,CAAA,KAAA,EAAA,sCACf,UAAW,EAAA,EAAA,OAAA,EAAQ,IAAK,EAAA,SAAA,EAAU,MAAK,SAAW,EAAA,OAAA,CAAQ,aACxD,CAAE,CAAA,8CAA8C,CACnD,CACA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAO,EAAA;AAAA,QACL,OAAS,EAAA,MAAA;AAAA,QACT,QAAU,EAAA,UAAA;AAAA,QACV,UAAY,EAAA,YAAA;AAAA,QACZ,cAAgB,EAAA,QAAA;AAAA,QAChB,YAAc,EAAA,YAAA;AAAA,OAChB;AAAA,KAAA;AAAA,IAEC,YAAgB,IAAA,aAAA;AAAA,IAChB,cAAA;AAAA,IACA,CAAC,YAAgB,IAAA,aAAA;AAAA,IACjB,iBAAA;AAAA,GAEL,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -9,6 +9,8 @@ import { ScaffolderPageContextMenu } from '@backstage/plugin-scaffolder-react/al
|
|
|
9
9
|
import { useNavigate } from 'react-router-dom';
|
|
10
10
|
import { useRouteRef } from '@backstage/core-plugin-api';
|
|
11
11
|
import { actionsRouteRef, scaffolderListTaskRouteRef, rootRouteRef } from '../../routes.esm.js';
|
|
12
|
+
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
13
|
+
import { scaffolderTranslationRef } from '../../translation.esm.js';
|
|
12
14
|
|
|
13
15
|
function TemplateEditorPage(props) {
|
|
14
16
|
const [selection, setSelection] = useState();
|
|
@@ -16,6 +18,7 @@ function TemplateEditorPage(props) {
|
|
|
16
18
|
const actionsLink = useRouteRef(actionsRouteRef);
|
|
17
19
|
const tasksLink = useRouteRef(scaffolderListTaskRouteRef);
|
|
18
20
|
const createLink = useRouteRef(rootRouteRef);
|
|
21
|
+
const { t } = useTranslationRef(scaffolderTranslationRef);
|
|
19
22
|
const scaffolderPageContextMenuProps = {
|
|
20
23
|
onEditorClicked: void 0,
|
|
21
24
|
onActionsClicked: () => navigate(actionsLink()),
|
|
@@ -71,8 +74,8 @@ function TemplateEditorPage(props) {
|
|
|
71
74
|
return /* @__PURE__ */ React.createElement(Page, { themeId: "home" }, /* @__PURE__ */ React.createElement(
|
|
72
75
|
Header,
|
|
73
76
|
{
|
|
74
|
-
title: "
|
|
75
|
-
subtitle: "
|
|
77
|
+
title: t("templateEditorPage.title"),
|
|
78
|
+
subtitle: t("templateEditorPage.subtitle")
|
|
76
79
|
},
|
|
77
80
|
/* @__PURE__ */ React.createElement(ScaffolderPageContextMenu, { ...scaffolderPageContextMenuProps })
|
|
78
81
|
), content);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateEditorPage.esm.js","sources":["../../../src/next/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, { useState } from 'react';\nimport { Content, Header, Page } from '@backstage/core-components';\nimport {\n TemplateDirectoryAccess,\n WebFileSystemAccess,\n} from '../../lib/filesystem';\nimport { CustomFieldExplorer } from './CustomFieldExplorer';\nimport { TemplateEditor } from './TemplateEditor';\nimport { TemplateFormPreviewer } from './TemplateFormPreviewer';\nimport {\n FieldExtensionOptions,\n type LayoutOptions,\n} from '@backstage/plugin-scaffolder-react';\nimport { TemplateEditorIntro } from './TemplateEditorIntro';\nimport { ScaffolderPageContextMenu } from '@backstage/plugin-scaffolder-react/alpha';\nimport { useNavigate } from 'react-router-dom';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport {\n actionsRouteRef,\n rootRouteRef,\n scaffolderListTaskRouteRef,\n} from '../../routes';\n\ntype Selection =\n | {\n type: 'local';\n directory: TemplateDirectoryAccess;\n }\n | {\n type: 'form';\n }\n | {\n type: 'field-explorer';\n };\n\ninterface TemplateEditorPageProps {\n defaultPreviewTemplate?: string;\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n layouts?: LayoutOptions[];\n}\n\nexport function TemplateEditorPage(props: TemplateEditorPageProps) {\n const [selection, setSelection] = useState<Selection>();\n const navigate = useNavigate();\n const actionsLink = useRouteRef(actionsRouteRef);\n const tasksLink = useRouteRef(scaffolderListTaskRouteRef);\n const createLink = useRouteRef(rootRouteRef);\n\n const scaffolderPageContextMenuProps = {\n onEditorClicked: undefined,\n onActionsClicked: () => navigate(actionsLink()),\n onTasksClicked: () => navigate(tasksLink()),\n onCreateClicked: () => navigate(createLink()),\n };\n\n let content: JSX.Element | null = null;\n if (selection?.type === 'local') {\n content = (\n <TemplateEditor\n directory={selection.directory}\n fieldExtensions={props.customFieldExtensions}\n onClose={() => setSelection(undefined)}\n layouts={props.layouts}\n />\n );\n } else if (selection?.type === 'form') {\n content = (\n <TemplateFormPreviewer\n defaultPreviewTemplate={props.defaultPreviewTemplate}\n customFieldExtensions={props.customFieldExtensions}\n onClose={() => setSelection(undefined)}\n layouts={props.layouts}\n />\n );\n } else if (selection?.type === 'field-explorer') {\n content = (\n <CustomFieldExplorer\n customFieldExtensions={props.customFieldExtensions}\n onClose={() => setSelection(undefined)}\n />\n );\n } else {\n content = (\n <Content>\n <TemplateEditorIntro\n onSelect={option => {\n if (option === 'local') {\n WebFileSystemAccess.requestDirectoryAccess()\n .then(directory => setSelection({ type: 'local', directory }))\n .catch(() => {});\n } else if (option === 'form') {\n setSelection({ type: 'form' });\n } else if (option === 'field-explorer') {\n setSelection({ type: 'field-explorer' });\n }\n }}\n />\n </Content>\n );\n }\n\n return (\n <Page themeId=\"home\">\n <Header\n title
|
|
1
|
+
{"version":3,"file":"TemplateEditorPage.esm.js","sources":["../../../src/next/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, { useState } from 'react';\nimport { Content, Header, Page } from '@backstage/core-components';\nimport {\n TemplateDirectoryAccess,\n WebFileSystemAccess,\n} from '../../lib/filesystem';\nimport { CustomFieldExplorer } from './CustomFieldExplorer';\nimport { TemplateEditor } from './TemplateEditor';\nimport { TemplateFormPreviewer } from './TemplateFormPreviewer';\nimport {\n FieldExtensionOptions,\n type LayoutOptions,\n} from '@backstage/plugin-scaffolder-react';\nimport { TemplateEditorIntro } from './TemplateEditorIntro';\nimport { ScaffolderPageContextMenu } from '@backstage/plugin-scaffolder-react/alpha';\nimport { useNavigate } from 'react-router-dom';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport {\n actionsRouteRef,\n rootRouteRef,\n scaffolderListTaskRouteRef,\n} from '../../routes';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../translation';\n\ntype Selection =\n | {\n type: 'local';\n directory: TemplateDirectoryAccess;\n }\n | {\n type: 'form';\n }\n | {\n type: 'field-explorer';\n };\n\ninterface TemplateEditorPageProps {\n defaultPreviewTemplate?: string;\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n layouts?: LayoutOptions[];\n}\n\nexport function TemplateEditorPage(props: TemplateEditorPageProps) {\n const [selection, setSelection] = useState<Selection>();\n const navigate = useNavigate();\n const actionsLink = useRouteRef(actionsRouteRef);\n const tasksLink = useRouteRef(scaffolderListTaskRouteRef);\n const createLink = useRouteRef(rootRouteRef);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const scaffolderPageContextMenuProps = {\n onEditorClicked: undefined,\n onActionsClicked: () => navigate(actionsLink()),\n onTasksClicked: () => navigate(tasksLink()),\n onCreateClicked: () => navigate(createLink()),\n };\n\n let content: JSX.Element | null = null;\n if (selection?.type === 'local') {\n content = (\n <TemplateEditor\n directory={selection.directory}\n fieldExtensions={props.customFieldExtensions}\n onClose={() => setSelection(undefined)}\n layouts={props.layouts}\n />\n );\n } else if (selection?.type === 'form') {\n content = (\n <TemplateFormPreviewer\n defaultPreviewTemplate={props.defaultPreviewTemplate}\n customFieldExtensions={props.customFieldExtensions}\n onClose={() => setSelection(undefined)}\n layouts={props.layouts}\n />\n );\n } else if (selection?.type === 'field-explorer') {\n content = (\n <CustomFieldExplorer\n customFieldExtensions={props.customFieldExtensions}\n onClose={() => setSelection(undefined)}\n />\n );\n } else {\n content = (\n <Content>\n <TemplateEditorIntro\n onSelect={option => {\n if (option === 'local') {\n WebFileSystemAccess.requestDirectoryAccess()\n .then(directory => setSelection({ type: 'local', directory }))\n .catch(() => {});\n } else if (option === 'form') {\n setSelection({ type: 'form' });\n } else if (option === 'field-explorer') {\n setSelection({ type: 'field-explorer' });\n }\n }}\n />\n </Content>\n );\n }\n\n return (\n <Page themeId=\"home\">\n <Header\n title={t('templateEditorPage.title')}\n subtitle={t('templateEditorPage.subtitle')}\n >\n <ScaffolderPageContextMenu {...scaffolderPageContextMenuProps} />\n </Header>\n {content}\n </Page>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,8 @@ import { useKeyboardEvent } from '@react-hookz/web';
|
|
|
11
11
|
import CodeMirror from '@uiw/react-codemirror';
|
|
12
12
|
import React, { useMemo } from 'react';
|
|
13
13
|
import { useDirectoryEditor } from './DirectoryEditorContext.esm.js';
|
|
14
|
+
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
15
|
+
import { scaffolderTranslationRef } from '../../translation.esm.js';
|
|
14
16
|
|
|
15
17
|
const useStyles = makeStyles((theme) => ({
|
|
16
18
|
container: {
|
|
@@ -42,6 +44,7 @@ const useStyles = makeStyles((theme) => ({
|
|
|
42
44
|
function TemplateEditorTextArea(props) {
|
|
43
45
|
const { errorText } = props;
|
|
44
46
|
const classes = useStyles();
|
|
47
|
+
const { t } = useTranslationRef(scaffolderTranslationRef);
|
|
45
48
|
const panelExtension = useMemo(() => {
|
|
46
49
|
if (!errorText) {
|
|
47
50
|
return showPanel.of(null);
|
|
@@ -70,21 +73,37 @@ function TemplateEditorTextArea(props) {
|
|
|
70
73
|
value: props.content,
|
|
71
74
|
onChange: props.onUpdate
|
|
72
75
|
}
|
|
73
|
-
), (props.onSave || props.onReload) && /* @__PURE__ */ React.createElement("div", { className: classes.floatingButtons }, /* @__PURE__ */ React.createElement(Paper, null, props.onSave && /* @__PURE__ */ React.createElement(
|
|
74
|
-
|
|
76
|
+
), (props.onSave || props.onReload) && /* @__PURE__ */ React.createElement("div", { className: classes.floatingButtons }, /* @__PURE__ */ React.createElement(Paper, null, props.onSave && /* @__PURE__ */ React.createElement(
|
|
77
|
+
Tooltip,
|
|
75
78
|
{
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
title: t(
|
|
80
|
+
"templateEditorPage.templateEditorTextArea.saveIconTooltip"
|
|
81
|
+
)
|
|
78
82
|
},
|
|
79
|
-
/* @__PURE__ */ React.createElement(
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
/* @__PURE__ */ React.createElement(
|
|
84
|
+
IconButton,
|
|
85
|
+
{
|
|
86
|
+
className: classes.floatingButton,
|
|
87
|
+
onClick: () => props.onSave?.()
|
|
88
|
+
},
|
|
89
|
+
/* @__PURE__ */ React.createElement(SaveIcon, null)
|
|
90
|
+
)
|
|
91
|
+
), props.onReload && /* @__PURE__ */ React.createElement(
|
|
92
|
+
Tooltip,
|
|
82
93
|
{
|
|
83
|
-
|
|
84
|
-
|
|
94
|
+
title: t(
|
|
95
|
+
"templateEditorPage.templateEditorTextArea.refreshIconTooltip"
|
|
96
|
+
)
|
|
85
97
|
},
|
|
86
|
-
/* @__PURE__ */ React.createElement(
|
|
87
|
-
|
|
98
|
+
/* @__PURE__ */ React.createElement(
|
|
99
|
+
IconButton,
|
|
100
|
+
{
|
|
101
|
+
className: classes.floatingButton,
|
|
102
|
+
onClick: () => props.onReload?.()
|
|
103
|
+
},
|
|
104
|
+
/* @__PURE__ */ React.createElement(RefreshIcon, null)
|
|
105
|
+
)
|
|
106
|
+
))));
|
|
88
107
|
}
|
|
89
108
|
function TemplateEditorDirectoryEditorTextArea(props) {
|
|
90
109
|
const directoryEditor = useDirectoryEditor();
|