@backstage/plugin-scaffolder 1.24.0-next.3 → 1.25.0-next.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.
Files changed (76) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/alpha/package.json +1 -1
  3. package/dist/alpha.d.ts +169 -2
  4. package/dist/alpha.esm.js +32 -25
  5. package/dist/alpha.esm.js.map +1 -1
  6. package/dist/components/ActionsPage/ActionsPage.esm.js +14 -10
  7. package/dist/components/ActionsPage/ActionsPage.esm.js.map +1 -1
  8. package/dist/components/ListTasksPage/ListTasksPage.esm.js +15 -11
  9. package/dist/components/ListTasksPage/ListTasksPage.esm.js.map +1 -1
  10. package/dist/components/ListTasksPage/OwnerListPicker.esm.js +8 -5
  11. package/dist/components/ListTasksPage/OwnerListPicker.esm.js.map +1 -1
  12. package/dist/components/OngoingTask/ContextMenu.esm.js +12 -4
  13. package/dist/components/OngoingTask/ContextMenu.esm.js.map +1 -1
  14. package/dist/components/OngoingTask/OngoingTask.esm.js +10 -7
  15. package/dist/components/OngoingTask/OngoingTask.esm.js.map +1 -1
  16. package/dist/components/TemplateTypePicker/TemplateTypePicker.esm.js +4 -1
  17. package/dist/components/TemplateTypePicker/TemplateTypePicker.esm.js.map +1 -1
  18. package/dist/components/fields/EntityNamePicker/EntityNamePicker.esm.js +7 -1
  19. package/dist/components/fields/EntityNamePicker/EntityNamePicker.esm.js.map +1 -1
  20. package/dist/components/fields/EntityPicker/EntityPicker.esm.js +7 -1
  21. package/dist/components/fields/EntityPicker/EntityPicker.esm.js.map +1 -1
  22. package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js +5 -2
  23. package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js.map +1 -1
  24. package/dist/components/fields/MyGroupsPicker/MyGroupsPicker.esm.js +7 -1
  25. package/dist/components/fields/MyGroupsPicker/MyGroupsPicker.esm.js.map +1 -1
  26. package/dist/components/fields/OwnedEntityPicker/OwnedEntityPicker.esm.js +7 -1
  27. package/dist/components/fields/OwnedEntityPicker/OwnedEntityPicker.esm.js.map +1 -1
  28. package/dist/components/fields/OwnerPicker/OwnerPicker.esm.js +7 -1
  29. package/dist/components/fields/OwnerPicker/OwnerPicker.esm.js.map +1 -1
  30. package/dist/components/fields/RepoBranchPicker/DefaultRepoBranchPicker.esm.js +3 -4
  31. package/dist/components/fields/RepoBranchPicker/DefaultRepoBranchPicker.esm.js.map +1 -1
  32. package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js +19 -15
  33. package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js.map +1 -1
  34. package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js +23 -6
  35. package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js.map +1 -1
  36. package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js +14 -11
  37. package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js.map +1 -1
  38. package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js +14 -9
  39. package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js.map +1 -1
  40. package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js +11 -8
  41. package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js.map +1 -1
  42. package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js +14 -9
  43. package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js.map +1 -1
  44. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerHost.esm.js +5 -2
  45. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerHost.esm.js.map +1 -1
  46. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js +13 -3
  47. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js.map +1 -1
  48. package/dist/next/TemplateEditorPage/CustomFieldExplorer.esm.js +20 -5
  49. package/dist/next/TemplateEditorPage/CustomFieldExplorer.esm.js.map +1 -1
  50. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResults.esm.js +4 -1
  51. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResults.esm.js.map +1 -1
  52. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js +17 -3
  53. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js.map +1 -1
  54. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js +22 -1
  55. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js.map +1 -1
  56. package/dist/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.esm.js +6 -1
  57. package/dist/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.esm.js.map +1 -1
  58. package/dist/next/TemplateEditorPage/TemplateEditorBrowser.esm.js +36 -13
  59. package/dist/next/TemplateEditorPage/TemplateEditorBrowser.esm.js.map +1 -1
  60. package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js +13 -6
  61. package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js.map +1 -1
  62. package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js +5 -2
  63. package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js.map +1 -1
  64. package/dist/next/TemplateEditorPage/TemplateEditorTextArea.esm.js +30 -11
  65. package/dist/next/TemplateEditorPage/TemplateEditorTextArea.esm.js.map +1 -1
  66. package/dist/next/TemplateEditorPage/TemplateFormPreviewer.esm.js +5 -2
  67. package/dist/next/TemplateEditorPage/TemplateFormPreviewer.esm.js.map +1 -1
  68. package/dist/next/TemplateListPage/TemplateListPage.esm.js +25 -17
  69. package/dist/next/TemplateListPage/TemplateListPage.esm.js.map +1 -1
  70. package/dist/next/TemplateWizardPage/TemplateWizardPage.esm.js +6 -3
  71. package/dist/next/TemplateWizardPage/TemplateWizardPage.esm.js.map +1 -1
  72. package/dist/next/TemplateWizardPage/TemplateWizardPageContextMenu.esm.js +11 -1
  73. package/dist/next/TemplateWizardPage/TemplateWizardPageContextMenu.esm.js.map +1 -1
  74. package/dist/translation.esm.js +258 -0
  75. package/dist/translation.esm.js.map +1 -0
  76. package/package.json +19 -19
