@olenbetong/synergi-react 2.2.3 → 2.3.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.
Files changed (116) hide show
  1. package/es/components/FilePond.d.ts +8 -5
  2. package/es/components/FilePond.js +47 -20
  3. package/es/elements/ElementDamage/DamageFormButtons.d.ts +9 -0
  4. package/es/elements/ElementDamage/DamageFormButtons.js +7 -0
  5. package/es/elements/ElementDamage/DescriptionInput.d.ts +14 -0
  6. package/es/elements/ElementDamage/DescriptionInput.js +44 -0
  7. package/es/elements/{ElementDamageForm/DuplicateDamage/DuplicateElementDamageDialog.d.ts → ElementDamage/DuplicateDamage/DublicateElementDamageDialog.d.ts} +4 -3
  8. package/es/elements/ElementDamage/DuplicateDamage/DublicateElementDamageDialog.js +12 -0
  9. package/es/elements/ElementDamage/DuplicateDamage/index.d.ts +36 -0
  10. package/es/elements/ElementDamage/DuplicateDamage/index.js +40 -0
  11. package/es/elements/ElementDamage/ElementNumberTextField.d.ts +10 -0
  12. package/es/elements/ElementDamage/ElementNumberTextField.js +18 -0
  13. package/es/elements/ElementDamage/HiddenDamageFields.d.ts +6 -0
  14. package/es/elements/ElementDamage/HiddenDamageFields.js +4 -0
  15. package/es/elements/ElementDamage/RegisterFix.d.ts +14 -0
  16. package/es/elements/ElementDamage/RegisterFix.js +45 -0
  17. package/es/elements/ElementDamage/SubmitButtons.d.ts +20 -0
  18. package/es/elements/ElementDamage/SubmitButtons.js +7 -0
  19. package/es/elements/ElementDamage/TransportElementSelect.d.ts +7 -0
  20. package/es/elements/ElementDamage/TransportElementSelect.js +16 -0
  21. package/es/elements/ElementLookup.d.ts +20 -0
  22. package/es/elements/ElementLookup.js +30 -0
  23. package/es/elements/{AddElementDialog → ElementLookupDialog}/Manual/ManualForm.js +4 -2
  24. package/es/elements/{AddElementDialog → ElementLookupDialog}/getElement.d.ts +1 -0
  25. package/es/elements/{AddElementDialog → ElementLookupDialog}/getElement.js +1 -0
  26. package/es/elements/{AddElementDialog → ElementLookupDialog}/index.d.ts +5 -5
  27. package/es/elements/{AddElementDialog → ElementLookupDialog}/index.js +4 -1
  28. package/es/elements/ProjectSelect.js +9 -2
  29. package/es/elements/data/dsDamages.d.ts +1 -1
  30. package/es/elements/data/dsDamages.js +2 -2
  31. package/es/elements/data/dsElements.d.ts +2 -0
  32. package/es/elements/data/dsElements.js +11 -1
  33. package/es/elements/data/dsTransportElements.d.ts +10 -0
  34. package/es/elements/data/dsTransportElements.js +57 -0
  35. package/es/elements/data/index.d.ts +5 -1
  36. package/es/elements/data/index.js +5 -1
  37. package/es/elements/data/procDeleteAttachment.d.ts +2 -0
  38. package/es/elements/data/procDeleteAttachment.js +18 -0
  39. package/es/elements/data/procDeleteDamage.d.ts +2 -0
  40. package/es/elements/data/procDeleteDamage.js +18 -0
  41. package/es/elements/data/procRemoveDamageFix.d.ts +2 -0
  42. package/es/elements/data/procRemoveDamageFix.js +18 -0
  43. package/es/elements/data/procRestoreAttachments.d.ts +2 -0
  44. package/es/elements/data/procRestoreAttachments.js +18 -0
  45. package/es/elements/index.d.ts +8 -2
  46. package/es/elements/index.js +8 -2
  47. package/es/index.d.ts +1 -1
  48. package/es/index.js +1 -1
  49. package/package.json +4 -4
  50. package/src/components/FilePond.tsx +73 -26
  51. package/src/elements/ElementDamage/DamageFormButtons.tsx +35 -0
  52. package/src/elements/ElementDamage/DescriptionInput.tsx +111 -0
  53. package/src/elements/{ElementDamageForm/DuplicateDamage/DuplicateElementDamageDialog.tsx → ElementDamage/DuplicateDamage/DublicateElementDamageDialog.tsx} +24 -9
  54. package/src/elements/ElementDamage/DuplicateDamage/index.tsx +105 -0
  55. package/src/elements/ElementDamage/ElementNumberTextField.tsx +41 -0
  56. package/src/elements/ElementDamage/HiddenDamageFields.tsx +13 -0
  57. package/src/elements/ElementDamage/RegisterFix.tsx +100 -0
  58. package/src/elements/ElementDamage/SubmitButtons.tsx +40 -0
  59. package/src/elements/ElementDamage/TransportElementSelect.tsx +52 -0
  60. package/src/elements/ElementLookup.tsx +90 -0
  61. package/src/elements/{AddElementDialog → ElementLookupDialog}/Manual/ManualForm.tsx +5 -2
  62. package/src/elements/{AddElementDialog → ElementLookupDialog}/getElement.ts +2 -0
  63. package/src/elements/{AddElementDialog → ElementLookupDialog}/index.tsx +9 -5
  64. package/src/elements/ProjectSelect.tsx +13 -3
  65. package/src/elements/data/dsDamages.ts +3 -3
  66. package/src/elements/data/dsElements.ts +13 -1
  67. package/src/elements/data/dsTransportElements.ts +68 -0
  68. package/src/elements/data/index.ts +5 -1
  69. package/src/elements/data/procDeleteAttachment.ts +19 -0
  70. package/src/elements/data/procDeleteDamage.ts +19 -0
  71. package/src/elements/data/procRemoveDamageFix.ts +19 -0
  72. package/src/elements/data/procRestoreAttachments.ts +19 -0
  73. package/src/elements/index.ts +8 -3
  74. package/src/index.ts +1 -1
  75. package/es/elements/ElementDamageForm/DamageFormFields.d.ts +0 -12
  76. package/es/elements/ElementDamageForm/DamageFormFields.js +0 -39
  77. package/es/elements/ElementDamageForm/DuplicateDamage/DuplicateElementDamageDialog.js +0 -11
  78. package/es/elements/ElementDamageForm/index.d.ts +0 -13
  79. package/es/elements/ElementDamageForm/index.js +0 -219
  80. package/src/elements/ElementDamageForm/DamageFormFields.tsx +0 -149
  81. package/src/elements/ElementDamageForm/index.tsx +0 -397
  82. /package/es/elements/{ElementDamageForm → ElementDamage}/DuplicateDamage/DesktopView.d.ts +0 -0
  83. /package/es/elements/{ElementDamageForm → ElementDamage}/DuplicateDamage/DesktopView.js +0 -0
  84. /package/es/elements/{ElementDamageForm → ElementDamage}/DuplicateDamage/PhoneView.d.ts +0 -0
  85. /package/es/elements/{ElementDamageForm → ElementDamage}/DuplicateDamage/PhoneView.js +0 -0
  86. /package/es/elements/{ElementDamageForm → ElementDamage}/index.css +0 -0
  87. /package/es/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/DeadIcon.d.ts +0 -0
  88. /package/es/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/DeadIcon.js +0 -0
  89. /package/es/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/Error.d.ts +0 -0
  90. /package/es/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/Error.js +0 -0
  91. /package/es/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/index.d.ts +0 -0
  92. /package/es/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/index.js +0 -0
  93. /package/es/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/useScanner.d.ts +0 -0
  94. /package/es/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/useScanner.js +0 -0
  95. /package/es/elements/{AddElementDialog → ElementLookupDialog}/HIDScanner/index.css +0 -0
  96. /package/es/elements/{AddElementDialog → ElementLookupDialog}/HIDScanner/index.d.ts +0 -0
  97. /package/es/elements/{AddElementDialog → ElementLookupDialog}/HIDScanner/index.js +0 -0
  98. /package/es/elements/{AddElementDialog → ElementLookupDialog}/HIDScanner/useHIDScanner.d.ts +0 -0
  99. /package/es/elements/{AddElementDialog → ElementLookupDialog}/HIDScanner/useHIDScanner.js +0 -0
  100. /package/es/elements/{AddElementDialog → ElementLookupDialog}/Manual/ManualForm.d.ts +0 -0
  101. /package/es/elements/{AddElementDialog → ElementLookupDialog}/utils/Giai.d.ts +0 -0
  102. /package/es/elements/{AddElementDialog → ElementLookupDialog}/utils/Giai.js +0 -0
  103. /package/es/elements/{AddElementDialog → ElementLookupDialog}/utils/beep.d.ts +0 -0
  104. /package/es/elements/{AddElementDialog → ElementLookupDialog}/utils/beep.js +0 -0
  105. /package/src/elements/{ElementDamageForm → ElementDamage}/DuplicateDamage/DesktopView.tsx +0 -0
  106. /package/src/elements/{ElementDamageForm → ElementDamage}/DuplicateDamage/PhoneView.tsx +0 -0
  107. /package/src/elements/{ElementDamageForm → ElementDamage}/index.css +0 -0
  108. /package/src/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/DeadIcon.tsx +0 -0
  109. /package/src/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/Error.tsx +0 -0
  110. /package/src/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/index.tsx +0 -0
  111. /package/src/elements/{AddElementDialog → ElementLookupDialog}/BarcodeScanner/useScanner.ts +0 -0
  112. /package/src/elements/{AddElementDialog → ElementLookupDialog}/HIDScanner/index.css +0 -0
  113. /package/src/elements/{AddElementDialog → ElementLookupDialog}/HIDScanner/index.tsx +0 -0
  114. /package/src/elements/{AddElementDialog → ElementLookupDialog}/HIDScanner/useHIDScanner.ts +0 -0
  115. /package/src/elements/{AddElementDialog → ElementLookupDialog}/utils/Giai.ts +0 -0
  116. /package/src/elements/{AddElementDialog → ElementLookupDialog}/utils/beep.ts +0 -0
