@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.
Files changed (46) hide show
  1. package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.d.ts +8 -4
  2. package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.js +242 -142
  3. package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.test.js +189 -67
  4. package/dist/published/components/custom/CriteriaBuilder/PropertyTree.d.ts +6 -6
  5. package/dist/published/components/custom/CriteriaBuilder/PropertyTree.js +12 -25
  6. package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.d.ts +4 -5
  7. package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.js +34 -22
  8. package/dist/published/components/custom/CriteriaBuilder/types.d.ts +2 -11
  9. package/dist/published/components/custom/CriteriaBuilder/utils.d.ts +6 -34
  10. package/dist/published/components/custom/CriteriaBuilder/utils.js +18 -89
  11. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.js +1 -1
  12. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.js +6 -3
  13. package/dist/published/components/custom/Form/utils.d.ts +1 -0
  14. package/dist/published/components/custom/FormV2/FormRenderer.d.ts +2 -1
  15. package/dist/published/components/custom/FormV2/FormRenderer.js +2 -8
  16. package/dist/published/components/custom/FormV2/FormRendererContainer.d.ts +4 -0
  17. package/dist/published/components/custom/FormV2/FormRendererContainer.js +229 -126
  18. package/dist/published/components/custom/FormV2/components/DefaultValues.d.ts +1 -1
  19. package/dist/published/components/custom/FormV2/components/DefaultValues.js +60 -89
  20. package/dist/published/components/custom/FormV2/components/FormContext.d.ts +1 -1
  21. package/dist/published/components/custom/FormV2/components/FormContext.js +0 -1
  22. package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/ActionDialog.d.ts +1 -0
  23. package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/RepeatableField.js +43 -16
  24. package/dist/published/components/custom/FormV2/components/FormFieldTypes/Criteria.d.ts +2 -2
  25. package/dist/published/components/custom/FormV2/components/FormFieldTypes/Criteria.js +3 -2
  26. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.d.ts +3 -2
  27. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.js +44 -11
  28. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.d.ts +4 -3
  29. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.js +41 -29
  30. package/dist/published/components/custom/FormV2/components/FormFieldTypes/FileContent.d.ts +12 -0
  31. package/dist/published/components/custom/FormV2/components/FormFieldTypes/FileContent.js +197 -0
  32. package/dist/published/components/custom/FormV2/components/FormFieldTypes/Image.js +2 -4
  33. package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/InstanceLookup.js +14 -0
  34. package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/RelatedObjectInstance.js +6 -2
  35. package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.js +16 -13
  36. package/dist/published/components/custom/FormV2/components/types.d.ts +6 -1
  37. package/dist/published/components/custom/FormV2/components/utils.d.ts +10 -8
  38. package/dist/published/components/custom/FormV2/components/utils.js +168 -82
  39. package/dist/published/components/custom/ViewDetailsV2/InstanceEntryRenderer.js +6 -1
  40. package/dist/published/components/custom/index.d.ts +1 -0
  41. package/dist/published/index.d.ts +1 -1
  42. package/dist/published/stories/CriteriaBuilder.stories.js +70 -22
  43. package/dist/published/stories/FormRenderer.stories.d.ts +6 -3
  44. package/dist/published/stories/FormRendererContainer.stories.d.ts +20 -0
  45. package/dist/published/theme/hooks.d.ts +3 -3
  46. 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 {TreeItem[]} tree - The tree structure to update.
6
+ * @param {TreeViewProperty[]} tree - The tree structure to update.
7
7
  * @param {string} nodeId - The ID of the node to update.
8
- * @param {(node: TreeItem) => TreeItem} updater - The function to apply to the node.
9
- * @returns {TreeItem[]} - The updated tree structure.
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 updateTreeNode = (tree, nodeId, updater) => {
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: updateTreeNode(node.children, nodeId, updater) };
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
- * Fetches the display name path for a given property ID within an object hierarchy.
26
- *
27
- * @param {string} propertyId - The property ID to find the display name for.
28
- * @param {Obj} rootObject - The root object to start the search from.
29
- * @param {FetchObjectFunction} fetchObject - Function to fetch an object by its ID.
30
- * @returns {Promise<string>} - A promise that resolves to the display name path.
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
- const found = node.children && findTreeItemById(node.children, nodeId);
188
- if (found)
189
- return found;
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(`/objects/sys__file/instances/${instance.id}/checkAccess?action=update`)
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)
@@ -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 permissions on the sys__file object
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/${instance.id}/checkAccess?action=view`)
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.get(endpoint).then((accessCheck) => setHasViewPermission(accessCheck.result));
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'];