@parallelworks/ui 0.19.0 → 0.19.1
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/dist/{chunks/memoryStore-CC91S5LP.js → ai/adapter/memoryStore.js} +2 -2
- package/dist/ai/adapter/mock/index.js +2 -80
- package/dist/ai/adapter/mock/mockAdapter.js +81 -0
- package/dist/ai/adapter/openai/createOpenAIStream.js +33 -0
- package/dist/ai/adapter/openai/errors.js +37 -0
- package/dist/ai/adapter/openai/index.js +5 -333
- package/dist/ai/adapter/openai/openaiAdapter.js +54 -0
- package/dist/ai/adapter/openai/responses.js +108 -0
- package/dist/ai/adapter/openai/sse.js +112 -0
- package/dist/{chunks/types-Yy0NrerF.js → ai/adapter/types.js} +1 -1
- package/dist/ai/agent/classifier.js +12 -0
- package/dist/ai/agent/diff.js +223 -0
- package/dist/ai/agent/diffHighlight.js +101 -0
- package/dist/ai/agent/permissions.js +29 -0
- package/dist/ai/agent/toolfmt.js +383 -0
- package/dist/ai/agent/transcript.js +127 -0
- package/dist/ai/components/AllocationSelector.js +56 -0
- package/dist/ai/components/AttachmentManager.js +144 -0
- package/dist/ai/components/AttachmentUpload.js +179 -0
- package/dist/ai/components/BlockedGroupBanner.js +29 -0
- package/dist/ai/components/BranchNavigator.js +57 -0
- package/dist/ai/components/ChatEmptyState.js +171 -0
- package/dist/ai/components/ChatInput.js +265 -0
- package/dist/ai/components/ChatLayout.js +15 -0
- package/dist/ai/components/ChatMessage.js +338 -0
- package/dist/ai/components/ChatMessageList.js +301 -0
- package/dist/ai/components/ChatSidebar.js +345 -0
- package/dist/ai/components/ChatThread.js +198 -0
- package/dist/ai/components/ComposerChrome.js +50 -0
- package/dist/ai/components/ComposerFrame.js +33 -0
- package/dist/ai/components/DragOverlay.js +20 -0
- package/dist/ai/components/ModelSelector.js +343 -0
- package/dist/ai/components/ShareDialog.js +260 -0
- package/dist/ai/components/SlashMenu.js +91 -0
- package/dist/ai/components/agent/ActivityLine.js +151 -0
- package/dist/ai/components/agent/AgentMessageParts.js +721 -0
- package/dist/ai/components/agent/PermissionPicker.js +38 -0
- package/dist/ai/components/attachmentKeys.js +10 -0
- package/dist/ai/core/ChatProvider.js +848 -0
- package/dist/ai/core/KeyboardShortcutsProvider.js +9 -0
- package/dist/ai/core/chatReducer.js +223 -0
- package/dist/ai/core/config.js +45 -0
- package/dist/ai/core/events.js +4 -0
- package/dist/ai/core/exportConversation.js +42 -0
- package/dist/ai/core/greeting.js +38 -0
- package/dist/ai/core/parts.js +84 -0
- package/dist/ai/core/useDragDrop.js +36 -0
- package/dist/ai/core/useKeyboardShortcuts.js +77 -0
- package/dist/ai/core/useSSEStream.js +98 -0
- package/dist/ai/index.js +43 -6644
- package/dist/ai/strings.js +175 -0
- package/dist/ai/ui/Avatar.js +35 -0
- package/dist/ai/ui/Dropdown.js +110 -0
- package/dist/ai/ui/Markdown.js +79 -0
- package/dist/ai/ui/Notice.js +77 -0
- package/dist/ai/ui/codeBreaks.js +36 -0
- package/dist/ai/ui/prose.js +13 -0
- package/dist/ai/ui/sidebar.js +148 -0
- package/dist/ai/utils.js +23 -0
- package/dist/components/AddMenu.js +46 -0
- package/dist/components/Avatar.js +46 -0
- package/dist/{chunks/BareModal-BtRiQezg.js → components/BareModal.js} +1 -1
- package/dist/components/Breadcrumbs.js +83 -0
- package/dist/components/Button.js +83 -0
- package/dist/components/Callout.js +23 -0
- package/dist/components/Card.js +31 -0
- package/dist/components/CollapsiblePanel.js +77 -0
- package/dist/{chunks/ConfirmModal-aOR4O1QE.js → components/ConfirmModal.js} +4 -9
- package/dist/components/CopyToClipboard.js +81 -0
- package/dist/{chunks/Markdown-CM-FenNE.js → components/CreateModal.js} +9 -116
- package/dist/components/DescriptionList.js +42 -0
- package/dist/components/Dropdown.js +349 -0
- package/dist/components/EmptyState.js +27 -0
- package/dist/components/Filter.js +32 -0
- package/dist/components/FilterPill.js +13 -0
- package/dist/components/IconButton.js +34 -0
- package/dist/{chunks/Indicator-hBSIxOPK.js → components/Indicator.js} +1 -1
- package/dist/components/Input.js +88 -0
- package/dist/components/LetterBadge.js +13 -0
- package/dist/components/Listbox.js +123 -0
- package/dist/{chunks/Loader-BXoXTZGc.js → components/Loader.js} +1 -1
- package/dist/components/Markdown.js +15 -0
- package/dist/components/MultiSelect.js +171 -0
- package/dist/components/Overview.js +39 -0
- package/dist/components/PageHeader.js +194 -0
- package/dist/components/Pagination.js +35 -0
- package/dist/{chunks/Provider-CDYurraE.js → components/Provider.js} +1 -1
- package/dist/{chunks/RequiredMark-DfLdYbYZ.js → components/RequiredMark.js} +1 -1
- package/dist/components/SectionHeader.js +11 -0
- package/dist/components/SettingModeOption.js +30 -0
- package/dist/components/SettingRow.js +35 -0
- package/dist/components/SettingsCard.js +31 -0
- package/dist/components/SettingsGroup.js +17 -0
- package/dist/components/Sort.js +42 -0
- package/dist/components/StatusBadge.js +63 -0
- package/dist/components/SwitchToggle.js +59 -0
- package/dist/{chunks/SwitchToggleSmall-FcsaYSTs.js → components/SwitchToggleSmall.js} +1 -1
- package/dist/{chunks/Table-DU2MW8xz.js → components/Table.js} +3 -3
- package/dist/components/Toggle.js +20 -0
- package/dist/{chunks/Tooltip-K5HJr4_p.js → components/Tooltip.js} +2 -27
- package/dist/{chunks/StatusBadge-C1Blx_cW.js → components/dropdownUtils.js} +2 -63
- package/dist/{chunks/focus-D_iZJTW1.js → components/focus.js} +1 -1
- package/dist/components/ghostButton.js +7 -0
- package/dist/components/inputClasses.js +4 -0
- package/dist/components/keys.js +27 -0
- package/dist/components/relativeTime.js +32 -0
- package/dist/{chunks/useCssIsDark-DHr05dG2.js → components/useCssIsDark.js} +1 -1
- package/dist/{chunks/duration-BOv8Phl8.js → duration.js} +1 -1
- package/dist/editor/Editor.js +13 -0
- package/dist/editor/EditorField.js +53 -0
- package/dist/editor/FormCodePanel.js +173 -0
- package/dist/{chunks/Monaco-DJ8MW-Dq.js → editor/Monaco.js} +4 -2
- package/dist/editor/index.js +6 -1
- package/dist/editor/themes.js +91 -0
- package/dist/editor/workers.js +29 -0
- package/dist/editor/yaml.js +15 -0
- package/dist/file-explorer/FileExplorer.js +1402 -0
- package/dist/file-explorer/FileExplorerContext.js +370 -0
- package/dist/{chunks/CodePreviewEditor-YqQBz1YL.js → file-explorer/FilePreview/CodePreviewEditor.js} +3 -2
- package/dist/file-explorer/FilePreview/Inline.js +45 -0
- package/dist/file-explorer/FilePreview/StreamedBadge.js +16 -0
- package/dist/file-explorer/FilePreview/Viewer.js +526 -0
- package/dist/file-explorer/FilePreview/index.js +266 -0
- package/dist/file-explorer/FilePreview/parse.js +63 -0
- package/dist/file-explorer/FilePreview/previewCache.js +98 -0
- package/dist/file-explorer/FilePreview/previewType.js +151 -0
- package/dist/file-explorer/FilePreview/readCappedBytes.js +196 -0
- package/dist/file-explorer/FilePreview/useObjectBlobUrl.js +95 -0
- package/dist/file-explorer/FilePreview/useObjectText.js +109 -0
- package/dist/file-explorer/FilePreview/usePresignedUrl.js +73 -0
- package/dist/file-explorer/FileRow.js +165 -0
- package/dist/file-explorer/FileRowsWindow.js +92 -0
- package/dist/file-explorer/FileTable.js +172 -0
- package/dist/file-explorer/FileTableHeaders.js +49 -0
- package/dist/file-explorer/LoadMoreRow.js +46 -0
- package/dist/file-explorer/TreeView.js +376 -0
- package/dist/file-explorer/helpers.js +537 -0
- package/dist/file-explorer/index.js +7 -5671
- package/dist/file-explorer/lib/batch.js +39 -0
- package/dist/file-explorer/lib/errors.js +9 -0
- package/dist/file-explorer/lib/paging.js +124 -0
- package/dist/file-explorer/lib/utils.js +322 -0
- package/dist/file-explorer/toasts.js +400 -0
- package/dist/file-explorer/treeRows.js +73 -0
- package/dist/file-explorer/useNearEnd.js +27 -0
- package/dist/form/FieldWrapper.js +54 -0
- package/dist/form/Fields/BooleanField.js +51 -0
- package/dist/form/Fields/CheckboxGroupField.js +72 -0
- package/dist/form/Fields/ColorField.js +33 -0
- package/dist/form/Fields/DropdownField.js +49 -0
- package/dist/form/Fields/DurationField.js +130 -0
- package/dist/form/Fields/LabelField.js +19 -0
- package/dist/form/Fields/MultiDropdownField.js +40 -0
- package/dist/form/Fields/NumberField.js +51 -0
- package/dist/form/Fields/ObjectField.js +54 -0
- package/dist/form/Fields/RadioField.js +49 -0
- package/dist/form/Fields/RangeField.js +58 -0
- package/dist/form/Fields/ResourceOptionIcon.js +21 -0
- package/dist/form/Fields/StepField.js +6 -0
- package/dist/form/Fields/StringField.js +37 -0
- package/dist/form/Fields/TextAreaField.js +31 -0
- package/dist/form/Fields/durationValidity.js +11 -0
- package/dist/form/Form.js +643 -0
- package/dist/form/SpecialTypes/DropdownWrapper.js +30 -0
- package/dist/form/SpecialTypes/FormikCustomDropdown.js +122 -0
- package/dist/form/SpecialTypes/FormikCustomInput.js +111 -0
- package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +31 -0
- package/dist/form/SpecialTypes/FormikNumericInput.js +60 -0
- package/dist/form/Wizard/WizardContainer.js +138 -0
- package/dist/form/Wizard/WizardNavigation.js +92 -0
- package/dist/form/Wizard/WizardStepContent.js +35 -0
- package/dist/form/Wizard/WizardStepIndicator.js +108 -0
- package/dist/form/Wizard/useWizardState.js +118 -0
- package/dist/form/Wizard/utils.js +34 -0
- package/dist/form/fieldContext.js +26 -0
- package/dist/form/fieldRegistry.js +50 -0
- package/dist/form/index.js +17 -2321
- package/dist/{chunks/FieldWrapper-Cszwg-4B.js → form/lib.js} +2 -97
- package/dist/form/useParsedOpts.js +62 -0
- package/dist/form/usePrevious.js +11 -0
- package/dist/form/utils/checkShowIfObject.js +14 -0
- package/dist/form/utils/duration.js +69 -0
- package/dist/form/utils/getParentValue.js +23 -0
- package/dist/form/utils/getPlaceholder.js +9 -0
- package/dist/form/utils/getValueUsingPath.js +23 -0
- package/dist/form/utils/secondaryField.js +22 -0
- package/dist/graph/AnnotationBanner.js +141 -0
- package/dist/graph/Collapse.js +41 -0
- package/dist/graph/DependencyGraph.js +1398 -0
- package/dist/graph/JobSummary.js +104 -0
- package/dist/graph/MatrixGroup.js +107 -0
- package/dist/graph/Reveal.js +57 -0
- package/dist/graph/TreeView.js +711 -0
- package/dist/graph/index.js +1 -2519
- package/dist/graph/types.js +6 -0
- package/dist/index.js +46 -599
- package/dist/list/ActionToolbar.js +184 -0
- package/dist/list/HoverCard.js +73 -0
- package/dist/list/ListPage.js +145 -0
- package/dist/list/ListPager.js +59 -0
- package/dist/list/ListTable.js +163 -0
- package/dist/list/ListViewControls.js +372 -0
- package/dist/list/RowContextMenu.js +350 -0
- package/dist/list/UserHoverCard.js +117 -0
- package/dist/list/index.js +11 -2
- package/dist/list/listSearch.js +137 -0
- package/dist/list/listView.js +210 -0
- package/dist/list/textEntry.js +10 -0
- package/dist/{chunks/logviewer-BTKuQWzw.js → logviewer/LogViewer.js} +4 -82
- package/dist/logviewer/index.js +2 -1
- package/dist/logviewer/segments.js +80 -0
- package/package.json +1 -1
- package/dist/chunks/PageHeader-0kG_iypP.js +0 -692
- package/dist/chunks/SwitchToggle-DShNdcao.js +0 -758
- package/dist/chunks/editor-Dk1rbV75.js +0 -361
- package/dist/chunks/list-CJm875m7.js +0 -1418
- /package/dist/{chunks/MarkdownImpl-CyeTVvSt.js → components/MarkdownImpl.js} +0 -0
|
@@ -1,52 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import cx from "classnames";
|
|
3
|
-
import { createContext, useContext, useId, useMemo } from "react";
|
|
4
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
//#region src/form/fieldContext.tsx
|
|
6
|
-
var FieldContext = createContext({ required: false });
|
|
7
|
-
var FieldProvider = FieldContext.Provider;
|
|
8
|
-
/** True when the surrounding FieldWrapper is showing the required asterisk. */
|
|
9
|
-
function useFieldRequired() {
|
|
10
|
-
return useContext(FieldContext).required;
|
|
11
|
-
}
|
|
12
|
-
/** Ties the single focusable control of a field to its FieldWrapper label. */
|
|
13
|
-
function useFieldControlProps() {
|
|
14
|
-
const { id, descriptionId } = useContext(FieldContext);
|
|
15
|
-
return {
|
|
16
|
-
id,
|
|
17
|
-
"aria-describedby": descriptionId
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
/** For controls and groups that can only be named through aria-labelledby. */
|
|
21
|
-
function useFieldLabelledByProps() {
|
|
22
|
-
const { labelId, descriptionId } = useContext(FieldContext);
|
|
23
|
-
return {
|
|
24
|
-
"aria-labelledby": labelId,
|
|
25
|
-
"aria-describedby": descriptionId
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
//#endregion
|
|
29
|
-
//#region src/form/utils/secondaryField.ts
|
|
30
|
-
function findSecondaryOption(options, value) {
|
|
31
|
-
for (const candidate of options) {
|
|
32
|
-
if (!candidate || typeof candidate !== "object") continue;
|
|
33
|
-
const option = candidate;
|
|
34
|
-
if (option.value === value) return option;
|
|
35
|
-
if (Array.isArray(option.options)) {
|
|
36
|
-
const nestedOption = findSecondaryOption(option.options, value);
|
|
37
|
-
if (nestedOption) return nestedOption;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
function applySecondaryField(secondaryField, secondaryValue, setFieldValue) {
|
|
42
|
-
if (secondaryField === void 0 || secondaryValue === void 0) return;
|
|
43
|
-
const fields = Array.isArray(secondaryField) ? secondaryField : [secondaryField];
|
|
44
|
-
const values = Array.isArray(secondaryValue) ? secondaryValue : [secondaryValue];
|
|
45
|
-
fields.forEach((field, index) => {
|
|
46
|
-
setFieldValue(field, values[index]);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
//#endregion
|
|
1
|
+
import { applySecondaryField, findSecondaryOption } from "./utils/secondaryField.js";
|
|
50
2
|
//#region src/form/lib.ts
|
|
51
3
|
var EMPTY_ENTRY = {};
|
|
52
4
|
function asRecord(value) {
|
|
@@ -201,51 +153,4 @@ function initializeValues(options, srcData = {}, blankDefault) {
|
|
|
201
153
|
}, data);
|
|
202
154
|
}
|
|
203
155
|
//#endregion
|
|
204
|
-
|
|
205
|
-
function FieldWrapper({ label, tooltipComponent, description, labelPosition = "left", spaceCompact = false, optional = false, children }) {
|
|
206
|
-
const isOptional = Boolean(resolvedFlag(optional));
|
|
207
|
-
const uid = useId();
|
|
208
|
-
const id = `${uid}control`;
|
|
209
|
-
const labelId = `${uid}label`;
|
|
210
|
-
const descriptionId = description ? `${uid}description` : void 0;
|
|
211
|
-
const field = useMemo(() => ({
|
|
212
|
-
required: !isOptional,
|
|
213
|
-
id,
|
|
214
|
-
labelId,
|
|
215
|
-
descriptionId
|
|
216
|
-
}), [
|
|
217
|
-
isOptional,
|
|
218
|
-
id,
|
|
219
|
-
labelId,
|
|
220
|
-
descriptionId
|
|
221
|
-
]);
|
|
222
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
223
|
-
className: cx("flex w-full", labelPosition === "left" ? "items-start" : "items-left flex-col"),
|
|
224
|
-
children: [/* @__PURE__ */ jsxs("label", {
|
|
225
|
-
htmlFor: id,
|
|
226
|
-
id: labelId,
|
|
227
|
-
className: cx("relative", labelPosition === "left" ? "form-label" : "form-label-top", spaceCompact && "form-label-compact"),
|
|
228
|
-
children: [
|
|
229
|
-
label,
|
|
230
|
-
!isOptional && /* @__PURE__ */ jsx(RequiredMark, {}),
|
|
231
|
-
tooltipComponent
|
|
232
|
-
]
|
|
233
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
234
|
-
className: "w-full",
|
|
235
|
-
children: [/* @__PURE__ */ jsx(FieldProvider, {
|
|
236
|
-
value: field,
|
|
237
|
-
children: typeof children === "function" ? children({
|
|
238
|
-
id,
|
|
239
|
-
labelId,
|
|
240
|
-
describedBy: descriptionId
|
|
241
|
-
}) : children
|
|
242
|
-
}), description && /* @__PURE__ */ jsx("div", {
|
|
243
|
-
id: descriptionId,
|
|
244
|
-
className: "text-xs theme-muted-text mt-1 leading-relaxed",
|
|
245
|
-
children: description
|
|
246
|
-
})]
|
|
247
|
-
})]
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
//#endregion
|
|
251
|
-
export { initializeValues as a, findSecondaryOption as c, useFieldLabelledByProps as d, useFieldRequired as f, impureSetValueFromPath as i, FieldProvider as l, enforceOneMustBeTrue as n, resolvedFlag as o, flattenGroups as r, applySecondaryField as s, FieldWrapper as t, useFieldControlProps as u };
|
|
156
|
+
export { enforceOneMustBeTrue, flattenGroups, impureSetValueFromPath, initializeValues, resolvedFlag };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { useWorkflowEngine } from "../components/Provider.js";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
import deepEqual from "fast-deep-equal";
|
|
4
|
+
//#region src/form/useParsedOpts.ts
|
|
5
|
+
var EMPTY_VARS = {};
|
|
6
|
+
var EMPTY_KEYS = [];
|
|
7
|
+
/**
|
|
8
|
+
* useMemo won't work here — Formik values changes on every keystroke, so this hook extracts which inputs.* keys the schema references and re-parses only when those change. Defaults `userVars`/`secretKeys` to empty — callers in React scope should pass them from `useUserVars()` so the parser leaves `${{ var.SECRET }}` literal during template eval (otherwise the recursive substitution turns `"https://${{ var.PAT }}@host/"` into `"https://@host/"`).
|
|
9
|
+
*/
|
|
10
|
+
function useParsedOpts(rawOptions, values, organizationVariables, userVars = EMPTY_VARS, secretKeys = EMPTY_KEYS, remoteVars = EMPTY_VARS) {
|
|
11
|
+
const engine = useWorkflowEngine();
|
|
12
|
+
const c = useRef({
|
|
13
|
+
rawOptions: null,
|
|
14
|
+
orgVars: void 0,
|
|
15
|
+
userVars: null,
|
|
16
|
+
secretKeys: null,
|
|
17
|
+
remoteVars: null,
|
|
18
|
+
converted: {},
|
|
19
|
+
inputDeps: /* @__PURE__ */ new Set(),
|
|
20
|
+
hasExpressions: false,
|
|
21
|
+
relevantSnapshot: {},
|
|
22
|
+
result: null
|
|
23
|
+
}).current;
|
|
24
|
+
if (rawOptions !== c.rawOptions) {
|
|
25
|
+
c.rawOptions = rawOptions;
|
|
26
|
+
c.converted = engine.convertInputs(rawOptions);
|
|
27
|
+
const { inputDeps, hasExpressions } = engine.inputDependencies(c.converted);
|
|
28
|
+
c.inputDeps = inputDeps;
|
|
29
|
+
c.hasExpressions = hasExpressions;
|
|
30
|
+
c.result = null;
|
|
31
|
+
}
|
|
32
|
+
if (organizationVariables !== c.orgVars || userVars !== c.userVars || secretKeys !== c.secretKeys || remoteVars !== c.remoteVars) {
|
|
33
|
+
c.orgVars = organizationVariables;
|
|
34
|
+
c.userVars = userVars;
|
|
35
|
+
c.secretKeys = secretKeys;
|
|
36
|
+
c.remoteVars = remoteVars;
|
|
37
|
+
c.result = null;
|
|
38
|
+
}
|
|
39
|
+
if (c.result !== null) {
|
|
40
|
+
if (c.inputDeps.size === 0) return c.result;
|
|
41
|
+
let inputsChanged = false;
|
|
42
|
+
for (const key of c.inputDeps) if (!deepEqual(values[key], c.relevantSnapshot[key])) {
|
|
43
|
+
inputsChanged = true;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
if (!inputsChanged) return c.result;
|
|
47
|
+
}
|
|
48
|
+
const parsed = engine.evaluate({
|
|
49
|
+
inputs: values,
|
|
50
|
+
obj: c.converted,
|
|
51
|
+
orgVars: organizationVariables,
|
|
52
|
+
userVars,
|
|
53
|
+
secretKeys,
|
|
54
|
+
remoteVars
|
|
55
|
+
});
|
|
56
|
+
c.result = parsed;
|
|
57
|
+
c.relevantSnapshot = {};
|
|
58
|
+
for (const key of c.inputDeps) c.relevantSnapshot[key] = values[key];
|
|
59
|
+
return parsed;
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { useParsedOpts };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { getValueUsingPath } from "./getValueUsingPath.js";
|
|
2
|
+
//#region src/form/utils/checkShowIfObject.ts
|
|
3
|
+
function checkShowIfObject(showIfObject, formValues, index) {
|
|
4
|
+
const valueList = [];
|
|
5
|
+
for (let [key, value] of Object.entries(showIfObject)) {
|
|
6
|
+
if (index !== void 0) key = key.replace("[index]", `[${index}]`);
|
|
7
|
+
const dependsOnValue = getValueUsingPath(formValues, key);
|
|
8
|
+
if (typeof value === "boolean" || typeof value === "string" || typeof value === "number") valueList.push(dependsOnValue !== null && dependsOnValue !== void 0 && dependsOnValue.toString() === value.toString());
|
|
9
|
+
else if (Array.isArray(value)) valueList.push(value.includes(dependsOnValue));
|
|
10
|
+
}
|
|
11
|
+
return valueList;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { checkShowIfObject };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Duration } from "luxon";
|
|
2
|
+
//#region src/form/utils/duration.ts
|
|
3
|
+
var WITH_DAYS = /^(\d+)-(\d{1,2})(?::(\d{1,2})(?::(\d{1,2}))?)?$/;
|
|
4
|
+
var WITHOUT_DAYS = /^(\d+):(\d{1,2}):(\d{1,2})$/;
|
|
5
|
+
function parseDuration(text) {
|
|
6
|
+
const trimmed = text.trim();
|
|
7
|
+
let days = 0;
|
|
8
|
+
let hours;
|
|
9
|
+
let minutes;
|
|
10
|
+
let seconds;
|
|
11
|
+
const withDays = trimmed.match(WITH_DAYS);
|
|
12
|
+
if (withDays) {
|
|
13
|
+
days = Number(withDays[1]);
|
|
14
|
+
hours = Number(withDays[2]);
|
|
15
|
+
minutes = Number(withDays[3] ?? 0);
|
|
16
|
+
seconds = Number(withDays[4] ?? 0);
|
|
17
|
+
if (hours > 23) return null;
|
|
18
|
+
} else {
|
|
19
|
+
const withoutDays = trimmed.match(WITHOUT_DAYS);
|
|
20
|
+
if (!withoutDays) return null;
|
|
21
|
+
hours = Number(withoutDays[1]);
|
|
22
|
+
minutes = Number(withoutDays[2]);
|
|
23
|
+
seconds = Number(withoutDays[3]);
|
|
24
|
+
}
|
|
25
|
+
if (minutes > 59 || seconds > 59) return null;
|
|
26
|
+
return days * 86400 + hours * 3600 + minutes * 60 + seconds;
|
|
27
|
+
}
|
|
28
|
+
function formatDuration(totalSeconds) {
|
|
29
|
+
if (!Number.isFinite(totalSeconds) || totalSeconds < 0) return "";
|
|
30
|
+
const parts = Duration.fromObject({ seconds: Math.floor(totalSeconds) }).shiftTo("days", "hours", "minutes", "seconds");
|
|
31
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
32
|
+
const time = `${pad(parts.hours)}:${pad(parts.minutes)}:${pad(parts.seconds)}`;
|
|
33
|
+
return parts.days > 0 ? `${parts.days}-${time}` : time;
|
|
34
|
+
}
|
|
35
|
+
var FLEX_MAX_DURATION_RANGE = {
|
|
36
|
+
min: 600,
|
|
37
|
+
max: 604800
|
|
38
|
+
};
|
|
39
|
+
var FLEX_WAIT_TIME_RANGE = {
|
|
40
|
+
min: 30,
|
|
41
|
+
max: 604800
|
|
42
|
+
};
|
|
43
|
+
var STANDARD_MAX_DURATION_RANGE = {
|
|
44
|
+
min: 30,
|
|
45
|
+
max: 10368e3
|
|
46
|
+
};
|
|
47
|
+
var DURATION_PATH = /^partitions\[\d+\]\.(maxDuration|flexStartWaitTime|suspendTime)$/;
|
|
48
|
+
function collectPartitionDurationIssues(partitions, invalidDurationPaths) {
|
|
49
|
+
const issues = new Set(invalidDurationPaths.filter((path) => DURATION_PATH.test(path)));
|
|
50
|
+
(partitions ?? []).forEach((partition, i) => {
|
|
51
|
+
const p = partition;
|
|
52
|
+
const check = (fieldName, range, required) => {
|
|
53
|
+
const raw = p?.[fieldName];
|
|
54
|
+
if (raw === void 0 || raw === null || raw === "") {
|
|
55
|
+
if (required) issues.add(`partitions[${i}].${fieldName}`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const value = Number(raw);
|
|
59
|
+
if (!Number.isFinite(value) || value < range.min || value > range.max) issues.add(`partitions[${i}].${fieldName}`);
|
|
60
|
+
};
|
|
61
|
+
if (p?.provisioningMode === "flex") {
|
|
62
|
+
check("maxDuration", FLEX_MAX_DURATION_RANGE, true);
|
|
63
|
+
check("flexStartWaitTime", FLEX_WAIT_TIME_RANGE, true);
|
|
64
|
+
} else check("maxDuration", STANDARD_MAX_DURATION_RANGE, false);
|
|
65
|
+
});
|
|
66
|
+
return [...issues];
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
export { FLEX_MAX_DURATION_RANGE, FLEX_WAIT_TIME_RANGE, STANDARD_MAX_DURATION_RANGE, collectPartitionDurationIssues, formatDuration, parseDuration };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getValueUsingPath } from "./getValueUsingPath.js";
|
|
2
|
+
import { checkShowIfObject } from "./checkShowIfObject.js";
|
|
3
|
+
//#region src/form/utils/getParentValue.ts
|
|
4
|
+
function getParentValue(index, targetField, values, dependentPath, field) {
|
|
5
|
+
let parentValue;
|
|
6
|
+
if (typeof targetField === "object" && targetField !== null && !Array.isArray(targetField)) parentValue = !checkShowIfObject(targetField, values, index).includes(false);
|
|
7
|
+
else if (field.depends_on) {
|
|
8
|
+
dependentPath = field.depends_on;
|
|
9
|
+
if (index !== void 0) dependentPath = field.depends_on.replace("[index]", `[${index}]`);
|
|
10
|
+
const dependsOnValue = getValueUsingPath(values, dependentPath);
|
|
11
|
+
const dependsOnText = dependsOnValue === null || dependsOnValue === void 0 ? void 0 : String(dependsOnValue);
|
|
12
|
+
if (Array.isArray(targetField)) parentValue = targetField.includes(dependsOnValue) || targetField.includes(dependsOnText);
|
|
13
|
+
else if (typeof targetField === "string") parentValue = dependsOnText !== void 0 && targetField.includes(dependsOnText);
|
|
14
|
+
else parentValue = targetField === dependsOnValue;
|
|
15
|
+
} else {
|
|
16
|
+
dependentPath = typeof targetField === "string" ? targetField : "";
|
|
17
|
+
if (index !== void 0 && typeof targetField === "string") dependentPath = targetField.replace("[index]", `[${index}]`);
|
|
18
|
+
parentValue = getValueUsingPath(values, dependentPath);
|
|
19
|
+
}
|
|
20
|
+
return parentValue;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { getParentValue };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/form/utils/getPlaceholder.ts
|
|
2
|
+
/** `placeholder=""` (empty string) intentionally overrides the default; undefined does not. */
|
|
3
|
+
function getPlaceholder(placeholder, defaultValue) {
|
|
4
|
+
if (placeholder !== void 0) return placeholder;
|
|
5
|
+
if (defaultValue && (typeof defaultValue === "string" || typeof defaultValue === "number")) return defaultValue.toString();
|
|
6
|
+
return "";
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { getPlaceholder };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/form/utils/getValueUsingPath.ts
|
|
2
|
+
function getValueUsingPath(obj, path) {
|
|
3
|
+
if (typeof path !== "string" || !path) return;
|
|
4
|
+
const keys = path.split(".");
|
|
5
|
+
let current = obj;
|
|
6
|
+
for (const key of keys) {
|
|
7
|
+
if (!current || typeof current !== "object") return;
|
|
8
|
+
const container = current;
|
|
9
|
+
if (key.includes("[")) {
|
|
10
|
+
const [arrayKey = "", indexStr = ""] = key.split("[");
|
|
11
|
+
const index = parseInt(indexStr.slice(0, -1), 10);
|
|
12
|
+
const list = container[arrayKey];
|
|
13
|
+
if (!Array.isArray(list) || isNaN(index)) return;
|
|
14
|
+
current = list[index];
|
|
15
|
+
} else {
|
|
16
|
+
if (!(key in container)) return;
|
|
17
|
+
current = container[key];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return current;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { getValueUsingPath };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/form/utils/secondaryField.ts
|
|
2
|
+
function findSecondaryOption(options, value) {
|
|
3
|
+
for (const candidate of options) {
|
|
4
|
+
if (!candidate || typeof candidate !== "object") continue;
|
|
5
|
+
const option = candidate;
|
|
6
|
+
if (option.value === value) return option;
|
|
7
|
+
if (Array.isArray(option.options)) {
|
|
8
|
+
const nestedOption = findSecondaryOption(option.options, value);
|
|
9
|
+
if (nestedOption) return nestedOption;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function applySecondaryField(secondaryField, secondaryValue, setFieldValue) {
|
|
14
|
+
if (secondaryField === void 0 || secondaryValue === void 0) return;
|
|
15
|
+
const fields = Array.isArray(secondaryField) ? secondaryField : [secondaryField];
|
|
16
|
+
const values = Array.isArray(secondaryValue) ? secondaryValue : [secondaryValue];
|
|
17
|
+
fields.forEach((field, index) => {
|
|
18
|
+
setFieldValue(field, values[index]);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { applySecondaryField, findSecondaryOption };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { ChevronDownIcon, ChevronRightIcon, ErrorIcon, InfoIcon, WarningIcon } from "../icons.js";
|
|
2
|
+
import { keyedByContent } from "../components/keys.js";
|
|
3
|
+
import cx from "classnames";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/graph/AnnotationBanner.tsx
|
|
7
|
+
var typeOrder = {
|
|
8
|
+
error: 0,
|
|
9
|
+
warning: 1,
|
|
10
|
+
notice: 2
|
|
11
|
+
};
|
|
12
|
+
var typeConfig = {
|
|
13
|
+
error: {
|
|
14
|
+
icon: ErrorIcon,
|
|
15
|
+
label: "Error",
|
|
16
|
+
accentClass: "text-red-500",
|
|
17
|
+
bgClass: "bg-red-500/5 dark:bg-red-500/10",
|
|
18
|
+
countBg: "bg-red-500/15 text-red-700 dark:text-red-400"
|
|
19
|
+
},
|
|
20
|
+
warning: {
|
|
21
|
+
icon: WarningIcon,
|
|
22
|
+
label: "Warning",
|
|
23
|
+
accentClass: "text-yellow-500",
|
|
24
|
+
bgClass: "bg-yellow-500/5 dark:bg-yellow-500/10",
|
|
25
|
+
countBg: "bg-yellow-500/15 text-yellow-700 dark:text-yellow-400"
|
|
26
|
+
},
|
|
27
|
+
notice: {
|
|
28
|
+
icon: InfoIcon,
|
|
29
|
+
label: "Notice",
|
|
30
|
+
accentClass: "text-blue-500",
|
|
31
|
+
bgClass: "bg-blue-500/5 dark:bg-blue-500/10",
|
|
32
|
+
countBg: "bg-blue-500/15 text-blue-700 dark:text-blue-400"
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
function collectAnnotations(executedJobs, parentPath) {
|
|
36
|
+
const annotations = [];
|
|
37
|
+
for (const [jobName, job] of Object.entries(executedJobs)) {
|
|
38
|
+
const fullJobName = parentPath ? `${parentPath} > ${jobName}` : jobName;
|
|
39
|
+
const steps = job?.steps;
|
|
40
|
+
if (!Array.isArray(steps)) continue;
|
|
41
|
+
for (let stepIndex = 0; stepIndex < steps.length; stepIndex++) {
|
|
42
|
+
const step = steps[stepIndex];
|
|
43
|
+
const stepAnnotations = step?.annotations;
|
|
44
|
+
if (Array.isArray(stepAnnotations)) {
|
|
45
|
+
for (const annotation of stepAnnotations) if (annotation?.message) annotations.push({
|
|
46
|
+
type: annotation.type || "notice",
|
|
47
|
+
message: annotation.message,
|
|
48
|
+
title: annotation.title,
|
|
49
|
+
file: annotation.file,
|
|
50
|
+
line: annotation.line,
|
|
51
|
+
jobName: fullJobName,
|
|
52
|
+
stepName: step?.name,
|
|
53
|
+
stepIndex
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const subJobs = step?.subworkflow?.jobs;
|
|
57
|
+
if (subJobs && typeof subJobs === "object") annotations.push(...collectAnnotations(subJobs, fullJobName));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
annotations.sort((a, b) => (typeOrder[a.type] ?? 2) - (typeOrder[b.type] ?? 2));
|
|
61
|
+
return annotations;
|
|
62
|
+
}
|
|
63
|
+
function AnnotationBanner({ executedJobs }) {
|
|
64
|
+
const [expanded, setExpanded] = useState(false);
|
|
65
|
+
if (!executedJobs) return null;
|
|
66
|
+
const annotations = collectAnnotations(executedJobs);
|
|
67
|
+
if (annotations.length === 0) return null;
|
|
68
|
+
const counts = {
|
|
69
|
+
error: 0,
|
|
70
|
+
warning: 0,
|
|
71
|
+
notice: 0
|
|
72
|
+
};
|
|
73
|
+
for (const a of annotations) counts[a.type]++;
|
|
74
|
+
const ChevronIcon = expanded ? ChevronDownIcon : ChevronRightIcon;
|
|
75
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
76
|
+
className: cx("rounded-lg border border-[var(--theme-border)] overflow-hidden", "bg-[var(--theme-panel-bg)]"),
|
|
77
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
78
|
+
type: "button",
|
|
79
|
+
onClick: () => setExpanded((prev) => !prev),
|
|
80
|
+
className: cx("w-full flex items-center gap-3 px-4 py-2.5 text-left", "hover:bg-[var(--theme-hover)] transition-colors", expanded && "border-b border-[var(--theme-border)]"),
|
|
81
|
+
children: [
|
|
82
|
+
/* @__PURE__ */ jsx(ChevronIcon, { className: "w-3.5 h-3.5 text-[var(--theme-muted-text-color)] shrink-0" }),
|
|
83
|
+
/* @__PURE__ */ jsx("span", {
|
|
84
|
+
className: "text-sm font-medium text-[var(--theme-panel-color)]",
|
|
85
|
+
children: "Annotations"
|
|
86
|
+
}),
|
|
87
|
+
/* @__PURE__ */ jsx("div", {
|
|
88
|
+
className: "flex items-center gap-1.5",
|
|
89
|
+
children: [
|
|
90
|
+
"error",
|
|
91
|
+
"warning",
|
|
92
|
+
"notice"
|
|
93
|
+
].map((type) => {
|
|
94
|
+
if (!counts[type]) return null;
|
|
95
|
+
const config = typeConfig[type];
|
|
96
|
+
const Icon = config.icon;
|
|
97
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
98
|
+
className: cx("inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium", config.countBg),
|
|
99
|
+
children: [/* @__PURE__ */ jsx(Icon, { className: "w-3 h-3" }), counts[type]]
|
|
100
|
+
}, type);
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
]
|
|
104
|
+
}), expanded && /* @__PURE__ */ jsx("div", {
|
|
105
|
+
className: "divide-y divide-[var(--theme-border)] max-h-[400px] overflow-y-auto",
|
|
106
|
+
children: keyedByContent(annotations, (a) => a.id ?? `${a.type}:${a.title}:${a.message}`).map(({ key, item: annotation }) => {
|
|
107
|
+
const config = typeConfig[annotation.type] || typeConfig.notice;
|
|
108
|
+
const Icon = config.icon;
|
|
109
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
110
|
+
className: cx("flex items-start gap-2.5 px-4 py-2 text-sm", config.bgClass),
|
|
111
|
+
children: [/* @__PURE__ */ jsx(Icon, { className: cx("w-4 h-4 mt-0.5 shrink-0", config.accentClass) }), /* @__PURE__ */ jsxs("div", {
|
|
112
|
+
className: "flex-1 min-w-0",
|
|
113
|
+
children: [
|
|
114
|
+
/* @__PURE__ */ jsxs("span", {
|
|
115
|
+
className: cx("font-medium", config.accentClass),
|
|
116
|
+
children: [annotation.title || config.label, ":"]
|
|
117
|
+
}),
|
|
118
|
+
" ",
|
|
119
|
+
/* @__PURE__ */ jsx("span", {
|
|
120
|
+
className: "text-[var(--theme-panel-color)]",
|
|
121
|
+
children: annotation.message
|
|
122
|
+
}),
|
|
123
|
+
/* @__PURE__ */ jsxs("span", {
|
|
124
|
+
className: "text-[var(--theme-muted-text-color)] ml-2 text-xs",
|
|
125
|
+
children: [
|
|
126
|
+
"in ",
|
|
127
|
+
annotation.jobName,
|
|
128
|
+
" →",
|
|
129
|
+
" ",
|
|
130
|
+
annotation.stepName || `step ${annotation.stepIndex}`
|
|
131
|
+
]
|
|
132
|
+
})
|
|
133
|
+
]
|
|
134
|
+
})]
|
|
135
|
+
}, key);
|
|
136
|
+
})
|
|
137
|
+
})]
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
export { AnnotationBanner };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { AnimatePresence, motion } from "framer-motion";
|
|
4
|
+
//#region src/graph/Collapse.tsx
|
|
5
|
+
function Collapse({ expanded, children, releaseOverflow = true }) {
|
|
6
|
+
const [overflowVisible, setOverflowVisible] = useState(false);
|
|
7
|
+
return /* @__PURE__ */ jsx(AnimatePresence, {
|
|
8
|
+
initial: false,
|
|
9
|
+
children: expanded && /* @__PURE__ */ jsx(motion.div, {
|
|
10
|
+
initial: {
|
|
11
|
+
height: 0,
|
|
12
|
+
opacity: 0
|
|
13
|
+
},
|
|
14
|
+
animate: {
|
|
15
|
+
height: "auto",
|
|
16
|
+
opacity: 1
|
|
17
|
+
},
|
|
18
|
+
exit: {
|
|
19
|
+
height: 0,
|
|
20
|
+
opacity: 0
|
|
21
|
+
},
|
|
22
|
+
transition: {
|
|
23
|
+
duration: .2,
|
|
24
|
+
ease: [
|
|
25
|
+
.25,
|
|
26
|
+
.1,
|
|
27
|
+
.25,
|
|
28
|
+
1
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
style: { overflow: overflowVisible ? "visible" : "hidden" },
|
|
32
|
+
onAnimationStart: () => setOverflowVisible(false),
|
|
33
|
+
onAnimationComplete: () => {
|
|
34
|
+
if (expanded && releaseOverflow) setOverflowVisible(true);
|
|
35
|
+
},
|
|
36
|
+
children
|
|
37
|
+
}, "collapse")
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { Collapse };
|