@olenbetong/synergi-react 2.3.0 → 2.3.2
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/esm/ob.react.css +27 -1189
- package/dist/esm/ob.react.js +711 -45615
- package/dist/esm/ob.react.min.css +1 -24
- package/dist/esm/ob.react.min.css.map +3 -3
- package/dist/esm/ob.react.min.js +1 -253
- package/dist/esm/ob.react.min.js.map +4 -4
- package/dist/iife/ob.react.css +27 -1189
- package/dist/iife/ob.react.js +737 -45641
- package/dist/iife/ob.react.min.css +1 -24
- package/dist/iife/ob.react.min.css.map +3 -3
- package/dist/iife/ob.react.min.js +1 -253
- package/dist/iife/ob.react.min.js.map +4 -4
- package/es/elements/ElementDamage/DescriptionInput.d.ts +3 -1
- package/es/elements/ElementDamage/DescriptionInput.js +10 -10
- package/es/elements/ElementDamage/DuplicateDamage/DesktopView.d.ts +2 -1
- package/es/elements/ElementDamage/DuplicateDamage/DesktopView.js +3 -3
- package/es/elements/ElementDamage/DuplicateDamage/DublicateElementDamageDialog.d.ts +2 -1
- package/es/elements/ElementDamage/DuplicateDamage/DublicateElementDamageDialog.js +2 -2
- package/es/elements/ElementDamage/DuplicateDamage/PhoneView.d.ts +2 -1
- package/es/elements/ElementDamage/DuplicateDamage/PhoneView.js +4 -2
- package/es/elements/ElementDamage/DuplicateDamage/index.d.ts +4 -0
- package/es/elements/ElementDamage/DuplicateDamage/index.js +2 -2
- package/es/elements/ElementLookup.d.ts +3 -1
- package/es/elements/ElementLookup.js +15 -4
- package/es/elements/ElementLookupDialog/Manual/ManualForm.d.ts +2 -1
- package/es/elements/ElementLookupDialog/Manual/ManualForm.js +44 -19
- package/es/elements/ElementLookupDialog/index.d.ts +1 -0
- package/es/elements/ElementLookupDialog/index.js +2 -2
- package/es/shared/licenses.d.ts +3 -0
- package/es/shared/licenses.js +5 -0
- package/package.json +4 -4
- package/src/elements/ElementDamage/DescriptionInput.tsx +19 -10
- package/src/elements/ElementDamage/DuplicateDamage/DesktopView.tsx +15 -10
- package/src/elements/ElementDamage/DuplicateDamage/DublicateElementDamageDialog.tsx +4 -2
- package/src/elements/ElementDamage/DuplicateDamage/PhoneView.tsx +5 -2
- package/src/elements/ElementDamage/DuplicateDamage/index.tsx +6 -0
- package/src/elements/ElementLookup.tsx +29 -3
- package/src/elements/ElementLookupDialog/Manual/ManualForm.tsx +54 -22
- package/src/elements/ElementLookupDialog/index.tsx +9 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import SearchIcon from "@mui/icons-material/Search";
|
|
2
2
|
import { IconButton, TextField } from "@mui/material";
|
|
3
3
|
import { getLocalizedString } from "@olenbetong/appframe-core";
|
|
4
|
-
import { type RefObject, useEffect, useImperativeHandle, useState } from "react";
|
|
4
|
+
import { type RefObject, useEffect, useImperativeHandle, useRef, useState } from "react";
|
|
5
5
|
import { type AddElement, ElementLookupDialog } from "./ElementLookupDialog";
|
|
6
6
|
|
|
7
7
|
export type Element = {
|
|
@@ -21,20 +21,38 @@ export type ElementLookupProps = {
|
|
|
21
21
|
value?: Element | null;
|
|
22
22
|
defaultValue?: Element | null;
|
|
23
23
|
ref?: RefObject<ElementLookupHandle | null>;
|
|
24
|
+
elementIDRequired?: boolean;
|
|
24
25
|
openLookupDialogIcon?: boolean;
|
|
25
26
|
onChange?: (value: Element | null) => void;
|
|
27
|
+
onDialogChange?: (open: boolean) => void;
|
|
26
28
|
};
|
|
27
29
|
|
|
28
|
-
export function ElementLookup({
|
|
30
|
+
export function ElementLookup({
|
|
31
|
+
value,
|
|
32
|
+
defaultValue,
|
|
33
|
+
ref,
|
|
34
|
+
elementIDRequired = false,
|
|
35
|
+
openLookupDialogIcon,
|
|
36
|
+
onChange,
|
|
37
|
+
onDialogChange,
|
|
38
|
+
}: ElementLookupProps) {
|
|
39
|
+
let initializedRef = useRef<boolean>(false);
|
|
40
|
+
|
|
29
41
|
let [openElementLookupDialog, setOpenElementLookupDialog] = useState<boolean>(false);
|
|
30
42
|
let [element, setElement] = useState<Element | null>(defaultValue ?? null);
|
|
31
43
|
let elementValue = value === undefined ? element : value;
|
|
32
44
|
|
|
45
|
+
// biome-ignore lint: intentionally skipping "value" dependency as this shouldn't run when "value" changes
|
|
33
46
|
useEffect(() => {
|
|
47
|
+
if (initializedRef.current) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
34
51
|
if (value === undefined && defaultValue) {
|
|
35
52
|
setElement(defaultValue);
|
|
53
|
+
initializedRef.current = true;
|
|
36
54
|
}
|
|
37
|
-
}, [defaultValue
|
|
55
|
+
}, [defaultValue]);
|
|
38
56
|
|
|
39
57
|
useImperativeHandle(ref, () => ({
|
|
40
58
|
openDialog: () => setOpenElementLookupDialog(true),
|
|
@@ -46,6 +64,11 @@ export function ElementLookup({ value, defaultValue, ref, openLookupDialogIcon,
|
|
|
46
64
|
setElement(addElement.element);
|
|
47
65
|
}
|
|
48
66
|
|
|
67
|
+
// biome-ignore lint: only run when openElementLookupDialog changes
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
onDialogChange?.(openElementLookupDialog);
|
|
70
|
+
}, [openElementLookupDialog]);
|
|
71
|
+
|
|
49
72
|
return (
|
|
50
73
|
<>
|
|
51
74
|
<ElementLookupDialog
|
|
@@ -53,6 +76,7 @@ export function ElementLookup({ value, defaultValue, ref, openLookupDialogIcon,
|
|
|
53
76
|
mode="single"
|
|
54
77
|
onClose={() => setOpenElementLookupDialog(false)}
|
|
55
78
|
onAdd={handleAddElement}
|
|
79
|
+
allowEmptyElement={true}
|
|
56
80
|
/>
|
|
57
81
|
|
|
58
82
|
<input type="hidden" name="ProjectID" value={elementValue?.ProjectID ?? ""} />
|
|
@@ -73,6 +97,7 @@ export function ElementLookup({ value, defaultValue, ref, openLookupDialogIcon,
|
|
|
73
97
|
value={elementValue ? elementValue.ElementID : ""}
|
|
74
98
|
label={getLocalizedString("Element ID")}
|
|
75
99
|
fullWidth
|
|
100
|
+
required={elementIDRequired}
|
|
76
101
|
autoComplete="off"
|
|
77
102
|
slotProps={{
|
|
78
103
|
htmlInput: { readOnly: true },
|
|
@@ -83,6 +108,7 @@ export function ElementLookup({ value, defaultValue, ref, openLookupDialogIcon,
|
|
|
83
108
|
</IconButton>
|
|
84
109
|
) : undefined,
|
|
85
110
|
},
|
|
111
|
+
inputLabel: { shrink: !!elementValue?.ElementID },
|
|
86
112
|
}}
|
|
87
113
|
/>
|
|
88
114
|
</>
|
|
@@ -6,7 +6,7 @@ import type { ProjectsRecord } from "../../data/dsProjects";
|
|
|
6
6
|
import { ProjectSelect } from "../../ProjectSelect";
|
|
7
7
|
import { type ElementDetails, getElement } from "../getElement";
|
|
8
8
|
|
|
9
|
-
const isElementsOnly = /^([a-z]{2,4}[\s]*[0-9]{4,8}[\s,]*)+$/i;
|
|
9
|
+
// const isElementsOnly = /^([a-z]{2,4}[\s]*[0-9]{4,8}[\s,]*)+$/i;
|
|
10
10
|
const matchElements = /([a-z]{2,4}[\s]*[0-9]{4,8})/gi;
|
|
11
11
|
|
|
12
12
|
export type ProjectRecordBase = {
|
|
@@ -19,9 +19,15 @@ export type AddElementManualFormProps = {
|
|
|
19
19
|
onAdd: (element: string | ElementDetails) => Promise<void>;
|
|
20
20
|
mode?: "single" | "multi";
|
|
21
21
|
defaultProject?: ProjectRecordBase;
|
|
22
|
+
allowEmptyElement?: boolean;
|
|
22
23
|
};
|
|
23
24
|
|
|
24
|
-
export function AddElementManualForm({
|
|
25
|
+
export function AddElementManualForm({
|
|
26
|
+
onAdd,
|
|
27
|
+
mode,
|
|
28
|
+
defaultProject,
|
|
29
|
+
allowEmptyElement = false,
|
|
30
|
+
}: AddElementManualFormProps) {
|
|
25
31
|
let id = useId();
|
|
26
32
|
let buttonRef = useRef<HTMLButtonElement>(null);
|
|
27
33
|
let [working, setWorking] = useState(false);
|
|
@@ -35,30 +41,53 @@ export function AddElementManualForm({ onAdd, mode, defaultProject }: AddElement
|
|
|
35
41
|
let formData = new FormData(evt.target as HTMLFormElement);
|
|
36
42
|
let elements = formData.get("ElementID");
|
|
37
43
|
let domain = formData.get("Domain");
|
|
38
|
-
let
|
|
44
|
+
let project: ProjectsRecord = JSON.parse(formData.get("Project") as string);
|
|
39
45
|
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
if (allowEmptyElement) {
|
|
47
|
+
if (!project.ProjectID) {
|
|
48
|
+
alert(getLocalizedString("Project is required"));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
if (!project.ProjectID || !domain || !elements) {
|
|
53
|
+
let warning = getLocalizedString(
|
|
54
|
+
mode === "multi" ? "Project and elements are required" : "Project and element are required",
|
|
55
|
+
);
|
|
56
|
+
alert(warning);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
46
59
|
}
|
|
47
60
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
if (elements) {
|
|
62
|
+
setWorking(true);
|
|
63
|
+
let record = (elements as string)
|
|
64
|
+
.match(matchElements)
|
|
65
|
+
?.map((elementId) => elementId.replace(/\s+/g, ""))
|
|
66
|
+
.map((elementId) =>
|
|
67
|
+
getElement({ projectId: project.ProjectID as string, elementId: elementId }, { mode: "manual" }),
|
|
68
|
+
);
|
|
53
69
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
70
|
+
if (!record) {
|
|
71
|
+
alert(getLocalizedString("Invalid elements"));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
58
74
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
75
|
+
let loaded = (await Promise.all(record)).map((record) => onAdd(record));
|
|
76
|
+
await Promise.all(loaded);
|
|
77
|
+
setWorking(false);
|
|
78
|
+
} else {
|
|
79
|
+
onAdd({
|
|
80
|
+
PrimKey: "",
|
|
81
|
+
Domain: domain?.toString() ?? "",
|
|
82
|
+
Created: project?.Created,
|
|
83
|
+
ProjectID: project.ProjectID,
|
|
84
|
+
ProjectName: project.ProjectName,
|
|
85
|
+
ProjectDomain: project.Domain,
|
|
86
|
+
ElementID: "",
|
|
87
|
+
DisplayName: "",
|
|
88
|
+
GiaiUri: "",
|
|
89
|
+
});
|
|
90
|
+
}
|
|
62
91
|
} catch (error) {
|
|
63
92
|
setWorking(false);
|
|
64
93
|
alert((error as Error).message);
|
|
@@ -73,6 +102,8 @@ export function AddElementManualForm({ onAdd, mode, defaultProject }: AddElement
|
|
|
73
102
|
)}
|
|
74
103
|
</Alert>
|
|
75
104
|
|
|
105
|
+
<input type="hidden" name="Project" value={project ? JSON.stringify(project) : ""} />
|
|
106
|
+
|
|
76
107
|
<ProjectSelect
|
|
77
108
|
onChange={(project) => (project ? setProject(project) : setProject(null))}
|
|
78
109
|
value={project}
|
|
@@ -98,7 +129,8 @@ export function AddElementManualForm({ onAdd, mode, defaultProject }: AddElement
|
|
|
98
129
|
variant="contained"
|
|
99
130
|
size="large"
|
|
100
131
|
type="submit"
|
|
101
|
-
disabled={!isElementsOnly.test(elementId) || working}
|
|
132
|
+
// disabled={!isElementsOnly.test(elementId) || working}
|
|
133
|
+
disabled={working}
|
|
102
134
|
loading={working}
|
|
103
135
|
loadingPosition="end"
|
|
104
136
|
endIcon={<Add />}
|
|
@@ -28,6 +28,7 @@ export type ElementLookupDialogSharedProps = {
|
|
|
28
28
|
onClose: () => void;
|
|
29
29
|
initialTab?: InitialTabProps | null;
|
|
30
30
|
useSearch?: boolean;
|
|
31
|
+
allowEmptyElement?: boolean;
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
export type ElementLookupDialogSingleModeProps = ElementLookupDialogSharedProps & {
|
|
@@ -128,7 +129,10 @@ export function ElementLookupDialog(props: ElementLookupDialogProps) {
|
|
|
128
129
|
)}
|
|
129
130
|
{tab === "manual" && (
|
|
130
131
|
<Box p={2}>
|
|
131
|
-
<AddElementManualForm
|
|
132
|
+
<AddElementManualForm
|
|
133
|
+
onAdd={(element) => handleElementAdd(element, "manual")}
|
|
134
|
+
allowEmptyElement={props.allowEmptyElement}
|
|
135
|
+
/>
|
|
132
136
|
</Box>
|
|
133
137
|
)}
|
|
134
138
|
{tab === "scanner" && (
|
|
@@ -171,7 +175,10 @@ export function ElementLookupDialog(props: ElementLookupDialogProps) {
|
|
|
171
175
|
</Button>
|
|
172
176
|
}
|
|
173
177
|
>
|
|
174
|
-
<ListItemText
|
|
178
|
+
<ListItemText
|
|
179
|
+
primary={element.DisplayName || element.ProjectName}
|
|
180
|
+
secondary={element.ElementID || element.ProjectID}
|
|
181
|
+
/>
|
|
175
182
|
</ListItem>
|
|
176
183
|
))}
|
|
177
184
|
</List>
|