@backstage/plugin-scaffolder 1.11.0-next.2 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/alpha/package.json +1 -1
- package/dist/esm/{ListTasksPage-6e377096.esm.js → ListTasksPage-a0fe74a9.esm.js} +2 -2
- package/dist/esm/{ListTasksPage-6e377096.esm.js.map → ListTasksPage-a0fe74a9.esm.js.map} +1 -1
- package/dist/esm/{Router-e878e04f.esm.js → Router-fae7a62f.esm.js} +63 -960
- package/dist/esm/Router-fae7a62f.esm.js.map +1 -0
- package/dist/esm/{index-02b0e824.esm.js → index-5b3a75fa.esm.js} +1627 -230
- package/dist/esm/index-5b3a75fa.esm.js.map +1 -0
- package/dist/esm/{index-9bea2c47.esm.js → index-83c9fe8a.esm.js} +104 -6
- package/dist/esm/index-83c9fe8a.esm.js.map +1 -0
- package/dist/index.esm.js +32 -3
- package/dist/index.esm.js.map +1 -1
- package/package.json +18 -17
- package/dist/esm/Router-e878e04f.esm.js.map +0 -1
- package/dist/esm/index-02b0e824.esm.js.map +0 -1
- package/dist/esm/index-9bea2c47.esm.js.map +0 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import React, { useState, useCallback,
|
|
1
|
+
import React, { useState, useCallback, useMemo, Component, useEffect } from 'react';
|
|
2
2
|
import { useNavigate, Navigate, useOutlet, Routes, Route } from 'react-router-dom';
|
|
3
|
-
import { ItemCardHeader, MarkdownContent, Button, Link, ContentHeader, Progress, WarningPanel, Content, ItemCardGrid, Page, Header, CreateButton, SupportButton, StructuredMetadataTable, InfoCard
|
|
3
|
+
import { ItemCardHeader, MarkdownContent, Button, Link, ContentHeader, Progress, WarningPanel, Content, ItemCardGrid, Page, Header, CreateButton, SupportButton, StructuredMetadataTable, InfoCard } from '@backstage/core-components';
|
|
4
4
|
import { useApp, useRouteRef, useApi, useRouteRefParams, useAnalytics, errorApiRef, featureFlagsApiRef, useApiHolder, AnalyticsContext, alertApiRef } from '@backstage/core-plugin-api';
|
|
5
5
|
import { getEntityRelations, getEntitySourceLocation, FavoriteEntity, EntityRefLinks, useEntityList, EntityListProvider, CatalogFilterLayout, EntitySearchBar, EntityKindPicker, UserListPicker, EntityTagPicker, catalogApiRef, humanizeEntityRef } from '@backstage/plugin-catalog-react';
|
|
6
6
|
import { RELATION_OWNED_BY, parseEntityRef, stringifyEntityRef, DEFAULT_NAMESPACE } from '@backstage/catalog-model';
|
|
7
|
-
import { makeStyles, useTheme, Card, CardMedia, CardContent, Box, Typography, Chip, CardActions, Tooltip, IconButton, Paper, Button as Button$1, Stepper, Step, StepLabel, StepContent, LinearProgress, FormControl, InputLabel, Select, MenuItem as MenuItem$1, CardHeader
|
|
7
|
+
import { makeStyles, useTheme, Card, CardMedia, CardContent, Box, Typography, Chip, CardActions, Tooltip, IconButton, Paper, Button as Button$1, Stepper, Step, StepLabel, StepContent, LinearProgress, FormControl, InputLabel, Select, MenuItem as MenuItem$1, CardHeader } from '@material-ui/core';
|
|
8
8
|
import { scmIntegrationsApiRef, ScmIntegrationIcon } from '@backstage/integration-react';
|
|
9
9
|
import LanguageIcon from '@material-ui/icons/Language';
|
|
10
10
|
import WarningIcon from '@material-ui/icons/Warning';
|
|
11
|
-
import { s as selectedTemplateRouteRef, v as viewTechDocRouteRef, e as editRouteRef, a as actionsRouteRef, b as scaffolderListTaskRouteRef, r as registerComponentRouteRef, T as TemplateTypePicker, c as scaffolderTaskRouteRef, d as rootRouteRef, f as
|
|
11
|
+
import { s as selectedTemplateRouteRef, v as viewTechDocRouteRef, e as editRouteRef, a as actionsRouteRef, b as scaffolderListTaskRouteRef, r as registerComponentRouteRef, T as TemplateTypePicker, c as scaffolderTaskRouteRef, d as rootRouteRef, u as useDryRun, f as useDirectoryEditor, D as DirectoryEditorProvider, g as DryRunProvider, h as TemplateEditorBrowser, i as TemplateEditorTextArea, j as DryRunResults, k as TemplateEditorIntro, W as WebFileSystemAccess, l as legacySelectedTemplateRouteRef, A as ActionsPage, m as TaskPage } from './index-5b3a75fa.esm.js';
|
|
12
12
|
import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common';
|
|
13
13
|
import { usePermission } from '@backstage/plugin-permission-react';
|
|
14
14
|
import IconButton$1 from '@material-ui/core/IconButton';
|
|
@@ -34,36 +34,7 @@ import CloseIcon from '@material-ui/icons/Close';
|
|
|
34
34
|
import CodeMirror from '@uiw/react-codemirror';
|
|
35
35
|
import yaml from 'yaml';
|
|
36
36
|
import useDebounce from 'react-use/lib/useDebounce';
|
|
37
|
-
import {
|
|
38
|
-
import Card$1 from '@material-ui/core/Card';
|
|
39
|
-
import CardActionArea from '@material-ui/core/CardActionArea';
|
|
40
|
-
import CardContent$1 from '@material-ui/core/CardContent';
|
|
41
|
-
import Tooltip$1 from '@material-ui/core/Tooltip';
|
|
42
|
-
import Typography$1 from '@material-ui/core/Typography';
|
|
43
|
-
import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined';
|
|
44
|
-
import Accordion from '@material-ui/core/Accordion';
|
|
45
|
-
import AccordionDetails from '@material-ui/core/AccordionDetails';
|
|
46
|
-
import AccordionSummary from '@material-ui/core/AccordionSummary';
|
|
47
|
-
import Divider from '@material-ui/core/Divider';
|
|
48
|
-
import ExpandMoreIcon$1 from '@material-ui/icons/ExpandLess';
|
|
49
|
-
import List$1 from '@material-ui/core/List';
|
|
50
|
-
import ListItem from '@material-ui/core/ListItem';
|
|
51
|
-
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
|
|
52
|
-
import Cancel from '@material-ui/icons/Cancel';
|
|
53
|
-
import Check from '@material-ui/icons/Check';
|
|
54
|
-
import DeleteIcon from '@material-ui/icons/Delete';
|
|
55
|
-
import Box$1 from '@material-ui/core/Box';
|
|
56
|
-
import Tab from '@material-ui/core/Tab';
|
|
57
|
-
import Tabs from '@material-ui/core/Tabs';
|
|
58
|
-
import TreeView from '@material-ui/lab/TreeView';
|
|
59
|
-
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
|
60
|
-
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
|
|
61
|
-
import TreeItem from '@material-ui/lab/TreeItem';
|
|
62
|
-
import classNames from 'classnames';
|
|
63
|
-
import RefreshIcon from '@material-ui/icons/Refresh';
|
|
64
|
-
import SaveIcon from '@material-ui/icons/Save';
|
|
65
|
-
import { showPanel } from '@codemirror/view';
|
|
66
|
-
import { D as DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS, L as ListTasksPage } from './ListTasksPage-6e377096.esm.js';
|
|
37
|
+
import { D as DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS, L as ListTasksPage } from './ListTasksPage-a0fe74a9.esm.js';
|
|
67
38
|
import '@backstage/errors';
|
|
68
39
|
import 'zen-observable';
|
|
69
40
|
import '@material-ui/core/FormControl';
|
|
@@ -78,28 +49,58 @@ import '@material-ui/lab';
|
|
|
78
49
|
import 'lodash/capitalize';
|
|
79
50
|
import '@material-ui/icons/CheckBox';
|
|
80
51
|
import '@material-ui/icons/CheckBoxOutlineBlank';
|
|
52
|
+
import '@material-ui/icons/ExpandMore';
|
|
81
53
|
import '@material-ui/core/Button';
|
|
82
54
|
import '@material-ui/core/useMediaQuery';
|
|
83
55
|
import '@material-ui/icons/AddCircleOutline';
|
|
84
56
|
import 'use-immer';
|
|
85
57
|
import '@material-ui/icons/RemoveCircleOutline';
|
|
86
58
|
import '@material-ui/icons/PanoramaFishEye';
|
|
59
|
+
import 'classnames';
|
|
87
60
|
import '@material-ui/icons/CheckCircleOutline';
|
|
88
61
|
import '@material-ui/icons/ErrorOutline';
|
|
89
62
|
import 'react-use/lib/useInterval';
|
|
90
63
|
import 'luxon';
|
|
91
64
|
import 'humanize-duration';
|
|
65
|
+
import '@react-hookz/web';
|
|
92
66
|
import '@material-ui/icons/Repeat';
|
|
93
67
|
import '@material-ui/icons/Toc';
|
|
94
68
|
import '@material-ui/icons/Settings';
|
|
95
69
|
import '@material-ui/icons/FontDownload';
|
|
70
|
+
import '@material-ui/core/Typography';
|
|
71
|
+
import '@rjsf/validator-ajv8';
|
|
72
|
+
import '@material-ui/core/Accordion';
|
|
73
|
+
import '@material-ui/core/AccordionDetails';
|
|
74
|
+
import '@material-ui/core/AccordionSummary';
|
|
75
|
+
import '@material-ui/core/Divider';
|
|
76
|
+
import '@material-ui/icons/ExpandLess';
|
|
77
|
+
import '@material-ui/core/List';
|
|
78
|
+
import '@material-ui/core/ListItem';
|
|
79
|
+
import '@material-ui/core/ListItemSecondaryAction';
|
|
80
|
+
import '@material-ui/icons/Cancel';
|
|
81
|
+
import '@material-ui/icons/Check';
|
|
82
|
+
import '@material-ui/icons/Delete';
|
|
83
|
+
import '@material-ui/core/Box';
|
|
84
|
+
import '@material-ui/core/Tab';
|
|
85
|
+
import '@material-ui/core/Tabs';
|
|
96
86
|
import '@material-ui/core/Grid';
|
|
97
87
|
import '@material-ui/core/Step';
|
|
98
88
|
import '@material-ui/core/StepLabel';
|
|
99
89
|
import '@material-ui/core/Stepper';
|
|
100
90
|
import '@material-ui/icons/FiberManualRecord';
|
|
91
|
+
import '@material-ui/lab/TreeView';
|
|
92
|
+
import '@material-ui/icons/ChevronRight';
|
|
93
|
+
import '@material-ui/lab/TreeItem';
|
|
94
|
+
import '@material-ui/icons/Refresh';
|
|
95
|
+
import '@material-ui/icons/Save';
|
|
96
|
+
import '@codemirror/view';
|
|
97
|
+
import '@material-ui/core/Card';
|
|
98
|
+
import '@material-ui/core/CardActionArea';
|
|
99
|
+
import '@material-ui/core/CardContent';
|
|
100
|
+
import '@material-ui/core/Tooltip';
|
|
101
|
+
import '@material-ui/icons/InfoOutlined';
|
|
101
102
|
|
|
102
|
-
const useStyles$
|
|
103
|
+
const useStyles$5 = makeStyles((theme) => ({
|
|
103
104
|
cardHeader: {
|
|
104
105
|
position: "relative"
|
|
105
106
|
},
|
|
@@ -189,7 +190,7 @@ const TemplateCard = ({ template, deprecated }) => {
|
|
|
189
190
|
);
|
|
190
191
|
const themeId = backstageTheme.getPageTheme({ themeId: templateProps.type }) ? templateProps.type : "other";
|
|
191
192
|
const theme = backstageTheme.getPageTheme({ themeId });
|
|
192
|
-
const classes = useStyles$
|
|
193
|
+
const classes = useStyles$5({ backgroundImage: theme.backgroundImage });
|
|
193
194
|
const { name, namespace } = parseEntityRef(stringifyEntityRef(template));
|
|
194
195
|
const href = templateRoute({ templateName: name, namespace });
|
|
195
196
|
const viewTechDoc = useRouteRef(viewTechDocRouteRef);
|
|
@@ -301,13 +302,13 @@ const TemplateList = ({
|
|
|
301
302
|
)))));
|
|
302
303
|
};
|
|
303
304
|
|
|
304
|
-
const useStyles$
|
|
305
|
+
const useStyles$4 = makeStyles$1({
|
|
305
306
|
button: {
|
|
306
307
|
color: "white"
|
|
307
308
|
}
|
|
308
309
|
});
|
|
309
310
|
function ScaffolderPageContextMenu(props) {
|
|
310
|
-
const classes = useStyles$
|
|
311
|
+
const classes = useStyles$4();
|
|
311
312
|
const [anchorEl, setAnchorEl] = useState();
|
|
312
313
|
const editLink = useRouteRef(editRouteRef);
|
|
313
314
|
const actionsLink = useRouteRef(actionsRouteRef);
|
|
@@ -716,6 +717,9 @@ const MultistepJsonForm = (props) => {
|
|
|
716
717
|
function isObject(obj) {
|
|
717
718
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
718
719
|
}
|
|
720
|
+
function isArray(obj) {
|
|
721
|
+
return typeof obj === "object" && obj !== null && Array.isArray(obj);
|
|
722
|
+
}
|
|
719
723
|
const createValidator = (rootSchema, validators, context) => {
|
|
720
724
|
function validate(schema, formData, errors) {
|
|
721
725
|
const schemaProps = schema.properties;
|
|
@@ -726,8 +730,8 @@ const createValidator = (rootSchema, validators, context) => {
|
|
|
726
730
|
if (schemaProps) {
|
|
727
731
|
for (const [key, propData] of Object.entries(formData)) {
|
|
728
732
|
const propValidation = errors[key];
|
|
733
|
+
const propSchemaProps = schemaProps[key];
|
|
729
734
|
if (isObject(propData)) {
|
|
730
|
-
const propSchemaProps = schemaProps[key];
|
|
731
735
|
if (isObject(propSchemaProps)) {
|
|
732
736
|
validate(
|
|
733
737
|
propSchemaProps,
|
|
@@ -735,9 +739,22 @@ const createValidator = (rootSchema, validators, context) => {
|
|
|
735
739
|
propValidation
|
|
736
740
|
);
|
|
737
741
|
}
|
|
742
|
+
} else if (isArray(propData)) {
|
|
743
|
+
if (isObject(propSchemaProps)) {
|
|
744
|
+
const { items } = propSchemaProps;
|
|
745
|
+
if (isObject(items)) {
|
|
746
|
+
const fieldName = items["ui:field"];
|
|
747
|
+
if (fieldName && typeof validators[fieldName] === "function") {
|
|
748
|
+
validators[fieldName](
|
|
749
|
+
propData,
|
|
750
|
+
propValidation,
|
|
751
|
+
context
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
738
756
|
} else {
|
|
739
|
-
const
|
|
740
|
-
const fieldName = isObject(propSchema) && propSchema["ui:field"];
|
|
757
|
+
const fieldName = isObject(propSchemaProps) && propSchemaProps["ui:field"];
|
|
741
758
|
if (fieldName && typeof validators[fieldName] === "function") {
|
|
742
759
|
validators[fieldName](
|
|
743
760
|
propData,
|
|
@@ -875,338 +892,7 @@ const TemplatePage = ({
|
|
|
875
892
|
))));
|
|
876
893
|
};
|
|
877
894
|
|
|
878
|
-
const
|
|
879
|
-
class WebFileAccess {
|
|
880
|
-
constructor(path, handle) {
|
|
881
|
-
this.path = path;
|
|
882
|
-
this.handle = handle;
|
|
883
|
-
}
|
|
884
|
-
file() {
|
|
885
|
-
return this.handle.getFile();
|
|
886
|
-
}
|
|
887
|
-
async save(data) {
|
|
888
|
-
const writable = await this.handle.createWritable();
|
|
889
|
-
await writable.write(data);
|
|
890
|
-
await writable.close();
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
class WebDirectoryAccess {
|
|
894
|
-
constructor(handle) {
|
|
895
|
-
this.handle = handle;
|
|
896
|
-
}
|
|
897
|
-
async listFiles() {
|
|
898
|
-
const content = [];
|
|
899
|
-
for await (const entry of this.listDirectoryContents(this.handle)) {
|
|
900
|
-
content.push(entry);
|
|
901
|
-
}
|
|
902
|
-
return content;
|
|
903
|
-
}
|
|
904
|
-
async *listDirectoryContents(dirHandle, basePath = []) {
|
|
905
|
-
for await (const handle of dirHandle.values()) {
|
|
906
|
-
if (handle.kind === "file") {
|
|
907
|
-
yield new WebFileAccess([...basePath, handle.name].join("/"), handle);
|
|
908
|
-
} else if (handle.kind === "directory") {
|
|
909
|
-
if (handle.name === ".git") {
|
|
910
|
-
continue;
|
|
911
|
-
}
|
|
912
|
-
yield* this.listDirectoryContents(handle, [...basePath, handle.name]);
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
class WebFileSystemAccess {
|
|
918
|
-
static isSupported() {
|
|
919
|
-
return Boolean(showDirectoryPicker);
|
|
920
|
-
}
|
|
921
|
-
static async requestDirectoryAccess() {
|
|
922
|
-
if (!showDirectoryPicker) {
|
|
923
|
-
throw new Error("File system access is not supported");
|
|
924
|
-
}
|
|
925
|
-
const handle = await showDirectoryPicker();
|
|
926
|
-
return new WebDirectoryAccess(handle);
|
|
927
|
-
}
|
|
928
|
-
constructor() {
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
var __accessCheck = (obj, member, msg) => {
|
|
933
|
-
if (!member.has(obj))
|
|
934
|
-
throw TypeError("Cannot " + msg);
|
|
935
|
-
};
|
|
936
|
-
var __privateGet = (obj, member, getter) => {
|
|
937
|
-
__accessCheck(obj, member, "read from private field");
|
|
938
|
-
return getter ? getter.call(obj) : member.get(obj);
|
|
939
|
-
};
|
|
940
|
-
var __privateAdd = (obj, member, value) => {
|
|
941
|
-
if (member.has(obj))
|
|
942
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
943
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
944
|
-
};
|
|
945
|
-
var __privateSet = (obj, member, value, setter) => {
|
|
946
|
-
__accessCheck(obj, member, "write to private field");
|
|
947
|
-
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
948
|
-
return value;
|
|
949
|
-
};
|
|
950
|
-
var _access, _signalUpdate, _content, _savedContent, _access2, _listeners, _files, _selectedFile, _signalUpdate2;
|
|
951
|
-
const MAX_SIZE = 1024 * 1024;
|
|
952
|
-
const MAX_SIZE_MESSAGE = "This file is too large to be displayed";
|
|
953
|
-
class DirectoryEditorFileManager {
|
|
954
|
-
constructor(access, signalUpdate) {
|
|
955
|
-
__privateAdd(this, _access, void 0);
|
|
956
|
-
__privateAdd(this, _signalUpdate, void 0);
|
|
957
|
-
__privateAdd(this, _content, void 0);
|
|
958
|
-
__privateAdd(this, _savedContent, void 0);
|
|
959
|
-
__privateSet(this, _access, access);
|
|
960
|
-
__privateSet(this, _signalUpdate, signalUpdate);
|
|
961
|
-
}
|
|
962
|
-
get path() {
|
|
963
|
-
return __privateGet(this, _access).path;
|
|
964
|
-
}
|
|
965
|
-
get content() {
|
|
966
|
-
var _a;
|
|
967
|
-
return (_a = __privateGet(this, _content)) != null ? _a : MAX_SIZE_MESSAGE;
|
|
968
|
-
}
|
|
969
|
-
updateContent(content) {
|
|
970
|
-
if (__privateGet(this, _content) === void 0) {
|
|
971
|
-
return;
|
|
972
|
-
}
|
|
973
|
-
__privateSet(this, _content, content);
|
|
974
|
-
__privateGet(this, _signalUpdate).call(this);
|
|
975
|
-
}
|
|
976
|
-
get dirty() {
|
|
977
|
-
return __privateGet(this, _content) !== __privateGet(this, _savedContent);
|
|
978
|
-
}
|
|
979
|
-
async save() {
|
|
980
|
-
if (__privateGet(this, _content) !== void 0) {
|
|
981
|
-
await __privateGet(this, _access).save(__privateGet(this, _content));
|
|
982
|
-
__privateSet(this, _savedContent, __privateGet(this, _content));
|
|
983
|
-
__privateGet(this, _signalUpdate).call(this);
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
async reload() {
|
|
987
|
-
const file = await __privateGet(this, _access).file();
|
|
988
|
-
if (file.size > MAX_SIZE) {
|
|
989
|
-
if (__privateGet(this, _content) !== void 0) {
|
|
990
|
-
__privateSet(this, _content, void 0);
|
|
991
|
-
__privateSet(this, _savedContent, void 0);
|
|
992
|
-
__privateGet(this, _signalUpdate).call(this);
|
|
993
|
-
}
|
|
994
|
-
return;
|
|
995
|
-
}
|
|
996
|
-
const content = await file.text();
|
|
997
|
-
if (__privateGet(this, _content) !== content) {
|
|
998
|
-
__privateSet(this, _content, content);
|
|
999
|
-
__privateSet(this, _savedContent, content);
|
|
1000
|
-
__privateGet(this, _signalUpdate).call(this);
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
_access = new WeakMap();
|
|
1005
|
-
_signalUpdate = new WeakMap();
|
|
1006
|
-
_content = new WeakMap();
|
|
1007
|
-
_savedContent = new WeakMap();
|
|
1008
|
-
class DirectoryEditorManager {
|
|
1009
|
-
constructor(access) {
|
|
1010
|
-
__privateAdd(this, _access2, void 0);
|
|
1011
|
-
__privateAdd(this, _listeners, /* @__PURE__ */ new Set());
|
|
1012
|
-
__privateAdd(this, _files, []);
|
|
1013
|
-
__privateAdd(this, _selectedFile, void 0);
|
|
1014
|
-
this.setSelectedFile = (path) => {
|
|
1015
|
-
const prev = __privateGet(this, _selectedFile);
|
|
1016
|
-
const next = __privateGet(this, _files).find((file) => file.path === path);
|
|
1017
|
-
if (prev !== next) {
|
|
1018
|
-
__privateSet(this, _selectedFile, next);
|
|
1019
|
-
__privateGet(this, _signalUpdate2).call(this);
|
|
1020
|
-
}
|
|
1021
|
-
};
|
|
1022
|
-
__privateAdd(this, _signalUpdate2, () => {
|
|
1023
|
-
__privateGet(this, _listeners).forEach((listener) => listener());
|
|
1024
|
-
});
|
|
1025
|
-
__privateSet(this, _access2, access);
|
|
1026
|
-
}
|
|
1027
|
-
get files() {
|
|
1028
|
-
return __privateGet(this, _files);
|
|
1029
|
-
}
|
|
1030
|
-
get selectedFile() {
|
|
1031
|
-
return __privateGet(this, _selectedFile);
|
|
1032
|
-
}
|
|
1033
|
-
get dirty() {
|
|
1034
|
-
return __privateGet(this, _files).some((file) => file.dirty);
|
|
1035
|
-
}
|
|
1036
|
-
async save() {
|
|
1037
|
-
await Promise.all(__privateGet(this, _files).map((file) => file.save()));
|
|
1038
|
-
}
|
|
1039
|
-
async reload() {
|
|
1040
|
-
var _a;
|
|
1041
|
-
const selectedPath = (_a = __privateGet(this, _selectedFile)) == null ? void 0 : _a.path;
|
|
1042
|
-
const files = await __privateGet(this, _access2).listFiles();
|
|
1043
|
-
const fileManagers = await Promise.all(
|
|
1044
|
-
files.map(async (file) => {
|
|
1045
|
-
const manager = new DirectoryEditorFileManager(
|
|
1046
|
-
file,
|
|
1047
|
-
__privateGet(this, _signalUpdate2)
|
|
1048
|
-
);
|
|
1049
|
-
await manager.reload();
|
|
1050
|
-
return manager;
|
|
1051
|
-
})
|
|
1052
|
-
);
|
|
1053
|
-
__privateGet(this, _files).length = 0;
|
|
1054
|
-
__privateGet(this, _files).push(...fileManagers);
|
|
1055
|
-
this.setSelectedFile(selectedPath);
|
|
1056
|
-
__privateGet(this, _signalUpdate2).call(this);
|
|
1057
|
-
}
|
|
1058
|
-
subscribe(listener) {
|
|
1059
|
-
__privateGet(this, _listeners).add(listener);
|
|
1060
|
-
return () => {
|
|
1061
|
-
__privateGet(this, _listeners).delete(listener);
|
|
1062
|
-
};
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
_access2 = new WeakMap();
|
|
1066
|
-
_listeners = new WeakMap();
|
|
1067
|
-
_files = new WeakMap();
|
|
1068
|
-
_selectedFile = new WeakMap();
|
|
1069
|
-
_signalUpdate2 = new WeakMap();
|
|
1070
|
-
const DirectoryEditorContext = createContext(
|
|
1071
|
-
void 0
|
|
1072
|
-
);
|
|
1073
|
-
function useDirectoryEditor() {
|
|
1074
|
-
const value = useContext(DirectoryEditorContext);
|
|
1075
|
-
const rerender = useRerender();
|
|
1076
|
-
useEffect(() => value == null ? void 0 : value.subscribe(rerender), [value, rerender]);
|
|
1077
|
-
if (!value) {
|
|
1078
|
-
throw new Error("must be used within a DirectoryEditorProvider");
|
|
1079
|
-
}
|
|
1080
|
-
return value;
|
|
1081
|
-
}
|
|
1082
|
-
function DirectoryEditorProvider(props) {
|
|
1083
|
-
const { directory } = props;
|
|
1084
|
-
const [{ result, error }, { execute }] = useAsync$1(
|
|
1085
|
-
async (dir) => {
|
|
1086
|
-
const manager = new DirectoryEditorManager(dir);
|
|
1087
|
-
await manager.reload();
|
|
1088
|
-
const firstYaml = manager.files.find((file) => file.path.match(/\.ya?ml$/));
|
|
1089
|
-
if (firstYaml) {
|
|
1090
|
-
manager.setSelectedFile(firstYaml.path);
|
|
1091
|
-
}
|
|
1092
|
-
return manager;
|
|
1093
|
-
}
|
|
1094
|
-
);
|
|
1095
|
-
useEffect(() => {
|
|
1096
|
-
execute(directory);
|
|
1097
|
-
}, [execute, directory]);
|
|
1098
|
-
if (error) {
|
|
1099
|
-
return /* @__PURE__ */ React.createElement(ErrorPanel, { error });
|
|
1100
|
-
} else if (!result) {
|
|
1101
|
-
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
1102
|
-
}
|
|
1103
|
-
return /* @__PURE__ */ React.createElement(DirectoryEditorContext.Provider, { value: result }, props.children);
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
const MAX_CONTENT_SIZE = 64 * 1024;
|
|
1107
|
-
const CHUNK_SIZE = 32 * 1024;
|
|
1108
|
-
const DryRunContext = createContext(void 0);
|
|
1109
|
-
function base64EncodeContent(content) {
|
|
1110
|
-
if (content.length > MAX_CONTENT_SIZE) {
|
|
1111
|
-
return window.btoa("<file too large>");
|
|
1112
|
-
}
|
|
1113
|
-
try {
|
|
1114
|
-
return window.btoa(content);
|
|
1115
|
-
} catch {
|
|
1116
|
-
const decoder = new TextEncoder();
|
|
1117
|
-
const buffer = decoder.encode(content);
|
|
1118
|
-
const chunks = new Array();
|
|
1119
|
-
for (let offset = 0; offset < buffer.length; offset += CHUNK_SIZE) {
|
|
1120
|
-
chunks.push(
|
|
1121
|
-
String.fromCharCode(...buffer.slice(offset, offset + CHUNK_SIZE))
|
|
1122
|
-
);
|
|
1123
|
-
}
|
|
1124
|
-
return window.btoa(chunks.join(""));
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
function DryRunProvider(props) {
|
|
1128
|
-
const scaffolderApi = useApi(scaffolderApiRef);
|
|
1129
|
-
const [state, setState] = useState({
|
|
1130
|
-
results: [],
|
|
1131
|
-
selectedResult: void 0
|
|
1132
|
-
});
|
|
1133
|
-
const idRef = useRef(1);
|
|
1134
|
-
const selectResult = useCallback((id) => {
|
|
1135
|
-
setState((prevState) => {
|
|
1136
|
-
const result = prevState.results.find((r) => r.id === id);
|
|
1137
|
-
if (result === prevState.selectedResult) {
|
|
1138
|
-
return prevState;
|
|
1139
|
-
}
|
|
1140
|
-
return {
|
|
1141
|
-
results: prevState.results,
|
|
1142
|
-
selectedResult: result
|
|
1143
|
-
};
|
|
1144
|
-
});
|
|
1145
|
-
}, []);
|
|
1146
|
-
const deleteResult = useCallback((id) => {
|
|
1147
|
-
setState((prevState) => {
|
|
1148
|
-
var _a;
|
|
1149
|
-
const index = prevState.results.findIndex((r) => r.id === id);
|
|
1150
|
-
if (index === -1) {
|
|
1151
|
-
return prevState;
|
|
1152
|
-
}
|
|
1153
|
-
const newResults = prevState.results.slice();
|
|
1154
|
-
const [deleted] = newResults.splice(index, 1);
|
|
1155
|
-
return {
|
|
1156
|
-
results: newResults,
|
|
1157
|
-
selectedResult: ((_a = prevState.selectedResult) == null ? void 0 : _a.id) === deleted.id ? newResults[0] : prevState.selectedResult
|
|
1158
|
-
};
|
|
1159
|
-
});
|
|
1160
|
-
}, []);
|
|
1161
|
-
const execute = useCallback(
|
|
1162
|
-
async (options) => {
|
|
1163
|
-
if (!scaffolderApi.dryRun) {
|
|
1164
|
-
throw new Error("Scaffolder API does not support dry-run");
|
|
1165
|
-
}
|
|
1166
|
-
const parsed = yaml.parse(options.templateContent);
|
|
1167
|
-
const response = await scaffolderApi.dryRun({
|
|
1168
|
-
template: parsed,
|
|
1169
|
-
values: options.values,
|
|
1170
|
-
secrets: {},
|
|
1171
|
-
directoryContents: options.files.map((file) => ({
|
|
1172
|
-
path: file.path,
|
|
1173
|
-
base64Content: base64EncodeContent(file.content)
|
|
1174
|
-
}))
|
|
1175
|
-
});
|
|
1176
|
-
const result = {
|
|
1177
|
-
...response,
|
|
1178
|
-
id: idRef.current++
|
|
1179
|
-
};
|
|
1180
|
-
setState((prevState) => {
|
|
1181
|
-
var _a;
|
|
1182
|
-
return {
|
|
1183
|
-
results: [...prevState.results, result],
|
|
1184
|
-
selectedResult: (_a = prevState.selectedResult) != null ? _a : result
|
|
1185
|
-
};
|
|
1186
|
-
});
|
|
1187
|
-
},
|
|
1188
|
-
[scaffolderApi]
|
|
1189
|
-
);
|
|
1190
|
-
const dryRun = useMemo(
|
|
1191
|
-
() => ({
|
|
1192
|
-
...state,
|
|
1193
|
-
selectResult,
|
|
1194
|
-
deleteResult,
|
|
1195
|
-
execute
|
|
1196
|
-
}),
|
|
1197
|
-
[state, selectResult, deleteResult, execute]
|
|
1198
|
-
);
|
|
1199
|
-
return /* @__PURE__ */ React.createElement(DryRunContext.Provider, { value: dryRun }, props.children);
|
|
1200
|
-
}
|
|
1201
|
-
function useDryRun() {
|
|
1202
|
-
const value = useContext(DryRunContext);
|
|
1203
|
-
if (!value) {
|
|
1204
|
-
throw new Error("must be used within a DryRunProvider");
|
|
1205
|
-
}
|
|
1206
|
-
return value;
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
const useStyles$b = makeStyles$1({
|
|
895
|
+
const useStyles$3 = makeStyles$1({
|
|
1210
896
|
containerWrapper: {
|
|
1211
897
|
position: "relative",
|
|
1212
898
|
width: "100%",
|
|
@@ -1255,7 +941,7 @@ function TemplateEditorForm(props) {
|
|
|
1255
941
|
fieldExtensions = [],
|
|
1256
942
|
layouts = []
|
|
1257
943
|
} = props;
|
|
1258
|
-
const classes = useStyles$
|
|
944
|
+
const classes = useStyles$3();
|
|
1259
945
|
const apiHolder = useApiHolder();
|
|
1260
946
|
const [steps, setSteps] = useState();
|
|
1261
947
|
const fields = useMemo(() => {
|
|
@@ -1370,7 +1056,7 @@ function TemplateEditorFormDirectoryEditorDryRun(props) {
|
|
|
1370
1056
|
TemplateEditorForm.DirectoryEditorDryRun = TemplateEditorFormDirectoryEditorDryRun;
|
|
1371
1057
|
|
|
1372
1058
|
const Form = withTheme(Theme);
|
|
1373
|
-
const useStyles$
|
|
1059
|
+
const useStyles$2 = makeStyles((theme) => ({
|
|
1374
1060
|
root: {
|
|
1375
1061
|
gridArea: "pageContent",
|
|
1376
1062
|
display: "grid",
|
|
@@ -1400,7 +1086,7 @@ const CustomFieldExplorer = ({
|
|
|
1400
1086
|
onClose
|
|
1401
1087
|
}) => {
|
|
1402
1088
|
var _a, _b;
|
|
1403
|
-
const classes = useStyles$
|
|
1089
|
+
const classes = useStyles$2();
|
|
1404
1090
|
const fieldOptions = customFieldExtensions.filter((field) => !!field.schema);
|
|
1405
1091
|
const [selectedField, setSelectedField] = useState(fieldOptions[0]);
|
|
1406
1092
|
const [fieldFormState, setFieldFormState] = useState({});
|
|
@@ -1500,589 +1186,6 @@ const CustomFieldExplorer = ({
|
|
|
1500
1186
|
)));
|
|
1501
1187
|
};
|
|
1502
1188
|
|
|
1503
|
-
const useStyles$9 = makeStyles$1((theme) => ({
|
|
1504
|
-
introText: {
|
|
1505
|
-
textAlign: "center",
|
|
1506
|
-
marginTop: theme.spacing(2)
|
|
1507
|
-
},
|
|
1508
|
-
card: {
|
|
1509
|
-
position: "relative",
|
|
1510
|
-
maxWidth: 340,
|
|
1511
|
-
marginTop: theme.spacing(4),
|
|
1512
|
-
margin: theme.spacing(0, 2)
|
|
1513
|
-
},
|
|
1514
|
-
infoIcon: {
|
|
1515
|
-
position: "absolute",
|
|
1516
|
-
top: theme.spacing(1),
|
|
1517
|
-
right: theme.spacing(1)
|
|
1518
|
-
}
|
|
1519
|
-
}));
|
|
1520
|
-
function TemplateEditorIntro(props) {
|
|
1521
|
-
const classes = useStyles$9();
|
|
1522
|
-
const supportsLoad = WebFileSystemAccess.isSupported();
|
|
1523
|
-
const cardLoadLocal = /* @__PURE__ */ React.createElement(Card$1, { className: classes.card, elevation: 4 }, /* @__PURE__ */ React.createElement(
|
|
1524
|
-
CardActionArea,
|
|
1525
|
-
{
|
|
1526
|
-
disabled: !supportsLoad,
|
|
1527
|
-
onClick: () => {
|
|
1528
|
-
var _a;
|
|
1529
|
-
return (_a = props.onSelect) == null ? void 0 : _a.call(props, "local");
|
|
1530
|
-
}
|
|
1531
|
-
},
|
|
1532
|
-
/* @__PURE__ */ React.createElement(CardContent$1, null, /* @__PURE__ */ React.createElement(
|
|
1533
|
-
Typography$1,
|
|
1534
|
-
{
|
|
1535
|
-
variant: "h5",
|
|
1536
|
-
gutterBottom: true,
|
|
1537
|
-
color: supportsLoad ? void 0 : "textSecondary",
|
|
1538
|
-
style: { display: "flex", flexFlow: "row nowrap" }
|
|
1539
|
-
},
|
|
1540
|
-
"Load Template Directory"
|
|
1541
|
-
), /* @__PURE__ */ React.createElement(
|
|
1542
|
-
Typography$1,
|
|
1543
|
-
{
|
|
1544
|
-
variant: "body1",
|
|
1545
|
-
color: supportsLoad ? void 0 : "textSecondary"
|
|
1546
|
-
},
|
|
1547
|
-
"Load a local template directory, allowing you to both edit and try executing your own template."
|
|
1548
|
-
))
|
|
1549
|
-
), !supportsLoad && /* @__PURE__ */ React.createElement("div", { className: classes.infoIcon }, /* @__PURE__ */ React.createElement(
|
|
1550
|
-
Tooltip$1,
|
|
1551
|
-
{
|
|
1552
|
-
placement: "top",
|
|
1553
|
-
title: "Only supported in some Chromium-based browsers"
|
|
1554
|
-
},
|
|
1555
|
-
/* @__PURE__ */ React.createElement(InfoOutlinedIcon, null)
|
|
1556
|
-
)));
|
|
1557
|
-
const cardFormEditor = /* @__PURE__ */ React.createElement(Card$1, { className: classes.card, elevation: 4 }, /* @__PURE__ */ React.createElement(CardActionArea, { onClick: () => {
|
|
1558
|
-
var _a;
|
|
1559
|
-
return (_a = props.onSelect) == null ? void 0 : _a.call(props, "form");
|
|
1560
|
-
} }, /* @__PURE__ */ React.createElement(CardContent$1, null, /* @__PURE__ */ React.createElement(Typography$1, { variant: "h5", gutterBottom: true }, "Edit Template Form"), /* @__PURE__ */ React.createElement(Typography$1, { variant: "body1" }, "Preview and edit a template form, either using a sample template or by loading a template from the catalog."))));
|
|
1561
|
-
const cardFieldExplorer = /* @__PURE__ */ React.createElement(Card$1, { className: classes.card, elevation: 4 }, /* @__PURE__ */ React.createElement(CardActionArea, { onClick: () => {
|
|
1562
|
-
var _a;
|
|
1563
|
-
return (_a = props.onSelect) == null ? void 0 : _a.call(props, "field-explorer");
|
|
1564
|
-
} }, /* @__PURE__ */ React.createElement(CardContent$1, null, /* @__PURE__ */ React.createElement(Typography$1, { variant: "h5", gutterBottom: true }, "Custom Field Explorer"), /* @__PURE__ */ React.createElement(Typography$1, { variant: "body1" }, "View and play around with available installed custom field extensions."))));
|
|
1565
|
-
return /* @__PURE__ */ React.createElement("div", { style: props.style }, /* @__PURE__ */ React.createElement(Typography$1, { variant: "h6", className: classes.introText }, "Get started by choosing one of the options below"), /* @__PURE__ */ React.createElement(
|
|
1566
|
-
"div",
|
|
1567
|
-
{
|
|
1568
|
-
style: {
|
|
1569
|
-
display: "flex",
|
|
1570
|
-
flexFlow: "row wrap",
|
|
1571
|
-
alignItems: "flex-start",
|
|
1572
|
-
justifyContent: "center",
|
|
1573
|
-
alignContent: "flex-start"
|
|
1574
|
-
}
|
|
1575
|
-
},
|
|
1576
|
-
supportsLoad && cardLoadLocal,
|
|
1577
|
-
cardFormEditor,
|
|
1578
|
-
!supportsLoad && cardLoadLocal,
|
|
1579
|
-
cardFieldExplorer
|
|
1580
|
-
));
|
|
1581
|
-
}
|
|
1582
|
-
|
|
1583
|
-
const useStyles$8 = makeStyles$1((theme) => ({
|
|
1584
|
-
root: {
|
|
1585
|
-
overflowY: "auto",
|
|
1586
|
-
background: theme.palette.background.default
|
|
1587
|
-
},
|
|
1588
|
-
iconSuccess: {
|
|
1589
|
-
minWidth: 0,
|
|
1590
|
-
marginRight: theme.spacing(1),
|
|
1591
|
-
color: theme.palette.status.ok
|
|
1592
|
-
},
|
|
1593
|
-
iconFailure: {
|
|
1594
|
-
minWidth: 0,
|
|
1595
|
-
marginRight: theme.spacing(1),
|
|
1596
|
-
color: theme.palette.status.error
|
|
1597
|
-
}
|
|
1598
|
-
}));
|
|
1599
|
-
function DryRunResultsList() {
|
|
1600
|
-
const classes = useStyles$8();
|
|
1601
|
-
const dryRun = useDryRun();
|
|
1602
|
-
return /* @__PURE__ */ React.createElement(List$1, { className: classes.root, dense: true }, dryRun.results.map((result) => {
|
|
1603
|
-
var _a;
|
|
1604
|
-
const failed = result.log.some((l) => l.body.status === "failed");
|
|
1605
|
-
return /* @__PURE__ */ React.createElement(
|
|
1606
|
-
ListItem,
|
|
1607
|
-
{
|
|
1608
|
-
button: true,
|
|
1609
|
-
key: result.id,
|
|
1610
|
-
selected: ((_a = dryRun.selectedResult) == null ? void 0 : _a.id) === result.id,
|
|
1611
|
-
onClick: () => dryRun.selectResult(result.id)
|
|
1612
|
-
},
|
|
1613
|
-
/* @__PURE__ */ React.createElement(
|
|
1614
|
-
ListItemIcon,
|
|
1615
|
-
{
|
|
1616
|
-
className: failed ? classes.iconFailure : classes.iconSuccess
|
|
1617
|
-
},
|
|
1618
|
-
failed ? /* @__PURE__ */ React.createElement(Cancel, null) : /* @__PURE__ */ React.createElement(Check, null)
|
|
1619
|
-
),
|
|
1620
|
-
/* @__PURE__ */ React.createElement(ListItemText, { primary: `Result ${result.id}` }),
|
|
1621
|
-
/* @__PURE__ */ React.createElement(ListItemSecondaryAction, null, /* @__PURE__ */ React.createElement(
|
|
1622
|
-
IconButton$1,
|
|
1623
|
-
{
|
|
1624
|
-
edge: "end",
|
|
1625
|
-
"aria-label": "delete",
|
|
1626
|
-
onClick: () => dryRun.deleteResult(result.id)
|
|
1627
|
-
},
|
|
1628
|
-
/* @__PURE__ */ React.createElement(DeleteIcon, null)
|
|
1629
|
-
))
|
|
1630
|
-
);
|
|
1631
|
-
}));
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
const useStyles$7 = makeStyles$1({
|
|
1635
|
-
root: {
|
|
1636
|
-
whiteSpace: "nowrap",
|
|
1637
|
-
overflowY: "auto"
|
|
1638
|
-
}
|
|
1639
|
-
});
|
|
1640
|
-
function parseFileEntires(paths) {
|
|
1641
|
-
const root = {
|
|
1642
|
-
type: "directory",
|
|
1643
|
-
name: "",
|
|
1644
|
-
path: "",
|
|
1645
|
-
children: []
|
|
1646
|
-
};
|
|
1647
|
-
for (const path of paths.slice().sort()) {
|
|
1648
|
-
const parts = path.split("/");
|
|
1649
|
-
let current = root;
|
|
1650
|
-
for (let i = 0; i < parts.length; i++) {
|
|
1651
|
-
const part = parts[i];
|
|
1652
|
-
if (part === "") {
|
|
1653
|
-
throw new Error(`Invalid path part: ''`);
|
|
1654
|
-
}
|
|
1655
|
-
const entryPath = parts.slice(0, i + 1).join("/");
|
|
1656
|
-
const existing = current.children.find((child) => child.name === part);
|
|
1657
|
-
if ((existing == null ? void 0 : existing.type) === "file") {
|
|
1658
|
-
throw new Error(`Duplicate filename at '${entryPath}'`);
|
|
1659
|
-
} else if (existing) {
|
|
1660
|
-
current = existing;
|
|
1661
|
-
} else {
|
|
1662
|
-
if (i < parts.length - 1) {
|
|
1663
|
-
const newEntry = {
|
|
1664
|
-
type: "directory",
|
|
1665
|
-
name: part,
|
|
1666
|
-
path: entryPath,
|
|
1667
|
-
children: []
|
|
1668
|
-
};
|
|
1669
|
-
const firstFileIndex = current.children.findIndex(
|
|
1670
|
-
(child) => child.type === "file"
|
|
1671
|
-
);
|
|
1672
|
-
current.children.splice(firstFileIndex, 0, newEntry);
|
|
1673
|
-
current = newEntry;
|
|
1674
|
-
} else {
|
|
1675
|
-
current.children.push({
|
|
1676
|
-
type: "file",
|
|
1677
|
-
name: part,
|
|
1678
|
-
path: entryPath
|
|
1679
|
-
});
|
|
1680
|
-
}
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
return root.children;
|
|
1685
|
-
}
|
|
1686
|
-
function FileTreeItem({ entry }) {
|
|
1687
|
-
if (entry.type === "file") {
|
|
1688
|
-
return /* @__PURE__ */ React.createElement(TreeItem, { nodeId: entry.path, label: entry.name });
|
|
1689
|
-
}
|
|
1690
|
-
return /* @__PURE__ */ React.createElement(TreeItem, { nodeId: entry.path, label: entry.name }, entry.children.map((child) => /* @__PURE__ */ React.createElement(FileTreeItem, { key: child.path, entry: child })));
|
|
1691
|
-
}
|
|
1692
|
-
function FileBrowser(props) {
|
|
1693
|
-
const classes = useStyles$7();
|
|
1694
|
-
const fileTree = useMemo(
|
|
1695
|
-
() => parseFileEntires(props.filePaths),
|
|
1696
|
-
[props.filePaths]
|
|
1697
|
-
);
|
|
1698
|
-
return /* @__PURE__ */ React.createElement(
|
|
1699
|
-
TreeView,
|
|
1700
|
-
{
|
|
1701
|
-
selected: props.selected,
|
|
1702
|
-
className: classes.root,
|
|
1703
|
-
defaultCollapseIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null),
|
|
1704
|
-
defaultExpandIcon: /* @__PURE__ */ React.createElement(ChevronRightIcon, null),
|
|
1705
|
-
onNodeSelect: (_e, nodeId) => {
|
|
1706
|
-
if (props.onSelect && props.filePaths.includes(nodeId)) {
|
|
1707
|
-
props.onSelect(nodeId);
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
},
|
|
1711
|
-
fileTree.map((entry) => /* @__PURE__ */ React.createElement(FileTreeItem, { key: entry.path, entry }))
|
|
1712
|
-
);
|
|
1713
|
-
}
|
|
1714
|
-
|
|
1715
|
-
const useStyles$6 = makeStyles$1((theme) => ({
|
|
1716
|
-
root: {
|
|
1717
|
-
display: "grid",
|
|
1718
|
-
gridTemplateColumns: "280px auto 3fr",
|
|
1719
|
-
gridTemplateRows: "1fr"
|
|
1720
|
-
},
|
|
1721
|
-
child: {
|
|
1722
|
-
overflowY: "auto",
|
|
1723
|
-
height: "100%",
|
|
1724
|
-
minHeight: 0
|
|
1725
|
-
},
|
|
1726
|
-
firstChild: {
|
|
1727
|
-
background: theme.palette.background.paper
|
|
1728
|
-
}
|
|
1729
|
-
}));
|
|
1730
|
-
function DryRunResultsSplitView(props) {
|
|
1731
|
-
const classes = useStyles$6();
|
|
1732
|
-
const childArray = Children.toArray(props.children);
|
|
1733
|
-
if (childArray.length !== 2) {
|
|
1734
|
-
throw new Error("must have exactly 2 children");
|
|
1735
|
-
}
|
|
1736
|
-
return /* @__PURE__ */ React.createElement("div", { className: classes.root }, /* @__PURE__ */ React.createElement("div", { className: classNames(classes.child, classes.firstChild) }, childArray[0]), /* @__PURE__ */ React.createElement(Divider, { orientation: "horizontal" }), /* @__PURE__ */ React.createElement("div", { className: classes.child }, childArray[1]));
|
|
1737
|
-
}
|
|
1738
|
-
|
|
1739
|
-
const useStyles$5 = makeStyles$1({
|
|
1740
|
-
root: {
|
|
1741
|
-
display: "flex",
|
|
1742
|
-
flexFlow: "column nowrap"
|
|
1743
|
-
},
|
|
1744
|
-
contentWrapper: {
|
|
1745
|
-
flex: 1,
|
|
1746
|
-
position: "relative"
|
|
1747
|
-
},
|
|
1748
|
-
content: {
|
|
1749
|
-
position: "absolute",
|
|
1750
|
-
top: 0,
|
|
1751
|
-
left: 0,
|
|
1752
|
-
right: 0,
|
|
1753
|
-
bottom: 0,
|
|
1754
|
-
display: "flex",
|
|
1755
|
-
"& > *": {
|
|
1756
|
-
flex: 1
|
|
1757
|
-
}
|
|
1758
|
-
},
|
|
1759
|
-
codeMirror: {
|
|
1760
|
-
height: "100%",
|
|
1761
|
-
overflowY: "auto"
|
|
1762
|
-
}
|
|
1763
|
-
});
|
|
1764
|
-
function FilesContent() {
|
|
1765
|
-
const classes = useStyles$5();
|
|
1766
|
-
const { selectedResult } = useDryRun();
|
|
1767
|
-
const [selectedPath, setSelectedPath] = useState("");
|
|
1768
|
-
const selectedFile = selectedResult == null ? void 0 : selectedResult.directoryContents.find(
|
|
1769
|
-
(f) => f.path === selectedPath
|
|
1770
|
-
);
|
|
1771
|
-
useEffect(() => {
|
|
1772
|
-
if (selectedResult) {
|
|
1773
|
-
const [firstFile] = selectedResult.directoryContents;
|
|
1774
|
-
if (firstFile) {
|
|
1775
|
-
setSelectedPath(firstFile.path);
|
|
1776
|
-
} else {
|
|
1777
|
-
setSelectedPath("");
|
|
1778
|
-
}
|
|
1779
|
-
}
|
|
1780
|
-
return void 0;
|
|
1781
|
-
}, [selectedResult]);
|
|
1782
|
-
if (!selectedResult) {
|
|
1783
|
-
return null;
|
|
1784
|
-
}
|
|
1785
|
-
return /* @__PURE__ */ React.createElement(DryRunResultsSplitView, null, /* @__PURE__ */ React.createElement(
|
|
1786
|
-
FileBrowser,
|
|
1787
|
-
{
|
|
1788
|
-
selected: selectedPath,
|
|
1789
|
-
onSelect: setSelectedPath,
|
|
1790
|
-
filePaths: selectedResult.directoryContents.map((file) => file.path)
|
|
1791
|
-
}
|
|
1792
|
-
), /* @__PURE__ */ React.createElement(
|
|
1793
|
-
CodeMirror,
|
|
1794
|
-
{
|
|
1795
|
-
className: classes.codeMirror,
|
|
1796
|
-
theme: "dark",
|
|
1797
|
-
height: "100%",
|
|
1798
|
-
extensions: [StreamLanguage.define(yaml$1)],
|
|
1799
|
-
readOnly: true,
|
|
1800
|
-
value: (selectedFile == null ? void 0 : selectedFile.base64Content) ? atob(selectedFile.base64Content) : ""
|
|
1801
|
-
}
|
|
1802
|
-
));
|
|
1803
|
-
}
|
|
1804
|
-
function LogContent() {
|
|
1805
|
-
var _a, _b;
|
|
1806
|
-
const { selectedResult } = useDryRun();
|
|
1807
|
-
const [currentStepId, setUserSelectedStepId] = useState();
|
|
1808
|
-
const steps = useMemo(() => {
|
|
1809
|
-
var _a2;
|
|
1810
|
-
if (!selectedResult) {
|
|
1811
|
-
return [];
|
|
1812
|
-
}
|
|
1813
|
-
return (_a2 = selectedResult.steps.map((step) => {
|
|
1814
|
-
var _a3, _b2;
|
|
1815
|
-
const stepLog = selectedResult.log.filter(
|
|
1816
|
-
(l) => l.body.stepId === step.id
|
|
1817
|
-
);
|
|
1818
|
-
return {
|
|
1819
|
-
id: step.id,
|
|
1820
|
-
name: step.name,
|
|
1821
|
-
logString: stepLog.map((l) => l.body.message).join("\n"),
|
|
1822
|
-
status: (_b2 = (_a3 = stepLog[stepLog.length - 1]) == null ? void 0 : _a3.body.status) != null ? _b2 : "completed"
|
|
1823
|
-
};
|
|
1824
|
-
})) != null ? _a2 : [];
|
|
1825
|
-
}, [selectedResult]);
|
|
1826
|
-
if (!selectedResult) {
|
|
1827
|
-
return null;
|
|
1828
|
-
}
|
|
1829
|
-
const selectedStep = (_a = steps.find((s) => s.id === currentStepId)) != null ? _a : steps[0];
|
|
1830
|
-
return /* @__PURE__ */ React.createElement(DryRunResultsSplitView, null, /* @__PURE__ */ React.createElement(
|
|
1831
|
-
TaskStatusStepper,
|
|
1832
|
-
{
|
|
1833
|
-
steps,
|
|
1834
|
-
currentStepId: selectedStep.id,
|
|
1835
|
-
onUserStepChange: setUserSelectedStepId
|
|
1836
|
-
}
|
|
1837
|
-
), /* @__PURE__ */ React.createElement(LogViewer, { text: (_b = selectedStep == null ? void 0 : selectedStep.logString) != null ? _b : "" }));
|
|
1838
|
-
}
|
|
1839
|
-
function OutputContent() {
|
|
1840
|
-
var _a, _b;
|
|
1841
|
-
const classes = useStyles$5();
|
|
1842
|
-
const { selectedResult } = useDryRun();
|
|
1843
|
-
if (!selectedResult) {
|
|
1844
|
-
return null;
|
|
1845
|
-
}
|
|
1846
|
-
return /* @__PURE__ */ React.createElement(DryRunResultsSplitView, null, /* @__PURE__ */ React.createElement(Box$1, { pt: 2 }, ((_b = (_a = selectedResult.output) == null ? void 0 : _a.links) == null ? void 0 : _b.length) && /* @__PURE__ */ React.createElement(TaskPageLinks, { output: selectedResult.output })), /* @__PURE__ */ React.createElement(
|
|
1847
|
-
CodeMirror,
|
|
1848
|
-
{
|
|
1849
|
-
className: classes.codeMirror,
|
|
1850
|
-
theme: "dark",
|
|
1851
|
-
height: "100%",
|
|
1852
|
-
extensions: [StreamLanguage.define(yaml$1)],
|
|
1853
|
-
readOnly: true,
|
|
1854
|
-
value: JSON.stringify(selectedResult.output, null, 2)
|
|
1855
|
-
}
|
|
1856
|
-
));
|
|
1857
|
-
}
|
|
1858
|
-
function DryRunResultsView() {
|
|
1859
|
-
const classes = useStyles$5();
|
|
1860
|
-
const [selectedTab, setSelectedTab] = useState(
|
|
1861
|
-
"files"
|
|
1862
|
-
);
|
|
1863
|
-
return /* @__PURE__ */ React.createElement("div", { className: classes.root }, /* @__PURE__ */ React.createElement(Tabs, { value: selectedTab, onChange: (_, v) => setSelectedTab(v) }, /* @__PURE__ */ React.createElement(Tab, { value: "files", label: "Files" }), /* @__PURE__ */ React.createElement(Tab, { value: "log", label: "Log" }), /* @__PURE__ */ React.createElement(Tab, { value: "output", label: "Output" })), /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement("div", { className: classes.contentWrapper }, /* @__PURE__ */ React.createElement("div", { className: classes.content }, selectedTab === "files" && /* @__PURE__ */ React.createElement(FilesContent, null), selectedTab === "log" && /* @__PURE__ */ React.createElement(LogContent, null), selectedTab === "output" && /* @__PURE__ */ React.createElement(OutputContent, null))));
|
|
1864
|
-
}
|
|
1865
|
-
|
|
1866
|
-
const useStyles$4 = makeStyles$1((theme) => ({
|
|
1867
|
-
header: {
|
|
1868
|
-
height: 48,
|
|
1869
|
-
minHeight: 0,
|
|
1870
|
-
"&.Mui-expanded": {
|
|
1871
|
-
height: 48,
|
|
1872
|
-
minHeight: 0
|
|
1873
|
-
}
|
|
1874
|
-
},
|
|
1875
|
-
content: {
|
|
1876
|
-
display: "grid",
|
|
1877
|
-
background: theme.palette.background.default,
|
|
1878
|
-
gridTemplateColumns: "180px auto 1fr",
|
|
1879
|
-
gridTemplateRows: "1fr",
|
|
1880
|
-
padding: 0,
|
|
1881
|
-
height: 400
|
|
1882
|
-
}
|
|
1883
|
-
}));
|
|
1884
|
-
function DryRunResults() {
|
|
1885
|
-
const classes = useStyles$4();
|
|
1886
|
-
const dryRun = useDryRun();
|
|
1887
|
-
const [expanded, setExpanded] = useState(false);
|
|
1888
|
-
const [hidden, setHidden] = useState(true);
|
|
1889
|
-
const resultsLength = dryRun.results.length;
|
|
1890
|
-
const prevResultsLength = usePrevious(resultsLength);
|
|
1891
|
-
useEffect(() => {
|
|
1892
|
-
if (prevResultsLength === 0 && resultsLength === 1) {
|
|
1893
|
-
setHidden(false);
|
|
1894
|
-
setExpanded(true);
|
|
1895
|
-
} else if (prevResultsLength === 1 && resultsLength === 0) {
|
|
1896
|
-
setExpanded(false);
|
|
1897
|
-
}
|
|
1898
|
-
}, [prevResultsLength, resultsLength]);
|
|
1899
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
1900
|
-
Accordion,
|
|
1901
|
-
{
|
|
1902
|
-
variant: "outlined",
|
|
1903
|
-
expanded,
|
|
1904
|
-
hidden: resultsLength === 0 && hidden,
|
|
1905
|
-
onChange: (_, exp) => setExpanded(exp),
|
|
1906
|
-
onTransitionEnd: () => resultsLength === 0 && setHidden(true)
|
|
1907
|
-
},
|
|
1908
|
-
/* @__PURE__ */ React.createElement(
|
|
1909
|
-
AccordionSummary,
|
|
1910
|
-
{
|
|
1911
|
-
className: classes.header,
|
|
1912
|
-
expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon$1, null)
|
|
1913
|
-
},
|
|
1914
|
-
/* @__PURE__ */ React.createElement(Typography$1, null, "Dry-run results")
|
|
1915
|
-
),
|
|
1916
|
-
/* @__PURE__ */ React.createElement(Divider, { orientation: "horizontal" }),
|
|
1917
|
-
/* @__PURE__ */ React.createElement(AccordionDetails, { className: classes.content }, /* @__PURE__ */ React.createElement(DryRunResultsList, null), /* @__PURE__ */ React.createElement(Divider, { orientation: "horizontal" }), /* @__PURE__ */ React.createElement(DryRunResultsView, null))
|
|
1918
|
-
));
|
|
1919
|
-
}
|
|
1920
|
-
|
|
1921
|
-
const useStyles$3 = makeStyles((theme) => ({
|
|
1922
|
-
button: {
|
|
1923
|
-
padding: theme.spacing(1)
|
|
1924
|
-
},
|
|
1925
|
-
buttons: {
|
|
1926
|
-
display: "flex",
|
|
1927
|
-
flexFlow: "row nowrap",
|
|
1928
|
-
alignItems: "center",
|
|
1929
|
-
justifyContent: "flex-start"
|
|
1930
|
-
},
|
|
1931
|
-
buttonsGap: {
|
|
1932
|
-
flex: "1 1 auto"
|
|
1933
|
-
},
|
|
1934
|
-
buttonsDivider: {
|
|
1935
|
-
marginBottom: theme.spacing(1)
|
|
1936
|
-
}
|
|
1937
|
-
}));
|
|
1938
|
-
function TemplateEditorBrowser(props) {
|
|
1939
|
-
var _a, _b;
|
|
1940
|
-
const classes = useStyles$3();
|
|
1941
|
-
const directoryEditor = useDirectoryEditor();
|
|
1942
|
-
const changedFiles = directoryEditor.files.filter((file) => file.dirty);
|
|
1943
|
-
const handleClose = () => {
|
|
1944
|
-
if (!props.onClose) {
|
|
1945
|
-
return;
|
|
1946
|
-
}
|
|
1947
|
-
if (changedFiles.length > 0) {
|
|
1948
|
-
const accepted = window.confirm(
|
|
1949
|
-
"Are you sure? Unsaved changes will be lost"
|
|
1950
|
-
);
|
|
1951
|
-
if (!accepted) {
|
|
1952
|
-
return;
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
props.onClose();
|
|
1956
|
-
};
|
|
1957
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: classes.buttons }, /* @__PURE__ */ React.createElement(Tooltip, { title: "Save all files" }, /* @__PURE__ */ React.createElement(
|
|
1958
|
-
IconButton,
|
|
1959
|
-
{
|
|
1960
|
-
className: classes.button,
|
|
1961
|
-
disabled: directoryEditor.files.every((file) => !file.dirty),
|
|
1962
|
-
onClick: () => directoryEditor.save()
|
|
1963
|
-
},
|
|
1964
|
-
/* @__PURE__ */ React.createElement(SaveIcon, null)
|
|
1965
|
-
)), /* @__PURE__ */ React.createElement(Tooltip, { title: "Reload directory" }, /* @__PURE__ */ React.createElement(
|
|
1966
|
-
IconButton,
|
|
1967
|
-
{
|
|
1968
|
-
className: classes.button,
|
|
1969
|
-
onClick: () => directoryEditor.reload()
|
|
1970
|
-
},
|
|
1971
|
-
/* @__PURE__ */ React.createElement(RefreshIcon, null)
|
|
1972
|
-
)), /* @__PURE__ */ React.createElement("div", { className: classes.buttonsGap }), /* @__PURE__ */ React.createElement(Tooltip, { title: "Close directory" }, /* @__PURE__ */ React.createElement(IconButton, { className: classes.button, onClick: handleClose }, /* @__PURE__ */ React.createElement(CloseIcon, null)))), /* @__PURE__ */ React.createElement(Divider$1, { className: classes.buttonsDivider }), /* @__PURE__ */ React.createElement(
|
|
1973
|
-
FileBrowser,
|
|
1974
|
-
{
|
|
1975
|
-
selected: (_b = (_a = directoryEditor.selectedFile) == null ? void 0 : _a.path) != null ? _b : "",
|
|
1976
|
-
onSelect: directoryEditor.setSelectedFile,
|
|
1977
|
-
filePaths: directoryEditor.files.map((file) => file.path)
|
|
1978
|
-
}
|
|
1979
|
-
));
|
|
1980
|
-
}
|
|
1981
|
-
|
|
1982
|
-
const useStyles$2 = makeStyles((theme) => ({
|
|
1983
|
-
container: {
|
|
1984
|
-
position: "relative",
|
|
1985
|
-
width: "100%",
|
|
1986
|
-
height: "100%"
|
|
1987
|
-
},
|
|
1988
|
-
codeMirror: {
|
|
1989
|
-
position: "absolute",
|
|
1990
|
-
top: 0,
|
|
1991
|
-
bottom: 0,
|
|
1992
|
-
left: 0,
|
|
1993
|
-
right: 0
|
|
1994
|
-
},
|
|
1995
|
-
errorPanel: {
|
|
1996
|
-
color: theme.palette.error.main,
|
|
1997
|
-
lineHeight: 2,
|
|
1998
|
-
margin: theme.spacing(0, 1)
|
|
1999
|
-
},
|
|
2000
|
-
floatingButtons: {
|
|
2001
|
-
position: "absolute",
|
|
2002
|
-
top: theme.spacing(1),
|
|
2003
|
-
right: theme.spacing(3)
|
|
2004
|
-
},
|
|
2005
|
-
floatingButton: {
|
|
2006
|
-
padding: theme.spacing(1)
|
|
2007
|
-
}
|
|
2008
|
-
}));
|
|
2009
|
-
function TemplateEditorTextArea(props) {
|
|
2010
|
-
const { errorText } = props;
|
|
2011
|
-
const classes = useStyles$2();
|
|
2012
|
-
const panelExtension = useMemo(() => {
|
|
2013
|
-
if (!errorText) {
|
|
2014
|
-
return showPanel.of(null);
|
|
2015
|
-
}
|
|
2016
|
-
const dom = document.createElement("div");
|
|
2017
|
-
dom.classList.add(classes.errorPanel);
|
|
2018
|
-
dom.textContent = errorText;
|
|
2019
|
-
return showPanel.of(() => ({ dom, bottom: true }));
|
|
2020
|
-
}, [classes, errorText]);
|
|
2021
|
-
useKeyboardEvent(
|
|
2022
|
-
(e) => e.key === "s" && (e.ctrlKey || e.metaKey),
|
|
2023
|
-
(e) => {
|
|
2024
|
-
e.preventDefault();
|
|
2025
|
-
if (props.onSave) {
|
|
2026
|
-
props.onSave();
|
|
2027
|
-
}
|
|
2028
|
-
}
|
|
2029
|
-
);
|
|
2030
|
-
return /* @__PURE__ */ React.createElement("div", { className: classes.container }, /* @__PURE__ */ React.createElement(
|
|
2031
|
-
CodeMirror,
|
|
2032
|
-
{
|
|
2033
|
-
className: classes.codeMirror,
|
|
2034
|
-
theme: "dark",
|
|
2035
|
-
height: "100%",
|
|
2036
|
-
extensions: [StreamLanguage.define(yaml$1), panelExtension],
|
|
2037
|
-
value: props.content,
|
|
2038
|
-
onChange: props.onUpdate
|
|
2039
|
-
}
|
|
2040
|
-
), (props.onSave || props.onReload) && /* @__PURE__ */ React.createElement("div", { className: classes.floatingButtons }, /* @__PURE__ */ React.createElement(Paper, null, props.onSave && /* @__PURE__ */ React.createElement(Tooltip, { title: "Save file" }, /* @__PURE__ */ React.createElement(
|
|
2041
|
-
IconButton,
|
|
2042
|
-
{
|
|
2043
|
-
className: classes.floatingButton,
|
|
2044
|
-
onClick: () => {
|
|
2045
|
-
var _a;
|
|
2046
|
-
return (_a = props.onSave) == null ? void 0 : _a.call(props);
|
|
2047
|
-
}
|
|
2048
|
-
},
|
|
2049
|
-
/* @__PURE__ */ React.createElement(SaveIcon, null)
|
|
2050
|
-
)), props.onReload && /* @__PURE__ */ React.createElement(Tooltip, { title: "Reload file" }, /* @__PURE__ */ React.createElement(
|
|
2051
|
-
IconButton,
|
|
2052
|
-
{
|
|
2053
|
-
className: classes.floatingButton,
|
|
2054
|
-
onClick: () => {
|
|
2055
|
-
var _a;
|
|
2056
|
-
return (_a = props.onReload) == null ? void 0 : _a.call(props);
|
|
2057
|
-
}
|
|
2058
|
-
},
|
|
2059
|
-
/* @__PURE__ */ React.createElement(RefreshIcon, null)
|
|
2060
|
-
)))));
|
|
2061
|
-
}
|
|
2062
|
-
function TemplateEditorDirectoryEditorTextArea(props) {
|
|
2063
|
-
var _a, _b;
|
|
2064
|
-
const directoryEditor = useDirectoryEditor();
|
|
2065
|
-
const actions = ((_a = directoryEditor.selectedFile) == null ? void 0 : _a.dirty) ? {
|
|
2066
|
-
onSave: () => directoryEditor.save(),
|
|
2067
|
-
onReload: () => directoryEditor.reload()
|
|
2068
|
-
} : {
|
|
2069
|
-
onReload: () => directoryEditor.reload()
|
|
2070
|
-
};
|
|
2071
|
-
return /* @__PURE__ */ React.createElement(
|
|
2072
|
-
TemplateEditorTextArea,
|
|
2073
|
-
{
|
|
2074
|
-
errorText: props.errorText,
|
|
2075
|
-
content: (_b = directoryEditor.selectedFile) == null ? void 0 : _b.content,
|
|
2076
|
-
onUpdate: (content) => {
|
|
2077
|
-
var _a2;
|
|
2078
|
-
return (_a2 = directoryEditor.selectedFile) == null ? void 0 : _a2.updateContent(content);
|
|
2079
|
-
},
|
|
2080
|
-
...actions
|
|
2081
|
-
}
|
|
2082
|
-
);
|
|
2083
|
-
}
|
|
2084
|
-
TemplateEditorTextArea.DirectoryEditor = TemplateEditorDirectoryEditorTextArea;
|
|
2085
|
-
|
|
2086
1189
|
const useStyles$1 = makeStyles({
|
|
2087
1190
|
// Reset and fix sizing to make sure scrolling behaves correctly
|
|
2088
1191
|
root: {
|
|
@@ -2411,4 +1514,4 @@ const Router = (props) => {
|
|
|
2411
1514
|
};
|
|
2412
1515
|
|
|
2413
1516
|
export { Router };
|
|
2414
|
-
//# sourceMappingURL=Router-
|
|
1517
|
+
//# sourceMappingURL=Router-fae7a62f.esm.js.map
|