@backstage/plugin-scaffolder 1.19.3 → 1.19.4-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 (152) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/alpha/package.json +1 -1
  3. package/dist/alpha.esm.js +3 -8
  4. package/dist/alpha.esm.js.map +1 -1
  5. package/dist/{esm/routes-BvToNy4N.esm.js → api.esm.js} +2 -46
  6. package/dist/api.esm.js.map +1 -0
  7. package/dist/components/ActionsPage/ActionsPage.esm.js +186 -0
  8. package/dist/components/ActionsPage/ActionsPage.esm.js.map +1 -0
  9. package/dist/components/FileBrowser/FileBrowser.esm.js +90 -0
  10. package/dist/components/FileBrowser/FileBrowser.esm.js.map +1 -0
  11. package/dist/components/ListTasksPage/ListTasksPage.esm.js +120 -0
  12. package/dist/components/ListTasksPage/ListTasksPage.esm.js.map +1 -0
  13. package/dist/components/ListTasksPage/OwnerListPicker.esm.js +88 -0
  14. package/dist/components/ListTasksPage/OwnerListPicker.esm.js.map +1 -0
  15. package/dist/components/ListTasksPage/columns/CreatedAtColumn.esm.js +13 -0
  16. package/dist/components/ListTasksPage/columns/CreatedAtColumn.esm.js.map +1 -0
  17. package/dist/components/ListTasksPage/columns/OwnerEntityColumn.esm.js +31 -0
  18. package/dist/components/ListTasksPage/columns/OwnerEntityColumn.esm.js.map +1 -0
  19. package/dist/components/ListTasksPage/columns/TaskStatusColumn.esm.js +17 -0
  20. package/dist/components/ListTasksPage/columns/TaskStatusColumn.esm.js.map +1 -0
  21. package/dist/components/ListTasksPage/columns/TemplateTitleColumn.esm.js +21 -0
  22. package/dist/components/ListTasksPage/columns/TemplateTitleColumn.esm.js.map +1 -0
  23. package/dist/components/OngoingTask/ContextMenu.esm.js +84 -0
  24. package/dist/components/OngoingTask/ContextMenu.esm.js.map +1 -0
  25. package/dist/components/OngoingTask/OngoingTask.esm.js +169 -0
  26. package/dist/components/OngoingTask/OngoingTask.esm.js.map +1 -0
  27. package/dist/components/Router/Router.esm.js +105 -0
  28. package/dist/components/Router/Router.esm.js.map +1 -0
  29. package/dist/components/Router/index.esm.js +2 -0
  30. package/dist/components/Router/index.esm.js.map +1 -0
  31. package/dist/components/TemplateTypePicker/TemplateTypePicker.esm.js +70 -0
  32. package/dist/components/TemplateTypePicker/TemplateTypePicker.esm.js.map +1 -0
  33. package/dist/components/fields/EntityNamePicker/EntityNamePicker.esm.js +34 -0
  34. package/dist/components/fields/EntityNamePicker/EntityNamePicker.esm.js.map +1 -0
  35. package/dist/components/fields/EntityNamePicker/schema.esm.js +8 -0
  36. package/dist/components/fields/EntityNamePicker/schema.esm.js.map +1 -0
  37. package/dist/components/fields/EntityNamePicker/validation.esm.js +12 -0
  38. package/dist/components/fields/EntityNamePicker/validation.esm.js.map +1 -0
  39. package/dist/components/fields/EntityPicker/EntityPicker.esm.js +151 -0
  40. package/dist/components/fields/EntityPicker/EntityPicker.esm.js.map +1 -0
  41. package/dist/components/fields/EntityPicker/schema.esm.js +29 -0
  42. package/dist/components/fields/EntityPicker/schema.esm.js.map +1 -0
  43. package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js +84 -0
  44. package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js.map +1 -0
  45. package/dist/components/fields/EntityTagsPicker/schema.esm.js +15 -0
  46. package/dist/components/fields/EntityTagsPicker/schema.esm.js.map +1 -0
  47. package/dist/components/fields/MultiEntityPicker/MultiEntityPicker.esm.js +168 -0
  48. package/dist/components/fields/MultiEntityPicker/MultiEntityPicker.esm.js.map +1 -0
  49. package/dist/components/fields/MultiEntityPicker/schema.esm.js +23 -0
  50. package/dist/components/fields/MultiEntityPicker/schema.esm.js.map +1 -0
  51. package/dist/components/fields/MyGroupsPicker/MyGroupsPicker.esm.js +83 -0
  52. package/dist/components/fields/MyGroupsPicker/MyGroupsPicker.esm.js.map +1 -0
  53. package/dist/components/fields/MyGroupsPicker/schema.esm.js +14 -0
  54. package/dist/components/fields/MyGroupsPicker/schema.esm.js.map +1 -0
  55. package/dist/components/fields/OwnedEntityPicker/OwnedEntityPicker.esm.js +68 -0
  56. package/dist/components/fields/OwnedEntityPicker/OwnedEntityPicker.esm.js.map +1 -0
  57. package/dist/components/fields/OwnedEntityPicker/schema.esm.js +24 -0
  58. package/dist/components/fields/OwnedEntityPicker/schema.esm.js.map +1 -0
  59. package/dist/components/fields/OwnerPicker/OwnerPicker.esm.js +37 -0
  60. package/dist/components/fields/OwnerPicker/OwnerPicker.esm.js.map +1 -0
  61. package/dist/components/fields/OwnerPicker/schema.esm.js +24 -0
  62. package/dist/components/fields/OwnerPicker/schema.esm.js.map +1 -0
  63. package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js +75 -0
  64. package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js.map +1 -0
  65. package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js +80 -0
  66. package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js.map +1 -0
  67. package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js +38 -0
  68. package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js.map +1 -0
  69. package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js +44 -0
  70. package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js.map +1 -0
  71. package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js +42 -0
  72. package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js.map +1 -0
  73. package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js +44 -0
  74. package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js.map +1 -0
  75. package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js +200 -0
  76. package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js.map +1 -0
  77. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerHost.esm.js +56 -0
  78. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerHost.esm.js.map +1 -0
  79. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js +48 -0
  80. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js.map +1 -0
  81. package/dist/components/fields/RepoUrlPicker/schema.esm.js +32 -0
  82. package/dist/components/fields/RepoUrlPicker/schema.esm.js.map +1 -0
  83. package/dist/components/fields/RepoUrlPicker/utils.esm.js +46 -0
  84. package/dist/components/fields/RepoUrlPicker/utils.esm.js.map +1 -0
  85. package/dist/components/fields/RepoUrlPicker/validation.esm.js +43 -0
  86. package/dist/components/fields/RepoUrlPicker/validation.esm.js.map +1 -0
  87. package/dist/components/fields/SecretInput/SecretInput.esm.js +48 -0
  88. package/dist/components/fields/SecretInput/SecretInput.esm.js.map +1 -0
  89. package/dist/components/fields/utils.esm.js +15 -0
  90. package/dist/components/fields/utils.esm.js.map +1 -0
  91. package/dist/deprecated.esm.js +13 -0
  92. package/dist/deprecated.esm.js.map +1 -0
  93. package/dist/extensions/default.esm.js +72 -0
  94. package/dist/extensions/default.esm.js.map +1 -0
  95. package/dist/index.esm.js +13 -214
  96. package/dist/index.esm.js.map +1 -1
  97. package/dist/lib/download/helpers.esm.js +11 -0
  98. package/dist/lib/download/helpers.esm.js.map +1 -0
  99. package/dist/lib/filesystem/WebFileSystemAccess.esm.js +56 -0
  100. package/dist/lib/filesystem/WebFileSystemAccess.esm.js.map +1 -0
  101. package/dist/next/TemplateEditorPage/CustomFieldExplorer.esm.js +151 -0
  102. package/dist/next/TemplateEditorPage/CustomFieldExplorer.esm.js.map +1 -0
  103. package/dist/next/TemplateEditorPage/DirectoryEditorContext.esm.js +186 -0
  104. package/dist/next/TemplateEditorPage/DirectoryEditorContext.esm.js.map +1 -0
  105. package/dist/next/TemplateEditorPage/DryRunContext.esm.js +110 -0
  106. package/dist/next/TemplateEditorPage/DryRunContext.esm.js.map +1 -0
  107. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResults.esm.js +70 -0
  108. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResults.esm.js.map +1 -0
  109. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js +98 -0
  110. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js.map +1 -0
  111. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.esm.js +31 -0
  112. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.esm.js.map +1 -0
  113. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js +145 -0
  114. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js.map +1 -0
  115. package/dist/next/TemplateEditorPage/DryRunResults/IconLink.esm.js +25 -0
  116. package/dist/next/TemplateEditorPage/DryRunResults/IconLink.esm.js.map +1 -0
  117. package/dist/next/TemplateEditorPage/DryRunResults/TaskPageLinks.esm.js +40 -0
  118. package/dist/next/TemplateEditorPage/DryRunResults/TaskPageLinks.esm.js.map +1 -0
  119. package/dist/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.esm.js +135 -0
  120. package/dist/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.esm.js.map +1 -0
  121. package/dist/next/TemplateEditorPage/TemplateEditor.esm.js +52 -0
  122. package/dist/next/TemplateEditorPage/TemplateEditor.esm.js.map +1 -0
  123. package/dist/next/TemplateEditorPage/TemplateEditorBrowser.esm.js +74 -0
  124. package/dist/next/TemplateEditorPage/TemplateEditorBrowser.esm.js.map +1 -0
  125. package/dist/next/TemplateEditorPage/TemplateEditorForm.esm.js +174 -0
  126. package/dist/next/TemplateEditorPage/TemplateEditorForm.esm.js.map +1 -0
  127. package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js +93 -0
  128. package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js.map +1 -0
  129. package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js +82 -0
  130. package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js.map +1 -0
  131. package/dist/next/TemplateEditorPage/TemplateEditorTextArea.esm.js +120 -0
  132. package/dist/next/TemplateEditorPage/TemplateEditorTextArea.esm.js.map +1 -0
  133. package/dist/next/TemplateEditorPage/TemplateFormPreviewer.esm.js +160 -0
  134. package/dist/next/TemplateEditorPage/TemplateFormPreviewer.esm.js.map +1 -0
  135. package/dist/next/TemplateListPage/RegisterExistingButton.esm.js +35 -0
  136. package/dist/next/TemplateListPage/RegisterExistingButton.esm.js.map +1 -0
  137. package/dist/next/TemplateListPage/TemplateListPage.esm.js +101 -0
  138. package/dist/next/TemplateListPage/TemplateListPage.esm.js.map +1 -0
  139. package/dist/next/TemplateWizardPage/TemplateWizardPage.esm.js +67 -0
  140. package/dist/next/TemplateWizardPage/TemplateWizardPage.esm.js.map +1 -0
  141. package/dist/next/TemplateWizardPage/TemplateWizardPageContextMenu.esm.js +60 -0
  142. package/dist/next/TemplateWizardPage/TemplateWizardPageContextMenu.esm.js.map +1 -0
  143. package/dist/plugin.esm.js +125 -0
  144. package/dist/plugin.esm.js.map +1 -0
  145. package/dist/routes.esm.js +47 -0
  146. package/dist/routes.esm.js.map +1 -0
  147. package/package.json +18 -18
  148. package/dist/esm/OngoingTask-ClfJCJcE.esm.js +0 -1575
  149. package/dist/esm/OngoingTask-ClfJCJcE.esm.js.map +0 -1
  150. package/dist/esm/index-UcPid-q1.esm.js +0 -2553
  151. package/dist/esm/index-UcPid-q1.esm.js.map +0 -1
  152. package/dist/esm/routes-BvToNy4N.esm.js.map +0 -1
