@ramesesinc/platform-core 0.1.5 → 0.1.8
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/components/action/LookupPage.js +9 -31
- package/dist/components/action/ViewPage.d.ts +2 -0
- package/dist/components/action/ViewPage.js +25 -31
- package/dist/components/common/UIComponent.js +4 -3
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/table/DataList.js +2 -2
- package/dist/components/view/PopupView.d.ts +13 -0
- package/dist/components/view/PopupView.js +25 -20
- package/dist/core/DataContext.d.ts +7 -4
- package/dist/core/DataContext.js +16 -4
- package/dist/core/Page.js +25 -26
- package/dist/core/PageCache.js +16 -3
- package/dist/core/PageContext.js +90 -18
- package/dist/core/PageViewContext.d.ts +13 -1
- package/dist/core/PageViewContext.js +89 -5
- package/dist/core/PopupContext.d.ts +49 -0
- package/dist/core/PopupContext.js +380 -0
- package/dist/core/RowContext.js +1 -1
- package/dist/core/WindowContext.d.ts +15 -0
- package/dist/core/WindowContext.js +28 -0
- package/dist/core/index.d.ts +16 -0
- package/dist/index.css +25 -7
- package/dist/lib/utils/BeanUtils.js +7 -7
- package/dist/templates/DataListTemplate.js +7 -2
- package/dist/templates/ExplorerTemplate.js +1 -1
- package/package.json +5 -5
- package/dist/components/action/AlertMessage.tsx +0 -38
- package/dist/components/action/Button.tsx +0 -230
- package/dist/components/action/CancelEdit.tsx +0 -40
- package/dist/components/action/DeleteData.tsx +0 -73
- package/dist/components/action/Edit.tsx +0 -40
- package/dist/components/action/LookupPage.tsx +0 -113
- package/dist/components/action/ProcessRunner.tsx +0 -337
- package/dist/components/action/Refresh.tsx +0 -35
- package/dist/components/action/SaveData.tsx +0 -74
- package/dist/components/action/SelectData.tsx +0 -47
- package/dist/components/action/Undo.tsx +0 -50
- package/dist/components/action/UpdateContext.tsx +0 -40
- package/dist/components/action/UpdateData.tsx +0 -49
- package/dist/components/action/ViewBackPage.tsx +0 -46
- package/dist/components/action/ViewPage.tsx +0 -141
- package/dist/components/common/UIComponent.tsx +0 -86
- package/dist/components/common/UIInput.tsx +0 -49
- package/dist/components/common/UIMenu.tsx +0 -91
- package/dist/components/index.ts +0 -51
- package/dist/components/input/CodeEditor.tsx +0 -188
- package/dist/components/input/DateField.tsx +0 -274
- package/dist/components/input/DayPicker.tsx +0 -5
- package/dist/components/input/HtmlCode.tsx +0 -203
- package/dist/components/input/JsonCode.tsx +0 -205
- package/dist/components/input/MonthPicker.tsx +0 -5
- package/dist/components/input/ScriptCode.tsx +0 -195
- package/dist/components/input/Select.tsx +0 -78
- package/dist/components/input/SqlCode.tsx +0 -162
- package/dist/components/input/StringDecision.tsx +0 -64
- package/dist/components/input/Text.tsx +0 -57
- package/dist/components/input/YearPicker.tsx +0 -81
- package/dist/components/list/IconMenu.tsx +0 -115
- package/dist/components/list/TabMenu.tsx +0 -127
- package/dist/components/list/TreeMenu.tsx +0 -279
- package/dist/components/list/TxnTaskList.tsx +0 -198
- package/dist/components/output/Label.tsx +0 -50
- package/dist/components/table/DataList.tsx +0 -820
- package/dist/components/table/DataTable.tsx +0 -572
- package/dist/components/table/ListHandler.ts +0 -276
- package/dist/components/table/TableContext.tsx +0 -122
- package/dist/components/view/ComponentView.tsx +0 -102
- package/dist/components/view/FilterView.tsx +0 -21
- package/dist/components/view/HtmlForm.tsx +0 -176
- package/dist/components/view/HtmlView.tsx +0 -98
- package/dist/components/view/IFrameView.tsx +0 -48
- package/dist/components/view/Modal.tsx +0 -72
- package/dist/components/view/PageView.tsx +0 -131
- package/dist/components/view/PopupView.tsx +0 -160
- package/dist/components/view/RootView.tsx +0 -109
- package/dist/components/view/WizardView.tsx +0 -48
- package/dist/lib/layouts/BorderLayout.tsx +0 -31
- package/dist/lib/layouts/CardLayout.tsx +0 -73
- package/dist/lib/layouts/CenterLayout.tsx +0 -20
- package/dist/lib/layouts/GridLayout.tsx +0 -20
- package/dist/lib/layouts/HPanel.tsx +0 -31
- package/dist/lib/layouts/HorizontalLayout.tsx +0 -29
- package/dist/lib/layouts/MainLayout.tsx +0 -16
- package/dist/lib/layouts/PageLayout.tsx +0 -29
- package/dist/lib/layouts/VPanel.tsx +0 -27
- package/dist/lib/layouts/XLayout.tsx +0 -29
- package/dist/lib/layouts/YLayout.tsx +0 -29
- package/dist/lib/layouts/index.ts +0 -13
- /package/dist/components/action/{UpdateContext.d.ts → UpdateState.d.ts} +0 -0
- /package/dist/components/action/{UpdateContext.js → UpdateState.js} +0 -0
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import Editor from "@monaco-editor/react";
|
|
2
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
-
import { usePageContext } from "../../core/PageContext";
|
|
4
|
-
import CopyButton from "../../lib/components/CopyButton";
|
|
5
|
-
import UIComponent from "../common/UIComponent";
|
|
6
|
-
import useUIInput, { UIInputProps } from "../common/UIInput";
|
|
7
|
-
|
|
8
|
-
type ScriptCodeProps = UIInputProps & {
|
|
9
|
-
height?: number | string;
|
|
10
|
-
width?: number | string;
|
|
11
|
-
showCopy?: boolean;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const ScriptCode = (props: ScriptCodeProps) => {
|
|
15
|
-
const { height = 300, width = "100%", showCopy = true } = props ?? {};
|
|
16
|
-
|
|
17
|
-
const pageContext = usePageContext();
|
|
18
|
-
const editorRef = useRef<any>(null);
|
|
19
|
-
const [fontSize, setFontSize] = useState(14);
|
|
20
|
-
const [error, setError] = useState("");
|
|
21
|
-
const [readOnly, setReadOnly] = useState(true);
|
|
22
|
-
|
|
23
|
-
const onRefresh = () => {
|
|
24
|
-
const val = getValue();
|
|
25
|
-
setEditorValue(val ?? "");
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const { initialValue, getValue, setValue } = useUIInput({ ...props, onRefresh });
|
|
29
|
-
|
|
30
|
-
const [editorValue, setEditorValue] = useState(() => initialValue ?? "");
|
|
31
|
-
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
const unsubscribe = pageContext?.dependsTo("editable", (val: any) => {
|
|
34
|
-
const isEditable = val === true || val === "true";
|
|
35
|
-
setReadOnly(!isEditable);
|
|
36
|
-
|
|
37
|
-
if (!isEditable) {
|
|
38
|
-
setEditorValue(getValue() ?? "");
|
|
39
|
-
setError("");
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
return unsubscribe;
|
|
43
|
-
}, []);
|
|
44
|
-
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
return () => {
|
|
47
|
-
editorRef.current = null;
|
|
48
|
-
};
|
|
49
|
-
}, []);
|
|
50
|
-
|
|
51
|
-
const handleKeyDown = useCallback((e: KeyboardEvent) => {
|
|
52
|
-
if (e.ctrlKey && e.key === "=") {
|
|
53
|
-
e.preventDefault();
|
|
54
|
-
setFontSize((prev) => Math.min(prev + 1, 40));
|
|
55
|
-
}
|
|
56
|
-
if (e.ctrlKey && e.key === "-") {
|
|
57
|
-
e.preventDefault();
|
|
58
|
-
setFontSize((prev) => Math.max(prev - 1, 8));
|
|
59
|
-
}
|
|
60
|
-
if (e.ctrlKey && e.key === "0") {
|
|
61
|
-
e.preventDefault();
|
|
62
|
-
setFontSize(14);
|
|
63
|
-
}
|
|
64
|
-
}, []);
|
|
65
|
-
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
68
|
-
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
69
|
-
}, [handleKeyDown]);
|
|
70
|
-
|
|
71
|
-
useEffect(() => {
|
|
72
|
-
editorRef.current?.updateOptions({ fontSize });
|
|
73
|
-
}, [fontSize]);
|
|
74
|
-
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
editorRef.current?.updateOptions({ readOnly, domReadOnly: readOnly });
|
|
77
|
-
}, [readOnly]);
|
|
78
|
-
|
|
79
|
-
const validateScript = (code: string) => {
|
|
80
|
-
if (!code.trim()) {
|
|
81
|
-
setError("");
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const errors: string[] = [];
|
|
86
|
-
const lines = code.split("\n");
|
|
87
|
-
|
|
88
|
-
let braceCount = 0;
|
|
89
|
-
let parenCount = 0;
|
|
90
|
-
let bracketCount = 0;
|
|
91
|
-
|
|
92
|
-
for (let i = 0; i < lines.length; i++) {
|
|
93
|
-
const line = lines[i];
|
|
94
|
-
const lineNum = i + 1;
|
|
95
|
-
|
|
96
|
-
for (const char of line) {
|
|
97
|
-
if (char === "{") braceCount++;
|
|
98
|
-
if (char === "}") braceCount--;
|
|
99
|
-
if (char === "(") parenCount++;
|
|
100
|
-
if (char === ")") parenCount--;
|
|
101
|
-
if (char === "[") bracketCount++;
|
|
102
|
-
if (char === "]") bracketCount--;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (line.trim().match(/^(let|const|var)\s+\w+\s*=.*[^;{}\s]$/)) {
|
|
106
|
-
errors.push(`Line ${lineNum}: Possible missing semicolon`);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (line.includes("console.log") && !line.trim().endsWith(";") && !line.trim().endsWith("{")) {
|
|
110
|
-
errors.push(`Line ${lineNum}: Missing semicolon after console.log`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (braceCount !== 0) errors.push(`Unmatched braces: ${braceCount > 0 ? "missing closing" : "missing opening"} brace(s)`);
|
|
115
|
-
|
|
116
|
-
if (parenCount !== 0) errors.push(`Unmatched parentheses: ${parenCount > 0 ? "missing closing" : "missing opening"}`);
|
|
117
|
-
|
|
118
|
-
if (bracketCount !== 0) errors.push(`Unmatched brackets: ${bracketCount > 0 ? "missing closing" : "missing opening"}`);
|
|
119
|
-
|
|
120
|
-
setError(errors.length > 0 ? errors.join("\n• ") : "");
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const handleEditorChange = (value?: string) => {
|
|
124
|
-
if (readOnly) return;
|
|
125
|
-
const safeValue = value ?? "";
|
|
126
|
-
setEditorValue(safeValue);
|
|
127
|
-
setValue(safeValue); // JavaScript is always a string, write through immediately
|
|
128
|
-
validateScript(safeValue);
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
const handleEditorDidMount = (editor: any) => {
|
|
132
|
-
editorRef.current = editor;
|
|
133
|
-
|
|
134
|
-
editor.updateOptions({
|
|
135
|
-
minimap: { enabled: false },
|
|
136
|
-
fontSize,
|
|
137
|
-
lineNumbers: "on",
|
|
138
|
-
renderWhitespace: "selection",
|
|
139
|
-
folding: true,
|
|
140
|
-
bracketPairColorization: { enabled: true },
|
|
141
|
-
formatOnPaste: true,
|
|
142
|
-
formatOnType: true,
|
|
143
|
-
});
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
return (
|
|
147
|
-
<UIComponent {...(props ?? {})}>
|
|
148
|
-
<div className="relative w-full bg-white">
|
|
149
|
-
{showCopy && (
|
|
150
|
-
<div className="absolute top-2 right-4 z-50">
|
|
151
|
-
<CopyButton item={editorValue} copySize={15} copiedSize={10} classNameCopied="!px-[15px] !py-[10px]" />
|
|
152
|
-
</div>
|
|
153
|
-
)}
|
|
154
|
-
<Editor
|
|
155
|
-
key="script-code-editor"
|
|
156
|
-
height={height}
|
|
157
|
-
width={width}
|
|
158
|
-
language="javascript"
|
|
159
|
-
value={editorValue}
|
|
160
|
-
onChange={handleEditorChange}
|
|
161
|
-
onMount={handleEditorDidMount}
|
|
162
|
-
theme="vs-dark"
|
|
163
|
-
options={{
|
|
164
|
-
readOnly,
|
|
165
|
-
domReadOnly: readOnly,
|
|
166
|
-
padding: { top: 10 },
|
|
167
|
-
selectOnLineNumbers: true,
|
|
168
|
-
automaticLayout: true,
|
|
169
|
-
minimap: { enabled: false },
|
|
170
|
-
fontSize,
|
|
171
|
-
wordWrap: "off",
|
|
172
|
-
lineNumbers: "on",
|
|
173
|
-
renderWhitespace: "selection",
|
|
174
|
-
folding: true,
|
|
175
|
-
bracketPairColorization: { enabled: true },
|
|
176
|
-
formatOnPaste: true,
|
|
177
|
-
formatOnType: true,
|
|
178
|
-
scrollBeyondLastLine: false,
|
|
179
|
-
smoothScrolling: true,
|
|
180
|
-
cursorBlinking: "smooth",
|
|
181
|
-
renderLineHighlight: "all",
|
|
182
|
-
autoIndent: "full",
|
|
183
|
-
suggestOnTriggerCharacters: true,
|
|
184
|
-
quickSuggestions: true,
|
|
185
|
-
parameterHints: { enabled: true },
|
|
186
|
-
scrollbar: { vertical: "visible", horizontal: "visible" },
|
|
187
|
-
}}
|
|
188
|
-
/>
|
|
189
|
-
{error && !readOnly && <div className="mt-2 text-sm text-red-500 whitespace-pre-wrap">• {error}</div>}
|
|
190
|
-
</div>
|
|
191
|
-
</UIComponent>
|
|
192
|
-
);
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
export default ScriptCode;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { useRef, useState } from "react";
|
|
2
|
-
import UIComponent from "../common/UIComponent";
|
|
3
|
-
import useUIInput, { UIInputProps } from "../common/UIInput";
|
|
4
|
-
|
|
5
|
-
type SelectOption = {
|
|
6
|
-
label: string;
|
|
7
|
-
value: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
type SelectFieldProps = UIInputProps & {
|
|
11
|
-
required?: boolean;
|
|
12
|
-
immediate?: boolean;
|
|
13
|
-
options?: SelectOption[];
|
|
14
|
-
placeholder?: string;
|
|
15
|
-
onChange?: (value: string) => void;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const SelectField = (props: SelectFieldProps) => {
|
|
19
|
-
const { immediate = true, options = [], placeholder } = props ?? {};
|
|
20
|
-
const [focused, setFocused] = useState(false);
|
|
21
|
-
const selectRef = useRef<HTMLSelectElement | null>(null);
|
|
22
|
-
const valueRef = useRef<string>("");
|
|
23
|
-
|
|
24
|
-
const className = "border rounded px-2 py-1 w-full";
|
|
25
|
-
|
|
26
|
-
const handleFocus = () => {
|
|
27
|
-
setFocused(true);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const handleBlur = () => {
|
|
31
|
-
if (!immediate) {
|
|
32
|
-
setValue(selectValue);
|
|
33
|
-
}
|
|
34
|
-
setFocused(false);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const onRefresh = () => {
|
|
38
|
-
setSelectValue(getValue());
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const { initialValue, getValue, setValue, binding } = useUIInput({ ...props, onRefresh });
|
|
42
|
-
valueRef.current = initialValue ?? "";
|
|
43
|
-
const [selectValue, setSelectValue] = useState(valueRef.current);
|
|
44
|
-
|
|
45
|
-
const onChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
46
|
-
const text = e.target.value ?? "";
|
|
47
|
-
|
|
48
|
-
if (text !== selectValue) {
|
|
49
|
-
valueRef.current = text;
|
|
50
|
-
setSelectValue(valueRef.current);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (immediate) {
|
|
54
|
-
setValue(text);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
props.onChange?.(text);
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<UIComponent {...(props ?? {})}>
|
|
62
|
-
<select ref={selectRef} onChange={onChange} value={selectValue} onFocus={handleFocus} onBlur={handleBlur} className={className}>
|
|
63
|
-
{placeholder && (
|
|
64
|
-
<option value="" disabled>
|
|
65
|
-
{placeholder}
|
|
66
|
-
</option>
|
|
67
|
-
)}
|
|
68
|
-
{options.map((opt) => (
|
|
69
|
-
<option key={opt.value} value={opt.value}>
|
|
70
|
-
{opt.label}
|
|
71
|
-
</option>
|
|
72
|
-
))}
|
|
73
|
-
</select>
|
|
74
|
-
</UIComponent>
|
|
75
|
-
);
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export default SelectField;
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import Editor from "@monaco-editor/react";
|
|
2
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
-
import { usePageContext } from "../../core/PageContext";
|
|
4
|
-
import CopyButton from "../../lib/components/CopyButton";
|
|
5
|
-
import UIComponent from "../common/UIComponent";
|
|
6
|
-
import useUIInput, { UIInputProps } from "../common/UIInput";
|
|
7
|
-
|
|
8
|
-
type SqlCodeProps = UIInputProps & {
|
|
9
|
-
height?: number | string;
|
|
10
|
-
width?: number | string;
|
|
11
|
-
showCopy?: boolean;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const SqlCode = (props: SqlCodeProps) => {
|
|
15
|
-
const { height = 300, width = "100%", showCopy = true } = props ?? {};
|
|
16
|
-
|
|
17
|
-
const pageContext = usePageContext();
|
|
18
|
-
const editorRef = useRef<any>(null);
|
|
19
|
-
const [fontSize, setFontSize] = useState(14);
|
|
20
|
-
const [error, setError] = useState("");
|
|
21
|
-
const [readOnly, setReadOnly] = useState(true);
|
|
22
|
-
|
|
23
|
-
const onRefresh = () => {
|
|
24
|
-
const val = getValue();
|
|
25
|
-
setEditorValue(val ?? "");
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const { initialValue, getValue, setValue } = useUIInput({ ...props, onRefresh });
|
|
29
|
-
|
|
30
|
-
const [editorValue, setEditorValue] = useState(() => initialValue ?? "");
|
|
31
|
-
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
const unsubscribe = pageContext?.dependsTo("editable", (val: any) => {
|
|
34
|
-
const isEditable = val === true || val === "true";
|
|
35
|
-
setReadOnly(!isEditable);
|
|
36
|
-
|
|
37
|
-
if (!isEditable) {
|
|
38
|
-
setEditorValue(getValue() ?? "");
|
|
39
|
-
setError("");
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
return unsubscribe;
|
|
43
|
-
}, []);
|
|
44
|
-
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
return () => {
|
|
47
|
-
editorRef.current = null;
|
|
48
|
-
};
|
|
49
|
-
}, []);
|
|
50
|
-
|
|
51
|
-
const handleKeyDown = useCallback((e: KeyboardEvent) => {
|
|
52
|
-
if (e.ctrlKey && e.key === "=") {
|
|
53
|
-
e.preventDefault();
|
|
54
|
-
setFontSize((prev) => Math.min(prev + 1, 40));
|
|
55
|
-
}
|
|
56
|
-
if (e.ctrlKey && e.key === "-") {
|
|
57
|
-
e.preventDefault();
|
|
58
|
-
setFontSize((prev) => Math.max(prev - 1, 8));
|
|
59
|
-
}
|
|
60
|
-
if (e.ctrlKey && e.key === "0") {
|
|
61
|
-
e.preventDefault();
|
|
62
|
-
setFontSize(14);
|
|
63
|
-
}
|
|
64
|
-
}, []);
|
|
65
|
-
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
68
|
-
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
69
|
-
}, [handleKeyDown]);
|
|
70
|
-
|
|
71
|
-
useEffect(() => {
|
|
72
|
-
editorRef.current?.updateOptions({ fontSize });
|
|
73
|
-
}, [fontSize]);
|
|
74
|
-
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
editorRef.current?.updateOptions({ readOnly, domReadOnly: readOnly });
|
|
77
|
-
}, [readOnly]);
|
|
78
|
-
|
|
79
|
-
const validateSql = (value: string) => {
|
|
80
|
-
if (!value.trim()) {
|
|
81
|
-
setError("");
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
const forbidden = /drop\s+table|delete\s+from/gi;
|
|
85
|
-
if (forbidden.test(value)) {
|
|
86
|
-
setError("Dangerous SQL statement detected.");
|
|
87
|
-
} else {
|
|
88
|
-
setError("");
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const handleEditorChange = (value?: string) => {
|
|
93
|
-
if (readOnly) return;
|
|
94
|
-
const safeValue = value ?? "";
|
|
95
|
-
setEditorValue(safeValue);
|
|
96
|
-
setValue(safeValue); // SQL is always a string, write through immediately
|
|
97
|
-
validateSql(safeValue);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const handleEditorDidMount = (editor: any, monaco: any) => {
|
|
101
|
-
editorRef.current = editor;
|
|
102
|
-
|
|
103
|
-
monaco.languages.register({ id: "sql" });
|
|
104
|
-
|
|
105
|
-
editor.updateOptions({
|
|
106
|
-
minimap: { enabled: false },
|
|
107
|
-
fontSize,
|
|
108
|
-
lineNumbers: "on",
|
|
109
|
-
renderWhitespace: "selection",
|
|
110
|
-
folding: true,
|
|
111
|
-
bracketPairColorization: { enabled: true },
|
|
112
|
-
formatOnPaste: true,
|
|
113
|
-
formatOnType: true,
|
|
114
|
-
});
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
return (
|
|
118
|
-
<UIComponent {...(props ?? {})}>
|
|
119
|
-
<div className="relative w-full bg-white">
|
|
120
|
-
{showCopy && (
|
|
121
|
-
<div className="absolute top-2 right-4 z-50">
|
|
122
|
-
<CopyButton item={editorValue} copySize={15} copiedSize={10} classNameCopied="!px-[15px] !py-[10px]" />
|
|
123
|
-
</div>
|
|
124
|
-
)}
|
|
125
|
-
<Editor
|
|
126
|
-
key="sql-code-editor"
|
|
127
|
-
height={height}
|
|
128
|
-
width={width}
|
|
129
|
-
language="sql"
|
|
130
|
-
value={editorValue}
|
|
131
|
-
onChange={handleEditorChange}
|
|
132
|
-
onMount={handleEditorDidMount}
|
|
133
|
-
theme="vs-dark"
|
|
134
|
-
options={{
|
|
135
|
-
readOnly,
|
|
136
|
-
domReadOnly: readOnly,
|
|
137
|
-
padding: { top: 10 },
|
|
138
|
-
selectOnLineNumbers: true,
|
|
139
|
-
automaticLayout: true,
|
|
140
|
-
minimap: { enabled: false },
|
|
141
|
-
fontSize,
|
|
142
|
-
wordWrap: "off",
|
|
143
|
-
lineNumbers: "on",
|
|
144
|
-
renderWhitespace: "selection",
|
|
145
|
-
folding: true,
|
|
146
|
-
bracketPairColorization: { enabled: true },
|
|
147
|
-
formatOnPaste: true,
|
|
148
|
-
formatOnType: true,
|
|
149
|
-
scrollBeyondLastLine: false,
|
|
150
|
-
smoothScrolling: true,
|
|
151
|
-
cursorBlinking: "smooth",
|
|
152
|
-
renderLineHighlight: "all",
|
|
153
|
-
scrollbar: { vertical: "visible", horizontal: "visible" },
|
|
154
|
-
}}
|
|
155
|
-
/>
|
|
156
|
-
{error && !readOnly && <p className="text-red-500 text-xs mt-1 px-1">{error}</p>}
|
|
157
|
-
</div>
|
|
158
|
-
</UIComponent>
|
|
159
|
-
);
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
export default SqlCode;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
import { usePageContext } from "../../core/PageContext";
|
|
3
|
-
import UIComponent from "../common/UIComponent";
|
|
4
|
-
|
|
5
|
-
const operators = [
|
|
6
|
-
{ label: "Matches", value: "matches" },
|
|
7
|
-
{ label: "Equals", value: "equals" },
|
|
8
|
-
{ label: "Not Equals", value: "neq" },
|
|
9
|
-
];
|
|
10
|
-
|
|
11
|
-
const StringDecision = (props: Record<string, any>) => {
|
|
12
|
-
const { name } = props ?? {};
|
|
13
|
-
const [inputOp, setInputOp] = useState("");
|
|
14
|
-
const [inputValue, setInputValue] = useState("");
|
|
15
|
-
const pageContext = usePageContext();
|
|
16
|
-
const binding = pageContext?.binding;
|
|
17
|
-
|
|
18
|
-
const inputClassName = "border rounded px-2 py-1 w-full";
|
|
19
|
-
const selectClassName =
|
|
20
|
-
"px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 disabled:bg-gray-100 disabled:cursor-not-allowed";
|
|
21
|
-
|
|
22
|
-
const handleChangeOperator = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
23
|
-
setInputOp(e.target.value);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const handleChangeValue = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
27
|
-
setInputValue(e.target.value);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
if (name && inputOp && inputValue) {
|
|
32
|
-
pageContext?.set(name, { [inputOp]: inputValue });
|
|
33
|
-
} else if (name && (!inputOp || !inputValue)) {
|
|
34
|
-
pageContext?.set(name, null);
|
|
35
|
-
}
|
|
36
|
-
}, [name, inputOp, inputValue, pageContext, binding]);
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<UIComponent {...(props ?? {})}>
|
|
40
|
-
<div className="flex gap-4 items-center justify-center">
|
|
41
|
-
<select value={inputOp} onChange={handleChangeOperator} className={selectClassName}>
|
|
42
|
-
<option value="">Select operator</option>
|
|
43
|
-
{operators.map((op) => (
|
|
44
|
-
<option key={op.value} value={op.value}>
|
|
45
|
-
{op.label}
|
|
46
|
-
</option>
|
|
47
|
-
))}
|
|
48
|
-
</select>
|
|
49
|
-
{/* <Select
|
|
50
|
-
options={operators}
|
|
51
|
-
placeholder="Select operator"
|
|
52
|
-
onChange={(value: string) => setInputOp(value)}
|
|
53
|
-
name={""}
|
|
54
|
-
onRefresh={function (): void {
|
|
55
|
-
throw new Error("Function not implemented.");
|
|
56
|
-
}}
|
|
57
|
-
/> */}
|
|
58
|
-
<input type="text" value={inputValue} onChange={handleChangeValue} className={inputClassName} placeholder="Enter value" />
|
|
59
|
-
</div>
|
|
60
|
-
</UIComponent>
|
|
61
|
-
);
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export default StringDecision;
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { useRef, useState } from "react";
|
|
2
|
-
import UIComponent from "../common/UIComponent";
|
|
3
|
-
import useUIInput, { UIInputProps } from "../common/UIInput";
|
|
4
|
-
|
|
5
|
-
type TextFieldProps = UIInputProps & {
|
|
6
|
-
required?: boolean;
|
|
7
|
-
immediate?: boolean;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const TextField = (props: TextFieldProps) => {
|
|
11
|
-
const { name, immediate = true } = props ?? {};
|
|
12
|
-
const [focused, setFocused] = useState(false);
|
|
13
|
-
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
14
|
-
const valueRef = useRef<string>("");
|
|
15
|
-
|
|
16
|
-
const className = "border rounded px-2 py-1 w-full";
|
|
17
|
-
|
|
18
|
-
const handleFocus = () => {
|
|
19
|
-
setFocused(true);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const handleBlur = () => {
|
|
23
|
-
if (!immediate) {
|
|
24
|
-
setValue(inputValue);
|
|
25
|
-
}
|
|
26
|
-
setFocused(false);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const onRefresh = () => {
|
|
30
|
-
setInputValue(getValue());
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const { initialValue, getValue, setValue, binding } = useUIInput({ ...props, onRefresh });
|
|
34
|
-
valueRef.current = initialValue ?? "";
|
|
35
|
-
const [inputValue, setInputValue] = useState(valueRef.current);
|
|
36
|
-
|
|
37
|
-
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
38
|
-
const text = e.target.value ?? "";
|
|
39
|
-
|
|
40
|
-
if (text !== inputValue) {
|
|
41
|
-
valueRef.current = text;
|
|
42
|
-
setInputValue(valueRef.current);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (immediate) {
|
|
46
|
-
setValue(text);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<UIComponent {...(props ?? {})}>
|
|
52
|
-
<input type="text" ref={inputRef} onChange={onChange} value={inputValue} onFocus={handleFocus} onBlur={handleBlur} className={className} />
|
|
53
|
-
</UIComponent>
|
|
54
|
-
);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export default TextField;
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from "react";
|
|
2
|
-
import UIComponent from "../common/UIComponent";
|
|
3
|
-
import useUIInput, { UIInputProps } from "../common/UIInput";
|
|
4
|
-
|
|
5
|
-
type YearPickerProps = UIInputProps & {
|
|
6
|
-
min?: number;
|
|
7
|
-
max?: number;
|
|
8
|
-
immediate?: boolean;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const YearPicker = (props: YearPickerProps) => {
|
|
12
|
-
const { min = 1900, max, immediate = true } = props ?? {};
|
|
13
|
-
const valueRef = useRef<string>("");
|
|
14
|
-
const [focused, setFocused] = useState(false);
|
|
15
|
-
|
|
16
|
-
// Set default max to current year if not provided
|
|
17
|
-
const currentYear = new Date().getFullYear();
|
|
18
|
-
const maxYear = max || currentYear;
|
|
19
|
-
|
|
20
|
-
// Generate array of years (descending order)
|
|
21
|
-
const years = Array.from({ length: maxYear - min + 1 }, (_, i) => maxYear - i);
|
|
22
|
-
|
|
23
|
-
const onRefresh = () => {
|
|
24
|
-
setInputValue(getValue());
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const { initialValue, getValue, setValue } = useUIInput({ ...props, onRefresh });
|
|
28
|
-
valueRef.current = initialValue ?? "";
|
|
29
|
-
const [inputValue, setInputValue] = useState(valueRef.current);
|
|
30
|
-
|
|
31
|
-
const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
32
|
-
const year = e.target.value;
|
|
33
|
-
|
|
34
|
-
if (year !== inputValue) {
|
|
35
|
-
valueRef.current = year;
|
|
36
|
-
setInputValue(valueRef.current);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (immediate) {
|
|
40
|
-
setValue(year);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const handleFocus = () => {
|
|
45
|
-
setFocused(true);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const handleBlur = () => {
|
|
49
|
-
if (!immediate) {
|
|
50
|
-
setValue(inputValue);
|
|
51
|
-
}
|
|
52
|
-
setFocused(false);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
// console.log("inputValue", inputValue);
|
|
57
|
-
}, [inputValue]);
|
|
58
|
-
|
|
59
|
-
return (
|
|
60
|
-
<UIComponent {...(props ?? {})}>
|
|
61
|
-
<div className="flex flex-col gap-1">
|
|
62
|
-
<select
|
|
63
|
-
value={inputValue}
|
|
64
|
-
onChange={handleChange}
|
|
65
|
-
onFocus={handleFocus}
|
|
66
|
-
onBlur={handleBlur}
|
|
67
|
-
className="px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 disabled:bg-gray-100 disabled:cursor-not-allowed"
|
|
68
|
-
>
|
|
69
|
-
<option value="">Select year</option>
|
|
70
|
-
{years.map((year) => (
|
|
71
|
-
<option key={year} value={year}>
|
|
72
|
-
{year}
|
|
73
|
-
</option>
|
|
74
|
-
))}
|
|
75
|
-
</select>
|
|
76
|
-
</div>
|
|
77
|
-
</UIComponent>
|
|
78
|
-
);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
export default YearPicker;
|