@parallelworks/ui 0.50.0 → 0.52.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/README.md +204 -18
- package/dist/ai/agent/toolStrings.d.ts +2 -0
- package/dist/ai/agent/toolStrings.js +20 -18
- package/dist/ai/ai.css +12 -0
- package/dist/ai/components/AllocationSelector.js +5 -1
- package/dist/ai/components/AttachmentManager.js +51 -42
- package/dist/ai/components/AttachmentUpload.d.ts +4 -2
- package/dist/ai/components/AttachmentUpload.js +9 -9
- package/dist/ai/components/BlockedGroupBanner.js +8 -14
- package/dist/ai/components/BranchNavigator.js +11 -12
- package/dist/ai/components/ChatEmptyState.js +12 -19
- package/dist/ai/components/ChatInput.d.ts +4 -3
- package/dist/ai/components/ChatInput.js +27 -13
- package/dist/ai/components/ChatMessage.js +45 -121
- package/dist/ai/components/ChatMessageList.d.ts +5 -2
- package/dist/ai/components/ChatMessageList.js +89 -51
- package/dist/ai/components/ChatSidebar.js +11 -7
- package/dist/ai/components/ChatThread.js +1 -13
- package/dist/ai/components/DragOverlay.js +3 -3
- package/dist/ai/components/MessageAttachments.d.ts +10 -0
- package/dist/ai/components/MessageAttachments.js +78 -0
- package/dist/ai/components/ModelSelector.js +4 -4
- package/dist/ai/components/PastedText.js +2 -2
- package/dist/ai/components/ProviderIssueBanner.js +19 -23
- package/dist/ai/components/ShareDialog.js +2 -2
- package/dist/ai/components/agent/ActivityLine.d.ts +0 -2
- package/dist/ai/components/agent/ActivityLine.js +8 -51
- package/dist/ai/components/agent/AgentMessageParts.js +117 -56
- package/dist/ai/core/ChatProvider.d.ts +16 -5
- package/dist/ai/core/ChatProvider.js +41 -8
- package/dist/ai/core/config.js +4 -3
- package/dist/ai/index.d.ts +1 -1
- package/dist/ai/index.js +3 -3
- package/dist/ai/strings.d.ts +29 -3
- package/dist/ai/strings.js +81 -26
- package/dist/ai/types.d.ts +4 -0
- package/dist/ai/ui/Notice.d.ts +2 -2
- package/dist/ai/ui/Notice.js +29 -62
- package/dist/ai/ui/sidebar.d.ts +5 -3
- package/dist/ai/ui/sidebar.js +21 -9
- package/dist/components/ActionMenu.d.ts +1 -0
- package/dist/components/ActionMenu.js +6 -1
- package/dist/components/AppLink.d.ts +26 -0
- package/dist/components/AppLink.js +51 -0
- package/dist/components/Avatar.d.ts +2 -1
- package/dist/components/Avatar.js +4 -2
- package/dist/components/Button.d.ts +15 -5
- package/dist/components/Button.js +47 -40
- package/dist/components/Callout.d.ts +31 -7
- package/dist/components/Callout.js +51 -24
- package/dist/components/Card.d.ts +11 -6
- package/dist/components/Card.js +14 -8
- package/dist/components/Checkbox.js +2 -1
- package/dist/components/ColorInput.js +5 -3
- package/dist/components/Combobox.js +49 -19
- package/dist/components/ConfirmModal.d.ts +19 -8
- package/dist/components/ConfirmModal.js +31 -53
- package/dist/components/CopyButton.d.ts +38 -0
- package/dist/components/CopyButton.js +68 -0
- package/dist/components/CreateModal.js +118 -111
- package/dist/components/DatePicker.js +12 -8
- package/dist/components/DescriptionList.d.ts +51 -17
- package/dist/components/DescriptionList.js +117 -31
- package/dist/components/Disclosure.js +1 -1
- package/dist/components/Drawer.js +10 -16
- package/dist/components/Field.d.ts +15 -5
- package/dist/components/Field.js +41 -9
- package/dist/components/IconButton.d.ts +14 -5
- package/dist/components/IconButton.js +25 -14
- package/dist/components/InfoTip.d.ts +4 -1
- package/dist/components/InfoTip.js +2 -1
- package/dist/components/Input.d.ts +14 -8
- package/dist/components/Input.js +46 -31
- package/dist/components/Loader.js +1 -1
- package/dist/components/MenuEntries.d.ts +43 -12
- package/dist/components/MenuEntries.js +34 -19
- package/dist/components/Meter.js +5 -4
- package/dist/components/Modal.d.ts +28 -4
- package/dist/components/Modal.js +37 -14
- package/dist/components/Overview.d.ts +20 -12
- package/dist/components/Overview.js +14 -9
- package/dist/components/PageHeader.d.ts +47 -65
- package/dist/components/PageHeader.js +275 -153
- package/dist/components/PageHeaderAction.d.ts +67 -0
- package/dist/components/PageHeaderAction.js +107 -0
- package/dist/components/Pagination.js +6 -16
- package/dist/components/Popover.js +3 -2
- package/dist/components/Provider.d.ts +79 -19
- package/dist/components/Provider.js +140 -130
- package/dist/components/Radio.js +2 -1
- package/dist/components/RefreshButton.js +7 -8
- package/dist/components/RequiredMark.js +1 -1
- package/dist/components/RunStatusIcon.js +2 -2
- package/dist/components/Section.js +1 -1
- package/dist/components/Select.d.ts +4 -9
- package/dist/components/Select.js +24 -11
- package/dist/components/SettingModeOption.d.ts +1 -1
- package/dist/components/SettingModeOption.js +7 -1
- package/dist/components/SettingsCard.d.ts +5 -3
- package/dist/components/SettingsCard.js +27 -20
- package/dist/components/Slider.js +1 -1
- package/dist/components/StatusBadge.js +2 -2
- package/dist/components/StatusIcons.js +2 -2
- package/dist/components/Switch.js +5 -4
- package/dist/components/Table.d.ts +30 -20
- package/dist/components/Table.js +50 -73
- package/dist/components/Tabs.d.ts +3 -7
- package/dist/components/Tabs.js +6 -10
- package/dist/components/ThemeEditor.js +24 -14
- package/dist/components/Toast.d.ts +11 -3
- package/dist/components/Toast.js +47 -22
- package/dist/components/buttonClasses.js +2 -2
- package/dist/components/comboboxItems.d.ts +4 -0
- package/dist/components/comboboxItems.js +6 -1
- package/dist/components/dismiss.d.ts +12 -0
- package/dist/components/dismiss.js +19 -0
- package/dist/components/fieldBox.d.ts +4 -0
- package/dist/components/fieldBox.js +7 -3
- package/dist/components/floating.d.ts +3 -3
- package/dist/components/floating.js +1 -1
- package/dist/components/markdownCodeBreaks.js +3 -4
- package/dist/components/pageHeaderStore.d.ts +41 -0
- package/dist/components/pageHeaderStore.js +67 -0
- package/dist/components/pathBreaks.d.ts +8 -0
- package/dist/components/pathBreaks.js +28 -0
- package/dist/components/segmented.js +1 -1
- package/dist/components/shortcutKey.d.ts +2 -1
- package/dist/components/shortcutKey.js +19 -2
- package/dist/components/splitter.js +1 -1
- package/dist/components/tone.d.ts +5 -2
- package/dist/components/tone.js +15 -6
- package/dist/components/useCssIsDark.js +40 -18
- package/dist/components/useTheme.js +9 -10
- package/dist/dev.d.ts +9 -0
- package/dist/dev.js +14 -0
- package/dist/editor/Editor.d.ts +3 -2
- package/dist/editor/Editor.js +11 -2
- package/dist/editor/EditorField.d.ts +2 -1
- package/dist/editor/EditorField.js +11 -29
- package/dist/editor/FormCodePanel.d.ts +7 -3
- package/dist/editor/FormCodePanel.js +14 -7
- package/dist/editor/Monaco.d.ts +14 -5
- package/dist/editor/Monaco.js +163 -112
- package/dist/editor/index.d.ts +5 -5
- package/dist/editor/index.js +3 -3
- package/dist/editor/themes.d.ts +8 -5
- package/dist/editor/themes.js +58 -30
- package/dist/editor/yaml.d.ts +6 -2
- package/dist/editor/yaml.js +11 -2
- package/dist/file-explorer/FileExplorer.js +143 -124
- package/dist/file-explorer/FileExplorerContext.js +1 -1
- package/dist/file-explorer/FilePreview/StreamedBadge.js +3 -1
- package/dist/file-explorer/FilePreview/Viewer.js +2 -2
- package/dist/file-explorer/FilePreview/index.js +4 -4
- package/dist/file-explorer/FileRow.js +1 -1
- package/dist/file-explorer/FileRowsWindow.js +34 -3
- package/dist/file-explorer/FileTable.js +3 -1
- package/dist/file-explorer/TreeView.js +37 -14
- package/dist/file-explorer/helpers.d.ts +2 -1
- package/dist/file-explorer/helpers.js +21 -20
- package/dist/file-explorer/toasts.js +27 -19
- package/dist/file-explorer/treeRows.d.ts +6 -0
- package/dist/file-explorer/treeRows.js +19 -1
- package/dist/file-explorer/useNearEnd.js +3 -6
- package/dist/form/Fields/CheckboxGroupField.js +12 -5
- package/dist/form/Fields/DurationField.js +1 -1
- package/dist/form/Fields/LabelField.js +1 -1
- package/dist/form/Fields/ObjectField.d.ts +1 -1
- package/dist/form/Fields/ObjectField.js +3 -2
- package/dist/form/Fields/StringField.js +16 -29
- package/dist/form/Fields/TextAreaField.js +3 -4
- package/dist/form/Form.js +3 -8
- package/dist/form/Wizard/WizardNavigation.js +1 -4
- package/dist/form/Wizard/WizardStepIndicator.js +1 -1
- package/dist/form/Wizard/utils.js +1 -1
- package/dist/form/fieldFrame.d.ts +1 -1
- package/dist/form/fieldFrame.js +2 -2
- package/dist/form/types/fieldComponentTypes.d.ts +2 -1
- package/dist/graph/AnnotationBanner.d.ts +1 -2
- package/dist/graph/AnnotationBanner.js +30 -32
- package/dist/graph/Connectors.js +4 -1
- package/dist/graph/DependencyGraph.js +2 -2
- package/dist/graph/GraphEditor.js +12 -10
- package/dist/graph/GraphEditorDialogs.js +2 -2
- package/dist/graph/GraphNode.js +7 -4
- package/dist/graph/InputDialog.js +1 -1
- package/dist/graph/InputsEditor.js +14 -11
- package/dist/graph/MatrixGroup.js +9 -3
- package/dist/graph/ProblemsButton.js +2 -2
- package/dist/graph/Reveal.js +18 -10
- package/dist/graph/ShortcutsButton.d.ts +11 -2
- package/dist/graph/ShortcutsButton.js +15 -4
- package/dist/graph/TreeView.js +35 -18
- package/dist/graph/WorkflowSettingsDialog.js +1 -1
- package/dist/graph/editorChrome.js +1 -1
- package/dist/graph/editorFields.js +1 -1
- package/dist/graph/editorRows.js +16 -10
- package/dist/graph/editorStrings.d.ts +7 -0
- package/dist/graph/editorStrings.js +8 -1
- package/dist/graph/fieldProblems.js +1 -1
- package/dist/graph/inputRefs.js +1 -1
- package/dist/graph/settingsViews.js +11 -18
- package/dist/graph/stepWith.js +2 -2
- package/dist/icons.d.ts +2 -0
- package/dist/icons.js +4 -2
- package/dist/index.d.ts +12 -12
- package/dist/index.js +16 -16
- package/dist/list/ActionToolbar.d.ts +44 -8
- package/dist/list/ActionToolbar.js +301 -102
- package/dist/list/ListPage.d.ts +15 -23
- package/dist/list/ListPage.js +46 -45
- package/dist/list/ListTable.d.ts +32 -7
- package/dist/list/ListTable.js +48 -12
- package/dist/list/ListViewControls.js +2 -2
- package/dist/list/UserHoverCard.js +7 -15
- package/dist/list/index.d.ts +2 -2
- package/dist/list/index.js +2 -2
- package/dist/list/listSearch.js +12 -10
- package/dist/list/listView.d.ts +10 -1
- package/dist/list/listView.js +15 -1
- package/dist/list/rowMenu.d.ts +2 -2
- package/dist/logviewer/LogViewer.d.ts +4 -2
- package/dist/logviewer/LogViewer.js +88 -70
- package/dist/logviewer/logviewer.css +3 -2
- package/dist/reducedMotion.d.ts +5 -0
- package/dist/reducedMotion.js +20 -0
- package/dist/safeUrl.d.ts +1 -1
- package/dist/safeUrl.js +4 -2
- package/dist/styles/theme.css +24 -10
- package/dist/styles.css +1 -1
- package/dist/theme/derive.d.ts +1 -1
- package/dist/theme/derive.js +46 -21
- package/dist/theme/fit.js +10 -4
- package/package.json +1 -1
- package/dist/components/Breadcrumbs.d.ts +0 -37
- package/dist/components/Breadcrumbs.js +0 -90
- package/dist/components/CopyToClipboard.d.ts +0 -17
- package/dist/components/CopyToClipboard.js +0 -66
- package/dist/components/Sort.d.ts +0 -9
- package/dist/components/Sort.js +0 -42
package/dist/editor/Monaco.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
|
+
import { useStrings } from "../components/Provider.js";
|
|
2
3
|
import { useCssIsDark } from "../components/useCssIsDark.js";
|
|
3
4
|
import { HOST_MARKER_OWNER, LINT_OWNER } from "./lintOwner.js";
|
|
4
5
|
import { lintContext, useLintEditing, useLintSources } from "./lintContext.js";
|
|
@@ -9,7 +10,7 @@ import { setupMonacoWorkers } from "./workers.js";
|
|
|
9
10
|
import { holdListeners, modelFor } from "./editorModel.js";
|
|
10
11
|
import { ensureYamlLanguage } from "./yamlLanguage.js";
|
|
11
12
|
import { jsx } from "react/jsx-runtime";
|
|
12
|
-
import { useEffect, useLayoutEffect, useRef } from "react";
|
|
13
|
+
import { useEffect, useId, useLayoutEffect, useRef } from "react";
|
|
13
14
|
import * as monaco from "monaco-editor";
|
|
14
15
|
//#region src/editor/Monaco.tsx
|
|
15
16
|
setupMonacoWorkers();
|
|
@@ -38,25 +39,166 @@ function editorText(value) {
|
|
|
38
39
|
return value.replace(/\r/g, "");
|
|
39
40
|
}
|
|
40
41
|
var noop = () => {};
|
|
41
|
-
|
|
42
|
+
var DISABLED_BACKGROUNDS = [
|
|
43
|
+
"--vscode-editor-background",
|
|
44
|
+
"--vscode-editorGutter-background",
|
|
45
|
+
"--vscode-editorStickyScroll-background",
|
|
46
|
+
"--vscode-minimap-background",
|
|
47
|
+
"--vscode-editorOverviewRuler-background"
|
|
48
|
+
];
|
|
49
|
+
function minimalEdit(model, from, to) {
|
|
50
|
+
let start = 0;
|
|
51
|
+
const shortest = Math.min(from.length, to.length);
|
|
52
|
+
while (start < shortest && from[start] === to[start]) start++;
|
|
53
|
+
let end = 0;
|
|
54
|
+
while (end < shortest - start && from[from.length - 1 - end] === to[to.length - 1 - end]) end++;
|
|
55
|
+
const a = model.getPositionAt(start);
|
|
56
|
+
const b = model.getPositionAt(from.length - end);
|
|
57
|
+
return {
|
|
58
|
+
range: new monaco.Range(a.lineNumber, a.column, b.lineNumber, b.column),
|
|
59
|
+
text: to.slice(start, to.length - end)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function MonacoEditor({ className, disabled, onChange = noop, onValidate = noop, width = "100%", height = "100%", path: pathProp, preserveUndo = false, lint = false, markers, nested, value, language, ...options }) {
|
|
63
|
+
const { common: t } = useStrings();
|
|
64
|
+
const ownPath = `file:///editor/${useId().replace(/[^\w-]/g, "")}`;
|
|
65
|
+
const path = useRef(pathProp ?? ownPath).current;
|
|
42
66
|
const isDark = useCssIsDark();
|
|
67
|
+
const isDarkRef = useRef(isDark);
|
|
68
|
+
isDarkRef.current = isDark;
|
|
43
69
|
const readOnly = Boolean(disabled || options.readOnly);
|
|
70
|
+
const containerRef = useRef(null);
|
|
44
71
|
const monacoRef = useRef(null);
|
|
45
72
|
const isSyncingValueRef = useRef(false);
|
|
46
73
|
const lintSources = useLintSources();
|
|
47
74
|
const lintSourcesRef = useRef(lintSources);
|
|
48
75
|
lintSourcesRef.current = lintSources;
|
|
49
76
|
const runLintRef = useRef(null);
|
|
50
|
-
const unregisterRevealRef = useRef(null);
|
|
51
|
-
const listenersRef = useRef([]);
|
|
52
77
|
const nestedRef = useRef(nested);
|
|
53
78
|
nestedRef.current = nested;
|
|
54
79
|
const isNested = nested !== void 0;
|
|
80
|
+
const onChangeRef = useRef(onChange);
|
|
81
|
+
onChangeRef.current = onChange;
|
|
82
|
+
const onValidateRef = useRef(onValidate);
|
|
83
|
+
onValidateRef.current = onValidate;
|
|
84
|
+
const markersRef = useRef(markers);
|
|
85
|
+
markersRef.current = markers;
|
|
86
|
+
const editorOptions = {
|
|
87
|
+
ariaLabel: t.codeEditor,
|
|
88
|
+
readOnlyMessage: { value: t.readOnlyText },
|
|
89
|
+
...options,
|
|
90
|
+
readOnly,
|
|
91
|
+
renderLineHighlight: disabled ? "none" : options.renderLineHighlight ?? "line"
|
|
92
|
+
};
|
|
93
|
+
const optionsKey = JSON.stringify(editorOptions);
|
|
94
|
+
const optionsRef = useRef(editorOptions);
|
|
95
|
+
optionsRef.current = editorOptions;
|
|
96
|
+
const initialRef = useRef({
|
|
97
|
+
value,
|
|
98
|
+
language
|
|
99
|
+
});
|
|
55
100
|
const lintEditing = useLintEditing(lint);
|
|
56
101
|
const lintEditingRef = useRef(lintEditing);
|
|
57
102
|
lintEditingRef.current = lintEditing;
|
|
58
103
|
const lintRef = useRef(lint);
|
|
59
104
|
lintRef.current = lint;
|
|
105
|
+
useLayoutEffect(() => {
|
|
106
|
+
const container = containerRef.current;
|
|
107
|
+
if (!container) return;
|
|
108
|
+
defineEditorThemes(monaco.editor);
|
|
109
|
+
monaco.editor.setTheme(getThemeName(isDarkRef.current));
|
|
110
|
+
const { value: initial, language: initialLanguage } = initialRef.current;
|
|
111
|
+
const model = modelFor(monaco.Uri.parse(path), initial ?? "", initialLanguage);
|
|
112
|
+
const editor = monaco.editor.create(container, {
|
|
113
|
+
automaticLayout: true,
|
|
114
|
+
model,
|
|
115
|
+
...optionsRef.current,
|
|
116
|
+
fixedOverflowWidgets: true,
|
|
117
|
+
suggest: {
|
|
118
|
+
preview: true,
|
|
119
|
+
showWords: false,
|
|
120
|
+
showInlineDetails: true
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
setMarkers(model, HOST_MARKER_OWNER, (markersRef.current ?? []).map((marker) => lintMarker(model, marker)));
|
|
124
|
+
setMarkers(model, LINT_OWNER, []);
|
|
125
|
+
const runLint = () => {
|
|
126
|
+
const editing = lintEditingRef.current;
|
|
127
|
+
if (!lintRef.current || !editing || model.isDisposed()) return;
|
|
128
|
+
const schema = monaco.editor.getModelMarkers({ resource: model.uri }).filter((marker) => marker.owner !== "workflowlint" && marker.owner !== "workflowmarkers" && String(marker.code ?? "") !== SCHEMA_UNREADABLE);
|
|
129
|
+
const source = model.getValue();
|
|
130
|
+
setMarkers(model, LINT_OWNER, schema.length > 0 ? [] : editing.lintWorkflow(source, lintContext(editing, source, lintSourcesRef.current, runLint)).map((problem) => lintMarker(model, problem)));
|
|
131
|
+
};
|
|
132
|
+
runLintRef.current = runLint;
|
|
133
|
+
let lintTimer;
|
|
134
|
+
const validate = () => {
|
|
135
|
+
runLint();
|
|
136
|
+
onValidateRef.current(monaco.editor.getModelMarkers({ resource: model.uri }));
|
|
137
|
+
};
|
|
138
|
+
const modelListeners = [
|
|
139
|
+
model.onDidChangeContent(() => {
|
|
140
|
+
if (lintRef.current) {
|
|
141
|
+
window.clearTimeout(lintTimer);
|
|
142
|
+
lintTimer = window.setTimeout(runLint, 300);
|
|
143
|
+
}
|
|
144
|
+
if (isSyncingValueRef.current) return;
|
|
145
|
+
onChangeRef.current(editorText(editor.getValue()));
|
|
146
|
+
}),
|
|
147
|
+
monaco.editor.onDidChangeMarkers((resources) => {
|
|
148
|
+
const uri = model.uri.toString();
|
|
149
|
+
if (resources.some((resource) => resource.toString() === uri)) validate();
|
|
150
|
+
}),
|
|
151
|
+
{ dispose: () => window.clearTimeout(lintTimer) }
|
|
152
|
+
];
|
|
153
|
+
holdListeners(model, modelListeners);
|
|
154
|
+
validate();
|
|
155
|
+
const unregisterReveal = registerRevealer(path, (start, end) => {
|
|
156
|
+
const last = Math.min(Math.max(start, end), model.getLineCount());
|
|
157
|
+
editor.revealLinesInCenterIfOutsideViewport(start, last);
|
|
158
|
+
editor.setPosition({
|
|
159
|
+
lineNumber: start,
|
|
160
|
+
column: model.getLineFirstNonWhitespaceColumn(start) || 1
|
|
161
|
+
});
|
|
162
|
+
const flash = editor.createDecorationsCollection([{
|
|
163
|
+
range: new monaco.Range(start, 1, last, 1),
|
|
164
|
+
options: {
|
|
165
|
+
isWholeLine: true,
|
|
166
|
+
className: "bg-(--theme-accent)/20"
|
|
167
|
+
}
|
|
168
|
+
}]);
|
|
169
|
+
window.setTimeout(() => flash.clear(), 1500);
|
|
170
|
+
});
|
|
171
|
+
const unfollow = followThemeTokens(monaco.editor, () => getThemeName(isDarkRef.current));
|
|
172
|
+
ensureYamlLanguage();
|
|
173
|
+
monacoRef.current = editor;
|
|
174
|
+
return () => {
|
|
175
|
+
unfollow();
|
|
176
|
+
unregisterReveal();
|
|
177
|
+
for (const listener of modelListeners) listener.dispose();
|
|
178
|
+
editor.dispose();
|
|
179
|
+
monacoRef.current = null;
|
|
180
|
+
runLintRef.current = null;
|
|
181
|
+
if (!model.isDisposed() && model.getLanguageId() !== "yaml") model.dispose();
|
|
182
|
+
};
|
|
183
|
+
}, [path]);
|
|
184
|
+
useEffect(() => {
|
|
185
|
+
if (monacoRef.current) {
|
|
186
|
+
defineEditorThemes(monaco.editor);
|
|
187
|
+
monaco.editor.setTheme(getThemeName(isDark));
|
|
188
|
+
}
|
|
189
|
+
}, [isDark]);
|
|
190
|
+
useEffect(() => {
|
|
191
|
+
const node = monacoRef.current?.getDomNode();
|
|
192
|
+
for (const name of DISABLED_BACKGROUNDS) if (disabled) node?.style.setProperty(name, "var(--theme-input-disabled-bg)");
|
|
193
|
+
else node?.style.removeProperty(name);
|
|
194
|
+
}, [disabled]);
|
|
195
|
+
useEffect(() => {
|
|
196
|
+
monacoRef.current?.updateOptions(optionsRef.current);
|
|
197
|
+
}, [optionsKey]);
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
const model = monacoRef.current?.getModel();
|
|
200
|
+
if (model && language && model.getLanguageId() !== language) monaco.editor.setModelLanguage(model, language);
|
|
201
|
+
}, [language]);
|
|
60
202
|
useEffect(() => {
|
|
61
203
|
const model = monacoRef.current?.getModel();
|
|
62
204
|
if (!lint && model) setMarkers(model, LINT_OWNER, []);
|
|
@@ -70,126 +212,35 @@ function MonacoEditor({ className, disabled, onChange = noop, onValidate = noop,
|
|
|
70
212
|
if (!isNested) return;
|
|
71
213
|
return publishNestedText(monaco.Uri.parse(path).toString(), nestedRef);
|
|
72
214
|
}, [path, isNested]);
|
|
73
|
-
const themeName = useRef(getThemeName(isDark, disabled));
|
|
74
|
-
themeName.current = getThemeName(isDark, disabled);
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
if (!monacoRef.current) return;
|
|
77
|
-
defineEditorThemes(monaco.editor);
|
|
78
|
-
monaco.editor.setTheme(getThemeName(isDark, disabled));
|
|
79
|
-
monacoRef.current.updateOptions({ readOnly });
|
|
80
|
-
}, [
|
|
81
|
-
disabled,
|
|
82
|
-
isDark,
|
|
83
|
-
readOnly
|
|
84
|
-
]);
|
|
85
|
-
useEffect(() => followThemeTokens(monaco.editor, () => themeName.current), []);
|
|
86
215
|
useLayoutEffect(() => {
|
|
87
|
-
const
|
|
88
|
-
|
|
216
|
+
const editor = monacoRef.current;
|
|
217
|
+
const model = editor?.getModel();
|
|
218
|
+
if (!editor || !model || value === void 0) return;
|
|
219
|
+
const current = model.getValue();
|
|
220
|
+
if (editorText(current) === editorText(value)) return;
|
|
89
221
|
isSyncingValueRef.current = true;
|
|
90
222
|
try {
|
|
91
223
|
if (preserveUndo) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
editor
|
|
99
|
-
}
|
|
224
|
+
editor.pushUndoStop();
|
|
225
|
+
model.pushEditOperations([], [minimalEdit(model, current, value)], () => null);
|
|
226
|
+
editor.pushUndoStop();
|
|
227
|
+
} else {
|
|
228
|
+
const view = editor.saveViewState();
|
|
229
|
+
model.setValue(value);
|
|
230
|
+
if (view) editor.restoreViewState(view);
|
|
231
|
+
}
|
|
100
232
|
} finally {
|
|
101
233
|
isSyncingValueRef.current = false;
|
|
102
234
|
}
|
|
103
|
-
}, [
|
|
104
|
-
useEffect(() => {
|
|
105
|
-
return () => {
|
|
106
|
-
unregisterRevealRef.current?.();
|
|
107
|
-
for (const listener of listenersRef.current) listener.dispose();
|
|
108
|
-
monacoRef.current?.dispose();
|
|
109
|
-
monacoRef.current = null;
|
|
110
|
-
};
|
|
111
|
-
}, []);
|
|
112
|
-
/** Strips CR (\r) — Windows line endings break bash scripts. */
|
|
113
|
-
const onChangeWrapper = (value) => {
|
|
114
|
-
value = editorText(value);
|
|
115
|
-
onChange(value);
|
|
116
|
-
};
|
|
235
|
+
}, [value, preserveUndo]);
|
|
117
236
|
return /* @__PURE__ */ jsx("div", {
|
|
237
|
+
ref: containerRef,
|
|
118
238
|
style: {
|
|
119
239
|
width,
|
|
120
240
|
height
|
|
121
241
|
},
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (ref && !monacoRef.current) {
|
|
125
|
-
defineEditorThemes(monaco.editor);
|
|
126
|
-
monaco.editor.setTheme(getThemeName(isDark, disabled));
|
|
127
|
-
const model = modelFor(monaco.Uri.parse(path), options.value ?? "", options.language);
|
|
128
|
-
const editor = monaco.editor.create(ref, {
|
|
129
|
-
automaticLayout: true,
|
|
130
|
-
model,
|
|
131
|
-
...options,
|
|
132
|
-
readOnly,
|
|
133
|
-
fixedOverflowWidgets: true,
|
|
134
|
-
suggest: {
|
|
135
|
-
preview: true,
|
|
136
|
-
showWords: false,
|
|
137
|
-
showInlineDetails: true
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
setMarkers(model, HOST_MARKER_OWNER, (markers ?? []).map((marker) => lintMarker(model, marker)));
|
|
141
|
-
setMarkers(model, LINT_OWNER, []);
|
|
142
|
-
const runLint = () => {
|
|
143
|
-
const editing = lintEditingRef.current;
|
|
144
|
-
if (!lintRef.current || !editing || model.isDisposed()) return;
|
|
145
|
-
const schema = monaco.editor.getModelMarkers({ resource: model.uri }).filter((marker) => marker.owner !== "workflowlint" && marker.owner !== "workflowmarkers" && String(marker.code ?? "") !== SCHEMA_UNREADABLE);
|
|
146
|
-
const source = model.getValue();
|
|
147
|
-
setMarkers(model, LINT_OWNER, schema.length > 0 ? [] : editing.lintWorkflow(source, lintContext(editing, source, lintSourcesRef.current, runLint)).map((problem) => lintMarker(model, problem)));
|
|
148
|
-
};
|
|
149
|
-
runLintRef.current = runLint;
|
|
150
|
-
let lintTimer;
|
|
151
|
-
const validate = () => {
|
|
152
|
-
runLint();
|
|
153
|
-
onValidate(monaco.editor.getModelMarkers({ resource: model.uri }));
|
|
154
|
-
};
|
|
155
|
-
const modelListeners = [
|
|
156
|
-
model.onDidChangeContent(() => {
|
|
157
|
-
if (lintRef.current) {
|
|
158
|
-
window.clearTimeout(lintTimer);
|
|
159
|
-
lintTimer = window.setTimeout(runLint, 300);
|
|
160
|
-
}
|
|
161
|
-
if (isSyncingValueRef.current) return;
|
|
162
|
-
onChangeWrapper(editor.getValue());
|
|
163
|
-
}),
|
|
164
|
-
monaco.editor.onDidChangeMarkers((resources) => {
|
|
165
|
-
const uri = model.uri.toString();
|
|
166
|
-
if (resources.some((resource) => resource.toString() === uri)) validate();
|
|
167
|
-
}),
|
|
168
|
-
{ dispose: () => window.clearTimeout(lintTimer) }
|
|
169
|
-
];
|
|
170
|
-
holdListeners(model, modelListeners);
|
|
171
|
-
listenersRef.current = modelListeners;
|
|
172
|
-
validate();
|
|
173
|
-
unregisterRevealRef.current = registerRevealer(path, (start, end) => {
|
|
174
|
-
const last = Math.min(Math.max(start, end), model.getLineCount());
|
|
175
|
-
editor.revealLinesInCenterIfOutsideViewport(start, last);
|
|
176
|
-
editor.setPosition({
|
|
177
|
-
lineNumber: start,
|
|
178
|
-
column: model.getLineFirstNonWhitespaceColumn(start) || 1
|
|
179
|
-
});
|
|
180
|
-
const flash = editor.createDecorationsCollection([{
|
|
181
|
-
range: new monaco.Range(start, 1, last, 1),
|
|
182
|
-
options: {
|
|
183
|
-
isWholeLine: true,
|
|
184
|
-
className: "bg-(--theme-accent)/20"
|
|
185
|
-
}
|
|
186
|
-
}]);
|
|
187
|
-
window.setTimeout(() => flash.clear(), 1500);
|
|
188
|
-
});
|
|
189
|
-
ensureYamlLanguage();
|
|
190
|
-
monacoRef.current = editor;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
242
|
+
"data-disabled": disabled ? "" : void 0,
|
|
243
|
+
className: cx("relative rounded border border-(--theme-border)", "focus-within:border-(--theme-accent) focus-within:ring-1 focus-within:ring-(--theme-accent)", "data-disabled:[&_.cursors-layer]:hidden data-disabled:[&_.view-lines]:opacity-60", className)
|
|
193
244
|
});
|
|
194
245
|
}
|
|
195
246
|
//#endregion
|
package/dist/editor/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
1
|
+
export { Editor } from './Editor.js';
|
|
2
|
+
export { EditorField, type IEditorField } from './EditorField.js';
|
|
3
|
+
export { FormCodePanel, type FormCodePanelProps } from './FormCodePanel.js';
|
|
4
4
|
export { HOST_MARKER_OWNER, LINT_OWNER } from './lintOwner.js';
|
|
5
|
-
export type {
|
|
5
|
+
export type { EditorMarker, EditorProps, ValidationMarker } from './Monaco.js';
|
|
6
6
|
export { type NestedWorkflowText, nestedWorkflowText } from './nestedText.js';
|
|
7
7
|
export { revealLines } from './reveal.js';
|
|
8
8
|
export { INPUT_YAML_PATH, JOB_YAML_PATH, type JsonSchema, SETTINGS_YAML_PATH, STEP_YAML_PATH, settingsSchemas, } from './settingsYaml.js';
|
|
9
9
|
export { defineEditorThemes, followThemeTokens, getThemeName } from './themes.js';
|
|
10
10
|
export { setupMonacoWorkers } from './workers.js';
|
|
11
|
-
export { configureEditorYaml } from './yaml.js';
|
|
11
|
+
export { configureEditorYaml, type SchemasSettings } from './yaml.js';
|
package/dist/editor/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { HOST_MARKER_OWNER, LINT_OWNER } from "./lintOwner.js";
|
|
2
2
|
import { INPUT_YAML_PATH, JOB_YAML_PATH, SETTINGS_YAML_PATH, STEP_YAML_PATH, settingsSchemas } from "./settingsYaml.js";
|
|
3
|
-
import Editor from "./Editor.js";
|
|
4
|
-
import EditorField from "./EditorField.js";
|
|
5
|
-
import FormCodePanel from "./FormCodePanel.js";
|
|
3
|
+
import { Editor } from "./Editor.js";
|
|
4
|
+
import { EditorField } from "./EditorField.js";
|
|
5
|
+
import { FormCodePanel } from "./FormCodePanel.js";
|
|
6
6
|
import { nestedWorkflowText } from "./nestedText.js";
|
|
7
7
|
import { revealLines } from "./reveal.js";
|
|
8
8
|
import { defineEditorThemes, followThemeTokens, getThemeName } from "./themes.js";
|
package/dist/editor/themes.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type * as monaco from 'monaco-editor';
|
|
2
2
|
export declare function expandShorthandHex(color: string): string;
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Defines the light and dark Monaco themes from the document's tokens. Call it again after the
|
|
5
|
+
* host applies other tokens; it returns whether anything changed.
|
|
6
|
+
*/
|
|
7
|
+
export declare function defineEditorThemes(monacoEditor: typeof monaco.editor): boolean;
|
|
8
|
+
/** Redefines the editor themes when the host applies other tokens or another scheme to the
|
|
9
|
+
* document, and sets `current()` again, so an open editor follows a theme being edited. */
|
|
7
10
|
export declare function followThemeTokens(monacoEditor: typeof monaco.editor, current: () => string): () => void;
|
|
8
|
-
export declare function getThemeName(isDark: boolean
|
|
11
|
+
export declare function getThemeName(isDark: boolean): string;
|
package/dist/editor/themes.js
CHANGED
|
@@ -9,9 +9,8 @@ var fallbacks = {};
|
|
|
9
9
|
/** A token as Monaco takes it: a 6-digit hex. Monaco can't read display-p3, so
|
|
10
10
|
* a wide-gamut value is mapped back into sRGB; the default theme fills in for
|
|
11
11
|
* a host that sets no tokens. */
|
|
12
|
-
function token(name, mode) {
|
|
13
|
-
const
|
|
14
|
-
const color = parseColor(expandShorthandHex(set));
|
|
12
|
+
function token(style, name, mode) {
|
|
13
|
+
const color = parseColor(expandShorthandHex(style?.getPropertyValue(name).trim() ?? ""));
|
|
15
14
|
if (color) return toHex(color);
|
|
16
15
|
fallbacks[mode] ??= deriveTheme(schemeFor(DEFAULT_THEME, mode));
|
|
17
16
|
return fallbacks[mode][name];
|
|
@@ -37,27 +36,22 @@ var RULES = [
|
|
|
37
36
|
["delimiter", "--theme-code-text"],
|
|
38
37
|
["operators", "--theme-code-text"]
|
|
39
38
|
];
|
|
40
|
-
function editorTheme(
|
|
41
|
-
const c = (name) => token(name, mode);
|
|
42
|
-
const foreground = disabled ? c("--theme-muted-text-color") : c("--theme-code-text");
|
|
43
|
-
const background = disabled ? c("--theme-input-disabled-bg") : c("--theme-panel-bg");
|
|
39
|
+
function editorTheme(style, mode) {
|
|
40
|
+
const c = (name) => token(style, name, mode);
|
|
44
41
|
return {
|
|
45
42
|
base: mode === "dark" ? "vs-dark" : "vs",
|
|
46
43
|
inherit: true,
|
|
47
|
-
rules:
|
|
48
|
-
token: "",
|
|
49
|
-
foreground: foreground.slice(1)
|
|
50
|
-
}] : RULES.map(([name, t, fontStyle]) => ({
|
|
44
|
+
rules: RULES.map(([name, t, fontStyle]) => ({
|
|
51
45
|
token: name,
|
|
52
46
|
foreground: c(t).slice(1),
|
|
53
47
|
...fontStyle ? { fontStyle } : {}
|
|
54
48
|
})),
|
|
55
49
|
colors: {
|
|
56
|
-
"editor.foreground":
|
|
57
|
-
"editor.background":
|
|
50
|
+
"editor.foreground": c("--theme-code-text"),
|
|
51
|
+
"editor.background": c("--theme-panel-bg"),
|
|
58
52
|
"editor.border": c("--theme-border"),
|
|
59
|
-
"editorCursor.foreground":
|
|
60
|
-
"editor.lineHighlightBackground":
|
|
53
|
+
"editorCursor.foreground": c("--theme-app"),
|
|
54
|
+
"editor.lineHighlightBackground": c("--theme-hover"),
|
|
61
55
|
"editorLineNumber.foreground": c("--theme-placeholder"),
|
|
62
56
|
"editorLineNumber.activeForeground": c("--theme-muted-text-color"),
|
|
63
57
|
"editor.selectionBackground": c("--theme-accent-subtle"),
|
|
@@ -65,26 +59,60 @@ function editorTheme(mode, disabled) {
|
|
|
65
59
|
}
|
|
66
60
|
};
|
|
67
61
|
}
|
|
68
|
-
|
|
62
|
+
var definedFor = /* @__PURE__ */ new WeakMap();
|
|
63
|
+
/**
|
|
64
|
+
* Defines the light and dark Monaco themes from the document's tokens. Call it again after the
|
|
65
|
+
* host applies other tokens; it returns whether anything changed.
|
|
66
|
+
*/
|
|
69
67
|
function defineEditorThemes(monacoEditor) {
|
|
70
|
-
|
|
68
|
+
const style = typeof window === "undefined" ? void 0 : getComputedStyle(document.documentElement);
|
|
69
|
+
const themes = ["light", "dark"].map((mode) => [mode, editorTheme(style, mode)]);
|
|
70
|
+
const snapshot = JSON.stringify(themes);
|
|
71
|
+
if (definedFor.get(monacoEditor) === snapshot) return false;
|
|
72
|
+
definedFor.set(monacoEditor, snapshot);
|
|
73
|
+
for (const [mode, data] of themes) monacoEditor.defineTheme(getThemeName(mode === "dark"), data);
|
|
74
|
+
return true;
|
|
71
75
|
}
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
var followers = /* @__PURE__ */ new Set();
|
|
77
|
+
var observer;
|
|
78
|
+
var frame = 0;
|
|
79
|
+
function flush() {
|
|
80
|
+
frame = 0;
|
|
81
|
+
for (const follow of followers) follow();
|
|
82
|
+
}
|
|
83
|
+
/** Redefines the editor themes when the host applies other tokens or another scheme to the
|
|
84
|
+
* document, and sets `current()` again, so an open editor follows a theme being edited. */
|
|
74
85
|
function followThemeTokens(monacoEditor, current) {
|
|
75
86
|
if (typeof MutationObserver === "undefined") return () => {};
|
|
76
|
-
const
|
|
77
|
-
defineEditorThemes(monacoEditor);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
observer
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
87
|
+
const follow = () => {
|
|
88
|
+
if (defineEditorThemes(monacoEditor)) monacoEditor.setTheme(current());
|
|
89
|
+
};
|
|
90
|
+
followers.add(follow);
|
|
91
|
+
if (!observer) {
|
|
92
|
+
observer = new MutationObserver(() => {
|
|
93
|
+
frame ||= requestAnimationFrame(flush);
|
|
94
|
+
});
|
|
95
|
+
observer.observe(document.documentElement, {
|
|
96
|
+
attributes: true,
|
|
97
|
+
attributeFilter: [
|
|
98
|
+
"style",
|
|
99
|
+
"class",
|
|
100
|
+
"data-theme"
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return () => {
|
|
105
|
+
followers.delete(follow);
|
|
106
|
+
if (followers.size === 0) {
|
|
107
|
+
observer?.disconnect();
|
|
108
|
+
observer = void 0;
|
|
109
|
+
cancelAnimationFrame(frame);
|
|
110
|
+
frame = 0;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
85
113
|
}
|
|
86
|
-
function getThemeName(isDark
|
|
87
|
-
return `app-${isDark ? "dark" : "light"}
|
|
114
|
+
function getThemeName(isDark) {
|
|
115
|
+
return `app-${isDark ? "dark" : "light"}`;
|
|
88
116
|
}
|
|
89
117
|
//#endregion
|
|
90
118
|
export { defineEditorThemes, expandShorthandHex, followThemeTokens, getThemeName };
|
package/dist/editor/yaml.d.ts
CHANGED
|
@@ -7,7 +7,11 @@ export interface SchemasSettings {
|
|
|
7
7
|
/** The schema itself, used instead of fetching `uri`. */
|
|
8
8
|
schema?: object;
|
|
9
9
|
}
|
|
10
|
-
/**
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Adds JSON schemas that validate and complete YAML models whose URI matches. A schema with the
|
|
12
|
+
* `uri` of one already added replaces it, so calling this again, as a reload or a second mount
|
|
13
|
+
* does, adds nothing twice. Returns a function that removes these schemas.
|
|
14
|
+
*/
|
|
15
|
+
export declare function configureEditorYaml(added: SchemasSettings[]): () => void;
|
|
12
16
|
/** Lets the loaded editor pick up schemas added before or after it loads. */
|
|
13
17
|
export declare function onYamlSchemas(listener: (schemas: SchemasSettings[]) => void): void;
|
package/dist/editor/yaml.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
//#region src/editor/yaml.ts
|
|
2
2
|
var schemas = [];
|
|
3
3
|
var apply;
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Adds JSON schemas that validate and complete YAML models whose URI matches. A schema with the
|
|
6
|
+
* `uri` of one already added replaces it, so calling this again, as a reload or a second mount
|
|
7
|
+
* does, adds nothing twice. Returns a function that removes these schemas.
|
|
8
|
+
*/
|
|
5
9
|
function configureEditorYaml(added) {
|
|
6
|
-
|
|
10
|
+
const uris = new Set(added.map((schema) => schema.uri));
|
|
11
|
+
schemas = [...schemas.filter((schema) => !uris.has(schema.uri)), ...added];
|
|
7
12
|
apply?.(schemas);
|
|
13
|
+
return () => {
|
|
14
|
+
schemas = schemas.filter((schema) => !added.includes(schema));
|
|
15
|
+
apply?.(schemas);
|
|
16
|
+
};
|
|
8
17
|
}
|
|
9
18
|
/** Lets the loaded editor pick up schemas added before or after it loads. */
|
|
10
19
|
function onYamlSchemas(listener) {
|