@parallelworks/ui 0.20.0 → 0.21.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/dist/ai/adapter/openai/createOpenAIStream.js +3 -2
- package/dist/ai/agent/diff.d.ts +0 -1
- package/dist/ai/agent/diff.js +3 -2
- package/dist/ai/agent/toolfmt.js +2 -3
- package/dist/ai/ai.css +5 -0
- package/dist/ai/components/AllocationSelector.js +3 -2
- package/dist/ai/components/AttachmentManager.js +1 -1
- package/dist/ai/components/BranchNavigator.js +4 -2
- package/dist/ai/components/ChatInput.d.ts +2 -5
- package/dist/ai/components/ChatInput.js +10 -7
- package/dist/ai/components/ChatMessage.js +7 -7
- package/dist/ai/components/ChatSidebar.d.ts +0 -1
- package/dist/ai/components/ChatSidebar.js +4 -6
- package/dist/ai/components/ChatThread.js +5 -8
- package/dist/ai/components/ModelSelector.js +3 -2
- package/dist/ai/components/ShareDialog.js +6 -3
- package/dist/ai/components/SlashMenu.d.ts +0 -1
- package/dist/ai/components/agent/ActivityLine.d.ts +0 -1
- package/dist/ai/components/agent/ActivityLine.js +2 -2
- package/dist/ai/components/agent/AgentMessageParts.d.ts +1 -26
- package/dist/ai/components/agent/AgentMessageParts.js +4 -5
- package/dist/ai/core/ChatProvider.d.ts +2 -6
- package/dist/ai/core/ChatProvider.js +42 -67
- package/dist/ai/core/KeyboardShortcutsProvider.js +1 -1
- package/dist/ai/core/chatReducer.d.ts +0 -6
- package/dist/ai/core/chatReducer.js +1 -15
- package/dist/ai/core/useKeyboardShortcuts.d.ts +3 -1
- package/dist/ai/core/useKeyboardShortcuts.js +9 -11
- package/dist/ai/core/useSSEStream.d.ts +0 -1
- package/dist/ai/core/useSSEStream.js +5 -17
- package/dist/ai/strings.d.ts +0 -1
- package/dist/ai/strings.js +0 -1
- package/dist/ai/types.d.ts +1 -1
- package/dist/ai/ui/Avatar.d.ts +1 -2
- package/dist/ai/ui/Avatar.js +7 -18
- package/dist/ai/ui/Markdown.d.ts +1 -3
- package/dist/ai/ui/Markdown.js +1 -2
- package/dist/ai/ui/sidebar.d.ts +0 -1
- package/dist/ai/ui/sidebar.js +3 -1
- package/dist/ai/utils.js +1 -1
- package/dist/components/Avatar.js +4 -2
- package/dist/components/BareModal.js +1 -5
- package/dist/components/Breadcrumbs.js +21 -14
- package/dist/components/CollapsiblePanel.d.ts +1 -3
- package/dist/components/CollapsiblePanel.js +5 -5
- package/dist/components/Dropdown.d.ts +0 -4
- package/dist/components/Dropdown.js +5 -6
- package/dist/components/Listbox.js +14 -18
- package/dist/components/MultiSelect.js +5 -8
- package/dist/components/Pagination.js +1 -1
- package/dist/components/Provider.d.ts +0 -8
- package/dist/components/SwitchToggle.js +3 -5
- package/dist/components/Table.d.ts +1 -3
- package/dist/components/dropdownUtils.js +5 -6
- package/dist/components/relativeTime.d.ts +0 -7
- package/dist/components/relativeTime.js +1 -1
- package/dist/duration.js +1 -1
- package/dist/editor/Editor.d.ts +1 -1
- package/dist/editor/Editor.js +1 -1
- package/dist/editor/EditorField.d.ts +0 -1
- package/dist/editor/EditorField.js +8 -8
- package/dist/editor/FormCodePanel.js +14 -20
- package/dist/editor/yamlLanguage.js +2 -2
- package/dist/file-explorer/FileExplorer.js +56 -59
- package/dist/file-explorer/FileExplorerContext.d.ts +1 -2
- package/dist/file-explorer/FileExplorerContext.js +92 -125
- package/dist/file-explorer/FilePreview/Inline.d.ts +1 -2
- package/dist/file-explorer/FilePreview/Inline.js +2 -2
- package/dist/file-explorer/FilePreview/Viewer.js +0 -4
- package/dist/file-explorer/FilePreview/index.d.ts +1 -2
- package/dist/file-explorer/FilePreview/index.js +3 -3
- package/dist/file-explorer/FilePreview/parse.d.ts +2 -1
- package/dist/file-explorer/FilePreview/useObjectBlobUrl.d.ts +5 -4
- package/dist/file-explorer/FilePreview/useObjectBlobUrl.js +23 -36
- package/dist/file-explorer/FilePreview/useObjectText.d.ts +1 -2
- package/dist/file-explorer/FilePreview/useObjectText.js +5 -7
- package/dist/file-explorer/FileRow.js +1 -1
- package/dist/file-explorer/FileRowsWindow.d.ts +5 -12
- package/dist/file-explorer/FileTable.d.ts +2 -6
- package/dist/file-explorer/LoadMoreRow.d.ts +8 -0
- package/dist/file-explorer/TreeView.d.ts +0 -1
- package/dist/file-explorer/TreeView.js +6 -6
- package/dist/file-explorer/helpers.js +2 -4
- package/dist/file-explorer/lib/fileExplorer.d.ts +0 -2
- package/dist/file-explorer/lib/types.d.ts +0 -1
- package/dist/file-explorer/lib/utils.js +15 -20
- package/dist/file-explorer/toasts.js +36 -34
- package/dist/form/Fields/BooleanField.js +5 -4
- package/dist/form/Fields/CheckboxGroupField.js +5 -4
- package/dist/form/Fields/ColorField.js +5 -4
- package/dist/form/Fields/DropdownField.d.ts +0 -1
- package/dist/form/Fields/DropdownField.js +10 -13
- package/dist/form/Fields/DurationField.js +2 -2
- package/dist/form/Fields/LabelField.js +5 -5
- package/dist/form/Fields/MultiDropdownField.d.ts +1 -1
- package/dist/form/Fields/MultiDropdownField.js +8 -11
- package/dist/form/Fields/NumberField.js +6 -5
- package/dist/form/Fields/ObjectField.d.ts +1 -2
- package/dist/form/Fields/ObjectField.js +22 -21
- package/dist/form/Fields/RadioField.js +4 -3
- package/dist/form/Fields/RangeField.js +7 -6
- package/dist/form/Fields/StringField.js +2 -1
- package/dist/form/Fields/TextAreaField.js +2 -1
- package/dist/form/Form.d.ts +7 -8
- package/dist/form/Form.js +52 -78
- package/dist/form/SpecialTypes/DropdownWrapper.d.ts +0 -2
- package/dist/form/SpecialTypes/DropdownWrapper.js +1 -3
- package/dist/form/SpecialTypes/FormikCustomDropdown.d.ts +1 -3
- package/dist/form/SpecialTypes/FormikCustomDropdown.js +4 -7
- package/dist/form/SpecialTypes/FormikCustomInput.js +13 -11
- package/dist/form/Wizard/WizardContainer.js +8 -25
- package/dist/form/Wizard/WizardNavigation.d.ts +1 -1
- package/dist/form/Wizard/WizardNavigation.js +5 -6
- package/dist/form/Wizard/WizardStepContent.d.ts +1 -1
- package/dist/form/Wizard/WizardStepContent.js +2 -2
- package/dist/form/Wizard/WizardStepIndicator.js +7 -17
- package/dist/form/Wizard/types.d.ts +4 -46
- package/dist/form/Wizard/useWizardState.d.ts +2 -10
- package/dist/form/Wizard/useWizardState.js +42 -92
- package/dist/form/Wizard/utils.js +6 -11
- package/dist/form/lib.js +28 -54
- package/dist/form/types/fieldTypes.d.ts +4 -5
- package/dist/form/utils/dependentOptions.d.ts +6 -0
- package/dist/form/utils/dependentOptions.js +21 -0
- package/dist/form/utils/getParentValue.d.ts +2 -1
- package/dist/form/utils/getParentValue.js +10 -15
- package/dist/form/utils/getValueUsingPath.js +1 -1
- package/dist/graph/AnnotationBanner.d.ts +1 -1
- package/dist/graph/AnnotationBanner.js +1 -1
- package/dist/graph/Collapse.d.ts +3 -3
- package/dist/graph/Collapse.js +3 -8
- package/dist/graph/DependencyGraph.d.ts +5 -4
- package/dist/graph/DependencyGraph.js +172 -222
- package/dist/graph/JobSummary.d.ts +10 -8
- package/dist/graph/JobSummary.js +13 -13
- package/dist/graph/MatrixGroup.d.ts +5 -17
- package/dist/graph/MatrixGroup.js +11 -22
- package/dist/graph/TreeView.d.ts +1 -3
- package/dist/graph/TreeView.js +104 -491
- package/dist/graph/types.d.ts +3 -2
- package/dist/graph/util.d.ts +5 -0
- package/dist/graph/util.js +18 -0
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/list/ListViewControls.js +17 -35
- package/dist/list/RowContextMenu.js +7 -7
- package/dist/logviewer/LogViewer.js +7 -9
- package/dist/logviewer/segments.js +2 -2
- package/dist/styles/theme.css +1 -0
- package/dist/styles.css +1 -1
- package/dist/theme/index.js +5 -5
- package/package.json +28 -30
- package/dist/ai/ui/buttons.d.ts +0 -1
|
@@ -1,46 +1,36 @@
|
|
|
1
1
|
import cx from "classnames";
|
|
2
|
-
import { useMemo } from "react";
|
|
3
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
3
|
//#region src/form/Wizard/WizardStepIndicator.tsx
|
|
5
4
|
function WizardStepIndicator({ stepOrder, currentStep, steps, visitedSteps, invalidSteps, onStepClick, allowJump = false, hideStepNumbers = false }) {
|
|
6
|
-
const currentIndex =
|
|
5
|
+
const currentIndex = stepOrder.indexOf(currentStep);
|
|
7
6
|
const getStepStatus = (stepKey, index) => {
|
|
8
7
|
if (stepKey === currentStep) return "active";
|
|
9
8
|
if (index < currentIndex) return "completed";
|
|
10
9
|
return "upcoming";
|
|
11
10
|
};
|
|
12
|
-
const handleStepClick = (stepKey) => {
|
|
13
|
-
if (!allowJump || !visitedSteps.has(stepKey)) return;
|
|
14
|
-
onStepClick?.(stepKey);
|
|
15
|
-
};
|
|
16
|
-
const isClickable = (stepKey) => {
|
|
17
|
-
return allowJump && visitedSteps.has(stepKey) && stepKey !== currentStep;
|
|
18
|
-
};
|
|
19
11
|
return /* @__PURE__ */ jsx("div", {
|
|
20
12
|
className: "flex items-start justify-between w-full mb-2 gap-4 py-2",
|
|
21
13
|
children: stepOrder.map((stepKey, index) => {
|
|
22
14
|
const stepConfig = steps[stepKey];
|
|
23
15
|
const status = getStepStatus(stepKey, index);
|
|
24
16
|
const isInvalid = invalidSteps.has(stepKey);
|
|
25
|
-
const
|
|
17
|
+
const isClickable = allowJump && visitedSteps.has(stepKey) && stepKey !== currentStep;
|
|
26
18
|
const isDotActive = status === "active";
|
|
27
19
|
const isDotCompleted = status === "completed";
|
|
28
|
-
const isDotUpcoming = status === "upcoming";
|
|
29
20
|
return /* @__PURE__ */ jsxs("div", {
|
|
30
21
|
className: "flex flex-col items-center flex-1 relative",
|
|
31
22
|
children: [
|
|
32
23
|
/* @__PURE__ */ jsxs("button", {
|
|
33
24
|
type: "button",
|
|
34
|
-
onClick: () =>
|
|
35
|
-
disabled: !
|
|
25
|
+
onClick: () => onStepClick(stepKey),
|
|
26
|
+
disabled: !isClickable,
|
|
36
27
|
className: cx("w-12 h-12 rounded-full border-3 flex items-center justify-center font-bold text-base transition-all duration-300 flex-shrink-0 relative", {
|
|
37
|
-
"cursor-pointer":
|
|
38
|
-
"cursor-not-allowed": !
|
|
28
|
+
"cursor-pointer": isClickable,
|
|
29
|
+
"cursor-not-allowed": !isClickable
|
|
39
30
|
}, {
|
|
40
31
|
"text-white": isDotActive,
|
|
41
32
|
"bg-green-500 border-green-600 text-white shadow-md": isDotCompleted && !isInvalid,
|
|
42
|
-
"bg-(--theme-border) theme-border theme-muted-text shadow-sm":
|
|
43
|
-
"bg-(--theme-muted-panel-bg) theme-border theme-muted-text shadow-sm": !isDotActive && !isDotCompleted && !isDotUpcoming && !isInvalid,
|
|
33
|
+
"bg-(--theme-border) theme-border theme-muted-text shadow-sm": status === "upcoming" && !isInvalid,
|
|
44
34
|
"bg-red-50 border-red-500 text-red-600 shadow-sm": isInvalid && status !== "active"
|
|
45
35
|
}),
|
|
46
36
|
style: isDotActive ? {
|
|
@@ -17,8 +17,6 @@ export interface WizardConfig {
|
|
|
17
17
|
navigation?: WizardNavigation;
|
|
18
18
|
/** Label for the final submit button */
|
|
19
19
|
submitLabel?: string;
|
|
20
|
-
/** Use URL-based routing instead of component state */
|
|
21
|
-
urlBased?: boolean;
|
|
22
20
|
/** Flatten step fields into top-level inputs (default: true). Set false to preserve step keys as nested objects. */
|
|
23
21
|
flatten?: boolean;
|
|
24
22
|
}
|
|
@@ -33,39 +31,10 @@ export interface StepFieldConfig {
|
|
|
33
31
|
options: DynamicFormSchema;
|
|
34
32
|
/** Validate current step before proceeding to next (default: true) */
|
|
35
33
|
validateOnNext?: boolean;
|
|
36
|
-
/** Allow skipping this step without validation */
|
|
37
|
-
canSkip?: boolean;
|
|
38
34
|
/** Custom label for next button on this step */
|
|
39
35
|
nextLabel?: string;
|
|
40
36
|
/** Custom label for previous button on this step */
|
|
41
37
|
prevLabel?: string;
|
|
42
|
-
/** Optional tooltip text */
|
|
43
|
-
tooltip?: string | string[];
|
|
44
|
-
/** Hidden field support */
|
|
45
|
-
hidden?: boolean;
|
|
46
|
-
/** Disable this step */
|
|
47
|
-
disabled?: boolean;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Internal wizard state managed by useWizardState hook
|
|
51
|
-
*/
|
|
52
|
-
export interface WizardState {
|
|
53
|
-
/** Current step ID/key */
|
|
54
|
-
currentStep: string;
|
|
55
|
-
/** Set of step IDs that have been visited */
|
|
56
|
-
visitedSteps: Set<string>;
|
|
57
|
-
/** Set of step IDs that have validation errors */
|
|
58
|
-
invalidSteps: Set<string>;
|
|
59
|
-
/** List of all step keys in order */
|
|
60
|
-
stepOrder: string[];
|
|
61
|
-
/** Total number of steps */
|
|
62
|
-
totalSteps: number;
|
|
63
|
-
/** Whether the wizard is on the last step */
|
|
64
|
-
isLastStep: boolean;
|
|
65
|
-
/** Whether the wizard can proceed to next step */
|
|
66
|
-
canProceedToNext: boolean;
|
|
67
|
-
/** Whether user can go back */
|
|
68
|
-
canGoBack: boolean;
|
|
69
38
|
}
|
|
70
39
|
/**
|
|
71
40
|
* Extracted wizard configuration and step information
|
|
@@ -77,12 +46,7 @@ export interface ParsedWizardConfig {
|
|
|
77
46
|
steps: Record<string, StepFieldConfig>;
|
|
78
47
|
/** Ordered list of step keys */
|
|
79
48
|
stepOrder: string[];
|
|
80
|
-
/** Schema for non-step fields (should be none in pure wizard) */
|
|
81
|
-
otherFields: Record<string, unknown>;
|
|
82
49
|
}
|
|
83
|
-
/**
|
|
84
|
-
* Wizard navigation parameters
|
|
85
|
-
*/
|
|
86
50
|
/**
|
|
87
51
|
* Props for WizardContainer component
|
|
88
52
|
*/
|
|
@@ -120,8 +84,8 @@ export interface WizardStepIndicatorProps {
|
|
|
120
84
|
visitedSteps: Set<string>;
|
|
121
85
|
/** Set of invalid step keys */
|
|
122
86
|
invalidSteps: Set<string>;
|
|
123
|
-
/** Callback when step is clicked */
|
|
124
|
-
onStepClick
|
|
87
|
+
/** Callback when a step the user may jump to is clicked */
|
|
88
|
+
onStepClick: (stepKey: string) => boolean;
|
|
125
89
|
/** Whether clicking completed steps is allowed */
|
|
126
90
|
allowJump?: boolean | undefined;
|
|
127
91
|
/** Hide step numbers */
|
|
@@ -131,12 +95,8 @@ export interface WizardStepIndicatorProps {
|
|
|
131
95
|
* Props for WizardNavigation component
|
|
132
96
|
*/
|
|
133
97
|
export interface WizardNavigationProps {
|
|
134
|
-
/**
|
|
135
|
-
|
|
136
|
-
/** List of step keys in order */
|
|
137
|
-
stepOrder: string[];
|
|
138
|
-
/** Whether user can go to next step */
|
|
139
|
-
canGoToNext: boolean;
|
|
98
|
+
/** Whether the wizard is on its last step, which submits instead of going next */
|
|
99
|
+
isLastStep: boolean;
|
|
140
100
|
/** Whether user can go back */
|
|
141
101
|
canGoBack: boolean;
|
|
142
102
|
/** Whether current step is valid */
|
|
@@ -164,8 +124,6 @@ export interface WizardStepContentProps {
|
|
|
164
124
|
stepConfig: StepFieldConfig;
|
|
165
125
|
/** Form values */
|
|
166
126
|
values: Record<string, unknown>;
|
|
167
|
-
/** Update form values */
|
|
168
|
-
onValuesChange?: ((values: Record<string, unknown>) => void) | undefined;
|
|
169
127
|
/** Label position for fields */
|
|
170
128
|
labelPosition?: LabelPosition | undefined;
|
|
171
129
|
/** Missing fields list */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { StepFieldConfig
|
|
1
|
+
import type { StepFieldConfig } from './types.js';
|
|
2
2
|
interface UseWizardStateProps {
|
|
3
3
|
/** Ordered list of step keys */
|
|
4
4
|
stepOrder: string[];
|
|
@@ -6,23 +6,15 @@ interface UseWizardStateProps {
|
|
|
6
6
|
steps: Record<string, StepFieldConfig>;
|
|
7
7
|
/** Function to validate current step */
|
|
8
8
|
validateStep: (stepKey: string) => Promise<boolean>;
|
|
9
|
-
/** Initial step to start with (default: first step) */
|
|
10
|
-
initialStep?: string;
|
|
11
9
|
}
|
|
12
|
-
export declare function useWizardState({ stepOrder, steps, validateStep
|
|
10
|
+
export declare function useWizardState({ stepOrder, steps, validateStep }: UseWizardStateProps): {
|
|
13
11
|
currentStep: string;
|
|
14
12
|
visitedSteps: Set<string>;
|
|
15
13
|
invalidSteps: Set<string>;
|
|
16
14
|
isLastStep: boolean;
|
|
17
15
|
canGoBack: boolean;
|
|
18
|
-
currentStepIndex: number;
|
|
19
|
-
totalSteps: number;
|
|
20
16
|
goToNext: () => Promise<boolean>;
|
|
21
17
|
goToPrevious: () => void;
|
|
22
18
|
jumpToStep: (stepKey: string) => boolean;
|
|
23
|
-
reset: () => void;
|
|
24
|
-
markStepVisited: (stepKey: string) => void;
|
|
25
|
-
markStepInvalid: (stepKey: string, invalid: boolean) => void;
|
|
26
|
-
getState: () => WizardState;
|
|
27
19
|
};
|
|
28
20
|
export {};
|
|
@@ -1,22 +1,13 @@
|
|
|
1
1
|
import { useCallback, useState } from "react";
|
|
2
2
|
//#region src/form/Wizard/useWizardState.ts
|
|
3
|
-
function useWizardState({ stepOrder, steps, validateStep
|
|
4
|
-
const firstStep =
|
|
3
|
+
function useWizardState({ stepOrder, steps, validateStep }) {
|
|
4
|
+
const firstStep = stepOrder[0] ?? "";
|
|
5
5
|
const [currentStep, setCurrentStep] = useState(firstStep);
|
|
6
6
|
const [visitedSteps, setVisitedSteps] = useState(/* @__PURE__ */ new Set([firstStep]));
|
|
7
7
|
const [invalidSteps, setInvalidSteps] = useState(/* @__PURE__ */ new Set());
|
|
8
8
|
const currentStepIndex = stepOrder.indexOf(currentStep);
|
|
9
9
|
const isLastStep = currentStepIndex === stepOrder.length - 1;
|
|
10
10
|
const canGoBack = currentStepIndex > 0;
|
|
11
|
-
/**
|
|
12
|
-
* Mark step as visited
|
|
13
|
-
*/
|
|
14
|
-
const markStepVisited = useCallback((stepKey) => {
|
|
15
|
-
setVisitedSteps((prev) => /* @__PURE__ */ new Set([...prev, stepKey]));
|
|
16
|
-
}, []);
|
|
17
|
-
/**
|
|
18
|
-
* Mark step as invalid
|
|
19
|
-
*/
|
|
20
11
|
const markStepInvalid = useCallback((stepKey, invalid) => {
|
|
21
12
|
setInvalidSteps((prev) => {
|
|
22
13
|
const next = new Set(prev);
|
|
@@ -25,93 +16,52 @@ function useWizardState({ stepOrder, steps, validateStep, initialStep }) {
|
|
|
25
16
|
return next;
|
|
26
17
|
});
|
|
27
18
|
}, []);
|
|
28
|
-
const goToNext = useCallback(async () => {
|
|
29
|
-
if (isLastStep) return false;
|
|
30
|
-
if (steps[currentStep]?.validateOnNext !== false) {
|
|
31
|
-
if (!await validateStep(currentStep)) {
|
|
32
|
-
markStepInvalid(currentStep, true);
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
markStepInvalid(currentStep, false);
|
|
37
|
-
const nextStepKey = stepOrder[currentStepIndex + 1];
|
|
38
|
-
setCurrentStep(nextStepKey ?? "");
|
|
39
|
-
markStepVisited(nextStepKey ?? "");
|
|
40
|
-
return true;
|
|
41
|
-
}, [
|
|
42
|
-
currentStep,
|
|
43
|
-
currentStepIndex,
|
|
44
|
-
isLastStep,
|
|
45
|
-
steps,
|
|
46
|
-
stepOrder,
|
|
47
|
-
validateStep,
|
|
48
|
-
markStepInvalid,
|
|
49
|
-
markStepVisited
|
|
50
|
-
]);
|
|
51
|
-
const goToPrevious = useCallback(() => {
|
|
52
|
-
if (!canGoBack) return;
|
|
53
|
-
const prevStepKey = stepOrder[currentStepIndex - 1];
|
|
54
|
-
setCurrentStep(prevStepKey ?? "");
|
|
55
|
-
}, [
|
|
56
|
-
canGoBack,
|
|
57
|
-
currentStepIndex,
|
|
58
|
-
stepOrder
|
|
59
|
-
]);
|
|
60
|
-
const jumpToStep = useCallback((stepKey) => {
|
|
61
|
-
if (!stepOrder.includes(stepKey)) return false;
|
|
62
|
-
if (!visitedSteps.has(stepKey) && stepKey !== currentStep) return false;
|
|
63
|
-
setCurrentStep(stepKey);
|
|
64
|
-
return true;
|
|
65
|
-
}, [
|
|
66
|
-
stepOrder,
|
|
67
|
-
visitedSteps,
|
|
68
|
-
currentStep
|
|
69
|
-
]);
|
|
70
|
-
/**
|
|
71
|
-
* Reset wizard to initial state
|
|
72
|
-
*/
|
|
73
|
-
const reset = useCallback(() => {
|
|
74
|
-
setCurrentStep(firstStep);
|
|
75
|
-
setVisitedSteps(/* @__PURE__ */ new Set([firstStep]));
|
|
76
|
-
setInvalidSteps(/* @__PURE__ */ new Set());
|
|
77
|
-
}, [firstStep]);
|
|
78
|
-
/**
|
|
79
|
-
* Get current wizard state
|
|
80
|
-
*/
|
|
81
|
-
const getState = useCallback(() => {
|
|
82
|
-
return {
|
|
83
|
-
currentStep,
|
|
84
|
-
visitedSteps,
|
|
85
|
-
invalidSteps,
|
|
86
|
-
stepOrder,
|
|
87
|
-
totalSteps: stepOrder.length,
|
|
88
|
-
isLastStep,
|
|
89
|
-
canProceedToNext: !isLastStep,
|
|
90
|
-
canGoBack
|
|
91
|
-
};
|
|
92
|
-
}, [
|
|
93
|
-
currentStep,
|
|
94
|
-
visitedSteps,
|
|
95
|
-
invalidSteps,
|
|
96
|
-
stepOrder,
|
|
97
|
-
isLastStep,
|
|
98
|
-
canGoBack
|
|
99
|
-
]);
|
|
100
19
|
return {
|
|
101
20
|
currentStep,
|
|
102
21
|
visitedSteps,
|
|
103
22
|
invalidSteps,
|
|
104
23
|
isLastStep,
|
|
105
24
|
canGoBack,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
25
|
+
goToNext: useCallback(async () => {
|
|
26
|
+
if (isLastStep) return false;
|
|
27
|
+
if (steps[currentStep]?.validateOnNext !== false) {
|
|
28
|
+
if (!await validateStep(currentStep)) {
|
|
29
|
+
markStepInvalid(currentStep, true);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
markStepInvalid(currentStep, false);
|
|
34
|
+
const nextStepKey = stepOrder[currentStepIndex + 1] ?? "";
|
|
35
|
+
setCurrentStep(nextStepKey);
|
|
36
|
+
setVisitedSteps((prev) => /* @__PURE__ */ new Set([...prev, nextStepKey]));
|
|
37
|
+
return true;
|
|
38
|
+
}, [
|
|
39
|
+
currentStep,
|
|
40
|
+
currentStepIndex,
|
|
41
|
+
isLastStep,
|
|
42
|
+
steps,
|
|
43
|
+
stepOrder,
|
|
44
|
+
validateStep,
|
|
45
|
+
markStepInvalid
|
|
46
|
+
]),
|
|
47
|
+
goToPrevious: useCallback(() => {
|
|
48
|
+
if (!canGoBack) return;
|
|
49
|
+
setCurrentStep(stepOrder[currentStepIndex - 1] ?? "");
|
|
50
|
+
}, [
|
|
51
|
+
canGoBack,
|
|
52
|
+
currentStepIndex,
|
|
53
|
+
stepOrder
|
|
54
|
+
]),
|
|
55
|
+
jumpToStep: useCallback((stepKey) => {
|
|
56
|
+
if (!stepOrder.includes(stepKey)) return false;
|
|
57
|
+
if (!visitedSteps.has(stepKey) && stepKey !== currentStep) return false;
|
|
58
|
+
setCurrentStep(stepKey);
|
|
59
|
+
return true;
|
|
60
|
+
}, [
|
|
61
|
+
stepOrder,
|
|
62
|
+
visitedSteps,
|
|
63
|
+
currentStep
|
|
64
|
+
])
|
|
115
65
|
};
|
|
116
66
|
}
|
|
117
67
|
//#endregion
|
|
@@ -8,17 +8,13 @@ function isStepField(field) {
|
|
|
8
8
|
function parseWizardConfig(options) {
|
|
9
9
|
const meta = options["$meta"];
|
|
10
10
|
const wizardConfig = isWizardMeta(meta) ? meta.wizard : void 0;
|
|
11
|
-
if (
|
|
11
|
+
if (wizardConfig?.mode !== "wizard") return null;
|
|
12
12
|
const steps = {};
|
|
13
13
|
const stepOrder = [];
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
steps[key] = field;
|
|
19
|
-
stepOrder.push(key);
|
|
20
|
-
} else otherFields[key] = field;
|
|
21
|
-
});
|
|
14
|
+
for (const [key, field] of Object.entries(options)) if (key !== "$meta" && isStepField(field)) {
|
|
15
|
+
steps[key] = field;
|
|
16
|
+
stepOrder.push(key);
|
|
17
|
+
}
|
|
22
18
|
if (stepOrder.length === 0) {
|
|
23
19
|
console.warn("Wizard mode enabled but no steps found");
|
|
24
20
|
return null;
|
|
@@ -26,8 +22,7 @@ function parseWizardConfig(options) {
|
|
|
26
22
|
return {
|
|
27
23
|
config: wizardConfig,
|
|
28
24
|
steps,
|
|
29
|
-
stepOrder
|
|
30
|
-
otherFields
|
|
25
|
+
stepOrder
|
|
31
26
|
};
|
|
32
27
|
}
|
|
33
28
|
//#endregion
|
package/dist/form/lib.js
CHANGED
|
@@ -23,56 +23,44 @@ function enforceOneMustBeTrue(items, options, promoteIndex) {
|
|
|
23
23
|
const fieldSchema = options[fieldKey];
|
|
24
24
|
const opts = typeof fieldSchema === "object" && fieldSchema && "options" in fieldSchema ? fieldSchema.options : void 0;
|
|
25
25
|
const trueOption = typeof opts === "object" && opts && !Array.isArray(opts) && "onOption" in opts ? opts.onOption || true : true;
|
|
26
|
-
|
|
26
|
+
const hasTrue = items.some((item) => item[fieldKey] === trueOption);
|
|
27
|
+
const promoted = items[clampedIndex];
|
|
28
|
+
if (!hasTrue && promoted) promoted[fieldKey] = trueOption;
|
|
27
29
|
}
|
|
28
30
|
return items;
|
|
29
31
|
}
|
|
30
32
|
function flattenGroups(schema) {
|
|
31
33
|
if (!schema || typeof schema !== "object") return {};
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const flattenedGroup = flattenGroups(entry.options);
|
|
38
|
-
flattenedFields = {
|
|
39
|
-
...flattenedFields,
|
|
40
|
-
...flattenedGroup
|
|
41
|
-
};
|
|
42
|
-
} else if (entry?.type === "object") {
|
|
43
|
-
const flattenedGroup = flattenGroups(entry.options);
|
|
44
|
-
flattenedFields = {
|
|
45
|
-
...flattenedFields,
|
|
46
|
-
[key]: flattenedGroup
|
|
47
|
-
};
|
|
48
|
-
} else flattenedFields[key] = entry;
|
|
49
|
-
});
|
|
50
|
-
return flattenedFields;
|
|
34
|
+
const flattened = {};
|
|
35
|
+
for (const [key, entry] of Object.entries(schema)) if (entry?.type === "group") Object.assign(flattened, flattenGroups(entry.options));
|
|
36
|
+
else if (entry?.type === "object") flattened[key] = flattenGroups(entry.options);
|
|
37
|
+
else flattened[key] = entry;
|
|
38
|
+
return flattened;
|
|
51
39
|
}
|
|
52
40
|
/**Not a pure function. Edits 'obj' passed into function */
|
|
53
41
|
function impureSetValueFromPath(obj, path, value) {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
obj[pathArray[0]] = value;
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
42
|
+
const parents = path.split(".");
|
|
43
|
+
const leaf = parents.pop() ?? "";
|
|
59
44
|
let current = obj;
|
|
60
|
-
for (
|
|
61
|
-
const segment = pathArray[i];
|
|
45
|
+
for (const segment of parents) {
|
|
62
46
|
const arrayMatch = segment.match(/^(.+)\[(\d+)\]$/);
|
|
63
47
|
if (arrayMatch) {
|
|
64
|
-
const key = arrayMatch
|
|
65
|
-
const index = Number(
|
|
48
|
+
const [, key = "", indexText] = arrayMatch;
|
|
49
|
+
const index = Number(indexText);
|
|
66
50
|
if (!current[key]) current[key] = [];
|
|
67
51
|
const list = current[key];
|
|
68
|
-
|
|
69
|
-
|
|
52
|
+
let item = list[index];
|
|
53
|
+
if (!item) {
|
|
54
|
+
item = {};
|
|
55
|
+
list[index] = item;
|
|
56
|
+
}
|
|
57
|
+
current = item;
|
|
70
58
|
} else {
|
|
71
59
|
if (!current[segment]) current[segment] = {};
|
|
72
60
|
current = current[segment];
|
|
73
61
|
}
|
|
74
62
|
}
|
|
75
|
-
current[
|
|
63
|
+
current[leaf] = value;
|
|
76
64
|
}
|
|
77
65
|
function initializeValues(options, srcData = {}, blankDefault) {
|
|
78
66
|
if (!options || typeof options !== "object") return;
|
|
@@ -82,25 +70,13 @@ function initializeValues(options, srcData = {}, blankDefault) {
|
|
|
82
70
|
return Object.keys(schema).reduce((acc, field) => {
|
|
83
71
|
if (field.startsWith("$")) return acc;
|
|
84
72
|
const fieldSchema = schema[field] ?? EMPTY_ENTRY;
|
|
85
|
-
|
|
73
|
+
const flattenStep = fieldSchema.type === "step" && schema["$meta"]?.wizard?.flatten !== false;
|
|
74
|
+
if (fieldSchema.type === "group" || flattenStep) {
|
|
86
75
|
const values = initializeValues(fieldSchema.options, data);
|
|
87
|
-
|
|
88
|
-
Object.keys(values).forEach((key) => {
|
|
89
|
-
acc[key] = data[key] ?? values[key];
|
|
90
|
-
});
|
|
91
|
-
return acc;
|
|
92
|
-
}
|
|
93
|
-
if (fieldSchema.type === "step") {
|
|
94
|
-
if (schema["$meta"]?.wizard?.flatten !== false) {
|
|
95
|
-
const values = initializeValues(fieldSchema.options, data);
|
|
96
|
-
if (!values) return acc;
|
|
97
|
-
Object.keys(values).forEach((key) => {
|
|
98
|
-
acc[key] = data[key] ?? values[key];
|
|
99
|
-
});
|
|
100
|
-
} else acc[field] = initializeValues(fieldSchema.options, asRecord(data[field]));
|
|
76
|
+
for (const key of Object.keys(values ?? {})) acc[key] = data[key] ?? values?.[key];
|
|
101
77
|
return acc;
|
|
102
78
|
}
|
|
103
|
-
if (fieldSchema.type === "object") {
|
|
79
|
+
if (fieldSchema.type === "step" || fieldSchema.type === "object") {
|
|
104
80
|
acc[field] = initializeValues(fieldSchema.options, asRecord(data[field]));
|
|
105
81
|
return acc;
|
|
106
82
|
}
|
|
@@ -110,14 +86,12 @@ function initializeValues(options, srcData = {}, blankDefault) {
|
|
|
110
86
|
acc[field] = Array.isArray(listData) ? [...listData] : [];
|
|
111
87
|
return acc;
|
|
112
88
|
}
|
|
113
|
-
|
|
114
|
-
if (Array.isArray(listData)) for (let i = 0; i < listData.length; i++) arr.push(initializeValues(fieldSchema.options, asRecord(listData[i])));
|
|
115
|
-
acc[field] = arr;
|
|
89
|
+
acc[field] = Array.isArray(listData) ? listData.map((item) => initializeValues(fieldSchema.options, asRecord(item))) : [];
|
|
116
90
|
return acc;
|
|
117
91
|
}
|
|
118
92
|
if (data[field] !== void 0) {
|
|
119
93
|
acc[field] = data[field];
|
|
120
|
-
if ((fieldSchema.type === "dropdown" || fieldSchema.type === "storage") && fieldSchema.secondaryField &&
|
|
94
|
+
if ((fieldSchema.type === "dropdown" || fieldSchema.type === "storage") && fieldSchema.secondaryField && Array.isArray(fieldSchema.options)) {
|
|
121
95
|
const option = findSecondaryOption(fieldSchema.options, data[field]);
|
|
122
96
|
applySecondaryField(fieldSchema.secondaryField, option?.secondaryValue, (secondaryField, secondaryValue) => {
|
|
123
97
|
if (!(fieldSchema.type === "storage" && Object.hasOwn(options, secondaryField) && source[secondaryField] !== void 0)) impureSetValueFromPath(acc, secondaryField, secondaryValue);
|
|
@@ -135,8 +109,8 @@ function initializeValues(options, srcData = {}, blankDefault) {
|
|
|
135
109
|
else acc[field] = false;
|
|
136
110
|
}
|
|
137
111
|
if (fieldSchema.type === "dropdown") {
|
|
138
|
-
if (
|
|
139
|
-
if (fieldSchema.
|
|
112
|
+
if (Array.isArray(fieldSchema.options) && fieldSchema.options.length > 0) acc[field] = fieldSchema.options[0].value;
|
|
113
|
+
if (fieldSchema.secondaryField && Array.isArray(fieldSchema.options)) {
|
|
140
114
|
const option = fieldSchema.options.find((option) => option.value === data[field]);
|
|
141
115
|
const secondaryField = Array.isArray(fieldSchema.secondaryField) ? fieldSchema.secondaryField : [fieldSchema.secondaryField];
|
|
142
116
|
const secondaryValue = Array.isArray(option?.secondaryValue) ? option?.secondaryValue : [option?.secondaryValue];
|
|
@@ -15,7 +15,8 @@ export interface RuntimeFieldExtensions {
|
|
|
15
15
|
one_must_be_true?: boolean;
|
|
16
16
|
computeOn?: boolean;
|
|
17
17
|
labelPosition?: LabelPosition;
|
|
18
|
-
|
|
18
|
+
/** Path of another field; when its value changes, this field's value is cleared. */
|
|
19
|
+
resetOnChange?: string;
|
|
19
20
|
options?: unknown;
|
|
20
21
|
}
|
|
21
22
|
export interface BaseField extends RuntimeFieldExtensions {
|
|
@@ -36,14 +37,13 @@ interface WizardConfig {
|
|
|
36
37
|
/** Navigation UI options */
|
|
37
38
|
navigation?: {
|
|
38
39
|
showSteps?: boolean;
|
|
39
|
-
showProgress?: boolean;
|
|
40
40
|
allowJump?: boolean;
|
|
41
41
|
hideStepNumbers?: boolean;
|
|
42
42
|
};
|
|
43
43
|
/** Label for the final submit button */
|
|
44
44
|
submitLabel?: string;
|
|
45
|
-
/**
|
|
46
|
-
|
|
45
|
+
/** Flatten step fields into top-level inputs (default: true). Set false to keep each step's fields under its key. */
|
|
46
|
+
flatten?: boolean;
|
|
47
47
|
}
|
|
48
48
|
interface StepField extends BaseField {
|
|
49
49
|
type: 'step';
|
|
@@ -51,7 +51,6 @@ interface StepField extends BaseField {
|
|
|
51
51
|
description?: string;
|
|
52
52
|
options: Record<string, AnyField>;
|
|
53
53
|
validateOnNext?: boolean;
|
|
54
|
-
canSkip?: boolean;
|
|
55
54
|
nextLabel?: string;
|
|
56
55
|
prevLabel?: string;
|
|
57
56
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Options for a field whose list is keyed by another field's value: with
|
|
2
|
+
* depends_on, the list follows whatever is currently chosen at that path. */
|
|
3
|
+
export declare function dependentOptions<T>(options: T[] | Record<string, T[]>, dependsOn: string | undefined, values: Record<string, unknown>): {
|
|
4
|
+
options: T[];
|
|
5
|
+
parentValue: unknown;
|
|
6
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getValueUsingPath } from "./getValueUsingPath.js";
|
|
2
|
+
//#region src/form/utils/dependentOptions.ts
|
|
3
|
+
/** Options for a field whose list is keyed by another field's value: with
|
|
4
|
+
* depends_on, the list follows whatever is currently chosen at that path. */
|
|
5
|
+
function dependentOptions(options, dependsOn, values) {
|
|
6
|
+
if (Array.isArray(options)) return {
|
|
7
|
+
options,
|
|
8
|
+
parentValue: void 0
|
|
9
|
+
};
|
|
10
|
+
const parentValue = dependsOn ? getValueUsingPath(values, dependsOn) : void 0;
|
|
11
|
+
if (parentValue === void 0 || parentValue === null) return {
|
|
12
|
+
options: [],
|
|
13
|
+
parentValue
|
|
14
|
+
};
|
|
15
|
+
return {
|
|
16
|
+
options: options[String(parentValue)] ?? [],
|
|
17
|
+
parentValue
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { dependentOptions };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
/** `index` replaces a path's `[index]` placeholder when the field sits in a list row. */
|
|
2
|
+
export declare function getParentValue(index: number | undefined, targetField: unknown, values: object, field: {
|
|
2
3
|
depends_on?: string | undefined;
|
|
3
4
|
}): unknown;
|
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
import { getValueUsingPath } from "./getValueUsingPath.js";
|
|
2
2
|
import { checkShowIfObject } from "./checkShowIfObject.js";
|
|
3
3
|
//#region src/form/utils/getParentValue.ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const dependsOnValue = getValueUsingPath(values, dependentPath);
|
|
4
|
+
/** `index` replaces a path's `[index]` placeholder when the field sits in a list row. */
|
|
5
|
+
function getParentValue(index, targetField, values, field) {
|
|
6
|
+
const atIndex = (path) => index === void 0 ? path : path.replace("[index]", `[${index}]`);
|
|
7
|
+
if (typeof targetField === "object" && targetField !== null && !Array.isArray(targetField)) return !checkShowIfObject(targetField, values, index).includes(false);
|
|
8
|
+
if (field.depends_on) {
|
|
9
|
+
const dependsOnValue = getValueUsingPath(values, atIndex(field.depends_on));
|
|
11
10
|
const dependsOnText = dependsOnValue === null || dependsOnValue === void 0 ? void 0 : String(dependsOnValue);
|
|
12
|
-
if (Array.isArray(targetField))
|
|
13
|
-
|
|
14
|
-
|
|
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);
|
|
11
|
+
if (Array.isArray(targetField)) return targetField.includes(dependsOnValue) || targetField.includes(dependsOnText);
|
|
12
|
+
if (typeof targetField === "string") return dependsOnText !== void 0 && targetField.includes(dependsOnText);
|
|
13
|
+
return targetField === dependsOnValue;
|
|
19
14
|
}
|
|
20
|
-
return
|
|
15
|
+
return getValueUsingPath(values, typeof targetField === "string" ? atIndex(targetField) : "");
|
|
21
16
|
}
|
|
22
17
|
//#endregion
|
|
23
18
|
export { getParentValue };
|
|
@@ -10,7 +10,7 @@ function getValueUsingPath(obj, path) {
|
|
|
10
10
|
const [arrayKey = "", indexStr = ""] = key.split("[");
|
|
11
11
|
const index = parseInt(indexStr.slice(0, -1), 10);
|
|
12
12
|
const list = container[arrayKey];
|
|
13
|
-
if (!Array.isArray(list) || isNaN(index)) return;
|
|
13
|
+
if (!Array.isArray(list) || Number.isNaN(index)) return;
|
|
14
14
|
current = list[index];
|
|
15
15
|
} else {
|
|
16
16
|
if (!(key in container)) return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { WorkflowJob } from './types.js';
|
|
2
2
|
interface AnnotationBannerProps {
|
|
3
|
-
executedJobs: Record<string, WorkflowJob
|
|
3
|
+
executedJobs: Record<string, WorkflowJob>;
|
|
4
4
|
}
|
|
5
5
|
export declare function AnnotationBanner({ executedJobs }: AnnotationBannerProps): import("react").JSX.Element | null;
|
|
6
6
|
export {};
|
|
@@ -48,6 +48,7 @@ function collectAnnotations(executedJobs, parentPath) {
|
|
|
48
48
|
title: annotation.title,
|
|
49
49
|
file: annotation.file,
|
|
50
50
|
line: annotation.line,
|
|
51
|
+
id: annotation.id,
|
|
51
52
|
jobName: fullJobName,
|
|
52
53
|
stepName: step?.name,
|
|
53
54
|
stepIndex
|
|
@@ -62,7 +63,6 @@ function collectAnnotations(executedJobs, parentPath) {
|
|
|
62
63
|
}
|
|
63
64
|
function AnnotationBanner({ executedJobs }) {
|
|
64
65
|
const [expanded, setExpanded] = useState(false);
|
|
65
|
-
if (!executedJobs) return null;
|
|
66
66
|
const annotations = collectAnnotations(executedJobs);
|
|
67
67
|
if (annotations.length === 0) return null;
|
|
68
68
|
const counts = {
|
package/dist/graph/Collapse.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function Collapse({ expanded,
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export declare function Collapse({ expanded, id, children, }: {
|
|
3
3
|
expanded: boolean;
|
|
4
|
+
id?: string;
|
|
4
5
|
children: ReactNode;
|
|
5
|
-
releaseOverflow?: boolean;
|
|
6
6
|
}): import("react").JSX.Element;
|