@evoke-platform/ui-components 1.0.0-dev.217 → 1.0.0-dev.218

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 (58) hide show
  1. package/dist/published/components/custom/Form/Common/Form.d.ts +38 -0
  2. package/dist/published/components/custom/Form/Common/Form.js +413 -0
  3. package/dist/published/components/custom/Form/Common/FormComponentWrapper.d.ts +26 -0
  4. package/dist/published/components/custom/Form/Common/FormComponentWrapper.js +79 -0
  5. package/dist/published/components/custom/Form/Common/index.d.ts +2 -0
  6. package/dist/published/components/custom/Form/Common/index.js +2 -0
  7. package/dist/published/components/custom/Form/FormComponents/ButtonComponent.d.ts +37 -0
  8. package/dist/published/components/custom/Form/FormComponents/ButtonComponent.js +150 -0
  9. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.d.ts +17 -0
  10. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.js +80 -0
  11. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.d.ts +23 -0
  12. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.js +154 -0
  13. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.d.ts +15 -0
  14. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.js +172 -0
  15. package/dist/published/components/custom/Form/FormComponents/FormFieldComponent.d.ts +41 -0
  16. package/dist/published/components/custom/Form/FormComponents/FormFieldComponent.js +409 -0
  17. package/dist/published/components/custom/Form/FormComponents/ImageComponent/Image.d.ts +15 -0
  18. package/dist/published/components/custom/Form/FormComponents/ImageComponent/Image.js +111 -0
  19. package/dist/published/components/custom/Form/FormComponents/ImageComponent/ImageComponent.d.ts +23 -0
  20. package/dist/published/components/custom/Form/FormComponents/ImageComponent/ImageComponent.js +112 -0
  21. package/dist/published/components/custom/Form/FormComponents/ObjectComponent/InstanceLookup.d.ts +20 -0
  22. package/dist/published/components/custom/Form/FormComponents/ObjectComponent/InstanceLookup.js +229 -0
  23. package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectComponent.d.ts +34 -0
  24. package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectComponent.js +150 -0
  25. package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectPropertyInput.d.ts +3 -0
  26. package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectPropertyInput.js +306 -0
  27. package/dist/published/components/custom/Form/FormComponents/ObjectComponent/RelatedObjectInstance.d.ts +24 -0
  28. package/dist/published/components/custom/Form/FormComponents/ObjectComponent/RelatedObjectInstance.js +126 -0
  29. package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ActionDialog.d.ts +21 -0
  30. package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ActionDialog.js +96 -0
  31. package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableField.d.ts +15 -0
  32. package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableField.js +158 -0
  33. package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableFieldInput.d.ts +39 -0
  34. package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableFieldInput.js +89 -0
  35. package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.d.ts +12 -0
  36. package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.js +369 -0
  37. package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableFieldComponent.d.ts +20 -0
  38. package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableFieldComponent.js +57 -0
  39. package/dist/published/components/custom/Form/FormComponents/UserComponent/UserComponent.d.ts +26 -0
  40. package/dist/published/components/custom/Form/FormComponents/UserComponent/UserComponent.js +99 -0
  41. package/dist/published/components/custom/Form/FormComponents/UserComponent/UserProperty.d.ts +23 -0
  42. package/dist/published/components/custom/Form/FormComponents/UserComponent/UserProperty.js +115 -0
  43. package/dist/published/components/custom/Form/FormComponents/ViewOnlyComponent.d.ts +20 -0
  44. package/dist/published/components/custom/Form/FormComponents/ViewOnlyComponent.js +83 -0
  45. package/dist/published/components/custom/Form/FormComponents/index.d.ts +8 -0
  46. package/dist/published/components/custom/Form/FormComponents/index.js +8 -0
  47. package/dist/published/components/custom/Form/index.d.ts +3 -0
  48. package/dist/published/components/custom/Form/index.js +3 -0
  49. package/dist/published/components/custom/Form/types.d.ts +109 -0
  50. package/dist/published/components/custom/Form/types.js +1 -0
  51. package/dist/published/components/custom/Form/utils.d.ts +45 -0
  52. package/dist/published/components/custom/Form/utils.js +1036 -0
  53. package/dist/published/components/custom/index.d.ts +1 -0
  54. package/dist/published/components/custom/index.js +1 -0
  55. package/dist/published/index.d.ts +1 -1
  56. package/dist/published/index.js +1 -1
  57. package/dist/published/styles/form-component.css +152 -0
  58. package/package.json +18 -5
