@backstage/plugin-scaffolder 0.11.13 → 0.11.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/dist/esm/{Router-8b2aa17e.esm.js → Router-552fb2ce.esm.js} +107 -70
- package/dist/esm/Router-552fb2ce.esm.js.map +1 -0
- package/dist/esm/{index-385b3fc1.esm.js → index-768702c3.esm.js} +214 -75
- package/dist/esm/index-768702c3.esm.js.map +1 -0
- package/dist/index.d.ts +18 -13
- package/dist/index.esm.js +6 -6
- package/package.json +18 -16
- package/dist/esm/Router-8b2aa17e.esm.js.map +0 -1
- package/dist/esm/index-385b3fc1.esm.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder
|
|
2
2
|
|
|
3
|
+
## 0.11.17
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @backstage/core-plugin-api@0.4.1
|
|
10
|
+
- @backstage/plugin-catalog-react@0.6.10
|
|
11
|
+
- @backstage/core-components@0.8.3
|
|
12
|
+
|
|
13
|
+
## 0.11.16
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 9c25894892: Implement a `EntityTagsPicker` field extension
|
|
18
|
+
- 7d4b4e937c: Uptake changes to the GitHub Credentials Provider interface.
|
|
19
|
+
- d078377f67: Support navigating back to pre-filled templates to update inputs of scaffolder tasks for resubmission
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
- @backstage/plugin-catalog-react@0.6.9
|
|
22
|
+
- @backstage/plugin-scaffolder-common@0.1.2
|
|
23
|
+
- @backstage/integration@0.7.0
|
|
24
|
+
- @backstage/integration-react@0.1.17
|
|
25
|
+
|
|
26
|
+
## 0.11.15
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- c5eb756760: Fix a small browser console warning
|
|
31
|
+
- ff5ff57883: EntityPicker can require an existing entity be selected by disallowing arbitrary values
|
|
32
|
+
- 0f645a7947: Added OwnedEntityPicker field which displays Owned Entities in options
|
|
33
|
+
- b646a73fe0: In @backstage/plugin-scaffolder - When user will have one option available in hostUrl or owner - autoselect and select component should be readonly.
|
|
34
|
+
|
|
35
|
+
in @backstage/core-components - Select component has extended API with few more props: native : boolean, disabled: boolean. native - if set to true - Select component will use native browser select picker (not rendered by Material UI lib ).
|
|
36
|
+
disabled - if set to true - action on component will not be possible.
|
|
37
|
+
|
|
38
|
+
- 7a4bd2ceac: Prefer using `Link` from `@backstage/core-components` rather than material-UI.
|
|
39
|
+
- 4c269c7c23: Add DescriptionField override to support Markdown
|
|
40
|
+
- Updated dependencies
|
|
41
|
+
- @backstage/core-plugin-api@0.4.0
|
|
42
|
+
- @backstage/plugin-catalog-react@0.6.8
|
|
43
|
+
- @backstage/core-components@0.8.2
|
|
44
|
+
- @backstage/catalog-client@0.5.3
|
|
45
|
+
- @backstage/integration-react@0.1.16
|
|
46
|
+
|
|
47
|
+
## 0.11.14
|
|
48
|
+
|
|
49
|
+
### Patch Changes
|
|
50
|
+
|
|
51
|
+
- 6845cce533: Can specify allowedOwners to the RepoUrlPicker picker in a template definition
|
|
52
|
+
- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used.
|
|
53
|
+
- 2edcf7738f: Fix bug with setting owner in RepoUrlPicker causing validation failure
|
|
54
|
+
- b291c3176e: Switch to using `LogViewer` component from `@backstage/core-components` to display scaffolder logs.
|
|
55
|
+
- Updated dependencies
|
|
56
|
+
- @backstage/core-components@0.8.0
|
|
57
|
+
- @backstage/core-plugin-api@0.3.0
|
|
58
|
+
- @backstage/integration-react@0.1.15
|
|
59
|
+
- @backstage/plugin-catalog-react@0.6.5
|
|
60
|
+
|
|
3
61
|
## 0.11.13
|
|
4
62
|
|
|
5
63
|
### Patch Changes
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import React, { useState, useCallback, useEffect, memo,
|
|
1
|
+
import React, { useState, useCallback, useEffect, memo, useMemo } from 'react';
|
|
2
2
|
import { useNavigate, Navigate, generatePath, useParams as useParams$1, useOutlet, Routes, Route } from 'react-router';
|
|
3
|
-
import { Page, Header, Lifecycle, Content, ContentHeader, CreateButton, SupportButton, StructuredMetadataTable, InfoCard, Link,
|
|
3
|
+
import { Page, Header, Lifecycle, Content, ContentHeader, CreateButton, SupportButton, MarkdownContent, StructuredMetadataTable, InfoCard, Link, ErrorPage, LogViewer, Progress } from '@backstage/core-components';
|
|
4
4
|
import { useRouteRef, useApi, errorApiRef, useApiHolder, useApp, useElementFilter } from '@backstage/core-plugin-api';
|
|
5
5
|
import { EntityListProvider, EntitySearchBar, EntityKindPicker, UserListPicker, EntityTagPicker, entityRouteRef } from '@backstage/plugin-catalog-react';
|
|
6
6
|
import { makeStyles, Stepper, Step, StepLabel, Typography, StepContent, Button, Paper, Box, LinearProgress, Grid, StepButton, CircularProgress, TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from '@material-ui/core';
|
|
7
|
-
import { E as EntityPicker, a as EntityNamePicker, e as entityNamePickerValidation, R as RepoUrlPicker, r as repoPickerValidation, O as OwnerPicker,
|
|
7
|
+
import { E as EntityPicker, a as EntityNamePicker, e as entityNamePickerValidation, b as EntityTagsPicker, R as RepoUrlPicker, r as repoPickerValidation, O as OwnerPicker, c as OwnedEntityPicker, d as registerComponentRouteRef, T as TemplateTypePicker, f as TemplateList, s as scaffolderApiRef, g as rootRouteRef, F as FIELD_EXTENSION_WRAPPER_KEY, h as FIELD_EXTENSION_KEY } from './index-768702c3.esm.js';
|
|
8
|
+
import qs from 'qs';
|
|
8
9
|
import { useParams } from 'react-router-dom';
|
|
9
|
-
import
|
|
10
|
+
import useAsync from 'react-use/lib/useAsync';
|
|
10
11
|
import { withTheme } from '@rjsf/core';
|
|
11
12
|
import { Theme } from '@rjsf/material-ui';
|
|
12
13
|
import Grid$1 from '@material-ui/core/Grid';
|
|
@@ -20,19 +21,20 @@ import Check from '@material-ui/icons/Check';
|
|
|
20
21
|
import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord';
|
|
21
22
|
import classNames from 'classnames';
|
|
22
23
|
import { DateTime, Interval } from 'luxon';
|
|
24
|
+
import useInterval from 'react-use/lib/useInterval';
|
|
23
25
|
import { useImmerReducer } from 'use-immer';
|
|
24
26
|
import { parseEntityName } from '@backstage/catalog-model';
|
|
25
27
|
import LanguageIcon from '@material-ui/icons/Language';
|
|
26
28
|
import '@backstage/errors';
|
|
27
|
-
import 'qs';
|
|
28
29
|
import 'zen-observable';
|
|
29
30
|
import '@material-ui/core/FormControl';
|
|
30
31
|
import '@material-ui/lab/Autocomplete';
|
|
32
|
+
import 'react-use';
|
|
33
|
+
import '@material-ui/lab';
|
|
31
34
|
import '@backstage/integration-react';
|
|
32
|
-
import '@material-ui/core/Select';
|
|
33
|
-
import '@material-ui/core/InputLabel';
|
|
34
|
-
import '@material-ui/core/Input';
|
|
35
35
|
import '@material-ui/core/FormHelperText';
|
|
36
|
+
import '@material-ui/core/Input';
|
|
37
|
+
import '@material-ui/core/InputLabel';
|
|
36
38
|
import '@material-ui/icons/Star';
|
|
37
39
|
import '@material-ui/icons/StarBorder';
|
|
38
40
|
import '@material-ui/icons/Warning';
|
|
@@ -40,7 +42,6 @@ import 'lodash/capitalize';
|
|
|
40
42
|
import '@material-ui/icons/CheckBox';
|
|
41
43
|
import '@material-ui/icons/CheckBoxOutlineBlank';
|
|
42
44
|
import '@material-ui/icons/ExpandMore';
|
|
43
|
-
import '@material-ui/lab';
|
|
44
45
|
|
|
45
46
|
const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [
|
|
46
47
|
{
|
|
@@ -52,6 +53,10 @@ const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [
|
|
|
52
53
|
name: "EntityNamePicker",
|
|
53
54
|
validation: entityNamePickerValidation
|
|
54
55
|
},
|
|
56
|
+
{
|
|
57
|
+
component: EntityTagsPicker,
|
|
58
|
+
name: "EntityTagsPicker"
|
|
59
|
+
},
|
|
55
60
|
{
|
|
56
61
|
component: RepoUrlPicker,
|
|
57
62
|
name: "RepoUrlPicker",
|
|
@@ -60,6 +65,10 @@ const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [
|
|
|
60
65
|
{
|
|
61
66
|
component: OwnerPicker,
|
|
62
67
|
name: "OwnerPicker"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
component: OwnedEntityPicker,
|
|
71
|
+
name: "OwnedEntityPicker"
|
|
63
72
|
}
|
|
64
73
|
];
|
|
65
74
|
|
|
@@ -105,10 +114,12 @@ const ScaffolderPageContents = ({
|
|
|
105
114
|
}), /* @__PURE__ */ React.createElement(UserListPicker, {
|
|
106
115
|
initialFilter: "all",
|
|
107
116
|
availableFilters: ["all", "starred"]
|
|
108
|
-
}), /* @__PURE__ */ React.createElement(TemplateTypePicker, null), /* @__PURE__ */ React.createElement(EntityTagPicker, null)), /* @__PURE__ */ React.createElement("div", null, groups && groups.map((group) => /* @__PURE__ */ React.createElement(TemplateList, {
|
|
117
|
+
}), /* @__PURE__ */ React.createElement(TemplateTypePicker, null), /* @__PURE__ */ React.createElement(EntityTagPicker, null)), /* @__PURE__ */ React.createElement("div", null, groups && groups.map((group, index) => /* @__PURE__ */ React.createElement(TemplateList, {
|
|
118
|
+
key: index,
|
|
109
119
|
TemplateCardComponent,
|
|
110
120
|
group
|
|
111
121
|
})), /* @__PURE__ */ React.createElement(TemplateList, {
|
|
122
|
+
key: "other",
|
|
112
123
|
TemplateCardComponent,
|
|
113
124
|
group: otherTemplatesGroup
|
|
114
125
|
})))));
|
|
@@ -128,7 +139,7 @@ function extractUiSchema(schema, uiSchema) {
|
|
|
128
139
|
if (!isObject$1(schema)) {
|
|
129
140
|
return;
|
|
130
141
|
}
|
|
131
|
-
const {properties, items, anyOf, oneOf, allOf, dependencies} = schema;
|
|
142
|
+
const { properties, items, anyOf, oneOf, allOf, dependencies } = schema;
|
|
132
143
|
for (const propName in schema) {
|
|
133
144
|
if (!schema.hasOwnProperty(propName)) {
|
|
134
145
|
continue;
|
|
@@ -197,9 +208,18 @@ function transformSchemaToProps(inputSchema) {
|
|
|
197
208
|
delete schema.title;
|
|
198
209
|
const uiSchema = {};
|
|
199
210
|
extractUiSchema(schema, uiSchema);
|
|
200
|
-
return {schema, uiSchema};
|
|
211
|
+
return { schema, uiSchema };
|
|
201
212
|
}
|
|
202
213
|
|
|
214
|
+
const DescriptionField = ({ description }) => description && /* @__PURE__ */ React.createElement(MarkdownContent, {
|
|
215
|
+
content: description
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
var fieldOverrides = /*#__PURE__*/Object.freeze({
|
|
219
|
+
__proto__: null,
|
|
220
|
+
DescriptionField: DescriptionField
|
|
221
|
+
});
|
|
222
|
+
|
|
203
223
|
const Form = withTheme(Theme);
|
|
204
224
|
function getUiSchemasFromSteps(steps) {
|
|
205
225
|
const uiSchemas = [];
|
|
@@ -278,7 +298,7 @@ const MultistepJsonForm = ({
|
|
|
278
298
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Stepper, {
|
|
279
299
|
activeStep,
|
|
280
300
|
orientation: "vertical"
|
|
281
|
-
}, steps.map(({title, schema, ...formProps}, index) => {
|
|
301
|
+
}, steps.map(({ title, schema, ...formProps }, index) => {
|
|
282
302
|
return /* @__PURE__ */ React.createElement(Step, {
|
|
283
303
|
key: title
|
|
284
304
|
}, /* @__PURE__ */ React.createElement(StepLabel, {
|
|
@@ -292,7 +312,7 @@ const MultistepJsonForm = ({
|
|
|
292
312
|
key: title
|
|
293
313
|
}, /* @__PURE__ */ React.createElement(Form, {
|
|
294
314
|
showErrorList: false,
|
|
295
|
-
fields,
|
|
315
|
+
fields: { ...fieldOverrides, ...fields },
|
|
296
316
|
widgets,
|
|
297
317
|
noHtml5Validate: true,
|
|
298
318
|
formData,
|
|
@@ -337,12 +357,12 @@ const MultistepJsonForm = ({
|
|
|
337
357
|
|
|
338
358
|
const useTemplateParameterSchema = (templateName) => {
|
|
339
359
|
const scaffolderApi = useApi(scaffolderApiRef);
|
|
340
|
-
const {value, loading, error} = useAsync(() => scaffolderApi.getTemplateParameterSchema({
|
|
360
|
+
const { value, loading, error } = useAsync(() => scaffolderApi.getTemplateParameterSchema({
|
|
341
361
|
name: templateName,
|
|
342
362
|
kind: "template",
|
|
343
363
|
namespace: "default"
|
|
344
364
|
}), [scaffolderApi, templateName]);
|
|
345
|
-
return {schema: value, loading, error};
|
|
365
|
+
return { schema: value, loading, error };
|
|
346
366
|
};
|
|
347
367
|
function isObject(obj) {
|
|
348
368
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
@@ -380,16 +400,26 @@ const TemplatePage = ({
|
|
|
380
400
|
const apiHolder = useApiHolder();
|
|
381
401
|
const errorApi = useApi(errorApiRef);
|
|
382
402
|
const scaffolderApi = useApi(scaffolderApiRef);
|
|
383
|
-
const {templateName} = useParams();
|
|
403
|
+
const { templateName } = useParams();
|
|
384
404
|
const navigate = useNavigate();
|
|
385
405
|
const rootLink = useRouteRef(rootRouteRef);
|
|
386
|
-
const {schema, loading, error} = useTemplateParameterSchema(templateName);
|
|
387
|
-
const [formState, setFormState] = useState({
|
|
406
|
+
const { schema, loading, error } = useTemplateParameterSchema(templateName);
|
|
407
|
+
const [formState, setFormState] = useState(() => {
|
|
408
|
+
var _a;
|
|
409
|
+
const query = qs.parse(window.location.search, {
|
|
410
|
+
ignoreQueryPrefix: true
|
|
411
|
+
});
|
|
412
|
+
return (_a = query.formData) != null ? _a : {};
|
|
413
|
+
});
|
|
388
414
|
const handleFormReset = () => setFormState({});
|
|
389
415
|
const handleChange = useCallback((e) => setFormState(e.formData), [setFormState]);
|
|
390
416
|
const handleCreate = async () => {
|
|
417
|
+
var _a;
|
|
391
418
|
const id = await scaffolderApi.scaffold(templateName, formState);
|
|
392
|
-
|
|
419
|
+
const formParams = qs.stringify({ formData: formState }, { addQueryPrefix: true });
|
|
420
|
+
const newUrl = `${window.location.pathname}${formParams}`;
|
|
421
|
+
(_a = window.history) == null ? void 0 : _a.replaceState(null, document.title, newUrl);
|
|
422
|
+
navigate(generatePath(`${rootLink()}/tasks/:taskId`, { taskId: id }));
|
|
393
423
|
};
|
|
394
424
|
if (error) {
|
|
395
425
|
errorApi.post(new Error(`Failed to load template, ${error}`));
|
|
@@ -403,8 +433,8 @@ const TemplatePage = ({
|
|
|
403
433
|
to: rootLink()
|
|
404
434
|
});
|
|
405
435
|
}
|
|
406
|
-
const customFieldComponents = Object.fromEntries(customFieldExtensions.map(({name, component}) => [name, component]));
|
|
407
|
-
const customFieldValidators = Object.fromEntries(customFieldExtensions.map(({name, validation}) => [name, validation]));
|
|
436
|
+
const customFieldComponents = Object.fromEntries(customFieldExtensions.map(({ name, component }) => [name, component]));
|
|
437
|
+
const customFieldValidators = Object.fromEntries(customFieldExtensions.map(({ name, validation }) => [name, validation]));
|
|
408
438
|
return /* @__PURE__ */ React.createElement(Page, {
|
|
409
439
|
themeId: "home"
|
|
410
440
|
}, /* @__PURE__ */ React.createElement(Header, {
|
|
@@ -418,7 +448,7 @@ const TemplatePage = ({
|
|
|
418
448
|
}), schema && /* @__PURE__ */ React.createElement(InfoCard, {
|
|
419
449
|
title: schema.title,
|
|
420
450
|
noPadding: true,
|
|
421
|
-
titleTypographyProps: {component: "h2"}
|
|
451
|
+
titleTypographyProps: { component: "h2" }
|
|
422
452
|
}, /* @__PURE__ */ React.createElement(MultistepJsonForm, {
|
|
423
453
|
formData: formState,
|
|
424
454
|
fields: customFieldComponents,
|
|
@@ -428,7 +458,7 @@ const TemplatePage = ({
|
|
|
428
458
|
steps: schema.steps.map((step) => {
|
|
429
459
|
return {
|
|
430
460
|
...step,
|
|
431
|
-
validate: createValidator(step.schema, customFieldValidators, {apiHolder})
|
|
461
|
+
validate: createValidator(step.schema, customFieldValidators, { apiHolder })
|
|
432
462
|
};
|
|
433
463
|
})
|
|
434
464
|
}))));
|
|
@@ -439,7 +469,7 @@ function reducer(draft, action) {
|
|
|
439
469
|
switch (action.type) {
|
|
440
470
|
case "INIT": {
|
|
441
471
|
draft.steps = action.data.spec.steps.reduce((current, next) => {
|
|
442
|
-
current[next.id] = {status: "open", id: next.id};
|
|
472
|
+
current[next.id] = { status: "open", id: next.id };
|
|
443
473
|
return current;
|
|
444
474
|
}, {});
|
|
445
475
|
draft.stepLogs = action.data.spec.steps.reduce((current, next) => {
|
|
@@ -505,13 +535,13 @@ const useTaskEventStream = (taskId) => {
|
|
|
505
535
|
if (didCancel) {
|
|
506
536
|
return;
|
|
507
537
|
}
|
|
508
|
-
dispatch({type: "INIT", data: task});
|
|
509
|
-
const observable = scaffolderApi.streamLogs({taskId});
|
|
538
|
+
dispatch({ type: "INIT", data: task });
|
|
539
|
+
const observable = scaffolderApi.streamLogs({ taskId });
|
|
510
540
|
const collectedLogEvents = new Array();
|
|
511
541
|
function emitLogs() {
|
|
512
542
|
if (collectedLogEvents.length) {
|
|
513
543
|
const logs = collectedLogEvents.splice(0, collectedLogEvents.length);
|
|
514
|
-
dispatch({type: "LOGS", data: logs});
|
|
544
|
+
dispatch({ type: "LOGS", data: logs });
|
|
515
545
|
}
|
|
516
546
|
}
|
|
517
547
|
logPusher = setInterval(emitLogs, 500);
|
|
@@ -522,7 +552,7 @@ const useTaskEventStream = (taskId) => {
|
|
|
522
552
|
return collectedLogEvents.push(event);
|
|
523
553
|
case "completion":
|
|
524
554
|
emitLogs();
|
|
525
|
-
dispatch({type: "COMPLETED", data: event});
|
|
555
|
+
dispatch({ type: "COMPLETED", data: event });
|
|
526
556
|
return void 0;
|
|
527
557
|
default:
|
|
528
558
|
throw new Error(`Unhandled event type ${event.type} in observer`);
|
|
@@ -530,12 +560,12 @@ const useTaskEventStream = (taskId) => {
|
|
|
530
560
|
},
|
|
531
561
|
error: (error) => {
|
|
532
562
|
emitLogs();
|
|
533
|
-
dispatch({type: "ERROR", data: error});
|
|
563
|
+
dispatch({ type: "ERROR", data: error });
|
|
534
564
|
}
|
|
535
565
|
});
|
|
536
566
|
}, (error) => {
|
|
537
567
|
if (!didCancel) {
|
|
538
|
-
dispatch({type: "ERROR", data: error});
|
|
568
|
+
dispatch({ type: "ERROR", data: error });
|
|
539
569
|
}
|
|
540
570
|
});
|
|
541
571
|
return () => {
|
|
@@ -562,7 +592,7 @@ const useStyles$2 = makeStyles({
|
|
|
562
592
|
}
|
|
563
593
|
});
|
|
564
594
|
const IconLink = (props) => {
|
|
565
|
-
const {href, text, Icon, ...linkProps} = props;
|
|
595
|
+
const { href, text, Icon, ...linkProps } = props;
|
|
566
596
|
const classes = useStyles$2();
|
|
567
597
|
return /* @__PURE__ */ React.createElement(Grid, {
|
|
568
598
|
container: true,
|
|
@@ -581,9 +611,9 @@ const IconLink = (props) => {
|
|
|
581
611
|
}, text || href)));
|
|
582
612
|
};
|
|
583
613
|
|
|
584
|
-
const TaskPageLinks = ({output}) => {
|
|
585
|
-
const {entityRef: entityRefOutput, remoteUrl} = output;
|
|
586
|
-
let {links = []} = output;
|
|
614
|
+
const TaskPageLinks = ({ output }) => {
|
|
615
|
+
const { entityRef: entityRefOutput, remoteUrl } = output;
|
|
616
|
+
let { links = [] } = output;
|
|
587
617
|
const app = useApp();
|
|
588
618
|
const entityRoute = useRouteRef(entityRouteRef);
|
|
589
619
|
const iconResolver = (key) => {
|
|
@@ -591,7 +621,7 @@ const TaskPageLinks = ({output}) => {
|
|
|
591
621
|
return key ? (_a = app.getSystemIcon(key)) != null ? _a : LanguageIcon : LanguageIcon;
|
|
592
622
|
};
|
|
593
623
|
if (remoteUrl) {
|
|
594
|
-
links = [{url: remoteUrl, title: "Repo"}, ...links];
|
|
624
|
+
links = [{ url: remoteUrl, title: "Repo" }, ...links];
|
|
595
625
|
}
|
|
596
626
|
if (entityRefOutput) {
|
|
597
627
|
links = [
|
|
@@ -606,14 +636,14 @@ const TaskPageLinks = ({output}) => {
|
|
|
606
636
|
return /* @__PURE__ */ React.createElement(Box, {
|
|
607
637
|
px: 3,
|
|
608
638
|
pb: 3
|
|
609
|
-
}, links.filter(({url, entityRef}) => url || entityRef).map(({url, entityRef, title, icon}) => {
|
|
639
|
+
}, links.filter(({ url, entityRef }) => url || entityRef).map(({ url, entityRef, title, icon }) => {
|
|
610
640
|
if (entityRef) {
|
|
611
641
|
const entityName = parseEntityName(entityRef);
|
|
612
642
|
const target = entityRoute(entityName);
|
|
613
|
-
return {title, icon, url: target};
|
|
643
|
+
return { title, icon, url: target };
|
|
614
644
|
}
|
|
615
|
-
return {title, icon, url};
|
|
616
|
-
}).map(({url, title, icon}, i) => /* @__PURE__ */ React.createElement(IconLink, {
|
|
645
|
+
return { title, icon, url };
|
|
646
|
+
}).map(({ url, title, icon }, i) => /* @__PURE__ */ React.createElement(IconLink, {
|
|
617
647
|
key: `output-link-${i}`,
|
|
618
648
|
href: url,
|
|
619
649
|
text: title != null ? title : url,
|
|
@@ -622,15 +652,14 @@ const TaskPageLinks = ({output}) => {
|
|
|
622
652
|
})));
|
|
623
653
|
};
|
|
624
654
|
|
|
625
|
-
const LazyLog = React.lazy(() => import('react-lazylog/build/LazyLog'));
|
|
626
655
|
const humanizeDuration = require("humanize-duration");
|
|
627
656
|
const useStyles$1 = makeStyles$1((theme) => createStyles({
|
|
628
657
|
root: {
|
|
629
658
|
width: "100%"
|
|
630
659
|
},
|
|
631
660
|
button: {
|
|
632
|
-
|
|
633
|
-
|
|
661
|
+
marginBottom: theme.spacing(2),
|
|
662
|
+
marginLeft: theme.spacing(2)
|
|
634
663
|
},
|
|
635
664
|
actionsContainer: {
|
|
636
665
|
marginBottom: theme.spacing(2)
|
|
@@ -648,7 +677,7 @@ const useStyles$1 = makeStyles$1((theme) => createStyles({
|
|
|
648
677
|
width: "100%"
|
|
649
678
|
}
|
|
650
679
|
}));
|
|
651
|
-
const StepTimeTicker = ({step}) => {
|
|
680
|
+
const StepTimeTicker = ({ step }) => {
|
|
652
681
|
const [time, setTime] = useState("");
|
|
653
682
|
useInterval(() => {
|
|
654
683
|
if (!step.startedAt) {
|
|
@@ -658,7 +687,7 @@ const StepTimeTicker = ({step}) => {
|
|
|
658
687
|
const end = step.endedAt ? DateTime.fromISO(step.endedAt) : DateTime.local();
|
|
659
688
|
const startedAt = DateTime.fromISO(step.startedAt);
|
|
660
689
|
const formatted = Interval.fromDateTimes(startedAt, end).toDuration().valueOf();
|
|
661
|
-
setTime(humanizeDuration(formatted, {round: true}));
|
|
690
|
+
setTime(humanizeDuration(formatted, { round: true }));
|
|
662
691
|
}, 1e3);
|
|
663
692
|
return /* @__PURE__ */ React.createElement(Typography$1, {
|
|
664
693
|
variant: "caption"
|
|
@@ -680,7 +709,7 @@ const useStepIconStyles = makeStyles$1((theme) => createStyles({
|
|
|
680
709
|
}));
|
|
681
710
|
function TaskStepIconComponent(props) {
|
|
682
711
|
const classes = useStepIconStyles();
|
|
683
|
-
const {active, completed, error} = props;
|
|
712
|
+
const { active, completed, error } = props;
|
|
684
713
|
const getMiddle = () => {
|
|
685
714
|
if (active) {
|
|
686
715
|
return /* @__PURE__ */ React.createElement(CircularProgress, {
|
|
@@ -743,24 +772,14 @@ const TaskStatusStepper = memo(({
|
|
|
743
772
|
})))));
|
|
744
773
|
})));
|
|
745
774
|
});
|
|
746
|
-
const
|
|
747
|
-
return /* @__PURE__ */ React.createElement(Suspense, {
|
|
748
|
-
fallback: /* @__PURE__ */ React.createElement(Progress, null)
|
|
749
|
-
}, /* @__PURE__ */ React.createElement("div", {
|
|
750
|
-
style: {height: "80vh"}
|
|
751
|
-
}, /* @__PURE__ */ React.createElement(LazyLog, {
|
|
752
|
-
text: log,
|
|
753
|
-
extraLines: 1,
|
|
754
|
-
follow: true,
|
|
755
|
-
selectableLines: true,
|
|
756
|
-
enableSearch: true
|
|
757
|
-
})));
|
|
758
|
-
});
|
|
759
|
-
const hasLinks = ({entityRef, remoteUrl, links = []}) => !!(entityRef || remoteUrl || links.length > 0);
|
|
775
|
+
const hasLinks = ({ entityRef, remoteUrl, links = [] }) => !!(entityRef || remoteUrl || links.length > 0);
|
|
760
776
|
const TaskPage = () => {
|
|
777
|
+
const classes = useStyles$1();
|
|
778
|
+
const navigate = useNavigate();
|
|
779
|
+
const rootLink = useRouteRef(rootRouteRef);
|
|
761
780
|
const [userSelectedStepId, setUserSelectedStepId] = useState(void 0);
|
|
762
781
|
const [lastActiveStepId, setLastActiveStepId] = useState(void 0);
|
|
763
|
-
const {taskId} = useParams$1();
|
|
782
|
+
const { taskId } = useParams$1();
|
|
764
783
|
const taskStream = useTaskEventStream(taskId);
|
|
765
784
|
const completed = taskStream.completed;
|
|
766
785
|
const steps = useMemo(() => {
|
|
@@ -794,7 +813,17 @@ const TaskPage = () => {
|
|
|
794
813
|
return log.join("\n");
|
|
795
814
|
}, [taskStream.stepLogs, currentStepId]);
|
|
796
815
|
const taskNotFound = taskStream.completed === true && taskStream.loading === false && !taskStream.task;
|
|
797
|
-
const {output} = taskStream;
|
|
816
|
+
const { output } = taskStream;
|
|
817
|
+
const handleStartOver = () => {
|
|
818
|
+
var _a, _b;
|
|
819
|
+
if (!taskStream.task || !((_b = (_a = taskStream.task) == null ? void 0 : _a.spec.metadata) == null ? void 0 : _b.name)) {
|
|
820
|
+
navigate(generatePath(rootLink()));
|
|
821
|
+
}
|
|
822
|
+
const formData = taskStream.task.spec.apiVersion === "backstage.io/v1beta2" ? taskStream.task.spec.values : taskStream.task.spec.parameters;
|
|
823
|
+
navigate(generatePath(`${rootLink()}/templates/:templateName?${qs.stringify({ formData })}`, {
|
|
824
|
+
templateName: taskStream.task.spec.metadata.name
|
|
825
|
+
}));
|
|
826
|
+
};
|
|
798
827
|
return /* @__PURE__ */ React.createElement(Page, {
|
|
799
828
|
themeId: "home"
|
|
800
829
|
}, /* @__PURE__ */ React.createElement(Header, {
|
|
@@ -819,12 +848,20 @@ const TaskPage = () => {
|
|
|
819
848
|
onUserStepChange: setUserSelectedStepId
|
|
820
849
|
}), output && hasLinks(output) && /* @__PURE__ */ React.createElement(TaskPageLinks, {
|
|
821
850
|
output
|
|
822
|
-
})
|
|
851
|
+
}), /* @__PURE__ */ React.createElement(Button, {
|
|
852
|
+
className: classes.button,
|
|
853
|
+
onClick: handleStartOver,
|
|
854
|
+
disabled: !completed,
|
|
855
|
+
variant: "contained",
|
|
856
|
+
color: "primary"
|
|
857
|
+
}, "Start Over"))), /* @__PURE__ */ React.createElement(Grid$1, {
|
|
823
858
|
item: true,
|
|
824
859
|
xs: 9
|
|
825
|
-
}, /* @__PURE__ */ React.createElement(
|
|
826
|
-
|
|
827
|
-
}
|
|
860
|
+
}, /* @__PURE__ */ React.createElement("div", {
|
|
861
|
+
style: { height: "80vh" }
|
|
862
|
+
}, /* @__PURE__ */ React.createElement(LogViewer, {
|
|
863
|
+
text: logAsString
|
|
864
|
+
})))))));
|
|
828
865
|
};
|
|
829
866
|
|
|
830
867
|
const useStyles = makeStyles((theme) => ({
|
|
@@ -851,7 +888,7 @@ const useStyles = makeStyles((theme) => ({
|
|
|
851
888
|
const ActionsPage = () => {
|
|
852
889
|
const api = useApi(scaffolderApiRef);
|
|
853
890
|
const classes = useStyles();
|
|
854
|
-
const {loading, value, error} = useAsync(async () => {
|
|
891
|
+
const { loading, value, error } = useAsync(async () => {
|
|
855
892
|
return api.listActions();
|
|
856
893
|
});
|
|
857
894
|
if (loading) {
|
|
@@ -935,7 +972,7 @@ const ActionsPage = () => {
|
|
|
935
972
|
}), /* @__PURE__ */ React.createElement(Content, null, items));
|
|
936
973
|
};
|
|
937
974
|
|
|
938
|
-
const Router = ({TemplateCardComponent, groups}) => {
|
|
975
|
+
const Router = ({ TemplateCardComponent, groups }) => {
|
|
939
976
|
const outlet = useOutlet();
|
|
940
977
|
const customFieldExtensions = useElementFilter(outlet, (elements) => elements.selectByComponentData({
|
|
941
978
|
key: FIELD_EXTENSION_WRAPPER_KEY
|
|
@@ -944,7 +981,7 @@ const Router = ({TemplateCardComponent, groups}) => {
|
|
|
944
981
|
}));
|
|
945
982
|
const fieldExtensions = [
|
|
946
983
|
...customFieldExtensions,
|
|
947
|
-
...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(({name}) => !customFieldExtensions.some((customFieldExtension) => customFieldExtension.name === name))
|
|
984
|
+
...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(({ name }) => !customFieldExtensions.some((customFieldExtension) => customFieldExtension.name === name))
|
|
948
985
|
];
|
|
949
986
|
return /* @__PURE__ */ React.createElement(Routes, null, /* @__PURE__ */ React.createElement(Route, {
|
|
950
987
|
path: "/",
|
|
@@ -967,4 +1004,4 @@ const Router = ({TemplateCardComponent, groups}) => {
|
|
|
967
1004
|
};
|
|
968
1005
|
|
|
969
1006
|
export { Router };
|
|
970
|
-
//# sourceMappingURL=Router-
|
|
1007
|
+
//# sourceMappingURL=Router-552fb2ce.esm.js.map
|