@@ -1 +1 @@
1
- {"version":3,"file":"CustomFieldExplorer.esm.js","sources":["../../../src/next/TemplateEditorPage/CustomFieldExplorer.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 { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\nimport Button from '@material-ui/core/Button';\nimport Card from '@material-ui/core/Card';\nimport CardContent from '@material-ui/core/CardContent';\nimport CardHeader from '@material-ui/core/CardHeader';\nimport FormControl from '@material-ui/core/FormControl';\nimport IconButton from '@material-ui/core/IconButton';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Select from '@material-ui/core/Select';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CloseIcon from '@material-ui/icons/Close';\nimport CodeMirror from '@uiw/react-codemirror';\nimport React, { useCallback, useMemo, useState } from 'react';\nimport yaml from 'yaml';\nimport { Form } from '@backstage/plugin-scaffolder-react/alpha';\nimport { TemplateEditorForm } from './TemplateEditorForm';\nimport validator from '@rjsf/validator-ajv8';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateAreas: `\n \"controls controls\"\n \"fieldForm preview\"\n `,\n gridTemplateRows: 'auto 1fr',\n gridTemplateColumns: '1fr 1fr',\n },\n controls: {\n gridArea: 'controls',\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n margin: theme.spacing(1),\n },\n fieldForm: {\n gridArea: 'fieldForm',\n },\n preview: {\n gridArea: 'preview',\n },\n}));\n\nexport const CustomFieldExplorer = ({\n customFieldExtensions = [],\n onClose,\n}: {\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n onClose?: () => void;\n}) => {\n const classes = useStyles();\n const fieldOptions = customFieldExtensions.filter(field => !!field.schema);\n const [selectedField, setSelectedField] = useState(fieldOptions[0]);\n const [fieldFormState, setFieldFormState] = useState({});\n const [refreshKey, setRefreshKey] = useState(Date.now());\n const sampleFieldTemplate = useMemo(\n () =>\n yaml.stringify({\n parameters: [\n {\n title: `${selectedField.name} Example`,\n properties: {\n [selectedField.name]: {\n type: selectedField.schema?.returnValue?.type,\n 'ui:field': selectedField.name,\n 'ui:options': fieldFormState,\n },\n },\n },\n ],\n }),\n [fieldFormState, selectedField],\n );\n\n const fieldComponents = useMemo(() => {\n return Object.fromEntries(\n customFieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [customFieldExtensions]);\n\n const handleSelectionChange = useCallback(\n (selection: FieldExtensionOptions) => {\n setSelectedField(selection);\n setFieldFormState({});\n },\n [setFieldFormState, setSelectedField],\n );\n\n const handleFieldConfigChange = useCallback(\n (state: {}) => {\n setFieldFormState(state);\n // Force TemplateEditorForm to re-render since some fields\n // may not be responsive to ui:option changes\n setRefreshKey(Date.now());\n },\n [setFieldFormState, setRefreshKey],\n );\n\n return (\n <main className={classes.root}>\n <div className={classes.controls}>\n <FormControl variant=\"outlined\" size=\"small\" fullWidth>\n <InputLabel id=\"select-field-label\">\n Choose Custom Field Extension\n </InputLabel>\n <Select\n value={selectedField}\n label=\"Choose Custom Field Extension\"\n labelId=\"select-field-label\"\n onChange={e =>\n handleSelectionChange(e.target.value as FieldExtensionOptions)\n }\n >\n {fieldOptions.map((option, idx) => (\n <MenuItem key={idx} value={option as any}>\n {option.name}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n\n <IconButton size=\"medium\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </IconButton>\n </div>\n <div className={classes.fieldForm}>\n <Card>\n <CardHeader title=\"Field Options\" />\n <CardContent>\n <Form\n showErrorList={false}\n fields={{ ...fieldComponents }}\n noHtml5Validate\n formData={fieldFormState}\n formContext={{ fieldFormState }}\n onSubmit={e => handleFieldConfigChange(e.formData)}\n validator={validator}\n schema={selectedField.schema?.uiOptions || {}}\n experimental_defaultFormStateBehavior={{\n allOf: 'populateDefaults',\n }}\n >\n <Button\n variant=\"contained\"\n color=\"primary\"\n type=\"submit\"\n disabled={!selectedField.schema?.uiOptions}\n >\n Apply\n </Button>\n </Form>\n </CardContent>\n </Card>\n </div>\n <div className={classes.preview}>\n <Card>\n <CardHeader title=\"Example Template Spec\" />\n <CardContent>\n <CodeMirror\n readOnly\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n value={sampleFieldTemplate}\n />\n </CardContent>\n </Card>\n <TemplateEditorForm\n key={refreshKey}\n content={sampleFieldTemplate}\n contentIsSpec\n fieldExtensions={customFieldExtensions}\n setErrorText={() => null}\n />\n </div>\n </main>\n );\n};\n"],"names":["yamlSupport"],"mappings":"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"}
1
+ {"version":3,"file":"CustomFieldExplorer.esm.js","sources":["../../../src/next/TemplateEditorPage/CustomFieldExplorer.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 { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\nimport Button from '@material-ui/core/Button';\nimport Card from '@material-ui/core/Card';\nimport CardContent from '@material-ui/core/CardContent';\nimport CardHeader from '@material-ui/core/CardHeader';\nimport FormControl from '@material-ui/core/FormControl';\nimport IconButton from '@material-ui/core/IconButton';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Select from '@material-ui/core/Select';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CloseIcon from '@material-ui/icons/Close';\nimport CodeMirror from '@uiw/react-codemirror';\nimport React, { useCallback, useMemo, useState } from 'react';\nimport yaml from 'yaml';\nimport { Form } from '@backstage/plugin-scaffolder-react/alpha';\nimport { TemplateEditorForm } from './TemplateEditorForm';\nimport validator from '@rjsf/validator-ajv8';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../translation';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateAreas: `\n \"controls controls\"\n \"fieldForm preview\"\n `,\n gridTemplateRows: 'auto 1fr',\n gridTemplateColumns: '1fr 1fr',\n },\n controls: {\n gridArea: 'controls',\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n margin: theme.spacing(1),\n },\n fieldForm: {\n gridArea: 'fieldForm',\n },\n preview: {\n gridArea: 'preview',\n },\n}));\n\nexport const CustomFieldExplorer = ({\n customFieldExtensions = [],\n onClose,\n}: {\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n onClose?: () => void;\n}) => {\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const fieldOptions = customFieldExtensions.filter(field => !!field.schema);\n const [selectedField, setSelectedField] = useState(fieldOptions[0]);\n const [fieldFormState, setFieldFormState] = useState({});\n const [refreshKey, setRefreshKey] = useState(Date.now());\n const sampleFieldTemplate = useMemo(\n () =>\n yaml.stringify({\n parameters: [\n {\n title: `${selectedField.name} Example`,\n properties: {\n [selectedField.name]: {\n type: selectedField.schema?.returnValue?.type,\n 'ui:field': selectedField.name,\n 'ui:options': fieldFormState,\n },\n },\n },\n ],\n }),\n [fieldFormState, selectedField],\n );\n\n const fieldComponents = useMemo(() => {\n return Object.fromEntries(\n customFieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [customFieldExtensions]);\n\n const handleSelectionChange = useCallback(\n (selection: FieldExtensionOptions) => {\n setSelectedField(selection);\n setFieldFormState({});\n },\n [setFieldFormState, setSelectedField],\n );\n\n const handleFieldConfigChange = useCallback(\n (state: {}) => {\n setFieldFormState(state);\n // Force TemplateEditorForm to re-render since some fields\n // may not be responsive to ui:option changes\n setRefreshKey(Date.now());\n },\n [setFieldFormState, setRefreshKey],\n );\n\n return (\n <main className={classes.root}>\n <div className={classes.controls}>\n <FormControl variant=\"outlined\" size=\"small\" fullWidth>\n <InputLabel id=\"select-field-label\">\n {t('templateEditorPage.customFieldExplorer.selectFieldLabel')}\n </InputLabel>\n <Select\n value={selectedField}\n label={t('templateEditorPage.customFieldExplorer.selectFieldLabel')}\n labelId=\"select-field-label\"\n onChange={e =>\n handleSelectionChange(e.target.value as FieldExtensionOptions)\n }\n >\n {fieldOptions.map((option, idx) => (\n <MenuItem key={idx} value={option as any}>\n {option.name}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n\n <IconButton size=\"medium\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </IconButton>\n </div>\n <div className={classes.fieldForm}>\n <Card>\n <CardHeader\n title={t('templateEditorPage.customFieldExplorer.fieldForm.title')}\n />\n <CardContent>\n <Form\n showErrorList={false}\n fields={{ ...fieldComponents }}\n noHtml5Validate\n formData={fieldFormState}\n formContext={{ fieldFormState }}\n onSubmit={e => handleFieldConfigChange(e.formData)}\n validator={validator}\n schema={selectedField.schema?.uiOptions || {}}\n experimental_defaultFormStateBehavior={{\n allOf: 'populateDefaults',\n }}\n >\n <Button\n variant=\"contained\"\n color=\"primary\"\n type=\"submit\"\n disabled={!selectedField.schema?.uiOptions}\n >\n {t(\n 'templateEditorPage.customFieldExplorer.fieldForm.applyButtonTitle',\n )}\n </Button>\n </Form>\n </CardContent>\n </Card>\n </div>\n <div className={classes.preview}>\n <Card>\n <CardHeader\n title={t('templateEditorPage.customFieldExplorer.preview.title')}\n />\n <CardContent>\n <CodeMirror\n readOnly\n theme=\"dark\"\n height=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n value={sampleFieldTemplate}\n />\n </CardContent>\n </Card>\n <TemplateEditorForm\n key={refreshKey}\n content={sampleFieldTemplate}\n contentIsSpec\n fieldExtensions={customFieldExtensions}\n setErrorText={() => null}\n />\n </div>\n </main>\n );\n};\n"],"names":["yamlSupport"],"mappings":"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"}
@@ -10,6 +10,8 @@ import React, { useState, useEffect } from 'react';
10
10
  import { useDryRun } from '../DryRunContext.esm.js';