@@ -0,0 +1,158 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { useNotification, } from '@evoke-platform/context';
11
+ import { debounce, isEmpty, isObject } from 'lodash';
12
+ import React, { useCallback, useEffect, useState } from 'react';
13
+ import { Skeleton } from '../../../../../core';
14
+ import { getMiddleObject, getPrefixedUrl, transformToWhere } from '../../../utils';
15
+ import { DropdownRepeatableFieldInput } from './DropdownRepeatableFieldInput';
16
+ export const DropdownRepeatableField = (props) => {
17
+ var _a;
18
+ const { id, property, criteria, instance, readOnly, apiServices, initialMiddleObjectInstances, middleObject, getMiddleObjectInstances, fieldHeight, } = props;
19
+ const [middleObjectInstances, setMiddleObjectInstances] = useState(initialMiddleObjectInstances);
20
+ const [endObject, setEndObject] = useState();
21
+ const [endObjectInstances, setEndObjectInstances] = useState([]);
22
+ const [viewLayout, setViewLayout] = useState();
23
+ const [loading, setLoading] = useState(false);
24
+ const [initialLoading, setInitialLoading] = useState(true);
25
+ const [selectedOptions, setSelectedOptions] = useState([]);
26
+ const [snackbarError, setSnackbarError] = useState({
27
+ showAlert: false,
28
+ isError: true,
29
+ });
30
+ const [searchValue, setSearchValue] = useState('');
31
+ const { instanceChanges } = useNotification();
32
+ const fetchMiddleObjectInstances = () => __awaiter(void 0, void 0, void 0, function* () {
33
+ const newInstances = yield getMiddleObjectInstances();
34
+ setMiddleObjectInstances(newInstances);
35
+ });
36
+ const setDropDownSelections = (instances) => {
37
+ setSelectedOptions(instances
38
+ .filter((currInstance) => property.manyToManyPropertyId in currInstance)
39
+ .map((currInstance) => {
40
+ var _a;
41
+ return ({
42
+ label: (_a = currInstance[property.manyToManyPropertyId]) === null || _a === void 0 ? void 0 : _a.name,
43
+ endObjectId: currInstance[property.manyToManyPropertyId].id,
44
+ middleObjectId: currInstance.id,
45
+ });
46
+ })
47
+ .sort((instanceA, instanceB) => instanceA.label.localeCompare(instanceB.label)));
48
+ };
49
+ useEffect(() => {
50
+ var _a;
51
+ const endObjectProperty = (_a = middleObject === null || middleObject === void 0 ? void 0 : middleObject.properties) === null || _a === void 0 ? void 0 : _a.find((currProperty) => property.manyToManyPropertyId === currProperty.id);
52
+ if (endObjectProperty && endObjectProperty.objectId) {
53
+ apiServices.get(getPrefixedUrl(`/objects/${endObjectProperty.objectId}/effective`), { params: { filter: { fields: ['id', 'name', 'properties', 'viewLayout'] } } }, (error, effectiveObject) => {
54
+ var _a;
55
+ if (error) {
56
+ console.error(error);
57
+ }
58
+ else {
59
+ // If there's no error then the effective object is defined.
60
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
61
+ const endObject = effectiveObject;
62
+ setEndObject(endObject);
63
+ if ((_a = endObject.viewLayout) === null || _a === void 0 ? void 0 : _a.dropdown) {
64
+ setViewLayout(endObject.viewLayout.dropdown);
65
+ }
66
+ }
67
+ });
68
+ }
69
+ }, [middleObject, apiServices]);
70
+ useEffect(() => {
71
+ instanceChanges === null || instanceChanges === void 0 ? void 0 : instanceChanges.subscribe(middleObject.rootObjectId, () => {
72
+ fetchMiddleObjectInstances();
73
+ });
74
+ return () => instanceChanges === null || instanceChanges === void 0 ? void 0 : instanceChanges.unsubscribe(middleObject.rootObjectId);
75
+ }, [instanceChanges, fetchMiddleObjectInstances]);
76
+ const fetchEndObjectInstances = useCallback((searchedName) => {
77
+ var _a;
78
+ if (property.objectId && property.manyToManyPropertyId) {
79
+ setLoading(true);
80
+ const endObjectProperty = (_a = middleObject.properties) === null || _a === void 0 ? void 0 : _a.find((currProperty) => property.manyToManyPropertyId === currProperty.id);
81
+ if (endObjectProperty === null || endObjectProperty === void 0 ? void 0 : endObjectProperty.objectId) {
82
+ const filter = {
83
+ limit: 100,
84
+ order: 'name ASC',
85
+ };
86
+ let searchCriteria = criteria && !isEmpty(criteria) ? transformToWhere(criteria) : {};
87
+ if (searchedName === null || searchedName === void 0 ? void 0 : searchedName.length) {
88
+ const nameCriteria = transformToWhere({
89
+ name: {
90
+ like: searchedName,
91
+ options: 'i',
92
+ },
93
+ });
94
+ searchCriteria = !isEmpty(criteria)
95
+ ? {
96
+ and: [searchCriteria, nameCriteria],
97
+ }
98
+ : nameCriteria;
99
+ }
100
+ filter.where = searchCriteria;
101
+ apiServices.get(getPrefixedUrl(`/objects/${endObjectProperty.objectId}/instances`), { params: { filter: JSON.stringify(filter) } }, (error, instances) => {
102
+ if (!error && instances) {
103
+ setEndObjectInstances(instances);
104
+ }
105
+ setInitialLoading(false);
106
+ setLoading(false);
107
+ });
108
+ }
109
+ }
110
+ }, [property.objectId, property.manyToManyPropertyId, apiServices, middleObject]);
111
+ const debouncedEndObjectSearch = useCallback(debounce(fetchEndObjectInstances, 500), [fetchEndObjectInstances]);
112
+ useEffect(() => {
113
+ debouncedEndObjectSearch(searchValue);
114
+ return () => debouncedEndObjectSearch.cancel();
115
+ }, [searchValue, debouncedEndObjectSearch]);
116
+ useEffect(() => {
117
+ fetchEndObjectInstances();
118
+ }, [criteria, middleObject, property, fetchEndObjectInstances]);
119
+ const saveMiddleInstance = (endObjectId, endObjectName) => {
120
+ if (property.objectId) {
121
+ const middleObject = getMiddleObject(instance, property, endObjectId, endObjectName);
122
+ apiServices.post(getPrefixedUrl(`/objects/${property.objectId}/instances/actions`), { actionId: `_create`, input: middleObject }, (error, newInstance) => {
123
+ if (!error && newInstance && isObject(newInstance)) {
124
+ setMiddleObjectInstances((prevObjectInstances) => [
125
+ ...prevObjectInstances,
126
+ newInstance,
127
+ ]);
128
+ }
129
+ else {
130
+ if (error) {
131
+ setSnackbarError({
132
+ showAlert: true,
133
+ message: 'An error occured while adding an instance',
134
+ isError: true,
135
+ });
136
+ setDropDownSelections(middleObjectInstances);
137
+ }
138
+ }
139
+ });
140
+ }
141
+ };
142
+ const removeMiddleInstance = (instanceId) => {
143
+ apiServices.post(getPrefixedUrl(`/objects/${property.objectId}/instances/${instanceId}/actions`), { actionId: '_delete' }, (error, res) => {
144
+ if (!error) {
145
+ setMiddleObjectInstances((prevInstances) => prevInstances.filter((curr) => curr.id !== instanceId));
146
+ }
147
+ else {
148
+ setDropDownSelections(middleObjectInstances);
149
+ setSnackbarError({
150
+ showAlert: true,
151
+ message: 'An error occurred while deleting the instance',
152
+ isError: true,
153
+ });
154
+ }
155
+ });
156
+ };
157
+ return initialLoading ? (React.createElement(Skeleton, null)) : (React.createElement(React.Fragment, null, middleObjectInstances && endObject && (React.createElement(DropdownRepeatableFieldInput, { id: id, property: property, readOnly: readOnly || !((_a = middleObject.actions) === null || _a === void 0 ? void 0 : _a.some((action) => action.id === '_create')), viewLayout: viewLayout, middleObjectInstances: middleObjectInstances, endObjectInstances: endObjectInstances !== null && endObjectInstances !== void 0 ? endObjectInstances : [], endObject: endObject, searchValue: searchValue, loading: loading, handleSaveMiddleInstance: saveMiddleInstance, handleRemoveMiddleInstance: removeMiddleInstance, setSearchValue: setSearchValue, setSnackbarError: setSnackbarError, snackbarError: snackbarError, selectedOptions: selectedOptions, setSelectedOptions: setSelectedOptions, setDropdownSelections: setDropDownSelections, fieldHeight: fieldHeight }))));
158
+ };
@@ -0,0 +1,39 @@
1
+ /// <reference types="react" />
2
+ import { DropdownViewLayout, Obj, ObjectInstance, Property } from '@evoke-platform/context';
3
+ import { AutocompleteOption } from '../../../../../core';
4
+ declare type DropdownRepeatableFieldInputProps = {
5
+ id: string;
6
+ property: Property;
7
+ readOnly: boolean;
8
+ viewLayout?: DropdownViewLayout;
9
+ middleObjectInstances: ObjectInstance[];
10
+ endObjectInstances: ObjectInstance[];
11
+ endObject: Obj;
12
+ searchValue: string;
13
+ loading: boolean;
14
+ fieldHeight?: 'small' | 'medium';
15
+ handleSaveMiddleInstance: (endObjectId: string, endObjectName: string) => void;
16
+ handleRemoveMiddleInstance: (instanceId: string) => void;
17
+ setSearchValue: (value: string) => void;
18
+ setSelectedOptions: (selectedOptions: DropdownRepeatableFieldInputOption[]) => void;
19
+ selectedOptions: DropdownRepeatableFieldInputOption[];
20
+ setSnackbarError: (snackbarError: {
21
+ showAlert: boolean;
22
+ message?: string;
23
+ isError: boolean;
24
+ }) => void;
25
+ snackbarError: {
26
+ showAlert: boolean;
27
+ message?: string;
28
+ isError: boolean;
29
+ };
30
+ setDropdownSelections?: (middleObjectInstances: ObjectInstance[]) => void;
31
+ };
32
+ export declare type DropdownRepeatableFieldInputOption = AutocompleteOption & {
33
+ endObjectId: string;
34
+ middleObjectId?: string;
35
+ subLabel?: string;
36
+ hidden?: boolean;
37
+ };
38
+ export declare const DropdownRepeatableFieldInput: (props: DropdownRepeatableFieldInputProps) => JSX.Element;
39
+ export {};
@@ -0,0 +1,89 @@
1
+ import Handlebars from 'handlebars';
2
+ import { difference, isEmpty, isObject } from 'lodash';
3
+ import React, { useEffect, useState } from 'react';
4
+ import { FormField } from '../../../..';
5
+ import { Snackbar, TextField, Typography } from '../../../../../core';
6
+ import { normalizeDates } from '../../../utils';
7
+ const isDropdownRepeatableFieldInputOption = (option) => isObject(option) && 'label' in option && 'endObjectId' in option;
8
+ export const DropdownRepeatableFieldInput = (props) => {
9
+ const { id, property, readOnly, viewLayout, middleObjectInstances, endObjectInstances, endObject, searchValue, loading, handleSaveMiddleInstance, handleRemoveMiddleInstance, setSearchValue, selectedOptions, setSnackbarError, snackbarError, setDropdownSelections, fieldHeight, } = props;
10
+ const [selectOptions, setSelectOptions] = useState([]);
11
+ useEffect(() => {
12
+ setDropdownSelections && setDropdownSelections(middleObjectInstances);
13
+ }, [middleObjectInstances]);
14
+ useEffect(() => {
15
+ var _a;
16
+ const manyToManyPropertyId = property.manyToManyPropertyId;
17
+ if (manyToManyPropertyId) {
18
+ const enums = endObjectInstances
19
+ .map((endObjectInstance) => {
20
+ const normalizedInstance = Object.assign({}, endObjectInstance);
21
+ normalizeDates([normalizedInstance], endObject);
22
+ return normalizedInstance;
23
+ })
24
+ .map((endObjectInstance) => ({
25
+ label: endObjectInstance.name,
26
+ subLabel: (viewLayout === null || viewLayout === void 0 ? void 0 : viewLayout.secondaryTextExpression)
27
+ ? compileExpression(endObjectInstance, viewLayout.secondaryTextExpression)
28
+ : undefined,
29
+ endObjectId: endObjectInstance.id,
30
+ value: undefined,
31
+ }));
32
+ setSelectOptions((_a = [
33
+ ...enums,
34
+ ...selectedOptions
35
+ .filter((selectedOption) => !enums.find((availableOption) => availableOption.endObjectId === selectedOption.endObjectId))
36
+ .map((option) => (Object.assign(Object.assign({}, option), { hidden: true }))),
37
+ ]) !== null && _a !== void 0 ? _a : []);
38
+ }
39
+ }, [endObjectInstances, viewLayout]);
40
+ const handleChange = (key, newSelectedOptions) => {
41
+ // Delete middle objects that have been removed
42
+ // Add middle objects that have been added
43
+ // You can only really add or remove one value at a time
44
+ const addedValues = difference(newSelectedOptions, selectedOptions);
45
+ if (!isEmpty(addedValues)) {
46
+ addedValues.forEach((newValue) => {
47
+ if (isDropdownRepeatableFieldInputOption(newValue) &&
48
+ property.relatedPropertyId &&
49
+ property.manyToManyPropertyId) {
50
+ handleSaveMiddleInstance(newValue.endObjectId, newValue.label);
51
+ }
52
+ });
53
+ }
54
+ const removedValues = difference(selectedOptions, newSelectedOptions);
55
+ if (!isEmpty(removedValues)) {
56
+ removedValues.forEach((removedValue) => {
57
+ if (isObject(removedValue) && removedValue.middleObjectId) {
58
+ handleRemoveMiddleInstance(removedValue.middleObjectId);
59
+ }
60
+ });
61
+ }
62
+ };
63
+ const compileExpression = (instance, expression) => {
64
+ const template = Handlebars.compile(expression);
65
+ return template(instance);
66
+ };
67
+ return (React.createElement(React.Fragment, null, !readOnly ? (property && (React.createElement(React.Fragment, null,
68
+ React.createElement(FormField, { id: id, property: Object.assign(Object.assign({}, property), { type: 'array',
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
+ enum: selectOptions }), onChange: handleChange, defaultValue: selectedOptions, isOptionEqualToValue: (option, value) => isDropdownRepeatableFieldInputOption(value) &&
71
+ isDropdownRepeatableFieldInputOption(option) &&
72
+ option.endObjectId === value.endObjectId, size: fieldHeight !== null && fieldHeight !== void 0 ? fieldHeight : 'medium', renderOption: (props, option) => {
73
+ return isObject(props) && isDropdownRepeatableFieldInputOption(option) ? (React.createElement("li", Object.assign({}, props, { key: option.endObjectId }),
74
+ React.createElement(Typography, null,
75
+ option.label,
76
+ React.createElement("br", null),
77
+ React.createElement(Typography, { variant: "caption", color: "#586069" }, option.subLabel ? option.subLabel : '')))) : null;
78
+ }, disableCloseOnSelect: true, additionalProps: {
79
+ filterOptions: (options) => {
80
+ return options.filter((option) => !option.hidden);
81
+ },
82
+ inputValue: searchValue,
83
+ renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { onChange: (event) => {
84
+ setSearchValue(event.target.value);
85
+ } }))),
86
+ loading: loading,
87
+ } }),
88
+ React.createElement(Snackbar, { open: snackbarError.showAlert, handleClose: () => setSnackbarError({ isError: snackbarError.isError, showAlert: false }), message: snackbarError.message, error: snackbarError.isError })))) : (React.createElement(Typography, null, selectedOptions && selectedOptions.map((option) => option.label).join(', ')))));
89
+ };
@@ -0,0 +1,12 @@
1
+ /// <reference types="react" />
2
+ import { ApiServices, ObjectInstance, Property, UserAccount } from '@evoke-platform/context';
3
+ export declare type ObjectPropertyInputProps = {
4
+ property: Property;
5
+ instance: ObjectInstance;
6
+ canUpdateProperty: boolean;
7
+ apiServices: ApiServices;
8
+ queryAddresses?: unknown;
9
+ user?: UserAccount;
10
+ };
11
+ declare const RepeatableField: (props: ObjectPropertyInputProps) => JSX.Element;
12
+ export default RepeatableField;