@guillotinaweb/react-gmi 0.29.2 → 0.30.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 (70) hide show
  1. package/README.md +2 -1
  2. package/dist/actions/copy_item.d.ts +2 -2
  3. package/dist/actions/move_item.d.ts +2 -2
  4. package/dist/actions/remove_item.d.ts +2 -2
  5. package/dist/components/behaviors/iattachment.d.ts +4 -2
  6. package/dist/components/behaviors/imultiimageorderedattachment.d.ts +3 -1
  7. package/dist/components/behaviors/iworkflow.d.ts +1 -1
  8. package/dist/components/context_toolbar.d.ts +1 -1
  9. package/dist/components/fields/editComponent.d.ts +5 -4
  10. package/dist/components/fields/editableField.d.ts +4 -2
  11. package/dist/components/fields/renderField.d.ts +8 -5
  12. package/dist/components/flash.d.ts +1 -1
  13. package/dist/components/input/email.d.ts +1 -1
  14. package/dist/components/input/form_builder.d.ts +2 -2
  15. package/dist/components/input/input.d.ts +1 -1
  16. package/dist/components/input/search_input.d.ts +1 -1
  17. package/dist/components/input/search_input_list.d.ts +2 -2
  18. package/dist/components/input/select_vocabulary.d.ts +2 -2
  19. package/dist/components/input/upload.d.ts +1 -2
  20. package/dist/components/pagination.d.ts +1 -1
  21. package/dist/components/panel/permissions.d.ts +1 -1
  22. package/dist/components/panel/permissions_prinperm.d.ts +2 -2
  23. package/dist/components/panel/permissions_prinrole.d.ts +1 -1
  24. package/dist/components/panel/permissions_roleperm.d.ts +1 -1
  25. package/dist/components/path.d.ts +1 -1
  26. package/dist/components/properties_view.d.ts +2 -2
  27. package/dist/components/search_labels.d.ts +1 -1
  28. package/dist/components/search_options_labels.d.ts +1 -1
  29. package/dist/components/search_vocabulary_labels.d.ts +2 -2
  30. package/dist/components/selected_items_actions.d.ts +14 -0
  31. package/dist/components/tabs.d.ts +4 -2
  32. package/dist/components/widgets/tags.d.ts +4 -1
  33. package/dist/contexts/index.d.ts +21 -19
  34. package/dist/forms/required_fields.d.ts +2 -3
  35. package/dist/forms/users.d.ts +1 -1
  36. package/dist/hooks/useClickAway.d.ts +2 -1
  37. package/dist/hooks/useConfig.d.ts +4 -2
  38. package/dist/hooks/useCrudContext.d.ts +11 -10
  39. package/dist/hooks/useInput.d.ts +4 -3
  40. package/dist/hooks/useRegistry.d.ts +29 -29
  41. package/dist/hooks/useSetState.d.ts +6 -1
  42. package/dist/hooks/useVocabulary.d.ts +1 -1
  43. package/dist/lib/auth.d.ts +14 -19
  44. package/dist/lib/client.d.ts +49 -36
  45. package/dist/lib/helpers.d.ts +10 -18
  46. package/dist/lib/processResponse.d.ts +9 -0
  47. package/dist/lib/rest.d.ts +9 -16
  48. package/dist/lib/utils.d.ts +3 -2
  49. package/dist/lib/validators.d.ts +1 -1
  50. package/dist/locales/generic_messages.d.ts +248 -370
  51. package/dist/models/index.d.ts +5 -5
  52. package/dist/models/sharing.d.ts +5 -5
  53. package/dist/react-gmi.esm.js +1182 -905
  54. package/dist/react-gmi.esm.js.map +1 -1
  55. package/dist/react-gmi.js +1181 -905
  56. package/dist/react-gmi.js.map +1 -1
  57. package/dist/react-gmi.modern.js +1155 -852
  58. package/dist/react-gmi.modern.js.map +1 -1
  59. package/dist/react-gmi.umd.js +1181 -905
  60. package/dist/react-gmi.umd.js.map +1 -1
  61. package/dist/reducers/guillotina.d.ts +22 -8
  62. package/dist/types/global.d.ts +9 -0
  63. package/dist/types/guillotina.d.ts +192 -44
  64. package/dist/views/folder.d.ts +1 -1
  65. package/dist/views/groups.d.ts +1 -1
  66. package/dist/views/item.d.ts +1 -1
  67. package/dist/views/users.d.ts +1 -1
  68. package/package.json +3 -2
  69. package/dist/lib/search.test.d.ts +0 -1
  70. package/dist/setupTests.d.ts +0 -1
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import React, { createContext, useContext, useState, useCallback, useRef, useEffect, forwardRef, Children, isValidElement, cloneElement, Fragment as Fragment$1, Component, useReducer } from 'react';
2
+ import React, { createContext, useContext, useState, useCallback, useRef, useEffect, forwardRef, Children, isValidElement, cloneElement, Fragment as Fragment$1, useMemo, Component, useReducer } from 'react';
3
3
  import usePortal from 'react-useportal';
4
4
  import { defineMessages, useIntl, injectIntl, IntlProvider } from 'react-intl';
5
5
  import PropTypes from 'prop-types';
@@ -40,6 +40,97 @@ function _objectWithoutPropertiesLoose(source, excluded) {
40
40
  return target;
41
41
  }
42
42
 
43
+ const initialState = {
44
+ path: '',
45
+ loading: false,
46
+ context: undefined,
47
+ flash: {
48
+ message: undefined,
49
+ type: undefined
50
+ },
51
+ action: {
52
+ action: undefined,
53
+ params: undefined
54
+ },
55
+ permissions: [],
56
+ errorStatus: undefined,
57
+ registry: {},
58
+ refresh: undefined
59
+ };
60
+ var GuillotinaReducerActionTypes;
61
+
62
+ (function (GuillotinaReducerActionTypes) {
63
+ GuillotinaReducerActionTypes["SET_PATH"] = "SET_PATH";
64
+ GuillotinaReducerActionTypes["SET_CONTEXT"] = "SET_CONTEXT";
65
+ GuillotinaReducerActionTypes["SET_ERROR"] = "SET_ERROR";
66
+ GuillotinaReducerActionTypes["SET_FLASH"] = "SET_FLASH";
67
+ GuillotinaReducerActionTypes["CLEAR_FLASH"] = "CLEAR_FLASH";
68
+ GuillotinaReducerActionTypes["SET_ACTION"] = "SET_ACTION";
69
+ GuillotinaReducerActionTypes["CLEAR_ACTION"] = "CLEAR_ACTION";
70
+ GuillotinaReducerActionTypes["REFRESH"] = "REFRESH";
71
+ GuillotinaReducerActionTypes["APPLY"] = "APPLY";
72
+ })(GuillotinaReducerActionTypes || (GuillotinaReducerActionTypes = {}));
73
+
74
+ function guillotinaReducer(state, action) {
75
+ switch (action.type) {
76
+ case GuillotinaReducerActionTypes.SET_PATH:
77
+ return _extends({}, state, {
78
+ path: action.payload.path,
79
+ loading: true
80
+ });
81
+
82
+ case GuillotinaReducerActionTypes.SET_CONTEXT:
83
+ return _extends({}, state, action.payload, {
84
+ errorStatus: undefined,
85
+ loading: false
86
+ });
87
+
88
+ case GuillotinaReducerActionTypes.SET_ERROR:
89
+ return _extends({}, state, {
90
+ errorStatus: action.payload.errorStatus,
91
+ loading: false
92
+ });
93
+
94
+ case GuillotinaReducerActionTypes.SET_FLASH:
95
+ return _extends({}, state, action.payload);
96
+
97
+ case GuillotinaReducerActionTypes.CLEAR_FLASH:
98
+ return _extends({}, state, {
99
+ flash: {
100
+ message: undefined,
101
+ type: undefined
102
+ }
103
+ });
104
+
105
+ case GuillotinaReducerActionTypes.SET_ACTION:
106
+ return _extends({}, state, {
107
+ action: action.payload
108
+ });
109
+
110
+ case GuillotinaReducerActionTypes.CLEAR_ACTION:
111
+ return _extends({}, state, {
112
+ action: {
113
+ action: undefined,
114
+ params: undefined
115
+ }
116
+ });
117
+
118
+ case GuillotinaReducerActionTypes.REFRESH:
119
+ return _extends({}, state, {
120
+ refresh: Date.now(),
121
+ loading: !action.payload.transparent
122
+ });
123
+
124
+ case GuillotinaReducerActionTypes.APPLY:
125
+ return _extends({}, state, {
126
+ context: _extends({}, state.context, action.payload.context)
127
+ });
128
+
129
+ default:
130
+ return state;
131
+ }
132
+ }
133
+
43
134
  const AuthContext = createContext({});
44
135
  const ClientContext = createContext(null);
