@evoke-platform/ui-components 1.15.0 → 1.16.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/published/components/custom/CriteriaBuilder/CriteriaBuilder.d.ts +8 -4
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.js +242 -142
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.test.js +189 -67
- package/dist/published/components/custom/CriteriaBuilder/PropertyTree.d.ts +6 -6
- package/dist/published/components/custom/CriteriaBuilder/PropertyTree.js +12 -25
- package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.d.ts +4 -5
- package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.js +34 -22
- package/dist/published/components/custom/CriteriaBuilder/types.d.ts +2 -11
- package/dist/published/components/custom/CriteriaBuilder/utils.d.ts +6 -34
- package/dist/published/components/custom/CriteriaBuilder/utils.js +18 -89
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.js +1 -1
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.js +6 -3
- package/dist/published/components/custom/Form/utils.d.ts +1 -0
- package/dist/published/components/custom/FormV2/FormRenderer.d.ts +2 -1
- package/dist/published/components/custom/FormV2/FormRenderer.js +2 -8
- package/dist/published/components/custom/FormV2/FormRendererContainer.d.ts +4 -0
- package/dist/published/components/custom/FormV2/FormRendererContainer.js +229 -126
- package/dist/published/components/custom/FormV2/components/DefaultValues.d.ts +1 -1
- package/dist/published/components/custom/FormV2/components/DefaultValues.js +60 -89
- package/dist/published/components/custom/FormV2/components/FormContext.d.ts +1 -1
- package/dist/published/components/custom/FormV2/components/FormContext.js +0 -1
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/ActionDialog.d.ts +1 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/RepeatableField.js +43 -16
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Criteria.d.ts +2 -2
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Criteria.js +3 -2
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.d.ts +3 -2
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.js +44 -11
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.d.ts +4 -3
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.js +41 -29
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/FileContent.d.ts +12 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/FileContent.js +197 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Image.js +2 -4
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/InstanceLookup.js +14 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/RelatedObjectInstance.js +6 -2
- package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.js +16 -13
- package/dist/published/components/custom/FormV2/components/types.d.ts +6 -1
- package/dist/published/components/custom/FormV2/components/utils.d.ts +10 -8
- package/dist/published/components/custom/FormV2/components/utils.js +168 -82
- package/dist/published/components/custom/ViewDetailsV2/InstanceEntryRenderer.js +6 -1
- package/dist/published/components/custom/index.d.ts +1 -0
- package/dist/published/index.d.ts +1 -1
- package/dist/published/stories/CriteriaBuilder.stories.js +70 -22
- package/dist/published/stories/FormRenderer.stories.d.ts +6 -3
- package/dist/published/stories/FormRendererContainer.stories.d.ts +20 -0
- package/dist/published/theme/hooks.d.ts +3 -3
- package/package.json +3 -1
|
@@ -3,105 +3,32 @@ import { parseMongoDB } from '../util';
|
|
|
3
3
|
/**
|
|
4
4
|
* Recursively updates a node in a tree structure by applying an updater function to the node with the specified ID.
|
|
5
5
|
*
|
|
6
|
-
* @param {
|
|
6
|
+
* @param {TreeViewProperty[]} tree - The tree structure to update.
|
|
7
7
|
* @param {string} nodeId - The ID of the node to update.
|
|
8
|
-
* @param {(node:
|
|
9
|
-
* @returns {
|
|
8
|
+
* @param {(node: TreeViewProperty) => TreeViewProperty} updater - The function to apply to the node.
|
|
9
|
+
* @returns {TreeViewProperty[]} - The updated tree structure.
|
|
10
10
|
*/
|
|
11
|
-
export const
|
|
11
|
+
export const updateTreeViewProperty = (tree, nodeId, updater) => {
|
|
12
12
|
return tree.map((node) => {
|
|
13
13
|
if (node.id === nodeId) {
|
|
14
14
|
return updater(node);
|
|
15
15
|
}
|
|
16
16
|
else if (node.children) {
|
|
17
|
-
return { ...node, children:
|
|
17
|
+
return { ...node, children: updateTreeViewProperty(node.children, nodeId, updater) };
|
|
18
18
|
}
|
|
19
19
|
else {
|
|
20
20
|
return node;
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
export const fetchDisplayNamePath = async (propertyId, rootObject, fetchObject) => {
|
|
33
|
-
const propertyInfo = await traversePropertyPath(propertyId, rootObject, fetchObject);
|
|
34
|
-
return propertyInfo ? propertyInfo.name : '';
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* stores full dot-notation path to each property ID in the given array of properties.
|
|
38
|
-
*
|
|
39
|
-
* @param {ObjectProperty[]} properties - The array of properties to update.
|
|
40
|
-
* @param {string} parentPath - The parent path to attach to each property ID.
|
|
41
|
-
* @returns {ObjectProperty[]} The updated array of properties with the parent path attached to each property ID.
|
|
42
|
-
*/
|
|
43
|
-
export const setIdPaths = (properties, parentPath) => {
|
|
44
|
-
return properties.map((prop) => {
|
|
45
|
-
const fullPath = parentPath ? `${parentPath}.${prop.id}` : prop.id;
|
|
46
|
-
return {
|
|
47
|
-
...prop,
|
|
48
|
-
id: fullPath,
|
|
49
|
-
};
|
|
50
|
-
});
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* Traverses a property path within an object hierarchy to retrieve detailed property information.
|
|
54
|
-
*
|
|
55
|
-
* @param {string} propertyPath - The dot-separated path of the property to traverse.
|
|
56
|
-
* @param {Obj} rootObject - The root object from which to start the traversal.
|
|
57
|
-
* @param {FetchObjectFunction} fetchObject - A function to fetch an object by its ID.
|
|
58
|
-
* @returns {Promise<ObjectProperty | null>} A promise that resolves to an ObjectProperty if found, or null otherwise.
|
|
59
|
-
*/
|
|
60
|
-
export const traversePropertyPath = async (propertyPath, rootObject, fetchObject) => {
|
|
61
|
-
const segments = propertyPath.split('.');
|
|
62
|
-
let currentObject = rootObject;
|
|
63
|
-
let fullPath = '';
|
|
64
|
-
let namePath = '';
|
|
65
|
-
for (let i = 0; i < segments.length; i++) {
|
|
66
|
-
const remainingPath = segments.slice(i).join('.');
|
|
67
|
-
let prop = currentObject.properties?.find((p) => p.id === remainingPath);
|
|
68
|
-
if (prop) {
|
|
69
|
-
// flattened address or user properties
|
|
70
|
-
fullPath = fullPath ? `${fullPath}.${remainingPath}` : remainingPath;
|
|
71
|
-
namePath = namePath ? `${namePath} / ${prop.name}` : prop.name;
|
|
72
|
-
return {
|
|
73
|
-
...prop,
|
|
74
|
-
id: fullPath,
|
|
75
|
-
name: namePath,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
prop = currentObject.properties?.find((p) => p.id === segments[i]);
|
|
80
|
-
if (!prop) {
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
fullPath = fullPath ? `${fullPath}.${prop.id}` : prop.id;
|
|
84
|
-
namePath = namePath ? `${namePath} / ${prop.name}` : prop.name;
|
|
85
|
-
if (i === segments.length - 1) {
|
|
86
|
-
return {
|
|
87
|
-
...prop,
|
|
88
|
-
id: fullPath,
|
|
89
|
-
name: namePath,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
if (prop.type === 'object' && prop.objectId) {
|
|
93
|
-
const fetchedObject = await fetchObject(prop.objectId);
|
|
94
|
-
if (fetchedObject) {
|
|
95
|
-
currentObject = fetchedObject;
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return null;
|
|
104
|
-
};
|
|
24
|
+
export const convertTreeViewPropertyToTreeItem = (property) => ({
|
|
25
|
+
id: property.id,
|
|
26
|
+
label: property.name,
|
|
27
|
+
value: property.id,
|
|
28
|
+
type: property.type,
|
|
29
|
+
objectId: property.objectId,
|
|
30
|
+
children: property.children?.map(convertTreeViewPropertyToTreeItem),
|
|
31
|
+
});
|
|
105
32
|
/**
|
|
106
33
|
* Truncates the name path if it exceeds the specified character limit.
|
|
107
34
|
*
|
|
@@ -184,9 +111,11 @@ export const findTreeItemById = (nodes, nodeId) => {
|
|
|
184
111
|
for (const node of nodes) {
|
|
185
112
|
if (node.id === nodeId)
|
|
186
113
|
return node;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
114
|
+
if (nodeId.startsWith(node.id)) {
|
|
115
|
+
const found = node.children && findTreeItemById(node.children, nodeId);
|
|
116
|
+
if (found)
|
|
117
|
+
return found;
|
|
118
|
+
}
|
|
190
119
|
}
|
|
191
120
|
return null;
|
|
192
121
|
};
|
|
@@ -43,7 +43,7 @@ export const Document = (props) => {
|
|
|
43
43
|
// For 'file' type properties, check permissions on the sys__file object
|
|
44
44
|
// For 'document' type properties, check document attachment permissions
|
|
45
45
|
const endpoint = property.type === 'file'
|
|
46
|
-
? getPrefixedUrl(
|
|
46
|
+
? getPrefixedUrl('/objects/sys__file/instances/checkAccess?action=execute&field=_create')
|
|
47
47
|
: getPrefixedUrl(`/objects/${objectId}/instances/${instance.id}/documents/checkAccess?action=update`);
|
|
48
48
|
apiServices
|
|
49
49
|
.get(endpoint)
|
package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.js
CHANGED
|
@@ -64,12 +64,15 @@ export const DocumentList = (props) => {
|
|
|
64
64
|
}, []);
|
|
65
65
|
const checkPermissions = () => {
|
|
66
66
|
if (instance?.[property.id]?.length) {
|
|
67
|
-
// For 'file' type properties, check
|
|
67
|
+
// For 'file' type properties, check regular object instance permissions
|
|
68
68
|
// For 'document' type properties, check document attachment permissions
|
|
69
69
|
const endpoint = property.type === 'file'
|
|
70
|
-
? getPrefixedUrl(`/objects/sys__file/instances
|
|
70
|
+
? getPrefixedUrl(`/objects/sys__file/instances/checkAccess?action=read&field=content`)
|
|
71
71
|
: getPrefixedUrl(`/objects/${objectId}/instances/${instance.id}/documents/checkAccess?action=view`);
|
|
72
|
-
apiServices
|
|
72
|
+
apiServices
|
|
73
|
+
.get(endpoint)
|
|
74
|
+
.then((accessCheck) => setHasViewPermission(accessCheck.result))
|
|
75
|
+
.catch(() => setHasViewPermission(false));
|
|
73
76
|
}
|
|
74
77
|
};
|
|
75
78
|
const isFile = (doc) => doc instanceof File;
|
|
@@ -25,6 +25,7 @@ export declare function flattenFormComponents(components?: ActionInput[]): Actio
|
|
|
25
25
|
export declare function addObjectPropertiesToComponentProps(properties: Property[], formComponents: any[], allCriteriaInputs?: string[], instance?: ObjectInstance, objectPropertyInputProps?: ObjectPropertyInputProps, associatedObject?: {
|
|
26
26
|
instanceId?: string;
|
|
27
27
|
propertyId?: string;
|
|
28
|
+
objectId?: string;
|
|
28
29
|
}, autoSave?: (data: Record<string, unknown>) => void, readOnly?: boolean, defaultPages?: Record<string, string>, navigateTo?: (path: string) => void, queryAddresses?: (query: string) => Promise<Address[]>, apiServices?: ApiServices, isModal?: boolean, fieldHeight?: 'small' | 'medium', richTextEditor?: typeof ReactComponent): Promise<ActionInput[]>;
|
|
29
30
|
export declare function getDefaultValue(initialValue: unknown, selectOptions?: AutocompleteOption[]): unknown;
|
|
30
31
|
export declare const buildComponentPropsFromObjectProperties: (properties: Property[], objectId: string, instance?: ObjectInstance, objectPropertyInputProps?: ObjectPropertyInputProps, hasActionPermissions?: boolean, autoSave?: ((data: Record<string, unknown>) => void) | undefined, readOnly?: boolean, queryAddresses?: ((query: string) => Promise<Address[]>) | undefined, isModal?: boolean, fieldHeight?: 'small' | 'medium', richTextEditor?: typeof ReactComponent) => unknown[];
|
|
@@ -9,7 +9,7 @@ import ValidationErrors from './components/ValidationFiles/ValidationErrors';
|
|
|
9
9
|
export type FormRendererProps = BaseProps & {
|
|
10
10
|
richTextEditor?: ComponentType<SimpleEditorProps>;
|
|
11
11
|
value?: FieldValues;
|
|
12
|
-
onSubmit?: (data: FieldValues) => void;
|
|
12
|
+
onSubmit?: (data: FieldValues) => Promise<void> | ((data: FieldValues) => void);
|
|
13
13
|
onDiscardChanges?: () => void;
|
|
14
14
|
onSubmitError?: SubmitErrorHandler<FieldValues>;
|
|
15
15
|
hideTitle?: boolean;
|
|
@@ -22,6 +22,7 @@ export type FormRendererProps = BaseProps & {
|
|
|
22
22
|
associatedObject?: {
|
|
23
23
|
instanceId: string;
|
|
24
24
|
propertyId: string;
|
|
25
|
+
objectId?: string;
|
|
25
26
|
};
|
|
26
27
|
renderHeader?: (props: HeaderProps) => React.ReactNode;
|
|
27
28
|
renderBody?: (props: BodyProps) => React.ReactNode;
|
|
@@ -30,7 +30,6 @@ const FormRendererInternal = (props) => {
|
|
|
30
30
|
const [fetchedOptions, setFetchedOptions] = useState({});
|
|
31
31
|
const [expandAll, setExpandAll] = useState();
|
|
32
32
|
const [action, setAction] = useState();
|
|
33
|
-
const [triggerFieldReset, setTriggerFieldReset] = useState(false);
|
|
34
33
|
const [isInitializing, setIsInitializing] = useState(true);
|
|
35
34
|
const [parameters, setParameters] = useState();
|
|
36
35
|
const validationContainerRef = useRef(null);
|
|
@@ -83,9 +82,6 @@ const FormRendererInternal = (props) => {
|
|
|
83
82
|
setValue(key, value[key], { shouldValidate: true });
|
|
84
83
|
}
|
|
85
84
|
}
|
|
86
|
-
if (triggerFieldReset === true) {
|
|
87
|
-
setTriggerFieldReset(false);
|
|
88
|
-
}
|
|
89
85
|
}
|
|
90
86
|
}, [value]);
|
|
91
87
|
const handleReset = () => {
|
|
@@ -95,7 +91,6 @@ const FormRendererInternal = (props) => {
|
|
|
95
91
|
else {
|
|
96
92
|
reset(instance); // clears react-hook-form state back to default values
|
|
97
93
|
}
|
|
98
|
-
setTriggerFieldReset(true);
|
|
99
94
|
};
|
|
100
95
|
useEffect(() => {
|
|
101
96
|
handleValidation(entries, register, getValues(), action?.parameters, instance);
|
|
@@ -163,9 +158,9 @@ const FormRendererInternal = (props) => {
|
|
|
163
158
|
async function unregisterHiddenFieldsAndSubmit() {
|
|
164
159
|
unregisterHiddenFields(entries ?? []);
|
|
165
160
|
removeUneditedProtectedValues();
|
|
166
|
-
await handleSubmit((data) => {
|
|
161
|
+
await handleSubmit(async (data) => {
|
|
167
162
|
if (onSubmit) {
|
|
168
|
-
onSubmit(action?.type === 'delete' ? {} : data);
|
|
163
|
+
await onSubmit(action?.type === 'delete' ? {} : data);
|
|
169
164
|
// clear fetched options after successful submit to allow re-evaluation with the new instance data
|
|
170
165
|
setFetchedOptions({});
|
|
171
166
|
}
|
|
@@ -209,7 +204,6 @@ const FormRendererInternal = (props) => {
|
|
|
209
204
|
fieldHeight,
|
|
210
205
|
handleChange: onChange,
|
|
211
206
|
onAutosave,
|
|
212
|
-
triggerFieldReset,
|
|
213
207
|
showSubmitError: isSubmitted,
|
|
214
208
|
associatedObject,
|
|
215
209
|
form,
|
|
@@ -34,6 +34,10 @@ export type FormRendererContainerProps = BaseProps & {
|
|
|
34
34
|
associatedObject?: {
|
|
35
35
|
instanceId: string;
|
|
36
36
|
propertyId: string;
|
|
37
|
+
objectId?: string;
|
|
38
|
+
} | {
|
|
39
|
+
instanceId: string;
|
|
40
|
+
objectId: string;
|
|
37
41
|
};
|
|
38
42
|
renderContainer?: (state: FormRendererState) => React.ReactNode;
|
|
39
43
|
renderHeader?: FormRendererProps['renderHeader'];
|