@parallelworks/ui 0.18.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/README.md +86 -6
- package/dist/ai/adapter/memoryStore.d.ts +8 -0
- package/dist/ai/adapter/memoryStore.js +152 -0
- package/dist/ai/adapter/mock/index.d.ts +2 -0
- package/dist/ai/adapter/mock/index.js +3 -0
- package/dist/ai/adapter/mock/mockAdapter.d.ts +4 -0
- package/dist/ai/adapter/mock/mockAdapter.js +81 -0
- package/dist/ai/adapter/openai/createOpenAIStream.d.ts +9 -0
- package/dist/ai/adapter/openai/createOpenAIStream.js +33 -0
- package/dist/ai/adapter/openai/errors.d.ts +3 -0
- package/dist/ai/adapter/openai/errors.js +37 -0
- package/dist/ai/adapter/openai/index.d.ts +6 -0
- package/dist/ai/adapter/openai/index.js +6 -0
- package/dist/ai/adapter/openai/openaiAdapter.d.ts +9 -0
- package/dist/ai/adapter/openai/openaiAdapter.js +54 -0
- package/dist/ai/adapter/openai/responses.d.ts +4 -0
- package/dist/ai/adapter/openai/responses.js +108 -0
- package/dist/ai/adapter/openai/sse.d.ts +24 -0
- package/dist/ai/adapter/openai/sse.js +112 -0
- package/dist/ai/adapter/openai/wire.d.ts +40 -0
- package/dist/ai/adapter/types.d.ts +131 -0
- package/dist/ai/adapter/types.js +11 -0
- package/dist/ai/agent/classifier.d.ts +2 -0
- package/dist/ai/agent/classifier.js +12 -0
- package/dist/ai/agent/diff.d.ts +35 -0
- package/dist/ai/agent/diff.js +223 -0
- package/dist/ai/agent/diffHighlight.d.ts +6 -0
- package/dist/ai/agent/diffHighlight.js +101 -0
- package/dist/ai/agent/index.d.ts +6 -0
- package/dist/ai/agent/permissions.d.ts +11 -0
- package/dist/ai/agent/permissions.js +29 -0
- package/dist/ai/agent/toolfmt.d.ts +18 -0
- package/dist/ai/agent/toolfmt.js +383 -0
- package/dist/ai/agent/transcript.d.ts +38 -0
- package/dist/ai/agent/transcript.js +127 -0
- package/dist/ai/ai.css +325 -0
- package/dist/ai/components/AllocationSelector.d.ts +4 -0
- package/dist/ai/components/AllocationSelector.js +56 -0
- package/dist/ai/components/AttachmentManager.d.ts +1 -0
- package/dist/ai/components/AttachmentManager.js +144 -0
- package/dist/ai/components/AttachmentUpload.d.ts +24 -0
- package/dist/ai/components/AttachmentUpload.js +179 -0
- package/dist/ai/components/BlockedGroupBanner.d.ts +1 -0
- package/dist/ai/components/BlockedGroupBanner.js +29 -0
- package/dist/ai/components/BranchNavigator.d.ts +8 -0
- package/dist/ai/components/BranchNavigator.js +57 -0
- package/dist/ai/components/ChatEmptyState.d.ts +3 -0
- package/dist/ai/components/ChatEmptyState.js +171 -0
- package/dist/ai/components/ChatInput.d.ts +45 -0
- package/dist/ai/components/ChatInput.js +265 -0
- package/dist/ai/components/ChatLayout.d.ts +5 -0
- package/dist/ai/components/ChatLayout.js +15 -0
- package/dist/ai/components/ChatMessage.d.ts +24 -0
- package/dist/ai/components/ChatMessage.js +338 -0
- package/dist/ai/components/ChatMessageList.d.ts +35 -0
- package/dist/ai/components/ChatMessageList.js +301 -0
- package/dist/ai/components/ChatSidebar.d.ts +5 -0
- package/dist/ai/components/ChatSidebar.js +345 -0
- package/dist/ai/components/ChatThread.d.ts +3 -0
- package/dist/ai/components/ChatThread.js +198 -0
- package/dist/ai/components/ComposerChrome.d.ts +18 -0
- package/dist/ai/components/ComposerChrome.js +50 -0
- package/dist/ai/components/ComposerFrame.d.ts +16 -0
- package/dist/ai/components/ComposerFrame.js +33 -0
- package/dist/ai/components/DragOverlay.d.ts +5 -0
- package/dist/ai/components/DragOverlay.js +20 -0
- package/dist/ai/components/ModelSelector.d.ts +6 -0
- package/dist/ai/components/ModelSelector.js +343 -0
- package/dist/ai/components/ShareDialog.d.ts +11 -0
- package/dist/ai/components/ShareDialog.js +260 -0
- package/dist/ai/components/SlashMenu.d.ts +28 -0
- package/dist/ai/components/SlashMenu.js +91 -0
- package/dist/ai/components/agent/ActivityLine.d.ts +21 -0
- package/dist/ai/components/agent/ActivityLine.js +151 -0
- package/dist/ai/components/agent/AgentMessageParts.d.ts +54 -0
- package/dist/ai/components/agent/AgentMessageParts.js +721 -0
- package/dist/ai/components/agent/PermissionPicker.d.ts +11 -0
- package/dist/ai/components/agent/PermissionPicker.js +38 -0
- package/dist/ai/components/attachmentKeys.d.ts +4 -0
- package/dist/ai/components/attachmentKeys.js +10 -0
- package/dist/ai/core/ChatProvider.d.ts +66 -0
- package/dist/ai/core/ChatProvider.js +848 -0
- package/dist/ai/core/KeyboardShortcutsProvider.d.ts +5 -0
- package/dist/ai/core/KeyboardShortcutsProvider.js +9 -0
- package/dist/ai/core/chatReducer.d.ts +114 -0
- package/dist/ai/core/chatReducer.js +223 -0
- package/dist/ai/core/config.d.ts +47 -0
- package/dist/ai/core/config.js +45 -0
- package/dist/ai/core/events.d.ts +1 -0
- package/dist/ai/core/events.js +4 -0
- package/dist/ai/core/exportConversation.d.ts +4 -0
- package/dist/ai/core/exportConversation.js +42 -0
- package/dist/ai/core/greeting.d.ts +3 -0
- package/dist/ai/core/greeting.js +38 -0
- package/dist/ai/core/parts.d.ts +11 -0
- package/dist/ai/core/parts.js +84 -0
- package/dist/ai/core/useDragDrop.d.ts +14 -0
- package/dist/ai/core/useDragDrop.js +36 -0
- package/dist/ai/core/useKeyboardShortcuts.d.ts +12 -0
- package/dist/ai/core/useKeyboardShortcuts.js +77 -0
- package/dist/ai/core/useSSEStream.d.ts +34 -0
- package/dist/ai/core/useSSEStream.js +98 -0
- package/dist/ai/index.d.ts +40 -0
- package/dist/ai/index.js +44 -0
- package/dist/ai/strings.d.ts +167 -0
- package/dist/ai/strings.js +175 -0
- package/dist/ai/types.d.ts +236 -0
- package/dist/ai/ui/Avatar.d.ts +8 -0
- package/dist/ai/ui/Avatar.js +35 -0
- package/dist/ai/ui/Dropdown.d.ts +31 -0
- package/dist/ai/ui/Dropdown.js +110 -0
- package/dist/ai/ui/Markdown.d.ts +8 -0
- package/dist/ai/ui/Markdown.js +79 -0
- package/dist/ai/ui/Notice.d.ts +21 -0
- package/dist/ai/ui/Notice.js +77 -0
- package/dist/ai/ui/buttons.d.ts +1 -0
- package/dist/ai/ui/codeBreaks.d.ts +16 -0
- package/dist/ai/ui/codeBreaks.js +36 -0
- package/dist/ai/ui/prose.d.ts +1 -0
- package/dist/ai/ui/prose.js +13 -0
- package/dist/ai/ui/sidebar.d.ts +81 -0
- package/dist/ai/ui/sidebar.js +148 -0
- package/dist/ai/utils.d.ts +4 -0
- package/dist/ai/utils.js +23 -0
- package/dist/assets/{editor.worker-CuBRIwi-.js → editor.worker-BmHUIVG4.js} +194 -163
- package/dist/assets/{json.worker-8ytS02vz.js → json.worker-D8bJ92nw.js} +384 -338
- package/dist/assets/{yaml.worker-DJC-VUcv.js → yaml.worker-C4gyGAko.js} +15657 -13823
- package/dist/components/AddMenu.js +46 -0
- package/dist/components/Avatar.d.ts +1 -1
- package/dist/components/Avatar.js +46 -0
- package/dist/{chunks/BareModal-BtRiQezg.js → components/BareModal.js} +1 -1
- package/dist/components/Breadcrumbs.d.ts +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/components/ConfirmModal.js +74 -0
- package/dist/components/CopyToClipboard.js +81 -0
- package/dist/{chunks/CreateModal-BY6DLmur.js → components/CreateModal.js} +10 -189
- package/dist/components/DescriptionList.js +42 -0
- package/dist/components/Dropdown.d.ts +1 -1
- package/dist/components/Dropdown.js +349 -0
- package/dist/components/EmptyState.d.ts +1 -1
- 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/components/Indicator.d.ts +2 -2
- package/dist/{chunks/Indicator-hBSIxOPK.js → components/Indicator.js} +1 -1
- package/dist/components/Input.d.ts +1 -1
- package/dist/components/Input.js +88 -0
- package/dist/components/LetterBadge.d.ts +1 -1
- 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/MarkdownImpl.d.ts +1 -1
- 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/components/Provider.d.ts +16 -65
- package/dist/{chunks/Provider-Ghua9PkN.js → components/Provider.js} +54 -20
- 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.d.ts +1 -1
- package/dist/components/SettingRow.js +35 -0
- package/dist/components/SettingsCard.js +31 -0
- package/dist/components/SettingsGroup.d.ts +1 -1
- 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-4OHjdKdO.js → components/Table.js} +7 -5
- package/dist/components/Toggle.js +20 -0
- package/dist/{chunks/Tooltip-Crxo_eU_.js → components/Tooltip.js} +6 -4
- package/dist/{chunks/StatusBadge-C1Blx_cW.js → components/dropdownUtils.js} +2 -63
- package/dist/components/focus.d.ts +2 -0
- package/dist/components/focus.js +7 -0
- package/dist/components/ghostButton.js +7 -0
- package/dist/components/inputClasses.js +4 -0
- package/dist/components/keys.d.ts +12 -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/duration.d.ts +3 -0
- package/dist/duration.js +17 -0
- package/dist/editor/Editor.js +13 -0
- package/dist/editor/EditorField.js +53 -0
- package/dist/editor/FormCodePanel.js +173 -0
- package/dist/editor/Monaco.d.ts +1 -20
- package/dist/editor/Monaco.js +112 -0
- package/dist/editor/index.d.ts +2 -1
- package/dist/editor/index.js +7 -2
- package/dist/editor/themes.js +91 -0
- package/dist/editor/workers.js +29 -0
- package/dist/editor/yaml.d.ts +5 -0
- package/dist/editor/yaml.js +15 -0
- package/dist/engine.d.ts +98 -0
- package/dist/file-explorer/FileExplorer.d.ts +11 -2
- package/dist/file-explorer/FileExplorer.js +1402 -0
- package/dist/file-explorer/FileExplorerContext.d.ts +1 -1
- package/dist/file-explorer/FileExplorerContext.js +370 -0
- package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +1 -1
- package/dist/{chunks/CodePreviewEditor-4lx3kE-w.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.d.ts +1 -1
- 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.d.ts +1 -1
- 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.d.ts +4 -4
- package/dist/file-explorer/helpers.js +537 -0
- package/dist/file-explorer/index.d.ts +3 -3
- package/dist/file-explorer/index.js +7 -5705
- 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/types.d.ts +6 -1
- package/dist/file-explorer/lib/utils.d.ts +1 -3
- 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.d.ts +1 -1
- package/dist/file-explorer/useNearEnd.js +27 -0
- package/dist/form/FieldWrapper.d.ts +2 -2
- 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.d.ts +1 -1
- 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.d.ts +4 -21
- 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.d.ts +11 -12
- package/dist/form/index.js +18 -2445
- package/dist/form/lib.d.ts +6 -1
- package/dist/{chunks/FieldWrapper-Bef01EWO.js → form/lib.js} +5 -104
- package/dist/form/types/fieldComponentTypes.d.ts +3 -2
- package/dist/form/types/fieldTypes.d.ts +6 -20
- package/dist/form/useParsedOpts.d.ts +1 -1
- 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/{slurmDuration.d.ts → duration.d.ts} +2 -2
- 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/{workflow/index.js → graph/DependencyGraph.js} +76 -1163
- package/dist/graph/JobSummary.js +104 -0
- package/dist/{workflow → graph}/MatrixGroup.d.ts +2 -2
- package/dist/graph/MatrixGroup.js +107 -0
- package/dist/graph/Reveal.js +57 -0
- package/dist/graph/TreeView.js +711 -0
- package/dist/{workflow → graph}/index.d.ts +1 -1
- package/dist/graph/index.js +2 -0
- package/dist/{workflow → graph}/types.d.ts +3 -3
- package/dist/graph/types.js +6 -0
- package/dist/icons.d.ts +20 -21
- package/dist/index.d.ts +38 -40
- package/dist/index.js +47 -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.d.ts +1 -1
- package/dist/list/ListTable.js +163 -0
- package/dist/list/ListViewControls.d.ts +2 -2
- 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.d.ts +9 -9
- 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/logviewer/LogViewer.d.ts +1 -1
- package/dist/logviewer/LogViewer.js +750 -0
- package/dist/logviewer/index.d.ts +1 -0
- package/dist/logviewer/index.js +3 -742
- package/dist/logviewer/segments.d.ts +9 -0
- package/dist/logviewer/segments.js +80 -0
- package/dist/styles/fonts.css +4 -4
- package/dist/styles/theme.css +6 -4
- package/dist/styles.css +1 -1
- package/dist/theme/index.js +2 -2
- package/package.json +38 -14
- package/LICENSE +0 -202
- package/dist/chunks/Monaco-C1POOdVv.js +0 -1046
- package/dist/chunks/PageHeader-l49p1nM9.js +0 -690
- package/dist/chunks/SwitchToggle-CHPP8uZQ.js +0 -755
- package/dist/chunks/editor-9_uVtUyy.js +0 -347
- package/dist/chunks/list-qrojZZNv.js +0 -1411
- package/dist/editor/usesGitlab.d.ts +0 -97
- package/dist/form/Fields/BucketReadOnlyField.d.ts +0 -7
- package/dist/form/types/workflow-schema.d.ts +0 -1145
- package/dist/form/utils/pwResolver.d.ts +0 -18
- package/dist/{chunks/MarkdownImpl-Bq4QhrtA.js → components/MarkdownImpl.js} +1 -1
- /package/dist/{workflow → graph}/AnnotationBanner.d.ts +0 -0
- /package/dist/{workflow → graph}/Collapse.d.ts +0 -0
- /package/dist/{workflow → graph}/DependencyGraph.d.ts +0 -0
- /package/dist/{workflow → graph}/JobSummary.d.ts +0 -0
- /package/dist/{workflow → graph}/Reveal.d.ts +0 -0
- /package/dist/{workflow → graph}/TreeView.d.ts +0 -0
package/dist/form/lib.d.ts
CHANGED
|
@@ -12,4 +12,9 @@ export declare function enforceOneMustBeTrue(items: Array<Record<string, unknown
|
|
|
12
12
|
export declare function flattenGroups(schema: unknown): Record<string, unknown>;
|
|
13
13
|
/**Not a pure function. Edits 'obj' passed into function */
|
|
14
14
|
export declare function impureSetValueFromPath(obj: Record<string, unknown>, path: string, value: unknown): void;
|
|
15
|
-
export declare function initializeValues(options: unknown, srcData?: object,
|
|
15
|
+
export declare function initializeValues(options: unknown, srcData?: object,
|
|
16
|
+
/** Fields whose schema default the host wants left blank. */
|
|
17
|
+
blankDefault?: (field: {
|
|
18
|
+
type?: string;
|
|
19
|
+
default?: unknown;
|
|
20
|
+
}) => boolean): Record<string, unknown> | undefined;
|
|
@@ -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) {
|
|
@@ -122,7 +74,7 @@ function impureSetValueFromPath(obj, path, value) {
|
|
|
122
74
|
}
|
|
123
75
|
current[pathArray[pathArray.length - 1]] = value;
|
|
124
76
|
}
|
|
125
|
-
function initializeValues(options, srcData = {},
|
|
77
|
+
function initializeValues(options, srcData = {}, blankDefault) {
|
|
126
78
|
if (!options || typeof options !== "object") return;
|
|
127
79
|
const schema = options;
|
|
128
80
|
const source = srcData;
|
|
@@ -168,7 +120,7 @@ function initializeValues(options, srcData = {}, ignoreDefaultStrings = false) {
|
|
|
168
120
|
if ((fieldSchema.type === "dropdown" || fieldSchema.type === "storage") && fieldSchema.secondaryField && fieldSchema.options && Array.isArray(fieldSchema.options)) {
|
|
169
121
|
const option = findSecondaryOption(fieldSchema.options, data[field]);
|
|
170
122
|
applySecondaryField(fieldSchema.secondaryField, option?.secondaryValue, (secondaryField, secondaryValue) => {
|
|
171
|
-
if (!(fieldSchema.type === "storage" && Object.
|
|
123
|
+
if (!(fieldSchema.type === "storage" && Object.hasOwn(options, secondaryField) && source[secondaryField] !== void 0)) impureSetValueFromPath(acc, secondaryField, secondaryValue);
|
|
172
124
|
});
|
|
173
125
|
}
|
|
174
126
|
return acc;
|
|
@@ -195,61 +147,10 @@ function initializeValues(options, srcData = {}, ignoreDefaultStrings = false) {
|
|
|
195
147
|
}
|
|
196
148
|
}
|
|
197
149
|
if (fieldSchema.type === "multi-dropdown" || fieldSchema.type === "checkbox-group") acc[field] = [];
|
|
198
|
-
if (fieldSchema.default !== void 0)
|
|
199
|
-
const dflt = fieldSchema.default;
|
|
200
|
-
const isPwResource = typeof dflt === "string" && dflt.startsWith("pw://");
|
|
201
|
-
acc[field] = fieldSchema.type === "string" || ignoreDefaultStrings && !isPwResource && (fieldSchema.type === "textarea" || fieldSchema.type === "compute-clusters" || fieldSchema.type === "compute-resources") ? "" : dflt;
|
|
202
|
-
}
|
|
150
|
+
if (fieldSchema.default !== void 0) acc[field] = fieldSchema.type === "string" || blankDefault?.(fieldSchema) ? "" : fieldSchema.default;
|
|
203
151
|
if (fieldSchema.prefillDefault && fieldSchema.default !== void 0) acc[field] = fieldSchema.default;
|
|
204
152
|
return acc;
|
|
205
153
|
}, data);
|
|
206
154
|
}
|
|
207
155
|
//#endregion
|
|
208
|
-
|
|
209
|
-
function FieldWrapper({ label, tooltipComponent, description, labelPosition = "left", spaceCompact = false, optional = false, children }) {
|
|
210
|
-
const isOptional = Boolean(resolvedFlag(optional));
|
|
211
|
-
const uid = useId();
|
|
212
|
-
const id = `${uid}control`;
|
|
213
|
-
const labelId = `${uid}label`;
|
|
214
|
-
const descriptionId = description ? `${uid}description` : void 0;
|
|
215
|
-
const field = useMemo(() => ({
|
|
216
|
-
required: !isOptional,
|
|
217
|
-
id,
|
|
218
|
-
labelId,
|
|
219
|
-
descriptionId
|
|
220
|
-
}), [
|
|
221
|
-
isOptional,
|
|
222
|
-
id,
|
|
223
|
-
labelId,
|
|
224
|
-
descriptionId
|
|
225
|
-
]);
|
|
226
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
227
|
-
className: cx("flex w-full", labelPosition === "left" ? "items-start" : "items-left flex-col"),
|
|
228
|
-
children: [/* @__PURE__ */ jsxs("label", {
|
|
229
|
-
htmlFor: id,
|
|
230
|
-
id: labelId,
|
|
231
|
-
className: cx("relative", labelPosition === "left" ? "form-label" : "form-label-top", spaceCompact && "form-label-compact"),
|
|
232
|
-
children: [
|
|
233
|
-
label,
|
|
234
|
-
!isOptional && /* @__PURE__ */ jsx(RequiredMark, {}),
|
|
235
|
-
tooltipComponent
|
|
236
|
-
]
|
|
237
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
238
|
-
className: "w-full",
|
|
239
|
-
children: [/* @__PURE__ */ jsx(FieldProvider, {
|
|
240
|
-
value: field,
|
|
241
|
-
children: typeof children === "function" ? children({
|
|
242
|
-
id,
|
|
243
|
-
labelId,
|
|
244
|
-
describedBy: descriptionId
|
|
245
|
-
}) : children
|
|
246
|
-
}), description && /* @__PURE__ */ jsx("div", {
|
|
247
|
-
id: descriptionId,
|
|
248
|
-
className: "text-xs theme-muted-text mt-1 leading-relaxed",
|
|
249
|
-
children: description
|
|
250
|
-
})]
|
|
251
|
-
})]
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
//#endregion
|
|
255
|
-
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 };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TSetFormDirty } from '../Form.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { BaseField, LabelPosition, RuntimeFieldExtensions } from './fieldTypes.js';
|
|
3
3
|
/** Intentionally loose to allow both manual types and schema-generated types. */
|
|
4
4
|
interface FieldBase {
|
|
5
5
|
type?: string;
|
|
@@ -29,5 +29,6 @@ export interface FieldComponentProps<TField extends FieldBase = FieldBase, TValu
|
|
|
29
29
|
setFieldValue?: (field: string, value: unknown, shouldValidate?: boolean) => void;
|
|
30
30
|
setFieldTouched?: (field: string, isTouched?: boolean, shouldValidate?: boolean) => void;
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
/** Props for a field component, given the field definition it renders. */
|
|
33
|
+
export type FieldProps<TField extends FieldBase = BaseField, TValue = unknown> = FieldComponentProps<TField & RuntimeFieldExtensions, TValue>;
|
|
33
34
|
export {};
|
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
import type { Hidden, Ignore, Inputs, Optional } from './workflow-schema.js';
|
|
2
1
|
export type LabelPosition = 'left' | 'top';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
id: string;
|
|
6
|
-
name?: string;
|
|
7
|
-
user?: string;
|
|
8
|
-
};
|
|
9
|
-
type InputFieldValue = Inputs[string];
|
|
10
|
-
export type SchemaField = Exclude<InputFieldValue, {
|
|
11
|
-
labelPosition?: LabelPosition;
|
|
12
|
-
}>;
|
|
13
|
-
export type FieldType<T extends SchemaField['type']> = Extract<SchemaField, {
|
|
14
|
-
type: T;
|
|
15
|
-
}> & RuntimeFieldExtensions;
|
|
2
|
+
/** A flag a field may set literally or as an expression the engine resolves. */
|
|
3
|
+
export type FieldFlag = string | boolean;
|
|
16
4
|
/** NOT part of the workflow JSON schema — added by the form system at runtime. */
|
|
17
|
-
interface RuntimeFieldExtensions {
|
|
5
|
+
export interface RuntimeFieldExtensions {
|
|
18
6
|
name?: string;
|
|
19
7
|
description?: string;
|
|
20
8
|
showInUI?: boolean;
|
|
@@ -30,19 +18,17 @@ interface RuntimeFieldExtensions {
|
|
|
30
18
|
resetOnChange?: boolean;
|
|
31
19
|
options?: unknown;
|
|
32
20
|
}
|
|
33
|
-
/** Legacy — use schema types from workflow-schema.d.ts for new field components. */
|
|
34
21
|
export interface BaseField extends RuntimeFieldExtensions {
|
|
35
22
|
type: string;
|
|
36
23
|
label?: string;
|
|
37
24
|
tooltip?: string | string[];
|
|
38
|
-
hidden?:
|
|
39
|
-
optional?:
|
|
40
|
-
ignore?:
|
|
25
|
+
hidden?: FieldFlag;
|
|
26
|
+
optional?: FieldFlag;
|
|
27
|
+
ignore?: FieldFlag;
|
|
41
28
|
collapsed?: boolean;
|
|
42
29
|
disabled?: boolean;
|
|
43
30
|
default?: unknown;
|
|
44
31
|
}
|
|
45
|
-
/** Permissive type for backward-compatible components; new code uses workflow-schema.d.ts types. */
|
|
46
32
|
type AnyField = BaseField;
|
|
47
33
|
interface WizardConfig {
|
|
48
34
|
/** Must be 'wizard' to activate wizard mode */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { WorkflowVariables } from '../engine.js';
|
|
2
2
|
/**
|
|
3
3
|
* 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/"`).
|
|
4
4
|
*/
|
|
@@ -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 };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare function
|
|
2
|
-
export declare function
|
|
1
|
+
export declare function parseDuration(text: string): number | null;
|
|
2
|
+
export declare function formatDuration(totalSeconds: number): string;
|
|
3
3
|
export declare const FLEX_MAX_DURATION_RANGE: {
|
|
4
4
|
min: number;
|
|
5
5
|
max: number;
|
|
@@ -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 };
|