@backstage/plugin-scaffolder 1.20.0 → 1.20.1-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 (83) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/alpha/package.json +1 -1
  3. package/dist/api.esm.js +9 -17
  4. package/dist/api.esm.js.map +1 -1
  5. package/dist/components/ActionsPage/ActionsPage.esm.js +10 -13
  6. package/dist/components/ActionsPage/ActionsPage.esm.js.map +1 -1
  7. package/dist/components/FileBrowser/FileBrowser.esm.js +1 -1
  8. package/dist/components/FileBrowser/FileBrowser.esm.js.map +1 -1
  9. package/dist/components/ListTasksPage/ListTasksPage.esm.js +9 -17
  10. package/dist/components/ListTasksPage/ListTasksPage.esm.js.map +1 -1
  11. package/dist/components/ListTasksPage/columns/OwnerEntityColumn.esm.js +1 -2
  12. package/dist/components/ListTasksPage/columns/OwnerEntityColumn.esm.js.map +1 -1
  13. package/dist/components/ListTasksPage/columns/TemplateTitleColumn.esm.js +1 -1
  14. package/dist/components/ListTasksPage/columns/TemplateTitleColumn.esm.js.map +1 -1
  15. package/dist/components/OngoingTask/ContextMenu.esm.js +1 -1
  16. package/dist/components/OngoingTask/ContextMenu.esm.js.map +1 -1
  17. package/dist/components/OngoingTask/OngoingTask.esm.js +10 -18
  18. package/dist/components/OngoingTask/OngoingTask.esm.js.map +1 -1
  19. package/dist/components/fields/EntityNamePicker/EntityNamePicker.esm.js +3 -3
  20. package/dist/components/fields/EntityNamePicker/EntityNamePicker.esm.js.map +1 -1
  21. package/dist/components/fields/EntityPicker/EntityPicker.esm.js +11 -13
  22. package/dist/components/fields/EntityPicker/EntityPicker.esm.js.map +1 -1
  23. package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js +6 -7
  24. package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js.map +1 -1
  25. package/dist/components/fields/MultiEntityPicker/MultiEntityPicker.esm.js +15 -21
  26. package/dist/components/fields/MultiEntityPicker/MultiEntityPicker.esm.js.map +1 -1
  27. package/dist/components/fields/MyGroupsPicker/MyGroupsPicker.esm.js +7 -11
  28. package/dist/components/fields/MyGroupsPicker/MyGroupsPicker.esm.js.map +1 -1
  29. package/dist/components/fields/OwnedEntityPicker/OwnedEntityPicker.esm.js +1 -1
  30. package/dist/components/fields/OwnedEntityPicker/OwnedEntityPicker.esm.js.map +1 -1
  31. package/dist/components/fields/OwnerPicker/OwnerPicker.esm.js +4 -5
  32. package/dist/components/fields/OwnerPicker/OwnerPicker.esm.js.map +1 -1
  33. package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js +16 -16
  34. package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js.map +1 -1
  35. package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js +6 -6
  36. package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js.map +1 -1
  37. package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js +2 -2
  38. package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js.map +1 -1
  39. package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js +2 -2
  40. package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js.map +1 -1
  41. package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js +2 -2
  42. package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js.map +1 -1
  43. package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js +2 -2
  44. package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js.map +1 -1
  45. package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js +8 -25
  46. package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js.map +1 -1
  47. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerHost.esm.js +6 -6
  48. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerHost.esm.js.map +1 -1
  49. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js +3 -3
  50. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js.map +1 -1
  51. package/dist/components/fields/RepoUrlPicker/validation.esm.js +2 -3
  52. package/dist/components/fields/RepoUrlPicker/validation.esm.js.map +1 -1
  53. package/dist/components/fields/SecretInput/SecretInput.esm.js +3 -5
  54. package/dist/components/fields/SecretInput/SecretInput.esm.js.map +1 -1
  55. package/dist/next/TemplateEditorPage/CustomFieldExplorer.esm.js +14 -18
  56. package/dist/next/TemplateEditorPage/CustomFieldExplorer.esm.js.map +1 -1
  57. package/dist/next/TemplateEditorPage/DirectoryEditorContext.esm.js +55 -91
  58. package/dist/next/TemplateEditorPage/DirectoryEditorContext.esm.js.map +1 -1
  59. package/dist/next/TemplateEditorPage/DryRunContext.esm.js +5 -9
  60. package/dist/next/TemplateEditorPage/DryRunContext.esm.js.map +1 -1
  61. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js +1 -2
  62. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js.map +1 -1
  63. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js +8 -12
  64. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js.map +1 -1
  65. package/dist/next/TemplateEditorPage/DryRunResults/TaskPageLinks.esm.js +2 -5
  66. package/dist/next/TemplateEditorPage/DryRunResults/TaskPageLinks.esm.js.map +1 -1
  67. package/dist/next/TemplateEditorPage/TemplateEditorBrowser.esm.js +1 -2
  68. package/dist/next/TemplateEditorPage/TemplateEditorBrowser.esm.js.map +1 -1
  69. package/dist/next/TemplateEditorPage/TemplateEditorForm.esm.js +4 -13
  70. package/dist/next/TemplateEditorPage/TemplateEditorForm.esm.js.map +1 -1
  71. package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js +3 -12
  72. package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js.map +1 -1
  73. package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js +3 -3
  74. package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js.map +1 -1
  75. package/dist/next/TemplateEditorPage/TemplateEditorTextArea.esm.js +5 -15
  76. package/dist/next/TemplateEditorPage/TemplateEditorTextArea.esm.js.map +1 -1
  77. package/dist/next/TemplateEditorPage/TemplateFormPreviewer.esm.js +4 -7
  78. package/dist/next/TemplateEditorPage/TemplateFormPreviewer.esm.js.map +1 -1
  79. package/dist/next/TemplateListPage/TemplateListPage.esm.js +5 -7
  80. package/dist/next/TemplateListPage/TemplateListPage.esm.js.map +1 -1
  81. package/dist/next/TemplateWizardPage/TemplateWizardPage.esm.js +1 -2
  82. package/dist/next/TemplateWizardPage/TemplateWizardPage.esm.js.map +1 -1
  83. package/package.json +10 -10