11
11
  import { DryRunResultsList } from './DryRunResultsList.esm.js';
12
12
  import { DryRunResultsView } from './DryRunResultsView.esm.js';
13
+ import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
14
+ import { scaffolderTranslationRef } from '../../../translation.esm.js';
13
15
 
14
16
  const useStyles = makeStyles((theme) => ({
15
17
  header: {
@@ -34,6 +36,7 @@ function DryRunResults() {
34
36
  const dryRun = useDryRun();
35
37
  const [expanded, setExpanded] = useState(false);
36
38
  const [hidden, setHidden] = useState(true);
39
+ const { t } = useTranslationRef(scaffolderTranslationRef);
37
40
  const resultsLength = dryRun.results.length;
38
41
  const prevResultsLength = usePrevious(resultsLength);
39
42
  useEffect(() => {
@@ -59,7 +62,7 @@ function DryRunResults() {
59
62
  className: classes.header,
60
63
  expandIcon: /* @__PURE__ */ React.createElement(ExpandLessIcon, null)
61
64
  },
62
- /* @__PURE__ */ React.createElement(Typography, null, "Dry-run results")
65
+ /* @__PURE__ */ React.createElement(Typography, null, t("templateEditorPage.dryRunResults.title"))
63
66
  ),
64
67
  /* @__PURE__ */ React.createElement(Divider, { orientation: "horizontal" }),
65
68
  /* @__PURE__ */ React.createElement(AccordionDetails, { className: classes.content }, /* @__PURE__ */ React.createElement(DryRunResultsList, null), /* @__PURE__ */ React.createElement(Divider, { orientation: "horizontal" }), /* @__PURE__ */ React.createElement(DryRunResultsView, null))
@@ -1 +1 @@
1
- {"version":3,"file":"DryRunResults.esm.js","sources":["../../../../src/next/TemplateEditorPage/DryRunResults/DryRunResults.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 Accordion from '@material-ui/core/Accordion';\nimport AccordionDetails from '@material-ui/core/AccordionDetails';\nimport AccordionSummary from '@material-ui/core/AccordionSummary';\nimport Divider from '@material-ui/core/Divider';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandLess';\nimport { usePrevious } from '@react-hookz/web';\nimport React, { useEffect, useState } from 'react';\nimport { useDryRun } from '../DryRunContext';\nimport { DryRunResultsList } from './DryRunResultsList';\nimport { DryRunResultsView } from './DryRunResultsView';\n\nconst useStyles = makeStyles(theme => ({\n header: {\n height: 48,\n minHeight: 0,\n '&.Mui-expanded': {\n height: 48,\n minHeight: 0,\n },\n },\n content: {\n display: 'grid',\n background: theme.palette.background.default,\n gridTemplateColumns: '180px auto 1fr',\n gridTemplateRows: '1fr',\n padding: 0,\n height: 400,\n },\n}));\n\nexport function DryRunResults() {\n const classes = useStyles();\n const dryRun = useDryRun();\n const [expanded, setExpanded] = useState(false);\n const [hidden, setHidden] = useState(true);\n\n const resultsLength = dryRun.results.length;\n const prevResultsLength = usePrevious(resultsLength);\n useEffect(() => {\n if (prevResultsLength === 0 && resultsLength === 1) {\n setHidden(false);\n setExpanded(true);\n } else if (prevResultsLength === 1 && resultsLength === 0) {\n setExpanded(false);\n }\n }, [prevResultsLength, resultsLength]);\n\n return (\n <>\n <Accordion\n variant=\"outlined\"\n expanded={expanded}\n hidden={resultsLength === 0 && hidden}\n onChange={(_, exp) => setExpanded(exp)}\n onTransitionEnd={() => resultsLength === 0 && setHidden(true)}\n >\n <AccordionSummary\n className={classes.header}\n expandIcon={<ExpandMoreIcon />}\n >\n <Typography>Dry-run results</Typography>\n </AccordionSummary>\n <Divider orientation=\"horizontal\" />\n <AccordionDetails className={classes.content}>\n <DryRunResultsList />\n <Divider orientation=\"horizontal\" />\n <DryRunResultsView />\n </AccordionDetails>\n </Accordion>\n </>\n );\n}\n"],"names":["ExpandMoreIcon"],"mappings":";;;;;;;;;;;;;AA6BA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA,EAAA;AAAA,IACR,SAAW,EAAA,CAAA;AAAA,IACX,gBAAkB,EAAA;AAAA,MAChB,MAAQ,EAAA,EAAA;AAAA,MACR,SAAW,EAAA,CAAA;AAAA,KACb;AAAA,GACF;AAAA,EACA,OAAS,EAAA;AAAA,IACP,OAAS,EAAA,MAAA;AAAA,IACT,UAAA,EAAY,KAAM,CAAA,OAAA,CAAQ,UAAW,CAAA,OAAA;AAAA,IACrC,mBAAqB,EAAA,gBAAA;AAAA,IACrB,gBAAkB,EAAA,KAAA;AAAA,IAClB,OAAS,EAAA,CAAA;AAAA,IACT,MAAQ,EAAA,GAAA;AAAA,GACV;AACF,CAAE,CAAA,CAAA,CAAA;AAEK,SAAS,aAAgB,GAAA;AAC9B,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,SAAS,SAAU,EAAA,CAAA;AACzB,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA,CAAA;AAC9C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAS,IAAI,CAAA,CAAA;AAEzC,EAAM,MAAA,aAAA,GAAgB,OAAO,OAAQ,CAAA,MAAA,CAAA;AACrC,EAAM,MAAA,iBAAA,GAAoB,YAAY,aAAa,CAAA,CAAA;AACnD,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,iBAAA,KAAsB,CAAK,IAAA,aAAA,KAAkB,CAAG,EAAA;AAClD,MAAA,SAAA,CAAU,KAAK,CAAA,CAAA;AACf,MAAA,WAAA,CAAY,IAAI,CAAA,CAAA;AAAA,KACP,MAAA,IAAA,iBAAA,KAAsB,CAAK,IAAA,aAAA,KAAkB,CAAG,EAAA;AACzD,MAAA,WAAA,CAAY,KAAK,CAAA,CAAA;AAAA,KACnB;AAAA,GACC,EAAA,CAAC,iBAAmB,EAAA,aAAa,CAAC,CAAA,CAAA;AAErC,EAAA,uBAEI,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,UAAA;AAAA,MACR,QAAA;AAAA,MACA,MAAA,EAAQ,kBAAkB,CAAK,IAAA,MAAA;AAAA,MAC/B,QAAU,EAAA,CAAC,CAAG,EAAA,GAAA,KAAQ,YAAY,GAAG,CAAA;AAAA,MACrC,eAAiB,EAAA,MAAM,aAAkB,KAAA,CAAA,IAAK,UAAU,IAAI,CAAA;AAAA,KAAA;AAAA,oBAE5D,KAAA,CAAA,aAAA;AAAA,MAAC,gBAAA;AAAA,MAAA;AAAA,QACC,WAAW,OAAQ,CAAA,MAAA;AAAA,QACnB,UAAA,sCAAaA,cAAe,EAAA,IAAA,CAAA;AAAA,OAAA;AAAA,sBAE5B,KAAA,CAAA,aAAA,CAAC,kBAAW,iBAAe,CAAA;AAAA,KAC7B;AAAA,oBACA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,WAAA,EAAY,YAAa,EAAA,CAAA;AAAA,oBACjC,KAAA,CAAA,aAAA,CAAA,gBAAA,EAAA,EAAiB,SAAW,EAAA,OAAA,CAAQ,2BAClC,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,IAAkB,CACnB,kBAAA,KAAA,CAAA,aAAA,CAAC,WAAQ,WAAY,EAAA,YAAA,EAAa,CAClC,kBAAA,KAAA,CAAA,aAAA,CAAC,uBAAkB,CACrB,CAAA;AAAA,GAEJ,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"DryRunResults.esm.js","sources":["../../../../src/next/TemplateEditorPage/DryRunResults/DryRunResults.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 Accordion from '@material-ui/core/Accordion';\nimport AccordionDetails from '@material-ui/core/AccordionDetails';\nimport AccordionSummary from '@material-ui/core/AccordionSummary';\nimport Divider from '@material-ui/core/Divider';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandLess';\nimport { usePrevious } from '@react-hookz/web';\nimport React, { useEffect, useState } from 'react';\nimport { useDryRun } from '../DryRunContext';\nimport { DryRunResultsList } from './DryRunResultsList';\nimport { DryRunResultsView } from './DryRunResultsView';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\n\nconst useStyles = makeStyles(theme => ({\n header: {\n height: 48,\n minHeight: 0,\n '&.Mui-expanded': {\n height: 48,\n minHeight: 0,\n },\n },\n content: {\n display: 'grid',\n background: theme.palette.background.default,\n gridTemplateColumns: '180px auto 1fr',\n gridTemplateRows: '1fr',\n padding: 0,\n height: 400,\n },\n}));\n\nexport function DryRunResults() {\n const classes = useStyles();\n const dryRun = useDryRun();\n const [expanded, setExpanded] = useState(false);\n const [hidden, setHidden] = useState(true);\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const resultsLength = dryRun.results.length;\n const prevResultsLength = usePrevious(resultsLength);\n useEffect(() => {\n if (prevResultsLength === 0 && resultsLength === 1) {\n setHidden(false);\n setExpanded(true);\n } else if (prevResultsLength === 1 && resultsLength === 0) {\n setExpanded(false);\n }\n }, [prevResultsLength, resultsLength]);\n\n return (\n <>\n <Accordion\n variant=\"outlined\"\n expanded={expanded}\n hidden={resultsLength === 0 && hidden}\n onChange={(_, exp) => setExpanded(exp)}\n onTransitionEnd={() => resultsLength === 0 && setHidden(true)}\n >\n <AccordionSummary\n className={classes.header}\n expandIcon={<ExpandMoreIcon />}\n >\n <Typography>{t('templateEditorPage.dryRunResults.title')}</Typography>\n </AccordionSummary>\n <Divider orientation=\"horizontal\" />\n <AccordionDetails className={classes.content}>\n <DryRunResultsList />\n <Divider orientation=\"horizontal\" />\n <DryRunResultsView />\n </AccordionDetails>\n </Accordion>\n </>\n );\n}\n"],"names":["ExpandMoreIcon"],"mappings":"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"}
@@ -12,6 +12,8 @@ import DownloadIcon from '@material-ui/icons/GetApp';
12
12
  import React from 'react';
13
13
  import { useDryRun } from '../DryRunContext.esm.js';
14
14
  import { downloadBlob } from '../../../lib/download/helpers.esm.js';
15
+ import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
16
+ import { scaffolderTranslationRef } from '../../../translation.esm.js';
15
17
 
16
18
  const useStyles = makeStyles((theme) => ({
17
19
  root: {
@@ -32,6 +34,7 @@ const useStyles = makeStyles((theme) => ({
32
34
  function DryRunResultsList() {
33
35
  const classes = useStyles();
34
36
  const dryRun = useDryRun();
37
+ const { t } = useTranslationRef(scaffolderTranslationRef);
35
38
  return /* @__PURE__ */ React.createElement(List, { className: classes.root, dense: true }, dryRun.results.map((result) => {
36
39
  const failed = result.log.some((l) => l.body.status === "failed");
37
40
  let isLoading = false;
@@ -58,13 +61,22 @@ function DryRunResultsList() {
58
61
  },
59
62
  failed ? /* @__PURE__ */ React.createElement(Cancel, null) : /* @__PURE__ */ React.createElement(CheckIcon, null)
60
63
  ),
61
- /* @__PURE__ */ React.createElement(ListItemText, { primary: `Result ${result.id}` }),
64
+ /* @__PURE__ */ React.createElement(
65
+ ListItemText,
66
+ {
67
+ primary: t("templateEditorPage.dryRunResultsList.title", {
68
+ resultId: `${result.id}`
69
+ })
70
+ }
71
+ ),
62
72
  /* @__PURE__ */ React.createElement(ListItemSecondaryAction, null, /* @__PURE__ */ React.createElement(
63
73
  IconButton,
64
74
  {
65
75
  edge: "end",
66
76
  "aria-label": "download",
67
- title: "Download as .zip",
77
+ title: t(
78
+ "templateEditorPage.dryRunResultsList.downloadButtonTitle"
79
+ ),
68
80
  disabled: isLoading,
69
81
  onClick: () => downloadResult()
70
82
  },
@@ -74,7 +86,9 @@ function DryRunResultsList() {
74
86
  {
75
87
  edge: "end",
76
88
  "aria-label": "delete",
77
- title: "Delete result",
89
+ title: t(
90
+ "templateEditorPage.dryRunResultsList.deleteButtonTitle"
91
+ ),
78
92
  onClick: () => dryRun.deleteResult(result.id)
79
93
  },
80
94
  /* @__PURE__ */ React.createElement(DeleteIcon, null)
@@ -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 primary={`Result ${result.id}`} />\n <ListItemSecondaryAction>\n <IconButton\n edge=\"end\"\n aria-label=\"download\"\n title=\"Download as .zip\"\n disabled={isLoading}\n onClick={() => downloadResult()}\n >\n <DownloadIcon />\n </IconButton>\n <IconButton\n edge=\"end\"\n aria-label=\"delete\"\n title=\"Delete result\"\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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"}
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
- return /* @__PURE__ */ React.createElement("div", { className: classes.root }, /* @__PURE__ */ React.createElement(Tabs, { value: selectedTab, onChange: (_, v) => setSelectedTab(v) }, /* @__PURE__ */ React.createElement(Tab, { value: "files", label: "Files" }), /* @__PURE__ */ React.createElement(Tab, { value: "log", label: "Log" }), /* @__PURE__ */ React.createElement(Tab, { value: "output", label: "Output" })), /* @__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))));
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":";;;;;;;;;;;;;;;;AAgCA,MAAM,YAAY,UAAW,CAAA;AAAA,EAC3B,IAAM,EAAA;AAAA,IACJ,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,eAAA;AAAA,GACZ;AAAA,EACA,cAAgB,EAAA;AAAA,IACd,IAAM,EAAA,CAAA;AAAA,IACN,QAAU,EAAA,UAAA;AAAA,GACZ;AAAA,EACA,OAAS,EAAA;AAAA,IACP,QAAU,EAAA,UAAA;AAAA,IACV,GAAK,EAAA,CAAA;AAAA,IACL,IAAM,EAAA,CAAA;AAAA,IACN,KAAO,EAAA,CAAA;AAAA,IACP,MAAQ,EAAA,CAAA;AAAA,IAER,OAAS,EAAA,MAAA;AAAA,IACT,OAAS,EAAA;AAAA,MACP,IAAM,EAAA,CAAA;AAAA,KACR;AAAA,GACF;AAAA,EACA,UAAY,EAAA;AAAA,IACV,MAAQ,EAAA,MAAA;AAAA,IACR,SAAW,EAAA,MAAA;AAAA,GACb;AACF,CAAC,CAAA,CAAA;AAED,SAAS,YAAe,GAAA;AACtB,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAM,MAAA,EAAE,cAAe,EAAA,GAAI,SAAU,EAAA,CAAA;AACrC,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAiB,EAAE,CAAA,CAAA;AAC3D,EAAM,MAAA,YAAA,GAAe,gBAAgB,iBAAkB,CAAA,IAAA;AAAA,IACrD,CAAA,CAAA,KAAK,EAAE,IAAS,KAAA,YAAA;AAAA,GAClB,CAAA;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,cAAgB,EAAA;AAClB,MAAM,MAAA,CAAC,SAAS,CAAA,GAAI,cAAe,CAAA,iBAAA,CAAA;AACnC,MAAA,IAAI,SAAW,EAAA;AACb,QAAA,eAAA,CAAgB,UAAU,IAAI,CAAA,CAAA;AAAA,OACzB,MAAA;AACL,QAAA,eAAA,CAAgB,EAAE,CAAA,CAAA;AAAA,OACpB;AAAA,KACF;AACA,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT,EAAG,CAAC,cAAc,CAAC,CAAA,CAAA;AAEnB,EAAA,IAAI,CAAC,cAAgB,EAAA;AACnB,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AACA,EAAA,2CACG,sBACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,QAAU,EAAA,YAAA;AAAA,MACV,QAAU,EAAA,eAAA;AAAA,MACV,WAAW,cAAe,CAAA,iBAAA,CAAkB,GAAI,CAAA,CAAA,IAAA,KAAQ,KAAK,IAAI,CAAA;AAAA,KAAA;AAAA,GAEnE,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,WAAW,OAAQ,CAAA,UAAA;AAAA,MACnB,KAAM,EAAA,MAAA;AAAA,MACN,MAAO,EAAA,MAAA;AAAA,MACP,UAAY,EAAA,CAAC,cAAe,CAAA,MAAA,CAAOA,IAAW,CAAC,CAAA;AAAA,MAC/C,QAAQ,EAAA,IAAA;AAAA,MACR,OACE,YAAc,EAAA,aAAA,GAAgB,IAAK,CAAA,YAAA,CAAa,aAAa,CAAI,GAAA,EAAA;AAAA,KAAA;AAAA,GAGvE,CAAA,CAAA;AAEJ,CAAA;AACA,SAAS,UAAa,GAAA;AACpB,EAAM,MAAA,EAAE,cAAe,EAAA,GAAI,SAAU,EAAA,CAAA;AACrC,EAAA,MAAM,CAAC,aAAA,EAAe,qBAAqB,CAAA,GAAI,QAAiB,EAAA,CAAA;AAEhE,EAAM,MAAA,KAAA,GAAQ,QAAQ,MAAM;AAC1B,IAAA,IAAI,CAAC,cAAgB,EAAA;AACnB,MAAA,OAAO,EAAC,CAAA;AAAA,KACV;AACA,IACE,OAAA,cAAA,CAAe,KAAM,CAAA,GAAA,CAAI,CAAQ,IAAA,KAAA;AAC/B,MAAM,MAAA,OAAA,GAAU,eAAe,GAAI,CAAA,MAAA;AAAA,QACjC,CAAK,CAAA,KAAA,CAAA,CAAE,IAAK,CAAA,MAAA,KAAW,IAAK,CAAA,EAAA;AAAA,OAC9B,CAAA;AACA,MAAO,OAAA;AAAA,QACL,IAAI,IAAK,CAAA,EAAA;AAAA,QACT,MAAM,IAAK,CAAA,IAAA;AAAA,QACX,SAAA,EAAW,QAAQ,GAAI,CAAA,CAAA,CAAA,KAAK,EAAE,IAAK,CAAA,OAAO,CAAE,CAAA,IAAA,CAAK,IAAI,CAAA;AAAA,QACrD,QAAQ,OAAQ,CAAA,OAAA,CAAQ,SAAS,CAAC,CAAA,EAAG,KAAK,MAAU,IAAA,WAAA;AAAA,OACtD,CAAA;AAAA,KACD,KAAK,EAAC,CAAA;AAAA,GAEX,EAAG,CAAC,cAAc,CAAC,CAAA,CAAA;AAEnB,EAAA,IAAI,CAAC,cAAgB,EAAA;AACnB,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EAAM,MAAA,YAAA,GAAe,MAAM,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,EAAO,KAAA,aAAa,CAAK,IAAA,KAAA,CAAM,CAAC,CAAA,CAAA;AAEvE,EAAA,2CACG,sBACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,iBAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,eAAe,YAAa,CAAA,EAAA;AAAA,MAC5B,gBAAkB,EAAA,qBAAA;AAAA,KAAA;AAAA,qBAEnB,KAAA,CAAA,aAAA,CAAA,SAAA,EAAA,EAAU,MAAM,YAAc,EAAA,SAAA,IAAa,IAAI,CAClD,CAAA,CAAA;AAEJ,CAAA;AAEA,SAAS,aAAgB,GAAA;AACvB,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAM,MAAA,EAAE,cAAe,EAAA,GAAI,SAAU,EAAA,CAAA;AAErC,EAAA,IAAI,CAAC,cAAgB,EAAA;AACnB,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EAAA,2CACG,sBACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,GAAI,EAAA,EAAA,EAAA,EAAI,KACN,cAAe,CAAA,MAAA,EAAQ,KAAO,EAAA,MAAA,wCAC5B,aAAc,EAAA,EAAA,MAAA,EAAQ,cAAe,CAAA,MAAA,EAAQ,CAElD,CACA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,WAAW,OAAQ,CAAA,UAAA;AAAA,MACnB,KAAM,EAAA,MAAA;AAAA,MACN,MAAO,EAAA,MAAA;AAAA,MACP,UAAY,EAAA,CAAC,cAAe,CAAA,MAAA,CAAOA,IAAW,CAAC,CAAA;AAAA,MAC/C,QAAQ,EAAA,IAAA;AAAA,MACR,OAAO,IAAK,CAAA,SAAA,CAAU,cAAe,CAAA,MAAA,EAAQ,MAAM,CAAC,CAAA;AAAA,KAAA;AAAA,GAExD,CAAA,CAAA;AAEJ,CAAA;AAEO,SAAS,iBAAoB,GAAA;AAClC,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAM,MAAA,CAAC,WAAa,EAAA,cAAc,CAAI,GAAA,QAAA;AAAA,IACpC,OAAA;AAAA,GACF,CAAA;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,OAAA,CAAQ,IACtB,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,WAAa,EAAA,QAAA,EAAU,CAAC,CAAA,EAAG,MAAM,cAAe,CAAA,CAAC,CAC5D,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,GAAI,EAAA,EAAA,KAAA,EAAM,OAAQ,EAAA,KAAA,EAAM,SAAQ,CACjC,kBAAA,KAAA,CAAA,aAAA,CAAC,GAAI,EAAA,EAAA,KAAA,EAAM,KAAM,EAAA,KAAA,EAAM,KAAM,EAAA,CAAA,sCAC5B,GAAI,EAAA,EAAA,KAAA,EAAM,QAAS,EAAA,KAAA,EAAM,QAAS,EAAA,CACrC,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,aAAQ,CAET,kBAAA,KAAA,CAAA,aAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,cAAA,EAAA,kBACrB,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,WAAW,OAAQ,CAAA,OAAA,EAAA,EACrB,WAAgB,KAAA,OAAA,oBAAY,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,IAAa,CACzC,EAAA,WAAA,KAAgB,yBAAU,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,IAAW,CACrC,EAAA,WAAA,KAAgB,QAAY,oBAAA,KAAA,CAAA,aAAA,CAAC,aAAc,EAAA,IAAA,CAC9C,CACF,CACF,CAAA,CAAA;AAEJ;;;;"}
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" }, "Skipped") : /* @__PURE__ */ React.createElement(StepTimeTicker, { step }))
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
- "Are you sure? Unsaved changes will be lost"
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(Tooltip, { title: "Save all files" }, /* @__PURE__ */ React.createElement(
48
- IconButton,
50
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: classes.buttons }, /* @__PURE__ */ React.createElement(
51
+ Tooltip,
49
52
  {
50
- className: classes.button,
51
- disabled: directoryEditor.files.every((file) => !file.dirty),
52
- onClick: () => directoryEditor.save()
53
+ title: t("templateEditorPage.templateEditorBrowser.saveIconTooltip")
53
54
  },
54
- /* @__PURE__ */ React.createElement(SaveIcon, null)
55
- )), /* @__PURE__ */ React.createElement(Tooltip, { title: "Reload directory" }, /* @__PURE__ */ React.createElement(
56
- IconButton,
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
- className: classes.button,
59
- onClick: () => directoryEditor.reload()
67
+ title: t(
68
+ "templateEditorPage.templateEditorBrowser.reloadIconTooltip"
69
+ )
60
70
  },
61
- /* @__PURE__ */ React.createElement(RefreshIcon, null)
62
- )), /* @__PURE__ */ React.createElement("div", { className: classes.buttonsGap }), /* @__PURE__ */ React.createElement(Tooltip, { title: "Close directory" }, /* @__PURE__ */ React.createElement(IconButton, { className: classes.button, onClick: handleClose }, /* @__PURE__ */ React.createElement(CloseIcon, null)))), /* @__PURE__ */ React.createElement(Divider, { className: classes.buttonsDivider }), /* @__PURE__ */ React.createElement(
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 'Are you sure? Unsaved changes will be lost',\n );\n if (!accepted) {\n return;\n }\n }\n props.onClose();\n };\n\n return (\n <>\n <div className={classes.buttons}>\n <Tooltip title=\"Save all files\">\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 title=\"Reload directory\">\n <IconButton\n className={classes.button}\n onClick={() => directoryEditor.reload()}\n >\n <RefreshIcon />\n </IconButton>\n </Tooltip>\n <div className={classes.buttonsGap} />\n <Tooltip title=\"Close directory\">\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":"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"}
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":"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"}
@@ -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
- "Load Template Directory"
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
- "Load a local template directory, allowing you to both edit and try executing your own template."
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: "Only supported in some Chromium-based browsers"
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 }, "Edit Template Form"), /* @__PURE__ */ React.createElement(Typography, { variant: "body1" }, "Preview and edit a template form, either using a sample template or by loading a template from the catalog."))));
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 }, "Custom Field Explorer"), /* @__PURE__ */ React.createElement(Typography, { variant: "body1" }, "View and play around with available installed custom field extensions."))));
65
- return /* @__PURE__ */ React.createElement("div", { style: props.style }, /* @__PURE__ */ React.createElement(Typography, { variant: "h4", component: "h2", className: classes.introText }, "Get started by choosing one of the options below"), /* @__PURE__ */ React.createElement(
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: {