@@ -1,1575 +0,0 @@
1
- import { parseEntityRef, stringifyEntityRef, KubernetesValidatorFunctions, RELATION_OWNED_BY, makeValidator } from '@backstage/catalog-model';
2
- import React, { useCallback, useEffect, useState, useMemo } from 'react';
3
- import TextField from '@material-ui/core/TextField';
4
- import { z } from 'zod';
5
- import { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';
6
- import { useApi, identityApiRef, errorApiRef, useRouteRef } from '@backstage/core-plugin-api';
7
- import { catalogApiRef, humanizeEntityRef } from '@backstage/plugin-catalog-react';
8
- import FormControl from '@material-ui/core/FormControl';
9
- import Autocomplete from '@material-ui/lab/Autocomplete';
10
- import useAsync from 'react-use/esm/useAsync';
11
- import { scmIntegrationsApiRef, scmAuthApiRef } from '@backstage/integration-react';
12
- import FormHelperText from '@material-ui/core/FormHelperText';
13
- import Input from '@material-ui/core/Input';
14
- import InputLabel from '@material-ui/core/InputLabel';
15
- import { Select, Progress, Page, Header, Content, ErrorPanel } from '@backstage/core-components';
16
- import { scaffolderApiRef, useTemplateSecrets, useTaskEventStream } from '@backstage/plugin-scaffolder-react';
17
- import useDebounce from 'react-use/esm/useDebounce';
18
- import Box from '@material-ui/core/Box';
19
- import Divider from '@material-ui/core/Divider';
20
- import Typography from '@material-ui/core/Typography';
21
- import useEffectOnce from 'react-use/esm/useEffectOnce';
22
- import zodToJsonSchema from 'zod-to-json-schema';
23
- import { NotFoundError } from '@backstage/errors';
24
- import { useParams, useNavigate } from 'react-router-dom';
25
- import Button from '@material-ui/core/Button';
26
- import Paper from '@material-ui/core/Paper';
27
- import { makeStyles, useTheme } from '@material-ui/core/styles';
28
- import { s as selectedTemplateRouteRef } from './routes-BvToNy4N.esm.js';
29
- import qs from 'qs';
30
- import IconButton from '@material-ui/core/IconButton';
31
- import ListItemIcon from '@material-ui/core/ListItemIcon';
32
- import ListItemText from '@material-ui/core/ListItemText';
33
- import MenuItem from '@material-ui/core/MenuItem';
34
- import MenuList from '@material-ui/core/MenuList';
35
- import Popover from '@material-ui/core/Popover';
36
- import { useAsync as useAsync$1 } from '@react-hookz/web';
37
- import Cancel from '@material-ui/icons/Cancel';
38
- import Retry from '@material-ui/icons/Repeat';
39
- import Toc from '@material-ui/icons/Toc';
40
- import ControlPointIcon from '@material-ui/icons/ControlPoint';
41
- import MoreVert from '@material-ui/icons/MoreVert';
42
- import { DefaultTemplateOutputs, TaskSteps, TaskLogStream } from '@backstage/plugin-scaffolder-react/alpha';
43
-
44
- function makeFieldSchemaFromZod(returnSchema, uiOptionsSchema) {
45
- return {
46
- schema: {
47
- returnValue: zodToJsonSchema(returnSchema),
48
- uiOptions: uiOptionsSchema ? zodToJsonSchema(uiOptionsSchema) : void 0
49
- },
50
- type: null,
51
- uiOptionsType: null
52
- };
53
- }
54
-
55
- const entityQueryFilterExpressionSchema$1 = z.record(
56
- z.string().or(z.object({ exists: z.boolean().optional() })).or(z.array(z.string()))
57
- );
58
- const EntityPickerFieldSchema = makeFieldSchemaFromZod(
59
- z.string(),
60
- z.object({
61
- /**
62
- * @deprecated Use `catalogFilter` instead.
63
- */
64
- allowedKinds: z.array(z.string()).optional().describe(
65
- "DEPRECATED: Use `catalogFilter` instead. List of kinds of entities to derive options from"
66
- ),
67
- defaultKind: z.string().optional().describe(
68
- "The default entity kind. Options of this kind will not be prefixed."
69
- ),
70
- allowArbitraryValues: z.boolean().optional().describe("Whether to allow arbitrary user input. Defaults to true"),
71
- defaultNamespace: z.union([z.string(), z.literal(false)]).optional().describe(
72
- "The default namespace. Options with this namespace will not be prefixed."
73
- ),
74
- catalogFilter: z.array(entityQueryFilterExpressionSchema$1).or(entityQueryFilterExpressionSchema$1).optional().describe("List of key-value filter expression for entities")
75
- })
76
- );
77
- const EntityPickerSchema = EntityPickerFieldSchema.schema;
78
-
79
- const EntityPicker = (props) => {
80
- var _a, _b, _c, _d, _e;
81
- const {
82
- onChange,
83
- schema: { title = "Entity", description = "An entity from the catalog" },
84
- required,
85
- uiSchema,
86
- rawErrors,
87
- formData,
88
- idSchema
89
- } = props;
90
- const catalogFilter = buildCatalogFilter$1(uiSchema);
91
- const defaultKind = (_a = uiSchema["ui:options"]) == null ? void 0 : _a.defaultKind;
92
- const defaultNamespace = ((_b = uiSchema["ui:options"]) == null ? void 0 : _b.defaultNamespace) || void 0;
93
- const catalogApi = useApi(catalogApiRef);
94
- const { value: entities, loading } = useAsync(async () => {
95
- const fields = ["metadata.name", "metadata.namespace", "kind"];
96
- const { items } = await catalogApi.getEntities(
97
- catalogFilter ? { filter: catalogFilter, fields } : { filter: void 0, fields }
98
- );
99
- return items;
100
- });
101
- const allowArbitraryValues = (_d = (_c = uiSchema["ui:options"]) == null ? void 0 : _c.allowArbitraryValues) != null ? _d : true;
102
- const getLabel = useCallback(
103
- (ref) => {
104
- try {
105
- return humanizeEntityRef(
106
- parseEntityRef(ref, { defaultKind, defaultNamespace }),
107
- {
108
- defaultKind,
109
- defaultNamespace
110
- }
111
- );
112
- } catch (err) {
113
- return ref;
114
- }
115
- },
116
- [defaultKind, defaultNamespace]
117
- );
118
- const onSelect = useCallback(
119
- (_, ref, reason) => {
120
- if (typeof ref !== "string") {
121
- onChange(ref ? stringifyEntityRef(ref) : void 0);
122
- } else {
123
- if (reason === "blur" || reason === "create-option") {
124
- let entityRef = ref;
125
- try {
126
- entityRef = stringifyEntityRef(
127
- parseEntityRef(ref, {
128
- defaultKind,
129
- defaultNamespace
130
- })
131
- );
132
- } catch (err) {
133
- }
134
- if (formData !== ref || allowArbitraryValues) {
135
- onChange(entityRef);
136
- }
137
- }
138
- }
139
- },
140
- [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues]
141
- );
142
- const selectedEntity = (_e = entities == null ? void 0 : entities.find((e) => stringifyEntityRef(e) === formData)) != null ? _e : allowArbitraryValues && formData ? getLabel(formData) : "";
143
- useEffect(() => {
144
- if ((entities == null ? void 0 : entities.length) === 1 && selectedEntity === "") {
145
- onChange(stringifyEntityRef(entities[0]));
146
- }
147
- }, [entities, onChange, selectedEntity]);
148
- return /* @__PURE__ */ React.createElement(
149
- FormControl,
150
- {
151
- margin: "normal",
152
- required,
153
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !formData
154
- },
155
- /* @__PURE__ */ React.createElement(
156
- Autocomplete,
157
- {
158
- disabled: (entities == null ? void 0 : entities.length) === 1,
159
- id: idSchema == null ? void 0 : idSchema.$id,
160
- value: selectedEntity,
161
- loading,
162
- onChange: onSelect,
163
- options: entities || [],
164
- getOptionLabel: (option) => (
165
- // option can be a string due to freeSolo.
166
- typeof option === "string" ? option : humanizeEntityRef(option, { defaultKind, defaultNamespace })
167
- ),
168
- autoSelect: true,
169
- freeSolo: allowArbitraryValues,
170
- renderInput: (params) => /* @__PURE__ */ React.createElement(
171
- TextField,
172
- {
173
- ...params,
174
- label: title,
175
- margin: "dense",
176
- helperText: description,
177
- FormHelperTextProps: { margin: "dense", style: { marginLeft: 0 } },
178
- variant: "outlined",
179
- required,
180
- InputProps: params.InputProps
181
- }
182
- )
183
- }
184
- )
185
- );
186
- };
187
- function convertOpsValues$1(value) {
188
- if (typeof value === "object" && value.exists) {
189
- return CATALOG_FILTER_EXISTS;
190
- }
191
- return value == null ? void 0 : value.toString();
192
- }
193
- function convertSchemaFiltersToQuery$1(schemaFilters) {
194
- const query = {};
195
- for (const [key, value] of Object.entries(schemaFilters)) {
196
- if (Array.isArray(value)) {
197
- query[key] = value;
198
- } else {
199
- query[key] = convertOpsValues$1(value);
200
- }
201
- }
202
- return query;
203
- }
204
- function buildCatalogFilter$1(uiSchema) {
205
- var _a, _b;
206
- const allowedKinds = (_a = uiSchema["ui:options"]) == null ? void 0 : _a.allowedKinds;
207
- const catalogFilter = ((_b = uiSchema["ui:options"]) == null ? void 0 : _b.catalogFilter) || allowedKinds && { kind: allowedKinds };
208
- if (!catalogFilter) {
209
- return void 0;
210
- }
211
- if (Array.isArray(catalogFilter)) {
212
- return catalogFilter.map(convertSchemaFiltersToQuery$1);
213
- }
214
- return convertSchemaFiltersToQuery$1(catalogFilter);
215
- }
216
-
217
- const entityNamePickerValidation = (value, validation) => {
218
- if (!KubernetesValidatorFunctions.isValidObjectName(value)) {
219
- validation.addError(
220
- "Must start and end with an alphanumeric character, and contain only alphanumeric characters, hyphens, underscores, and periods. Maximum length is 63 characters."
221
- );
222
- }
223
- };
224
-
225
- const EntityNamePickerFieldSchema = makeFieldSchemaFromZod(z.string());
226
- const EntityNamePickerSchema = EntityNamePickerFieldSchema.schema;
227
-
228
- const EntityNamePicker = (props) => {
229
- const {
230
- onChange,
231
- required,
232
- schema: { title = "Name", description = "Unique name of the component" },
233
- rawErrors,
234
- formData,
235
- uiSchema: { "ui:autofocus": autoFocus },
236
- idSchema,
237
- placeholder
238
- } = props;
239
- return /* @__PURE__ */ React.createElement(
240
- TextField,
241
- {
242
- id: idSchema == null ? void 0 : idSchema.$id,
243
- label: title,
244
- placeholder,
245
- helperText: description,
246
- required,
247
- value: formData != null ? formData : "",
248
- onChange: ({ target: { value } }) => onChange(value),
249
- margin: "normal",
250
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !formData,
251
- inputProps: { autoFocus }
252
- }
253
- );
254
- };
255
-
256
- const OwnerPickerFieldSchema = makeFieldSchemaFromZod(
257
- z.string(),
258
- z.object({
259
- /**
260
- * @deprecated Use `catalogFilter` instead.
261
- */
262
- allowedKinds: z.array(z.string()).default(["Group", "User"]).optional().describe(
263
- "DEPRECATED: Use `catalogFilter` instead. List of kinds of entities to derive options from. Defaults to Group and User"
264
- ),
265
- allowArbitraryValues: z.boolean().optional().describe("Whether to allow arbitrary user input. Defaults to true"),
266
- defaultNamespace: z.union([z.string(), z.literal(false)]).optional().describe(
267
- "The default namespace. Options with this namespace will not be prefixed."
268
- ),
269
- catalogFilter: z.array(entityQueryFilterExpressionSchema$1).or(entityQueryFilterExpressionSchema$1).optional().describe("List of key-value filter expression for entities")
270
- })
271
- );
272
- const OwnerPickerSchema = OwnerPickerFieldSchema.schema;
273
-
274
- const OwnerPicker = (props) => {
275
- var _a, _b, _c, _d, _e;
276
- const {
277
- schema: { title = "Owner", description = "The owner of the component" },
278
- uiSchema,
279
- ...restProps
280
- } = props;
281
- const defaultNamespace = (_a = uiSchema["ui:options"]) == null ? void 0 : _a.defaultNamespace;
282
- const allowedKinds = (_b = uiSchema["ui:options"]) == null ? void 0 : _b.allowedKinds;
283
- const catalogFilter = ((_c = uiSchema["ui:options"]) == null ? void 0 : _c.catalogFilter) || {
284
- kind: allowedKinds || ["Group", "User"]
285
- };
286
- const ownerUiSchema = {
287
- ...uiSchema,
288
- "ui:options": {
289
- catalogFilter,
290
- defaultKind: "Group",
291
- allowArbitraryValues: (_e = (_d = uiSchema["ui:options"]) == null ? void 0 : _d.allowArbitraryValues) != null ? _e : true,
292
- ...defaultNamespace !== void 0 ? { defaultNamespace } : {}
293
- }
294
- };
295
- return /* @__PURE__ */ React.createElement(
296
- EntityPicker,
297
- {
298
- ...restProps,
299
- schema: { title, description },
300
- uiSchema: ownerUiSchema
301
- }
302
- );
303
- };
304
-
305
- const entityQueryFilterExpressionSchema = z.record(
306
- z.string().or(z.object({ exists: z.boolean().optional() })).or(z.array(z.string()))
307
- );
308
- const MultiEntityPickerFieldSchema = makeFieldSchemaFromZod(
309
- z.array(z.string()),
310
- z.object({
311
- defaultKind: z.string().optional().describe(
312
- "The default entity kind. Options of this kind will not be prefixed."
313
- ),
314
- allowArbitraryValues: z.boolean().optional().describe("Whether to allow arbitrary user input. Defaults to true"),
315
- defaultNamespace: z.union([z.string(), z.literal(false)]).optional().describe(
316
- "The default namespace. Options with this namespace will not be prefixed."
317
- ),
318
- catalogFilter: z.array(entityQueryFilterExpressionSchema).or(entityQueryFilterExpressionSchema).optional().describe("List of key-value filter expression for entities")
319
- })
320
- );
321
- const MultiEntityPickerSchema = MultiEntityPickerFieldSchema.schema;
322
-
323
- const MultiEntityPicker = (props) => {
324
- var _a, _b, _c, _d, _e;
325
- const {
326
- onChange,
327
- schema: { title = "Entity", description = "An entity from the catalog" },
328
- required,
329
- uiSchema,
330
- rawErrors,
331
- formData,
332
- idSchema
333
- } = props;
334
- const catalogFilter = buildCatalogFilter(uiSchema);
335
- const defaultKind = (_a = uiSchema["ui:options"]) == null ? void 0 : _a.defaultKind;
336
- const defaultNamespace = ((_b = uiSchema["ui:options"]) == null ? void 0 : _b.defaultNamespace) || void 0;
337
- const catalogApi = useApi(catalogApiRef);
338
- const { value: entities, loading } = useAsync(async () => {
339
- const { items } = await catalogApi.getEntities(
340
- catalogFilter ? { filter: catalogFilter } : void 0
341
- );
342
- return items;
343
- });
344
- const allowArbitraryValues = (_d = (_c = uiSchema["ui:options"]) == null ? void 0 : _c.allowArbitraryValues) != null ? _d : true;
345
- const getLabel = useCallback(
346
- (ref) => {
347
- try {
348
- return humanizeEntityRef(
349
- parseEntityRef(ref, { defaultKind, defaultNamespace }),
350
- {
351
- defaultKind,
352
- defaultNamespace
353
- }
354
- );
355
- } catch (err) {
356
- return ref;
357
- }
358
- },
359
- [defaultKind, defaultNamespace]
360
- );
361
- const onSelect = useCallback(
362
- (_, refs, reason) => {
363
- const values = refs.map((ref) => {
364
- if (typeof ref !== "string") {
365
- return ref ? stringifyEntityRef(ref) : void 0;
366
- }
367
- if (reason === "blur" || reason === "create-option") {
368
- let entityRef = ref;
369
- try {
370
- entityRef = stringifyEntityRef(
371
- parseEntityRef(ref, {
372
- defaultKind,
373
- defaultNamespace
374
- })
375
- );
376
- } catch (err) {
377
- }
378
- if (formData.includes(ref) || allowArbitraryValues) {
379
- return entityRef;
380
- }
381
- }
382
- return void 0;
383
- }).filter((ref) => ref !== void 0);
384
- onChange(values);
385
- },
386
- [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues]
387
- );
388
- useEffect(() => {
389
- if ((entities == null ? void 0 : entities.length) === 1) {
390
- onChange([stringifyEntityRef(entities[0])]);
391
- }
392
- }, [entities, onChange]);
393
- return /* @__PURE__ */ React.createElement(
394
- FormControl,
395
- {
396
- margin: "normal",
397
- required,
398
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !formData
399
- },
400
- /* @__PURE__ */ React.createElement(
401
- Autocomplete,
402
- {
403
- multiple: true,
404
- filterSelectedOptions: true,
405
- disabled: (entities == null ? void 0 : entities.length) === 1,
406
- id: idSchema == null ? void 0 : idSchema.$id,
407
- value: (
408
- // Since free solo can be enabled, attempt to parse as a full entity ref first, then fall
409
- // back to the given value.
410
- (_e = entities == null ? void 0 : entities.filter(
411
- (e) => formData && formData.includes(stringifyEntityRef(e))
412
- )) != null ? _e : allowArbitraryValues && formData ? formData.map(getLabel) : []
413
- ),
414
- loading,
415
- onChange: onSelect,
416
- options: entities || [],
417
- getOptionLabel: (option) => (
418
- // option can be a string due to freeSolo.
419
- typeof option === "string" ? option : humanizeEntityRef(option, { defaultKind, defaultNamespace })
420
- ),
421
- autoSelect: true,
422
- freeSolo: allowArbitraryValues,
423
- renderInput: (params) => /* @__PURE__ */ React.createElement(
424
- TextField,
425
- {
426
- ...params,
427
- label: title,
428
- margin: "dense",
429
- helperText: description,
430
- FormHelperTextProps: { margin: "dense", style: { marginLeft: 0 } },
431
- variant: "outlined",
432
- required,
433
- InputProps: params.InputProps
434
- }
435
- )
436
- }
437
- )
438
- );
439
- };
440
- const validateMultiEntityPickerValidation = (values, validation) => {
441
- values.forEach((value) => {
442
- try {
443
- parseEntityRef(value);
444
- } catch {
445
- validation.addError(`${value} is not a valid entity ref`);
446
- }
447
- });
448
- };
449
- function convertOpsValues(value) {
450
- if (typeof value === "object" && value.exists) {
451
- return CATALOG_FILTER_EXISTS;
452
- }
453
- return value == null ? void 0 : value.toString();
454
- }
455
- function convertSchemaFiltersToQuery(schemaFilters) {
456
- const query = {};
457
- for (const [key, value] of Object.entries(schemaFilters)) {
458
- if (Array.isArray(value)) {
459
- query[key] = value;
460
- } else {
461
- query[key] = convertOpsValues(value);
462
- }
463
- }
464
- return query;
465
- }
466
- function buildCatalogFilter(uiSchema) {
467
- var _a;
468
- const catalogFilter = (_a = uiSchema["ui:options"]) == null ? void 0 : _a.catalogFilter;
469
- if (!catalogFilter) {
470
- return void 0;
471
- }
472
- if (Array.isArray(catalogFilter)) {
473
- return catalogFilter.map(convertSchemaFiltersToQuery);
474
- }
475
- return convertSchemaFiltersToQuery(catalogFilter);
476
- }
477
-
478
- const RepoUrlPickerFieldSchema = makeFieldSchemaFromZod(
479
- z.string(),
480
- z.object({
481
- allowedHosts: z.array(z.string()).optional().describe("List of allowed SCM platform hosts"),
482
- allowedOrganizations: z.array(z.string()).optional().describe("List of allowed organizations in the given SCM platform"),
483
- allowedOwners: z.array(z.string()).optional().describe("List of allowed owners in the given SCM platform"),
484
- allowedProjects: z.array(z.string()).optional().describe("List of allowed projects in the given SCM platform"),
485
- allowedRepos: z.array(z.string()).optional().describe("List of allowed repos in the given SCM platform"),
486
- requestUserCredentials: z.object({
487
- secretsKey: z.string().describe(
488
- "Key used within the template secrets context to store the credential"
489
- ),
490
- additionalScopes: z.object({
491
- gitea: z.array(z.string()).optional().describe("Additional Gitea scopes to request"),
492
- gerrit: z.array(z.string()).optional().describe("Additional Gerrit scopes to request"),
493
- github: z.array(z.string()).optional().describe("Additional GitHub scopes to request"),
494
- gitlab: z.array(z.string()).optional().describe("Additional GitLab scopes to request"),
495
- bitbucket: z.array(z.string()).optional().describe("Additional BitBucket scopes to request"),
496
- azure: z.array(z.string()).optional().describe("Additional Azure scopes to request")
497
- }).optional().describe("Additional permission scopes to request")
498
- }).optional().describe(
499
- "If defined will request user credentials to auth against the given SCM platform"
500
- )
501
- })
502
- );
503
- const RepoUrlPickerSchema = RepoUrlPickerFieldSchema.schema;
504
-
505
- const repoPickerValidation = (value, validation, context) => {
506
- var _a, _b;
507
- try {
508
- const { host, searchParams } = new URL(`https://${value}`);
509
- const integrationApi = context.apiHolder.get(scmIntegrationsApiRef);
510
- if (!host) {
511
- validation.addError(
512
- "Incomplete repository location provided, host not provided"
513
- );
514
- } else {
515
- if (((_a = integrationApi == null ? void 0 : integrationApi.byHost(host)) == null ? void 0 : _a.type) === "bitbucket") {
516
- if (host === "bitbucket.org" && !searchParams.get("workspace")) {
517
- validation.addError(
518
- "Incomplete repository location provided, workspace not provided"
519
- );
520
- }
521
- if (!searchParams.get("project")) {
522
- validation.addError(
523
- "Incomplete repository location provided, project not provided"
524
- );
525
- }
526
- } else if (((_b = integrationApi == null ? void 0 : integrationApi.byHost(host)) == null ? void 0 : _b.type) !== "gerrit") {
527
- if (!searchParams.get("owner")) {
528
- validation.addError(
529
- "Incomplete repository location provided, owner not provided"
530
- );
531
- }
532
- }
533
- if (!searchParams.get("repo")) {
534
- validation.addError(
535
- "Incomplete repository location provided, repo not provided"
536
- );
537
- }
538
- }
539
- } catch {
540
- validation.addError("Unable to parse the Repository URL");
541
- }
542
- };
543
-
544
- const GithubRepoPicker = (props) => {
545
- const { allowedOwners = [], rawErrors, state, onChange } = props;
546
- const ownerItems = allowedOwners ? allowedOwners.map((i) => ({ label: i, value: i })) : [{ label: "Loading...", value: "loading" }];
547
- const { owner } = state;
548
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
549
- FormControl,
550
- {
551
- margin: "normal",
552
- required: true,
553
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !owner
554
- },
555
- (allowedOwners == null ? void 0 : allowedOwners.length) ? /* @__PURE__ */ React.createElement(
556
- Select,
557
- {
558
- native: true,
559
- label: "Owner Available",
560
- onChange: (s) => onChange({ owner: String(Array.isArray(s) ? s[0] : s) }),
561
- disabled: allowedOwners.length === 1,
562
- selected: owner,
563
- items: ownerItems
564
- }
565
- ) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(InputLabel, { htmlFor: "ownerInput" }, "Owner"), /* @__PURE__ */ React.createElement(
566
- Input,
567
- {
568
- id: "ownerInput",
569
- onChange: (e) => onChange({ owner: e.target.value }),
570
- value: owner
571
- }
572
- )),
573
- /* @__PURE__ */ React.createElement(FormHelperText, null, "The organization, user or project that this repo will belong to")
574
- ));
575
- };
576
-
577
- const GiteaRepoPicker = (props) => {
578
- const { allowedOwners = [], state, onChange, rawErrors } = props;
579
- const ownerItems = allowedOwners ? allowedOwners.map((i) => ({ label: i, value: i })) : [{ label: "Loading...", value: "loading" }];
580
- const { owner } = state;
581
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
582
- FormControl,
583
- {
584
- margin: "normal",
585
- required: true,
586
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !owner
587
- },
588
- (allowedOwners == null ? void 0 : allowedOwners.length) ? /* @__PURE__ */ React.createElement(
589
- Select,
590
- {
591
- native: true,
592
- label: "Owner Available",
593
- onChange: (selected) => onChange({
594
- owner: String(Array.isArray(selected) ? selected[0] : selected)
595
- }),
596
- disabled: allowedOwners.length === 1,
597
- selected: owner,
598
- items: ownerItems
599
- }
600
- ) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(InputLabel, { htmlFor: "ownerInput" }, "Owner"), /* @__PURE__ */ React.createElement(
601
- Input,
602
- {
603
- id: "ownerInput",
604
- onChange: (e) => onChange({ owner: e.target.value }),
605
- value: owner
606
- }
607
- )),
608
- /* @__PURE__ */ React.createElement(FormHelperText, null, "Gitea namespace where this repository will belong to. It can be the name of organization, group, subgroup, user, or the project.")
609
- ));
610
- };
611
-
612
- const GitlabRepoPicker = (props) => {
613
- const { allowedOwners = [], state, onChange, rawErrors } = props;
614
- const ownerItems = allowedOwners ? allowedOwners.map((i) => ({ label: i, value: i })) : [{ label: "Loading...", value: "loading" }];
615
- const { owner } = state;
616
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
617
- FormControl,
618
- {
619
- margin: "normal",
620
- required: true,
621
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !owner
622
- },
623
- (allowedOwners == null ? void 0 : allowedOwners.length) ? /* @__PURE__ */ React.createElement(
624
- Select,
625
- {
626
- native: true,
627
- label: "Owner Available",
628
- onChange: (selected) => onChange({
629
- owner: String(Array.isArray(selected) ? selected[0] : selected)
630
- }),
631
- disabled: allowedOwners.length === 1,
632
- selected: owner,
633
- items: ownerItems
634
- }
635
- ) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(InputLabel, { htmlFor: "ownerInput" }, "Owner"), /* @__PURE__ */ React.createElement(
636
- Input,
637
- {
638
- id: "ownerInput",
639
- onChange: (e) => onChange({ owner: e.target.value }),
640
- value: owner
641
- }
642
- )),
643
- /* @__PURE__ */ React.createElement(FormHelperText, null, "GitLab namespace where this repository will belong to. It can be the name of organization, group, subgroup, user, or the project.")
644
- ));
645
- };
646
-
647
- const AzureRepoPicker = (props) => {
648
- const {
649
- allowedOrganizations = [],
650
- allowedOwners = [],
651
- rawErrors,
652
- state,
653
- onChange
654
- } = props;
655
- const organizationItems = allowedOrganizations ? allowedOrganizations.map((i) => ({ label: i, value: i })) : [{ label: "Loading...", value: "loading" }];
656
- const ownerItems = allowedOwners ? allowedOwners.map((i) => ({ label: i, value: i })) : [{ label: "Loading...", value: "loading" }];
657
- const { organization, owner } = state;
658
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
659
- FormControl,
660
- {
661
- margin: "normal",
662
- required: true,
663
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !organization
664
- },
665
- (allowedOrganizations == null ? void 0 : allowedOrganizations.length) ? /* @__PURE__ */ React.createElement(
666
- Select,
667
- {
668
- native: true,
669
- label: "Organization",
670
- onChange: (s) => onChange({ organization: String(Array.isArray(s) ? s[0] : s) }),
671
- disabled: allowedOrganizations.length === 1,
672
- selected: organization,
673
- items: organizationItems
674
- }
675
- ) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(InputLabel, { htmlFor: "orgInput" }, "Organization"), /* @__PURE__ */ React.createElement(
676
- Input,
677
- {
678
- id: "orgInput",
679
- onChange: (e) => onChange({ organization: e.target.value }),
680
- value: organization
681
- }
682
- )),
683
- /* @__PURE__ */ React.createElement(FormHelperText, null, "The Organization that this repo will belong to")
684
- ), /* @__PURE__ */ React.createElement(
685
- FormControl,
686
- {
687
- margin: "normal",
688
- required: true,
689
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !owner
690
- },
691
- (allowedOwners == null ? void 0 : allowedOwners.length) ? /* @__PURE__ */ React.createElement(
692
- Select,
693
- {
694
- native: true,
695
- label: "Owner",
696
- onChange: (s) => onChange({ owner: String(Array.isArray(s) ? s[0] : s) }),
697
- disabled: allowedOwners.length === 1,
698
- selected: owner,
699
- items: ownerItems
700
- }
701
- ) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(InputLabel, { htmlFor: "ownerInput" }, "Project"), /* @__PURE__ */ React.createElement(
702
- Input,
703
- {
704
- id: "ownerInput",
705
- onChange: (e) => onChange({ owner: e.target.value }),
706
- value: owner
707
- }
708
- )),
709
- /* @__PURE__ */ React.createElement(FormHelperText, null, "The Project that this repo will belong to")
710
- ));
711
- };
712
-
713
- const BitbucketRepoPicker = (props) => {
714
- const {
715
- allowedOwners = [],
716
- allowedProjects = [],
717
- onChange,
718
- rawErrors,
719
- state
720
- } = props;
721
- const { host, workspace, project } = state;
722
- const ownerItems = allowedOwners ? allowedOwners == null ? void 0 : allowedOwners.map((i) => ({ label: i, value: i })) : [];
723
- const projectItems = allowedProjects ? allowedProjects == null ? void 0 : allowedProjects.map((i) => ({ label: i, value: i })) : [];
724
- useEffect(() => {
725
- if (host === "bitbucket.org" && allowedOwners.length) {
726
- onChange({ workspace: allowedOwners[0] });
727
- }
728
- }, [allowedOwners, host, onChange]);
729
- return /* @__PURE__ */ React.createElement(React.Fragment, null, host === "bitbucket.org" && /* @__PURE__ */ React.createElement(
730
- FormControl,
731
- {
732
- margin: "normal",
733
- required: true,
734
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !workspace
735
- },
736
- (allowedOwners == null ? void 0 : allowedOwners.length) ? /* @__PURE__ */ React.createElement(
737
- Select,
738
- {
739
- native: true,
740
- label: "Allowed Workspaces",
741
- onChange: (s) => onChange({ workspace: String(Array.isArray(s) ? s[0] : s) }),
742
- disabled: allowedOwners.length === 1,
743
- selected: workspace,
744
- items: ownerItems
745
- }
746
- ) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(InputLabel, { htmlFor: "workspaceInput" }, "Workspace"), /* @__PURE__ */ React.createElement(
747
- Input,
748
- {
749
- id: "workspaceInput",
750
- onChange: (e) => onChange({ workspace: e.target.value }),
751
- value: workspace
752
- }
753
- )),
754
- /* @__PURE__ */ React.createElement(FormHelperText, null, "The Workspace that this repo will belong to")
755
- ), /* @__PURE__ */ React.createElement(
756
- FormControl,
757
- {
758
- margin: "normal",
759
- required: true,
760
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !project
761
- },
762
- (allowedProjects == null ? void 0 : allowedProjects.length) ? /* @__PURE__ */ React.createElement(
763
- Select,
764
- {
765
- native: true,
766
- label: "Allowed Projects",
767
- onChange: (s) => onChange({ project: String(Array.isArray(s) ? s[0] : s) }),
768
- disabled: allowedProjects.length === 1,
769
- selected: project,
770
- items: projectItems
771
- }
772
- ) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(InputLabel, { htmlFor: "projectInput" }, "Project"), /* @__PURE__ */ React.createElement(
773
- Input,
774
- {
775
- id: "projectInput",
776
- onChange: (e) => onChange({ project: e.target.value }),
777
- value: project
778
- }
779
- )),
780
- /* @__PURE__ */ React.createElement(FormHelperText, null, "The Project that this repo will belong to")
781
- ));
782
- };
783
-
784
- const GerritRepoPicker = (props) => {
785
- const { onChange, rawErrors, state } = props;
786
- const { workspace, owner } = state;
787
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(FormControl, { margin: "normal", error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !workspace }, /* @__PURE__ */ React.createElement(InputLabel, { htmlFor: "ownerInput" }, "Owner"), /* @__PURE__ */ React.createElement(
788
- Input,
789
- {
790
- id: "ownerInput",
791
- onChange: (e) => onChange({ owner: e.target.value }),
792
- value: owner
793
- }
794
- ), /* @__PURE__ */ React.createElement(FormHelperText, null, "The owner of the project (optional)")), /* @__PURE__ */ React.createElement(
795
- FormControl,
796
- {
797
- margin: "normal",
798
- required: true,
799
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !workspace
800
- },
801
- /* @__PURE__ */ React.createElement(InputLabel, { htmlFor: "parentInput" }, "Parent"),
802
- /* @__PURE__ */ React.createElement(
803
- Input,
804
- {
805
- id: "parentInput",
806
- onChange: (e) => onChange({ workspace: e.target.value }),
807
- value: workspace
808
- }
809
- ),
810
- /* @__PURE__ */ React.createElement(FormHelperText, null, "The project parent that the repo will belong to")
811
- ));
812
- };
813
-
814
- const RepoUrlPickerHost = (props) => {
815
- const { host, hosts, onChange, rawErrors } = props;
816
- const scaffolderApi = useApi(scaffolderApiRef);
817
- const { value: { integrations } = { integrations: [] }, loading } = useAsync(
818
- async () => {
819
- return await scaffolderApi.getIntegrationsList({
820
- allowedHosts: hosts != null ? hosts : []
821
- });
822
- }
823
- );
824
- useEffect(() => {
825
- if (!host) {
826
- if (hosts == null ? void 0 : hosts.length) {
827
- onChange(hosts[0]);
828
- } else if (integrations == null ? void 0 : integrations.length) {
829
- onChange(integrations[0].host);
830
- }
831
- }
832
- }, [hosts, host, onChange, integrations]);
833
- const hostsOptions = integrations ? integrations.filter((i) => (hosts == null ? void 0 : hosts.length) ? hosts == null ? void 0 : hosts.includes(i.host) : true).map((i) => ({ label: i.title, value: i.host })) : [{ label: "Loading...", value: "loading" }];
834
- if (loading) {
835
- return /* @__PURE__ */ React.createElement(Progress, null);
836
- }
837
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
838
- FormControl,
839
- {
840
- margin: "normal",
841
- required: true,
842
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !host
843
- },
844
- /* @__PURE__ */ React.createElement(
845
- Select,
846
- {
847
- native: true,
848
- disabled: (hosts == null ? void 0 : hosts.length) === 1,
849
- label: "Host",
850
- onChange: (s) => onChange(String(Array.isArray(s) ? s[0] : s)),
851
- selected: host,
852
- items: hostsOptions,
853
- "data-testid": "host-select"
854
- }
855
- ),
856
- /* @__PURE__ */ React.createElement(FormHelperText, null, "The host where the repository will be created")
857
- ));
858
- };
859
-
860
- const RepoUrlPickerRepoName = (props) => {
861
- const { repoName, allowedRepos, onChange, rawErrors } = props;
862
- useEffect(() => {
863
- if (!repoName) {
864
- if (allowedRepos == null ? void 0 : allowedRepos.length) {
865
- onChange(allowedRepos[0]);
866
- }
867
- }
868
- }, [allowedRepos, repoName, onChange]);
869
- const repoItems = allowedRepos ? allowedRepos.map((i) => ({ label: i, value: i })) : [{ label: "Loading...", value: "loading" }];
870
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
871
- FormControl,
872
- {
873
- margin: "normal",
874
- required: true,
875
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !repoName
876
- },
877
- (allowedRepos == null ? void 0 : allowedRepos.length) ? /* @__PURE__ */ React.createElement(
878
- Select,
879
- {
880
- native: true,
881
- label: "Repositories Available",
882
- onChange: (selected) => onChange(String(Array.isArray(selected) ? selected[0] : selected)),
883
- disabled: allowedRepos.length === 1,
884
- selected: repoName,
885
- items: repoItems
886
- }
887
- ) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(InputLabel, { htmlFor: "repoNameInput" }, "Repository"), /* @__PURE__ */ React.createElement(
888
- Input,
889
- {
890
- id: "repoNameInput",
891
- onChange: (e) => onChange(String(e.target.value)),
892
- value: repoName
893
- }
894
- )),
895
- /* @__PURE__ */ React.createElement(FormHelperText, null, "The name of the repository")
896
- ));
897
- };
898
-
899
- function serializeRepoPickerUrl(data) {
900
- if (!data.host) {
901
- return void 0;
902
- }
903
- const params = new URLSearchParams();
904
- if (data.owner) {
905
- params.set("owner", data.owner);
906
- }
907
- if (data.repoName) {
908
- params.set("repo", data.repoName);
909
- }
910
- if (data.organization) {
911
- params.set("organization", data.organization);
912
- }
913
- if (data.workspace) {
914
- params.set("workspace", data.workspace);
915
- }
916
- if (data.project) {
917
- params.set("project", data.project);
918
- }
919
- return `${data.host}?${params.toString()}`;
920
- }
921
- function parseRepoPickerUrl(url) {
922
- let host = "";
923
- let owner = "";
924
- let repoName = "";
925
- let organization = "";
926
- let workspace = "";
927
- let project = "";
928
- try {
929
- if (url) {
930
- const parsed = new URL(`https://${url}`);
931
- host = parsed.host;
932
- owner = parsed.searchParams.get("owner") || "";
933
- repoName = parsed.searchParams.get("repo") || "";
934
- organization = parsed.searchParams.get("organization") || "";
935
- workspace = parsed.searchParams.get("workspace") || "";
936
- project = parsed.searchParams.get("project") || "";
937
- }
938
- } catch {
939
- }
940
- return { host, owner, repoName, organization, workspace, project };
941
- }
942
-
943
- const RepoUrlPicker = (props) => {
944
- var _a, _b;
945
- const { uiSchema, onChange, rawErrors, formData, schema } = props;
946
- const [state, setState] = useState(
947
- parseRepoPickerUrl(formData)
948
- );
949
- const integrationApi = useApi(scmIntegrationsApiRef);
950
- const scmAuthApi = useApi(scmAuthApiRef);
951
- const { secrets, setSecrets } = useTemplateSecrets();
952
- const allowedHosts = useMemo(
953
- () => {
954
- var _a2, _b2;
955
- return (_b2 = (_a2 = uiSchema == null ? void 0 : uiSchema["ui:options"]) == null ? void 0 : _a2.allowedHosts) != null ? _b2 : [];
956
- },
957
- [uiSchema]
958
- );
959
- const allowedOrganizations = useMemo(
960
- () => {
961
- var _a2, _b2;
962
- return (_b2 = (_a2 = uiSchema == null ? void 0 : uiSchema["ui:options"]) == null ? void 0 : _a2.allowedOrganizations) != null ? _b2 : [];
963
- },
964
- [uiSchema]
965
- );
966
- const allowedOwners = useMemo(
967
- () => {
968
- var _a2, _b2;
969
- return (_b2 = (_a2 = uiSchema == null ? void 0 : uiSchema["ui:options"]) == null ? void 0 : _a2.allowedOwners) != null ? _b2 : [];
970
- },
971
- [uiSchema]
972
- );
973
- const allowedProjects = useMemo(
974
- () => {
975
- var _a2, _b2;
976
- return (_b2 = (_a2 = uiSchema == null ? void 0 : uiSchema["ui:options"]) == null ? void 0 : _a2.allowedProjects) != null ? _b2 : [];
977
- },
978
- [uiSchema]
979
- );
980
- const allowedRepos = useMemo(
981
- () => {
982
- var _a2, _b2;
983
- return (_b2 = (_a2 = uiSchema == null ? void 0 : uiSchema["ui:options"]) == null ? void 0 : _a2.allowedRepos) != null ? _b2 : [];
984
- },
985
- [uiSchema]
986
- );
987
- const { owner, organization, project, repoName } = state;
988
- useEffect(() => {
989
- onChange(serializeRepoPickerUrl(state));
990
- }, [state, onChange]);
991
- useEffect(() => {
992
- if (allowedOrganizations.length > 0 && !organization) {
993
- setState((prevState) => ({
994
- ...prevState,
995
- organization: allowedOrganizations[0]
996
- }));
997
- }
998
- }, [setState, allowedOrganizations, organization]);
999
- useEffect(() => {
1000
- if (allowedOwners.length > 0 && !owner) {
1001
- setState((prevState) => ({
1002
- ...prevState,
1003
- owner: allowedOwners[0]
1004
- }));
1005
- }
1006
- }, [setState, allowedOwners, owner]);
1007
- useEffect(() => {
1008
- if (allowedProjects.length > 0 && !project) {
1009
- setState((prevState) => ({
1010
- ...prevState,
1011
- project: allowedProjects[0]
1012
- }));
1013
- }
1014
- }, [setState, allowedProjects, project]);
1015
- useEffect(() => {
1016
- if (allowedRepos.length > 0 && !repoName) {
1017
- setState((prevState) => ({ ...prevState, repoName: allowedRepos[0] }));
1018
- }
1019
- }, [setState, allowedRepos, repoName]);
1020
- const updateLocalState = useCallback(
1021
- (newState) => {
1022
- setState((prevState) => ({ ...prevState, ...newState }));
1023
- },
1024
- [setState]
1025
- );
1026
- useDebounce(
1027
- async () => {
1028
- var _a2;
1029
- const { requestUserCredentials } = (_a2 = uiSchema == null ? void 0 : uiSchema["ui:options"]) != null ? _a2 : {};
1030
- const workspace = state.owner ? state.owner : state.project;
1031
- if (!requestUserCredentials || !(state.host && workspace && state.repoName)) {
1032
- return;
1033
- }
1034
- if (secrets[requestUserCredentials.secretsKey]) {
1035
- return;
1036
- }
1037
- const [encodedHost, encodedRepoName] = [state.host, state.repoName].map(
1038
- encodeURIComponent
1039
- );
1040
- const { token } = await scmAuthApi.getCredentials({
1041
- url: `https://${encodedHost}/${workspace}/${encodedRepoName}`,
1042
- additionalScope: {
1043
- repoWrite: true,
1044
- customScopes: requestUserCredentials.additionalScopes
1045
- }
1046
- });
1047
- setSecrets({ [requestUserCredentials.secretsKey]: token });
1048
- },
1049
- 500,
1050
- [state, uiSchema]
1051
- );
1052
- const hostType = (_b = state.host && ((_a = integrationApi.byHost(state.host)) == null ? void 0 : _a.type)) != null ? _b : null;
1053
- return /* @__PURE__ */ React.createElement(React.Fragment, null, schema.title && /* @__PURE__ */ React.createElement(Box, { my: 1 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5" }, schema.title), /* @__PURE__ */ React.createElement(Divider, null)), schema.description && /* @__PURE__ */ React.createElement(Typography, { variant: "body1" }, schema.description), /* @__PURE__ */ React.createElement(
1054
- RepoUrlPickerHost,
1055
- {
1056
- host: state.host,
1057
- hosts: allowedHosts,
1058
- onChange: (host) => setState((prevState) => ({ ...prevState, host })),
1059
- rawErrors
1060
- }
1061
- ), hostType === "github" && /* @__PURE__ */ React.createElement(
1062
- GithubRepoPicker,
1063
- {
1064
- allowedOwners,
1065
- onChange: updateLocalState,
1066
- rawErrors,
1067
- state
1068
- }
1069
- ), hostType === "gitea" && /* @__PURE__ */ React.createElement(
1070
- GiteaRepoPicker,
1071
- {
1072
- allowedOwners,
1073
- allowedRepos,
1074
- rawErrors,
1075
- state,
1076
- onChange: updateLocalState
1077
- }
1078
- ), hostType === "gitlab" && /* @__PURE__ */ React.createElement(
1079
- GitlabRepoPicker,
1080
- {
1081
- allowedOwners,
1082
- rawErrors,
1083
- state,
1084
- onChange: updateLocalState
1085
- }
1086
- ), hostType === "bitbucket" && /* @__PURE__ */ React.createElement(
1087
- BitbucketRepoPicker,
1088
- {
1089
- allowedOwners,
1090
- allowedProjects,
1091
- rawErrors,
1092
- state,
1093
- onChange: updateLocalState
1094
- }
1095
- ), hostType === "azure" && /* @__PURE__ */ React.createElement(
1096
- AzureRepoPicker,
1097
- {
1098
- allowedOrganizations,
1099
- allowedOwners,
1100
- rawErrors,
1101
- state,
1102
- onChange: updateLocalState
1103
- }
1104
- ), hostType === "gerrit" && /* @__PURE__ */ React.createElement(
1105
- GerritRepoPicker,
1106
- {
1107
- rawErrors,
1108
- state,
1109
- onChange: updateLocalState
1110
- }
1111
- ), /* @__PURE__ */ React.createElement(
1112
- RepoUrlPickerRepoName,
1113
- {
1114
- repoName: state.repoName,
1115
- allowedRepos,
1116
- onChange: (repo) => setState((prevState) => ({ ...prevState, repoName: repo })),
1117
- rawErrors
1118
- }
1119
- ));
1120
- };
1121
-
1122
- const OwnedEntityPickerFieldSchema = makeFieldSchemaFromZod(
1123
- z.string(),
1124
- z.object({
1125
- allowedKinds: z.array(z.string()).optional().describe(
1126
- "DEPRECATED: Use `catalogFilter` instead. List of kinds of entities to derive options from"
1127
- ),
1128
- defaultKind: z.string().optional().describe(
1129
- "The default entity kind. Options of this kind will not be prefixed."
1130
- ),
1131
- allowArbitraryValues: z.boolean().optional().describe("Whether to allow arbitrary user input. Defaults to true"),
1132
- defaultNamespace: z.union([z.string(), z.literal(false)]).optional().describe(
1133
- "The default namespace. Options with this namespace will not be prefixed."
1134
- ),
1135
- catalogFilter: z.array(entityQueryFilterExpressionSchema$1).or(entityQueryFilterExpressionSchema$1).optional().describe("List of key-value filter expression for entities")
1136
- })
1137
- );
1138
- const OwnedEntityPickerSchema = OwnedEntityPickerFieldSchema.schema;
1139
-
1140
- const OwnedEntityPicker = (props) => {
1141
- const {
1142
- schema: { title = "Entity", description = "An entity from the catalog" },
1143
- uiSchema,
1144
- required
1145
- } = props;
1146
- const identityApi = useApi(identityApiRef);
1147
- const { loading, value: identityRefs } = useAsync(async () => {
1148
- const identity = await identityApi.getBackstageIdentity();
1149
- return identity.ownershipEntityRefs;
1150
- });
1151
- if (loading)
1152
- return /* @__PURE__ */ React.createElement(
1153
- Autocomplete,
1154
- {
1155
- loading,
1156
- renderInput: (params) => /* @__PURE__ */ React.createElement(
1157
- TextField,
1158
- {
1159
- ...params,
1160
- label: title,
1161
- margin: "dense",
1162
- helperText: description,
1163
- FormHelperTextProps: { margin: "dense", style: { marginLeft: 0 } },
1164
- variant: "outlined",
1165
- required,
1166
- InputProps: params.InputProps
1167
- }
1168
- ),
1169
- options: []
1170
- }
1171
- );
1172
- const entityPickerUISchema = buildEntityPickerUISchema(
1173
- uiSchema,
1174
- identityRefs
1175
- );
1176
- return /* @__PURE__ */ React.createElement(EntityPicker, { ...props, uiSchema: entityPickerUISchema });
1177
- };
1178
- function buildEntityPickerUISchema(uiSchema, identityRefs) {
1179
- const uiOptions = (uiSchema == null ? void 0 : uiSchema["ui:options"]) || {};
1180
- const allowedKinds = uiOptions.allowedKinds;
1181
- const catalogFilter = {
1182
- ...uiOptions.catalogFilter,
1183
- ...allowedKinds ? {
1184
- kind: allowedKinds,
1185
- [`relations.${RELATION_OWNED_BY}`]: identityRefs || []
1186
- } : {
1187
- [`relations.${RELATION_OWNED_BY}`]: identityRefs || []
1188
- }
1189
- };
1190
- return {
1191
- "ui:options": {
1192
- catalogFilter
1193
- }
1194
- };
1195
- }
1196
-
1197
- const EntityTagsPickerFieldSchema = makeFieldSchemaFromZod(
1198
- z.array(z.string()),
1199
- z.object({
1200
- kinds: z.array(z.string()).optional().describe("List of kinds of entities to derive tags from"),
1201
- showCounts: z.boolean().optional().describe("Whether to show usage counts per tag"),
1202
- helperText: z.string().optional().describe("Helper text to display")
1203
- })
1204
- );
1205
- const EntityTagsPickerSchema = EntityTagsPickerFieldSchema.schema;
1206
-
1207
- const EntityTagsPicker = (props) => {
1208
- var _a, _b, _c;
1209
- const { formData, onChange, uiSchema } = props;
1210
- const catalogApi = useApi(catalogApiRef);
1211
- const [tagOptions, setTagOptions] = useState([]);
1212
- const [inputValue, setInputValue] = useState("");
1213
- const [inputError, setInputError] = useState(false);
1214
- const tagValidator = makeValidator().isValidTag;
1215
- const kinds = (_a = uiSchema["ui:options"]) == null ? void 0 : _a.kinds;
1216
- const showCounts = (_b = uiSchema["ui:options"]) == null ? void 0 : _b.showCounts;
1217
- const helperText = (_c = uiSchema["ui:options"]) == null ? void 0 : _c.helperText;
1218
- const { loading, value: existingTags } = useAsync(async () => {
1219
- const facet = "metadata.tags";
1220
- const tagsRequest = { facets: [facet] };
1221
- if (kinds) {
1222
- tagsRequest.filter = { kind: kinds };
1223
- }
1224
- const { facets } = await catalogApi.getEntityFacets(tagsRequest);
1225
- const tagFacets = Object.fromEntries(
1226
- facets[facet].map(({ value, count }) => [value, count])
1227
- );
1228
- setTagOptions(
1229
- Object.keys(tagFacets).sort(
1230
- (a, b) => showCounts ? tagFacets[b] - tagFacets[a] : a.localeCompare(b)
1231
- )
1232
- );
1233
- return tagFacets;
1234
- });
1235
- const setTags = (_, values) => {
1236
- let hasError = false;
1237
- let addDuplicate = false;
1238
- const currentTags = formData || [];
1239
- if ((values == null ? void 0 : values.length) && currentTags.length < values.length) {
1240
- const newTag = values[values.length - 1] = values[values.length - 1].toLocaleLowerCase("en-US").trim();
1241
- hasError = !tagValidator(newTag);
1242
- addDuplicate = currentTags.indexOf(newTag) !== -1;
1243
- }
1244
- setInputError(hasError);
1245
- setInputValue(!hasError ? "" : inputValue);
1246
- if (!hasError && !addDuplicate) {
1247
- onChange(values || []);
1248
- }
1249
- };
1250
- useEffectOnce(() => onChange(formData || []));
1251
- return /* @__PURE__ */ React.createElement(FormControl, { margin: "normal" }, /* @__PURE__ */ React.createElement(
1252
- Autocomplete,
1253
- {
1254
- multiple: true,
1255
- freeSolo: true,
1256
- filterSelectedOptions: true,
1257
- onChange: setTags,
1258
- value: formData || [],
1259
- inputValue,
1260
- loading,
1261
- options: tagOptions,
1262
- ChipProps: { size: "small" },
1263
- renderOption: (option) => showCounts ? `${option} (${existingTags == null ? void 0 : existingTags[option]})` : option,
1264
- renderInput: (params) => /* @__PURE__ */ React.createElement(
1265
- TextField,
1266
- {
1267
- ...params,
1268
- label: "Tags",
1269
- onChange: (e) => setInputValue(e.target.value),
1270
- error: inputError,
1271
- helperText: helperText != null ? helperText : "Add any relevant tags, hit 'Enter' to add new tags. Valid format: [a-z0-9+#] separated by [-], at most 63 characters"
1272
- }
1273
- )
1274
- }
1275
- ));
1276
- };
1277
-
1278
- const MyGroupsPickerFieldSchema = makeFieldSchemaFromZod(
1279
- z.string(),
1280
- z.object({
1281
- title: z.string().default("Group").describe("Group"),
1282
- description: z.string().default("A group you are part of").describe("The group to which the entity belongs")
1283
- })
1284
- );
1285
- const MyGroupsPickerSchema = MyGroupsPickerFieldSchema.schema;
1286
-
1287
- const MyGroupsPicker = (props) => {
1288
- const {
1289
- schema: { title, description },
1290
- required,
1291
- rawErrors,
1292
- onChange,
1293
- formData
1294
- } = props;
1295
- const identityApi = useApi(identityApiRef);
1296
- const catalogApi = useApi(catalogApiRef);
1297
- const errorApi = useApi(errorApiRef);
1298
- const [groups, setGroups] = useState([]);
1299
- useAsync(async () => {
1300
- const { userEntityRef } = await identityApi.getBackstageIdentity();
1301
- if (!userEntityRef) {
1302
- errorApi.post(new NotFoundError("No user entity ref found"));
1303
- return;
1304
- }
1305
- const { items } = await catalogApi.getEntities({
1306
- filter: {
1307
- kind: "Group",
1308
- ["relations.hasMember"]: [userEntityRef]
1309
- }
1310
- });
1311
- const groupValues = items.filter((e) => Boolean(e)).map((item) => {
1312
- var _a;
1313
- return {
1314
- label: (_a = item.metadata.title) != null ? _a : item.metadata.name,
1315
- ref: stringifyEntityRef(item)
1316
- };
1317
- });
1318
- setGroups(groupValues);
1319
- });
1320
- const updateChange = (_, value) => {
1321
- var _a;
1322
- onChange((_a = value == null ? void 0 : value.ref) != null ? _a : "");
1323
- };
1324
- const selectedEntity = (groups == null ? void 0 : groups.find((e) => e.ref === formData)) || null;
1325
- return /* @__PURE__ */ React.createElement(
1326
- FormControl,
1327
- {
1328
- margin: "normal",
1329
- required,
1330
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0
1331
- },
1332
- /* @__PURE__ */ React.createElement(
1333
- Autocomplete,
1334
- {
1335
- id: "OwnershipEntityRefPicker-dropdown",
1336
- options: groups || [],
1337
- value: selectedEntity,
1338
- onChange: updateChange,
1339
- getOptionLabel: (group) => group.label,
1340
- renderInput: (params) => /* @__PURE__ */ React.createElement(
1341
- TextField,
1342
- {
1343
- ...params,
1344
- label: title,
1345
- margin: "dense",
1346
- helperText: description,
1347
- FormHelperTextProps: { margin: "dense", style: { marginLeft: 0 } },
1348
- variant: "outlined",
1349
- required
1350
- }
1351
- )
1352
- }
1353
- )
1354
- );
1355
- };
1356
-
1357
- const useStyles$1 = makeStyles(() => ({
1358
- button: {
1359
- color: ({ fontColor }) => fontColor
1360
- }
1361
- }));
1362
- const ContextMenu = (props) => {
1363
- const {
1364
- cancelEnabled,
1365
- logsVisible,
1366
- buttonBarVisible,
1367
- onStartOver,
1368
- onToggleLogs,
1369
- onToggleButtonBar,
1370
- taskId
1371
- } = props;
1372
- const { getPageTheme } = useTheme();
1373
- const pageTheme = getPageTheme({ themeId: "website" });
1374
- const classes = useStyles$1({ fontColor: pageTheme.fontColor });
1375
- const scaffolderApi = useApi(scaffolderApiRef);
1376
- const [anchorEl, setAnchorEl] = useState();
1377
- const [{ status: cancelStatus }, { execute: cancel }] = useAsync$1(async () => {
1378
- if (taskId) {
1379
- await scaffolderApi.cancelTask(taskId);
1380
- }
1381
- });
1382
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
1383
- IconButton,
1384
- {
1385
- "aria-label": "more",
1386
- "aria-controls": "long-menu",
1387
- "aria-haspopup": "true",
1388
- onClick: (event) => {
1389
- setAnchorEl(event.currentTarget);
1390
- },
1391
- "data-testid": "menu-button",
1392
- className: classes.button
1393
- },
1394
- /* @__PURE__ */ React.createElement(MoreVert, null)
1395
- ), /* @__PURE__ */ React.createElement(
1396
- Popover,
1397
- {
1398
- open: Boolean(anchorEl),
1399
- onClose: () => setAnchorEl(void 0),
1400
- anchorEl,
1401
- anchorOrigin: { vertical: "bottom", horizontal: "right" },
1402
- transformOrigin: { vertical: "top", horizontal: "right" }
1403
- },
1404
- /* @__PURE__ */ React.createElement(MenuList, null, /* @__PURE__ */ React.createElement(MenuItem, { onClick: () => onToggleLogs == null ? void 0 : onToggleLogs(!logsVisible) }, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(Toc, { fontSize: "small" })), /* @__PURE__ */ React.createElement(ListItemText, { primary: logsVisible ? "Hide Logs" : "Show Logs" })), /* @__PURE__ */ React.createElement(MenuItem, { onClick: () => onToggleButtonBar == null ? void 0 : onToggleButtonBar(!buttonBarVisible) }, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(ControlPointIcon, { fontSize: "small" })), /* @__PURE__ */ React.createElement(
1405
- ListItemText,
1406
- {
1407
- primary: buttonBarVisible ? "Hide Button Bar" : "Show Button Bar"
1408
- }
1409
- )), /* @__PURE__ */ React.createElement(MenuItem, { onClick: onStartOver }, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(Retry, { fontSize: "small" })), /* @__PURE__ */ React.createElement(ListItemText, { primary: "Start Over" })), /* @__PURE__ */ React.createElement(
1410
- MenuItem,
1411
- {
1412
- onClick: cancel,
1413
- disabled: !cancelEnabled || cancelStatus !== "not-executed",
1414
- "data-testid": "cancel-task"
1415
- },
1416
- /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(Cancel, { fontSize: "small" })),
1417
- /* @__PURE__ */ React.createElement(ListItemText, { primary: "Cancel" })
1418
- ))
1419
- ));
1420
- };
1421
-
1422
- const useStyles = makeStyles((theme) => ({
1423
- contentWrapper: {
1424
- display: "flex",
1425
- flexDirection: "column"
1426
- },
1427
- buttonBar: {
1428
- display: "flex",
1429
- flexDirection: "row",
1430
- justifyContent: "right"
1431
- },
1432
- cancelButton: {
1433
- marginRight: theme.spacing(1)
1434
- },
1435
- logsVisibilityButton: {
1436
- marginRight: theme.spacing(1)
1437
- }
1438
- }));
1439
- const OngoingTask = (props) => {
1440
- var _a, _b, _c, _d, _e, _f, _g, _h;
1441
- const { taskId } = useParams();
1442
- const templateRouteRef = useRouteRef(selectedTemplateRouteRef);
1443
- const navigate = useNavigate();
1444
- const scaffolderApi = useApi(scaffolderApiRef);
1445
- const taskStream = useTaskEventStream(taskId);
1446
- const classes = useStyles();
1447
- const steps = useMemo(
1448
- () => {
1449
- var _a2, _b2;
1450
- return (_b2 = (_a2 = taskStream.task) == null ? void 0 : _a2.spec.steps.map((step) => {
1451
- var _a3;
1452
- return {
1453
- ...step,
1454
- ...(_a3 = taskStream == null ? void 0 : taskStream.steps) == null ? void 0 : _a3[step.id]
1455
- };
1456
- })) != null ? _b2 : [];
1457
- },
1458
- [taskStream]
1459
- );
1460
- const [logsVisible, setLogVisibleState] = useState(false);
1461
- const [buttonBarVisible, setButtonBarVisibleState] = useState(true);
1462
- useEffect(() => {
1463
- if (taskStream.error) {
1464
- setLogVisibleState(true);
1465
- }
1466
- }, [taskStream.error]);
1467
- useEffect(() => {
1468
- if (taskStream.completed && !taskStream.error) {
1469
- setButtonBarVisibleState(false);
1470
- }
1471
- }, [taskStream.error, taskStream.completed]);
1472
- const activeStep = useMemo(() => {
1473
- for (let i = steps.length - 1; i >= 0; i--) {
1474
- if (steps[i].status !== "open") {
1475
- return i;
1476
- }
1477
- }
1478
- return 0;
1479
- }, [steps]);
1480
- const startOver = useCallback(() => {
1481
- var _a2, _b2, _c2, _d2, _e2, _f2;
1482
- const { namespace, name } = (_d2 = (_c2 = (_b2 = (_a2 = taskStream.task) == null ? void 0 : _a2.spec.templateInfo) == null ? void 0 : _b2.entity) == null ? void 0 : _c2.metadata) != null ? _d2 : {};
1483
- const formData = (_f2 = (_e2 = taskStream.task) == null ? void 0 : _e2.spec.parameters) != null ? _f2 : {};
1484
- if (!namespace || !name) {
1485
- return;
1486
- }
1487
- navigate({
1488
- pathname: templateRouteRef({
1489
- namespace,
1490
- templateName: name
1491
- }),
1492
- search: `?${qs.stringify({ formData: JSON.stringify(formData) })}`
1493
- });
1494
- }, [
1495
- navigate,
1496
- (_a = taskStream.task) == null ? void 0 : _a.spec.parameters,
1497
- (_d = (_c = (_b = taskStream.task) == null ? void 0 : _b.spec.templateInfo) == null ? void 0 : _c.entity) == null ? void 0 : _d.metadata,
1498
- templateRouteRef
1499
- ]);
1500
- const [{ status: cancelStatus }, { execute: triggerCancel }] = useAsync$1(
1501
- async () => {
1502
- if (taskId) {
1503
- await scaffolderApi.cancelTask(taskId);
1504
- }
1505
- }
1506
- );
1507
- const Outputs = (_e = props.TemplateOutputsComponent) != null ? _e : DefaultTemplateOutputs;
1508
- const templateName = (_h = (_g = (_f = taskStream.task) == null ? void 0 : _f.spec.templateInfo) == null ? void 0 : _g.entity) == null ? void 0 : _h.metadata.name;
1509
- const cancelEnabled = !(taskStream.cancelled || taskStream.completed);
1510
- return /* @__PURE__ */ React.createElement(Page, { themeId: "website" }, /* @__PURE__ */ React.createElement(
1511
- Header,
1512
- {
1513
- pageTitleOverride: `Run of ${templateName}`,
1514
- title: /* @__PURE__ */ React.createElement("div", null, "Run of ", /* @__PURE__ */ React.createElement("code", null, templateName)),
1515
- subtitle: `Task ${taskId}`
1516
- },
1517
- /* @__PURE__ */ React.createElement(
1518
- ContextMenu,
1519
- {
1520
- cancelEnabled,
1521
- logsVisible,
1522
- buttonBarVisible,
1523
- onStartOver: startOver,
1524
- onToggleLogs: setLogVisibleState,
1525
- onToggleButtonBar: setButtonBarVisibleState,
1526
- taskId
1527
- }
1528
- )
1529
- ), /* @__PURE__ */ React.createElement(Content, { className: classes.contentWrapper }, taskStream.error ? /* @__PURE__ */ React.createElement(Box, { paddingBottom: 2 }, /* @__PURE__ */ React.createElement(
1530
- ErrorPanel,
1531
- {
1532
- error: taskStream.error,
1533
- titleFormat: "markdown",
1534
- title: taskStream.error.message
1535
- }
1536
- )) : null, /* @__PURE__ */ React.createElement(Box, { paddingBottom: 2 }, /* @__PURE__ */ React.createElement(
1537
- TaskSteps,
1538
- {
1539
- steps,
1540
- activeStep,
1541
- isComplete: taskStream.completed,
1542
- isError: Boolean(taskStream.error)
1543
- }
1544
- )), /* @__PURE__ */ React.createElement(Outputs, { output: taskStream.output }), buttonBarVisible ? /* @__PURE__ */ React.createElement(Box, { paddingBottom: 2 }, /* @__PURE__ */ React.createElement(Paper, null, /* @__PURE__ */ React.createElement(Box, { padding: 2 }, /* @__PURE__ */ React.createElement("div", { className: classes.buttonBar }, /* @__PURE__ */ React.createElement(
1545
- Button,
1546
- {
1547
- className: classes.cancelButton,
1548
- disabled: !cancelEnabled || cancelStatus !== "not-executed",
1549
- onClick: triggerCancel,
1550
- "data-testid": "cancel-button"
1551
- },
1552
- "Cancel"
1553
- ), /* @__PURE__ */ React.createElement(
1554
- Button,
1555
- {
1556
- className: classes.logsVisibilityButton,
1557
- color: "primary",
1558
- variant: "outlined",
1559
- onClick: () => setLogVisibleState(!logsVisible)
1560
- },
1561
- logsVisible ? "Hide Logs" : "Show Logs"
1562
- ), /* @__PURE__ */ React.createElement(
1563
- Button,
1564
- {
1565
- variant: "contained",
1566
- color: "primary",
1567
- disabled: cancelEnabled,
1568
- onClick: startOver
1569
- },
1570
- "Start Over"
1571
- ))))) : null, logsVisible ? /* @__PURE__ */ React.createElement(Box, { paddingBottom: 2, height: "100%" }, /* @__PURE__ */ React.createElement(Paper, { style: { height: "100%" } }, /* @__PURE__ */ React.createElement(Box, { padding: 2, height: "100%" }, /* @__PURE__ */ React.createElement(TaskLogStream, { logs: taskStream.stepLogs })))) : null));
1572
- };
1573
-
1574
- export { EntityPicker as E, MultiEntityPicker as M, OwnerPicker as O, RepoUrlPicker as R, EntityPickerSchema as a, EntityNamePicker as b, EntityNamePickerSchema as c, MultiEntityPickerSchema as d, entityNamePickerValidation as e, RepoUrlPickerSchema as f, OwnerPickerSchema as g, MyGroupsPicker as h, MyGroupsPickerSchema as i, OwnedEntityPicker as j, OwnedEntityPickerSchema as k, EntityTagsPicker as l, EntityTagsPickerSchema as m, OngoingTask as n, makeFieldSchemaFromZod as o, EntityPickerFieldSchema as p, OwnerPickerFieldSchema as q, repoPickerValidation as r, RepoUrlPickerFieldSchema as s, OwnedEntityPickerFieldSchema as t, EntityTagsPickerFieldSchema as u, validateMultiEntityPickerValidation as v, MyGroupsPickerFieldSchema as w };
1575
- //# sourceMappingURL=OngoingTask-ClfJCJcE.esm.js.map