@@ -1 +1 @@
1
- {"version":3,"file":"DirectoryEditorContext.esm.js","sources":["../../../src/next/TemplateEditorPage/DirectoryEditorContext.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 { ErrorPanel, Progress } from '@backstage/core-components';\nimport { useAsync, useRerender } from '@react-hookz/web';\nimport React, { createContext, ReactNode, useContext, useEffect } from 'react';\nimport {\n TemplateDirectoryAccess,\n TemplateFileAccess,\n} from '../../lib/filesystem';\n\nconst MAX_SIZE = 1024 * 1024;\nconst MAX_SIZE_MESSAGE = 'This file is too large to be displayed';\n\ninterface DirectoryEditorFile {\n /** The path of the file relative to the root directory */\n path: string;\n /** The staged content of the file */\n content: string;\n /** Whether the staged content matches what is on disk */\n dirty: boolean;\n\n /** Update the staged content of the file without saving */\n updateContent(content: string): void;\n /** Save the staged content of the file to disk */\n save(): Promise<void>;\n /** Reload the staged content of the file from disk */\n reload(): Promise<void>;\n}\n\ninterface DirectoryEditor {\n /** A list of all files in the edited directory */\n files: Array<DirectoryEditorFile>;\n\n /** The currently selected file */\n selectedFile: DirectoryEditorFile | undefined;\n /** Switch the selected file */\n setSelectedFile(path: string | undefined): void;\n\n /** Save all files to disk */\n save(): Promise<void>;\n /** Reload all files from disk */\n reload(): Promise<void>;\n\n subscribe(listener: () => void): () => void;\n}\n\nclass DirectoryEditorFileManager implements DirectoryEditorFile {\n readonly #access: TemplateFileAccess;\n readonly #signalUpdate: () => void;\n\n #content?: string;\n #savedContent?: string;\n\n constructor(access: TemplateFileAccess, signalUpdate: () => void) {\n this.#access = access;\n this.#signalUpdate = signalUpdate;\n }\n\n get path() {\n return this.#access.path;\n }\n\n get content() {\n return this.#content ?? MAX_SIZE_MESSAGE;\n }\n\n updateContent(content: string): void {\n if (this.#content === undefined) {\n return;\n }\n this.#content = content;\n this.#signalUpdate();\n }\n\n get dirty() {\n return this.#content !== this.#savedContent;\n }\n\n async save(): Promise<void> {\n if (this.#content !== undefined) {\n await this.#access.save(this.#content);\n this.#savedContent = this.#content;\n this.#signalUpdate();\n }\n }\n\n async reload(): Promise<void> {\n const file = await this.#access.file();\n if (file.size > MAX_SIZE) {\n if (this.#content !== undefined) {\n this.#content = undefined;\n this.#savedContent = undefined;\n this.#signalUpdate();\n }\n return;\n }\n\n const content = await file.text();\n if (this.#content !== content) {\n this.#content = content;\n this.#savedContent = content;\n this.#signalUpdate();\n }\n }\n}\n\nclass DirectoryEditorManager implements DirectoryEditor {\n readonly #access: TemplateDirectoryAccess;\n readonly #listeners = new Set<() => void>();\n\n #files: DirectoryEditorFile[] = [];\n #selectedFile: DirectoryEditorFile | undefined;\n\n constructor(access: TemplateDirectoryAccess) {\n this.#access = access;\n }\n\n get files() {\n return this.#files;\n }\n\n get selectedFile() {\n return this.#selectedFile;\n }\n\n setSelectedFile = (path: string | undefined): void => {\n const prev = this.#selectedFile;\n const next = this.#files.find(file => file.path === path);\n if (prev !== next) {\n this.#selectedFile = next;\n this.#signalUpdate();\n }\n };\n\n get dirty() {\n return this.#files.some(file => file.dirty);\n }\n\n async save(): Promise<void> {\n await Promise.all(this.#files.map(file => file.save()));\n }\n\n async reload(): Promise<void> {\n const selectedPath = this.#selectedFile?.path;\n\n const files = await this.#access.listFiles();\n const fileManagers = await Promise.all(\n files.map(async file => {\n const manager = new DirectoryEditorFileManager(\n file,\n this.#signalUpdate,\n );\n await manager.reload();\n return manager;\n }),\n );\n this.#files.length = 0;\n this.#files.push(...fileManagers);\n\n this.setSelectedFile(selectedPath);\n this.#signalUpdate();\n }\n\n subscribe(listener: () => void): () => void {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n }\n\n #signalUpdate = () => {\n this.#listeners.forEach(listener => listener());\n };\n}\n\nconst DirectoryEditorContext = createContext<DirectoryEditor | undefined>(\n undefined,\n);\n\nexport function useDirectoryEditor(): DirectoryEditor {\n const value = useContext(DirectoryEditorContext);\n const rerender = useRerender();\n\n useEffect(() => value?.subscribe(rerender), [value, rerender]);\n\n if (!value) {\n throw new Error('must be used within a DirectoryEditorProvider');\n }\n return value;\n}\n\ninterface DirectoryEditorProviderProps {\n directory: TemplateDirectoryAccess;\n children?: ReactNode;\n}\n\nexport function DirectoryEditorProvider(props: DirectoryEditorProviderProps) {\n const { directory } = props;\n\n const [{ result, error }, { execute }] = useAsync(\n async (dir: TemplateDirectoryAccess) => {\n const manager = new DirectoryEditorManager(dir);\n await manager.reload();\n\n const firstYaml = manager.files.find(file => file.path.match(/\\.ya?ml$/));\n if (firstYaml) {\n manager.setSelectedFile(firstYaml.path);\n }\n\n return manager;\n },\n );\n\n useEffect(() => {\n execute(directory);\n }, [execute, directory]);\n\n if (error) {\n return <ErrorPanel error={error} />;\n } else if (!result) {\n return <Progress />;\n }\n\n return (\n <DirectoryEditorContext.Provider value={result}>\n {props.children}\n </DirectoryEditorContext.Provider>\n );\n}\n"],"names":["_access","_signalUpdate"],"mappings":"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"}
1
+ {"version":3,"file":"DirectoryEditorContext.esm.js","sources":["../../../src/next/TemplateEditorPage/DirectoryEditorContext.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 { ErrorPanel, Progress } from '@backstage/core-components';\nimport { useAsync, useRerender } from '@react-hookz/web';\nimport React, { createContext, ReactNode, useContext, useEffect } from 'react';\nimport {\n TemplateDirectoryAccess,\n TemplateFileAccess,\n} from '../../lib/filesystem';\n\nconst MAX_SIZE = 1024 * 1024;\nconst MAX_SIZE_MESSAGE = 'This file is too large to be displayed';\n\ninterface DirectoryEditorFile {\n /** The path of the file relative to the root directory */\n path: string;\n /** The staged content of the file */\n content: string;\n /** Whether the staged content matches what is on disk */\n dirty: boolean;\n\n /** Update the staged content of the file without saving */\n updateContent(content: string): void;\n /** Save the staged content of the file to disk */\n save(): Promise<void>;\n /** Reload the staged content of the file from disk */\n reload(): Promise<void>;\n}\n\ninterface DirectoryEditor {\n /** A list of all files in the edited directory */\n files: Array<DirectoryEditorFile>;\n\n /** The currently selected file */\n selectedFile: DirectoryEditorFile | undefined;\n /** Switch the selected file */\n setSelectedFile(path: string | undefined): void;\n\n /** Save all files to disk */\n save(): Promise<void>;\n /** Reload all files from disk */\n reload(): Promise<void>;\n\n subscribe(listener: () => void): () => void;\n}\n\nclass DirectoryEditorFileManager implements DirectoryEditorFile {\n readonly #access: TemplateFileAccess;\n readonly #signalUpdate: () => void;\n\n #content?: string;\n #savedContent?: string;\n\n constructor(access: TemplateFileAccess, signalUpdate: () => void) {\n this.#access = access;\n this.#signalUpdate = signalUpdate;\n }\n\n get path() {\n return this.#access.path;\n }\n\n get content() {\n return this.#content ?? MAX_SIZE_MESSAGE;\n }\n\n updateContent(content: string): void {\n if (this.#content === undefined) {\n return;\n }\n this.#content = content;\n this.#signalUpdate();\n }\n\n get dirty() {\n return this.#content !== this.#savedContent;\n }\n\n async save(): Promise<void> {\n if (this.#content !== undefined) {\n await this.#access.save(this.#content);\n this.#savedContent = this.#content;\n this.#signalUpdate();\n }\n }\n\n async reload(): Promise<void> {\n const file = await this.#access.file();\n if (file.size > MAX_SIZE) {\n if (this.#content !== undefined) {\n this.#content = undefined;\n this.#savedContent = undefined;\n this.#signalUpdate();\n }\n return;\n }\n\n const content = await file.text();\n if (this.#content !== content) {\n this.#content = content;\n this.#savedContent = content;\n this.#signalUpdate();\n }\n }\n}\n\nclass DirectoryEditorManager implements DirectoryEditor {\n readonly #access: TemplateDirectoryAccess;\n readonly #listeners = new Set<() => void>();\n\n #files: DirectoryEditorFile[] = [];\n #selectedFile: DirectoryEditorFile | undefined;\n\n constructor(access: TemplateDirectoryAccess) {\n this.#access = access;\n }\n\n get files() {\n return this.#files;\n }\n\n get selectedFile() {\n return this.#selectedFile;\n }\n\n setSelectedFile = (path: string | undefined): void => {\n const prev = this.#selectedFile;\n const next = this.#files.find(file => file.path === path);\n if (prev !== next) {\n this.#selectedFile = next;\n this.#signalUpdate();\n }\n };\n\n get dirty() {\n return this.#files.some(file => file.dirty);\n }\n\n async save(): Promise<void> {\n await Promise.all(this.#files.map(file => file.save()));\n }\n\n async reload(): Promise<void> {\n const selectedPath = this.#selectedFile?.path;\n\n const files = await this.#access.listFiles();\n const fileManagers = await Promise.all(\n files.map(async file => {\n const manager = new DirectoryEditorFileManager(\n file,\n this.#signalUpdate,\n );\n await manager.reload();\n return manager;\n }),\n );\n this.#files.length = 0;\n this.#files.push(...fileManagers);\n\n this.setSelectedFile(selectedPath);\n this.#signalUpdate();\n }\n\n subscribe(listener: () => void): () => void {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n }\n\n #signalUpdate = () => {\n this.#listeners.forEach(listener => listener());\n };\n}\n\nconst DirectoryEditorContext = createContext<DirectoryEditor | undefined>(\n undefined,\n);\n\nexport function useDirectoryEditor(): DirectoryEditor {\n const value = useContext(DirectoryEditorContext);\n const rerender = useRerender();\n\n useEffect(() => value?.subscribe(rerender), [value, rerender]);\n\n if (!value) {\n throw new Error('must be used within a DirectoryEditorProvider');\n }\n return value;\n}\n\ninterface DirectoryEditorProviderProps {\n directory: TemplateDirectoryAccess;\n children?: ReactNode;\n}\n\nexport function DirectoryEditorProvider(props: DirectoryEditorProviderProps) {\n const { directory } = props;\n\n const [{ result, error }, { execute }] = useAsync(\n async (dir: TemplateDirectoryAccess) => {\n const manager = new DirectoryEditorManager(dir);\n await manager.reload();\n\n const firstYaml = manager.files.find(file => file.path.match(/\\.ya?ml$/));\n if (firstYaml) {\n manager.setSelectedFile(firstYaml.path);\n }\n\n return manager;\n },\n );\n\n useEffect(() => {\n execute(directory);\n }, [execute, directory]);\n\n if (error) {\n return <ErrorPanel error={error} />;\n } else if (!result) {\n return <Progress />;\n }\n\n return (\n <DirectoryEditorContext.Provider value={result}>\n {props.children}\n </DirectoryEditorContext.Provider>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -45,7 +45,6 @@ function DryRunProvider(props) {
45
45
  }, []);