45
136
  class Traversal {
@@ -68,7 +159,7 @@ class Traversal {
68
159
  transparent = false
69
160
  } = {}) {
70
161
  this.dispatch({
71
- type: 'REFRESH',
162
+ type: GuillotinaReducerActionTypes.REFRESH,
72
163
  payload: {
73
164
  transparent
74
165
  }
@@ -84,6 +175,10 @@ class Traversal {
84
175
  }
85
176
 
86
177
  get context() {
178
+ if (this.state.context === undefined) {
179
+ throw new Error('Context is not loaded');
180
+ }
181
+
87
182
  return this.state.context;
88
183
  }
89
184
 
@@ -92,15 +187,18 @@ class Traversal {
92
187
  }
93
188
 
94
189
  apply(data) {
190
+ // apply a optimistic update to context
95
191
  this.dispatch({
96
- type: 'APPLY',
97
- payload: data
192
+ type: GuillotinaReducerActionTypes.APPLY,
193
+ payload: {
194
+ context: data
195
+ }
98
196
  });
99
197
  }
100
198
 
101
199
  flash(message, type) {
102
200
  this.dispatch({
103
- type: 'SET_FLASH',
201
+ type: GuillotinaReducerActionTypes.SET_FLASH,
104
202
  payload: {
105
203
  flash: {
106
204
  message,
@@ -117,13 +215,14 @@ class Traversal {
117
215
 
118
216
  clearFlash() {
119
217
  this.dispatch({
120
- type: 'CLEAR_FLASH'
218
+ type: GuillotinaReducerActionTypes.CLEAR_FLASH,
219
+ payload: {}
121
220
  });
122
221
  }
123
222
 
124
223
  doAction(action, params = {}) {
125
224
  this.dispatch({
126
- type: 'SET_ACTION',
225
+ type: GuillotinaReducerActionTypes.SET_ACTION,
127
226
  payload: {
128
227
  action,
129
228
  params
@@ -133,7 +232,8 @@ class Traversal {
133
232
 
134
233
  cancelAction() {
135
234
  this.dispatch({
136
- type: 'CLEAR_ACTION'
235
+ type: GuillotinaReducerActionTypes.CLEAR_ACTION,
236
+ payload: {}
137
237
  });
138
238
  }
139
239
 
@@ -169,7 +269,13 @@ function TraversalProvider(_ref2) {
169
269
  });
170
270
  }
171
271
  function useTraversal() {
172
- return useContext(TraversalContext);
272
+ const traversal = useContext(TraversalContext);
273
+
274
+ if (!traversal) {
275
+ throw new Error('useTraversal must be used within a TraversalProvider');
276
+ }
277
+
278
+ return traversal;
173
279
  }
174
280
  function ClientProvider({
175
281
  children,
@@ -181,7 +287,13 @@ function ClientProvider({
181
287
  });
182
288
  }
183
289
  function useGuillotinaClient() {
184
- return useContext(ClientContext);
290
+ const client = useContext(ClientContext);
291
+
292
+ if (!client) {
293
+ throw new Error('useGuillotinaClient must be used within a ClientProvider');
294
+ }
295
+
296
+ return client;
185
297
  }
186
298
 
187
299
  const genericMessages = defineMessages({
@@ -682,8 +794,10 @@ function base64ToArrayBuffer(base64) {
682
794
  return bytes;
683
795
  }
684
796
  function stringToSlug(str) {
685
- str = str.replace(/^\s+|\s+$/g, '');
686
- str = str.toLowerCase();
797
+ str = str.replace(/^\s+|\s+$/g, ''); // trim
798
+
799
+ str = str.toLowerCase(); // remove accents, swap ñ for n, etc
800
+
687
801
  const from = 'àáäâèéëêìíïîòóöôùúüûñç·/_,:;';
688
802
  const to = 'aaaaeeeeiiiioooouuuunc------';
689
803
 
@@ -691,13 +805,16 @@ function stringToSlug(str) {
691
805
  str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
692
806
  }
693
807
 
694
- str = str.replace(/[^a-z0-9 -]/g, '').replace(/\s+/g, '-').replace(/-+/g, '-');
808
+ str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
809
+ .replace(/\s+/g, '-') // collapse whitespace and replace by -
810
+ .replace(/-+/g, '-'); // collapse dashes
811
+
695
812
  return str;
696
813
  }
697
814
  function sleep(ms) {
698
815
  return new Promise(resolve => {
699
816
  setTimeout(function () {
700
- resolve(null);
817
+ resolve();
701
818
  }, ms);
702
819
  });
703
820
  }
@@ -728,7 +845,7 @@ const Button = ({
728
845
  disabled: _disabled = false,
729
846
  dataTest
730
847
  }) => {
731
- let css = [].concat('button', ..._className.split(' '));
848
+ let css = [..._className.split(' '), 'button'];
732
849
  if (_loading) css = css.concat('is-loading');
733
850
  return jsx("p", {
734
851
  className: "control",
@@ -743,6 +860,41 @@ const Button = ({
743
860
  });
744
861
  };
745
862
 
863
+ const formatDate = str => {
864
+ const d = new Date(str);
865
+ const minutes = d.getMinutes() < 10 ? `0${d.getMinutes()}` : d.getMinutes();
866
+ return `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()} ${d.getHours()}:${minutes}`;
867
+ };
868
+ const get = (obj, path, defValue) => {
869
+ var _pathArray$reduce;
870
+
871
+ // If path is not defined or it has false value
872
+ if (!path) return defValue; // Check if path is string or array. Regex : ensure that we do not have '.' and brackets.
873
+ // Regex explained: https://regexr.com/58j0k
874
+
875
+ const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g); // Find value if exist return otherwise return undefined value;
876
+
877
+ if (pathArray === null) return defValue;
878
+ return (_pathArray$reduce = pathArray.reduce((prevObj, key) => prevObj && prevObj[key], obj)) != null ? _pathArray$reduce : defValue;
879
+ };
880
+ function getNewId(id = '') {
881
+ const suffix = '-copy-';
882
+ const rgx = new RegExp(`($|${suffix}\\d*)`);
883
+ return stringToSlug(id).replace(rgx, r => {
884
+ const num = parseInt(r.replace(suffix, '') || '0');
885
+ return `${suffix}${num + 1}`;
886
+ });
887
+ }
888
+ function debounce(callback, wait) {
889
+ let timer;
890
+ return (...args) => {
891
+ clearTimeout(timer);
892
+ return new Promise(resolve => {
893
+ timer = setTimeout(() => resolve(callback(...args)), wait);
894
+ });
895
+ };
896
+ }
897
+
746
898
  function Modal(props) {
747
899
  const {
748
900
  isActive,
@@ -814,7 +966,8 @@ function Confirm({
814
966
  })]
815
967
  })]
816
968
  });
817
- }
969
+ } // @todo Improve it... Replacing the inputText to a tree
970
+
818
971
  function PathTree({
819
972
  title,
820
973
  defaultPath,
@@ -831,7 +984,7 @@ function PathTree({
831
984
  }), jsxs("form", {
832
985
  onSubmit: e => {
833
986
  e.preventDefault();
834
- onConfirm(e.target[0].value, e.target);
987
+ onConfirm(get(e, 'target.0.value', ''), e.target);
835
988
  },
836
989
  children: [jsx("small", {
837
990
  style: {
@@ -863,22 +1016,6 @@ function PathTree({
863
1016
  });
864
1017
  }
865
1018
 
866
- function useSetState(initialState) {
867
- const [state, set] = useState(initialState);
868
- const setState = useCallback(patch => {
869
- set(prevState => Object.assign({}, prevState, patch instanceof Function ? patch(prevState) : patch));
870
- }, [set]);
871
- return [state, setState];
872
- }
873
-
874
- const initial = {
875
- loading: undefined,
876
- isError: false,
877
- errorMessage: undefined,
878
- result: undefined,
879
- response: undefined
880
- };
881
-
882
1019
  const getErrorMessage = (dataError, defaultValue) => {
883
1020
  if (dataError && dataError.details) {
884
1021
  return dataError.details;
@@ -889,7 +1026,7 @@ const getErrorMessage = (dataError, defaultValue) => {
889
1026
  return defaultValue;
890
1027
  };
891
1028
 
892
- const processResponse = async (res, ready_body = true) => {
1029
+ async function processResponse(res, ready_body = true) {
893
1030
  if (res.status < 400) return {
894
1031
  isError: false,
895
1032
  loading: false,
@@ -898,98 +1035,139 @@ const processResponse = async (res, ready_body = true) => {
898
1035
  };else return {
899
1036
  isError: true,
900
1037
  loading: false,
901
- errorMessage: getErrorMessage(await res.json(), res.status),
1038
+ errorMessage: getErrorMessage(await res.json(), res.status).toString(),
902
1039
  response: res
903
1040
  };
904
- };
1041
+ }
905
1042
 
906
- const patch = (setState, Ctx) => async (data, endpoint = undefined, body = false) => {
907
- setState({
908
- loading: true
909
- });
910
- let newState = {};
1043
+ /**
1044
+ * Do setState like react class component.
1045
+ */
911
1046
 
912
- try {
913
- const path = endpoint ? `${Ctx.path}${endpoint}` : Ctx.path;
914
- const res = await Ctx.client.patch(path, data);
915
- newState = await processResponse(res, body);
916
- } catch (e) {
917
- console.error('Error', e);
918
- newState = {
919
- isError: true,
920
- errorMessage: 'unhandled exception'
921
- };
922
- }
1047
+ function useSetState(initialState) {
1048
+ const [state, setState] = useState(initialState); // Function which accepts a partial state to merge
1049
+
1050
+ const setCustomState = useCallback(newPartialState => {
1051
+ try {
1052
+ setState(prevState => {
1053
+ return _extends({}, prevState, newPartialState);
1054
+ });
1055
+ } catch (error) {
1056
+ // eslint-disable-next-line no-console
1057
+ console.error(error);
1058
+ }
1059
+ }, []); // Return
1060
+
1061
+ return [state, setCustomState];
1062
+ } // **** Export Default **** //
923
1063
 
924
- setState(newState);
925
- return newState;
1064
+ const initial = {
1065
+ loading: undefined,
1066
+ isError: false,
1067
+ errorMessage: undefined,
1068
+ result: undefined,
1069
+ response: undefined
926
1070
  };
927
1071
 
928
- const del = (setState, Ctx) => async (data = {}, endpoint = undefined, body = false) => {
929
- setState({
930
- loading: true
931
- });
932
- let newState = {};
1072
+ function patch(setState, Ctx) {
1073
+ return async (data = {}, endpoint, body = false) => {
1074
+ setState({
1075
+ loading: true
1076
+ });
1077
+ let newState = {};
933
1078
 
934
- try {
935
- const path = endpoint ? `${Ctx.path}${endpoint}` : Ctx.path;
936
- const res = await Ctx.client.delete(path, data);
937
- newState = await processResponse(res, body);
938
- } catch (e) {
939
- console.error('Error', e);
940
- newState = {
941
- isError: true,
942
- errorMessage: 'unhandled exception'
943
- };
944
- }
1079
+ try {
1080
+ const path = endpoint ? `${Ctx.path}${endpoint}` : Ctx.path;
1081
+ const res = await Ctx.client.patch(path, data);
1082
+ newState = await processResponse(res, body);
1083
+ } catch (e) {
1084
+ console.error('Error', e);
1085
+ newState = {
1086
+ isError: true,
1087
+ errorMessage: 'unhandled exception'
1088
+ };
1089
+ }
945
1090
 
946
- setState(newState);
947
- return newState;
948
- };
1091
+ setState(newState);
1092
+ return newState;
1093
+ };
1094
+ }
949
1095
 
950
- const post = (setState, Ctx) => async (data, endpoint = undefined, body = true) => {
951
- setState({
952
- loading: true
953
- });
954
- let newState = {};
1096
+ function del(setState, Ctx) {
1097
+ return async (data = {}, endpoint, body = false) => {
1098
+ setState({
1099
+ loading: true
1100
+ });
1101
+ let newState = {};
955
1102
 
956
- try {
957
- const path = endpoint ? `${Ctx.path}${endpoint}` : Ctx.path;
958
- const res = await Ctx.client.post(path, data);
959
- newState = await processResponse(res, body);
960
- } catch (e) {
961
- console.error('Error', e);
962
- newState = {
963
- isError: true,
964
- errorMessage: 'unhandled exception'
965
- };
966
- }
1103
+ try {
1104
+ const path = endpoint ? `${Ctx.path}${endpoint}` : Ctx.path;
1105
+ const res = await Ctx.client.delete(path, data);
1106
+ newState = await processResponse(res, body);
1107
+ } catch (e) {
1108
+ console.error('Error', e);
1109
+ newState = {
1110
+ isError: true,
1111
+ errorMessage: 'unhandled exception'
1112
+ };
1113
+ }
967
1114
 
968
- setState(newState);
969
- return newState;
970
- };
1115
+ setState(newState);
1116
+ return newState;
1117
+ };
1118
+ }
971
1119
 
972
- const get = (setState, Ctx) => async (endpoint = undefined) => {
973
- setState({
974
- loading: true
975
- });
976
- let newState = {};
1120
+ function post(setState, Ctx) {
1121
+ return async (data = {}, endpoint, body = true) => {
1122
+ setState({
1123
+ loading: true
1124
+ });
1125
+ let newState = {};
977
1126
 
978
- try {
979
- const path = endpoint ? `${Ctx.path}${endpoint}` : Ctx.path;
980
- const res = await Ctx.client.get(path);
981
- newState = await processResponse(res, true);
982
- } catch (e) {
983
- console.error('Error', e);
984
- newState = {
985
- isError: true,
986
- errorMessage: 'unhandled exception'
987
- };
988
- }
1127
+ try {
1128
+ const path = endpoint ? `${Ctx.path}${endpoint}` : Ctx.path;
1129
+ const res = await Ctx.client.post(path, data);
1130
+ newState = await processResponse(res, body);
1131
+ } catch (e) {
1132
+ console.error('Error', e);
1133
+ newState = {
1134
+ isError: true,
1135
+ errorMessage: 'unhandled exception'
1136
+ };
1137
+ }
1138
+
1139
+ setState(newState);
1140
+ return newState;
1141
+ };
1142
+ }
1143
+
1144
+ function get$1(setState, Ctx) {
1145
+ return async endpoint => {
1146
+ setState({
1147
+ loading: true
1148
+ });
1149
+ let newState = {};
1150
+
1151
+ try {
1152
+ const path = endpoint ? `${Ctx.path}${endpoint}` : Ctx.path;
1153
+ const res = await Ctx.client.get(path);
1154
+ newState = await processResponse(res, true);
1155
+ } catch (e) {
1156
+ console.error('Error', e);
1157
+ newState = {
1158
+ isError: true,
1159
+ errorMessage: 'unhandled exception'
1160
+ };
1161
+ }
1162
+
1163
+ setState(newState);
1164
+ return newState;
1165
+ };
1166
+ } // const get = (
1167
+ // setState: (value: Partial<State>) => void,
1168
+ // Ctx: Traversal
1169
+ // ) =>
989
1170
 
990
- setState(newState);
991
- return newState;
992
- };
993
1171
 
994
1172
  function useCrudContext() {
995
1173
  const Ctx = useTraversal();
@@ -999,7 +1177,7 @@ function useCrudContext() {
999
1177
  patch: patch(setState, Ctx),
1000
1178
  del: del(setState, Ctx),
1001
1179
  post: post(setState, Ctx),
1002
- get: get(setState, Ctx)
1180
+ get: get$1(setState, Ctx)
1003
1181
  });
1004
1182
  }
1005
1183
 
@@ -1046,7 +1224,6 @@ function AddItem(props) {
1046
1224
  children: jsx(Form, {
1047
1225
  loading: loading,
1048
1226
  onSubmit: doSubmit,
1049
- onError: err => console.log(err),
1050
1227
  actionName: 'Add ' + type,
1051
1228
  title: 'Add ' + type,
1052
1229
  type: type,
@@ -1056,31 +1233,50 @@ function AddItem(props) {
1056
1233
  }
1057
1234
 
1058
1235
  const Permissions = ['guillotina.AddContent', 'guillotina.ModifyContent', 'guillotina.ViewContent', 'guillotina.DeleteContent', 'guillotina.AccessContent', 'guillotina.SeePermissions', 'guillotina.ChangePermissions', 'guillotina.MoveContent', 'guillotina.DuplicateContent', 'guillotina.ReadConfiguration', 'guillotina.RegisterConfigurations', 'guillotina.WriteConfiguration', 'guillotina.ManageAddons', 'guillotina.swagger.View'];
1059
- const Config = {
1236
+ const defaultConfig = {
1060
1237
  DisabledTypes: ['UserManager', 'GroupManager'],
1061
1238
  PageSize: 10,
1062
1239
  DelayActions: 200,
1063
1240
  Permissions: Permissions,
1064
1241
  SearchEngine: 'PostreSQL',
1242
+ // Elasticsearch
1065
1243
  fieldHaveDeleteButton: schema => {
1066
1244
  return (schema == null ? void 0 : schema.widget) === 'file' || (schema == null ? void 0 : schema.widget) === 'select' || (schema == null ? void 0 : schema.type) === 'array';
1067
1245
  }
1068
1246
  };
1069
- let calculated = Object.assign({}, Config);
1070
-
1071
- const addConfig = (additional, original) => {
1072
- const rest = Object.assign({}, original);
1073
- Object.keys(additional).forEach(item => {
1074
- if (typeof Config[item] === 'object' && Array.isArray(Config[item])) {
1075
- rest[item] = [].concat(Config[item], additional[item]);
1076
- } else if (typeof Config[item] === 'object') {
1077
- rest[item] = Object.assign({}, Config[item], additional[item]);
1247
+ let calculated = Object.assign({}, defaultConfig);
1248
+
1249
+ function addConfig(updates, currentConfig) {
1250
+ let updatedConfig = _extends({}, currentConfig);
1251
+
1252
+ Object.entries(updates).forEach(([key, value]) => {
1253
+ const currentKey = key;
1254
+ const currentValue = currentConfig[currentKey];
1255
+
1256
+ if (Array.isArray(value) && Array.isArray(currentValue)) {
1257
+ // Correctly type the array concatenation
1258
+ updatedConfig = _extends({}, updatedConfig, {
1259
+ [currentKey]: [...currentValue, ...value]
1260
+ });
1261
+ } else if (isPlainObject(value) && isPlainObject(currentValue)) {
1262
+ // Correctly type the object merging
1263
+ updatedConfig = _extends({}, updatedConfig, {
1264
+ [currentKey]: _extends({}, currentValue, value)
1265
+ });
1078
1266
  } else {
1079
- rest[item] = additional[item];
1267
+ // Directly assign all other types
1268
+ updatedConfig = _extends({}, updatedConfig, {
1269
+ [currentKey]: value
1270
+ });
1080
1271
  }
1081
1272
  });
1082
- return rest;
1083
- };
1273
+ return updatedConfig;
1274
+ } // Helper function to check if a value is a plain object (and not a React node, etc.)
1275
+
1276
+
1277
+ function isPlainObject(value) {
1278
+ return Object.prototype.toString.call(value) === '[object Object]';
1279
+ }
1084
1280
 
1085
1281
  function useConfig(cfg = {}) {
1086
1282
  const ref = useRef();
@@ -1100,20 +1296,22 @@ function RemoveItems(props) {
1100
1296
  const {
1101
1297
  items = []
1102
1298
  } = props;
1103
- const last = items[items.length - 1]['@name'];
1104
- const itemsNames = items.map(item => item['@name']).join(', ').replace(`, ${last}`, ` and ${last}`);
1299
+ const last = items[items.length - 1].id;
1300
+ const itemsNames = items.map(item => item.id).join(', ').replace(`, ${last}`, ` and ${last}`);
1105
1301
 
1106
1302
  async function removeItems() {
1107
1303
  const errors = [];
1108
1304
  setLoading(true);
1109
1305
  const actions = items.map(async item => {
1110
- const res = await Ctx.client.delete(`${Ctx.path}${item['@name']}`);
1306
+ const res = await Ctx.client.delete(`${Ctx.path}${item.id}`, {});
1111
1307
 
1112
1308
  if (!res.ok) {
1113
1309
  const err = await res.json();
1114
1310
  errors.push(err);
1115
1311
  }
1116
- });
1312
+ }); // this sleep is here, to let elasticsearch, wait for
1313
+ // index our operations... (will work 99% of use cases)
1314
+
1117
1315
  actions.push(sleep(cfg.DelayActions));
1118
1316
  await Promise.all(actions);
1119
1317
 
@@ -1151,7 +1349,7 @@ const Checkbox = ({
1151
1349
  dataTest
1152
1350
  }) => {
1153
1351
  const inputRef = useRef(null);
1154
- const [state, setState] = useState(checked);
1352
+ const [state, setState] = useState(!!checked);
1155
1353
  useEffect(() => {
1156
1354
  if (inputRef.current) {
1157
1355
  inputRef.current.indeterminate = _indeterminate;
@@ -1167,13 +1365,13 @@ const Checkbox = ({
1167
1365
  className: "field",
1168
1366
  children: jsxs("label", {
1169
1367
  htmlFor: id,
1170
- className: classnames(['checkbox', className]),
1368
+ className: classnames(['checkbox', className != null ? className : '']),
1171
1369
  children: [jsx("input", {
1172
1370
  ref: inputRef,
1173
1371
  disabled: disabled || loading,
1174
1372
  id: id,
1175
1373
  type: "checkbox",
1176
- className: classnames(['checkbox', classNameInput]),
1374
+ className: classnames(['checkbox', classNameInput != null ? classNameInput : '']),
1177
1375
  checked: state,
1178
1376
  onChange: updateState,
1179
1377
  "data-test": dataTest
@@ -1211,14 +1409,14 @@ const applyValidators = (value, validators) => {
1211
1409
  return result;
1212
1410
  };
1213
1411
 
1214
- const useInput = (onChange, value, validator) => {
1412
+ const useInput = (onChange, value, validators) => {
1215
1413
  const [state, setState] = useState({
1216
1414
  hasError: false,
1217
1415
  value: value
1218
1416
  });
1219
1417
 
1220
1418
  const onUpdate = ev => {
1221
- const value = ev && ev.target ? ev.target.value : ev ? ev : '';
1419
+ const value = ev && ev.target ? ev.target.value : '';
1222
1420
  setState({
1223
1421
  value,
1224
1422
  hasError: false
@@ -1227,7 +1425,7 @@ const useInput = (onChange, value, validator) => {
1227
1425
  };
1228
1426
 
1229
1427
  const onBlur = () => {
1230
- const hasError = applyValidators(state.value, validator) === false;
1428
+ const hasError = applyValidators(state.value, validators) === false;
1231
1429
  if (hasError) setState({
1232
1430
  value: state.value,
1233
1431
  hasError
@@ -1257,6 +1455,9 @@ const useInput = (onChange, value, validator) => {
1257
1455
  };
1258
1456
  };
1259
1457
 
1458
+ // From github.com/protonmail/proton-shared
1459
+
1460
+ /* eslint-disable no-useless-escape */
1260
1461
  const REGEX_EMAIL = /(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/i;
1261
1462
  const REGEX_URL = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/;
1262
1463
  const REGEX_HEX_COLOR = /^#([a-f0-9]{3,4}|[a-f0-9]{4}(?:[a-f0-9]{2}){1,2})\b$/i;
@@ -1294,10 +1495,10 @@ const Input = forwardRef(({
1294
1495
  disabled,
1295
1496
  onKeyUp
1296
1497
  }, ref) => {
1297
- let validatorFn = null;
1498
+ let validatorFn = [];
1298
1499
 
1299
1500
  if (_required) {
1300
- validatorFn = Array.isArray(_validator) ? _validator.push(notEmpty) : [_validator, notEmpty];
1501
+ validatorFn = Array.isArray(_validator) ? [..._validator, notEmpty] : [_validator, notEmpty];
1301
1502
  }
1302
1503
 
1303
1504
  const _useInput = useInput(onChange, value != null ? value : '', validatorFn),
@@ -1307,16 +1508,17 @@ const Input = forwardRef(({
1307
1508
  handlers = _objectWithoutPropertiesLoose(_useInput, ["state"]);
1308
1509
 
1309
1510
  const [uid] = useState(generateUID('input'));
1310
- const [mounted, setMounted] = useState(false);
1311
- ref = ref || useRef();
1511
+ const [mounted, setMounted] = useState(false); // eslint-disable-next-line
1512
+
1513
+ const newRef = ref || useRef();
1312
1514
  useEffect(() => {
1313
1515
  setMounted(true);
1314
1516
  }, []);
1315
1517
  useEffect(() => {
1316
- if (_autofocus && !error && ref != null && typeof ref !== 'function') {
1317
- ref.current.focus();
1518
+ if (_autofocus && !error && newRef != null && typeof newRef !== 'function' && newRef.current) {
1519
+ newRef.current.focus();
1318
1520
  }
1319
- }, [mounted, _autofocus, ref, error]);
1521
+ }, [mounted, _autofocus, newRef, error]);
1320
1522
  const theError = state.hasError ? errorMessage || 'invalid field' : '';
1321
1523
  const statusClasses = state.hasError ? 'is-danger' : '';
1322
1524
 
@@ -1355,10 +1557,10 @@ Input.displayName = 'Input';
1355
1557
 
1356
1558
  const Icon = ({
1357
1559
  icon,
1358
- className,
1560
+ className: _className = '',
1359
1561
  align
1360
1562
  }) => {
1361
- const addClass = className ? className.split(' ') : [className];
1563
+ const addClass = _className ? _className.split(' ') : [_className];
1362
1564
  align = align || 'is-right';
1363
1565
  return jsx("span", {
1364
1566
  className: classnames(['icon', align, ...addClass]),
@@ -1463,22 +1665,24 @@ function FormBuilder({
1463
1665
  remotes = {},
1464
1666
  submitButton = true
1465
1667
  }) {
1466
- const ref = useRef();
1668
+ const ref = useRef(null);
1467
1669
  const {
1468
1670
  properties,
1469
1671
  required
1470
1672
  } = schema;
1471
- const values = Object.assign({}, formData || {});
1673
+ const values = Object.assign({}, formData || {}); // build initial state
1674
+
1472
1675
  const initialState = {};
1473
1676
  const fields = Object.keys(properties).filter(x => !exclude.includes(x));
1474
1677
  fields.forEach(element => {
1475
1678
  initialState[element] = values[element] || undefined;
1476
- });
1679
+ }); // Register remotes
1477
1680
 
1478
- if (!ref.current) {
1681
+ if (ref.current === null) {
1479
1682
  ref.current = {};
1480
1683
  Object.keys(remotes).forEach(item => ref.current[item] = remotes[item]);
1481
1684
  } else {
1685
+ // apply remote changes
1482
1686
  Object.keys(remotes).forEach(key => {
1483
1687
  if (JSON.stringify(ref.current[key]) !== JSON.stringify(remotes[key])) {
1484
1688
  ref.current[key] = remotes[key];
@@ -1488,15 +1692,16 @@ function FormBuilder({
1488
1692
 
1489
1693
  ref.current = ref.current || {};
1490
1694
 
1491
- const onUpdate = field => ev => {
1492
- ref.current[field] = ev.target ? ev.target.value : ev.value || ev;
1695
+ const onUpdate = field => value => {
1696
+ ref.current[field] = value;
1493
1697
  };
1494
1698
 
1495
1699
  const GetTag = ({
1496
1700
  field
1497
1701
  }) => {
1498
1702
  const property = properties[field];
1499
- const Tag = formComponents[property.widget || property.type];
1703
+ const key = property.widget || property.type;
1704
+ const Tag = formComponents[key];
1500
1705
  const props = {
1501
1706
  value: initialState[field],
1502
1707
  onChange: onUpdate(field),
@@ -1511,7 +1716,6 @@ function FormBuilder({
1511
1716
  props.placeholder += ' *';
1512
1717
  }
1513
1718
 
1514
- Tag.displayName = `${field}Field`;
1515
1719
  return jsx(Tag, _extends({}, props));
1516
1720
  };
1517
1721
 
@@ -1570,9 +1774,13 @@ const Select = forwardRef(({
1570
1774
  selectValue = selectValue.concat([ev.target.selectedOptions[i].value]);
1571
1775
  }
1572
1776
 
1573
- onChange(selectValue);
1777
+ if (onChange) {
1778
+ onChange(selectValue);
1779
+ }
1574
1780
  } else {
1575
- onChange(ev.target.value);
1781
+ if (onChange) {
1782
+ onChange(ev.target.value);
1783
+ }
1576
1784
  }
1577
1785
  };
1578
1786
 
@@ -1623,28 +1831,7 @@ const Select = forwardRef(({
1623
1831
  });
1624
1832
  Select.displayName = 'Select';
1625
1833
 
1626
- const formatDate = str => {
1627
- const d = new Date(str);
1628
- const minutes = d.getMinutes() < 10 ? `0${d.getMinutes()}` : d.getMinutes();
1629
- return `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()} ${d.getHours()}:${minutes}`;
1630
- };
1631
- const get$1 = (obj, path, defValue) => {
1632
- var _pathArray$reduce;
1633
-
1634
- if (!path) return undefined;
1635
- const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
1636
- return (_pathArray$reduce = pathArray.reduce((prevObj, key) => prevObj && prevObj[key], obj)) != null ? _pathArray$reduce : defValue;
1637
- };
1638
- function getNewId(id = '') {
1639
- const suffix = '-copy-';
1640
- const rgx = new RegExp(`($|${suffix}\\d*)`);
1641
- return stringToSlug(id).replace(rgx, r => {
1642
- const num = parseInt(r.replace(suffix, '') || '0');
1643
- return `${suffix}${num + 1}`;
1644
- });
1645
- }
1646
-
1647
- function useVocabulary(vocabularyName, path = null) {
1834
+ function useVocabulary(vocabularyName, path) {
1648
1835
  const traversal = useTraversal();
1649
1836
  const [vocabulary, setVocabulary] = useSetState({
1650
1837
  data: undefined,
@@ -1699,8 +1886,10 @@ const SelectVocabulary = forwardRef(({
1699
1886
  const vocabulary = useVocabulary(vocabularyName);
1700
1887
 
1701
1888
  const getOptions = () => {
1702
- if (get$1(vocabulary, 'data.items', null)) {
1703
- const vocData = vocabulary.data.items.map(item => {
1889
+ if (get(vocabulary, 'data.items', null)) {
1890
+ var _vocabulary$data$item, _vocabulary$data;
1891
+
1892
+ const vocData = ((_vocabulary$data$item = vocabulary == null ? void 0 : (_vocabulary$data = vocabulary.data) == null ? void 0 : _vocabulary$data.items) != null ? _vocabulary$data$item : []).map(item => {
1704
1893
  return {
1705
1894
  text: item.title,
1706
1895
  value: item.token
@@ -1746,6 +1935,8 @@ const SelectVocabulary = forwardRef(({
1746
1935
  });
1747
1936
  SelectVocabulary.displayName = 'SelectVocabulary';
1748
1937
 
1938
+ // https://github.com/molefrog/wouter
1939
+
1749
1940
  const setURLParams = p => {
1750
1941
  return window.history.pushState(0, '0', '' + '?' + p.toString().replace(/%2F/g, '/'));
1751
1942
  };
@@ -1760,7 +1951,10 @@ const useLocation = () => {
1760
1951
  const [path, update] = useState(currentSearchParams());
1761
1952
  const prevPath = useRef(path);
1762
1953
  useEffect(() => {
1763
- patchHistoryEvents();
1954
+ patchHistoryEvents(); // this function checks if the location has been changed since the
1955
+ // last render and updates the state only when needed.
1956
+ // unfortunately, we can't rely on `path` value here, since it can be stale,
1957
+ // that's why we store the last pathname in a ref.
1764
1958
 
1765
1959
  const checkForUpdates = () => {
1766
1960
  const pathname = currentSearchParams();
@@ -1768,12 +1962,20 @@ const useLocation = () => {
1768
1962
  };
1769
1963
 
1770
1964
  const events = ['popstate', 'pushState', 'replaceState'];
1771
- events.map(e => window.addEventListener(e, checkForUpdates));
1965
+ events.map(e => window.addEventListener(e, checkForUpdates)); // it's possible that an update has occurred between render and the effect handler,
1966
+ // so we run additional check on mount to catch these updates. Based on:
1967
+ // https://gist.github.com/bvaughn/e25397f70e8c65b0ae0d7c90b731b189
1968
+
1772
1969
  checkForUpdates();
1773
1970
  return () => {
1774
1971
  events.map(e => window.removeEventListener(e, checkForUpdates));
1775
1972
  };
1776
- }, []);
1973
+ }, []); // the 2nd argument of the `useLocation` return value is a function
1974
+ // that allows to perform a navigation.
1975
+ //
1976
+ // the function reference should stay the same between re-renders, so that
1977
+ // it can be passed down as an element prop without any performance concerns.
1978
+
1777
1979
  const navigate = useCallback((to, replace) => {
1778
1980
  if (replace) {
1779
1981
  clean(to);
@@ -1790,22 +1992,38 @@ const useLocation = () => {
1790
1992
  setURLParams(current);
1791
1993
  }, [path]);
1792
1994
  return [path, navigate, remove];
1793
- };
1995
+ }; // While History API does have `popstate` event, the only
1996
+ // proper way to listen to changes via `push/replaceState`
1997
+ // is to monkey-patch these methods.
1998
+ //
1999
+ // See https://stackoverflow.com/a/4585031
2000
+
1794
2001
  let patched = 0;
1795
2002
 
1796
2003
  const patchHistoryEvents = () => {
1797
2004
  if (patched) return;
1798
- ['pushState', 'replaceState'].map(type => {
1799
- const original = window.history[type];
1800
-
1801
- window.history[type] = function (...args) {
1802
- const result = original.apply(this, args);
1803
- const event = new Event(type);
1804
- event.arguments = args;
1805
- dispatchEvent(event);
1806
- return result;
1807
- };
1808
- });
2005
+ const originalPushState = window.history.pushState;
2006
+
2007
+ window.history.pushState = function (...args) {
2008
+ const result = originalPushState.apply(this, args); // eslint-disable-next-line @typescript-eslint/no-explicit-any
2009
+
2010
+ const event = new Event('pushState');
2011
+ event.arguments = args;
2012
+ dispatchEvent(event);
2013
+ return result;
2014
+ };
2015
+
2016
+ const originalReplaceState = window.history.replaceState;
2017
+
2018
+ window.history.replaceState = function (...args) {
2019
+ const result = originalReplaceState.apply(this, args); // eslint-disable-next-line @typescript-eslint/no-explicit-any
2020
+
2021
+ const event = new Event('replaceState');
2022
+ event.arguments = args;
2023
+ dispatchEvent(event);
2024
+ return result;
2025
+ };
2026
+
1809
2027
  return patched = 1;
1810
2028
  };
1811
2029
 
@@ -1853,7 +2071,7 @@ function TdLink({
1853
2071
  children,
1854
2072
  style = {}
1855
2073
  }) {
1856
- const link = useRef();
2074
+ const link = useRef(null);
1857
2075
 
1858
2076
  function onClick() {
1859
2077
  if (link && link.current) {
@@ -1949,7 +2167,7 @@ class RestClient {
1949
2167
  this.container = container;
1950
2168
  }
1951
2169
 
1952
- async request(path, data = undefined, headers = undefined) {
2170
+ async request(path, data, headers, signal) {
1953
2171
  if (path.indexOf(this.url) !== -1) {
1954
2172
  path = path.replace(this.url, '');
1955
2173
  }
@@ -1962,19 +2180,28 @@ class RestClient {
1962
2180
  path = `/${path}`;
1963
2181
  }
1964
2182
 
1965
- data = data || {};
1966
- data.headers = headers || this.getHeaders();
1967
- return await fetch(`${this.url}${path}`, data);
2183
+ const dataRequest = data || {};
2184
+ dataRequest.headers = this.getHeaders();
2185
+
2186
+ if (headers) {
2187
+ dataRequest.headers = _extends({}, dataRequest.headers, headers);
2188
+ }
2189
+
2190
+ if (signal) {
2191
+ dataRequest.signal = signal;
2192
+ }
2193
+
2194
+ return await fetch(`${this.url}${path}`, dataRequest);
1968
2195
  }
1969
2196
 
1970
2197
  getHeaders() {
1971
2198
  const authToken = this.auth.getToken();
1972
- if (!authToken) return {};
1973
- return {
1974
- Accept: 'application/json',
1975
- 'Content-Type': 'application/json',
1976
- Authorization: 'Bearer ' + authToken
1977
- };
2199
+ const headersInit = {};
2200
+ if (!authToken) return headersInit;
2201
+ headersInit.Accept = 'application/json';
2202
+ headersInit['Content-Type'] = 'application/json';
2203
+ headersInit.Authorization = 'Bearer ' + authToken;
2204
+ return headersInit;
1978
2205
  }
1979
2206
 
1980
2207
  async post(path, data) {
@@ -1984,8 +2211,8 @@ class RestClient {
1984
2211
  });
1985
2212
  }
1986
2213
 
1987
- async get(path) {
1988
- return await this.request(path);
2214
+ async get(path, signal) {
2215
+ return await this.request(path, undefined, undefined, signal);
1989
2216
  }
1990
2217
 
1991
2218
  async put(path, data) {
@@ -2004,17 +2231,17 @@ class RestClient {
2004
2231
 
2005
2232
  async upload(path, data) {
2006
2233
  const headers = this.getHeaders();
2007
- delete headers['Content-Type'];
2008
- headers['Content-Type'] = data['content-type'];
2009
- headers['X-UPLOAD-FILENAME'] = data.filename;
2010
- headers['Content-Encoding'] = 'base64';
2234
+ const newHeaders = {};
2235
+ newHeaders['Content-Type'] = data['content-type'];
2236
+ newHeaders['X-UPLOAD-FILENAME'] = data.filename;
2237
+ newHeaders['Content-Encoding'] = 'base64';
2011
2238
  return await this.request(path, {
2012
2239
  method: 'PATCH',
2013
2240
  body: data.data
2014
- }, headers);
2241
+ }, _extends({}, headers, newHeaders));
2015
2242
  }
2016
2243
 
2017
- async delete(path, data = undefined) {
2244
+ async delete(path, data) {
2018
2245
  return await this.request(path, {
2019
2246
  method: 'delete',
2020
2247
  body: JSON.stringify(data)
@@ -2121,6 +2348,14 @@ class GuillotinaClient {
2121
2348
  return await this.rest.get(path);
2122
2349
  }
2123
2350
 
2351
+ getQueryParamsSearchFunction(name) {
2352
+ if (name === 'getQueryParamsElasticsearch') {
2353
+ return this.getQueryParamsElasticsearch;
2354
+ }
2355
+
2356
+ return this.getQueryParamsPostresql;
2357
+ }
2358
+
2124
2359
  getQueryParamsPostresql({
2125
2360
  start = 0,
2126
2361
  pageSize = 10,
@@ -2157,7 +2392,7 @@ class GuillotinaClient {
2157
2392
  objectPath = objectPath.slice(0, -1);
2158
2393
  }
2159
2394
 
2160
- result = [...parser(start.toString(), '_from'), ...parser(pageSize.toString(), 'size'), ...parser('*', '_metadata')];
2395
+ result = [...parser(start.toString(), '_from'), ...parser(pageSize.toString(), '_size'), ...parser('*', '_metadata')];
2161
2396
 
2162
2397
  if (withDepth) {
2163
2398
  var _parser2;
@@ -2204,7 +2439,7 @@ class GuillotinaClient {
2204
2439
  label: 'id/name',
2205
2440
  key: 'title',
2206
2441
  isSortable: true,
2207
- child: (m, navigate, search) => jsxs(TdLink, {
2442
+ child: (m, _navigate, search) => jsxs(TdLink, {
2208
2443
  model: m,
2209
2444
  children: [m.name, search && jsxs(React.Fragment, {
2210
2445
  children: [jsx("br", {}), jsx("span", {
@@ -2234,15 +2469,19 @@ class GuillotinaClient {
2234
2469
  children: m.updated
2235
2470
  })
2236
2471
  }];
2237
- }
2472
+ } // BBB API changes. Compat G5 and G6
2473
+
2238
2474
 
2239
2475
  applyCompat(data) {
2240
- data.member = data.items;
2241
- data.items_count = data.items_total;
2242
- return data;
2476
+ const result = _extends({}, data, {
2477
+ member: data.items,
2478
+ items_count: data.items_total
2479
+ });
2480
+
2481
+ return result;
2243
2482
  }
2244
2483
 
2245
- async search(path, params, container = false, prepare = true) {
2484
+ async search(path, params, container = false, prepare = true, signal) {
2246
2485
  if (path.startsWith('/')) {
2247
2486
  path = path.slice(1);
2248
2487
  }
@@ -2253,7 +2492,7 @@ class GuillotinaClient {
2253
2492
 
2254
2493
  const query = prepare ? toQueryString(params) : params;
2255
2494
  const url = `${path}@search?${query}`;
2256
- const res = await this.rest.get(url);
2495
+ const res = await this.rest.get(url, signal);
2257
2496
  const data = await res.json();
2258
2497
  return this.applyCompat(data);
2259
2498
  }
@@ -2322,7 +2561,8 @@ class GuillotinaClient {
2322
2561
 
2323
2562
  async getTypeSchema(path, name) {
2324
2563
  if (!cacheSchemas[name]) {
2325
- const url = this.getContainerFromPath(path);
2564
+ const url = this.getContainerFromPath(path); // todo: handle db case (only addable containers)
2565
+
2326
2566
  const res = await this.rest.get(`${url}@types/${name}`);
2327
2567
  cacheSchemas[name] = await res.json();
2328
2568
  }
@@ -2359,10 +2599,36 @@ class GuillotinaClient {
2359
2599
  async getPrincipals(path) {
2360
2600
  const groups = this.getGroups(path);
2361
2601
  const users = this.getUsers(path);
2362
- const [gr, usr] = await Promise.all([groups, users]);
2602
+ const [responseGroups, responseUsers] = await Promise.all([groups, users]);
2603
+ let groupsData = [];
2604
+ let usersData = [];
2605
+
2606
+ if (responseGroups.ok) {
2607
+ const groupsDataResponse = await responseGroups.json();
2608
+ groupsData = groupsDataResponse.map(group => {
2609
+ return {
2610
+ '@name': group.id,
2611
+ user_roles: group.roles,
2612
+ users: group.users
2613
+ };
2614
+ });
2615
+ }
2616
+
2617
+ if (responseUsers) {
2618
+ const usersDataResponse = await responseUsers.json();
2619
+ usersData = usersDataResponse.map(user => {
2620
+ return {
2621
+ '@name': user.id,
2622
+ user_roles: user.roles,
2623
+ fullname: user.fullname,
2624
+ email: user.email
2625
+ };
2626
+ });
2627
+ }
2628
+
2363
2629
  return {
2364
- groups: gr.ok ? await gr.json() : [],
2365
- users: usr.ok ? await usr.json() : []
2630
+ groups: groupsData,
2631
+ users: usersData
2366
2632
  };
2367
2633
  }
2368
2634
 
@@ -2372,6 +2638,7 @@ class GuillotinaClient {
2372
2638
  }
2373
2639
 
2374
2640
  async getAllPermissions(path) {
2641
+ // paths used to query the API always has to start without a "/"
2375
2642
  if (path.startsWith('/')) {
2376
2643
  path = path.slice(1);
2377
2644
  }
@@ -2406,17 +2673,24 @@ function getClient(url, container, auth) {
2406
2673
  return new GuillotinaClient(new RestClient(url, container, auth), container === '/');
2407
2674
  }
2408
2675
  const lightFileReader = file => {
2409
- return new Promise(resolve => {
2676
+ return new Promise((resolve, reject) => {
2410
2677
  const reader = new FileReader();
2411
2678
  reader.readAsArrayBuffer(file);
2412
2679
 
2413
2680
  reader.onloadend = e => {
2414
- const fileData = e.target.result;
2415
- resolve({
2416
- filename: file.name.normalize('NFD').replace(/[\u0300-\u036f]/g, ''),
2417
- data: fileData,
2418
- 'content-type': file.type
2419
- });
2681
+ var _e$target;
2682
+
2683
+ const fileData = e == null ? void 0 : (_e$target = e.target) == null ? void 0 : _e$target.result;
2684
+
2685
+ if (fileData) {
2686
+ resolve({
2687
+ filename: file.name.normalize('NFD').replace(/[\u0300-\u036f]/g, ''),
2688
+ data: fileData,
2689
+ 'content-type': file.type
2690
+ });
2691
+ } else {
2692
+ reject('Error reading file');
2693
+ }
2420
2694
  };
2421
2695
  });
2422
2696
  };
@@ -2443,8 +2717,10 @@ function FileUpload({
2443
2717
  const intl = useIntl();
2444
2718
 
2445
2719
  const changed = async event => {
2446
- const fileToUpload = await lightFileReader(event.target.files[0]);
2447
- onChange(fileToUpload);
2720
+ if (event.target.files) {
2721
+ const fileToUpload = await lightFileReader(event.target.files[0]);
2722
+ onChange(fileToUpload);
2723
+ }
2448
2724
  };
2449
2725
 
2450
2726
  return jsx("div", {
@@ -2527,9 +2803,9 @@ Textarea.displayName = 'Textarea';
2527
2803
 
2528
2804
  const defaultEvents = ['mousedown', 'touchstart'];
2529
2805
 
2530
- const on = (obj, ...args) => obj.addEventListener(...args);
2806
+ const on = (obj, type, handler) => obj.addEventListener(type, handler);
2531
2807
 
2532
- const off = (obj, ...args) => obj.removeEventListener(...args);
2808
+ const off = (obj, type, handler) => obj.removeEventListener(type, handler);
2533
2809
 
2534
2810
  function useClickAway(ref, onClickAway, events = defaultEvents) {
2535
2811
  const savedCallback = useRef(onClickAway);
@@ -2556,23 +2832,7 @@ function useClickAway(ref, onClickAway, events = defaultEvents) {
2556
2832
  }, [events, ref]);
2557
2833
  }
2558
2834
 
2559
- function debounce(func, wait) {
2560
- let timeout;
2561
- return function () {
2562
- const context = this;
2563
- const args = arguments;
2564
-
2565
- const later = function later() {
2566
- timeout = null;
2567
- func.apply(context, args);
2568
- };
2569
-
2570
- clearTimeout(timeout);
2571
- timeout = setTimeout(later, wait);
2572
- };
2573
- }
2574
-
2575
- const initialState = {
2835
+ const initialState$1 = {
2576
2836
  page: 0,
2577
2837
  items: undefined,
2578
2838
  loading: false,
@@ -2582,8 +2842,8 @@ const SearchInput = ({
2582
2842
  onChange,
2583
2843
  error,
2584
2844
  errorZoneClassName,
2585
- traversal: _traversal = null,
2586
- path: _path = null,
2845
+ traversal,
2846
+ path: _path = undefined,
2587
2847
  qs: _qs = [],
2588
2848
  queryCondition: _queryCondition = 'id__in',
2589
2849
  value,
@@ -2591,12 +2851,12 @@ const SearchInput = ({
2591
2851
  dataTestWrapper: _dataTestWrapper = 'wrapperSearchInputTest',
2592
2852
  dataTestSearchInput: _dataTestSearchInput = 'searchInputTest',
2593
2853
  dataTestItem: _dataTestItem = 'searchInputItemTest',
2594
- renderTextItemOption: _renderTextItemOption = null,
2595
- typeNameQuery: _typeNameQuery = null,
2854
+ renderTextItemOption: _renderTextItemOption = undefined,
2855
+ typeNameQuery: _typeNameQuery = undefined,
2596
2856
  labelProperty: _labelProperty = 'id'
2597
2857
  }) => {
2598
2858
  const intl = useIntl();
2599
- const [options, setOptions] = useSetState(initialState);
2859
+ const [options, setOptions] = useSetState(initialState$1);
2600
2860
  const [isOpen, setIsOpen] = useState(false);
2601
2861
  const [searchTerm, setSearchTerm] = useState('');
2602
2862
  const inputRef = useRef(null);
@@ -2631,16 +2891,14 @@ const SearchInput = ({
2631
2891
  const searchTermParsed = [`id`, value];
2632
2892
  const {
2633
2893
  get: getSearch
2634
- } = _traversal.registry;
2894
+ } = traversal.registry;
2635
2895
  const fnName = getSearch('searchEngineQueryParamsFunction', SearchEngine);
2636
-
2637
- const qsParsed = _traversal.client[fnName]({
2638
- path: _traversal.path,
2896
+ const qsParsed = traversal.client.getQueryParamsSearchFunction(fnName)({
2897
+ path: traversal.path,
2639
2898
  start: 0,
2640
2899
  pageSize: PageSize,
2641
2900
  withDepth: false
2642
2901
  });
2643
-
2644
2902
  let typeNameParsed = [];
2645
2903
 
2646
2904
  if (_typeNameQuery) {
@@ -2651,9 +2909,9 @@ const SearchInput = ({
2651
2909
  searchTermQs = buildQs([..._qs, searchTermParsed, ...qsParsed, ...typeNameParsed]);
2652
2910
  }
2653
2911
 
2654
- const data = await _traversal.client.search(_path ? _path : _traversal.client.getContainerFromPath(_traversal.path), searchTermQs, false, false);
2912
+ const data = await traversal.client.search(_path ? _path : traversal.client.getContainerFromPath(traversal.path), searchTermQs, false, false);
2655
2913
  const newValuesLabel = data.items.reduce((result, item) => {
2656
- result[item.id] = get$1(item, _labelProperty, item.id);
2914
+ result[item.id] = get(item, _labelProperty, item.id);
2657
2915
  return result;
2658
2916
  }, {});
2659
2917
  setValueLabel(newValuesLabel);
@@ -2663,6 +2921,7 @@ const SearchInput = ({
2663
2921
  const handleSearch = async (page = 0, concat = false, value = '') => {
2664
2922
  var _data$items_total;
2665
2923
 
2924
+ console.log('handle search input');
2666
2925
  setOptions({
2667
2926
  loading: true
2668
2927
  });
@@ -2675,16 +2934,14 @@ const SearchInput = ({
2675
2934
 
2676
2935
  const {
2677
2936
  get
2678
- } = _traversal.registry;
2937
+ } = traversal.registry;
2679
2938
  const fnName = get('searchEngineQueryParamsFunction', SearchEngine);
2680
-
2681
- const qsParsed = _traversal.client[fnName]({
2682
- path: _traversal.path,
2939
+ const qsParsed = traversal.client.getQueryParamsSearchFunction(fnName)({
2940
+ path: traversal.path,
2683
2941
  start: page * PageSize,
2684
2942
  pageSize: PageSize,
2685
2943
  withDepth: false
2686
2944
  });
2687
-
2688
2945
  const sortParsed = parser(`_sort_des=${_labelProperty}`);
2689
2946
  let typeNameParsed = [];
2690
2947
 
@@ -2692,11 +2949,11 @@ const SearchInput = ({
2692
2949
  typeNameParsed = parser(`type_name__in=${_typeNameQuery}`);
2693
2950
  }
2694
2951
 
2695
- if (_qs.length > 0 || searchTermParsed.length > 0 || qsParsed.length > 0 || typeNameParsed.length > 0) {
2952
+ if (_qs.length > 0 || searchTermParsed.length > 0 || qsParsed.length > 0 || typeNameParsed.length > 0 || sortParsed.length > 0) {
2696
2953
  searchTermQs = buildQs([..._qs, ...searchTermParsed, ...qsParsed, ...typeNameParsed, ...sortParsed]);
2697
2954
  }
2698
2955
 
2699
- const data = await _traversal.client.search(_path ? _path : _traversal.client.getContainerFromPath(_traversal.path), searchTermQs, false, false);
2956
+ const data = await traversal.client.search(_path ? _path : traversal.client.getContainerFromPath(traversal.path), searchTermQs, false, false);
2700
2957
  const newItems = options.items && concat ? [...options.items, ...data.items] : data.items;
2701
2958
  setOptions({
2702
2959
  items: newItems != null ? newItems : [],
@@ -2711,7 +2968,7 @@ const SearchInput = ({
2711
2968
  return _renderTextItemOption(item);
2712
2969
  }
2713
2970
 
2714
- return get$1(item, _labelProperty, item.title) || item['@name'];
2971
+ return get(item, _labelProperty, item.title) || item['@name'];
2715
2972
  };
2716
2973
 
2717
2974
  useEffect(() => {
@@ -2737,7 +2994,7 @@ const SearchInput = ({
2737
2994
  if (!ev.currentTarget.contains(ev.relatedTarget)) {
2738
2995
  if (searchTerm !== '') {
2739
2996
  setSearchTerm('');
2740
- setOptions(initialState);
2997
+ setOptions(initialState$1);
2741
2998
  }
2742
2999
 
2743
3000
  setIsOpen(false);
@@ -2755,6 +3012,7 @@ const SearchInput = ({
2755
3012
  }
2756
3013
 
2757
3014
  setIsOpen(!isOpen);
3015
+ console.log('on clic btn', options);
2758
3016
 
2759
3017
  if (!options.loading && !options.items) {
2760
3018
  handleSearch(options.page);
@@ -2763,7 +3021,7 @@ const SearchInput = ({
2763
3021
  "aria-haspopup": "true",
2764
3022
  "aria-controls": "dropdown-menu",
2765
3023
  children: [jsx("span", {
2766
- children: value ? get$1(valueLabel, value, value) : intl.formatMessage(genericMessages.choose)
3024
+ children: value ? get(valueLabel, value, value) : intl.formatMessage(genericMessages.choose)
2767
3025
  }), jsx("span", {
2768
3026
  className: "icon",
2769
3027
  children: jsx("i", {
@@ -2837,23 +3095,7 @@ const SearchInput = ({
2837
3095
  });
2838
3096
  };
2839
3097
 
2840
- function debounce$1(func, wait) {
2841
- let timeout;
2842
- return function () {
2843
- const context = this;
2844
- const args = arguments;
2845
-
2846
- const later = function later() {
2847
- timeout = null;
2848
- func.apply(context, args);
2849
- };
2850
-
2851
- clearTimeout(timeout);
2852
- timeout = setTimeout(later, wait);
2853
- };
2854
- }
2855
-
2856
- const initialState$1 = {
3098
+ const initialState$2 = {
2857
3099
  page: 0,
2858
3100
  items: undefined,
2859
3101
  loading: false,
@@ -2863,8 +3105,8 @@ const SearchInputList = ({
2863
3105
  onChange,
2864
3106
  error,
2865
3107
  errorZoneClassName,
2866
- traversal: _traversal = null,
2867
- path: _path = null,
3108
+ traversal,
3109
+ path: _path = undefined,
2868
3110
  qs: _qs = [],
2869
3111
  queryCondition: _queryCondition = 'id__in',
2870
3112
  value,
@@ -2872,12 +3114,12 @@ const SearchInputList = ({
2872
3114
  dataTestWrapper: _dataTestWrapper = 'wrapperSearchInputTest',
2873
3115
  dataTestSearchInput: _dataTestSearchInput = 'searchInputTest',
2874
3116
  dataTestItem: _dataTestItem = 'searchInputItemTest',
2875
- renderTextItemOption: _renderTextItemOption = null,
2876
- typeNameQuery: _typeNameQuery = null,
3117
+ renderTextItemOption: _renderTextItemOption = undefined,
3118
+ typeNameQuery: _typeNameQuery = undefined,
2877
3119
  labelProperty: _labelProperty = 'id'
2878
3120
  }) => {
2879
3121
  const intl = useIntl();
2880
- const [options, setOptions] = useSetState(initialState$1);
3122
+ const [options, setOptions] = useSetState(initialState$2);
2881
3123
  const [valuesLabel, setValuesLabels] = useState(undefined);
2882
3124
  const [isOpen, setIsOpen] = useState(false);
2883
3125
  const [searchTerm, setSearchTerm] = useState('');
@@ -2905,7 +3147,7 @@ const SearchInputList = ({
2905
3147
  };
2906
3148
  };
2907
3149
 
2908
- const delayedQuery = useCallback(debounce$1(value => handleSearch(0, false, value), 500), []);
3150
+ const delayedQuery = useCallback(debounce(value => handleSearch(0, false, value), 500), []);
2909
3151
 
2910
3152
  const handleSearch = async (page = 0, concat = false, value = '') => {
2911
3153
  var _data$items_total;
@@ -2922,16 +3164,14 @@ const SearchInputList = ({
2922
3164
 
2923
3165
  const {
2924
3166
  get
2925
- } = _traversal.registry;
3167
+ } = traversal.registry;
2926
3168
  const fnName = get('searchEngineQueryParamsFunction', SearchEngine);
2927
-
2928
- const qsParsed = _traversal.client[fnName]({
2929
- path: _traversal.path,
3169
+ const qsParsed = traversal.client.getQueryParamsSearchFunction(fnName)({
3170
+ path: traversal.path,
2930
3171
  start: page * PageSize,
2931
3172
  pageSize: PageSize,
2932
3173
  withDepth: false
2933
3174
  });
2934
-
2935
3175
  const sortParsed = parser(`_sort_des=${_labelProperty}`);
2936
3176
  let typeNameParsed = [];
2937
3177
 
@@ -2943,7 +3183,7 @@ const SearchInputList = ({
2943
3183
  searchTermQs = buildQs([..._qs, ...searchTermParsed, ...qsParsed, ...typeNameParsed, ...sortParsed]);
2944
3184
  }
2945
3185
 
2946
- const data = await _traversal.client.search(_path ? _path : _traversal.client.getContainerFromPath(_traversal.path), searchTermQs, false, false);
3186
+ const data = await traversal.client.search(_path ? _path : traversal.client.getContainerFromPath(traversal.path), searchTermQs, false, false);
2947
3187
  const newItems = options.items && concat ? [...options.items, ...data.items] : data.items;
2948
3188
  setOptions({
2949
3189
  items: newItems != null ? newItems : [],
@@ -2960,16 +3200,14 @@ const SearchInputList = ({
2960
3200
  const searchTermParsed = ['__or', `id=${value.join('%26id=')}`];
2961
3201
  const {
2962
3202
  get: getSearch
2963
- } = _traversal.registry;
3203
+ } = traversal.registry;
2964
3204
  const fnName = getSearch('searchEngineQueryParamsFunction', SearchEngine);
2965
-
2966
- const qsParsed = _traversal.client[fnName]({
2967
- path: _traversal.path,
3205
+ const qsParsed = traversal.client.getQueryParamsSearchFunction(fnName)({
3206
+ path: traversal.path,
2968
3207
  start: 0,
2969
3208
  pageSize: 100,
2970
3209
  withDepth: false
2971
3210
  });
2972
-
2973
3211
  let typeNameParsed = [];
2974
3212
 
2975
3213
  if (_typeNameQuery) {
@@ -2980,9 +3218,9 @@ const SearchInputList = ({
2980
3218
  searchTermQs = buildQs([..._qs, searchTermParsed, ...qsParsed, ...typeNameParsed]);
2981
3219
  }
2982
3220
 
2983
- const data = await _traversal.client.search(_path ? _path : _traversal.client.getContainerFromPath(_traversal.path), searchTermQs, false, false, 0, 100);
3221
+ const data = await traversal.client.search(_path ? _path : traversal.client.getContainerFromPath(traversal.path), searchTermQs, false, false);
2984
3222
  const newValuesLabel = data.items.reduce((result, item) => {
2985
- result[item.id] = get$1(item, _labelProperty, item.id);
3223
+ result[item.id] = get(item, _labelProperty, item.id);
2986
3224
  return result;
2987
3225
  }, {});
2988
3226
  setValuesLabels(newValuesLabel);
@@ -2995,7 +3233,7 @@ const SearchInputList = ({
2995
3233
  return _renderTextItemOption(item);
2996
3234
  }
2997
3235
 
2998
- return get$1(item, _labelProperty, item.title) || item['@name'];
3236
+ return get(item, _labelProperty, item.title) || item['@name'];
2999
3237
  };
3000
3238
 
3001
3239
  useEffect(() => {
@@ -3017,7 +3255,7 @@ const SearchInputList = ({
3017
3255
  className: "tags mb-2",
3018
3256
  children: value.map((tag, index) => jsxs("div", {
3019
3257
  className: "tag is-info is-medium",
3020
- children: [get$1(valuesLabel, tag, tag), jsx("button", {
3258
+ children: [get(valuesLabel, tag, tag), jsx("button", {
3021
3259
  className: "delete is-small",
3022
3260
  onClick: ev => {
3023
3261
  ev.stopPropagation();
@@ -3034,7 +3272,7 @@ const SearchInputList = ({
3034
3272
  if (!ev.currentTarget.contains(ev.relatedTarget)) {
3035
3273
  if (searchTerm !== '') {
3036
3274
  setSearchTerm('');
3037
- setOptions(initialState$1);
3275
+ setOptions(initialState$2);
3038
3276
  }
3039
3277
 
3040
3278
  setIsOpen(false);
@@ -3097,7 +3335,7 @@ const SearchInputList = ({
3097
3335
 
3098
3336
  if (onChange && !value.includes(item.id)) {
3099
3337
  setValuesLabels(_extends({}, valuesLabel, {
3100
- [item.id]: get$1(item, _labelProperty, item.id)
3338
+ [item.id]: get(item, _labelProperty, item.id)
3101
3339
  }));
3102
3340
  onChange([...value, item.id]);
3103
3341
  }
@@ -3262,7 +3500,7 @@ function EditableField({
3262
3500
  ref.current.focus();
3263
3501
  }
3264
3502
  });
3265
- const canModified = modifyContent && !get$1(schema, 'readonly', false);
3503
+ const canModified = schema !== undefined && modifyContent && !get(schema, 'readonly', false);
3266
3504
 
3267
3505
  const saveField = async ev => {
3268
3506
  if (ev) ev.preventDefault();
@@ -3320,6 +3558,8 @@ function EditableField({
3320
3558
  };
3321
3559
 
3322
3560
  const deleteField = async ev => {
3561
+ var _schema$items;
3562
+
3323
3563
  if (ev) ev.preventDefault();
3324
3564
 
3325
3565
  if ((schema == null ? void 0 : schema.widget) === 'file') {
@@ -3353,7 +3593,7 @@ function EditableField({
3353
3593
  Ctx.refresh();
3354
3594
  } else if ((schema == null ? void 0 : schema.type) === 'string' && schema != null && schema.enum) {
3355
3595
  setValue(null);
3356
- } else if ((schema == null ? void 0 : schema.type) === 'array' && (schema == null ? void 0 : schema.items.type) === 'string') {
3596
+ } else if ((schema == null ? void 0 : schema.type) === 'array' && (schema == null ? void 0 : (_schema$items = schema.items) == null ? void 0 : _schema$items.type) === 'string') {
3357
3597
  setValue([]);
3358
3598
  }
3359
3599
  };
@@ -3404,7 +3644,7 @@ function EditableField({
3404
3644
  dataTest: "editableFieldBtnCancelTest",
3405
3645
  children: intl.formatMessage(genericMessages.cancel)
3406
3646
  })
3407
- }), !required && fieldHaveDeleteButton(schema) && jsx("div", {
3647
+ }), !required && schema && fieldHaveDeleteButton(schema) && jsx("div", {
3408
3648
  className: "control",
3409
3649
  children: jsx(Button, {
3410
3650
  className: "is-small is-danger",
@@ -3435,7 +3675,8 @@ const DownloadField = ({
3435
3675
  const blob = new Blob([text], {
3436
3676
  type: data.content_type
3437
3677
  });
3438
- const url = window.URL.createObjectURL(blob);
3678
+ const url = window.URL.createObjectURL(blob); // Create blob link to download
3679
+
3439
3680
  const link = document.createElement('a');
3440
3681
  link.href = url;
3441
3682
 
@@ -3450,6 +3691,7 @@ const DownloadField = ({
3450
3691
  setTimeout(function () {
3451
3692
  var _link$parentNode;
3452
3693
 
3694
+ // For Firefox it is necessary to delay revoking the ObjectURL
3453
3695
  window.URL.revokeObjectURL(url);
3454
3696
  (_link$parentNode = link.parentNode) == null ? void 0 : _link$parentNode.removeChild(link);
3455
3697
  }, 100);
@@ -3511,19 +3753,23 @@ function RenderField({
3511
3753
  }
3512
3754
 
3513
3755
  if (type === 'object') {
3756
+ var _schema$properties;
3757
+
3514
3758
  if (Array.isArray(value)) {
3515
- return value.map(item => jsx("div", {
3759
+ return value.map((item, index) => jsx("div", {
3516
3760
  children: jsx(RenderField, {
3517
3761
  value: item
3518
3762
  })
3519
- }, item));
3763
+ }, `renderField_${index}_${schema == null ? void 0 : schema.title}`));
3520
3764
  }
3521
3765
 
3522
- return Object.keys(value).map(key => jsx(FieldValue, {
3523
- field: get$1(schema, `properties.${key}.title`, key),
3524
- schema: get$1(schema, `properties.${key}`, {}),
3525
- value: value[key]
3526
- }, key));
3766
+ if ((schema == null ? void 0 : (_schema$properties = schema.properties) == null ? void 0 : _schema$properties.key) !== undefined) {
3767
+ return Object.keys(value).map(key => jsx(FieldValue, {
3768
+ field: get(schema, `properties.${key}.title`, key),
3769
+ schema: schema.properties.key,
3770
+ value: get(value, key, {})
3771
+ }, key));
3772
+ }
3527
3773
  }
3528
3774
 
3529
3775
  return jsxs("p", {
@@ -3567,6 +3813,7 @@ const SearchRenderField = ({
3567
3813
  value,
3568
3814
  modifyContent
3569
3815
  }) => {
3816
+ console.log('search render fields');
3570
3817
  const intl = useIntl();
3571
3818
  const [valuesLabels, setValuesLabels] = useState([]);
3572
3819
  const [isLoadingData, setIsLoadingData] = useState(false);
@@ -3584,7 +3831,7 @@ const SearchRenderField = ({
3584
3831
  get: getSearch
3585
3832
  } = traversal.registry;
3586
3833
  const fnName = getSearch('searchEngineQueryParamsFunction', SearchEngine);
3587
- const qsParsed = traversal.client[fnName]({
3834
+ const qsParsed = traversal.client.getQueryParamsSearchFunction(fnName)({
3588
3835
  path: traversal.path,
3589
3836
  start: 0,
3590
3837
  pageSize: 100,
@@ -3595,23 +3842,25 @@ const SearchRenderField = ({
3595
3842
  searchTermQs = buildQs([searchTermParsed, ...qsParsed]);
3596
3843
  }
3597
3844
 
3598
- const data = await traversal.client.search(traversal.client.getContainerFromPath(traversal.path), searchTermQs, false, false, 0, 100);
3845
+ const data = await traversal.client.search(traversal.client.getContainerFromPath(traversal.path), searchTermQs, false, false);
3599
3846
  const newValuesLabel = data.items.map(item => {
3600
3847
  var _schema$labelProperty;
3601
3848
 
3602
- return get$1(item, (_schema$labelProperty = schema == null ? void 0 : schema.labelProperty) != null ? _schema$labelProperty : 'title', item.id);
3849
+ return get(item, (_schema$labelProperty = schema == null ? void 0 : schema.labelProperty) != null ? _schema$labelProperty : 'title', item.id);
3603
3850
  });
3604
3851
  setValuesLabels(newValuesLabel);
3605
3852
  setIsLoadingData(false);
3606
3853
  };
3607
3854
 
3608
- let valuesToSearch = value;
3855
+ let valuesToSearch = [];
3609
3856
 
3610
- if (typeof valuesToSearch === 'string') {
3611
- valuesToSearch = [valuesToSearch];
3857
+ if (typeof value === 'string' && value) {
3858
+ valuesToSearch = [value];
3859
+ } else if (Array.isArray(value)) {
3860
+ valuesToSearch = value;
3612
3861
  }
3613
3862
 
3614
- if (valuesToSearch !== undefined && valuesToSearch.length > 0) {
3863
+ if (valuesToSearch.length > 0) {
3615
3864
  fetchData(valuesToSearch);
3616
3865
  } else {
3617
3866
  setValuesLabels([]);
@@ -3647,7 +3896,7 @@ const VocabularyRenderField = ({
3647
3896
 
3648
3897
  const intl = useIntl();
3649
3898
  const DEFAULT_VALUE_EDITABLE_FIELD = getDefaultValueEditableField(intl);
3650
- const vocabularyName = (schema == null ? void 0 : (_schema$items = schema.items) == null ? void 0 : _schema$items.vocabularyName) || (schema == null ? void 0 : schema.vocabularyName);
3899
+ const vocabularyName = (schema == null ? void 0 : (_schema$items = schema.items) == null ? void 0 : _schema$items.vocabularyName) || (schema == null ? void 0 : schema.vocabularyName) || '';
3651
3900
  const vocabulary = useVocabulary(vocabularyName);
3652
3901
 
3653
3902
  const getRenderProps = () => {
@@ -3658,7 +3907,7 @@ const VocabularyRenderField = ({
3658
3907
  if (schema != null && schema.vocabularyName) {
3659
3908
  var _vocabularyValue$titl;
3660
3909
 
3661
- const vocabularyValue = get$1(vocabulary, 'data.items', []).find(item => item.token === value);
3910
+ const vocabularyValue = get(vocabulary, 'data.items', []).find(item => item.token === value);
3662
3911
  renderProps['value'] = (_vocabularyValue$titl = vocabularyValue == null ? void 0 : vocabularyValue.title) != null ? _vocabularyValue$titl : '';
3663
3912
  } else {
3664
3913
  var _renderProps$value;
@@ -3666,7 +3915,7 @@ const VocabularyRenderField = ({
3666
3915
  renderProps['value'] = ((_renderProps$value = renderProps['value']) != null ? _renderProps$value : []).map(value => {
3667
3916
  var _get$find$title, _get$find;
3668
3917
 
3669
- return (_get$find$title = (_get$find = get$1(vocabulary, 'data.items', []).find(item => item.token === value)) == null ? void 0 : _get$find.title) != null ? _get$find$title : '';
3918
+ return (_get$find$title = (_get$find = get(vocabulary, 'data.items', []).find(item => item.token === value)) == null ? void 0 : _get$find.title) != null ? _get$find$title : '';
3670
3919
  });
3671
3920
  }
3672
3921
 
@@ -3741,7 +3990,7 @@ const EditComponent = forwardRef(({
3741
3990
  queryCondition: schema != null && schema.queryCondition ? schema.queryCondition : 'title__in',
3742
3991
  path: schema.queryPath,
3743
3992
  labelProperty: schema != null && schema.labelProperty ? schema.labelProperty : 'title',
3744
- typeNameQuery: schema != null && schema.typeNameQuery ? schema.typeNameQuery : null
3993
+ typeNameQuery: schema == null ? void 0 : schema.typeNameQuery
3745
3994
  })]
3746
3995
  });
3747
3996
  } else if ((schema == null ? void 0 : schema.widget) === 'search') {
@@ -3756,7 +4005,7 @@ const EditComponent = forwardRef(({
3756
4005
  queryCondition: schema != null && schema.queryCondition ? schema.queryCondition : 'title__in',
3757
4006
  path: schema.queryPath,
3758
4007
  labelProperty: schema != null && schema.labelProperty ? schema.labelProperty : 'title',
3759
- typeNameQuery: schema != null && schema.typeNameQuery ? schema.typeNameQuery : null
4008
+ typeNameQuery: schema == null ? void 0 : schema.typeNameQuery
3760
4009
  })]
3761
4010
  });
3762
4011
  } else if ((schema == null ? void 0 : schema.widget) === 'textarea' || (schema == null ? void 0 : schema.widget) === 'richtext') {
@@ -3782,7 +4031,7 @@ const EditComponent = forwardRef(({
3782
4031
 
3783
4032
  if (schema.items.vocabularyName) {
3784
4033
  return jsx(SelectVocabulary, {
3785
- vocabularyName: get$1(schema, 'items.vocabularyName', null),
4034
+ vocabularyName: get(schema, 'items.vocabularyName', ''),
3786
4035
  val: val || [],
3787
4036
  className: className,
3788
4037
  classWrap: "is-fullwidth",
@@ -3819,18 +4068,21 @@ const EditComponent = forwardRef(({
3819
4068
  }), jsx(InputList, {
3820
4069
  value: val || [],
3821
4070
  className: className,
3822
- onChange: ev => setValue(ev),
4071
+ onChange: val => setValue(val),
3823
4072
  ref: ref,
3824
4073
  dataTest: dataTest
3825
4074
  })]
3826
4075
  });
3827
4076
  } else if ((schema == null ? void 0 : schema.widget) === 'file') {
4077
+ const value = val;
3828
4078
  return jsx(FileUpload, {
3829
4079
  onChange: ev => setValue(ev),
3830
- label: get$1(val, 'filename', null),
4080
+ label: get(value, 'filename', undefined),
3831
4081
  dataTest: dataTest
3832
4082
  });
3833
4083
  } else if ((schema == null ? void 0 : schema.widget) === 'select' && schema.type === 'string') {
4084
+ var _schema$vocabulary;
4085
+
3834
4086
  if (schema != null && schema.vocabularyName) {
3835
4087
  return jsx(SelectVocabulary, {
3836
4088
  val: val || '',
@@ -3839,7 +4091,7 @@ const EditComponent = forwardRef(({
3839
4091
  classWrap: "is-fullwidth",
3840
4092
  dataTest: dataTest,
3841
4093
  onChange: setValue,
3842
- vocabularyName: get$1(schema, 'vocabularyName', null),
4094
+ vocabularyName: get(schema, 'vocabularyName', ''),
3843
4095
  placeholder: placeholder,
3844
4096
  id: id
3845
4097
  });
@@ -3851,7 +4103,7 @@ const EditComponent = forwardRef(({
3851
4103
  appendDefault: true,
3852
4104
  classWrap: "is-fullwidth",
3853
4105
  dataTest: dataTest,
3854
- options: schema == null ? void 0 : schema.vocabulary.map(item => {
4106
+ options: ((_schema$vocabulary = schema == null ? void 0 : schema.vocabulary) != null ? _schema$vocabulary : []).map(item => {
3855
4107
  return {
3856
4108
  text: item,
3857
4109
  value: item
@@ -3867,11 +4119,12 @@ const EditComponent = forwardRef(({
3867
4119
  children: [schema.title && jsx("h4", {
3868
4120
  className: "subtitle mt-2",
3869
4121
  children: schema.title
3870
- }), Object.keys(get$1(schema, 'properties', {})).map(key => {
4122
+ }), Object.keys(get(schema, 'properties', {})).map(key => {
3871
4123
  var _subSchema$title;
3872
4124
 
3873
- const subSchema = get$1(schema, 'properties', {})[key];
3874
- const requiredFields = get$1(schema, 'required', []);
4125
+ const subSchema = get(schema, `properties.${key}`, null);
4126
+ const requiredFields = get(schema, 'required', []);
4127
+ if (!subSchema) return null;
3875
4128
  return jsx(EditComponent, {
3876
4129
  id: `${id}[${key}]`,
3877
4130
  schema: subSchema,
@@ -3941,9 +4194,9 @@ function IAttachment({
3941
4194
  }, 1), jsx("td", {
3942
4195
  children: jsx(EditableField, {
3943
4196
  field: key,
3944
- value: values[key],
4197
+ value: values.file,
3945
4198
  ns: "guillotina.behaviors.attachment.IAttachment",
3946
- schema: properties[key],
4199
+ schema: properties.file,
3947
4200
  modifyContent: modifyContent && ['file'].includes(key)
3948
4201
  })
3949
4202
  }, 2)]
@@ -3976,6 +4229,11 @@ function IMultiAttachment({
3976
4229
 
3977
4230
  setLoading(true);
3978
4231
  setError(undefined);
4232
+
4233
+ if (!file) {
4234
+ return;
4235
+ }
4236
+
3979
4237
  const endpoint = `${Ctx.path}@upload/files/${fileKey}`;
3980
4238
  const req = await Ctx.client.upload(endpoint, file);
3981
4239
 
@@ -4032,7 +4290,7 @@ function IMultiAttachment({
4032
4290
  field: `files/${key}`,
4033
4291
  value: values['files'][key],
4034
4292
  ns: "guillotina.behaviors.attachment.IMultiAttachment.files",
4035
- schema: properties['files']['additionalProperties'],
4293
+ schema: get(properties, 'files.additionalProperties', {}),
4036
4294
  modifyContent: false
4037
4295
  }), jsx("div", {
4038
4296
  className: "ml-5",
@@ -4110,6 +4368,11 @@ function IImageAttachment({
4110
4368
  ev.preventDefault();
4111
4369
  setLoading(true);
4112
4370
  setError(undefined);
4371
+
4372
+ if (!file) {
4373
+ return;
4374
+ }
4375
+
4113
4376
  const endpoint = `${Ctx.path}@upload/image`;
4114
4377
  const req = await Ctx.client.upload(endpoint, file);
4115
4378
 
@@ -4140,7 +4403,7 @@ function IImageAttachment({
4140
4403
  }
4141
4404
  }
4142
4405
 
4143
- setFile(undefined);
4406
+ setFile(null);
4144
4407
  setLoading(false);
4145
4408
  Ctx.flash(intl.formatMessage(genericFileMessages.image_uploaded), 'success');
4146
4409
  Ctx.refresh();
@@ -4239,7 +4502,7 @@ function IMultiImageAttachment({
4239
4502
  const intl = useIntl();
4240
4503
  const cfg = useConfig();
4241
4504
  const [fileKey, setFileKey] = useState('');
4242
- const [file, setFile] = useState(null);
4505
+ const [file, setFile] = useState(undefined);
4243
4506
  const [fileKeyToDelete, setFileKeyToDelete] = useState(undefined);
4244
4507
  const [loading, setLoading] = useState(false);
4245
4508
  const [error, setError] = useState(undefined);
@@ -4259,6 +4522,11 @@ function IMultiImageAttachment({
4259
4522
 
4260
4523
  setLoading(true);
4261
4524
  setError(undefined);
4525
+
4526
+ if (!file) {
4527
+ return;
4528
+ }
4529
+
4262
4530
  const endpoint = `${Ctx.path}@upload/images/${fileKey}`;
4263
4531
  const req = await Ctx.client.upload(endpoint, file);
4264
4532
 
@@ -4336,7 +4604,7 @@ function IMultiImageAttachment({
4336
4604
  field: `images/${key}`,
4337
4605
  value: values['images'][key],
4338
4606
  ns: "guillotina.contrib.image.behaviors.IMultiImageAttachment.images",
4339
- schema: properties['images']['additionalProperties'],
4607
+ schema: get(properties, 'images.additionalProperties', {}),
4340
4608
  modifyContent: false,
4341
4609
  required: false
4342
4610
  }), jsx("div", {
@@ -4452,7 +4720,7 @@ function IMultiImageOrderedAttachment({
4452
4720
  const intl = useIntl();
4453
4721
  const cfg = useConfig();
4454
4722
  const [sortedList, setSortedList] = useState(Object.keys(values['images']));
4455
- const [file, setFile] = useState(null);
4723
+ const [file, setFile] = useState(undefined);
4456
4724
  const [fileKeyToDelete, setFileKeyToDelete] = useState(undefined);
4457
4725
  const [loading, setLoading] = useState(false);
4458
4726
  const [error, setError] = useState(undefined);
@@ -4582,7 +4850,7 @@ function IMultiImageOrderedAttachment({
4582
4850
  field: `images/${key}`,
4583
4851
  value: values['images'][key],
4584
4852
  ns: "guillotina.contrib.image.behaviors.IMultiImageAttachment.images",
4585
- schema: properties['images']['additionalProperties'],
4853
+ schema: get(properties, 'images.additionalProperties', {}),
4586
4854
  modifyContent: false,
4587
4855
  required: false
4588
4856
  }), jsx("div", {
@@ -4632,138 +4900,6 @@ function IMultiImageOrderedAttachment({
4632
4900
  });
4633
4901
  }
4634
4902
 
4635
- const base = {
4636
- local: {
4637
- roleperm: {},
4638
- prinperm: {},
4639
- prinrole: {}
4640
- },
4641
- inherit: []
4642
- };
4643
- class Sharing {
4644
- constructor(element) {
4645
- this.local = void 0;
4646
- this.inherit = void 0;
4647
- Object.assign(this, element || base);
4648
- }
4649
-
4650
- get roles() {
4651
- return Object.keys(this.local.roleperm);
4652
- }
4653
-
4654
- getRole(role) {
4655
- return this.local.roleperm[role];
4656
- }
4657
-
4658
- get principals() {
4659
- return Object.keys(this.local.prinperm);
4660
- }
4661
-
4662
- getPrincipals(principal) {
4663
- return this.local.prinperm[principal];
4664
- }
4665
-
4666
- get prinrole() {
4667
- return Object.keys(this.local.prinrole);
4668
- }
4669
-
4670
- getPrinroles(role) {
4671
- return this.local.prinrole[role];
4672
- }
4673
-
4674
- }
4675
-
4676
- class ItemModel {
4677
- constructor(item, url = '') {
4678
- this.item = void 0;
4679
- this.url = void 0;
4680
- this.item = item;
4681
- this.url = url;
4682
- }
4683
-
4684
- get path() {
4685
- const item = this.item['@id'] ? this.item['@id'] : this.item['@absolute_url'];
4686
- let path = item.split('//')[1].split('/').splice(1).join('/');
4687
- path = `/${path}/`;
4688
-
4689
- if (this.url.length > 0) {
4690
- if (this.url.startsWith('/')) {
4691
- path = path.replace(this.url.substring(1), '');
4692
- } else {
4693
- path = path.replace(this.url, '');
4694
- }
4695
- }
4696
-
4697
- return path;
4698
- }
4699
-
4700
- get name() {
4701
- return this.item.title || this.item['@name'];
4702
- }
4703
-
4704
- get icon() {
4705
- const cfg = useConfig();
4706
-
4707
- if (cfg.icons && cfg.icons[this.type]) {
4708
- return cfg.icons[this.type];
4709
- }
4710
-
4711
- switch (this.type) {
4712
- case 'GroupManager':
4713
- return 'fas fa-users-cog';
4714
-
4715
- case 'UserManager':
4716
- return 'fas fa-user-cog';
4717
-
4718
- case 'User':
4719
- return 'fas fa-user';
4720
-
4721
- case 'Group':
4722
- return 'fas fa-users';
4723
-
4724
- case 'Folder':
4725
- return 'fas fa-folder';
4726
-
4727
- default:
4728
- return 'fas fa-file';
4729
- }
4730
- }
4731
-
4732
- get fullPath() {
4733
- return this.url + this.item.id;
4734
- }
4735
-
4736
- get id() {
4737
- if (this.item.id) {
4738
- return this.item.id;
4739
- }
4740
-
4741
- const id = this.item['@id'].split('&')[0].split('/');
4742
- return id[id.length - 1];
4743
- }
4744
-
4745
- get uid() {
4746
- return this.item['@uid'];
4747
- }
4748
-
4749
- get type() {
4750
- return this.item['@type'] || this.item.type_name;
4751
- }
4752
-
4753
- get title() {
4754
- return this.item.title;
4755
- }
4756
-
4757
- get created() {
4758
- return this.item.creation_date ? formatDate(this.item.creation_date) : '';
4759
- }
4760
-
4761
- get updated() {
4762
- return this.item.modification_date ? formatDate(this.item.modification_date) : '';
4763
- }
4764
-
4765
- }
4766
-
4767
4903
  const messages$1 = defineMessages({
4768
4904
  status_changed_ok: {
4769
4905
  id: "status_changed_ok",
@@ -4822,10 +4958,9 @@ function IWorkflow() {
4822
4958
  } = useCrudContext();
4823
4959
  const modifyContent = Ctx.hasPerm('guillotina.ModifyContent');
4824
4960
  const [definition, setDefinition] = useState(undefined);
4825
- const [workflowAction, setWorkflowAction] = useState(null);
4826
- const model = new ItemModel(Ctx.context);
4961
+ const [workflowAction, setWorkflowAction] = useState(undefined);
4827
4962
  const vocabulary = useVocabulary('workflow_states');
4828
- const currentState = model.item['guillotina.contrib.workflows.interfaces.IWorkflowBehavior']['review_state'];
4963
+ const currentState = Ctx.context['guillotina.contrib.workflows.interfaces.IWorkflowBehavior']['review_state'];
4829
4964
 
4830
4965
  async function loadDefinition() {
4831
4966
  const response = await Ctx.client.get(`${Ctx.path}/@workflow`);
@@ -4853,23 +4988,25 @@ function IWorkflow() {
4853
4988
  }
4854
4989
 
4855
4990
  Ctx.refresh();
4856
- setWorkflowAction(null);
4991
+ setWorkflowAction(undefined);
4857
4992
  };
4858
4993
 
4859
4994
  const getStateTitle = () => {
4860
- var _vocabulary$data, _vocabulary$data$item;
4995
+ var _vocabulary$data$item, _vocabulary$data;
4861
4996
 
4862
- if (((_vocabulary$data = vocabulary.data) == null ? void 0 : (_vocabulary$data$item = _vocabulary$data.items) == null ? void 0 : _vocabulary$data$item.length) > 0) {
4863
- const vocabularyValue = vocabulary.data.items.find(item => item.token === currentState);
4997
+ if (((_vocabulary$data$item = (_vocabulary$data = vocabulary.data) == null ? void 0 : _vocabulary$data.items) != null ? _vocabulary$data$item : []).length > 0) {
4998
+ var _vocabulary$data2;
4999
+
5000
+ const vocabularyValue = vocabulary == null ? void 0 : (_vocabulary$data2 = vocabulary.data) == null ? void 0 : _vocabulary$data2.items.find(item => item.token === currentState);
4864
5001
 
4865
5002
  if (vocabularyValue) {
4866
- const translatedValue = get$1(vocabularyValue, `title.translated_title.${intl.locale}`, null);
5003
+ const translatedValue = get(vocabularyValue, `title.translated_title.${intl.locale}`, null);
4867
5004
 
4868
5005
  if (translatedValue !== null) {
4869
5006
  return translatedValue;
4870
5007
  }
4871
5008
 
4872
- const titleValue = get$1(vocabularyValue, `title.title.${intl.locale}`, null);
5009
+ const titleValue = get(vocabularyValue, `title.title.${intl.locale}`, null);
4873
5010
 
4874
5011
  if (titleValue !== null) {
4875
5012
  return titleValue;
@@ -4884,7 +5021,7 @@ function IWorkflow() {
4884
5021
  return jsxs(Fragment, {
4885
5022
  children: [workflowAction && jsx(Confirm, {
4886
5023
  loading: loading,
4887
- onCancel: () => setWorkflowAction(null),
5024
+ onCancel: () => setWorkflowAction(undefined),
4888
5025
  onConfirm: doWorkflowAction,
4889
5026
  message: intl.formatMessage(messages$1.confirm_message, {
4890
5027
  title: Ctx.context.title || Ctx.context['@name']
@@ -4907,7 +5044,7 @@ function IWorkflow() {
4907
5044
  return jsx("button", {
4908
5045
  className: "button mr-4",
4909
5046
  onClick: () => setWorkflowAction(transition['@id'].split('@workflow')[1].slice(1)),
4910
- children: get$1(transition, `metadata.translated_title.${intl.locale}`, transition.title)
5047
+ children: get(transition, `metadata.translated_title.${intl.locale}`, transition.title)
4911
5048
  }, transition['@id']);
4912
5049
  })]
4913
5050
  })]
@@ -4931,14 +5068,17 @@ function PanelActions() {
4931
5068
 
4932
5069
  return jsx(Fragment$1, {
4933
5070
  children: Object.keys(ACTIONS_OBJECT).map(actionKey => {
4934
- if (hasPerm(ACTIONS_OBJECT[actionKey].perms)) {
5071
+ const actionKeyTyped = actionKey;
5072
+ const actionObject = ACTIONS_OBJECT[actionKeyTyped];
5073
+
5074
+ if (hasPerm(actionObject.perms)) {
4935
5075
  return jsx("button", {
4936
5076
  className: "button mr-4",
4937
5077
  onClick: () => {
4938
- onAction(actionKey);
5078
+ onAction(actionKeyTyped);
4939
5079
  },
4940
- children: ACTIONS_OBJECT[actionKey].text
4941
- }, `panel_action_${ACTIONS_OBJECT[actionKey].text}`);
5080
+ children: actionObject.text
5081
+ }, `panel_action_${actionObject.text}`);
4942
5082
  }
4943
5083
  })
4944
5084
  });
@@ -4966,7 +5106,8 @@ const messages$2 = defineMessages({
4966
5106
  "value": "Installed Addons"
4967
5107
  }]
4968
5108
  }
4969
- });
5109
+ }); // TODO: Refactor without useAsync... just crudContext
5110
+
4970
5111
  function PanelAddons() {
4971
5112
  var _state$data$available, _state$data, _state$data$available2, _state$data2, _state$data$installed, _state$data3, _state$data$installed2, _state$data4;
4972
5113
 
@@ -5079,8 +5220,9 @@ const prepareData = result => {
5079
5220
  };
5080
5221
 
5081
5222
  const arrayToObject = array => array.reduce((obj, item) => {
5082
- obj[item.id] = item;
5083
- return obj;
5223
+ return _extends({}, obj, {
5224
+ [item.id]: item
5225
+ });
5084
5226
  }, {});
5085
5227
 
5086
5228
  function PanelBehaviors() {
@@ -5215,8 +5357,9 @@ function ItemsActionsProvider({
5215
5357
 
5216
5358
  function onSelectAllItems(checked) {
5217
5359
  setSelected(items.reduce((obj, item) => {
5218
- obj[`${item.path}/${item.id}`] = checked;
5219
- return obj;
5360
+ return _extends({}, obj, {
5361
+ [`${item.path}/${item.id}`]: checked
5362
+ });
5220
5363
  }, {
5221
5364
  all: checked
5222
5365
  }));
@@ -5245,13 +5388,39 @@ function ItemsActionsProvider({
5245
5388
  children: children
5246
5389
  });
5247
5390
  }
5391
+
5392
+ const useItemsActions = () => {
5393
+ const {
5394
+ onAction,
5395
+ onSelectOneItem,
5396
+ onSelectAllItems,
5397
+ selected
5398
+ } = useContext(ItemsActionsCtx);
5399
+
5400
+ if (!onAction || !onSelectOneItem || !onSelectAllItems || !selected) {
5401
+ throw new Error('useItemsActions must be used inside ItemsActionsProvider');
5402
+ }
5403
+
5404
+ return {
5405
+ onAction,
5406
+ onSelectOneItem,
5407
+ onSelectAllItems,
5408
+ selected
5409
+ };
5410
+ };
5411
+ /**
5412
+ * Checkbox component without props that consume the ItemsActionsContext
5413
+ * and it select/unselect all items of the page.
5414
+ */
5415
+
5416
+
5248
5417
  function AllItemsCheckbox({
5249
5418
  dataTest
5250
5419
  }) {
5251
5420
  const {
5252
5421
  onSelectAllItems,
5253
5422
  selected
5254
- } = useContext(ItemsActionsCtx);
5423
+ } = useItemsActions();
5255
5424
  return jsx(Checkbox, {
5256
5425
  onChange: onSelectAllItems,
5257
5426
  checked: selected.all,
@@ -5265,7 +5434,7 @@ function ItemCheckbox({
5265
5434
  const {
5266
5435
  selected,
5267
5436
  onSelectOneItem
5268
- } = useContext(ItemsActionsCtx);
5437
+ } = useItemsActions();
5269
5438
  const absId = `${item.path}/${item.id}`;
5270
5439
  const value = selected[absId];
5271
5440
  return jsx(Checkbox, {
@@ -5274,6 +5443,10 @@ function ItemCheckbox({
5274
5443
  dataTest: dataTest
5275
5444
  });
5276
5445
  }
5446
+ /**
5447
+ * Dropdown to choose some action to apply to the selected items.
5448
+ */
5449
+
5277
5450
  function ItemsActionsDropdown() {
5278
5451
  const intl = useIntl();
5279
5452
  const ACTIONS_OBJECT = getActionsObject(intl, true);
@@ -5281,7 +5454,7 @@ function ItemsActionsDropdown() {
5281
5454
  const {
5282
5455
  selected,
5283
5456
  onAction
5284
- } = useContext(ItemsActionsCtx);
5457
+ } = useItemsActions();
5285
5458
  const disabled = Object.values(selected).every(v => !v);
5286
5459
  const options = Object.keys(ACTIONS_OBJECT).map(action => ({
5287
5460
  text: ACTIONS_OBJECT[action].text,
@@ -5307,75 +5480,216 @@ function ItemsActionsDropdown() {
5307
5480
  });
5308
5481
  }
5309
5482
 
5310
- function Pagination({
5311
- current,
5312
- total,
5313
- doPaginate,
5314
- pager
5315
- }) {
5316
- const intl = useIntl();
5317
- const maxPages = Math.ceil(total / pager);
5483
+ function Pagination({
5484
+ current,
5485
+ total,
5486
+ doPaginate,
5487
+ pager
5488
+ }) {
5489
+ const intl = useIntl();
5490
+ const maxPages = Math.ceil(total / pager);
5491
+
5492
+ if (maxPages <= 1) {
5493
+ return null;
5494
+ }
5495
+
5496
+ return jsxs("div", {
5497
+ children: [jsx("p", {
5498
+ className: "level-right has-text-grey is-size-7",
5499
+ children: jsx("span", {
5500
+ children: intl.formatMessage({
5501
+ id: "pagination",
5502
+ defaultMessage: [{
5503
+ "type": 1,
5504
+ "value": "currentPage"
5505
+ }, {
5506
+ "type": 0,
5507
+ "value": " / "
5508
+ }, {
5509
+ "type": 1,
5510
+ "value": "totalPages"
5511
+ }, {
5512
+ "type": 0,
5513
+ "value": " of "
5514
+ }, {
5515
+ "type": 1,
5516
+ "value": "totalItems"
5517
+ }, {
5518
+ "type": 0,
5519
+ "value": " items"
5520
+ }]
5521
+ }, {
5522
+ currentPage: current + 1,
5523
+ totalPages: maxPages,
5524
+ totalItems: total
5525
+ })
5526
+ })
5527
+ }), jsxs("nav", {
5528
+ className: "pagination is-size-7",
5529
+ role: "navigation",
5530
+ "aria-label": "pagination",
5531
+ children: [jsx("a", {
5532
+ className: "pagination-previous is-small",
5533
+ // disabled={current === 0}
5534
+ onClick: () => current > 0 ? doPaginate(current - 1) : null,
5535
+ children: jsx("span", {
5536
+ className: "icon",
5537
+ children: jsx("i", {
5538
+ className: "fas fa-arrow-left"
5539
+ })
5540
+ })
5541
+ }), jsx("a", {
5542
+ className: "pagination-next is-small",
5543
+ // disabled={current >= maxPages - 1}
5544
+ onClick: () => doPaginate(current + 1),
5545
+ children: jsx("span", {
5546
+ className: "icon",
5547
+ children: jsx("i", {
5548
+ className: "fas fa-arrow-right"
5549
+ })
5550
+ })
5551
+ })]
5552
+ })]
5553
+ });
5554
+ }
5555
+
5556
+ const base = {
5557
+ local: {
5558
+ roleperm: {},
5559
+ prinperm: {},
5560
+ prinrole: {}
5561
+ },
5562
+ inherit: []
5563
+ };
5564
+ class Sharing {
5565
+ constructor(element) {
5566
+ this.local = void 0;
5567
+ this.inherit = void 0;
5568
+
5569
+ if (element === undefined) {
5570
+ throw new Error('Sharing element is undefined');
5571
+ }
5572
+
5573
+ this.local = element.local || base.local;
5574
+ this.inherit = element.inherit || base.inherit;
5575
+ }
5576
+
5577
+ get roles() {
5578
+ return Object.keys(this.local.roleperm);
5579
+ }
5580
+
5581
+ getRole(role) {
5582
+ return this.local.roleperm[role];
5583
+ }
5584
+
5585
+ get principals() {
5586
+ return Object.keys(this.local.prinperm);
5587
+ }
5588
+
5589
+ getPrincipals(principal) {
5590
+ return this.local.prinperm[principal];
5591
+ }
5592
+
5593
+ get prinrole() {
5594
+ return Object.keys(this.local.prinrole);
5595
+ }
5596
+
5597
+ getPrinroles(role) {
5598
+ return this.local.prinrole[role];
5599
+ }
5600
+
5601
+ }
5602
+
5603
+ class ItemModel {
5604
+ constructor(item, url = '') {
5605
+ this.item = void 0;
5606
+ this.url = void 0;
5607
+ this.item = item;
5608
+ this.url = url;
5609
+ }
5610
+
5611
+ get path() {
5612
+ // Compat
5613
+ const item = this.item['@id'] ? this.item['@id'] : this.item['@absolute_url'];
5614
+ let path = item.split('//')[1].split('/').splice(1).join('/');
5615
+ path = `/${path}/`;
5616
+
5617
+ if (this.url.length > 0) {
5618
+ if (this.url.startsWith('/')) {
5619
+ path = path.replace(this.url.substring(1), '');
5620
+ } else {
5621
+ path = path.replace(this.url, '');
5622
+ }
5623
+ }
5624
+
5625
+ return path;
5626
+ }
5627
+
5628
+ get name() {
5629
+ return this.item.title || this.item['@name'];
5630
+ }
5631
+
5632
+ get icon() {
5633
+ const cfg = useConfig();
5634
+
5635
+ if (cfg.icons && cfg.icons[this.type]) {
5636
+ return cfg.icons[this.type];
5637
+ }
5638
+
5639
+ switch (this.type) {
5640
+ case 'GroupManager':
5641
+ return 'fas fa-users-cog';
5642
+
5643
+ case 'UserManager':
5644
+ return 'fas fa-user-cog';
5645
+
5646
+ case 'User':
5647
+ return 'fas fa-user';
5648
+
5649
+ case 'Group':
5650
+ return 'fas fa-users';
5651
+
5652
+ case 'Folder':
5653
+ return 'fas fa-folder';
5654
+
5655
+ default:
5656
+ return 'fas fa-file';
5657
+ }
5658
+ }
5659
+
5660
+ get fullPath() {
5661
+ return this.url + this.id;
5662
+ }
5663
+
5664
+ get id() {
5665
+ if ('id' in this.item) {
5666
+ return this.item.id;
5667
+ }
5668
+
5669
+ const id = this.item['@id'].split('&')[0].split('/');
5670
+ return id[id.length - 1];
5671
+ }
5672
+
5673
+ get uid() {
5674
+ return this.item['@uid'];
5675
+ }
5676
+
5677
+ get type() {
5678
+ return this.item['@type'] || this.item.type_name;
5679
+ }
5318
5680
 
5319
- if (maxPages <= 1) {
5320
- return null;
5681
+ get title() {
5682
+ return this.item.title;
5683
+ }
5684
+
5685
+ get created() {
5686
+ return this.item.creation_date ? formatDate(this.item.creation_date) : '';
5687
+ }
5688
+
5689
+ get updated() {
5690
+ return this.item.modification_date ? formatDate(this.item.modification_date) : '';
5321
5691
  }
5322
5692
 
5323
- return jsxs("div", {
5324
- children: [jsx("p", {
5325
- className: "level-right has-text-grey is-size-7",
5326
- children: jsx("span", {
5327
- children: intl.formatMessage({
5328
- id: "pagination",
5329
- defaultMessage: [{
5330
- "type": 1,
5331
- "value": "currentPage"
5332
- }, {
5333
- "type": 0,
5334
- "value": " / "
5335
- }, {
5336
- "type": 1,
5337
- "value": "totalPages"
5338
- }, {
5339
- "type": 0,
5340
- "value": " of "
5341
- }, {
5342
- "type": 1,
5343
- "value": "totalItems"
5344
- }, {
5345
- "type": 0,
5346
- "value": " items"
5347
- }]
5348
- }, {
5349
- currentPage: current + 1,
5350
- totalPages: maxPages,
5351
- totalItems: total
5352
- })
5353
- })
5354
- }), jsxs("nav", {
5355
- className: "pagination is-size-7",
5356
- role: "navigation",
5357
- "aria-label": "pagination",
5358
- children: [jsx("a", {
5359
- className: "pagination-previous is-small",
5360
- onClick: () => current > 0 ? doPaginate(current - 1) : null,
5361
- children: jsx("span", {
5362
- className: "icon",
5363
- children: jsx("i", {
5364
- className: "fas fa-arrow-left"
5365
- })
5366
- })
5367
- }), jsx("a", {
5368
- className: "pagination-next is-small",
5369
- onClick: () => doPaginate(current + 1),
5370
- children: jsx("span", {
5371
- className: "icon",
5372
- children: jsx("i", {
5373
- className: "fas fa-arrow-right"
5374
- })
5375
- })
5376
- })]
5377
- })]
5378
- });
5379
5693
  }
5380
5694
 
5381
5695
  function Item({
@@ -5496,11 +5810,11 @@ function SearchOptionsLabels({
5496
5810
  }) {
5497
5811
  const [location,, del] = useLocation();
5498
5812
  const [renderValue, setRenderValue] = useState(undefined);
5499
- const defaultRenderValue = location.get(query);
5813
+ const defaultRenderValue = location.get(query) || '';
5500
5814
  useEffect(() => {
5501
5815
  let value = defaultRenderValue;
5502
5816
 
5503
- if ((options != null ? options : []).length > 0) {
5817
+ if (options && (options != null ? options : []).length > 0) {
5504
5818
  const option = options.find(item => item.value === value);
5505
5819
 
5506
5820
  if (option) {
@@ -5538,14 +5852,16 @@ function SearchVocabularyLabels({
5538
5852
  const [location,, del] = useLocation();
5539
5853
  const [renderValue, setRenderValue] = useState(undefined);
5540
5854
  const vocabulary = useVocabulary(vocabularyName);
5541
- const defaultRenderValue = location.get(query);
5855
+ const defaultRenderValue = location.get(query) || '';
5542
5856
  useEffect(() => {
5543
5857
  var _vocabulary$data$item, _vocabulary$data;
5544
5858
 
5545
5859
  let value = defaultRenderValue;
5546
5860
 
5547
5861
  if (((_vocabulary$data$item = vocabulary == null ? void 0 : (_vocabulary$data = vocabulary.data) == null ? void 0 : _vocabulary$data.items) != null ? _vocabulary$data$item : []).length > 0) {
5548
- const vocabularyValue = vocabulary.data.items.find(item => item.token === value);
5862
+ var _vocabulary$data2;
5863
+
5864
+ const vocabularyValue = vocabulary == null ? void 0 : (_vocabulary$data2 = vocabulary.data) == null ? void 0 : _vocabulary$data2.items.find(item => item.token === value);
5549
5865
 
5550
5866
  if (vocabularyValue) {
5551
5867
  value = vocabularyValue.title;
@@ -5575,7 +5891,7 @@ function SearchVocabularyLabels({
5575
5891
  return null;
5576
5892
  }
5577
5893
 
5578
- const initialState$2 = {
5894
+ const initialState$3 = {
5579
5895
  page: 0,
5580
5896
  items: [],
5581
5897
  loading: true,
@@ -5589,7 +5905,7 @@ function PanelItems() {
5589
5905
  } = useConfig();
5590
5906
  const intl = useIntl();
5591
5907
  const Ctx = useTraversal();
5592
- const [state, setState] = useSetState(initialState$2);
5908
+ const [state, setState] = useSetState(initialState$3);
5593
5909
  const {
5594
5910
  items,
5595
5911
  loading,
@@ -5604,7 +5920,7 @@ function PanelItems() {
5604
5920
  let page;
5605
5921
 
5606
5922
  try {
5607
- page = parseInt(location.get('page')) || 0;
5923
+ page = parseInt(location.get('page') || '0');
5608
5924
  } catch (_unused) {
5609
5925
  page = 0;
5610
5926
  }
@@ -5651,7 +5967,7 @@ function PanelItems() {
5651
5967
  let resultQueryParams = [];
5652
5968
  const resultDynamicLocation = [];
5653
5969
  filterSchema.forEach(filter => {
5654
- const itemParam = location.get(filter.attribute_key);
5970
+ const itemParam = location.get(filter.attribute_key) || '';
5655
5971
  resultDynamicLocation.push(itemParam);
5656
5972
 
5657
5973
  if (itemParam) {
@@ -5663,7 +5979,7 @@ function PanelItems() {
5663
5979
  const controller = new AbortController();
5664
5980
  if (Ctx.state.loading) return;
5665
5981
 
5666
- (async () => {
5982
+ const getData = async () => {
5667
5983
  setState({
5668
5984
  loading: true,
5669
5985
  total: Ctx.context.length
@@ -5674,14 +5990,11 @@ function PanelItems() {
5674
5990
  const fnName = get('searchEngineQueryParamsFunction', SearchEngine);
5675
5991
 
5676
5992
  if (sortParsed === undefined) {
5677
- const defaultSortValue = Ctx.registry.getDefaultSortValue(Ctx.context['@type'], {
5678
- key: 'id',
5679
- direction: 'des'
5680
- });
5993
+ const defaultSortValue = Ctx.registry.getDefaultSortValue(Ctx.context['@type']);
5681
5994
  sortParsed = parser(`_sort_${defaultSortValue.direction}=${defaultSortValue.key}`);
5682
5995
  }
5683
5996
 
5684
- const qsParsed = Ctx.client[fnName]({
5997
+ const qsParsed = Ctx.client.getQueryParamsSearchFunction(fnName)({
5685
5998
  path: Ctx.path,
5686
5999
  start: page * PageSize,
5687
6000
  pageSize: PageSize
@@ -5701,16 +6014,15 @@ function PanelItems() {
5701
6014
  const {
5702
6015
  signal
5703
6016
  } = controller;
5704
- const data = await Ctx.client.search(Ctx.path, qs, false, false, {
5705
- signal
5706
- });
6017
+ const data = await Ctx.client.search(Ctx.path, qs, false, false, signal);
5707
6018
  setState({
5708
- items: data.member,
6019
+ items: data.items,
5709
6020
  loading: false,
5710
6021
  total: data.items_count
5711
6022
  });
5712
- })();
6023
+ };
5713
6024
 
6025
+ getData();
5714
6026
  return () => {
5715
6027
  controller.abort();
5716
6028
  };
@@ -5755,12 +6067,14 @@ function PanelItems() {
5755
6067
  var _filter$values;
5756
6068
 
5757
6069
  if (filter.type === 'select' && ((_filter$values = filter.values) != null ? _filter$values : []).length > 0) {
6070
+ var _filter$values2;
6071
+
5758
6072
  return jsx(Select, {
5759
6073
  id: filter.attribute_key,
5760
6074
  placeholder: filter.label,
5761
6075
  appendDefault: true,
5762
6076
  classWrap: "is-size-7 is-fullwidth",
5763
- options: filter.values,
6077
+ options: (_filter$values2 = filter.values) != null ? _filter$values2 : [],
5764
6078
  value: location.get(filter.attribute_key) || '',
5765
6079
  dataTest: `filterInput${filter.attribute_key}`,
5766
6080
  onChange: value => {
@@ -5833,7 +6147,7 @@ function PanelItems() {
5833
6147
  const filterData = location.get(filter.attribute_key);
5834
6148
 
5835
6149
  if (filterData) {
5836
- var _filter$values2;
6150
+ var _filter$values3;
5837
6151
 
5838
6152
  if (filter.type === 'select' && filter.vocabulary) {
5839
6153
  return jsx("div", {
@@ -5842,7 +6156,7 @@ function PanelItems() {
5842
6156
  vocabularyName: filter == null ? void 0 : filter.vocabulary
5843
6157
  })
5844
6158
  }, filter.attribute_key);
5845
- } else if (filter.type === 'select' && ((_filter$values2 = filter.values) != null ? _filter$values2 : []).length > 0) {
6159
+ } else if (filter.type === 'select' && ((_filter$values3 = filter.values) != null ? _filter$values3 : []).length > 0) {
5846
6160
  return jsx("div", {
5847
6161
  children: jsx(SearchOptionsLabels, {
5848
6162
  query: filter.attribute_key,
@@ -5885,7 +6199,7 @@ function PanelItems() {
5885
6199
  className: "has-text-info is-flex is-align-items-center",
5886
6200
  children: [jsx("span", {
5887
6201
  children: column.label
5888
- }), getIcon(column.key, column.isSortable)]
6202
+ }), getIcon(column.key, !!column.isSortable)]
5889
6203
  })
5890
6204
  }, `table-col-${column.label}`)), jsx("th", {
5891
6205
  children: "\u00A0"
@@ -5894,7 +6208,7 @@ function PanelItems() {
5894
6208
  }), jsxs("tbody", {
5895
6209
  children: [items && items.map(item => jsx(RItem, {
5896
6210
  item: item,
5897
- search: search,
6211
+ search: search != null ? search : '',
5898
6212
  columns: columns
5899
6213
  }, item['@uid'])), items && items.length === 0 && jsx("tr", {
5900
6214
  children: jsx("td", {
@@ -5920,17 +6234,19 @@ function BehaviorsView({
5920
6234
  context,
5921
6235
  schema
5922
6236
  }) {
6237
+ var _context$__behaviors_;
6238
+
5923
6239
  const Ctx = useTraversal();
5924
6240
  const {
5925
6241
  getBehavior
5926
6242
  } = Ctx.registry;
5927
- const behaviors = [].concat(context.__behaviors__, context['@static_behaviors']);
6243
+ const behaviors = [...((_context$__behaviors_ = context.__behaviors__) != null ? _context$__behaviors_ : []), ...Object(context['@static_behaviors'])];
5928
6244
 
5929
- const GetBehavior = b => {
5930
- const Cls = getBehavior(b, BehaviorNotImplemented);
6245
+ const GetBehavior = behaviorName => {
6246
+ const Cls = getBehavior(behaviorName, BehaviorNotImplemented);
5931
6247
  return jsx(Cls, {
5932
- values: context[b],
5933
- properties: get$1(schema, ['definitions', b, 'properties'], {})
6248
+ values: context[behaviorName],
6249
+ properties: get(schema, ['definitions', behaviorName, 'properties'], {})
5934
6250
  });
5935
6251
  };
5936
6252
 
@@ -6007,10 +6323,14 @@ function PanelProperties() {
6007
6323
 
6008
6324
  const ignoreFields = Ctx.registry.getProperties(Ctx.context['@type']).ignoreField || cfg.properties_ignore_fields || _ignoreFields;
6009
6325
 
6010
- const properties = Object.keys((schema == null ? void 0 : (_schema$data = schema.data) == null ? void 0 : _schema$data.properties) || []).filter(key => !ignoreFields.includes(key)).map(key => ({
6011
- key,
6012
- value: schema.data.properties[key]
6013
- }));
6326
+ const properties = Object.keys((schema == null ? void 0 : (_schema$data = schema.data) == null ? void 0 : _schema$data.properties) || []).filter(key => !ignoreFields.includes(key)).map(key => {
6327
+ var _schema$data2;
6328
+
6329
+ return {
6330
+ key,
6331
+ value: schema == null ? void 0 : (_schema$data2 = schema.data) == null ? void 0 : _schema$data2.properties[key]
6332
+ };
6333
+ });
6014
6334
  useEffect(() => {
6015
6335
  async function getSchema() {
6016
6336
  if (!schema.loading && !schema.data && !schema.error) {
@@ -6018,7 +6338,7 @@ function PanelProperties() {
6018
6338
  setSchema({
6019
6339
  loading: true
6020
6340
  });
6021
- const dataJson = await Ctx.client.getTypeSchema(Ctx.path, model.type);
6341
+ const dataJson = await Ctx.client.getTypeSchema(Ctx.path, Ctx.context.type_name);
6022
6342
  setSchema({
6023
6343
  loading: false,
6024
6344
  data: dataJson
@@ -6083,7 +6403,7 @@ function PanelProperties() {
6083
6403
  }), jsx("td", {
6084
6404
  children: jsx(EditableField, {
6085
6405
  field: prop,
6086
- value: Ctx.context[prop],
6406
+ value: get(Ctx.context, prop, ''),
6087
6407
  modifyContent: false
6088
6408
  })
6089
6409
  })]
@@ -6109,7 +6429,7 @@ function PanelProperties() {
6109
6429
  key,
6110
6430
  value
6111
6431
  }) => {
6112
- var _schema$data$required, _schema$data2;
6432
+ var _schema$data$required, _schema$data3;
6113
6433
 
6114
6434
  return jsxs("tr", {
6115
6435
  children: [jsx("td", {
@@ -6120,10 +6440,10 @@ function PanelProperties() {
6120
6440
  }), jsx("td", {
6121
6441
  children: jsx(EditableField, {
6122
6442
  field: key,
6123
- value: Ctx.context[key],
6443
+ value: get(Ctx.context, key, ''),
6124
6444
  schema: value,
6125
6445
  modifyContent: modifyContent,
6126
- required: ((_schema$data$required = (_schema$data2 = schema.data) == null ? void 0 : _schema$data2.required) != null ? _schema$data$required : []).includes(key)
6446
+ required: ((_schema$data$required = (_schema$data3 = schema.data) == null ? void 0 : _schema$data3.required) != null ? _schema$data$required : []).includes(key)
6127
6447
  })
6128
6448
  })]
6129
6449
  }, 'prop' + key);
@@ -6157,12 +6477,6 @@ function PermissionPrinperm({
6157
6477
  error: undefined
6158
6478
  });
6159
6479
 
6160
- const getMultiples = (field, setter) => values => {
6161
- setter({
6162
- [field]: values
6163
- });
6164
- };
6165
-
6166
6480
  const savePermission = async () => {
6167
6481
  if (!state.principal || !state.setting || state.permission.length === 0) {
6168
6482
  setState({
@@ -6206,7 +6520,7 @@ function PermissionPrinperm({
6206
6520
  children: intl.formatMessage(genericMessages.select_principal)
6207
6521
  }), jsx(Select, {
6208
6522
  appendDefault: true,
6209
- options: principals,
6523
+ options: principals != null ? principals : [],
6210
6524
  onChange: value => setState({
6211
6525
  principal: value
6212
6526
  }),
@@ -6218,8 +6532,12 @@ function PermissionPrinperm({
6218
6532
  className: "label",
6219
6533
  children: intl.formatMessage(genericMessages.select_permissions)
6220
6534
  }), jsx(Select, {
6221
- options: permissions,
6222
- onChange: getMultiples('permission', setState),
6535
+ options: permissions != null ? permissions : [],
6536
+ onChange: values => {
6537
+ setState({
6538
+ permission: values
6539
+ });
6540
+ },
6223
6541
  size: 5,
6224
6542
  multiple: true,
6225
6543
  dataTest: "selectPermissionsTest"
@@ -6266,12 +6584,6 @@ function PermissionPrinrole({
6266
6584
  error: undefined
6267
6585
  });
6268
6586
 
6269
- const getMultiples = (field, setter) => values => {
6270
- setter({
6271
- [field]: values
6272
- });
6273
- };
6274
-
6275
6587
  const savePermission = async () => {
6276
6588
  if (!state.principal || !state.setting || state.roles.length === 0) {
6277
6589
  setState({
@@ -6315,7 +6627,7 @@ function PermissionPrinrole({
6315
6627
  children: intl.formatMessage(genericMessages.select_principal)
6316
6628
  }), jsx(Select, {
6317
6629
  appendDefault: true,
6318
- options: principals,
6630
+ options: principals != null ? principals : [],
6319
6631
  onChange: value => setState({
6320
6632
  principal: value
6321
6633
  }),
@@ -6328,7 +6640,11 @@ function PermissionPrinrole({
6328
6640
  children: intl.formatMessage(genericMessages.select_role)
6329
6641
  }), jsx(Select, {
6330
6642
  options: roles,
6331
- onChange: getMultiples('roles', setState),
6643
+ onChange: values => {
6644
+ setState({
6645
+ roles: values
6646
+ });
6647
+ },
6332
6648
  size: 5,
6333
6649
  multiple: true,
6334
6650
  dataTest: "selectRoleTest"
@@ -6375,12 +6691,6 @@ function PermissionRoleperm({
6375
6691
  error: undefined
6376
6692
  });
6377
6693
 
6378
- const getMultiples = (field, setter) => values => {
6379
- setter({
6380
- [field]: values
6381
- });
6382
- };
6383
-
6384
6694
  const savePermission = async () => {
6385
6695
  if (!state.role || !state.setting || state.permission.length === 0) {
6386
6696
  setState({
@@ -6436,8 +6746,12 @@ function PermissionRoleperm({
6436
6746
  className: "label",
6437
6747
  children: intl.formatMessage(genericMessages.select_permissions)
6438
6748
  }), jsx(Select, {
6439
- options: permissions,
6440
- onChange: getMultiples('permission', setState),
6749
+ options: permissions != null ? permissions : [],
6750
+ onChange: values => {
6751
+ setState({
6752
+ permission: values
6753
+ });
6754
+ },
6441
6755
  dataTest: "selectPermissionsTest",
6442
6756
  size: 5,
6443
6757
  multiple: true
@@ -6563,7 +6877,18 @@ function PanelPermissions() {
6563
6877
  useEffect(() => {
6564
6878
  get('@sharing');
6565
6879
  }, [reset]);
6566
- const perms = new Sharing(result);
6880
+ const perms = useMemo(() => {
6881
+ if (result) {
6882
+ return new Sharing(result);
6883
+ }
6884
+
6885
+ return null;
6886
+ }, [result]);
6887
+
6888
+ if (perms === null) {
6889
+ return null;
6890
+ }
6891
+
6567
6892
  return jsxs("div", {
6568
6893
  className: "columns",
6569
6894
  children: [!loading && jsxs("div", {
@@ -6700,12 +7025,12 @@ function AddPermission({
6700
7025
  let roles = [];
6701
7026
  const principalsData = await Ctx.client.getPrincipals(Ctx.path);
6702
7027
  const groups = principalsData.groups.map(group => ({
6703
- text: group.id,
6704
- value: group.id
7028
+ text: group['@name'],
7029
+ value: group['@name']
6705
7030
  }));
6706
7031
  const users = principalsData.users.map(user => ({
6707
- text: user.fullname || user.id,
6708
- value: user.id
7032
+ text: user.fullname || user['@name'],
7033
+ value: user['@name']
6709
7034
  }));
6710
7035
  principals = [...groups, ...users];
6711
7036
  const req = await Ctx.client.getRoles(Ctx.path);
@@ -6758,14 +7083,6 @@ const prepareAvailable = (items, already, title) => {
6758
7083
  text: `Add ${title}`
6759
7084
  };
6760
7085
  if (items.length === 0) return [];
6761
-
6762
- if (items[0] && typeof items[0] === 'string') {
6763
- return [def].concat(items.map(x => ({
6764
- value: x,
6765
- text: x
6766
- }))).filter(item => !already.includes(item.value));
6767
- }
6768
-
6769
7086
  return [def].concat(items).filter(item => !already.includes(item.value));
6770
7087
  };
6771
7088
 
@@ -6777,7 +7094,7 @@ function TagsWidget({
6777
7094
  onChange,
6778
7095
  loading
6779
7096
  }) {
6780
- const selectRef = useRef();
7097
+ const selectRef = useRef(null);
6781
7098
  const [result, setResult] = useState(items);
6782
7099
  const availableData = prepareAvailable(available || [], result, title);
6783
7100
 
@@ -6815,7 +7132,7 @@ function TagsWidget({
6815
7132
  marginBottom: '20px'
6816
7133
  },
6817
7134
  children: noData
6818
- }), available.length > 1 && jsx("li", {
7135
+ }), (available != null ? available : []).length > 1 && jsx("li", {
6819
7136
  className: "widget-list-add select is-small",
6820
7137
  children: jsx(Select, {
6821
7138
  options: availableData,
@@ -6833,12 +7150,12 @@ function TagsWidget({
6833
7150
  });
6834
7151
  }
6835
7152
 
6836
- const initialState$3 = {
6837
- types: undefined
7153
+ const initialState$4 = {
7154
+ types: []
6838
7155
  };
6839
7156
  function CreateButton() {
6840
7157
  const intl = useIntl();
6841
- const [state, setState] = useSetState(initialState$3);
7158
+ const [state, setState] = useSetState(initialState$4);
6842
7159
  const Ctx = useTraversal();
6843
7160
  const Config = useConfig();
6844
7161
  useEffect(() => {
@@ -6874,7 +7191,8 @@ function CreateButton() {
6874
7191
 
6875
7192
  if (state.types && state.types.length === 0) {
6876
7193
  return null;
6877
- }
7194
+ } // Implement some kind of filtering
7195
+
6878
7196
 
6879
7197
  return jsx(Dropdown, {
6880
7198
  id: "dropdown-menu",
@@ -6897,11 +7215,11 @@ function ContextToolbar({
6897
7215
  AddButton
6898
7216
  }) {
6899
7217
  const intl = useIntl();
6900
- const [state, setState] = useSetState(initialState$3);
7218
+ const [state, setState] = useSetState(initialState$4);
6901
7219
  const [location, setLocation, del] = useLocation();
6902
7220
  const traversal = useTraversal();
6903
7221
  const Config = useConfig();
6904
- const searchText = location.get('q');
7222
+ const searchText = location.get('q') || '';
6905
7223
  const [searchValue, setSearchValue] = useState(searchText || '');
6906
7224
  useEffect(() => {
6907
7225
  loadTypes();
@@ -6917,14 +7235,13 @@ function ContextToolbar({
6917
7235
  });
6918
7236
  }
6919
7237
 
6920
- const onSearchQuery = ev => {
6921
- const search = ev.target[0].value;
7238
+ const onSearchQuery = event => {
7239
+ event.preventDefault();
6922
7240
  setLocation({
6923
- q: search,
7241
+ q: event.currentTarget.elements.filterInput.value,
6924
7242
  tab: 'Items',
6925
7243
  page: 0
6926
7244
  });
6927
- ev.preventDefault();
6928
7245
  };
6929
7246
 
6930
7247
  const onSearchByType = typeText => {
@@ -6956,7 +7273,8 @@ function ContextToolbar({
6956
7273
  type: "text",
6957
7274
  className: "input is-size-7",
6958
7275
  placeholder: intl.formatMessage(genericMessages.search),
6959
- "data-test": "inputFilterTest"
7276
+ "data-test": "inputFilterTest",
7277
+ id: "filterInput"
6960
7278
  })
6961
7279
  }), jsx("div", {
6962
7280
  className: "control",
@@ -6981,7 +7299,7 @@ function ContextToolbar({
6981
7299
  text: item,
6982
7300
  value: item
6983
7301
  })),
6984
- onChange: onSearchByType
7302
+ onChange: value => onSearchByType(value)
6985
7303
  })
6986
7304
  }), traversal.hasPerm('guillotina.AddContent') && jsx("div", {
6987
7305
  className: "level-item",
@@ -7019,18 +7337,17 @@ function TabsPanel({
7019
7337
  fallback = FallbackTab
7020
7338
  }) {
7021
7339
  const [location, setLocation] = useLocation();
7022
-
7023
- if (location.get('tab')) {
7024
- currentTab = location.get('tab');
7025
- } else {
7026
- currentTab = currentTab || Object.keys(tabs)[0];
7027
- }
7340
+ currentTab = location.get('tab') || Object.keys(tabs)[0];
7341
+ /*if (!Object.keys(tabs).includes(currentTab)) {
7342
+ setLocation(defaultTab)
7343
+ currentTab = defaultTab
7344
+ }*/
7028
7345
 
7029
7346
  const [current, setTab] = useState(currentTab);
7030
7347
  const CurrentComp = tabs[current] || fallback;
7031
7348
  React.useEffect(() => {
7032
7349
  if (Object.keys(tabs).includes(currentTab)) {
7033
- setTab(currentTab);
7350
+ setTab(currentTab); // setLocation({tab: currentTab})
7034
7351
  }
7035
7352
  }, [currentTab, tabs]);
7036
7353
 
@@ -7085,14 +7402,14 @@ const tabsPermissions = {
7085
7402
  Behaviors: 'guillotina.ModifyContent',
7086
7403
  Permissions: 'guillotina.SeePermissions'
7087
7404
  };
7088
- function FolderCtx(props) {
7405
+ function FolderCtx() {
7089
7406
  const ctx = useTraversal();
7090
7407
  const calculated = ctx.filterTabs(tabs, tabsPermissions);
7091
- return jsx(TabsPanel, _extends({
7408
+ return jsx(TabsPanel, {
7092
7409
  tabs: calculated,
7093
7410
  currentTab: "Items",
7094
- rightToolbar: jsx(ContextToolbar, _extends({}, props))
7095
- }, props));
7411
+ rightToolbar: jsx(ContextToolbar, {})
7412
+ });
7096
7413
  }
7097
7414
 
7098
7415
  const tabs$1 = {
@@ -7106,21 +7423,22 @@ const tabsPermissions$1 = {
7106
7423
  Behaviors: 'guillotina.ModifyContent',
7107
7424
  Permissions: 'guillotina.SeePermissions'
7108
7425
  };
7109
- function ItemCtx(props) {
7426
+ function ItemCtx() {
7110
7427
  const ctx = useTraversal();
7111
7428
  const calculated = ctx.filterTabs(tabs$1, tabsPermissions$1);
7112
- return jsx(TabsPanel, _extends({
7429
+ return jsx(TabsPanel, {
7113
7430
  tabs: calculated,
7114
7431
  currentTab: "Properties"
7115
- }, props));
7432
+ });
7116
7433
  }
7117
7434
 
7118
7435
  function ApplicationCtx() {
7119
7436
  const intl = useIntl();
7120
- const context = useTraversal();
7437
+ const traversal = useTraversal();
7438
+ const appContext = traversal.state.context;
7121
7439
  const {
7122
7440
  databases
7123
- } = context.state.context;
7441
+ } = appContext;
7124
7442
  return jsxs(Fragment, {
7125
7443
  children: [jsx("h3", {
7126
7444
  children: intl.formatMessage({
@@ -7134,24 +7452,28 @@ function ApplicationCtx() {
7134
7452
  className: "container",
7135
7453
  children: [jsx(ItemTitle, {
7136
7454
  title: "Objects"
7137
- }), databases.map(db => jsx(Item, {
7138
- item: {
7139
- id: db,
7140
- path: `/${db}/`
7141
- },
7142
- icon: 'fas fa-database'
7143
- }, db))]
7455
+ }), jsx("table", {
7456
+ children: jsx("tbody", {
7457
+ children: databases.map(db => jsx(Item, {
7458
+ item: {
7459
+ id: db,
7460
+ path: `/${db}/`
7461
+ },
7462
+ icon: 'fas fa-database'
7463
+ }, db))
7464
+ })
7465
+ })]
7144
7466
  })]
7145
7467
  });
7146
7468
  }
7147
7469
  function DatabaseCtx() {
7148
- const context = useTraversal();
7470
+ const traversal = useTraversal();
7149
7471
  const {
7150
7472
  containers
7151
- } = context.state.context;
7473
+ } = traversal.state.context;
7152
7474
  const {
7153
7475
  path
7154
- } = context.state;
7476
+ } = traversal.state;
7155
7477
  return jsx(Fragment, {
7156
7478
  children: jsxs("div", {
7157
7479
  className: "container",
@@ -7409,17 +7731,17 @@ function UsersToolbar() {
7409
7731
  const [location, setLocation] = useLocation();
7410
7732
  const searchText = location.get('q');
7411
7733
 
7412
- const onSearchQuery = ev => {
7413
- const search = ev.target[0].value;
7734
+ const onSearchQuery = event => {
7735
+ event.preventDefault();
7414
7736
  setLocation({
7415
- q: search,
7737
+ q: event.currentTarget.elements.filterInput.value,
7416
7738
  page: 0
7417
7739
  });
7418
- ev.preventDefault();
7419
- };
7740
+ }; // cleanup form on state.search change
7741
+
7420
7742
 
7421
7743
  useEffect(() => {
7422
- if (!searchText || searchText === '') {
7744
+ if (ref.current && (!searchText || searchText === '')) {
7423
7745
  ref.current.value = '';
7424
7746
  }
7425
7747
  }, [searchText]);
@@ -7439,7 +7761,8 @@ function UsersToolbar() {
7439
7761
  type: "text",
7440
7762
  className: "input is-size-7",
7441
7763
  placeholder: intl.formatMessage(genericMessages.search),
7442
- "data-test": "inputFilterTest"
7764
+ "data-test": "inputFilterTest",
7765
+ id: "filterInput"
7443
7766
  })
7444
7767
  }), jsx("div", {
7445
7768
  className: "control",
@@ -7469,12 +7792,12 @@ function UsersToolbar() {
7469
7792
  })]
7470
7793
  });
7471
7794
  }
7472
- function UsersCtx(props) {
7473
- return jsx(TabsPanel, _extends({
7795
+ function UsersCtx() {
7796
+ return jsx(TabsPanel, {
7474
7797
  tabs: tabs$3,
7475
7798
  currentTab: "Users",
7476
7799
  rightToolbar: jsx(UsersToolbar, {})
7477
- }, props));
7800
+ });
7478
7801
  }
7479
7802
  function UserCtx() {
7480
7803
  const intl = useIntl();
@@ -7487,9 +7810,10 @@ function UserCtx() {
7487
7810
  roles: [],
7488
7811
  groups: []
7489
7812
  });
7813
+ const userDataContext = Ctx.context;
7490
7814
  const fields = {
7491
7815
  user_groups: [],
7492
- user_roles: Ctx.context.user_roles
7816
+ user_roles: userDataContext.user_roles
7493
7817
  };
7494
7818
  const [remotes, updateRemote] = useRemoteField(fields);
7495
7819
  useEffect(() => {
@@ -7567,7 +7891,7 @@ function UserCtx() {
7567
7891
  "value": "Username"
7568
7892
  }]
7569
7893
  }), ":", ' ']
7570
- }), ' ', Ctx.context.username, " (", Ctx.context.email, ")"]
7894
+ }), ' ', userDataContext.username, " (", userDataContext.email, ")"]
7571
7895
  }), jsxs("p", {
7572
7896
  children: [jsxs("label", {
7573
7897
  children: [' ', intl.formatMessage({
@@ -7577,7 +7901,7 @@ function UserCtx() {
7577
7901
  "value": "Creation Date"
7578
7902
  }]
7579
7903
  }), ":", ' ']
7580
- }), ' ', formatDate(Ctx.context.creation_date)]
7904
+ }), ' ', formatDate(userDataContext.creation_date)]
7581
7905
  }), jsxs("p", {
7582
7906
  children: [jsxs("label", {
7583
7907
  children: [' ', intl.formatMessage({
@@ -7587,7 +7911,7 @@ function UserCtx() {
7587
7911
  "value": "Modification Date"
7588
7912
  }]
7589
7913
  }), ":", ' ']
7590
- }), ' ', formatDate(Ctx.context.modification_date)]
7914
+ }), ' ', formatDate(userDataContext.modification_date)]
7591
7915
  }), jsx(Button, {
7592
7916
  className: "is-size-7 is-info",
7593
7917
  onClick: () => {
@@ -7604,7 +7928,7 @@ function UserCtx() {
7604
7928
  }), jsx("hr", {}), jsx(UserForm, {
7605
7929
  actionName: "Save",
7606
7930
  onSubmit: ev => updateObject(ev),
7607
- formData: Ctx.context,
7931
+ formData: userDataContext,
7608
7932
  exclude: ['password'],
7609
7933
  remotes: remotes,
7610
7934
  submitButton: false,
@@ -7618,7 +7942,7 @@ function UserCtx() {
7618
7942
  className: "column",
7619
7943
  children: [jsx(TagsWidget, {
7620
7944
  onChange: updateRemote('user_groups'),
7621
- items: Ctx.context.user_groups,
7945
+ items: userDataContext.user_groups,
7622
7946
  title: "Groups",
7623
7947
  noData: intl.formatMessage({
7624
7948
  id: "there_is_no_groups_for_this_user",
@@ -7639,7 +7963,10 @@ function UserCtx() {
7639
7963
  "value": "The user doesn't have any role"
7640
7964
  }]
7641
7965
  }),
7642
- available: state.roles
7966
+ available: state.roles.map(x => ({
7967
+ value: x,
7968
+ text: x
7969
+ }))
7643
7970
  })]
7644
7971
  })]
7645
7972
  })]
@@ -7657,7 +7984,7 @@ function CopyItems(props) {
7657
7984
  async function copyItems(path, form) {
7658
7985
  const responses = await Promise.all(items.map((item, i) => {
7659
7986
  const input = form[i + 1] || {};
7660
- return Ctx.client.post(`${Ctx.path}${item['@name']}/@duplicate`, {
7987
+ return Ctx.client.post(`${Ctx.path}${item.id}/@duplicate`, {
7661
7988
  destination: path,
7662
7989
  new_id: input.value || getNewId(item.id)
7663
7990
  });
@@ -7693,7 +8020,7 @@ function CopyItems(props) {
7693
8020
  }), jsx("input", {
7694
8021
  type: "text",
7695
8022
  className: "input",
7696
- "data-test": `inputCopyIdTest-${item['@name']}`,
8023
+ "data-test": `inputCopyIdTest-${item.id}`,
7697
8024
  defaultValue: getNewId(item.id)
7698
8025
  })]
7699
8026
  }, item.id)), "\u00A0"]
@@ -7763,9 +8090,9 @@ function MoveItems(props) {
7763
8090
 
7764
8091
  async function moveItems(path) {
7765
8092
  const responses = await Promise.all(items.map(item => {
7766
- return Ctx.client.post(`${Ctx.path}${item['@name']}/@move`, {
8093
+ return Ctx.client.post(`${Ctx.path}${item.id}/@move`, {
7767
8094
  destination: path,
7768
- new_id: item['@name']
8095
+ new_id: item.id
7769
8096
  });
7770
8097
  }));
7771
8098
  Ctx.refresh();
@@ -8054,17 +8381,17 @@ function GroupToolbar() {
8054
8381
  const [location, setLocation] = useLocation();
8055
8382
  const searchText = location.get('q');
8056
8383
 
8057
- const onSearchQuery = ev => {
8058
- const search = ev.target[0].value;
8384
+ const onSearchQuery = event => {
8385
+ event.preventDefault();
8059
8386
  setLocation({
8060
- q: search,
8387
+ q: event.currentTarget.elements.filterInput.value,
8061
8388
  page: 0
8062
8389
  });
8063
- ev.preventDefault();
8064
- };
8390
+ }; // cleanup form on state.search change
8391
+
8065
8392
 
8066
8393
  useEffect(() => {
8067
- if (!searchText || searchText === '') {
8394
+ if (ref.current && (!searchText || searchText === '')) {
8068
8395
  ref.current.value = '';
8069
8396
  }
8070
8397
  }, [searchText]);
@@ -8084,7 +8411,8 @@ function GroupToolbar() {
8084
8411
  type: "text",
8085
8412
  className: "input is-size-7",
8086
8413
  placeholder: intl.formatMessage(genericMessages.search),
8087
- "data-test": "inputFilterTest"
8414
+ "data-test": "inputFilterTest",
8415
+ id: "filterInput"
8088
8416
  })
8089
8417
  }), jsx("div", {
8090
8418
  className: "control",
@@ -8120,12 +8448,12 @@ function GroupToolbar() {
8120
8448
  })]
8121
8449
  });
8122
8450
  }
8123
- function GroupsCtx(props) {
8124
- return jsx(TabsPanel, _extends({
8451
+ function GroupsCtx() {
8452
+ return jsx(TabsPanel, {
8125
8453
  tabs: tabs$4,
8126
8454
  currentTab: "Groups",
8127
8455
  rightToolbar: jsx(GroupToolbar, {})
8128
- }, props));
8456
+ });
8129
8457
  }
8130
8458
  const sortParsed = parser(`_sort_asc=id`);
8131
8459
  const searchParsed = parser('type_name=User');
@@ -8136,6 +8464,7 @@ function GroupCtx() {
8136
8464
  patch
8137
8465
  } = useCrudContext();
8138
8466
  const [roles, setRoles] = useState([]);
8467
+ const groupDataContext = Ctx.context;
8139
8468
  useEffect(() => {
8140
8469
  async function getRoles() {
8141
8470
  const requestGetRoles = await Ctx.client.getRoles(Ctx.path);
@@ -8170,9 +8499,9 @@ function GroupCtx() {
8170
8499
  isError,
8171
8500
  errorMessage
8172
8501
  } = await patch({
8173
- user_roles: Ctx.context.user_roles.concat(role)
8502
+ user_roles: groupDataContext.user_roles.concat(role)
8174
8503
  });
8175
- handleResponse(isError, intl.formatMessage({
8504
+ handleResponse(!!isError, intl.formatMessage({
8176
8505
  id: "role_added_to_group",
8177
8506
  defaultMessage: [{
8178
8507
  "type": 0,
@@ -8186,7 +8515,7 @@ function GroupCtx() {
8186
8515
  }]
8187
8516
  }, {
8188
8517
  role
8189
- }), errorMessage);
8518
+ }), errorMessage != null ? errorMessage : '');
8190
8519
  };
8191
8520
 
8192
8521
  const removeRole = async role => {
@@ -8194,9 +8523,9 @@ function GroupCtx() {
8194
8523
  isError,
8195
8524
  errorMessage
8196
8525
  } = await patch({
8197
- user_roles: Ctx.context.user_roles.filter(r => r !== role)
8526
+ user_roles: groupDataContext.user_roles.filter(r => r !== role)
8198
8527
  });
8199
- handleResponse(isError, intl.formatMessage({
8528
+ handleResponse(!!isError, intl.formatMessage({
8200
8529
  id: "role_removed_from_group",
8201
8530
  defaultMessage: [{
8202
8531
  "type": 0,
@@ -8210,21 +8539,22 @@ function GroupCtx() {
8210
8539
  }]
8211
8540
  }, {
8212
8541
  role
8213
- }), errorMessage);
8542
+ }), errorMessage != null ? errorMessage : '');
8214
8543
  };
8215
8544
 
8216
8545
  const addUser = async newUserId => {
8217
8546
  const data = {};
8218
- Ctx.context.users.forEach(user => {
8547
+ groupDataContext.users.forEach(user => {
8219
8548
  data[user] = true;
8220
8549
  });
8221
8550
  data[newUserId] = true;
8551
+ const response = await Ctx.client.rest.patch(`${Ctx.containerPath}@groups/${Ctx.context['@name']}`, {
8552
+ users: data
8553
+ });
8222
8554
  const {
8223
8555
  isError,
8224
8556
  errorMessage
8225
- } = await Ctx.client.rest.patch(`${Ctx.containerPath}@groups/${Ctx.context['@name']}`, {
8226
- users: data
8227
- });
8557
+ } = await processResponse(response);
8228
8558
  handleResponse(isError, intl.formatMessage({
8229
8559
  id: "user_added_to_group",
8230
8560
  defaultMessage: [{
@@ -8239,20 +8569,21 @@ function GroupCtx() {
8239
8569
  }]
8240
8570
  }, {
8241
8571
  user: newUserId
8242
- }), errorMessage);
8572
+ }), errorMessage != null ? errorMessage : '');
8243
8573
  };
8244
8574
 
8245
8575
  const removeUser = async userToRemove => {
8246
8576
  const data = {};
8247
- Ctx.context.users.forEach(user => {
8577
+ groupDataContext.users.forEach(user => {
8248
8578
  data[user] = userToRemove !== user;
8249
8579
  });
8580
+ const response = await Ctx.client.rest.patch(`${Ctx.containerPath}@groups/${Ctx.context['@name']}`, {
8581
+ users: data
8582
+ });
8250
8583
  const {
8251
8584
  isError,
8252
8585
  errorMessage
8253
- } = await Ctx.client.rest.patch(`${Ctx.containerPath}@groups/${Ctx.context['@name']}`, {
8254
- users: data
8255
- });
8586
+ } = await processResponse(response);
8256
8587
  handleResponse(isError, intl.formatMessage({
8257
8588
  id: "user_removed_from_group",
8258
8589
  defaultMessage: [{
@@ -8267,7 +8598,7 @@ function GroupCtx() {
8267
8598
  }]
8268
8599
  }, {
8269
8600
  user: userToRemove
8270
- }), errorMessage);
8601
+ }), errorMessage != null ? errorMessage : '');
8271
8602
  };
8272
8603
 
8273
8604
  return jsxs("div", {
@@ -8317,10 +8648,10 @@ function GroupCtx() {
8317
8648
  }]
8318
8649
  })
8319
8650
  }), jsx(Select, {
8320
- options: roles.filter(role => !Ctx.context.user_roles.includes(role.value)),
8651
+ options: roles.filter(role => !groupDataContext.user_roles.includes(role.value)),
8321
8652
  appendDefault: true,
8322
- onChange: addRole
8323
- }), jsx("hr", {}), Ctx.context.user_roles.map(urole => jsx("p", {
8653
+ onChange: value => addRole(value)
8654
+ }), jsx("hr", {}), groupDataContext.user_roles.map(urole => jsx("p", {
8324
8655
  className: "control",
8325
8656
  children: jsx(Tag, {
8326
8657
  name: urole,
@@ -8348,7 +8679,7 @@ function GroupCtx() {
8348
8679
  traversal: Ctx,
8349
8680
  onChange: addUser,
8350
8681
  btnClass: "is-small"
8351
- }), jsx("hr", {}), Ctx.context.users.map(user => jsx("p", {
8682
+ }), jsx("hr", {}), groupDataContext.users.map(user => jsx("p", {
8352
8683
  className: "control",
8353
8684
  children: jsx(Tag, {
8354
8685
  name: user,
@@ -8479,7 +8810,7 @@ function Path() {
8479
8810
  const links = buildPaths(segments);
8480
8811
 
8481
8812
  if (segments.length === 1) {
8482
- return false;
8813
+ return null;
8483
8814
  }
8484
8815
 
8485
8816
  return jsx("nav", {
@@ -8605,11 +8936,13 @@ const get$2 = (key, param, fallback = undefined) => {
8605
8936
  };
8606
8937
 
8607
8938
  const getComponent = (context, path, fallback = undefined) => {
8608
- if (!context) return;
8939
+ if (!context) return; // console.log("Component for path", path)
8940
+ // lookup by path
8609
8941
 
8610
8942
  if (registry.paths[path]) {
8611
8943
  return registry.paths[path];
8612
- }
8944
+ } // by type
8945
+
8613
8946
 
8614
8947
  if (registry.views[context['@type']]) {
8615
8948
  return registry.views[context['@type']];
@@ -8632,11 +8965,15 @@ const getItemsColumn = type => {
8632
8965
  return undefined;
8633
8966
  };
8634
8967
 
8635
- const getForm = (type, fallback = BaseForm) => {
8636
- return registry.forms[type] || fallback;
8968
+ const getView = name => {
8969
+ return registry.views[name];
8970
+ };
8971
+
8972
+ const getForm = (type, fallback) => {
8973
+ return registry.forms[type] || fallback || BaseForm;
8637
8974
  };
8638
8975
 
8639
- const getAction = (type, fallback = undefined) => {
8976
+ const getAction = (type, fallback) => {
8640
8977
  return registry.actions[type] || fallback;
8641
8978
  };
8642
8979
 
@@ -8652,11 +8989,14 @@ const getSchemas = type => {
8652
8989
  return registry.schemas[type] || {};
8653
8990
  };
8654
8991
 
8655
- const getFieldsToFilter = (type, fallback) => {
8992
+ const getFieldsToFilter = (type, fallback = ['title']) => {
8656
8993
  return registry.fieldsToFilter[type] || fallback;
8657
8994
  };
8658
8995
 
8659
- const getDefaultSortValue = (type, fallback) => {
8996
+ const getDefaultSortValue = (type, fallback = {
8997
+ key: 'id',
8998
+ direction: 'des'
8999
+ }) => {
8660
9000
  return registry.defaultSortValue[type] || fallback;
8661
9001
  };
8662
9002
 
@@ -8664,11 +9004,15 @@ const defaultComponent = context => {
8664
9004
  return context.is_folderish ? FolderCtx : ItemCtx;
8665
9005
  };
8666
9006
  function useRegistry(data) {
9007
+ // if data is provided we need to merge it into actual registry
8667
9008
  const ref = React.useRef();
8668
9009
 
8669
9010
  if (data && !ref.current) {
8670
9011
  ref.current = true;
8671
- Object.keys(data).map(key => registry[key] = _extends({}, registry[key], data[key]));
9012
+ Object.keys(data).map(key => {
9013
+ const registryKey = key;
9014
+ registry[registryKey] = _extends({}, registry[registryKey], data[registryKey]);
9015
+ });
8672
9016
  }
8673
9017
 
8674
9018
  return {
@@ -8682,86 +9026,26 @@ function useRegistry(data) {
8682
9026
  getItemsColumn,
8683
9027
  getFieldsToFilter,
8684
9028
  getDefaultSortValue,
8685
- getSchemas
9029
+ getSchemas,
9030
+ getView
8686
9031
  };
8687
9032
  }
9033
+ /*
8688
9034
 
8689
- const initialState$4 = {
8690
- path: '',
8691
- loading: false,
8692
- context: undefined,
8693
- flash: {
8694
- message: undefined,
8695
- type: undefined
8696
- },
8697
- action: {
8698
- action: undefined,
8699
- params: undefined
9035
+ const registry = {
9036
+ paths: {
9037
+ "/db/guillotina/tags/": TagsContext
8700
9038
  },
8701
- permissions: undefined,
8702
- errorStatus: undefined,
8703
- registry: {},
8704
- refresh: undefined
8705
- };
8706
- function guillotinaReducer(state, action) {
8707
- switch (action.type) {
8708
- case 'SET_PATH':
8709
- return _extends({}, state, {
8710
- path: action.payload,
8711
- loading: true
8712
- });
8713
-
8714
- case 'SET_CONTEXT':
8715
- return _extends({}, state, action.payload, {
8716
- errorStatus: undefined,
8717
- loading: false
8718
- });
8719
-
8720
- case 'SET_ERROR':
8721
- return _extends({}, state, {
8722
- errorStatus: action.payload,
8723
- loading: false
8724
- });
8725
-
8726
- case 'SET_FLASH':
8727
- return _extends({}, state, action.payload);
8728
-
8729
- case 'CLEAR_FLASH':
8730
- return _extends({}, state, {
8731
- flash: {
8732
- message: undefined,
8733
- type: undefined
8734
- }
8735
- });
8736
-
8737
- case 'SET_ACTION':
8738
- return _extends({}, state, {
8739
- action: action.payload
8740
- });
9039
+ forms: {
9040
+ Tag: AddTagForm
9041
+ }
9042
+ }
8741
9043
 
8742
- case 'CLEAR_ACTION':
8743
- return _extends({}, state, {
8744
- action: {
8745
- action: undefined,
8746
- params: undefined
8747
- }
8748
- });
8749
9044
 
8750
- case 'REFRESH':
8751
- return _extends({}, state, {
8752
- refresh: Date.now(),
8753
- loading: !action.payload.transparent
8754
- });
9045
+ <guillotina registry={registry} />
8755
9046
 
8756
- case 'APPLY':
8757
- return _extends({}, state, {
8758
- context: _extends({}, state.context, action.payload)
8759
- });
8760
9047
 
8761
- default:
8762
- return state;
8763
- }
8764
- }
9048
+ */
8765
9049
 
8766
9050
  var actions = [
8767
9051
  {
@@ -11574,29 +11858,34 @@ function Guillotina(_ref) {
11574
11858
  props = _objectWithoutPropertiesLoose(_ref, ["auth", "locale"]);
11575
11859
 
11576
11860
  const messages = loadLocaleData(locale);
11577
- const url = props.url || 'http://localhost:8080';
11861
+ const url = props.url || 'http://localhost:8080'; // without trailing slash
11862
+
11578
11863
  const config = props.config || {};
11579
11864
  const client = useGuillotinaClient();
11580
11865
  const {
11581
11866
  Permissions
11582
11867
  } = useConfig(config);
11583
- const registry = useRegistry(props.registry || {});
11584
- const [location] = useLocation();
11868
+ const registry = useRegistry(props.registry); // Location is cooked routing solution (only uses search params)
11869
+
11870
+ const [location] = useLocation(); // if there is no path provided just go to root
11871
+
11585
11872
  const searchPath = location.get('path') || '/';
11586
11873
 
11587
11874
  if (searchPath && searchPath !== '') {
11588
- initialState$4.path = searchPath;
11875
+ initialState.path = searchPath;
11589
11876
  }
11590
11877
 
11591
- const [state, dispatch] = useReducer(guillotinaReducer, initialState$4);
11878
+ const [state, dispatch] = useReducer(guillotinaReducer, initialState);
11592
11879
  const {
11593
11880
  path,
11594
11881
  refresh
11595
11882
  } = state;
11596
11883
  useEffect(() => {
11597
11884
  dispatch({
11598
- type: 'SET_PATH',
11599
- payload: searchPath
11885
+ type: GuillotinaReducerActionTypes.SET_PATH,
11886
+ payload: {
11887
+ path: searchPath
11888
+ }
11600
11889
  });
11601
11890
  }, [searchPath]);
11602
11891
  useEffect(() => {
@@ -11605,14 +11894,18 @@ function Guillotina(_ref) {
11605
11894
 
11606
11895
  if (data.status === 401) {
11607
11896
  dispatch({
11608
- type: 'SET_ERROR',
11609
- payload: 'notallowed'
11897
+ type: GuillotinaReducerActionTypes.SET_ERROR,
11898
+ payload: {
11899
+ errorStatus: 'notallowed'
11900
+ }
11610
11901
  });
11611
11902
  return;
11612
11903
  } else if (data.status === 404) {
11613
11904
  dispatch({
11614
- type: 'SET_ERROR',
11615
- payload: 'notfound'
11905
+ type: GuillotinaReducerActionTypes.SET_ERROR,
11906
+ payload: {
11907
+ errorStatus: 'notallowed'
11908
+ }
11616
11909
  });
11617
11910
  return;
11618
11911
  }
@@ -11621,7 +11914,7 @@ function Guillotina(_ref) {
11621
11914
  const pr = await client.canido(path, Permissions);
11622
11915
  const permissions = await pr.json();
11623
11916
  dispatch({
11624
- type: 'SET_CONTEXT',
11917
+ type: GuillotinaReducerActionTypes.SET_CONTEXT,
11625
11918
  payload: {
11626
11919
  context,
11627
11920
  permissions
@@ -11631,9 +11924,9 @@ function Guillotina(_ref) {
11631
11924
 
11632
11925
  initContext();
11633
11926
  }, [path, refresh, client]);
11634
- const ErrorBoundary = registry.get('views', 'ErrorBoundary');
11635
- const NotAllowed = registry.get('views', 'NotAllowed');
11636
- const NotFound = registry.get('views', 'NotFound');
11927
+ const ErrorBoundary = registry.getView('ErrorBoundary');
11928
+ const NotAllowed = registry.getView('NotAllowed');
11929
+ const NotFound = registry.getView('NotFound');
11637
11930
  const Path = registry.get('components', 'Path');
11638
11931
  const contextData = {
11639
11932
  url,
@@ -11658,7 +11951,7 @@ function Guillotina(_ref) {
11658
11951
  children: jsxs(ErrorBoundary, {
11659
11952
  children: [!errorStatus && jsx(TraversalProvider, _extends({}, contextData, {
11660
11953
  children: permissions && jsxs(React.Fragment, {
11661
- children: [action.action && jsx(Action, _extends({}, action.params)), jsx("div", {
11954
+ children: [action.action && Action !== null && jsx(Action, _extends({}, action.params)), jsx("div", {
11662
11955
  className: "level",
11663
11956
  children: jsx("div", {
11664
11957
  className: "level-left",
@@ -11667,7 +11960,7 @@ function Guillotina(_ref) {
11667
11960
  children: jsx(Path, {})
11668
11961
  })
11669
11962
  })
11670
- }), jsx(Flash, {}), Main && jsx(ErrorBoundary, {
11963
+ }), jsx(Flash, {}), Main !== undefined && jsx(ErrorBoundary, {
11671
11964
  children: jsxs("div", {
11672
11965
  className: "box main-panel",
11673
11966
  children: [state.loading && jsx(Loading, {}), !state.loading && jsx(Main, {
@@ -11773,7 +12066,7 @@ const ERRORS = {
11773
12066
  const initialState$5 = {
11774
12067
  username: '',
11775
12068
  password: '',
11776
- loading: undefined,
12069
+ loading: false,
11777
12070
  errors: undefined
11778
12071
  };
11779
12072
  const Login = ({
@@ -11786,7 +12079,7 @@ const Login = ({
11786
12079
  const [state, setState] = useSetState(initialState$5);
11787
12080
  const inputRef = useRef(null);
11788
12081
  useEffect(() => {
11789
- if (inputRef) {
12082
+ if (inputRef && inputRef.current) {
11790
12083
  inputRef.current.focus();
11791
12084
  }
11792
12085
  }, [inputRef]);
@@ -11963,28 +12256,28 @@ function RequiredFieldsForm({
11963
12256
  dataTest: dataTest,
11964
12257
  children: [schema && schema.data && !schema.loading && schema.formFields.map(key => {
11965
12258
  if (!ignoreFiels.includes(key)) {
11966
- var _value$title;
12259
+ var _schema$data, _value$title, _schema$data2;
11967
12260
 
11968
- const value = schema.data.properties[key];
12261
+ const value = (_schema$data = schema.data) == null ? void 0 : _schema$data.properties[key];
11969
12262
  return jsx(EditComponent, {
11970
12263
  id: key,
11971
12264
  placeholder: (_value$title = value == null ? void 0 : value.title) != null ? _value$title : '',
11972
12265
  className: "",
11973
12266
  required: true,
11974
- schema: schema.data.properties[key],
11975
- setValue: ev => {
12267
+ schema: (_schema$data2 = schema.data) == null ? void 0 : _schema$data2.properties[key],
12268
+ setValue: value => {
11976
12269
  if (key === 'title') {
11977
12270
  setFormData(_extends({}, formData, {
11978
- uuid: stringToSlug(ev),
11979
- [key]: ev
12271
+ uuid: stringToSlug(value),
12272
+ [key]: value
11980
12273
  }));
11981
12274
  } else if (key === 'uuid') {
11982
12275
  setFormData(_extends({}, formData, {
11983
- uuid: stringToSlug(ev)
12276
+ uuid: stringToSlug(value)
11984
12277
  }));
11985
12278
  } else {
11986
12279
  setFormData(_extends({}, formData, {
11987
- [key]: ev
12280
+ [key]: value
11988
12281
  }));
11989
12282
  }
11990
12283
  },
@@ -12110,6 +12403,7 @@ class Auth {
12110
12403
  });
12111
12404
 
12112
12405
  if (data.status === 401) {
12406
+ // invalid token
12113
12407
  this.cleanAuth();
12114
12408
  this.logout();
12115
12409
  return;
@@ -12160,7 +12454,7 @@ class Auth {
12160
12454
 
12161
12455
  if (!authToken) return {};
12162
12456
 
12163
- if (this.willExpire(expires) && this.retryRefresh < this.maxRetry) {
12457
+ if (this.willExpire(expires != null ? expires : '') && this.retryRefresh < this.maxRetry) {
12164
12458
 
12165
12459
  (async function () {
12166
12460
  return await _this.refreshToken();
@@ -12176,5 +12470,14 @@ class Auth {
12176
12470
 
12177
12471
  }
12178
12472
 
12179
- export { AddItem, AddPermission, AllItemsCheckbox, ApplicationCtx, Auth, AuthContext, BaseForm, BehaviorNotImplemented, BehaviorsView, Button, Checkbox, ClientContext, ClientProvider, Config, Confirm, ContainerCtx, ContextToolbar, CreateButton, CreateContainer, DatabaseCtx, Delete, DownloadField, EditComponent, EditableField, EmailInput, FileUpload, Flash, FolderCtx, Form, FormBuilder, GroupCtx, GroupToolbar, GroupsCtx, Guillotina, GuillotinaClient, IAttachment, IImageAttachment, IMultiAttachment, IMultiImageAttachment, IMultiImageOrderedAttachment, IWorkflow, Icon, Input, InputList, Item, ItemCheckbox, ItemCtx, ItemModel, ItemTitle, ItemsActionsDropdown, ItemsActionsProvider, Layout, Link, Loading, Login, Modal, NotAllowed, Notification, Pagination, PanelActions, PanelAddons, PanelBehaviors, PanelItems, PanelNotImplemented, PanelPermissions, PanelProperties, PasswordInput, Path, PathTree, PermissionPrinperm, PermissionPrinrole, PermissionRoleperm, Permissions, PropertiesButtonView, PropertiesView, REGEX_EMAIL, REGEX_HEX_COLOR, REGEX_NUMBER, REGEX_URL, RItem, RemoveItems, RenderField, RenderFieldComponent, RequiredFieldsForm, RestClient, SearchInput, SearchInputList, SearchLabels, SearchOptionsLabels, SearchRenderField, SearchVocabularyLabels, Select, SelectVocabulary, Sharing, Table, TabsPanel, Tag, TagsWidget, TdLink, Textarea, Traversal, TraversalContext, TraversalProvider, UserCtx, UserForm, UsersCtx, UsersToolbar, VocabularyRenderField, base64ToArrayBuffer, buildQs, classnames, defaultComponent, formatDate, generateUID, genericFileMessages, genericMessages, get$1 as get, getActionsObject, getClient, getNewId, isEmail, isEmpty, isHexColor, isNumber, isURL, lightFileReader, maxLength, messages$4 as messages, minLength, noop, notEmpty, parser, sleep, stringToSlug, toQueryString, useConfig, useCrudContext, useGuillotinaClient, useLocation, useRegistry, useRemoteField, useTraversal, useVocabulary };
12473
+ var Setting;
12474
+
12475
+ (function (Setting) {
12476
+ Setting["Allow"] = "Allow";
12477
+ Setting["AllowSingle"] = "AllowSingle";
12478
+ Setting["Deny"] = "Deny";
12479
+ Setting["Unset"] = "Unset";
12480
+ })(Setting || (Setting = {}));
12481
+
12482
+ export { AddItem, AddPermission, AllItemsCheckbox, ApplicationCtx, Auth, AuthContext, BaseForm, BehaviorNotImplemented, BehaviorsView, Button, Checkbox, ClientContext, ClientProvider, Confirm, ContainerCtx, ContextToolbar, CreateButton, CreateContainer, DatabaseCtx, Delete, DownloadField, EditComponent, EditableField, EmailInput, FileUpload, Flash, FolderCtx, Form, FormBuilder, GroupCtx, GroupToolbar, GroupsCtx, Guillotina, GuillotinaClient, IAttachment, IImageAttachment, IMultiAttachment, IMultiImageAttachment, IMultiImageOrderedAttachment, IWorkflow, Icon, Input, InputList, Item, ItemCheckbox, ItemCtx, ItemModel, ItemTitle, ItemsActionsDropdown, ItemsActionsProvider, Layout, Link, Loading, Login, Modal, NotAllowed, Notification, Pagination, PanelActions, PanelAddons, PanelBehaviors, PanelItems, PanelNotImplemented, PanelPermissions, PanelProperties, PasswordInput, Path, PathTree, PermissionPrinperm, PermissionPrinrole, PermissionRoleperm, Permissions, PropertiesButtonView, PropertiesView, REGEX_EMAIL, REGEX_HEX_COLOR, REGEX_NUMBER, REGEX_URL, RItem, RemoveItems, RenderField, RenderFieldComponent, RequiredFieldsForm, RestClient, SearchInput, SearchInputList, SearchLabels, SearchOptionsLabels, SearchRenderField, SearchVocabularyLabels, Select, SelectVocabulary, Setting, Sharing, Table, TabsPanel, Tag, TagsWidget, TdLink, Textarea, Traversal, TraversalContext, TraversalProvider, UserCtx, UserForm, UsersCtx, UsersToolbar, VocabularyRenderField, base64ToArrayBuffer, buildQs, classnames, debounce, defaultComponent, defaultConfig, formatDate, generateUID, genericFileMessages, genericMessages, get, getActionsObject, getClient, getNewId, isEmail, isEmpty, isHexColor, isNumber, isURL, lightFileReader, maxLength, messages$4 as messages, minLength, noop, notEmpty, parser, sleep, stringToSlug, toQueryString, useConfig, useCrudContext, useGuillotinaClient, useLocation, useRegistry, useRemoteField, useTraversal, useVocabulary };
12180
12483
  //# sourceMappingURL=react-gmi.modern.js.map