@@ -8,10 +8,11 @@ export { registerPlugin, FileStatus };
8
8
  type FilePondProps<T extends Record<string, unknown>> = React.HTMLProps<HTMLInputElement> & {
9
9
  dataObject: DataObject<T>;
10
10
  fields: Partial<T>;
11
- onFileStart: () => void;
12
- onFileProcessed: (error: FilePondErrorDescription | null, file: FilePondFile) => void;
13
- onFilesProcessed: () => void;
14
- onError: () => void;
11
+ onUploadStart: () => void;
12
+ onFileUploaded: (error: FilePondErrorDescription | null, file: FilePondFile) => void;
13
+ onFinishedUploads: () => void;
14
+ onError: (error: string) => void;
15
+ onFileRemoved?: (primKey: string) => void;
15
16
  /**
16
17
  * If the file should be uploaded to a blob field, set the field name here
17
18
  */
@@ -28,6 +29,8 @@ type FilePondProps<T extends Record<string, unknown>> = React.HTMLProps<HTMLInpu
28
29
  * Options to pass to FilePond
29
30
  */
30
31
  filePondOptions?: Partial<FilePondOptions>;
32
+ attachmentPrimKeys?: string[];
33
+ whereClause?: string;
31
34
  };
32
35
  type FileStoreDataObjectRecord = {
33
36
  PrimKey: string;
@@ -38,4 +41,4 @@ type FileStoreDataObjectRecord = {
38
41
  Damage: boolean;
39
42
  DamageID: number | null;
40
43
  };
41
- export declare function FilePond<T extends FileStoreDataObjectRecord>({ dataObject, fields, onFileStart, onFileProcessed, onFilesProcessed, onError, fieldName, filePondOptions, primKey, inputRef: inputRefProp, ...props }: FilePondProps<T>): import("react/jsx-runtime").JSX.Element;
44
+ export declare function FilePond<T extends FileStoreDataObjectRecord>({ dataObject, fields, onUploadStart, onFileUploaded, onFinishedUploads, onFileRemoved, onError, fieldName, filePondOptions, primKey, attachmentPrimKeys, whereClause, inputRef: inputRefProp, ...props }: FilePondProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -1,15 +1,15 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import "filepond-plugin-file-poster/dist/filepond-plugin-file-poster.css";
3
3
  import "filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css";
4
4
  import "filepond/dist/filepond.css";
5
5
  import { getLocalizedString } from "@olenbetong/appframe-core";
6
- import { useData } from "@olenbetong/appframe-react";
6
+ import { useData, useFetchData } from "@olenbetong/appframe-react";
7
7
  import { create, FileStatus, registerPlugin, } from "filepond";
8
8
  import FilePondPluginImageExifOrientation from "filepond-plugin-image-exif-orientation";
9
9
  import FilePondPluginImagePreview from "filepond-plugin-image-preview";
10
10
  import FilePondPluginImageResize from "filepond-plugin-image-resize";
11
11
  import FilePondPluginImageTransform from "filepond-plugin-image-transform";
12
- import { useEffect, useRef } from "react";
12
+ import { useEffect, useMemo, useRef } from "react";
13
13
  export { registerPlugin, FileStatus };
14
14
  registerPlugin(FilePondPluginImageExifOrientation, FilePondPluginImageResize, FilePondPluginImagePreview, FilePondPluginImageTransform);
15
15
  let isMostLikelyMobile = navigator.userAgent.match(/Android/i) ||
@@ -57,10 +57,26 @@ const labels = {
57
57
  imageValidateSizeLabelExpectedMinResolution: getLocalizedString("Minimum resolution is {minResolution}"),
58
58
  imageValidateSizeLabelExpectedMaxResolution: getLocalizedString("Maximum resolution is {maxResolution}"),
59
59
  };
60
- export function FilePond({ dataObject, fields, onFileStart, onFileProcessed, onFilesProcessed, onError, fieldName, filePondOptions, primKey, inputRef: inputRefProp, ...props }) {
60
+ function getFileUrl(dataObject, fieldName, primKey, action = "upload") {
61
+ let url = action === "upload"
62
+ ? dataObject.dataHandler.getUploadUrl()
63
+ : dataObject.dataHandler.getFileStoreURL(primKey ?? "", fieldName ?? "");
64
+ if (action === "upload") {
65
+ url += "/";
66
+ }
67
+ return url?.replaceAll("//", "/") ?? "";
68
+ }
69
+ export function FilePond({ dataObject, fields, onUploadStart, onFileUploaded, onFinishedUploads, onFileRemoved, onError, fieldName, filePondOptions, primKey, attachmentPrimKeys, whereClause, inputRef: inputRefProp, ...props }) {
61
70
  let inputRef = useRef(null);
62
71
  let pondRef = useRef(null);
63
- let files = useData(dataObject);
72
+ let filesData = useData(dataObject);
73
+ let { data: filesFetched } = useFetchData(dataObject, whereClause ?? "1=2");
74
+ let files = useMemo(() => {
75
+ if (whereClause) {
76
+ return filesFetched;
77
+ }
78
+ return filesData;
79
+ }, [whereClause, filesFetched, filesData]);
64
80
  let clearFilesRef = useRef(false);
65
81
  useEffect(() => {
66
82
  return () => {
@@ -82,6 +98,7 @@ export function FilePond({ dataObject, fields, onFileStart, onFileProcessed, onF
82
98
  PrimKey: source,
83
99
  });
84
100
  if (result) {
101
+ onFileRemoved?.(source);
85
102
  load();
86
103
  }
87
104
  else {
@@ -95,10 +112,6 @@ export function FilePond({ dataObject, fields, onFileStart, onFileProcessed, onF
95
112
  "Failed to delete file on server but no error was returned.");
96
113
  }
97
114
  }
98
- let uploadUrl = dataObject.dataHandler.getUploadUrl({ fieldName, primKey });
99
- if (!uploadUrl) {
100
- throw new Error("DataHandler does not support file uploads.");
101
- }
102
115
  let options = {
103
116
  allowMultiple: Boolean(props.multiple),
104
117
  allowImageResize: true,
@@ -107,21 +120,34 @@ export function FilePond({ dataObject, fields, onFileStart, onFileProcessed, onF
107
120
  imageResizeTargetHeight: 2400,
108
121
  imageResizeUpscale: false,
109
122
  ...labels,
110
- onaddfilestart: () => onFileStart(),
111
- onprocessfile: (error, file) => onFileProcessed(error, file),
112
- onprocessfiles: () => onFilesProcessed(),
113
- onerror: () => onError(),
114
- beforeRemoveFile: (_file) => {
123
+ onaddfilestart: (file) => {
124
+ if (file.status !== 5 && file.status !== 6 && file.status !== 10) {
125
+ onUploadStart();
126
+ }
127
+ },
128
+ onprocessfile: (error, file) => {
129
+ onFileUploaded(error, file);
130
+ let refFiles = pondRef.current?.getFiles();
131
+ let found = refFiles?.find((file) => file.status !== 2 && file.status !== 5 && file.status !== 6 && file.status !== 10);
132
+ if (found === undefined) {
133
+ onFinishedUploads();
134
+ }
135
+ },
136
+ onprocessfiles: () => onFinishedUploads(),
137
+ onerror: (error) => onError(error.body),
138
+ beforeRemoveFile: () => {
115
139
  if (confirm(getLocalizedString("Are you sure you want to remove this file?"))) {
116
140
  return true;
117
141
  }
118
142
  return false;
119
143
  },
120
144
  server: {
145
+ load: getFileUrl(dataObject, fieldName, primKey, "view"),
146
+ restore: getFileUrl(dataObject, fieldName, primKey, "view"),
121
147
  revert: removeUploadedFile,
122
148
  remove: removeUploadedFile,
123
149
  process: {
124
- url: uploadUrl,
150
+ url: getFileUrl(dataObject, fieldName),
125
151
  ondata: (formData) => {
126
152
  let masterChildCriteria = dataObject.getParameter("masterChildCriteria");
127
153
  let allFields = { ...masterChildCriteria, ...fields };
@@ -148,13 +174,14 @@ export function FilePond({ dataObject, fields, onFileStart, onFileProcessed, onF
148
174
  props.multiple,
149
175
  fields,
150
176
  fieldName,
177
+ primKey,
151
178
  inputRefProp,
152
179
  filePondOptions,
153
180
  onError,
154
- onFileProcessed,
155
- onFileStart,
156
- onFilesProcessed,
157
- primKey,
181
+ onFileUploaded,
182
+ onUploadStart,
183
+ onFinishedUploads,
184
+ onFileRemoved,
158
185
  ]);
159
186
  useEffect(() => {
160
187
  if (pondRef.current) {
@@ -174,5 +201,5 @@ export function FilePond({ dataObject, fields, onFileStart, onFileProcessed, onF
174
201
  clearFilesRef.current = false;
175
202
  };
176
203
  }, [files]);
177
- return (_jsx("div", { className: "filepond--wrapper", children: _jsx("input", { type: "file", ...props, name: "File", ref: inputRefProp ?? inputRef }) }));
204
+ return (_jsxs("div", { className: "filepond--wrapper", children: [attachmentPrimKeys && _jsx("input", { type: "hidden", name: "AttachmentPrimkeys", value: attachmentPrimKeys }), _jsx("input", { type: "file", ...props, name: "File", ref: inputRefProp ?? inputRef })] }));
178
205
  }
@@ -0,0 +1,9 @@
1
+ type DamageFormButtonsProps = {
2
+ isEdit: boolean;
3
+ loading: boolean;
4
+ uploadingFile: boolean;
5
+ handleDelete: () => void;
6
+ handleCancel: () => void;
7
+ };
8
+ export declare function DamageFormButtonsProps({ isEdit, loading, uploadingFile, handleDelete, handleCancel, }: DamageFormButtonsProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Add from "@mui/icons-material/Add";
3
+ import { Button } from "@mui/material";
4
+ import { getLocalizedString } from "@olenbetong/appframe-core";
5
+ export function DamageFormButtonsProps({ isEdit, loading, uploadingFile, handleDelete, handleCancel, }) {
6
+ return (_jsxs(_Fragment, { children: [isEdit && _jsx(Button, { onClick: handleDelete, children: getLocalizedString("Delete") }), _jsx(Button, { onClick: handleCancel, children: getLocalizedString("Cancel") }), _jsx(Button, { loading: loading || uploadingFile, loadingPosition: "start", startIcon: _jsx(Add, {}), type: "submit", variant: "contained", children: isEdit ? getLocalizedString("Save changes") : getLocalizedString("Register damage") })] }));
7
+ }
@@ -0,0 +1,14 @@
1
+ export type DescriptionInputType = {
2
+ Description?: string | null;
3
+ Cause?: string | null;
4
+ Action?: string | null;
5
+ Date?: Date;
6
+ };
7
+ type DescriptionInputProps = {
8
+ value?: DescriptionInputType | null;
9
+ defaultValue?: DescriptionInputType | null;
10
+ onCopyPrevDamage?: (value: DescriptionInputType) => void;
11
+ onChange?: (value: DescriptionInputType) => void;
12
+ };
13
+ export declare function DescriptionInput({ value, defaultValue, onCopyPrevDamage, onChange }: DescriptionInputProps): import("react/jsx-runtime").JSX.Element;
14
+ export {};
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Autocomplete, Button, TextField } from "@mui/material";
3
+ import { getLocalizedString } from "@olenbetong/appframe-core";
4
+ import { useEffect, useRef, useState } from "react";
5
+ export function DescriptionInput({ value, defaultValue, onCopyPrevDamage, onChange }) {
6
+ let initializedRef = useRef(false);
7
+ let [input, setInput] = useState(defaultValue ?? null);
8
+ let inputValue = value === undefined ? input : value;
9
+ // biome-ignore lint: intentionally skipping "value" dependency as this should never run when "value" changes
10
+ useEffect(() => {
11
+ if (initializedRef.current) {
12
+ return;
13
+ }
14
+ if (value === undefined && defaultValue) {
15
+ setInput(defaultValue);
16
+ initializedRef.current = true;
17
+ }
18
+ }, [defaultValue]);
19
+ function handleCopyPrevDamage() {
20
+ let description = localStorage.getItem("ElementDamage_Description") ?? "";
21
+ let cause = localStorage.getItem("ElementDamage_Cause") ?? "";
22
+ let action = localStorage.getItem("ElementDamage_Action") ?? "";
23
+ onCopyPrevDamage?.({
24
+ Description: description,
25
+ Cause: cause,
26
+ Action: action,
27
+ });
28
+ setInput({
29
+ ...inputValue,
30
+ Description: description,
31
+ Cause: cause,
32
+ Action: action,
33
+ });
34
+ }
35
+ function handleOnChange(value) {
36
+ onChange?.(value);
37
+ setInput(value);
38
+ }
39
+ return (_jsxs(_Fragment, { children: [_jsx(TextField, { name: "Date", type: "date", value: (inputValue?.Date ?? new Date()).toISOString().split("T")[0], onChange: (event) => handleOnChange({ ...inputValue, Date: new Date(event.target.value) }), id: "NewElementDamage_Date", label: getLocalizedString("Date"), fullWidth: true, required: true, slotProps: { inputLabel: { shrink: true } } }), _jsx(Button, { variant: "contained", onClick: handleCopyPrevDamage, children: getLocalizedString("Copy previous damage") }), _jsx(Autocomplete, { value: inputValue?.Description ?? "", onChange: (_event, value) => handleOnChange({ ...inputValue, Description: value ?? "" }), options: [
40
+ getLocalizedString("Tear in element"),
41
+ getLocalizedString("Damage around lifting anchor"),
42
+ getLocalizedString("Damage on underside"),
43
+ ], freeSolo: true, renderInput: (params) => (_jsx(TextField, { name: "Description", required: true, ...params, label: getLocalizedString("Description") })) }), _jsx(TextField, { name: "Cause", id: "NewElementDamage_Cause", value: inputValue?.Cause ?? "", onChange: (event) => handleOnChange({ ...inputValue, Cause: event.currentTarget.value }), label: getLocalizedString("Cause"), fullWidth: true }), _jsx(TextField, { name: "Action", id: "NewElementDamage_Action", value: inputValue?.Action ?? "", onChange: (event) => handleOnChange({ ...inputValue, Action: event.currentTarget.value }), label: getLocalizedString("Action"), fullWidth: true })] }));
44
+ }
@@ -1,9 +1,10 @@
1
1
  import type { DamagesRecord } from "../../data";
2
2
  type DuplicateElementDamageDialogProps = {
3
3
  open: boolean;
4
- onClose: (value: boolean) => void;
4
+ onClose: () => void;
5
5
  record: DamagesRecord[];
6
- fallBack: () => void;
6
+ onRegisterAnyway: () => void;
7
+ loading: boolean;
7
8
  };
8
- export declare function DuplicateElementDamageDialog({ open, onClose, record, fallBack }: DuplicateElementDamageDialogProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function DuplicateElementDamageDialog({ open, onClose, record, onRegisterAnyway, loading, }: DuplicateElementDamageDialogProps): import("react/jsx-runtime").JSX.Element;
9
10
  export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Add from "@mui/icons-material/Add";
3
+ import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Grid, useMediaQuery } from "@mui/material";
4
+ import { getLocalizedString } from "@olenbetong/appframe-core";
5
+ import { theme } from "@olenbetong/appframe-mui";
6
+ import { ElementDamagesHeader, ElementDamagesItem } from "./DesktopView";
7
+ import { DuplicatePhoneViewItem } from "./PhoneView";
8
+ export function DuplicateElementDamageDialog({ open, onClose, record, onRegisterAnyway, loading, }) {
9
+ let matches = useMediaQuery(theme.breakpoints.up("lg"));
10
+ let backgroundColor = "#e9ebee";
11
+ return (_jsxs(Dialog, { open: open, onClose: onClose, fullWidth: true, fullScreen: !matches, children: [_jsx(DialogTitle, { sx: { backgroundColor: backgroundColor }, children: getLocalizedString("This element has one or more unfixed registered damage") }), _jsx(DialogContent, { sx: { backgroundColor: backgroundColor }, children: _jsx(Grid, { container: true, children: matches ? (_jsxs(_Fragment, { children: [_jsx(ElementDamagesHeader, {}), record.map((record) => (_jsx(ElementDamagesItem, { record: record }, record.PrimKey)))] })) : (_jsx("div", { className: "flow", style: { width: "100%" }, children: record.map((record) => (_jsx(DuplicatePhoneViewItem, { record: record }, record.PrimKey))) })) }) }), _jsxs(DialogActions, { sx: { backgroundColor: backgroundColor }, children: [_jsx(Button, { onClick: onClose, children: getLocalizedString("Cancel") }), _jsx(Button, { startIcon: _jsx(Add, {}), variant: "contained", type: "submit", onClick: onRegisterAnyway, loading: loading, loadingPosition: "start", children: getLocalizedString("Register damage anyway") })] })] }));
12
+ }
@@ -0,0 +1,36 @@
1
+ import { type DamagesRecord } from "../../data";
2
+ import type { Element } from "../../ElementLookup";
3
+ export { DuplicateElementDamageDialog } from "./DublicateElementDamageDialog";
4
+ export type DuplicateElementDamageHandle = {
5
+ onClose: () => void;
6
+ checkDuplicate: () => Promise<DamagesRecord[] | null>;
7
+ record: DamagesRecord[];
8
+ };
9
+ type DuplicateElementDamageProps = {
10
+ element: Element | null;
11
+ /**
12
+ * External control of dialog visibility
13
+ */
14
+ open?: boolean;
15
+ onOpenChange?: (value: boolean) => void;
16
+ /**
17
+ * Skip duplicate checking (used in edit mode)
18
+ */
19
+ disableCheck?: boolean;
20
+ /**
21
+ * Loading state for submit button
22
+ */
23
+ loading?: boolean;
24
+ /**
25
+ * Called when duplicate or duplicates are found
26
+ * @param record Array with all of the duplicate damages
27
+ * @returns void
28
+ */
29
+ onDuplicateFound?: (record: DamagesRecord[]) => void;
30
+ /**
31
+ * Called when user presses register anyway in dialog
32
+ * @returns void
33
+ */
34
+ onRegisterAnyway?: () => void;
35
+ };
36
+ export declare const DuplicateElementDamage: import("react").ForwardRefExoticComponent<DuplicateElementDamageProps & import("react").RefAttributes<DuplicateElementDamageHandle>>;
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useDataWithFilter } from "@olenbetong/appframe-react";
3
+ import { forwardRef, useImperativeHandle, useMemo, useState } from "react";
4
+ import { dsDamagesDuplicateCheck } from "../../data";
5
+ import { DuplicateElementDamageDialog } from "./DublicateElementDamageDialog";
6
+ export { DuplicateElementDamageDialog } from "./DublicateElementDamageDialog";
7
+ export const DuplicateElementDamage = forwardRef(function DuplicateElementDamage({ element, open: controlledOpen, onOpenChange, disableCheck = false, loading = false, onRegisterAnyway, }, ref) {
8
+ let [record, setRecord] = useState([]);
9
+ let [uncontrolledOpen, setUncontrolledOpen] = useState(false);
10
+ let open = controlledOpen === undefined ? uncontrolledOpen : controlledOpen;
11
+ let whereClause = useMemo(() => {
12
+ if (!element) {
13
+ return "1=0";
14
+ }
15
+ return `Domain = '${element.Domain}' AND ElementID = '${element.ElementID}' AND ProjectID = '${element.ProjectID}'`;
16
+ }, [element]);
17
+ let duplicateRecord = useDataWithFilter(dsDamagesDuplicateCheck, whereClause, "whereClause");
18
+ async function runDuplicateCheck() {
19
+ // If we are editing a record, we don't need to check for duplicates
20
+ if (disableCheck) {
21
+ return null;
22
+ }
23
+ if (duplicateRecord.length > 0) {
24
+ setRecord(duplicateRecord);
25
+ setUncontrolledOpen(true);
26
+ return duplicateRecord;
27
+ }
28
+ return null;
29
+ }
30
+ function handleOpenChange(value) {
31
+ setUncontrolledOpen(value);
32
+ onOpenChange?.(value);
33
+ }
34
+ useImperativeHandle(ref, () => ({
35
+ onClose: () => setUncontrolledOpen(false),
36
+ checkDuplicate: () => runDuplicateCheck(),
37
+ record: record,
38
+ }));
39
+ return (_jsx(DuplicateElementDamageDialog, { open: open, onClose: () => handleOpenChange(false), record: record, onRegisterAnyway: onRegisterAnyway ?? (() => { }), loading: loading ?? false }));
40
+ });
@@ -0,0 +1,10 @@
1
+ import { type SxProps, type Theme } from "@mui/material";
2
+ type ElementNumberTextFieldProps = {
3
+ value?: string | null;
4
+ defaultValue?: string | null;
5
+ onChange?: (value: string) => void;
6
+ disabled?: boolean;
7
+ sx?: SxProps<Theme>;
8
+ };
9
+ export declare function ElementNumberTextField({ value, defaultValue, onChange, disabled, sx }: ElementNumberTextFieldProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { TextField } from "@mui/material";
3
+ import { getLocalizedString } from "@olenbetong/appframe-core";
4
+ import { useEffect, useState } from "react";
5
+ export function ElementNumberTextField({ value, defaultValue, onChange, disabled, sx }) {
6
+ let [elementNumber, setElementNumber] = useState(defaultValue ?? "");
7
+ let elementNumberValue = value === undefined ? elementNumber : value;
8
+ useEffect(() => {
9
+ if (value === undefined && defaultValue) {
10
+ setElementNumber(defaultValue);
11
+ }
12
+ }, [defaultValue, value]);
13
+ function handleChange(value) {
14
+ onChange?.(value);
15
+ setElementNumber(value);
16
+ }
17
+ return (_jsx(TextField, { name: "ElementNumber", id: "NewElementDamage_ElementNr", value: elementNumberValue, onChange: (event) => handleChange(event.currentTarget.value), label: getLocalizedString("Element number"), fullWidth: true, autoComplete: "off", disabled: disabled ?? false, sx: { ...sx } }));
18
+ }
@@ -0,0 +1,6 @@
1
+ type HiddenDamageFieldsProps = {
2
+ primKey: string;
3
+ ID: number;
4
+ };
5
+ export declare function HiddenDamageFields({ primKey, ID }: HiddenDamageFieldsProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function HiddenDamageFields({ primKey, ID }) {
3
+ return (_jsxs(_Fragment, { children: [_jsx("input", { type: "hidden", name: "PrimKey", value: primKey }), _jsx("input", { type: "hidden", name: "ID", value: ID })] }));
4
+ }
@@ -0,0 +1,14 @@
1
+ type RegisterFixType = {
2
+ ID: number;
3
+ RegisteredFixFullName: string | null;
4
+ RegisteredFix: Date | null;
5
+ RegisteredFixBy: string | null;
6
+ };
7
+ type RegisterFixProps = {
8
+ value?: RegisterFixType | null;
9
+ defaultValue?: RegisterFixType | null;
10
+ onFix?: (ID: number) => void;
11
+ edit?: boolean;
12
+ };
13
+ export declare function RegisterFix({ value, defaultValue, onFix, edit }: RegisterFixProps): import("react/jsx-runtime").JSX.Element;
14
+ export {};
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import CheckIcon from "@mui/icons-material/Check";
3
+ import { Button, Checkbox, FormControlLabel, Typography } from "@mui/material";
4
+ import { getLocalizedString, localize } from "@olenbetong/appframe-core";
5
+ import { useEffect, useRef, useState } from "react";
6
+ import { procApproveDamage } from "../data";
7
+ const formatter = new Intl.DateTimeFormat(af.userSession.culture, {
8
+ day: "numeric",
9
+ month: "long",
10
+ year: "numeric",
11
+ hour: "2-digit",
12
+ minute: "2-digit",
13
+ timeZone: "UTC",
14
+ });
15
+ export function RegisterFix({ value, defaultValue, onFix, edit }) {
16
+ let [loading, setLoading] = useState(false);
17
+ let initializedRef = useRef(false);
18
+ let [fix, setFix] = useState(defaultValue ?? null);
19
+ let fixValue = value === undefined ? fix : value;
20
+ // biome-ignore lint: intentionally skipping "value" dependency as this should never run when "value" changes
21
+ useEffect(() => {
22
+ if (initializedRef.current) {
23
+ return;
24
+ }
25
+ if (value === undefined && defaultValue) {
26
+ setFix(defaultValue);
27
+ initializedRef.current = true;
28
+ }
29
+ }, [defaultValue]);
30
+ async function handleRegisterFix() {
31
+ try {
32
+ if (confirm(getLocalizedString("Are you sure you want to register a fix for this damage?"))) {
33
+ setLoading(true);
34
+ let record = (await procApproveDamage.execute({ ID: fixValue?.ID }));
35
+ setFix({ ...record.Table[0] });
36
+ setLoading(false);
37
+ onFix?.(fixValue?.ID ?? -1);
38
+ }
39
+ }
40
+ catch (error) {
41
+ alert(error.message);
42
+ }
43
+ }
44
+ return (_jsxs(_Fragment, { children: [edit ? (_jsx(Button, { loading: loading, loadingPosition: "end", endIcon: _jsx(CheckIcon, {}), onClick: handleRegisterFix, disabled: !!fixValue?.RegisteredFix, variant: "contained", children: getLocalizedString("Register fix") })) : (_jsx(FormControlLabel, { control: _jsx(Checkbox, {}), label: getLocalizedString("Register fixed"), name: "RegisteredFix", id: "NewElementDamage_RegisteredFix" })), fixValue?.RegisteredFix && (_jsx(Typography, { mb: 1.5, color: "text.secondary", children: localize `Registered fix by ${fixValue.RegisteredFixFullName ?? fixValue.RegisteredFixBy} on the ${formatter.format(fixValue.RegisteredFix)}` }))] }));
45
+ }
@@ -0,0 +1,20 @@
1
+ import { type SxProps, type Theme } from "@mui/material";
2
+ type SubmitButtonsProps = {
3
+ /**
4
+ * Whether the form is in edit mode. If true, delete button is visible and submit button's text changes.
5
+ */
6
+ edit?: boolean;
7
+ /**
8
+ * Set loading state for submit button
9
+ */
10
+ loading?: boolean;
11
+ /**
12
+ * Custom styles for Box wrapper around buttons
13
+ */
14
+ sx?: SxProps<Theme>;
15
+ onDelete?: () => void;
16
+ onCancel?: () => void;
17
+ onSubmit?: () => void;
18
+ };
19
+ export declare function SubmitButtons({ edit, loading, onDelete, onCancel, onSubmit, sx }: SubmitButtonsProps): import("react/jsx-runtime").JSX.Element;
20
+ export {};
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Add from "@mui/icons-material/Add";
3
+ import { Box, Button } from "@mui/material";
4
+ import { getLocalizedString } from "@olenbetong/appframe-core";
5
+ export function SubmitButtons({ edit, loading, onDelete, onCancel, onSubmit, sx }) {
6
+ return (_jsxs(Box, { sx: { display: "flex", flexWrap: "wrap", gap: 2, justifyContent: "flex-end", ...sx }, children: [edit && _jsx(Button, { onClick: onDelete, children: getLocalizedString("Delete") }), _jsx(Button, { onClick: onCancel, children: getLocalizedString("Cancel") }), _jsx(Button, { loading: loading, loadingPosition: "start", startIcon: _jsx(Add, {}), type: "submit", variant: "contained", onClick: onSubmit, children: edit ? getLocalizedString("Save changes") : getLocalizedString("Register damage") })] }));
7
+ }
@@ -0,0 +1,7 @@
1
+ import type { TransportElementsRecord } from "../data/dsTransportElements.js";
2
+ type TransportElementSelectProps = {
3
+ elements: TransportElementsRecord[];
4
+ onSelect: (element: TransportElementsRecord) => void;
5
+ };
6
+ export declare function TransportElementSelect({ elements, onSelect }: TransportElementSelectProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import DropDownArrowIcon from "@mui/icons-material/KeyboardArrowDown";
3
+ import { Button, ListItemText, Menu, MenuItem } from "@mui/material";
4
+ import { getLocalizedString } from "@olenbetong/appframe-core";
5
+ import { useState } from "react";
6
+ export function TransportElementSelect({ elements, onSelect }) {
7
+ let [anchorEl, setAnchorEl] = useState(null);
8
+ let open = !!anchorEl;
9
+ let [selected, setSelected] = useState(null);
10
+ function handleChange(element) {
11
+ setAnchorEl(null);
12
+ onSelect(element);
13
+ setSelected(element);
14
+ }
15
+ return (_jsxs(_Fragment, { children: [_jsx(Button, { id: "select_element", variant: "contained", endIcon: _jsx(DropDownArrowIcon, { style: { transform: open ? "rotate(180deg)" : "rotate(0deg)", transition: "transform 0.2s" } }), sx: { width: "165px" }, "aria-controls": open ? "basic-menu" : undefined, "aria-haspopup": "true", "aria-expanded": open ? "true" : undefined, onClick: (event) => setAnchorEl(event.currentTarget), children: selected ? `${selected.ElementID} - ${selected.Name}` : getLocalizedString("Select element") }), _jsx(Menu, { id: "menu_element", anchorEl: anchorEl, open: open, onClose: () => setAnchorEl(null), children: elements.map((element) => (_jsx(MenuItem, { onClick: () => handleChange(element), children: _jsxs(ListItemText, { children: [element.ElementID, " - ", element.Name] }) }, element.PrimKey))) })] }));
16
+ }
@@ -0,0 +1,20 @@
1
+ import { type RefObject } from "react";
2
+ export type Element = {
3
+ Domain: string;
4
+ PrimKey: string;
5
+ ProjectID: string;
6
+ ProjectName: string;
7
+ ElementID: string | null;
8
+ };
9
+ export type ElementLookupHandle = {
10
+ openDialog: () => void;
11
+ closeDialog: () => void;
12
+ };
13
+ export type ElementLookupProps = {
14
+ value?: Element | null;
15
+ defaultValue?: Element | null;
16
+ ref?: RefObject<ElementLookupHandle | null>;
17
+ openLookupDialogIcon?: boolean;
18
+ onChange?: (value: Element | null) => void;
19
+ };
20
+ export declare function ElementLookup({ value, defaultValue, ref, openLookupDialogIcon, onChange }: ElementLookupProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import SearchIcon from "@mui/icons-material/Search";
3
+ import { IconButton, TextField } from "@mui/material";
4
+ import { getLocalizedString } from "@olenbetong/appframe-core";
5
+ import { useEffect, useImperativeHandle, useState } from "react";
6
+ import { ElementLookupDialog } from "./ElementLookupDialog";
7
+ export function ElementLookup({ value, defaultValue, ref, openLookupDialogIcon, onChange }) {
8
+ let [openElementLookupDialog, setOpenElementLookupDialog] = useState(false);
9
+ let [element, setElement] = useState(defaultValue ?? null);
10
+ let elementValue = value === undefined ? element : value;
11
+ useEffect(() => {
12
+ if (value === undefined && defaultValue) {
13
+ setElement(defaultValue);
14
+ }
15
+ }, [defaultValue, value]);
16
+ useImperativeHandle(ref, () => ({
17
+ openDialog: () => setOpenElementLookupDialog(true),
18
+ closeDialog: () => setOpenElementLookupDialog(false),
19
+ }));
20
+ async function handleAddElement(addElement) {
21
+ onChange?.(addElement.element);
22
+ setElement(addElement.element);
23
+ }
24
+ return (_jsxs(_Fragment, { children: [_jsx(ElementLookupDialog, { open: openElementLookupDialog, mode: "single", onClose: () => setOpenElementLookupDialog(false), onAdd: handleAddElement }), _jsx("input", { type: "hidden", name: "ProjectID", value: elementValue?.ProjectID ?? "" }), _jsx("input", { type: "hidden", name: "ElementRef", value: elementValue?.PrimKey ?? "" }), _jsx(TextField, { id: "NewElementDamge_Project", value: elementValue ? `${elementValue.ProjectID}: ${elementValue.ProjectName}` : "", label: getLocalizedString("Project"), fullWidth: true, required: true, autoComplete: "off", slotProps: { htmlInput: { readOnly: true } } }), _jsx(TextField, { name: "ElementID", id: "NewElementDamage_ElementID", value: elementValue ? elementValue.ElementID : "", label: getLocalizedString("Element ID"), fullWidth: true, autoComplete: "off", slotProps: {
25
+ htmlInput: { readOnly: true },
26
+ input: {
27
+ endAdornment: openLookupDialogIcon ? (_jsx(IconButton, { onClick: () => setOpenElementLookupDialog(true), children: _jsx(SearchIcon, {}) })) : undefined,
28
+ },
29
+ } })] }));
30
+ }
@@ -2,12 +2,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import Add from "@mui/icons-material/Add";
3
3
  import { Alert, Button, TextField } from "@mui/material";
4
4
  import { getLocalizedString } from "@olenbetong/appframe-core";
5
- import { useRef, useState } from "react";
5
+ import { useId, useRef, useState } from "react";
6
6
  import { ProjectSelect } from "../../ProjectSelect";
7
7
  import { getElement } from "../getElement";
8
8
  const isElementsOnly = /^([a-z]{2,4}[\s]*[0-9]{4,8}[\s,]*)+$/i;
9
9
  const matchElements = /([a-z]{2,4}[\s]*[0-9]{4,8})/gi;
10
10
  export function AddElementManualForm({ onAdd, mode, defaultProject }) {
11
+ let id = useId();
11
12
  let buttonRef = useRef(null);
12
13
  let [working, setWorking] = useState(false);
13
14
  let [elementId, setElementId] = useState("");
@@ -15,6 +16,7 @@ export function AddElementManualForm({ onAdd, mode, defaultProject }) {
15
16
  async function handleSubmit(evt) {
16
17
  try {
17
18
  evt.preventDefault();
19
+ evt.stopPropagation();
18
20
  let formData = new FormData(evt.target);
19
21
  let elements = formData.get("ElementID");
20
22
  let domain = formData.get("Domain");
@@ -42,5 +44,5 @@ export function AddElementManualForm({ onAdd, mode, defaultProject }) {
42
44
  alert(error.message);
43
45
  }
44
46
  }
45
- return (_jsxs("form", { onSubmit: handleSubmit, method: "post", children: [_jsx(Alert, { severity: "warning", sx: { mb: 2 }, children: getLocalizedString("Manually entering elements is a major source of errors. Only use this as a last resort. If the camera or scanner is not working, please contact the IT department.") }), _jsx(ProjectSelect, { onChange: (project) => (project ? setProject(project) : setProject(null)), value: project, id: "AddElement_Project" }), _jsx(TextField, { variant: "filled", fullWidth: true, autoComplete: "off", margin: "normal", name: "ElementID", id: "AddElement_ElementID", label: getLocalizedString("Element ID"), value: elementId, onChange: (evt) => setElementId(evt.target.value) }), _jsx(Button, { ref: buttonRef, color: "primary", variant: "contained", size: "large", type: "submit", disabled: !isElementsOnly.test(elementId) || working, loading: working, loadingPosition: "end", endIcon: _jsx(Add, {}), children: getLocalizedString("Add") })] }));
47
+ return (_jsxs("form", { id: id, onSubmit: handleSubmit, method: "post", children: [_jsx(Alert, { severity: "warning", sx: { mb: 2 }, children: getLocalizedString("Manually entering elements is a major source of errors. Only use this as a last resort. If the camera or scanner is not working, please contact the IT department.") }), _jsx(ProjectSelect, { onChange: (project) => (project ? setProject(project) : setProject(null)), value: project, id: "AddElement_Project" }), _jsx(TextField, { variant: "filled", fullWidth: true, autoComplete: "off", margin: "normal", name: "ElementID", id: "AddElement_ElementID", label: getLocalizedString("Element ID"), value: elementId, onChange: (evt) => setElementId(evt.target.value) }), _jsx(Button, { form: id, ref: buttonRef, color: "primary", variant: "contained", size: "large", type: "submit", disabled: !isElementsOnly.test(elementId) || working, loading: working, loadingPosition: "end", endIcon: _jsx(Add, {}), children: getLocalizedString("Add") })] }));
46
48
  }
@@ -1,5 +1,6 @@
1
1
  export type AddElementSource = "manual" | "camera-barcode" | "loading-list" | "hid-barcode" | "hid-rfid";
2
2
  export type ElementDetails = {
3
+ Domain: string;
3
4
  PrimKey: string;
4
5
  Created: Date;
5
6
  ProjectID: string;
@@ -6,6 +6,7 @@ const elementsDataHandler = new DataProviderHandlerAPI({
6
6
  fields: [
7
7
  { name: "PrimKey", type: "string" },
8
8
  { name: "Created", type: "datetime" },
9
+ { name: "Domain", type: "string" },
9
10
  { name: "ProjectID", type: "string" },
10
11
  { name: "ProjectName", type: "string" },
11
12
  { name: "ProjectDomain", type: "string" },