46
46
  const deleteResult = useCallback((id) => {
47
47
  setState((prevState) => {
48
- var _a;
49
48
  const index = prevState.results.findIndex((r) => r.id === id);
50
49
  if (index === -1) {
51
50
  return prevState;
@@ -54,7 +53,7 @@ function DryRunProvider(props) {
54
53
  const [deleted] = newResults.splice(index, 1);
55
54
  return {
56
55
  results: newResults,
57
- selectedResult: ((_a = prevState.selectedResult) == null ? void 0 : _a.id) === deleted.id ? newResults[0] : prevState.selectedResult
56
+ selectedResult: prevState.selectedResult?.id === deleted.id ? newResults[0] : prevState.selectedResult
58
57
  };
59
58
  });
60
59
  }, []);
@@ -77,13 +76,10 @@ function DryRunProvider(props) {
77
76
  ...response,
78
77
  id: idRef.current++
79
78
  };
80
- setState((prevState) => {
81
- var _a;
82
- return {
83
- results: [...prevState.results, result],
84
- selectedResult: (_a = prevState.selectedResult) != null ? _a : result
85
- };
86
- });
79
+ setState((prevState) => ({
80
+ results: [...prevState.results, result],
81
+ selectedResult: prevState.selectedResult ?? result
82
+ }));
87
83
  },
88
84
  [scaffolderApi]
89
85
  );
@@ -1 +1 @@
1
- {"version":3,"file":"DryRunContext.esm.js","sources":["../../../src/next/TemplateEditorPage/DryRunContext.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport yaml from 'yaml';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport React, {\n createContext,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n scaffolderApiRef,\n ScaffolderDryRunResponse,\n} from '@backstage/plugin-scaffolder-react';\n\nconst MAX_CONTENT_SIZE = 64 * 1024;\nconst CHUNK_SIZE = 32 * 1024;\n\ninterface DryRunOptions {\n templateContent: string;\n values: JsonObject;\n files: Array<{ path: string; content: string }>;\n}\n\nexport interface DryRunResult extends ScaffolderDryRunResponse {\n id: number;\n}\n\ninterface DryRun {\n results: DryRunResult[];\n selectedResult: DryRunResult | undefined;\n\n selectResult(id: number): void;\n deleteResult(id: number): void;\n execute(options: DryRunOptions): Promise<void>;\n}\n\nconst DryRunContext = createContext<DryRun | undefined>(undefined);\n\ninterface DryRunProviderProps {\n children: ReactNode;\n}\n\nexport function base64EncodeContent(content: string): string {\n if (content.length > MAX_CONTENT_SIZE) {\n return window.btoa('<file too large>');\n }\n\n try {\n return window.btoa(content);\n } catch {\n const decoder = new TextEncoder();\n const buffer = decoder.encode(content);\n\n const chunks = new Array<string>();\n for (let offset = 0; offset < buffer.length; offset += CHUNK_SIZE) {\n chunks.push(\n String.fromCharCode(...buffer.slice(offset, offset + CHUNK_SIZE)),\n );\n }\n return window.btoa(chunks.join(''));\n }\n}\n\nexport function DryRunProvider(props: DryRunProviderProps) {\n const scaffolderApi = useApi(scaffolderApiRef);\n\n const [state, setState] = useState<\n Pick<DryRun, 'results' | 'selectedResult'>\n >({\n results: [],\n selectedResult: undefined,\n });\n const idRef = useRef(1);\n\n const selectResult = useCallback((id: number) => {\n setState(prevState => {\n const result = prevState.results.find(r => r.id === id);\n if (result === prevState.selectedResult) {\n return prevState;\n }\n return {\n results: prevState.results,\n selectedResult: result,\n };\n });\n }, []);\n\n const deleteResult = useCallback((id: number) => {\n setState(prevState => {\n const index = prevState.results.findIndex(r => r.id === id);\n if (index === -1) {\n return prevState;\n }\n const newResults = prevState.results.slice();\n const [deleted] = newResults.splice(index, 1);\n return {\n results: newResults,\n selectedResult:\n prevState.selectedResult?.id === deleted.id\n ? newResults[0]\n : prevState.selectedResult,\n };\n });\n }, []);\n\n const execute = useCallback(\n async (options: DryRunOptions) => {\n if (!scaffolderApi.dryRun) {\n throw new Error('Scaffolder API does not support dry-run');\n }\n\n const parsed = yaml.parse(options.templateContent);\n\n const response = await scaffolderApi.dryRun({\n template: parsed,\n values: options.values,\n secrets: {},\n directoryContents: options.files.map(file => ({\n path: file.path,\n base64Content: base64EncodeContent(file.content),\n })),\n });\n\n const result = {\n ...response,\n id: idRef.current++,\n };\n\n setState(prevState => ({\n results: [...prevState.results, result],\n selectedResult: prevState.selectedResult ?? result,\n }));\n },\n [scaffolderApi],\n );\n\n const dryRun = useMemo(\n () => ({\n ...state,\n selectResult,\n deleteResult,\n execute,\n }),\n [state, selectResult, deleteResult, execute],\n );\n\n return (\n <DryRunContext.Provider value={dryRun}>\n {props.children}\n </DryRunContext.Provider>\n );\n}\n\nexport function useDryRun(): DryRun {\n const value = useContext(DryRunContext);\n if (!value) {\n throw new Error('must be used within a DryRunProvider');\n }\n return value;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DryRunContext.esm.js","sources":["../../../src/next/TemplateEditorPage/DryRunContext.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport yaml from 'yaml';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport React, {\n createContext,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n scaffolderApiRef,\n ScaffolderDryRunResponse,\n} from '@backstage/plugin-scaffolder-react';\n\nconst MAX_CONTENT_SIZE = 64 * 1024;\nconst CHUNK_SIZE = 32 * 1024;\n\ninterface DryRunOptions {\n templateContent: string;\n values: JsonObject;\n files: Array<{ path: string; content: string }>;\n}\n\nexport interface DryRunResult extends ScaffolderDryRunResponse {\n id: number;\n}\n\ninterface DryRun {\n results: DryRunResult[];\n selectedResult: DryRunResult | undefined;\n\n selectResult(id: number): void;\n deleteResult(id: number): void;\n execute(options: DryRunOptions): Promise<void>;\n}\n\nconst DryRunContext = createContext<DryRun | undefined>(undefined);\n\ninterface DryRunProviderProps {\n children: ReactNode;\n}\n\nexport function base64EncodeContent(content: string): string {\n if (content.length > MAX_CONTENT_SIZE) {\n return window.btoa('<file too large>');\n }\n\n try {\n return window.btoa(content);\n } catch {\n const decoder = new TextEncoder();\n const buffer = decoder.encode(content);\n\n const chunks = new Array<string>();\n for (let offset = 0; offset < buffer.length; offset += CHUNK_SIZE) {\n chunks.push(\n String.fromCharCode(...buffer.slice(offset, offset + CHUNK_SIZE)),\n );\n }\n return window.btoa(chunks.join(''));\n }\n}\n\nexport function DryRunProvider(props: DryRunProviderProps) {\n const scaffolderApi = useApi(scaffolderApiRef);\n\n const [state, setState] = useState<\n Pick<DryRun, 'results' | 'selectedResult'>\n >({\n results: [],\n selectedResult: undefined,\n });\n const idRef = useRef(1);\n\n const selectResult = useCallback((id: number) => {\n setState(prevState => {\n const result = prevState.results.find(r => r.id === id);\n if (result === prevState.selectedResult) {\n return prevState;\n }\n return {\n results: prevState.results,\n selectedResult: result,\n };\n });\n }, []);\n\n const deleteResult = useCallback((id: number) => {\n setState(prevState => {\n const index = prevState.results.findIndex(r => r.id === id);\n if (index === -1) {\n return prevState;\n }\n const newResults = prevState.results.slice();\n const [deleted] = newResults.splice(index, 1);\n return {\n results: newResults,\n selectedResult:\n prevState.selectedResult?.id === deleted.id\n ? newResults[0]\n : prevState.selectedResult,\n };\n });\n }, []);\n\n const execute = useCallback(\n async (options: DryRunOptions) => {\n if (!scaffolderApi.dryRun) {\n throw new Error('Scaffolder API does not support dry-run');\n }\n\n const parsed = yaml.parse(options.templateContent);\n\n const response = await scaffolderApi.dryRun({\n template: parsed,\n values: options.values,\n secrets: {},\n directoryContents: options.files.map(file => ({\n path: file.path,\n base64Content: base64EncodeContent(file.content),\n })),\n });\n\n const result = {\n ...response,\n id: idRef.current++,\n };\n\n setState(prevState => ({\n results: [...prevState.results, result],\n selectedResult: prevState.selectedResult ?? result,\n }));\n },\n [scaffolderApi],\n );\n\n const dryRun = useMemo(\n () => ({\n ...state,\n selectResult,\n deleteResult,\n execute,\n }),\n [state, selectResult, deleteResult, execute],\n );\n\n return (\n <DryRunContext.Provider value={dryRun}>\n {props.children}\n </DryRunContext.Provider>\n );\n}\n\nexport function useDryRun(): DryRun {\n const value = useContext(DryRunContext);\n if (!value) {\n throw new Error('must be used within a DryRunProvider');\n }\n return value;\n}\n"],"names":[],"mappings":";;;;;AAiCA,MAAM,mBAAmB,EAAK,GAAA,IAAA,CAAA;AAC9B,MAAM,aAAa,EAAK,GAAA,IAAA,CAAA;AAqBxB,MAAM,aAAA,GAAgB,cAAkC,KAAS,CAAA,CAAA,CAAA;AAM1D,SAAS,oBAAoB,OAAyB,EAAA;AAC3D,EAAI,IAAA,OAAA,CAAQ,SAAS,gBAAkB,EAAA;AACrC,IAAO,OAAA,MAAA,CAAO,KAAK,kBAAkB,CAAA,CAAA;AAAA,GACvC;AAEA,EAAI,IAAA;AACF,IAAO,OAAA,MAAA,CAAO,KAAK,OAAO,CAAA,CAAA;AAAA,GACpB,CAAA,MAAA;AACN,IAAM,MAAA,OAAA,GAAU,IAAI,WAAY,EAAA,CAAA;AAChC,IAAM,MAAA,MAAA,GAAS,OAAQ,CAAA,MAAA,CAAO,OAAO,CAAA,CAAA;AAErC,IAAM,MAAA,MAAA,GAAS,IAAI,KAAc,EAAA,CAAA;AACjC,IAAA,KAAA,IAAS,SAAS,CAAG,EAAA,MAAA,GAAS,MAAO,CAAA,MAAA,EAAQ,UAAU,UAAY,EAAA;AACjE,MAAO,MAAA,CAAA,IAAA;AAAA,QACL,MAAA,CAAO,aAAa,GAAG,MAAA,CAAO,MAAM,MAAQ,EAAA,MAAA,GAAS,UAAU,CAAC,CAAA;AAAA,OAClE,CAAA;AAAA,KACF;AACA,IAAA,OAAO,MAAO,CAAA,IAAA,CAAK,MAAO,CAAA,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA;AAAA,GACpC;AACF,CAAA;AAEO,SAAS,eAAe,KAA4B,EAAA;AACzD,EAAM,MAAA,aAAA,GAAgB,OAAO,gBAAgB,CAAA,CAAA;AAE7C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAExB,CAAA;AAAA,IACA,SAAS,EAAC;AAAA,IACV,cAAgB,EAAA,KAAA,CAAA;AAAA,GACjB,CAAA,CAAA;AACD,EAAM,MAAA,KAAA,GAAQ,OAAO,CAAC,CAAA,CAAA;AAEtB,EAAM,MAAA,YAAA,GAAe,WAAY,CAAA,CAAC,EAAe,KAAA;AAC/C,IAAA,QAAA,CAAS,CAAa,SAAA,KAAA;AACpB,MAAA,MAAM,SAAS,SAAU,CAAA,OAAA,CAAQ,KAAK,CAAK,CAAA,KAAA,CAAA,CAAE,OAAO,EAAE,CAAA,CAAA;AACtD,MAAI,IAAA,MAAA,KAAW,UAAU,cAAgB,EAAA;AACvC,QAAO,OAAA,SAAA,CAAA;AAAA,OACT;AACA,MAAO,OAAA;AAAA,QACL,SAAS,SAAU,CAAA,OAAA;AAAA,QACnB,cAAgB,EAAA,MAAA;AAAA,OAClB,CAAA;AAAA,KACD,CAAA,CAAA;AAAA,GACH,EAAG,EAAE,CAAA,CAAA;AAEL,EAAM,MAAA,YAAA,GAAe,WAAY,CAAA,CAAC,EAAe,KAAA;AAC/C,IAAA,QAAA,CAAS,CAAa,SAAA,KAAA;AACpB,MAAA,MAAM,QAAQ,SAAU,CAAA,OAAA,CAAQ,UAAU,CAAK,CAAA,KAAA,CAAA,CAAE,OAAO,EAAE,CAAA,CAAA;AAC1D,MAAA,IAAI,UAAU,CAAI,CAAA,EAAA;AAChB,QAAO,OAAA,SAAA,CAAA;AAAA,OACT;AACA,MAAM,MAAA,UAAA,GAAa,SAAU,CAAA,OAAA,CAAQ,KAAM,EAAA,CAAA;AAC3C,MAAA,MAAM,CAAC,OAAO,CAAA,GAAI,UAAW,CAAA,MAAA,CAAO,OAAO,CAAC,CAAA,CAAA;AAC5C,MAAO,OAAA;AAAA,QACL,OAAS,EAAA,UAAA;AAAA,QACT,cAAA,EACE,UAAU,cAAgB,EAAA,EAAA,KAAO,QAAQ,EACrC,GAAA,UAAA,CAAW,CAAC,CAAA,GACZ,SAAU,CAAA,cAAA;AAAA,OAClB,CAAA;AAAA,KACD,CAAA,CAAA;AAAA,GACH,EAAG,EAAE,CAAA,CAAA;AAEL,EAAA,MAAM,OAAU,GAAA,WAAA;AAAA,IACd,OAAO,OAA2B,KAAA;AAChC,MAAI,IAAA,CAAC,cAAc,MAAQ,EAAA;AACzB,QAAM,MAAA,IAAI,MAAM,yCAAyC,CAAA,CAAA;AAAA,OAC3D;AAEA,MAAA,MAAM,MAAS,GAAA,IAAA,CAAK,KAAM,CAAA,OAAA,CAAQ,eAAe,CAAA,CAAA;AAEjD,MAAM,MAAA,QAAA,GAAW,MAAM,aAAA,CAAc,MAAO,CAAA;AAAA,QAC1C,QAAU,EAAA,MAAA;AAAA,QACV,QAAQ,OAAQ,CAAA,MAAA;AAAA,QAChB,SAAS,EAAC;AAAA,QACV,iBAAmB,EAAA,OAAA,CAAQ,KAAM,CAAA,GAAA,CAAI,CAAS,IAAA,MAAA;AAAA,UAC5C,MAAM,IAAK,CAAA,IAAA;AAAA,UACX,aAAA,EAAe,mBAAoB,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,SAC/C,CAAA,CAAA;AAAA,OACH,CAAA,CAAA;AAED,MAAA,MAAM,MAAS,GAAA;AAAA,QACb,GAAG,QAAA;AAAA,QACH,IAAI,KAAM,CAAA,OAAA,EAAA;AAAA,OACZ,CAAA;AAEA,MAAA,QAAA,CAAS,CAAc,SAAA,MAAA;AAAA,QACrB,OAAS,EAAA,CAAC,GAAG,SAAA,CAAU,SAAS,MAAM,CAAA;AAAA,QACtC,cAAA,EAAgB,UAAU,cAAkB,IAAA,MAAA;AAAA,OAC5C,CAAA,CAAA,CAAA;AAAA,KACJ;AAAA,IACA,CAAC,aAAa,CAAA;AAAA,GAChB,CAAA;AAEA,EAAA,MAAM,MAAS,GAAA,OAAA;AAAA,IACb,OAAO;AAAA,MACL,GAAG,KAAA;AAAA,MACH,YAAA;AAAA,MACA,YAAA;AAAA,MACA,OAAA;AAAA,KACF,CAAA;AAAA,IACA,CAAC,KAAA,EAAO,YAAc,EAAA,YAAA,EAAc,OAAO,CAAA;AAAA,GAC7C,CAAA;AAEA,EAAA,2CACG,aAAc,CAAA,QAAA,EAAd,EAAuB,KAAO,EAAA,MAAA,EAAA,EAC5B,MAAM,QACT,CAAA,CAAA;AAEJ,CAAA;AAEO,SAAS,SAAoB,GAAA;AAClC,EAAM,MAAA,KAAA,GAAQ,WAAW,aAAa,CAAA,CAAA;AACtC,EAAA,IAAI,CAAC,KAAO,EAAA;AACV,IAAM,MAAA,IAAI,MAAM,sCAAsC,CAAA,CAAA;AAAA,GACxD;AACA,EAAO,OAAA,KAAA,CAAA;AACT;;;;"}
@@ -33,7 +33,6 @@ function DryRunResultsList() {
33
33
  const classes = useStyles();
34
34
  const dryRun = useDryRun();
35
35
  return /* @__PURE__ */ React.createElement(List, { className: classes.root, dense: true }, dryRun.results.map((result) => {
36
- var _a;
37
36
  const failed = result.log.some((l) => l.body.status === "failed");
38
37
  let isLoading = false;
39
38
  async function downloadResult() {
@@ -49,7 +48,7 @@ function DryRunResultsList() {
49
48
  {
50
49
  button: true,
51
50
  key: result.id,
52
- selected: ((_a = dryRun.selectedResult) == null ? void 0 : _a.id) === result.id,
51
+ selected: dryRun.selectedResult?.id === result.id,
53
52
  onClick: () => dryRun.selectResult(result.id)
54
53
  },
55
54
  /* @__PURE__ */ React.createElement(
@@ -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';\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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"}
@@ -43,7 +43,7 @@ function FilesContent() {
43
43
  const classes = useStyles();
44
44
  const { selectedResult } = useDryRun();
45
45
  const [selectedPath, setSelectedPath] = useState("");
46
- const selectedFile = selectedResult == null ? void 0 : selectedResult.directoryContents.find(
46
+ const selectedFile = selectedResult?.directoryContents.find(
47
47
  (f) => f.path === selectedPath
48
48
  );
49
49
  useEffect(() => {
@@ -75,21 +75,18 @@ function FilesContent() {
75
75
  height: "100%",
76
76
  extensions: [StreamLanguage.define(yaml)],
77
77
  readOnly: true,
78
- value: (selectedFile == null ? void 0 : selectedFile.base64Content) ? atob(selectedFile.base64Content) : ""
78
+ value: selectedFile?.base64Content ? atob(selectedFile.base64Content) : ""
79
79
  }
80
80
  ));
81
81
  }
82
82
  function LogContent() {
83
- var _a, _b;
84
83
  const { selectedResult } = useDryRun();
85
84
  const [currentStepId, setUserSelectedStepId] = useState();
86
85
  const steps = useMemo(() => {
87
- var _a2;
88
86
  if (!selectedResult) {
89
87
  return [];
90
88
  }
91
- return (_a2 = selectedResult.steps.map((step) => {
92
- var _a3, _b2;
89
+ return selectedResult.steps.map((step) => {
93
90
  const stepLog = selectedResult.log.filter(
94
91
  (l) => l.body.stepId === step.id
95
92
  );
@@ -97,14 +94,14 @@ function LogContent() {
97
94
  id: step.id,
98
95
  name: step.name,
99
96
  logString: stepLog.map((l) => l.body.message).join("\n"),
100
- status: (_b2 = (_a3 = stepLog[stepLog.length - 1]) == null ? void 0 : _a3.body.status) != null ? _b2 : "completed"
97
+ status: stepLog[stepLog.length - 1]?.body.status ?? "completed"
101
98
  };
102
- })) != null ? _a2 : [];
99
+ }) ?? [];
103
100
  }, [selectedResult]);
104
101
  if (!selectedResult) {
105
102
  return null;
106
103
  }
107
- const selectedStep = (_a = steps.find((s) => s.id === currentStepId)) != null ? _a : steps[0];
104
+ const selectedStep = steps.find((s) => s.id === currentStepId) ?? steps[0];
108
105
  return /* @__PURE__ */ React.createElement(DryRunResultsSplitView, null, /* @__PURE__ */ React.createElement(
109
106
  TaskStatusStepper,
110
107
  {
@@ -112,16 +109,15 @@ function LogContent() {
112
109
  currentStepId: selectedStep.id,
113
110
  onUserStepChange: setUserSelectedStepId
114
111
  }
115
- ), /* @__PURE__ */ React.createElement(LogViewer, { text: (_b = selectedStep == null ? void 0 : selectedStep.logString) != null ? _b : "" }));
112
+ ), /* @__PURE__ */ React.createElement(LogViewer, { text: selectedStep?.logString ?? "" }));
116
113
  }
117
114
  function OutputContent() {
118
- var _a, _b;
119
115
  const classes = useStyles();
120
116
  const { selectedResult } = useDryRun();
121
117
  if (!selectedResult) {
122
118
  return null;
123
119
  }
124
- return /* @__PURE__ */ React.createElement(DryRunResultsSplitView, null, /* @__PURE__ */ React.createElement(Box, { pt: 2 }, ((_b = (_a = selectedResult.output) == null ? void 0 : _a.links) == null ? void 0 : _b.length) && /* @__PURE__ */ React.createElement(TaskPageLinks, { output: selectedResult.output })), /* @__PURE__ */ React.createElement(
120
+ return /* @__PURE__ */ React.createElement(DryRunResultsSplitView, null, /* @__PURE__ */ React.createElement(Box, { pt: 2 }, selectedResult.output?.links?.length && /* @__PURE__ */ React.createElement(TaskPageLinks, { output: selectedResult.output })), /* @__PURE__ */ React.createElement(
125
121
  CodeMirror,
126
122
  {
127
123
  className: classes.codeMirror,
@@ -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","_a","_b"],"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';\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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"}
@@ -10,10 +10,7 @@ const TaskPageLinks = ({ output }) => {
10
10
  const { links = [] } = output;
11
11
  const app = useApp();
12
12
  const entityRoute = useRouteRef(entityRouteRef);
13
- const iconResolver = (key) => {
14
- var _a;
15
- return key ? (_a = app.getSystemIcon(key)) != null ? _a : LanguageIcon : LanguageIcon;
16
- };
13
+ const iconResolver = (key) => key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon;
17
14
  return /* @__PURE__ */ React.createElement(Box, { px: 3, pb: 3 }, links.filter(({ url, entityRef }) => url || entityRef).map(({ url, entityRef, title, icon }) => {
18
15
  if (entityRef) {
19
16
  const entityName = parseEntityRef(entityRef, {
@@ -29,7 +26,7 @@ const TaskPageLinks = ({ output }) => {
29
26
  {
30
27
  key: `output-link-${i}`,
31
28
  href: url,
32
- text: title != null ? title : url,
29
+ text: title ?? url,
33
30
  Icon: iconResolver(icon),
34
31
  target: "_blank"
35
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TaskPageLinks.esm.js","sources":["../../../../src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport Box from '@material-ui/core/Box';\nimport LanguageIcon from '@material-ui/icons/Language';\nimport React from 'react';\nimport { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react';\nimport { IconLink } from './IconLink';\nimport { IconComponent, useApp, useRouteRef } from '@backstage/core-plugin-api';\n\ntype TaskPageLinksProps = {\n output: ScaffolderTaskOutput;\n};\n\nexport const TaskPageLinks = ({ output }: TaskPageLinksProps) => {\n const { links = [] } = output;\n const app = useApp();\n const entityRoute = useRouteRef(entityRouteRef);\n\n const iconResolver = (key?: string): IconComponent =>\n key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon;\n\n return (\n <Box px={3} pb={3}>\n {links\n .filter(({ url, entityRef }) => url || entityRef)\n .map(({ url, entityRef, title, icon }) => {\n if (entityRef) {\n const entityName = parseEntityRef(entityRef, {\n defaultKind: '<unknown>',\n defaultNamespace: '<unknown>',\n });\n const target = entityRoute(entityName);\n return { title, icon, url: target };\n }\n return { title, icon, url: url! };\n })\n .map(({ url, title, icon }, i) => (\n <IconLink\n key={`output-link-${i}`}\n href={url}\n text={title ?? url}\n Icon={iconResolver(icon)}\n target=\"_blank\"\n />\n ))}\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AA6BO,MAAM,aAAgB,GAAA,CAAC,EAAE,MAAA,EAAiC,KAAA;AAC/D,EAAA,MAAM,EAAE,KAAA,GAAQ,EAAC,EAAM,GAAA,MAAA,CAAA;AACvB,EAAA,MAAM,MAAM,MAAO,EAAA,CAAA;AACnB,EAAM,MAAA,WAAA,GAAc,YAAY,cAAc,CAAA,CAAA;AAE9C,EAAM,MAAA,YAAA,GAAe,CAAC,GAA6B,KAAA;AAlCrD,IAAA,IAAA,EAAA,CAAA;AAmCI,IAAA,OAAA,GAAA,GAAA,CAAM,EAAI,GAAA,GAAA,CAAA,aAAA,CAAc,GAAG,CAAA,KAArB,YAA0B,YAAe,GAAA,YAAA,CAAA;AAAA,GAAA,CAAA;AAEjD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,OAAI,EAAI,EAAA,CAAA,EAAG,IAAI,CACb,EAAA,EAAA,KAAA,CACE,MAAO,CAAA,CAAC,EAAE,GAAA,EAAK,WAAgB,KAAA,GAAA,IAAO,SAAS,CAAA,CAC/C,GAAI,CAAA,CAAC,EAAE,GAAK,EAAA,SAAA,EAAW,KAAO,EAAA,IAAA,EAAW,KAAA;AACxC,IAAA,IAAI,SAAW,EAAA;AACb,MAAM,MAAA,UAAA,GAAa,eAAe,SAAW,EAAA;AAAA,QAC3C,WAAa,EAAA,WAAA;AAAA,QACb,gBAAkB,EAAA,WAAA;AAAA,OACnB,CAAA,CAAA;AACD,MAAM,MAAA,MAAA,GAAS,YAAY,UAAU,CAAA,CAAA;AACrC,MAAA,OAAO,EAAE,KAAA,EAAO,IAAM,EAAA,GAAA,EAAK,MAAO,EAAA,CAAA;AAAA,KACpC;AACA,IAAO,OAAA,EAAE,KAAO,EAAA,IAAA,EAAM,GAAU,EAAA,CAAA;AAAA,GACjC,EACA,GAAI,CAAA,CAAC,EAAE,GAAK,EAAA,KAAA,EAAO,IAAK,EAAA,EAAG,CAC1B,qBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,eAAe,CAAC,CAAA,CAAA;AAAA,MACrB,IAAM,EAAA,GAAA;AAAA,MACN,MAAM,KAAS,IAAA,IAAA,GAAA,KAAA,GAAA,GAAA;AAAA,MACf,IAAA,EAAM,aAAa,IAAI,CAAA;AAAA,MACvB,MAAO,EAAA,QAAA;AAAA,KAAA;AAAA,GAEV,CACL,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"TaskPageLinks.esm.js","sources":["../../../../src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport Box from '@material-ui/core/Box';\nimport LanguageIcon from '@material-ui/icons/Language';\nimport React from 'react';\nimport { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react';\nimport { IconLink } from './IconLink';\nimport { IconComponent, useApp, useRouteRef } from '@backstage/core-plugin-api';\n\ntype TaskPageLinksProps = {\n output: ScaffolderTaskOutput;\n};\n\nexport const TaskPageLinks = ({ output }: TaskPageLinksProps) => {\n const { links = [] } = output;\n const app = useApp();\n const entityRoute = useRouteRef(entityRouteRef);\n\n const iconResolver = (key?: string): IconComponent =>\n key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon;\n\n return (\n <Box px={3} pb={3}>\n {links\n .filter(({ url, entityRef }) => url || entityRef)\n .map(({ url, entityRef, title, icon }) => {\n if (entityRef) {\n const entityName = parseEntityRef(entityRef, {\n defaultKind: '<unknown>',\n defaultNamespace: '<unknown>',\n });\n const target = entityRoute(entityName);\n return { title, icon, url: target };\n }\n return { title, icon, url: url! };\n })\n .map(({ url, title, icon }, i) => (\n <IconLink\n key={`output-link-${i}`}\n href={url}\n text={title ?? url}\n Icon={iconResolver(icon)}\n target=\"_blank\"\n />\n ))}\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AA6BO,MAAM,aAAgB,GAAA,CAAC,EAAE,MAAA,EAAiC,KAAA;AAC/D,EAAA,MAAM,EAAE,KAAA,GAAQ,EAAC,EAAM,GAAA,MAAA,CAAA;AACvB,EAAA,MAAM,MAAM,MAAO,EAAA,CAAA;AACnB,EAAM,MAAA,WAAA,GAAc,YAAY,cAAc,CAAA,CAAA;AAE9C,EAAM,MAAA,YAAA,GAAe,CAAC,GACpB,KAAA,GAAA,GAAM,IAAI,aAAc,CAAA,GAAG,KAAK,YAAe,GAAA,YAAA,CAAA;AAEjD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,OAAI,EAAI,EAAA,CAAA,EAAG,IAAI,CACb,EAAA,EAAA,KAAA,CACE,MAAO,CAAA,CAAC,EAAE,GAAA,EAAK,WAAgB,KAAA,GAAA,IAAO,SAAS,CAAA,CAC/C,GAAI,CAAA,CAAC,EAAE,GAAK,EAAA,SAAA,EAAW,KAAO,EAAA,IAAA,EAAW,KAAA;AACxC,IAAA,IAAI,SAAW,EAAA;AACb,MAAM,MAAA,UAAA,GAAa,eAAe,SAAW,EAAA;AAAA,QAC3C,WAAa,EAAA,WAAA;AAAA,QACb,gBAAkB,EAAA,WAAA;AAAA,OACnB,CAAA,CAAA;AACD,MAAM,MAAA,MAAA,GAAS,YAAY,UAAU,CAAA,CAAA;AACrC,MAAA,OAAO,EAAE,KAAA,EAAO,IAAM,EAAA,GAAA,EAAK,MAAO,EAAA,CAAA;AAAA,KACpC;AACA,IAAO,OAAA,EAAE,KAAO,EAAA,IAAA,EAAM,GAAU,EAAA,CAAA;AAAA,GACjC,EACA,GAAI,CAAA,CAAC,EAAE,GAAK,EAAA,KAAA,EAAO,IAAK,EAAA,EAAG,CAC1B,qBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,eAAe,CAAC,CAAA,CAAA;AAAA,MACrB,IAAM,EAAA,GAAA;AAAA,MACN,MAAM,KAAS,IAAA,GAAA;AAAA,MACf,IAAA,EAAM,aAAa,IAAI,CAAA;AAAA,MACvB,MAAO,EAAA,QAAA;AAAA,KAAA;AAAA,GAEV,CACL,CAAA,CAAA;AAEJ;;;;"}
@@ -27,7 +27,6 @@ const useStyles = makeStyles((theme) => ({
27
27
  }
28
28
  }));
29
29
  function TemplateEditorBrowser(props) {
30
- var _a, _b;
31
30
  const classes = useStyles();
32
31
  const directoryEditor = useDirectoryEditor();
33
32
  const changedFiles = directoryEditor.files.filter((file) => file.dirty);
@@ -63,7 +62,7 @@ function TemplateEditorBrowser(props) {
63
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(
64
63
  FileBrowser,
65
64
  {
66
- selected: (_b = (_a = directoryEditor.selectedFile) == null ? void 0 : _a.path) != null ? _b : "",
65
+ selected: directoryEditor.selectedFile?.path ?? "",
67
66
  onSelect: directoryEditor.setSelectedFile,
68
67
  filePaths: directoryEditor.files.map((file) => file.path)
69
68
  }
@@ -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';\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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"}
@@ -7,12 +7,6 @@ import { createAsyncValidators, Stepper } from '@backstage/plugin-scaffolder-rea
7
7
  import { useDryRun } from './DryRunContext.esm.js';
8
8
  import { useDirectoryEditor } from './DirectoryEditorContext.esm.js';
9
9
 
10
- var __defProp = Object.defineProperty;
11
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
- var __publicField = (obj, key, value) => {
13
- __defNormalProp(obj, key + "" , value);
14
- return value;
15
- };
16
10
  const useStyles = makeStyles({
17
11
  containerWrapper: {
18
12
  position: "relative",
@@ -29,12 +23,9 @@ const useStyles = makeStyles({
29
23
  }
30
24
  });
31
25
  class ErrorBoundary extends Component {
32
- constructor() {
33
- super(...arguments);
34
- __publicField(this, "state", {
35
- shouldRender: true
36
- });
37
- }
26
+ state = {
27
+ shouldRender: true
28
+ };
38
29
  componentDidUpdate(prevProps) {
39
30
  if (prevProps.invalidator !== this.props.invalidator) {
40
31
  this.setState({ shouldRender: true });
@@ -129,7 +120,7 @@ function TemplateEditorForm(props) {
129
120
  extensions: fieldExtensions,
130
121
  components: fields,
131
122
  onCreate: async (options) => {
132
- await (onDryRun == null ? void 0 : onDryRun(options));
123
+ await onDryRun?.(options);
133
124
  },
134
125
  layouts
135
126
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateEditorForm.esm.js","sources":["../../../src/next/TemplateEditorPage/TemplateEditorForm.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { makeStyles } from '@material-ui/core/styles';\nimport React, { Component, ReactNode, useMemo, useState } from 'react';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport yaml from 'yaml';\nimport {\n LayoutOptions,\n TemplateParameterSchema,\n FieldExtensionOptions,\n} from '@backstage/plugin-scaffolder-react';\nimport {\n Stepper,\n createAsyncValidators,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { useDryRun } from './DryRunContext';\nimport { useDirectoryEditor } from './DirectoryEditorContext';\n\nconst useStyles = makeStyles({\n containerWrapper: {\n position: 'relative',\n width: '100%',\n height: '100%',\n },\n container: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n overflow: 'auto',\n },\n});\n\ninterface ErrorBoundaryProps {\n invalidator: unknown;\n setErrorText(errorText: string | undefined): void;\n children: ReactNode;\n}\n\ninterface ErrorBoundaryState {\n shouldRender: boolean;\n}\n\nclass ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state = {\n shouldRender: true,\n };\n\n componentDidUpdate(prevProps: { invalidator: unknown }) {\n if (prevProps.invalidator !== this.props.invalidator) {\n this.setState({ shouldRender: true });\n }\n }\n\n componentDidCatch(error: Error) {\n this.props.setErrorText(error.message);\n this.setState({ shouldRender: false });\n }\n\n render() {\n return this.state.shouldRender ? this.props.children : null;\n }\n}\n\ninterface TemplateEditorFormProps {\n content?: string;\n /** Setting this to true will cause the content to be parsed as if it is the template entity spec */\n contentIsSpec?: boolean;\n setErrorText: (errorText?: string) => void;\n\n onDryRun?: (data: JsonObject) => Promise<void>;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n layouts?: LayoutOptions[];\n}\n\nfunction isJsonObject(value: JsonValue | undefined): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Shows the a template form that is parsed from the provided content */\nexport function TemplateEditorForm(props: TemplateEditorFormProps) {\n const {\n content,\n contentIsSpec,\n onDryRun,\n setErrorText,\n fieldExtensions = [],\n layouts = [],\n } = props;\n const classes = useStyles();\n const apiHolder = useApiHolder();\n\n const [steps, setSteps] = useState<TemplateParameterSchema['steps']>();\n\n const fields = useMemo(() => {\n return Object.fromEntries(\n fieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [fieldExtensions]);\n\n useDebounce(\n () => {\n try {\n if (!content) {\n setSteps(undefined);\n return;\n }\n const parsed: JsonValue = yaml\n .parseAllDocuments(content)\n .filter(c => c)\n .map(c => c.toJSON())[0];\n\n if (!isJsonObject(parsed)) {\n setSteps(undefined);\n return;\n }\n\n let rootObj = parsed;\n if (!contentIsSpec) {\n const isTemplate =\n String(parsed.kind).toLocaleLowerCase('en-US') === 'template';\n if (!isTemplate) {\n setSteps(undefined);\n return;\n }\n\n rootObj = isJsonObject(parsed.spec) ? parsed.spec : {};\n }\n\n const { parameters } = rootObj;\n\n if (!Array.isArray(parameters)) {\n setErrorText('Template parameters must be an array');\n setSteps(undefined);\n return;\n }\n\n const fieldValidators = Object.fromEntries(\n fieldExtensions.map(({ name, validation }) => [name, validation]),\n );\n\n setErrorText();\n setSteps(\n parameters.flatMap(param =>\n isJsonObject(param)\n ? [\n {\n title: String(param.title),\n schema: param,\n validate: createAsyncValidators(param, fieldValidators, {\n apiHolder,\n }),\n },\n ]\n : [],\n ),\n );\n } catch (e) {\n setErrorText(e.message);\n }\n },\n 250,\n [contentIsSpec, content, apiHolder],\n );\n\n if (!steps) {\n return null;\n }\n\n return (\n <div className={classes.containerWrapper}>\n <div className={classes.container}>\n <ErrorBoundary invalidator={steps} setErrorText={setErrorText}>\n <Stepper\n manifest={{ steps, title: 'Template Editor' }}\n extensions={fieldExtensions}\n components={fields}\n onCreate={async options => {\n await onDryRun?.(options);\n }}\n layouts={layouts}\n />\n </ErrorBoundary>\n </div>\n </div>\n );\n}\n\n/** A version of the TemplateEditorForm that is connected to the DirectoryEditor and DryRun contexts */\nexport function TemplateEditorFormDirectoryEditorDryRun(\n props: Pick<\n TemplateEditorFormProps,\n 'setErrorText' | 'fieldExtensions' | 'layouts'\n >,\n) {\n const { setErrorText, fieldExtensions = [], layouts } = props;\n const dryRun = useDryRun();\n\n const directoryEditor = useDirectoryEditor();\n const { selectedFile } = directoryEditor;\n\n const handleDryRun = async (data: JsonObject) => {\n if (!selectedFile) {\n return;\n }\n\n try {\n await dryRun.execute({\n templateContent: selectedFile.content,\n values: data,\n files: directoryEditor.files,\n });\n setErrorText();\n } catch (e) {\n setErrorText(String(e.cause || e));\n throw e;\n }\n };\n\n const content =\n selectedFile && selectedFile.path.match(/\\.ya?ml$/)\n ? selectedFile.content\n : undefined;\n\n return (\n <TemplateEditorForm\n onDryRun={handleDryRun}\n fieldExtensions={fieldExtensions}\n setErrorText={setErrorText}\n content={content}\n layouts={layouts}\n />\n );\n}\n\nTemplateEditorForm.DirectoryEditorDryRun =\n TemplateEditorFormDirectoryEditorDryRun;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TemplateEditorForm.esm.js","sources":["../../../src/next/TemplateEditorPage/TemplateEditorForm.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { makeStyles } from '@material-ui/core/styles';\nimport React, { Component, ReactNode, useMemo, useState } from 'react';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport yaml from 'yaml';\nimport {\n LayoutOptions,\n TemplateParameterSchema,\n FieldExtensionOptions,\n} from '@backstage/plugin-scaffolder-react';\nimport {\n Stepper,\n createAsyncValidators,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { useDryRun } from './DryRunContext';\nimport { useDirectoryEditor } from './DirectoryEditorContext';\n\nconst useStyles = makeStyles({\n containerWrapper: {\n position: 'relative',\n width: '100%',\n height: '100%',\n },\n container: {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n overflow: 'auto',\n },\n});\n\ninterface ErrorBoundaryProps {\n invalidator: unknown;\n setErrorText(errorText: string | undefined): void;\n children: ReactNode;\n}\n\ninterface ErrorBoundaryState {\n shouldRender: boolean;\n}\n\nclass ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state = {\n shouldRender: true,\n };\n\n componentDidUpdate(prevProps: { invalidator: unknown }) {\n if (prevProps.invalidator !== this.props.invalidator) {\n this.setState({ shouldRender: true });\n }\n }\n\n componentDidCatch(error: Error) {\n this.props.setErrorText(error.message);\n this.setState({ shouldRender: false });\n }\n\n render() {\n return this.state.shouldRender ? this.props.children : null;\n }\n}\n\ninterface TemplateEditorFormProps {\n content?: string;\n /** Setting this to true will cause the content to be parsed as if it is the template entity spec */\n contentIsSpec?: boolean;\n setErrorText: (errorText?: string) => void;\n\n onDryRun?: (data: JsonObject) => Promise<void>;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n layouts?: LayoutOptions[];\n}\n\nfunction isJsonObject(value: JsonValue | undefined): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Shows the a template form that is parsed from the provided content */\nexport function TemplateEditorForm(props: TemplateEditorFormProps) {\n const {\n content,\n contentIsSpec,\n onDryRun,\n setErrorText,\n fieldExtensions = [],\n layouts = [],\n } = props;\n const classes = useStyles();\n const apiHolder = useApiHolder();\n\n const [steps, setSteps] = useState<TemplateParameterSchema['steps']>();\n\n const fields = useMemo(() => {\n return Object.fromEntries(\n fieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [fieldExtensions]);\n\n useDebounce(\n () => {\n try {\n if (!content) {\n setSteps(undefined);\n return;\n }\n const parsed: JsonValue = yaml\n .parseAllDocuments(content)\n .filter(c => c)\n .map(c => c.toJSON())[0];\n\n if (!isJsonObject(parsed)) {\n setSteps(undefined);\n return;\n }\n\n let rootObj = parsed;\n if (!contentIsSpec) {\n const isTemplate =\n String(parsed.kind).toLocaleLowerCase('en-US') === 'template';\n if (!isTemplate) {\n setSteps(undefined);\n return;\n }\n\n rootObj = isJsonObject(parsed.spec) ? parsed.spec : {};\n }\n\n const { parameters } = rootObj;\n\n if (!Array.isArray(parameters)) {\n setErrorText('Template parameters must be an array');\n setSteps(undefined);\n return;\n }\n\n const fieldValidators = Object.fromEntries(\n fieldExtensions.map(({ name, validation }) => [name, validation]),\n );\n\n setErrorText();\n setSteps(\n parameters.flatMap(param =>\n isJsonObject(param)\n ? [\n {\n title: String(param.title),\n schema: param,\n validate: createAsyncValidators(param, fieldValidators, {\n apiHolder,\n }),\n },\n ]\n : [],\n ),\n );\n } catch (e) {\n setErrorText(e.message);\n }\n },\n 250,\n [contentIsSpec, content, apiHolder],\n );\n\n if (!steps) {\n return null;\n }\n\n return (\n <div className={classes.containerWrapper}>\n <div className={classes.container}>\n <ErrorBoundary invalidator={steps} setErrorText={setErrorText}>\n <Stepper\n manifest={{ steps, title: 'Template Editor' }}\n extensions={fieldExtensions}\n components={fields}\n onCreate={async options => {\n await onDryRun?.(options);\n }}\n layouts={layouts}\n />\n </ErrorBoundary>\n </div>\n </div>\n );\n}\n\n/** A version of the TemplateEditorForm that is connected to the DirectoryEditor and DryRun contexts */\nexport function TemplateEditorFormDirectoryEditorDryRun(\n props: Pick<\n TemplateEditorFormProps,\n 'setErrorText' | 'fieldExtensions' | 'layouts'\n >,\n) {\n const { setErrorText, fieldExtensions = [], layouts } = props;\n const dryRun = useDryRun();\n\n const directoryEditor = useDirectoryEditor();\n const { selectedFile } = directoryEditor;\n\n const handleDryRun = async (data: JsonObject) => {\n if (!selectedFile) {\n return;\n }\n\n try {\n await dryRun.execute({\n templateContent: selectedFile.content,\n values: data,\n files: directoryEditor.files,\n });\n setErrorText();\n } catch (e) {\n setErrorText(String(e.cause || e));\n throw e;\n }\n };\n\n const content =\n selectedFile && selectedFile.path.match(/\\.ya?ml$/)\n ? selectedFile.content\n : undefined;\n\n return (\n <TemplateEditorForm\n onDryRun={handleDryRun}\n fieldExtensions={fieldExtensions}\n setErrorText={setErrorText}\n content={content}\n layouts={layouts}\n />\n );\n}\n\nTemplateEditorForm.DirectoryEditorDryRun =\n TemplateEditorFormDirectoryEditorDryRun;\n"],"names":[],"mappings":"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"}
@@ -32,10 +32,7 @@ function TemplateEditorIntro(props) {
32
32
  CardActionArea,
33
33
  {
34
34
  disabled: !supportsLoad,
35
- onClick: () => {
36
- var _a;
37
- return (_a = props.onSelect) == null ? void 0 : _a.call(props, "local");
38
- }
35
+ onClick: () => props.onSelect?.("local")
39
36
  },
40
37
  /* @__PURE__ */ React.createElement(CardContent, null, /* @__PURE__ */ React.createElement(
41
38
  Typography,
@@ -63,14 +60,8 @@ function TemplateEditorIntro(props) {
63
60
  },
64
61
  /* @__PURE__ */ React.createElement(InfoOutlinedIcon, null)
65
62
  )));
66
- const cardFormEditor = /* @__PURE__ */ React.createElement(Card, { className: classes.card, elevation: 4 }, /* @__PURE__ */ React.createElement(CardActionArea, { onClick: () => {
67
- var _a;
68
- return (_a = props.onSelect) == null ? void 0 : _a.call(props, "form");
69
- } }, /* @__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."))));
70
- const cardFieldExplorer = /* @__PURE__ */ React.createElement(Card, { className: classes.card, elevation: 4 }, /* @__PURE__ */ React.createElement(CardActionArea, { onClick: () => {
71
- var _a;
72
- return (_a = props.onSelect) == null ? void 0 : _a.call(props, "field-explorer");
73
- } }, /* @__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."))));
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."))));
74
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(
75
66
  "div",
76
67
  {
@@ -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 Load Template Directory\n </Typography>\n <Typography\n variant=\"body1\"\n color={supportsLoad ? undefined : 'textSecondary'}\n >\n Load a local template directory, allowing you to both edit and try\n executing your own template.\n </Typography>\n </CardContent>\n </CardActionArea>\n {!supportsLoad && (\n <div className={classes.infoIcon}>\n <Tooltip\n placement=\"top\"\n title=\"Only supported in some Chromium-based browsers\"\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 Edit Template Form\n </Typography>\n <Typography variant=\"body1\">\n Preview and edit a template form, either using a sample template or\n by loading a template from the catalog.\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 Custom Field Explorer\n </Typography>\n <Typography variant=\"body1\">\n View and play around with available installed custom field\n extensions.\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 Get started by choosing one of the options below\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":"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"}
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 Load Template Directory\n </Typography>\n <Typography\n variant=\"body1\"\n color={supportsLoad ? undefined : 'textSecondary'}\n >\n Load a local template directory, allowing you to both edit and try\n executing your own template.\n </Typography>\n </CardContent>\n </CardActionArea>\n {!supportsLoad && (\n <div className={classes.infoIcon}>\n <Tooltip\n placement=\"top\"\n title=\"Only supported in some Chromium-based browsers\"\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 Edit Template Form\n </Typography>\n <Typography variant=\"body1\">\n Preview and edit a template form, either using a sample template or\n by loading a template from the catalog.\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 Custom Field Explorer\n </Typography>\n <Typography variant=\"body1\">\n View and play around with available installed custom field\n extensions.\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 Get started by choosing one of the options below\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":"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"}