@guillotinaweb/react-gmi 0.29.1 → 0.29.2-alpha.3

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 +2 -2
  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 +1179 -900
  54. package/dist/react-gmi.esm.js.map +1 -1
  55. package/dist/react-gmi.js +1178 -900
  56. package/dist/react-gmi.js.map +1 -1
  57. package/dist/react-gmi.modern.js +1161 -856
  58. package/dist/react-gmi.modern.js.map +1 -1
  59. package/dist/react-gmi.umd.js +1178 -900
  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 +153 -19
  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]),
@@ -1372,7 +1574,8 @@ const EmailInput = ({
1372
1574
  value: _value = '',
1373
1575
  dataTest,
1374
1576
  placeholder,
1375
- id
1577
+ id,
1578
+ onChange
1376
1579
  }) => {
1377
1580
  const intl = useIntl();
1378
1581
  return jsx(Input, {
@@ -1391,7 +1594,8 @@ const EmailInput = ({
1391
1594
  icon: "fas fa-envelope"
1392
1595
  }),
1393
1596
  id: id,
1394
- placeholder: placeholder
1597
+ placeholder: placeholder,
1598
+ onChange: onChange
1395
1599
  });
1396
1600
  };
1397
1601
 
@@ -1461,22 +1665,24 @@ function FormBuilder({
1461
1665
  remotes = {},
1462
1666
  submitButton = true
1463
1667
  }) {
1464
- const ref = useRef();
1668
+ const ref = useRef(null);
1465
1669
  const {
1466
1670
  properties,
1467
1671
  required
1468
1672
  } = schema;
1469
- const values = Object.assign({}, formData || {});
1673
+ const values = Object.assign({}, formData || {}); // build initial state
1674
+
1470
1675
  const initialState = {};
1471
1676
  const fields = Object.keys(properties).filter(x => !exclude.includes(x));
1472
1677
  fields.forEach(element => {
1473
1678
  initialState[element] = values[element] || undefined;
1474
- });
1679
+ }); // Register remotes
1475
1680
 
1476
- if (!ref.current) {
1681
+ if (ref.current === null) {
1477
1682
  ref.current = {};
1478
1683
  Object.keys(remotes).forEach(item => ref.current[item] = remotes[item]);
1479
1684
  } else {
1685
+ // apply remote changes
1480
1686
  Object.keys(remotes).forEach(key => {
1481
1687
  if (JSON.stringify(ref.current[key]) !== JSON.stringify(remotes[key])) {
1482
1688
  ref.current[key] = remotes[key];
@@ -1486,15 +1692,16 @@ function FormBuilder({
1486
1692
 
1487
1693
  ref.current = ref.current || {};
1488
1694
 
1489
- const onUpdate = field => ev => {
1490
- ref.current[field] = ev.target ? ev.target.value : ev.value || ev;
1695
+ const onUpdate = field => value => {
1696
+ ref.current[field] = value;
1491
1697
  };
1492
1698
 
1493
1699
  const GetTag = ({
1494
1700
  field
1495
1701
  }) => {
1496
1702
  const property = properties[field];
1497
- const Tag = formComponents[property.widget || property.type];
1703
+ const key = property.widget || property.type;
1704
+ const Tag = formComponents[key];
1498
1705
  const props = {
1499
1706
  value: initialState[field],
1500
1707
  onChange: onUpdate(field),
@@ -1509,7 +1716,6 @@ function FormBuilder({
1509
1716
  props.placeholder += ' *';
1510
1717
  }
1511
1718
 
1512
- Tag.displayName = `${field}Field`;
1513
1719
  return jsx(Tag, _extends({}, props));
1514
1720
  };
1515
1721
 
@@ -1568,9 +1774,13 @@ const Select = forwardRef(({
1568
1774
  selectValue = selectValue.concat([ev.target.selectedOptions[i].value]);
1569
1775
  }
1570
1776
 
1571
- onChange(selectValue);
1777
+ if (onChange) {
1778
+ onChange(selectValue);
1779
+ }
1572
1780
  } else {
1573
- onChange(ev.target.value);
1781
+ if (onChange) {
1782
+ onChange(ev.target.value);
1783
+ }
1574
1784
  }
1575
1785
  };
1576
1786
 
@@ -1621,28 +1831,7 @@ const Select = forwardRef(({
1621
1831
  });
1622
1832
  Select.displayName = 'Select';
1623
1833
 
1624
- const formatDate = str => {
1625
- const d = new Date(str);
1626
- const minutes = d.getMinutes() < 10 ? `0${d.getMinutes()}` : d.getMinutes();
1627
- return `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()} ${d.getHours()}:${minutes}`;
1628
- };
1629
- const get$1 = (obj, path, defValue) => {
1630
- var _pathArray$reduce;
1631
-
1632
- if (!path) return undefined;
1633
- const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
1634
- return (_pathArray$reduce = pathArray.reduce((prevObj, key) => prevObj && prevObj[key], obj)) != null ? _pathArray$reduce : defValue;
1635
- };
1636
- function getNewId(id = '') {
1637
- const suffix = '-copy-';
1638
- const rgx = new RegExp(`($|${suffix}\\d*)`);
1639
- return stringToSlug(id).replace(rgx, r => {
1640
- const num = parseInt(r.replace(suffix, '') || '0');
1641
- return `${suffix}${num + 1}`;
1642
- });
1643
- }
1644
-
1645
- function useVocabulary(vocabularyName, path = null) {
1834
+ function useVocabulary(vocabularyName, path) {
1646
1835
  const traversal = useTraversal();
1647
1836
  const [vocabulary, setVocabulary] = useSetState({
1648
1837
  data: undefined,
@@ -1697,8 +1886,10 @@ const SelectVocabulary = forwardRef(({
1697
1886
  const vocabulary = useVocabulary(vocabularyName);
1698
1887
 
1699
1888
  const getOptions = () => {
1700
- if (get$1(vocabulary, 'data.items', null)) {
1701
- 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 => {
1702
1893
  return {
1703
1894
  text: item.title,
1704
1895
  value: item.token
@@ -1744,6 +1935,8 @@ const SelectVocabulary = forwardRef(({
1744
1935
  });
1745
1936
  SelectVocabulary.displayName = 'SelectVocabulary';
1746
1937
 
1938
+ // https://github.com/molefrog/wouter
1939
+
1747
1940
  const setURLParams = p => {
1748
1941
  return window.history.pushState(0, '0', '' + '?' + p.toString().replace(/%2F/g, '/'));
1749
1942
  };
@@ -1758,7 +1951,10 @@ const useLocation = () => {
1758
1951
  const [path, update] = useState(currentSearchParams());
1759
1952
  const prevPath = useRef(path);
1760
1953
  useEffect(() => {
1761
- 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.
1762
1958
 
1763
1959
  const checkForUpdates = () => {
1764
1960
  const pathname = currentSearchParams();
@@ -1766,12 +1962,20 @@ const useLocation = () => {
1766
1962
  };
1767
1963
 
1768
1964
  const events = ['popstate', 'pushState', 'replaceState'];
1769
- 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
+
1770
1969
  checkForUpdates();
1771
1970
  return () => {
1772
1971
  events.map(e => window.removeEventListener(e, checkForUpdates));
1773
1972
  };
1774
- }, []);
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
+
1775
1979
  const navigate = useCallback((to, replace) => {
1776
1980
  if (replace) {
1777
1981
  clean(to);
@@ -1788,22 +1992,38 @@ const useLocation = () => {
1788
1992
  setURLParams(current);
1789
1993
  }, [path]);
1790
1994
  return [path, navigate, remove];
1791
- };
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
+
1792
2001
  let patched = 0;
1793
2002
 
1794
2003
  const patchHistoryEvents = () => {
1795
2004
  if (patched) return;
1796
- ['pushState', 'replaceState'].map(type => {
1797
- const original = window.history[type];
1798
-
1799
- window.history[type] = function (...args) {
1800
- const result = original.apply(this, args);
1801
- const event = new Event(type);
1802
- event.arguments = args;
1803
- dispatchEvent(event);
1804
- return result;
1805
- };
1806
- });
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
+
1807
2027
  return patched = 1;
1808
2028
  };
1809
2029
 
@@ -1851,7 +2071,7 @@ function TdLink({
1851
2071
  children,
1852
2072
  style = {}
1853
2073
  }) {
1854
- const link = useRef();
2074
+ const link = useRef(null);
1855
2075
 
1856
2076
  function onClick() {
1857
2077
  if (link && link.current) {
@@ -1947,7 +2167,7 @@ class RestClient {
1947
2167
  this.container = container;
1948
2168
  }
1949
2169
 
1950
- async request(path, data = undefined, headers = undefined) {
2170
+ async request(path, data, headers, signal) {
1951
2171
  if (path.indexOf(this.url) !== -1) {
1952
2172
  path = path.replace(this.url, '');
1953
2173
  }
@@ -1960,19 +2180,28 @@ class RestClient {
1960
2180
  path = `/${path}`;
1961
2181
  }
1962
2182
 
1963
- data = data || {};
1964
- data.headers = headers || this.getHeaders();
1965
- return await fetch(`${this.url}${path}`, data);
1966
- }
2183
+ const dataRequest = data || {};
2184
+ dataRequest.headers = this.getHeaders();
1967
2185
 
1968
- getHeaders() {
1969
- const authToken = this.auth.getToken();
1970
- if (!authToken) return {};
1971
- return {
1972
- Accept: 'application/json',
1973
- 'Content-Type': 'application/json',
1974
- Authorization: 'Bearer ' + authToken
1975
- };
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);
2195
+ }
2196
+
2197
+ getHeaders() {
2198
+ const authToken = this.auth.getToken();
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;
1976
2205
  }
1977
2206
 
1978
2207
  async post(path, data) {
@@ -1982,8 +2211,8 @@ class RestClient {
1982
2211
  });
1983
2212
  }
1984
2213
 
1985
- async get(path) {
1986
- return await this.request(path);
2214
+ async get(path, signal) {
2215
+ return await this.request(path, undefined, undefined, signal);
1987
2216
  }
1988
2217
 
1989
2218
  async put(path, data) {
@@ -2002,17 +2231,17 @@ class RestClient {
2002
2231
 
2003
2232
  async upload(path, data) {
2004
2233
  const headers = this.getHeaders();
2005
- delete headers['Content-Type'];
2006
- headers['Content-Type'] = data['content-type'];
2007
- headers['X-UPLOAD-FILENAME'] = data.filename;
2008
- 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';
2009
2238
  return await this.request(path, {
2010
2239
  method: 'PATCH',
2011
2240
  body: data.data
2012
- }, headers);
2241
+ }, _extends({}, headers, newHeaders));
2013
2242
  }
2014
2243
 
2015
- async delete(path, data = undefined) {
2244
+ async delete(path, data) {
2016
2245
  return await this.request(path, {
2017
2246
  method: 'delete',
2018
2247
  body: JSON.stringify(data)
@@ -2119,6 +2348,14 @@ class GuillotinaClient {
2119
2348
  return await this.rest.get(path);
2120
2349
  }
2121
2350
 
2351
+ getQueryParamsSearchFunction(name) {
2352
+ if (name === 'getQueryParamsElasticsearch') {
2353
+ return this.getQueryParamsElasticsearch;
2354
+ }
2355
+
2356
+ return this.getQueryParamsPostresql;
2357
+ }
2358
+
2122
2359
  getQueryParamsPostresql({
2123
2360
  start = 0,
2124
2361
  pageSize = 10,
@@ -2202,7 +2439,7 @@ class GuillotinaClient {
2202
2439
  label: 'id/name',
2203
2440
  key: 'title',
2204
2441
  isSortable: true,
2205
- child: (m, navigate, search) => jsxs(TdLink, {
2442
+ child: (m, _navigate, search) => jsxs(TdLink, {
2206
2443
  model: m,
2207
2444
  children: [m.name, search && jsxs(React.Fragment, {
2208
2445
  children: [jsx("br", {}), jsx("span", {
@@ -2232,15 +2469,19 @@ class GuillotinaClient {
2232
2469
  children: m.updated
2233
2470
  })
2234
2471
  }];
2235
- }
2472
+ } // BBB API changes. Compat G5 and G6
2473
+
2236
2474
 
2237
2475
  applyCompat(data) {
2238
- data.member = data.items;
2239
- data.items_count = data.items_total;
2240
- return data;
2476
+ const result = _extends({}, data, {
2477
+ member: data.items,
2478
+ items_count: data.items_total
2479
+ });
2480
+
2481
+ return result;
2241
2482
  }
2242
2483
 
2243
- async search(path, params, container = false, prepare = true) {
2484
+ async search(path, params, container = false, prepare = true, signal) {
2244
2485
  if (path.startsWith('/')) {
2245
2486
  path = path.slice(1);
2246
2487
  }
@@ -2251,7 +2492,7 @@ class GuillotinaClient {
2251
2492
 
2252
2493
  const query = prepare ? toQueryString(params) : params;
2253
2494
  const url = `${path}@search?${query}`;
2254
- const res = await this.rest.get(url);
2495
+ const res = await this.rest.get(url, signal);
2255
2496
  const data = await res.json();
2256
2497
  return this.applyCompat(data);
2257
2498
  }
@@ -2320,7 +2561,8 @@ class GuillotinaClient {
2320
2561
 
2321
2562
  async getTypeSchema(path, name) {
2322
2563
  if (!cacheSchemas[name]) {
2323
- const url = this.getContainerFromPath(path);
2564
+ const url = this.getContainerFromPath(path); // todo: handle db case (only addable containers)
2565
+
2324
2566
  const res = await this.rest.get(`${url}@types/${name}`);
2325
2567
  cacheSchemas[name] = await res.json();
2326
2568
  }
@@ -2357,10 +2599,36 @@ class GuillotinaClient {
2357
2599
  async getPrincipals(path) {
2358
2600
  const groups = this.getGroups(path);
2359
2601
  const users = this.getUsers(path);
2360
- 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
+
2361
2629
  return {
2362
- groups: gr.ok ? await gr.json() : [],
2363
- users: usr.ok ? await usr.json() : []
2630
+ groups: groupsData,
2631
+ users: usersData
2364
2632
  };
2365
2633
  }
2366
2634
 
@@ -2370,6 +2638,7 @@ class GuillotinaClient {
2370
2638
  }
2371
2639
 
2372
2640
  async getAllPermissions(path) {
2641
+ // paths used to query the API always has to start without a "/"
2373
2642
  if (path.startsWith('/')) {
2374
2643
  path = path.slice(1);
2375
2644
  }
@@ -2404,17 +2673,24 @@ function getClient(url, container, auth) {
2404
2673
  return new GuillotinaClient(new RestClient(url, container, auth), container === '/');
2405
2674
  }
2406
2675
  const lightFileReader = file => {
2407
- return new Promise(resolve => {
2676
+ return new Promise((resolve, reject) => {
2408
2677
  const reader = new FileReader();
2409
2678
  reader.readAsArrayBuffer(file);
2410
2679
 
2411
2680
  reader.onloadend = e => {
2412
- const fileData = e.target.result;
2413
- resolve({
2414
- filename: file.name.normalize('NFD').replace(/[\u0300-\u036f]/g, ''),
2415
- data: fileData,
2416
- 'content-type': file.type
2417
- });
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
+ }
2418
2694
  };
2419
2695
  });
2420
2696
  };
@@ -2441,8 +2717,10 @@ function FileUpload({
2441
2717
  const intl = useIntl();
2442
2718
 
2443
2719
  const changed = async event => {
2444
- const fileToUpload = await lightFileReader(event.target.files[0]);
2445
- onChange(fileToUpload);
2720
+ if (event.target.files) {
2721
+ const fileToUpload = await lightFileReader(event.target.files[0]);
2722
+ onChange(fileToUpload);
2723
+ }
2446
2724
  };
2447
2725
 
2448
2726
  return jsx("div", {
@@ -2525,9 +2803,9 @@ Textarea.displayName = 'Textarea';
2525
2803
 
2526
2804
  const defaultEvents = ['mousedown', 'touchstart'];
2527
2805
 
2528
- const on = (obj, ...args) => obj.addEventListener(...args);
2806
+ const on = (obj, type, handler) => obj.addEventListener(type, handler);
2529
2807
 
2530
- const off = (obj, ...args) => obj.removeEventListener(...args);
2808
+ const off = (obj, type, handler) => obj.removeEventListener(type, handler);
2531
2809
 
2532
2810
  function useClickAway(ref, onClickAway, events = defaultEvents) {
2533
2811
  const savedCallback = useRef(onClickAway);
@@ -2554,23 +2832,7 @@ function useClickAway(ref, onClickAway, events = defaultEvents) {
2554
2832
  }, [events, ref]);
2555
2833
  }
2556
2834
 
2557
- function debounce(func, wait) {
2558
- let timeout;
2559
- return function () {
2560
- const context = this;
2561
- const args = arguments;
2562
-
2563
- const later = function later() {
2564
- timeout = null;
2565
- func.apply(context, args);
2566
- };
2567
-
2568
- clearTimeout(timeout);
2569
- timeout = setTimeout(later, wait);
2570
- };
2571
- }
2572
-
2573
- const initialState = {
2835
+ const initialState$1 = {
2574
2836
  page: 0,
2575
2837
  items: undefined,
2576
2838
  loading: false,
@@ -2580,8 +2842,8 @@ const SearchInput = ({
2580
2842
  onChange,
2581
2843
  error,
2582
2844
  errorZoneClassName,
2583
- traversal: _traversal = null,
2584
- path: _path = null,
2845
+ traversal,
2846
+ path: _path = undefined,
2585
2847
  qs: _qs = [],
2586
2848
  queryCondition: _queryCondition = 'id__in',
2587
2849
  value,
@@ -2589,12 +2851,12 @@ const SearchInput = ({
2589
2851
  dataTestWrapper: _dataTestWrapper = 'wrapperSearchInputTest',
2590
2852
  dataTestSearchInput: _dataTestSearchInput = 'searchInputTest',
2591
2853
  dataTestItem: _dataTestItem = 'searchInputItemTest',
2592
- renderTextItemOption: _renderTextItemOption = null,
2593
- typeNameQuery: _typeNameQuery = null,
2854
+ renderTextItemOption: _renderTextItemOption = undefined,
2855
+ typeNameQuery: _typeNameQuery = undefined,
2594
2856
  labelProperty: _labelProperty = 'id'
2595
2857
  }) => {
2596
2858
  const intl = useIntl();
2597
- const [options, setOptions] = useSetState(initialState);
2859
+ const [options, setOptions] = useSetState(initialState$1);
2598
2860
  const [isOpen, setIsOpen] = useState(false);
2599
2861
  const [searchTerm, setSearchTerm] = useState('');
2600
2862
  const inputRef = useRef(null);
@@ -2629,16 +2891,14 @@ const SearchInput = ({
2629
2891
  const searchTermParsed = [`id`, value];
2630
2892
  const {
2631
2893
  get: getSearch
2632
- } = _traversal.registry;
2894
+ } = traversal.registry;
2633
2895
  const fnName = getSearch('searchEngineQueryParamsFunction', SearchEngine);
2634
-
2635
- const qsParsed = _traversal.client[fnName]({
2636
- path: _traversal.path,
2896
+ const qsParsed = traversal.client.getQueryParamsSearchFunction(fnName)({
2897
+ path: traversal.path,
2637
2898
  start: 0,
2638
2899
  pageSize: PageSize,
2639
2900
  withDepth: false
2640
2901
  });
2641
-
2642
2902
  let typeNameParsed = [];
2643
2903
 
2644
2904
  if (_typeNameQuery) {
@@ -2649,9 +2909,9 @@ const SearchInput = ({
2649
2909
  searchTermQs = buildQs([..._qs, searchTermParsed, ...qsParsed, ...typeNameParsed]);
2650
2910
  }
2651
2911
 
2652
- 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);
2653
2913
  const newValuesLabel = data.items.reduce((result, item) => {
2654
- result[item.id] = get$1(item, _labelProperty, item.id);
2914
+ result[item.id] = get(item, _labelProperty, item.id);
2655
2915
  return result;
2656
2916
  }, {});
2657
2917
  setValueLabel(newValuesLabel);
@@ -2661,6 +2921,7 @@ const SearchInput = ({
2661
2921
  const handleSearch = async (page = 0, concat = false, value = '') => {
2662
2922
  var _data$items_total;
2663
2923
 
2924
+ console.log('handle search input');
2664
2925
  setOptions({
2665
2926
  loading: true
2666
2927
  });
@@ -2673,16 +2934,14 @@ const SearchInput = ({
2673
2934
 
2674
2935
  const {
2675
2936
  get
2676
- } = _traversal.registry;
2937
+ } = traversal.registry;
2677
2938
  const fnName = get('searchEngineQueryParamsFunction', SearchEngine);
2678
-
2679
- const qsParsed = _traversal.client[fnName]({
2680
- path: _traversal.path,
2939
+ const qsParsed = traversal.client.getQueryParamsSearchFunction(fnName)({
2940
+ path: traversal.path,
2681
2941
  start: page * PageSize,
2682
2942
  pageSize: PageSize,
2683
2943
  withDepth: false
2684
2944
  });
2685
-
2686
2945
  const sortParsed = parser(`_sort_des=${_labelProperty}`);
2687
2946
  let typeNameParsed = [];
2688
2947
 
@@ -2690,11 +2949,11 @@ const SearchInput = ({
2690
2949
  typeNameParsed = parser(`type_name__in=${_typeNameQuery}`);
2691
2950
  }
2692
2951
 
2693
- 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) {
2694
2953
  searchTermQs = buildQs([..._qs, ...searchTermParsed, ...qsParsed, ...typeNameParsed, ...sortParsed]);
2695
2954
  }
2696
2955
 
2697
- 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);
2698
2957
  const newItems = options.items && concat ? [...options.items, ...data.items] : data.items;
2699
2958
  setOptions({
2700
2959
  items: newItems != null ? newItems : [],
@@ -2709,7 +2968,7 @@ const SearchInput = ({
2709
2968
  return _renderTextItemOption(item);
2710
2969
  }
2711
2970
 
2712
- return get$1(item, _labelProperty, item.title) || item['@name'];
2971
+ return get(item, _labelProperty, item.title) || item['@name'];
2713
2972
  };
2714
2973
 
2715
2974
  useEffect(() => {
@@ -2735,7 +2994,7 @@ const SearchInput = ({
2735
2994
  if (!ev.currentTarget.contains(ev.relatedTarget)) {
2736
2995
  if (searchTerm !== '') {
2737
2996
  setSearchTerm('');
2738
- setOptions(initialState);
2997
+ setOptions(initialState$1);
2739
2998
  }
2740
2999
 
2741
3000
  setIsOpen(false);
@@ -2753,6 +3012,7 @@ const SearchInput = ({
2753
3012
  }
2754
3013
 
2755
3014
  setIsOpen(!isOpen);
3015
+ console.log('on clic btn', options);
2756
3016
 
2757
3017
  if (!options.loading && !options.items) {
2758
3018
  handleSearch(options.page);
@@ -2761,7 +3021,7 @@ const SearchInput = ({
2761
3021
  "aria-haspopup": "true",
2762
3022
  "aria-controls": "dropdown-menu",
2763
3023
  children: [jsx("span", {
2764
- children: value ? get$1(valueLabel, value, value) : intl.formatMessage(genericMessages.choose)
3024
+ children: value ? get(valueLabel, value, value) : intl.formatMessage(genericMessages.choose)
2765
3025
  }), jsx("span", {
2766
3026
  className: "icon",
2767
3027
  children: jsx("i", {
@@ -2835,23 +3095,7 @@ const SearchInput = ({
2835
3095
  });
2836
3096
  };
2837
3097
 
2838
- function debounce$1(func, wait) {
2839
- let timeout;
2840
- return function () {
2841
- const context = this;
2842
- const args = arguments;
2843
-
2844
- const later = function later() {
2845
- timeout = null;
2846
- func.apply(context, args);
2847
- };
2848
-
2849
- clearTimeout(timeout);
2850
- timeout = setTimeout(later, wait);
2851
- };
2852
- }
2853
-
2854
- const initialState$1 = {
3098
+ const initialState$2 = {
2855
3099
  page: 0,
2856
3100
  items: undefined,
2857
3101
  loading: false,
@@ -2861,8 +3105,8 @@ const SearchInputList = ({
2861
3105
  onChange,
2862
3106
  error,
2863
3107
  errorZoneClassName,
2864
- traversal: _traversal = null,
2865
- path: _path = null,
3108
+ traversal,
3109
+ path: _path = undefined,
2866
3110
  qs: _qs = [],
2867
3111
  queryCondition: _queryCondition = 'id__in',
2868
3112
  value,
@@ -2870,12 +3114,12 @@ const SearchInputList = ({
2870
3114
  dataTestWrapper: _dataTestWrapper = 'wrapperSearchInputTest',
2871
3115
  dataTestSearchInput: _dataTestSearchInput = 'searchInputTest',
2872
3116
  dataTestItem: _dataTestItem = 'searchInputItemTest',
2873
- renderTextItemOption: _renderTextItemOption = null,
2874
- typeNameQuery: _typeNameQuery = null,
3117
+ renderTextItemOption: _renderTextItemOption = undefined,
3118
+ typeNameQuery: _typeNameQuery = undefined,
2875
3119
  labelProperty: _labelProperty = 'id'
2876
3120
  }) => {
2877
3121
  const intl = useIntl();
2878
- const [options, setOptions] = useSetState(initialState$1);
3122
+ const [options, setOptions] = useSetState(initialState$2);
2879
3123
  const [valuesLabel, setValuesLabels] = useState(undefined);
2880
3124
  const [isOpen, setIsOpen] = useState(false);
2881
3125
  const [searchTerm, setSearchTerm] = useState('');
@@ -2903,7 +3147,7 @@ const SearchInputList = ({
2903
3147
  };
2904
3148
  };
2905
3149
 
2906
- const delayedQuery = useCallback(debounce$1(value => handleSearch(0, false, value), 500), []);
3150
+ const delayedQuery = useCallback(debounce(value => handleSearch(0, false, value), 500), []);
2907
3151
 
2908
3152
  const handleSearch = async (page = 0, concat = false, value = '') => {
2909
3153
  var _data$items_total;
@@ -2920,16 +3164,14 @@ const SearchInputList = ({
2920
3164
 
2921
3165
  const {
2922
3166
  get
2923
- } = _traversal.registry;
3167
+ } = traversal.registry;
2924
3168
  const fnName = get('searchEngineQueryParamsFunction', SearchEngine);
2925
-
2926
- const qsParsed = _traversal.client[fnName]({
2927
- path: _traversal.path,
3169
+ const qsParsed = traversal.client.getQueryParamsSearchFunction(fnName)({
3170
+ path: traversal.path,
2928
3171
  start: page * PageSize,
2929
3172
  pageSize: PageSize,
2930
3173
  withDepth: false
2931
3174
  });
2932
-
2933
3175
  const sortParsed = parser(`_sort_des=${_labelProperty}`);
2934
3176
  let typeNameParsed = [];
2935
3177
 
@@ -2941,7 +3183,7 @@ const SearchInputList = ({
2941
3183
  searchTermQs = buildQs([..._qs, ...searchTermParsed, ...qsParsed, ...typeNameParsed, ...sortParsed]);
2942
3184
  }
2943
3185
 
2944
- 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);
2945
3187
  const newItems = options.items && concat ? [...options.items, ...data.items] : data.items;
2946
3188
  setOptions({
2947
3189
  items: newItems != null ? newItems : [],
@@ -2958,16 +3200,14 @@ const SearchInputList = ({
2958
3200
  const searchTermParsed = ['__or', `id=${value.join('%26id=')}`];
2959
3201
  const {
2960
3202
  get: getSearch
2961
- } = _traversal.registry;
3203
+ } = traversal.registry;
2962
3204
  const fnName = getSearch('searchEngineQueryParamsFunction', SearchEngine);
2963
-
2964
- const qsParsed = _traversal.client[fnName]({
2965
- path: _traversal.path,
3205
+ const qsParsed = traversal.client.getQueryParamsSearchFunction(fnName)({
3206
+ path: traversal.path,
2966
3207
  start: 0,
2967
3208
  pageSize: 100,
2968
3209
  withDepth: false
2969
3210
  });
2970
-
2971
3211
  let typeNameParsed = [];
2972
3212
 
2973
3213
  if (_typeNameQuery) {
@@ -2978,9 +3218,9 @@ const SearchInputList = ({
2978
3218
  searchTermQs = buildQs([..._qs, searchTermParsed, ...qsParsed, ...typeNameParsed]);
2979
3219
  }
2980
3220
 
2981
- 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);
2982
3222
  const newValuesLabel = data.items.reduce((result, item) => {
2983
- result[item.id] = get$1(item, _labelProperty, item.id);
3223
+ result[item.id] = get(item, _labelProperty, item.id);
2984
3224
  return result;
2985
3225
  }, {});
2986
3226
  setValuesLabels(newValuesLabel);
@@ -2993,7 +3233,7 @@ const SearchInputList = ({
2993
3233
  return _renderTextItemOption(item);
2994
3234
  }
2995
3235
 
2996
- return get$1(item, _labelProperty, item.title) || item['@name'];
3236
+ return get(item, _labelProperty, item.title) || item['@name'];
2997
3237
  };
2998
3238
 
2999
3239
  useEffect(() => {
@@ -3015,7 +3255,7 @@ const SearchInputList = ({
3015
3255
  className: "tags mb-2",
3016
3256
  children: value.map((tag, index) => jsxs("div", {
3017
3257
  className: "tag is-info is-medium",
3018
- children: [get$1(valuesLabel, tag, tag), jsx("button", {
3258
+ children: [get(valuesLabel, tag, tag), jsx("button", {
3019
3259
  className: "delete is-small",
3020
3260
  onClick: ev => {
3021
3261
  ev.stopPropagation();
@@ -3032,7 +3272,7 @@ const SearchInputList = ({
3032
3272
  if (!ev.currentTarget.contains(ev.relatedTarget)) {
3033
3273
  if (searchTerm !== '') {
3034
3274
  setSearchTerm('');
3035
- setOptions(initialState$1);
3275
+ setOptions(initialState$2);
3036
3276
  }
3037
3277
 
3038
3278
  setIsOpen(false);
@@ -3095,7 +3335,7 @@ const SearchInputList = ({
3095
3335
 
3096
3336
  if (onChange && !value.includes(item.id)) {
3097
3337
  setValuesLabels(_extends({}, valuesLabel, {
3098
- [item.id]: get$1(item, _labelProperty, item.id)
3338
+ [item.id]: get(item, _labelProperty, item.id)
3099
3339
  }));
3100
3340
  onChange([...value, item.id]);
3101
3341
  }
@@ -3260,7 +3500,7 @@ function EditableField({
3260
3500
  ref.current.focus();
3261
3501
  }
3262
3502
  });
3263
- const canModified = modifyContent && !get$1(schema, 'readonly', false);
3503
+ const canModified = schema !== undefined && modifyContent && !get(schema, 'readonly', false);
3264
3504
 
3265
3505
  const saveField = async ev => {
3266
3506
  if (ev) ev.preventDefault();
@@ -3318,6 +3558,8 @@ function EditableField({
3318
3558
  };
3319
3559
 
3320
3560
  const deleteField = async ev => {
3561
+ var _schema$items;
3562
+
3321
3563
  if (ev) ev.preventDefault();
3322
3564
 
3323
3565
  if ((schema == null ? void 0 : schema.widget) === 'file') {
@@ -3351,7 +3593,7 @@ function EditableField({
3351
3593
  Ctx.refresh();
3352
3594
  } else if ((schema == null ? void 0 : schema.type) === 'string' && schema != null && schema.enum) {
3353
3595
  setValue(null);
3354
- } 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') {
3355
3597
  setValue([]);
3356
3598
  }
3357
3599
  };
@@ -3402,7 +3644,7 @@ function EditableField({
3402
3644
  dataTest: "editableFieldBtnCancelTest",
3403
3645
  children: intl.formatMessage(genericMessages.cancel)
3404
3646
  })
3405
- }), !required && fieldHaveDeleteButton(schema) && jsx("div", {
3647
+ }), !required && schema && fieldHaveDeleteButton(schema) && jsx("div", {
3406
3648
  className: "control",
3407
3649
  children: jsx(Button, {
3408
3650
  className: "is-small is-danger",
@@ -3433,7 +3675,8 @@ const DownloadField = ({
3433
3675
  const blob = new Blob([text], {
3434
3676
  type: data.content_type
3435
3677
  });
3436
- const url = window.URL.createObjectURL(blob);
3678
+ const url = window.URL.createObjectURL(blob); // Create blob link to download
3679
+
3437
3680
  const link = document.createElement('a');
3438
3681
  link.href = url;
3439
3682
 
@@ -3448,6 +3691,7 @@ const DownloadField = ({
3448
3691
  setTimeout(function () {
3449
3692
  var _link$parentNode;
3450
3693
 
3694
+ // For Firefox it is necessary to delay revoking the ObjectURL
3451
3695
  window.URL.revokeObjectURL(url);
3452
3696
  (_link$parentNode = link.parentNode) == null ? void 0 : _link$parentNode.removeChild(link);
3453
3697
  }, 100);
@@ -3509,19 +3753,23 @@ function RenderField({
3509
3753
  }
3510
3754
 
3511
3755
  if (type === 'object') {
3756
+ var _schema$properties;
3757
+
3512
3758
  if (Array.isArray(value)) {
3513
- return value.map(item => jsx("div", {
3759
+ return value.map((item, index) => jsx("div", {
3514
3760
  children: jsx(RenderField, {
3515
3761
  value: item
3516
3762
  })
3517
- }, item));
3763
+ }, `renderField_${index}_${schema == null ? void 0 : schema.title}`));
3518
3764
  }
3519
3765
 
3520
- return Object.keys(value).map(key => jsx(FieldValue, {
3521
- field: get$1(schema, `properties.${key}.title`, key),
3522
- schema: get$1(schema, `properties.${key}`, {}),
3523
- value: value[key]
3524
- }, 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
+ }
3525
3773
  }
3526
3774
 
3527
3775
  return jsxs("p", {
@@ -3565,6 +3813,7 @@ const SearchRenderField = ({
3565
3813
  value,
3566
3814
  modifyContent
3567
3815
  }) => {
3816
+ console.log('search render fields');
3568
3817
  const intl = useIntl();
3569
3818
  const [valuesLabels, setValuesLabels] = useState([]);
3570
3819
  const [isLoadingData, setIsLoadingData] = useState(false);
@@ -3582,7 +3831,7 @@ const SearchRenderField = ({
3582
3831
  get: getSearch
3583
3832
  } = traversal.registry;
3584
3833
  const fnName = getSearch('searchEngineQueryParamsFunction', SearchEngine);
3585
- const qsParsed = traversal.client[fnName]({
3834
+ const qsParsed = traversal.client.getQueryParamsSearchFunction(fnName)({
3586
3835
  path: traversal.path,
3587
3836
  start: 0,
3588
3837
  pageSize: 100,
@@ -3593,23 +3842,25 @@ const SearchRenderField = ({
3593
3842
  searchTermQs = buildQs([searchTermParsed, ...qsParsed]);
3594
3843
  }
3595
3844
 
3596
- 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);
3597
3846
  const newValuesLabel = data.items.map(item => {
3598
3847
  var _schema$labelProperty;
3599
3848
 
3600
- 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);
3601
3850
  });
3602
3851
  setValuesLabels(newValuesLabel);
3603
3852
  setIsLoadingData(false);
3604
3853
  };
3605
3854
 
3606
- let valuesToSearch = value;
3855
+ let valuesToSearch = [];
3607
3856
 
3608
- if (typeof valuesToSearch === 'string') {
3609
- valuesToSearch = [valuesToSearch];
3857
+ if (typeof value === 'string' && value) {
3858
+ valuesToSearch = [value];
3859
+ } else if (Array.isArray(value)) {
3860
+ valuesToSearch = value;
3610
3861
  }
3611
3862
 
3612
- if (valuesToSearch !== undefined && valuesToSearch.length > 0) {
3863
+ if (valuesToSearch.length > 0) {
3613
3864
  fetchData(valuesToSearch);
3614
3865
  } else {
3615
3866
  setValuesLabels([]);
@@ -3645,7 +3896,7 @@ const VocabularyRenderField = ({
3645
3896
 
3646
3897
  const intl = useIntl();
3647
3898
  const DEFAULT_VALUE_EDITABLE_FIELD = getDefaultValueEditableField(intl);
3648
- 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) || '';
3649
3900
  const vocabulary = useVocabulary(vocabularyName);
3650
3901
 
3651
3902
  const getRenderProps = () => {
@@ -3656,7 +3907,7 @@ const VocabularyRenderField = ({
3656
3907
  if (schema != null && schema.vocabularyName) {
3657
3908
  var _vocabularyValue$titl;
3658
3909
 
3659
- const vocabularyValue = get$1(vocabulary, 'data.items', []).find(item => item.token === value);
3910
+ const vocabularyValue = get(vocabulary, 'data.items', []).find(item => item.token === value);
3660
3911
  renderProps['value'] = (_vocabularyValue$titl = vocabularyValue == null ? void 0 : vocabularyValue.title) != null ? _vocabularyValue$titl : '';
3661
3912
  } else {
3662
3913
  var _renderProps$value;
@@ -3664,7 +3915,7 @@ const VocabularyRenderField = ({
3664
3915
  renderProps['value'] = ((_renderProps$value = renderProps['value']) != null ? _renderProps$value : []).map(value => {
3665
3916
  var _get$find$title, _get$find;
3666
3917
 
3667
- 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 : '';
3668
3919
  });
3669
3920
  }
3670
3921
 
@@ -3739,7 +3990,7 @@ const EditComponent = forwardRef(({
3739
3990
  queryCondition: schema != null && schema.queryCondition ? schema.queryCondition : 'title__in',
3740
3991
  path: schema.queryPath,
3741
3992
  labelProperty: schema != null && schema.labelProperty ? schema.labelProperty : 'title',
3742
- typeNameQuery: schema != null && schema.typeNameQuery ? schema.typeNameQuery : null
3993
+ typeNameQuery: schema == null ? void 0 : schema.typeNameQuery
3743
3994
  })]
3744
3995
  });
3745
3996
  } else if ((schema == null ? void 0 : schema.widget) === 'search') {
@@ -3754,7 +4005,7 @@ const EditComponent = forwardRef(({
3754
4005
  queryCondition: schema != null && schema.queryCondition ? schema.queryCondition : 'title__in',
3755
4006
  path: schema.queryPath,
3756
4007
  labelProperty: schema != null && schema.labelProperty ? schema.labelProperty : 'title',
3757
- typeNameQuery: schema != null && schema.typeNameQuery ? schema.typeNameQuery : null
4008
+ typeNameQuery: schema == null ? void 0 : schema.typeNameQuery
3758
4009
  })]
3759
4010
  });
3760
4011
  } else if ((schema == null ? void 0 : schema.widget) === 'textarea' || (schema == null ? void 0 : schema.widget) === 'richtext') {
@@ -3780,7 +4031,7 @@ const EditComponent = forwardRef(({
3780
4031
 
3781
4032
  if (schema.items.vocabularyName) {
3782
4033
  return jsx(SelectVocabulary, {
3783
- vocabularyName: get$1(schema, 'items.vocabularyName', null),
4034
+ vocabularyName: get(schema, 'items.vocabularyName', ''),
3784
4035
  val: val || [],
3785
4036
  className: className,
3786
4037
  classWrap: "is-fullwidth",
@@ -3817,18 +4068,21 @@ const EditComponent = forwardRef(({
3817
4068
  }), jsx(InputList, {
3818
4069
  value: val || [],
3819
4070
  className: className,
3820
- onChange: ev => setValue(ev),
4071
+ onChange: val => setValue(val),
3821
4072
  ref: ref,
3822
4073
  dataTest: dataTest
3823
4074
  })]
3824
4075
  });
3825
4076
  } else if ((schema == null ? void 0 : schema.widget) === 'file') {
4077
+ const value = val;
3826
4078
  return jsx(FileUpload, {
3827
4079
  onChange: ev => setValue(ev),
3828
- label: get$1(val, 'filename', null),
4080
+ label: get(value, 'filename', undefined),
3829
4081
  dataTest: dataTest
3830
4082
  });
3831
4083
  } else if ((schema == null ? void 0 : schema.widget) === 'select' && schema.type === 'string') {
4084
+ var _schema$vocabulary;
4085
+
3832
4086
  if (schema != null && schema.vocabularyName) {
3833
4087
  return jsx(SelectVocabulary, {
3834
4088
  val: val || '',
@@ -3837,7 +4091,7 @@ const EditComponent = forwardRef(({
3837
4091
  classWrap: "is-fullwidth",
3838
4092
  dataTest: dataTest,
3839
4093
  onChange: setValue,
3840
- vocabularyName: get$1(schema, 'vocabularyName', null),
4094
+ vocabularyName: get(schema, 'vocabularyName', ''),
3841
4095
  placeholder: placeholder,
3842
4096
  id: id
3843
4097
  });
@@ -3849,7 +4103,7 @@ const EditComponent = forwardRef(({
3849
4103
  appendDefault: true,
3850
4104
  classWrap: "is-fullwidth",
3851
4105
  dataTest: dataTest,
3852
- options: schema == null ? void 0 : schema.vocabulary.map(item => {
4106
+ options: ((_schema$vocabulary = schema == null ? void 0 : schema.vocabulary) != null ? _schema$vocabulary : []).map(item => {
3853
4107
  return {
3854
4108
  text: item,
3855
4109
  value: item
@@ -3865,11 +4119,12 @@ const EditComponent = forwardRef(({
3865
4119
  children: [schema.title && jsx("h4", {
3866
4120
  className: "subtitle mt-2",
3867
4121
  children: schema.title
3868
- }), Object.keys(get$1(schema, 'properties', {})).map(key => {
4122
+ }), Object.keys(get(schema, 'properties', {})).map(key => {
3869
4123
  var _subSchema$title;
3870
4124
 
3871
- const subSchema = get$1(schema, 'properties', {})[key];
3872
- 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;
3873
4128
  return jsx(EditComponent, {
3874
4129
  id: `${id}[${key}]`,
3875
4130
  schema: subSchema,
@@ -3939,9 +4194,9 @@ function IAttachment({
3939
4194
  }, 1), jsx("td", {
3940
4195
  children: jsx(EditableField, {
3941
4196
  field: key,
3942
- value: values[key],
4197
+ value: values.file,
3943
4198
  ns: "guillotina.behaviors.attachment.IAttachment",
3944
- schema: properties[key],
4199
+ schema: properties.file,
3945
4200
  modifyContent: modifyContent && ['file'].includes(key)
3946
4201
  })
3947
4202
  }, 2)]
@@ -3974,6 +4229,11 @@ function IMultiAttachment({
3974
4229
 
3975
4230
  setLoading(true);
3976
4231
  setError(undefined);
4232
+
4233
+ if (!file) {
4234
+ return;
4235
+ }
4236
+
3977
4237
  const endpoint = `${Ctx.path}@upload/files/${fileKey}`;
3978
4238
  const req = await Ctx.client.upload(endpoint, file);
3979
4239
 
@@ -4030,7 +4290,7 @@ function IMultiAttachment({
4030
4290
  field: `files/${key}`,
4031
4291
  value: values['files'][key],
4032
4292
  ns: "guillotina.behaviors.attachment.IMultiAttachment.files",
4033
- schema: properties['files']['additionalProperties'],
4293
+ schema: get(properties, 'files.additionalProperties', {}),
4034
4294
  modifyContent: false
4035
4295
  }), jsx("div", {
4036
4296
  className: "ml-5",
@@ -4108,6 +4368,11 @@ function IImageAttachment({
4108
4368
  ev.preventDefault();
4109
4369
  setLoading(true);
4110
4370
  setError(undefined);
4371
+
4372
+ if (!file) {
4373
+ return;
4374
+ }
4375
+
4111
4376
  const endpoint = `${Ctx.path}@upload/image`;
4112
4377
  const req = await Ctx.client.upload(endpoint, file);
4113
4378
 
@@ -4138,7 +4403,7 @@ function IImageAttachment({
4138
4403
  }
4139
4404
  }
4140
4405
 
4141
- setFile(undefined);
4406
+ setFile(null);
4142
4407
  setLoading(false);
4143
4408
  Ctx.flash(intl.formatMessage(genericFileMessages.image_uploaded), 'success');
4144
4409
  Ctx.refresh();
@@ -4237,7 +4502,7 @@ function IMultiImageAttachment({
4237
4502
  const intl = useIntl();
4238
4503
  const cfg = useConfig();
4239
4504
  const [fileKey, setFileKey] = useState('');
4240
- const [file, setFile] = useState(null);
4505
+ const [file, setFile] = useState(undefined);
4241
4506
  const [fileKeyToDelete, setFileKeyToDelete] = useState(undefined);
4242
4507
  const [loading, setLoading] = useState(false);
4243
4508
  const [error, setError] = useState(undefined);
@@ -4257,6 +4522,11 @@ function IMultiImageAttachment({
4257
4522
 
4258
4523
  setLoading(true);
4259
4524
  setError(undefined);
4525
+
4526
+ if (!file) {
4527
+ return;
4528
+ }
4529
+
4260
4530
  const endpoint = `${Ctx.path}@upload/images/${fileKey}`;
4261
4531
  const req = await Ctx.client.upload(endpoint, file);
4262
4532
 
@@ -4334,7 +4604,7 @@ function IMultiImageAttachment({
4334
4604
  field: `images/${key}`,
4335
4605
  value: values['images'][key],
4336
4606
  ns: "guillotina.contrib.image.behaviors.IMultiImageAttachment.images",
4337
- schema: properties['images']['additionalProperties'],
4607
+ schema: get(properties, 'images.additionalProperties', {}),
4338
4608
  modifyContent: false,
4339
4609
  required: false
4340
4610
  }), jsx("div", {
@@ -4450,7 +4720,7 @@ function IMultiImageOrderedAttachment({
4450
4720
  const intl = useIntl();
4451
4721
  const cfg = useConfig();
4452
4722
  const [sortedList, setSortedList] = useState(Object.keys(values['images']));
4453
- const [file, setFile] = useState(null);
4723
+ const [file, setFile] = useState(undefined);
4454
4724
  const [fileKeyToDelete, setFileKeyToDelete] = useState(undefined);
4455
4725
  const [loading, setLoading] = useState(false);
4456
4726
  const [error, setError] = useState(undefined);
@@ -4580,7 +4850,7 @@ function IMultiImageOrderedAttachment({
4580
4850
  field: `images/${key}`,
4581
4851
  value: values['images'][key],
4582
4852
  ns: "guillotina.contrib.image.behaviors.IMultiImageAttachment.images",
4583
- schema: properties['images']['additionalProperties'],
4853
+ schema: get(properties, 'images.additionalProperties', {}),
4584
4854
  modifyContent: false,
4585
4855
  required: false
4586
4856
  }), jsx("div", {
@@ -4630,138 +4900,6 @@ function IMultiImageOrderedAttachment({
4630
4900
  });
4631
4901
  }
4632
4902
 
4633
- const base = {
4634
- local: {
4635
- roleperm: {},
4636
- prinperm: {},
4637
- prinrole: {}
4638
- },
4639
- inherit: []
4640
- };
4641
- class Sharing {
4642
- constructor(element) {
4643
- this.local = void 0;
4644
- this.inherit = void 0;
4645
- Object.assign(this, element || base);
4646
- }
4647
-
4648
- get roles() {
4649
- return Object.keys(this.local.roleperm);
4650
- }
4651
-
4652
- getRole(role) {
4653
- return this.local.roleperm[role];
4654
- }
4655
-
4656
- get principals() {
4657
- return Object.keys(this.local.prinperm);
4658
- }
4659
-
4660
- getPrincipals(principal) {
4661
- return this.local.prinperm[principal];
4662
- }
4663
-
4664
- get prinrole() {
4665
- return Object.keys(this.local.prinrole);
4666
- }
4667
-
4668
- getPrinroles(role) {
4669
- return this.local.prinrole[role];
4670
- }
4671
-
4672
- }
4673
-
4674
- class ItemModel {
4675
- constructor(item, url = '') {
4676
- this.item = void 0;
4677
- this.url = void 0;
4678
- this.item = item;
4679
- this.url = url;
4680
- }
4681
-
4682
- get path() {
4683
- const item = this.item['@id'] ? this.item['@id'] : this.item['@absolute_url'];
4684
- let path = item.split('//')[1].split('/').splice(1).join('/');
4685
- path = `/${path}/`;
4686
-
4687
- if (this.url.length > 0) {
4688
- if (this.url.startsWith('/')) {
4689
- path = path.replace(this.url.substring(1), '');
4690
- } else {
4691
- path = path.replace(this.url, '');
4692
- }
4693
- }
4694
-
4695
- return path;
4696
- }
4697
-
4698
- get name() {
4699
- return this.item.title || this.item['@name'];
4700
- }
4701
-
4702
- get icon() {
4703
- const cfg = useConfig();
4704
-
4705
- if (cfg.icons && cfg.icons[this.type]) {
4706
- return cfg.icons[this.type];
4707
- }
4708
-
4709
- switch (this.type) {
4710
- case 'GroupManager':
4711
- return 'fas fa-users-cog';
4712
-
4713
- case 'UserManager':
4714
- return 'fas fa-user-cog';
4715
-
4716
- case 'User':
4717
- return 'fas fa-user';
4718
-
4719
- case 'Group':
4720
- return 'fas fa-users';
4721
-
4722
- case 'Folder':
4723
- return 'fas fa-folder';
4724
-
4725
- default:
4726
- return 'fas fa-file';
4727
- }
4728
- }
4729
-
4730
- get fullPath() {
4731
- return this.url + this.item.id;
4732
- }
4733
-
4734
- get id() {
4735
- if (this.item.id) {
4736
- return this.item.id;
4737
- }
4738
-
4739
- const id = this.item['@id'].split('&')[0].split('/');
4740
- return id[id.length - 1];
4741
- }
4742
-
4743
- get uid() {
4744
- return this.item['@uid'];
4745
- }
4746
-
4747
- get type() {
4748
- return this.item['@type'] || this.item.type_name;
4749
- }
4750
-
4751
- get title() {
4752
- return this.item.title;
4753
- }
4754
-
4755
- get created() {
4756
- return this.item.creation_date ? formatDate(this.item.creation_date) : '';
4757
- }
4758
-
4759
- get updated() {
4760
- return this.item.modification_date ? formatDate(this.item.modification_date) : '';
4761
- }
4762
-
4763
- }
4764
-
4765
4903
  const messages$1 = defineMessages({
4766
4904
  status_changed_ok: {
4767
4905
  id: "status_changed_ok",
@@ -4820,10 +4958,9 @@ function IWorkflow() {
4820
4958
  } = useCrudContext();
4821
4959
  const modifyContent = Ctx.hasPerm('guillotina.ModifyContent');
4822
4960
  const [definition, setDefinition] = useState(undefined);
4823
- const [workflowAction, setWorkflowAction] = useState(null);
4824
- const model = new ItemModel(Ctx.context);
4961
+ const [workflowAction, setWorkflowAction] = useState(undefined);
4825
4962
  const vocabulary = useVocabulary('workflow_states');
4826
- const currentState = model.item['guillotina.contrib.workflows.interfaces.IWorkflowBehavior']['review_state'];
4963
+ const currentState = Ctx.context['guillotina.contrib.workflows.interfaces.IWorkflowBehavior']['review_state'];
4827
4964
 
4828
4965
  async function loadDefinition() {
4829
4966
  const response = await Ctx.client.get(`${Ctx.path}/@workflow`);
@@ -4851,23 +4988,25 @@ function IWorkflow() {
4851
4988
  }
4852
4989
 
4853
4990
  Ctx.refresh();
4854
- setWorkflowAction(null);
4991
+ setWorkflowAction(undefined);
4855
4992
  };
4856
4993
 
4857
4994
  const getStateTitle = () => {
4858
- var _vocabulary$data, _vocabulary$data$item;
4995
+ var _vocabulary$data$item, _vocabulary$data;
4996
+
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;
4859
4999
 
4860
- if (((_vocabulary$data = vocabulary.data) == null ? void 0 : (_vocabulary$data$item = _vocabulary$data.items) == null ? void 0 : _vocabulary$data$item.length) > 0) {
4861
- const vocabularyValue = vocabulary.data.items.find(item => item.token === currentState);
5000
+ const vocabularyValue = vocabulary == null ? void 0 : (_vocabulary$data2 = vocabulary.data) == null ? void 0 : _vocabulary$data2.items.find(item => item.token === currentState);
4862
5001
 
4863
5002
  if (vocabularyValue) {
4864
- const translatedValue = get$1(vocabularyValue, `title.translated_title.${intl.locale}`, null);
5003
+ const translatedValue = get(vocabularyValue, `title.translated_title.${intl.locale}`, null);
4865
5004
 
4866
5005
  if (translatedValue !== null) {
4867
5006
  return translatedValue;
4868
5007
  }
4869
5008
 
4870
- const titleValue = get$1(vocabularyValue, `title.title.${intl.locale}`, null);
5009
+ const titleValue = get(vocabularyValue, `title.title.${intl.locale}`, null);
4871
5010
 
4872
5011
  if (titleValue !== null) {
4873
5012
  return titleValue;
@@ -4882,7 +5021,7 @@ function IWorkflow() {
4882
5021
  return jsxs(Fragment, {
4883
5022
  children: [workflowAction && jsx(Confirm, {
4884
5023
  loading: loading,
4885
- onCancel: () => setWorkflowAction(null),
5024
+ onCancel: () => setWorkflowAction(undefined),
4886
5025
  onConfirm: doWorkflowAction,
4887
5026
  message: intl.formatMessage(messages$1.confirm_message, {
4888
5027
  title: Ctx.context.title || Ctx.context['@name']
@@ -4905,7 +5044,7 @@ function IWorkflow() {
4905
5044
  return jsx("button", {
4906
5045
  className: "button mr-4",
4907
5046
  onClick: () => setWorkflowAction(transition['@id'].split('@workflow')[1].slice(1)),
4908
- children: get$1(transition, `metadata.translated_title.${intl.locale}`, transition.title)
5047
+ children: get(transition, `metadata.translated_title.${intl.locale}`, transition.title)
4909
5048
  }, transition['@id']);
4910
5049
  })]
4911
5050
  })]
@@ -4929,14 +5068,17 @@ function PanelActions() {
4929
5068
 
4930
5069
  return jsx(Fragment$1, {
4931
5070
  children: Object.keys(ACTIONS_OBJECT).map(actionKey => {
4932
- if (hasPerm(ACTIONS_OBJECT[actionKey].perms)) {
5071
+ const actionKeyTyped = actionKey;
5072
+ const actionObject = ACTIONS_OBJECT[actionKeyTyped];
5073
+
5074
+ if (hasPerm(actionObject.perms)) {
4933
5075
  return jsx("button", {
4934
5076
  className: "button mr-4",
4935
5077
  onClick: () => {
4936
- onAction(actionKey);
5078
+ onAction(actionKeyTyped);
4937
5079
  },
4938
- children: ACTIONS_OBJECT[actionKey].text
4939
- }, `panel_action_${ACTIONS_OBJECT[actionKey].text}`);
5080
+ children: actionObject.text
5081
+ }, `panel_action_${actionObject.text}`);
4940
5082
  }
4941
5083
  })
4942
5084
  });
@@ -4964,7 +5106,8 @@ const messages$2 = defineMessages({
4964
5106
  "value": "Installed Addons"
4965
5107
  }]
4966
5108
  }
4967
- });
5109
+ }); // TODO: Refactor without useAsync... just crudContext
5110
+
4968
5111
  function PanelAddons() {
4969
5112
  var _state$data$available, _state$data, _state$data$available2, _state$data2, _state$data$installed, _state$data3, _state$data$installed2, _state$data4;
4970
5113
 
@@ -5077,8 +5220,9 @@ const prepareData = result => {
5077
5220
  };
5078
5221
 
5079
5222
  const arrayToObject = array => array.reduce((obj, item) => {
5080
- obj[item.id] = item;
5081
- return obj;
5223
+ return _extends({}, obj, {
5224
+ [item.id]: item
5225
+ });
5082
5226
  }, {});
5083
5227
 
5084
5228
  function PanelBehaviors() {
@@ -5213,8 +5357,9 @@ function ItemsActionsProvider({
5213
5357
 
5214
5358
  function onSelectAllItems(checked) {
5215
5359
  setSelected(items.reduce((obj, item) => {
5216
- obj[`${item.path}/${item.id}`] = checked;
5217
- return obj;
5360
+ return _extends({}, obj, {
5361
+ [`${item.path}/${item.id}`]: checked
5362
+ });
5218
5363
  }, {
5219
5364
  all: checked
5220
5365
  }));
@@ -5243,13 +5388,39 @@ function ItemsActionsProvider({
5243
5388
  children: children
5244
5389
  });
5245
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
+
5246
5417
  function AllItemsCheckbox({
5247
5418
  dataTest
5248
5419
  }) {
5249
5420
  const {
5250
5421
  onSelectAllItems,
5251
5422
  selected
5252
- } = useContext(ItemsActionsCtx);
5423
+ } = useItemsActions();
5253
5424
  return jsx(Checkbox, {
5254
5425
  onChange: onSelectAllItems,
5255
5426
  checked: selected.all,
@@ -5263,7 +5434,7 @@ function ItemCheckbox({
5263
5434
  const {
5264
5435
  selected,
5265
5436
  onSelectOneItem
5266
- } = useContext(ItemsActionsCtx);
5437
+ } = useItemsActions();
5267
5438
  const absId = `${item.path}/${item.id}`;
5268
5439
  const value = selected[absId];
5269
5440
  return jsx(Checkbox, {
@@ -5272,6 +5443,10 @@ function ItemCheckbox({
5272
5443
  dataTest: dataTest
5273
5444
  });
5274
5445
  }
5446
+ /**
5447
+ * Dropdown to choose some action to apply to the selected items.
5448
+ */
5449
+
5275
5450
  function ItemsActionsDropdown() {
5276
5451
  const intl = useIntl();
5277
5452
  const ACTIONS_OBJECT = getActionsObject(intl, true);
@@ -5279,7 +5454,7 @@ function ItemsActionsDropdown() {
5279
5454
  const {
5280
5455
  selected,
5281
5456
  onAction
5282
- } = useContext(ItemsActionsCtx);
5457
+ } = useItemsActions();
5283
5458
  const disabled = Object.values(selected).every(v => !v);
5284
5459
  const options = Object.keys(ACTIONS_OBJECT).map(action => ({
5285
5460
  text: ACTIONS_OBJECT[action].text,
@@ -5305,75 +5480,216 @@ function ItemsActionsDropdown() {
5305
5480
  });
5306
5481
  }
5307
5482
 
5308
- function Pagination({
5309
- current,
5310
- total,
5311
- doPaginate,
5312
- pager
5313
- }) {
5314
- const intl = useIntl();
5315
- 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
+ }
5316
5680
 
5317
- if (maxPages <= 1) {
5318
- 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) : '';
5319
5691
  }
5320
5692
 
5321
- return jsxs("div", {
5322
- children: [jsx("p", {
5323
- className: "level-right has-text-grey is-size-7",
5324
- children: jsx("span", {
5325
- children: intl.formatMessage({
5326
- id: "pagination",
5327
- defaultMessage: [{
5328
- "type": 1,
5329
- "value": "currentPage"
5330
- }, {
5331
- "type": 0,
5332
- "value": " / "
5333
- }, {
5334
- "type": 1,
5335
- "value": "totalPages"
5336
- }, {
5337
- "type": 0,
5338
- "value": " of "
5339
- }, {
5340
- "type": 1,
5341
- "value": "totalItems"
5342
- }, {
5343
- "type": 0,
5344
- "value": " items"
5345
- }]
5346
- }, {
5347
- currentPage: current + 1,
5348
- totalPages: maxPages,
5349
- totalItems: total
5350
- })
5351
- })
5352
- }), jsxs("nav", {
5353
- className: "pagination is-size-7",
5354
- role: "navigation",
5355
- "aria-label": "pagination",
5356
- children: [jsx("a", {
5357
- className: "pagination-previous is-small",
5358
- onClick: () => current > 0 ? doPaginate(current - 1) : null,
5359
- children: jsx("span", {
5360
- className: "icon",
5361
- children: jsx("i", {
5362
- className: "fas fa-arrow-left"
5363
- })
5364
- })
5365
- }), jsx("a", {
5366
- className: "pagination-next is-small",
5367
- onClick: () => doPaginate(current + 1),
5368
- children: jsx("span", {
5369
- className: "icon",
5370
- children: jsx("i", {
5371
- className: "fas fa-arrow-right"
5372
- })
5373
- })
5374
- })]
5375
- })]
5376
- });
5377
5693
  }
5378
5694
 
5379
5695
  function Item({
@@ -5494,11 +5810,11 @@ function SearchOptionsLabels({
5494
5810
  }) {
5495
5811
  const [location,, del] = useLocation();
5496
5812
  const [renderValue, setRenderValue] = useState(undefined);
5497
- const defaultRenderValue = location.get(query);
5813
+ const defaultRenderValue = location.get(query) || '';
5498
5814
  useEffect(() => {
5499
5815
  let value = defaultRenderValue;
5500
5816
 
5501
- if ((options != null ? options : []).length > 0) {
5817
+ if (options && (options != null ? options : []).length > 0) {
5502
5818
  const option = options.find(item => item.value === value);
5503
5819
 
5504
5820
  if (option) {
@@ -5536,14 +5852,16 @@ function SearchVocabularyLabels({
5536
5852
  const [location,, del] = useLocation();
5537
5853
  const [renderValue, setRenderValue] = useState(undefined);
5538
5854
  const vocabulary = useVocabulary(vocabularyName);
5539
- const defaultRenderValue = location.get(query);
5855
+ const defaultRenderValue = location.get(query) || '';
5540
5856
  useEffect(() => {
5541
5857
  var _vocabulary$data$item, _vocabulary$data;
5542
5858
 
5543
5859
  let value = defaultRenderValue;
5544
5860
 
5545
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) {
5546
- 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);
5547
5865
 
5548
5866
  if (vocabularyValue) {
5549
5867
  value = vocabularyValue.title;
@@ -5573,7 +5891,7 @@ function SearchVocabularyLabels({
5573
5891
  return null;
5574
5892
  }
5575
5893
 
5576
- const initialState$2 = {
5894
+ const initialState$3 = {
5577
5895
  page: 0,
5578
5896
  items: [],
5579
5897
  loading: true,
@@ -5587,7 +5905,7 @@ function PanelItems() {
5587
5905
  } = useConfig();
5588
5906
  const intl = useIntl();
5589
5907
  const Ctx = useTraversal();
5590
- const [state, setState] = useSetState(initialState$2);
5908
+ const [state, setState] = useSetState(initialState$3);
5591
5909
  const {
5592
5910
  items,
5593
5911
  loading,
@@ -5602,7 +5920,7 @@ function PanelItems() {
5602
5920
  let page;
5603
5921
 
5604
5922
  try {
5605
- page = parseInt(location.get('page')) || 0;
5923
+ page = parseInt(location.get('page') || '0');
5606
5924
  } catch (_unused) {
5607
5925
  page = 0;
5608
5926
  }
@@ -5649,7 +5967,7 @@ function PanelItems() {
5649
5967
  let resultQueryParams = [];
5650
5968
  const resultDynamicLocation = [];
5651
5969
  filterSchema.forEach(filter => {
5652
- const itemParam = location.get(filter.attribute_key);
5970
+ const itemParam = location.get(filter.attribute_key) || '';
5653
5971
  resultDynamicLocation.push(itemParam);
5654
5972
 
5655
5973
  if (itemParam) {
@@ -5661,7 +5979,7 @@ function PanelItems() {
5661
5979
  const controller = new AbortController();
5662
5980
  if (Ctx.state.loading) return;
5663
5981
 
5664
- (async () => {
5982
+ const getData = async () => {
5665
5983
  setState({
5666
5984
  loading: true,
5667
5985
  total: Ctx.context.length
@@ -5672,14 +5990,11 @@ function PanelItems() {
5672
5990
  const fnName = get('searchEngineQueryParamsFunction', SearchEngine);
5673
5991
 
5674
5992
  if (sortParsed === undefined) {
5675
- const defaultSortValue = Ctx.registry.getDefaultSortValue(Ctx.context['@type'], {
5676
- key: 'id',
5677
- direction: 'des'
5678
- });
5993
+ const defaultSortValue = Ctx.registry.getDefaultSortValue(Ctx.context['@type']);
5679
5994
  sortParsed = parser(`_sort_${defaultSortValue.direction}=${defaultSortValue.key}`);
5680
5995
  }
5681
5996
 
5682
- const qsParsed = Ctx.client[fnName]({
5997
+ const qsParsed = Ctx.client.getQueryParamsSearchFunction(fnName)({
5683
5998
  path: Ctx.path,
5684
5999
  start: page * PageSize,
5685
6000
  pageSize: PageSize
@@ -5699,16 +6014,15 @@ function PanelItems() {
5699
6014
  const {
5700
6015
  signal
5701
6016
  } = controller;
5702
- const data = await Ctx.client.search(Ctx.path, qs, false, false, {
5703
- signal
5704
- });
6017
+ const data = await Ctx.client.search(Ctx.path, qs, false, false, signal);
5705
6018
  setState({
5706
- items: data.member,
6019
+ items: data.items,
5707
6020
  loading: false,
5708
6021
  total: data.items_count
5709
6022
  });
5710
- })();
6023
+ };
5711
6024
 
6025
+ getData();
5712
6026
  return () => {
5713
6027
  controller.abort();
5714
6028
  };
@@ -5753,12 +6067,14 @@ function PanelItems() {
5753
6067
  var _filter$values;
5754
6068
 
5755
6069
  if (filter.type === 'select' && ((_filter$values = filter.values) != null ? _filter$values : []).length > 0) {
6070
+ var _filter$values2;
6071
+
5756
6072
  return jsx(Select, {
5757
6073
  id: filter.attribute_key,
5758
6074
  placeholder: filter.label,
5759
6075
  appendDefault: true,
5760
6076
  classWrap: "is-size-7 is-fullwidth",
5761
- options: filter.values,
6077
+ options: (_filter$values2 = filter.values) != null ? _filter$values2 : [],
5762
6078
  value: location.get(filter.attribute_key) || '',
5763
6079
  dataTest: `filterInput${filter.attribute_key}`,
5764
6080
  onChange: value => {
@@ -5831,7 +6147,7 @@ function PanelItems() {
5831
6147
  const filterData = location.get(filter.attribute_key);
5832
6148
 
5833
6149
  if (filterData) {
5834
- var _filter$values2;
6150
+ var _filter$values3;
5835
6151
 
5836
6152
  if (filter.type === 'select' && filter.vocabulary) {
5837
6153
  return jsx("div", {
@@ -5840,7 +6156,7 @@ function PanelItems() {
5840
6156
  vocabularyName: filter == null ? void 0 : filter.vocabulary
5841
6157
  })
5842
6158
  }, filter.attribute_key);
5843
- } 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) {
5844
6160
  return jsx("div", {
5845
6161
  children: jsx(SearchOptionsLabels, {
5846
6162
  query: filter.attribute_key,
@@ -5883,7 +6199,7 @@ function PanelItems() {
5883
6199
  className: "has-text-info is-flex is-align-items-center",
5884
6200
  children: [jsx("span", {
5885
6201
  children: column.label
5886
- }), getIcon(column.key, column.isSortable)]
6202
+ }), getIcon(column.key, !!column.isSortable)]
5887
6203
  })
5888
6204
  }, `table-col-${column.label}`)), jsx("th", {
5889
6205
  children: "\u00A0"
@@ -5892,7 +6208,7 @@ function PanelItems() {
5892
6208
  }), jsxs("tbody", {
5893
6209
  children: [items && items.map(item => jsx(RItem, {
5894
6210
  item: item,
5895
- search: search,
6211
+ search: search != null ? search : '',
5896
6212
  columns: columns
5897
6213
  }, item['@uid'])), items && items.length === 0 && jsx("tr", {
5898
6214
  children: jsx("td", {
@@ -5918,17 +6234,19 @@ function BehaviorsView({
5918
6234
  context,
5919
6235
  schema
5920
6236
  }) {
6237
+ var _context$__behaviors_;
6238
+
5921
6239
  const Ctx = useTraversal();
5922
6240
  const {
5923
6241
  getBehavior
5924
6242
  } = Ctx.registry;
5925
- const behaviors = [].concat(context.__behaviors__, context['@static_behaviors']);
6243
+ const behaviors = [...((_context$__behaviors_ = context.__behaviors__) != null ? _context$__behaviors_ : []), ...Object(context['@static_behaviors'])];
5926
6244
 
5927
- const GetBehavior = b => {
5928
- const Cls = getBehavior(b, BehaviorNotImplemented);
6245
+ const GetBehavior = behaviorName => {
6246
+ const Cls = getBehavior(behaviorName, BehaviorNotImplemented);
5929
6247
  return jsx(Cls, {
5930
- values: context[b],
5931
- properties: get$1(schema, ['definitions', b, 'properties'], {})
6248
+ values: context[behaviorName],
6249
+ properties: get(schema, ['definitions', behaviorName, 'properties'], {})
5932
6250
  });
5933
6251
  };
5934
6252
 
@@ -6005,10 +6323,14 @@ function PanelProperties() {
6005
6323
 
6006
6324
  const ignoreFields = Ctx.registry.getProperties(Ctx.context['@type']).ignoreField || cfg.properties_ignore_fields || _ignoreFields;
6007
6325
 
6008
- 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 => ({
6009
- key,
6010
- value: schema.data.properties[key]
6011
- }));
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
+ });
6012
6334
  useEffect(() => {
6013
6335
  async function getSchema() {
6014
6336
  if (!schema.loading && !schema.data && !schema.error) {
@@ -6016,7 +6338,7 @@ function PanelProperties() {
6016
6338
  setSchema({
6017
6339
  loading: true
6018
6340
  });
6019
- const dataJson = await Ctx.client.getTypeSchema(Ctx.path, model.type);
6341
+ const dataJson = await Ctx.client.getTypeSchema(Ctx.path, Ctx.context.type_name);
6020
6342
  setSchema({
6021
6343
  loading: false,
6022
6344
  data: dataJson
@@ -6081,7 +6403,7 @@ function PanelProperties() {
6081
6403
  }), jsx("td", {
6082
6404
  children: jsx(EditableField, {
6083
6405
  field: prop,
6084
- value: Ctx.context[prop],
6406
+ value: get(Ctx.context, prop, ''),
6085
6407
  modifyContent: false
6086
6408
  })
6087
6409
  })]
@@ -6107,7 +6429,7 @@ function PanelProperties() {
6107
6429
  key,
6108
6430
  value
6109
6431
  }) => {
6110
- var _schema$data$required, _schema$data2;
6432
+ var _schema$data$required, _schema$data3;
6111
6433
 
6112
6434
  return jsxs("tr", {
6113
6435
  children: [jsx("td", {
@@ -6118,10 +6440,10 @@ function PanelProperties() {
6118
6440
  }), jsx("td", {
6119
6441
  children: jsx(EditableField, {
6120
6442
  field: key,
6121
- value: Ctx.context[key],
6443
+ value: get(Ctx.context, key, ''),
6122
6444
  schema: value,
6123
6445
  modifyContent: modifyContent,
6124
- 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)
6125
6447
  })
6126
6448
  })]
6127
6449
  }, 'prop' + key);
@@ -6155,12 +6477,6 @@ function PermissionPrinperm({
6155
6477
  error: undefined
6156
6478
  });
6157
6479
 
6158
- const getMultiples = (field, setter) => values => {
6159
- setter({
6160
- [field]: values
6161
- });
6162
- };
6163
-
6164
6480
  const savePermission = async () => {
6165
6481
  if (!state.principal || !state.setting || state.permission.length === 0) {
6166
6482
  setState({
@@ -6204,7 +6520,7 @@ function PermissionPrinperm({
6204
6520
  children: intl.formatMessage(genericMessages.select_principal)
6205
6521
  }), jsx(Select, {
6206
6522
  appendDefault: true,
6207
- options: principals,
6523
+ options: principals != null ? principals : [],
6208
6524
  onChange: value => setState({
6209
6525
  principal: value
6210
6526
  }),
@@ -6216,8 +6532,12 @@ function PermissionPrinperm({
6216
6532
  className: "label",
6217
6533
  children: intl.formatMessage(genericMessages.select_permissions)
6218
6534
  }), jsx(Select, {
6219
- options: permissions,
6220
- onChange: getMultiples('permission', setState),
6535
+ options: permissions != null ? permissions : [],
6536
+ onChange: values => {
6537
+ setState({
6538
+ permission: values
6539
+ });
6540
+ },
6221
6541
  size: 5,
6222
6542
  multiple: true,
6223
6543
  dataTest: "selectPermissionsTest"
@@ -6264,12 +6584,6 @@ function PermissionPrinrole({
6264
6584
  error: undefined
6265
6585
  });
6266
6586
 
6267
- const getMultiples = (field, setter) => values => {
6268
- setter({
6269
- [field]: values
6270
- });
6271
- };
6272
-
6273
6587
  const savePermission = async () => {
6274
6588
  if (!state.principal || !state.setting || state.roles.length === 0) {
6275
6589
  setState({
@@ -6313,7 +6627,7 @@ function PermissionPrinrole({
6313
6627
  children: intl.formatMessage(genericMessages.select_principal)
6314
6628
  }), jsx(Select, {
6315
6629
  appendDefault: true,
6316
- options: principals,
6630
+ options: principals != null ? principals : [],
6317
6631
  onChange: value => setState({
6318
6632
  principal: value
6319
6633
  }),
@@ -6326,7 +6640,11 @@ function PermissionPrinrole({
6326
6640
  children: intl.formatMessage(genericMessages.select_role)
6327
6641
  }), jsx(Select, {
6328
6642
  options: roles,
6329
- onChange: getMultiples('roles', setState),
6643
+ onChange: values => {
6644
+ setState({
6645
+ roles: values
6646
+ });
6647
+ },
6330
6648
  size: 5,
6331
6649
  multiple: true,
6332
6650
  dataTest: "selectRoleTest"
@@ -6373,12 +6691,6 @@ function PermissionRoleperm({
6373
6691
  error: undefined
6374
6692
  });
6375
6693
 
6376
- const getMultiples = (field, setter) => values => {
6377
- setter({
6378
- [field]: values
6379
- });
6380
- };
6381
-
6382
6694
  const savePermission = async () => {
6383
6695
  if (!state.role || !state.setting || state.permission.length === 0) {
6384
6696
  setState({
@@ -6434,8 +6746,12 @@ function PermissionRoleperm({
6434
6746
  className: "label",
6435
6747
  children: intl.formatMessage(genericMessages.select_permissions)
6436
6748
  }), jsx(Select, {
6437
- options: permissions,
6438
- onChange: getMultiples('permission', setState),
6749
+ options: permissions != null ? permissions : [],
6750
+ onChange: values => {
6751
+ setState({
6752
+ permission: values
6753
+ });
6754
+ },
6439
6755
  dataTest: "selectPermissionsTest",
6440
6756
  size: 5,
6441
6757
  multiple: true
@@ -6561,7 +6877,18 @@ function PanelPermissions() {
6561
6877
  useEffect(() => {
6562
6878
  get('@sharing');
6563
6879
  }, [reset]);
6564
- 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
+
6565
6892
  return jsxs("div", {
6566
6893
  className: "columns",
6567
6894
  children: [!loading && jsxs("div", {
@@ -6698,12 +7025,12 @@ function AddPermission({
6698
7025
  let roles = [];
6699
7026
  const principalsData = await Ctx.client.getPrincipals(Ctx.path);
6700
7027
  const groups = principalsData.groups.map(group => ({
6701
- text: group.id,
6702
- value: group.id
7028
+ text: group['@name'],
7029
+ value: group['@name']
6703
7030
  }));
6704
7031
  const users = principalsData.users.map(user => ({
6705
- text: user.fullname || user.id,
6706
- value: user.id
7032
+ text: user.fullname || user['@name'],
7033
+ value: user['@name']
6707
7034
  }));
6708
7035
  principals = [...groups, ...users];
6709
7036
  const req = await Ctx.client.getRoles(Ctx.path);
@@ -6756,14 +7083,6 @@ const prepareAvailable = (items, already, title) => {
6756
7083
  text: `Add ${title}`
6757
7084
  };
6758
7085
  if (items.length === 0) return [];
6759
-
6760
- if (items[0] && typeof items[0] === 'string') {
6761
- return [def].concat(items.map(x => ({
6762
- value: x,
6763
- text: x
6764
- }))).filter(item => !already.includes(item.value));
6765
- }
6766
-
6767
7086
  return [def].concat(items).filter(item => !already.includes(item.value));
6768
7087
  };
6769
7088
 
@@ -6775,7 +7094,7 @@ function TagsWidget({
6775
7094
  onChange,
6776
7095
  loading
6777
7096
  }) {
6778
- const selectRef = useRef();
7097
+ const selectRef = useRef(null);
6779
7098
  const [result, setResult] = useState(items);
6780
7099
  const availableData = prepareAvailable(available || [], result, title);
6781
7100
 
@@ -6813,7 +7132,7 @@ function TagsWidget({
6813
7132
  marginBottom: '20px'
6814
7133
  },
6815
7134
  children: noData
6816
- }), available.length > 1 && jsx("li", {
7135
+ }), (available != null ? available : []).length > 1 && jsx("li", {
6817
7136
  className: "widget-list-add select is-small",
6818
7137
  children: jsx(Select, {
6819
7138
  options: availableData,
@@ -6831,12 +7150,12 @@ function TagsWidget({
6831
7150
  });
6832
7151
  }
6833
7152
 
6834
- const initialState$3 = {
6835
- types: undefined
7153
+ const initialState$4 = {
7154
+ types: []
6836
7155
  };
6837
7156
  function CreateButton() {
6838
7157
  const intl = useIntl();
6839
- const [state, setState] = useSetState(initialState$3);
7158
+ const [state, setState] = useSetState(initialState$4);
6840
7159
  const Ctx = useTraversal();
6841
7160
  const Config = useConfig();
6842
7161
  useEffect(() => {
@@ -6872,7 +7191,8 @@ function CreateButton() {
6872
7191
 
6873
7192
  if (state.types && state.types.length === 0) {
6874
7193
  return null;
6875
- }
7194
+ } // Implement some kind of filtering
7195
+
6876
7196
 
6877
7197
  return jsx(Dropdown, {
6878
7198
  id: "dropdown-menu",
@@ -6895,11 +7215,11 @@ function ContextToolbar({
6895
7215
  AddButton
6896
7216
  }) {
6897
7217
  const intl = useIntl();
6898
- const [state, setState] = useSetState(initialState$3);
7218
+ const [state, setState] = useSetState(initialState$4);
6899
7219
  const [location, setLocation, del] = useLocation();
6900
7220
  const traversal = useTraversal();
6901
7221
  const Config = useConfig();
6902
- const searchText = location.get('q');
7222
+ const searchText = location.get('q') || '';
6903
7223
  const [searchValue, setSearchValue] = useState(searchText || '');
6904
7224
  useEffect(() => {
6905
7225
  loadTypes();
@@ -6915,14 +7235,13 @@ function ContextToolbar({
6915
7235
  });
6916
7236
  }
6917
7237
 
6918
- const onSearchQuery = ev => {
6919
- const search = ev.target[0].value;
7238
+ const onSearchQuery = event => {
7239
+ event.preventDefault();
6920
7240
  setLocation({
6921
- q: search,
7241
+ q: event.currentTarget.elements.filterInput.value,
6922
7242
  tab: 'Items',
6923
7243
  page: 0
6924
7244
  });
6925
- ev.preventDefault();
6926
7245
  };
6927
7246
 
6928
7247
  const onSearchByType = typeText => {
@@ -6954,7 +7273,8 @@ function ContextToolbar({
6954
7273
  type: "text",
6955
7274
  className: "input is-size-7",
6956
7275
  placeholder: intl.formatMessage(genericMessages.search),
6957
- "data-test": "inputFilterTest"
7276
+ "data-test": "inputFilterTest",
7277
+ id: "filterInput"
6958
7278
  })
6959
7279
  }), jsx("div", {
6960
7280
  className: "control",
@@ -6979,7 +7299,7 @@ function ContextToolbar({
6979
7299
  text: item,
6980
7300
  value: item
6981
7301
  })),
6982
- onChange: onSearchByType
7302
+ onChange: value => onSearchByType(value)
6983
7303
  })
6984
7304
  }), traversal.hasPerm('guillotina.AddContent') && jsx("div", {
6985
7305
  className: "level-item",
@@ -7017,18 +7337,17 @@ function TabsPanel({
7017
7337
  fallback = FallbackTab
7018
7338
  }) {
7019
7339
  const [location, setLocation] = useLocation();
7020
-
7021
- if (location.get('tab')) {
7022
- currentTab = location.get('tab');
7023
- } else {
7024
- currentTab = currentTab || Object.keys(tabs)[0];
7025
- }
7340
+ currentTab = location.get('tab') || Object.keys(tabs)[0];
7341
+ /*if (!Object.keys(tabs).includes(currentTab)) {
7342
+ setLocation(defaultTab)
7343
+ currentTab = defaultTab
7344
+ }*/
7026
7345
 
7027
7346
  const [current, setTab] = useState(currentTab);
7028
7347
  const CurrentComp = tabs[current] || fallback;
7029
7348
  React.useEffect(() => {
7030
7349
  if (Object.keys(tabs).includes(currentTab)) {
7031
- setTab(currentTab);
7350
+ setTab(currentTab); // setLocation({tab: currentTab})
7032
7351
  }
7033
7352
  }, [currentTab, tabs]);
7034
7353
 
@@ -7083,14 +7402,14 @@ const tabsPermissions = {
7083
7402
  Behaviors: 'guillotina.ModifyContent',
7084
7403
  Permissions: 'guillotina.SeePermissions'
7085
7404
  };
7086
- function FolderCtx(props) {
7405
+ function FolderCtx() {
7087
7406
  const ctx = useTraversal();
7088
7407
  const calculated = ctx.filterTabs(tabs, tabsPermissions);
7089
- return jsx(TabsPanel, _extends({
7408
+ return jsx(TabsPanel, {
7090
7409
  tabs: calculated,
7091
7410
  currentTab: "Items",
7092
- rightToolbar: jsx(ContextToolbar, _extends({}, props))
7093
- }, props));
7411
+ rightToolbar: jsx(ContextToolbar, {})
7412
+ });
7094
7413
  }
7095
7414
 
7096
7415
  const tabs$1 = {
@@ -7104,21 +7423,22 @@ const tabsPermissions$1 = {
7104
7423
  Behaviors: 'guillotina.ModifyContent',
7105
7424
  Permissions: 'guillotina.SeePermissions'
7106
7425
  };
7107
- function ItemCtx(props) {
7426
+ function ItemCtx() {
7108
7427
  const ctx = useTraversal();
7109
7428
  const calculated = ctx.filterTabs(tabs$1, tabsPermissions$1);
7110
- return jsx(TabsPanel, _extends({
7429
+ return jsx(TabsPanel, {
7111
7430
  tabs: calculated,
7112
7431
  currentTab: "Properties"
7113
- }, props));
7432
+ });
7114
7433
  }
7115
7434
 
7116
7435
  function ApplicationCtx() {
7117
7436
  const intl = useIntl();
7118
- const context = useTraversal();
7437
+ const traversal = useTraversal();
7438
+ const appContext = traversal.state.context;
7119
7439
  const {
7120
7440
  databases
7121
- } = context.state.context;
7441
+ } = appContext;
7122
7442
  return jsxs(Fragment, {
7123
7443
  children: [jsx("h3", {
7124
7444
  children: intl.formatMessage({
@@ -7132,24 +7452,28 @@ function ApplicationCtx() {
7132
7452
  className: "container",
7133
7453
  children: [jsx(ItemTitle, {
7134
7454
  title: "Objects"
7135
- }), databases.map(db => jsx(Item, {
7136
- item: {
7137
- id: db,
7138
- path: `/${db}/`
7139
- },
7140
- icon: 'fas fa-database'
7141
- }, 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
+ })]
7142
7466
  })]
7143
7467
  });
7144
7468
  }
7145
7469
  function DatabaseCtx() {
7146
- const context = useTraversal();
7470
+ const traversal = useTraversal();
7147
7471
  const {
7148
7472
  containers
7149
- } = context.state.context;
7473
+ } = traversal.state.context;
7150
7474
  const {
7151
7475
  path
7152
- } = context.state;
7476
+ } = traversal.state;
7153
7477
  return jsx(Fragment, {
7154
7478
  children: jsxs("div", {
7155
7479
  className: "container",
@@ -7407,17 +7731,17 @@ function UsersToolbar() {
7407
7731
  const [location, setLocation] = useLocation();
7408
7732
  const searchText = location.get('q');
7409
7733
 
7410
- const onSearchQuery = ev => {
7411
- const search = ev.target[0].value;
7734
+ const onSearchQuery = event => {
7735
+ event.preventDefault();
7412
7736
  setLocation({
7413
- q: search,
7737
+ q: event.currentTarget.elements.filterInput.value,
7414
7738
  page: 0
7415
7739
  });
7416
- ev.preventDefault();
7417
- };
7740
+ }; // cleanup form on state.search change
7741
+
7418
7742
 
7419
7743
  useEffect(() => {
7420
- if (!searchText || searchText === '') {
7744
+ if (ref.current && (!searchText || searchText === '')) {
7421
7745
  ref.current.value = '';
7422
7746
  }
7423
7747
  }, [searchText]);
@@ -7437,7 +7761,8 @@ function UsersToolbar() {
7437
7761
  type: "text",
7438
7762
  className: "input is-size-7",
7439
7763
  placeholder: intl.formatMessage(genericMessages.search),
7440
- "data-test": "inputFilterTest"
7764
+ "data-test": "inputFilterTest",
7765
+ id: "filterInput"
7441
7766
  })
7442
7767
  }), jsx("div", {
7443
7768
  className: "control",
@@ -7467,12 +7792,12 @@ function UsersToolbar() {
7467
7792
  })]
7468
7793
  });
7469
7794
  }
7470
- function UsersCtx(props) {
7471
- return jsx(TabsPanel, _extends({
7795
+ function UsersCtx() {
7796
+ return jsx(TabsPanel, {
7472
7797
  tabs: tabs$3,
7473
7798
  currentTab: "Users",
7474
7799
  rightToolbar: jsx(UsersToolbar, {})
7475
- }, props));
7800
+ });
7476
7801
  }
7477
7802
  function UserCtx() {
7478
7803
  const intl = useIntl();
@@ -7485,9 +7810,10 @@ function UserCtx() {
7485
7810
  roles: [],
7486
7811
  groups: []
7487
7812
  });
7813
+ const userDataContext = Ctx.context;
7488
7814
  const fields = {
7489
7815
  user_groups: [],
7490
- user_roles: Ctx.context.user_roles
7816
+ user_roles: userDataContext.user_roles
7491
7817
  };
7492
7818
  const [remotes, updateRemote] = useRemoteField(fields);
7493
7819
  useEffect(() => {
@@ -7565,7 +7891,7 @@ function UserCtx() {
7565
7891
  "value": "Username"
7566
7892
  }]
7567
7893
  }), ":", ' ']
7568
- }), ' ', Ctx.context.username, " (", Ctx.context.email, ")"]
7894
+ }), ' ', userDataContext.username, " (", userDataContext.email, ")"]
7569
7895
  }), jsxs("p", {
7570
7896
  children: [jsxs("label", {
7571
7897
  children: [' ', intl.formatMessage({
@@ -7575,7 +7901,7 @@ function UserCtx() {
7575
7901
  "value": "Creation Date"
7576
7902
  }]
7577
7903
  }), ":", ' ']
7578
- }), ' ', formatDate(Ctx.context.creation_date)]
7904
+ }), ' ', formatDate(userDataContext.creation_date)]
7579
7905
  }), jsxs("p", {
7580
7906
  children: [jsxs("label", {
7581
7907
  children: [' ', intl.formatMessage({
@@ -7585,7 +7911,7 @@ function UserCtx() {
7585
7911
  "value": "Modification Date"
7586
7912
  }]
7587
7913
  }), ":", ' ']
7588
- }), ' ', formatDate(Ctx.context.modification_date)]
7914
+ }), ' ', formatDate(userDataContext.modification_date)]
7589
7915
  }), jsx(Button, {
7590
7916
  className: "is-size-7 is-info",
7591
7917
  onClick: () => {
@@ -7602,7 +7928,7 @@ function UserCtx() {
7602
7928
  }), jsx("hr", {}), jsx(UserForm, {
7603
7929
  actionName: "Save",
7604
7930
  onSubmit: ev => updateObject(ev),
7605
- formData: Ctx.context,
7931
+ formData: userDataContext,
7606
7932
  exclude: ['password'],
7607
7933
  remotes: remotes,
7608
7934
  submitButton: false,
@@ -7616,7 +7942,7 @@ function UserCtx() {
7616
7942
  className: "column",
7617
7943
  children: [jsx(TagsWidget, {
7618
7944
  onChange: updateRemote('user_groups'),
7619
- items: Ctx.context.user_groups,
7945
+ items: userDataContext.user_groups,
7620
7946
  title: "Groups",
7621
7947
  noData: intl.formatMessage({
7622
7948
  id: "there_is_no_groups_for_this_user",
@@ -7637,7 +7963,10 @@ function UserCtx() {
7637
7963
  "value": "The user doesn't have any role"
7638
7964
  }]
7639
7965
  }),
7640
- available: state.roles
7966
+ available: state.roles.map(x => ({
7967
+ value: x,
7968
+ text: x
7969
+ }))
7641
7970
  })]
7642
7971
  })]
7643
7972
  })]
@@ -7655,7 +7984,7 @@ function CopyItems(props) {
7655
7984
  async function copyItems(path, form) {
7656
7985
  const responses = await Promise.all(items.map((item, i) => {
7657
7986
  const input = form[i + 1] || {};
7658
- return Ctx.client.post(`${Ctx.path}${item['@name']}/@duplicate`, {
7987
+ return Ctx.client.post(`${Ctx.path}${item.id}/@duplicate`, {
7659
7988
  destination: path,
7660
7989
  new_id: input.value || getNewId(item.id)
7661
7990
  });
@@ -7691,7 +8020,7 @@ function CopyItems(props) {
7691
8020
  }), jsx("input", {
7692
8021
  type: "text",
7693
8022
  className: "input",
7694
- "data-test": `inputCopyIdTest-${item['@name']}`,
8023
+ "data-test": `inputCopyIdTest-${item.id}`,
7695
8024
  defaultValue: getNewId(item.id)
7696
8025
  })]
7697
8026
  }, item.id)), "\u00A0"]
@@ -7761,9 +8090,9 @@ function MoveItems(props) {
7761
8090
 
7762
8091
  async function moveItems(path) {
7763
8092
  const responses = await Promise.all(items.map(item => {
7764
- return Ctx.client.post(`${Ctx.path}${item['@name']}/@move`, {
8093
+ return Ctx.client.post(`${Ctx.path}${item.id}/@move`, {
7765
8094
  destination: path,
7766
- new_id: item['@name']
8095
+ new_id: item.id
7767
8096
  });
7768
8097
  }));
7769
8098
  Ctx.refresh();
@@ -8052,17 +8381,17 @@ function GroupToolbar() {
8052
8381
  const [location, setLocation] = useLocation();
8053
8382
  const searchText = location.get('q');
8054
8383
 
8055
- const onSearchQuery = ev => {
8056
- const search = ev.target[0].value;
8384
+ const onSearchQuery = event => {
8385
+ event.preventDefault();
8057
8386
  setLocation({
8058
- q: search,
8387
+ q: event.currentTarget.elements.filterInput.value,
8059
8388
  page: 0
8060
8389
  });
8061
- ev.preventDefault();
8062
- };
8390
+ }; // cleanup form on state.search change
8391
+
8063
8392
 
8064
8393
  useEffect(() => {
8065
- if (!searchText || searchText === '') {
8394
+ if (ref.current && (!searchText || searchText === '')) {
8066
8395
  ref.current.value = '';
8067
8396
  }
8068
8397
  }, [searchText]);
@@ -8082,7 +8411,8 @@ function GroupToolbar() {
8082
8411
  type: "text",
8083
8412
  className: "input is-size-7",
8084
8413
  placeholder: intl.formatMessage(genericMessages.search),
8085
- "data-test": "inputFilterTest"
8414
+ "data-test": "inputFilterTest",
8415
+ id: "filterInput"
8086
8416
  })
8087
8417
  }), jsx("div", {
8088
8418
  className: "control",
@@ -8118,12 +8448,12 @@ function GroupToolbar() {
8118
8448
  })]
8119
8449
  });
8120
8450
  }
8121
- function GroupsCtx(props) {
8122
- return jsx(TabsPanel, _extends({
8451
+ function GroupsCtx() {
8452
+ return jsx(TabsPanel, {
8123
8453
  tabs: tabs$4,
8124
8454
  currentTab: "Groups",
8125
8455
  rightToolbar: jsx(GroupToolbar, {})
8126
- }, props));
8456
+ });
8127
8457
  }
8128
8458
  const sortParsed = parser(`_sort_asc=id`);
8129
8459
  const searchParsed = parser('type_name=User');
@@ -8134,6 +8464,7 @@ function GroupCtx() {
8134
8464
  patch
8135
8465
  } = useCrudContext();
8136
8466
  const [roles, setRoles] = useState([]);
8467
+ const groupDataContext = Ctx.context;
8137
8468
  useEffect(() => {
8138
8469
  async function getRoles() {
8139
8470
  const requestGetRoles = await Ctx.client.getRoles(Ctx.path);
@@ -8168,9 +8499,9 @@ function GroupCtx() {
8168
8499
  isError,
8169
8500
  errorMessage
8170
8501
  } = await patch({
8171
- user_roles: Ctx.context.user_roles.concat(role)
8502
+ user_roles: groupDataContext.user_roles.concat(role)
8172
8503
  });
8173
- handleResponse(isError, intl.formatMessage({
8504
+ handleResponse(!!isError, intl.formatMessage({
8174
8505
  id: "role_added_to_group",
8175
8506
  defaultMessage: [{
8176
8507
  "type": 0,
@@ -8184,7 +8515,7 @@ function GroupCtx() {
8184
8515
  }]
8185
8516
  }, {
8186
8517
  role
8187
- }), errorMessage);
8518
+ }), errorMessage != null ? errorMessage : '');
8188
8519
  };
8189
8520
 
8190
8521
  const removeRole = async role => {
@@ -8192,9 +8523,9 @@ function GroupCtx() {
8192
8523
  isError,
8193
8524
  errorMessage
8194
8525
  } = await patch({
8195
- user_roles: Ctx.context.user_roles.filter(r => r !== role)
8526
+ user_roles: groupDataContext.user_roles.filter(r => r !== role)
8196
8527
  });
8197
- handleResponse(isError, intl.formatMessage({
8528
+ handleResponse(!!isError, intl.formatMessage({
8198
8529
  id: "role_removed_from_group",
8199
8530
  defaultMessage: [{
8200
8531
  "type": 0,
@@ -8208,21 +8539,22 @@ function GroupCtx() {
8208
8539
  }]
8209
8540
  }, {
8210
8541
  role
8211
- }), errorMessage);
8542
+ }), errorMessage != null ? errorMessage : '');
8212
8543
  };
8213
8544
 
8214
8545
  const addUser = async newUserId => {
8215
8546
  const data = {};
8216
- Ctx.context.users.forEach(user => {
8547
+ groupDataContext.users.forEach(user => {
8217
8548
  data[user] = true;
8218
8549
  });
8219
8550
  data[newUserId] = true;
8551
+ const response = await Ctx.client.rest.patch(`${Ctx.containerPath}@groups/${Ctx.context['@name']}`, {
8552
+ users: data
8553
+ });
8220
8554
  const {
8221
8555
  isError,
8222
8556
  errorMessage
8223
- } = await Ctx.client.rest.patch(`${Ctx.containerPath}@groups/${Ctx.context['@name']}`, {
8224
- users: data
8225
- });
8557
+ } = await processResponse(response);
8226
8558
  handleResponse(isError, intl.formatMessage({
8227
8559
  id: "user_added_to_group",
8228
8560
  defaultMessage: [{
@@ -8237,20 +8569,21 @@ function GroupCtx() {
8237
8569
  }]
8238
8570
  }, {
8239
8571
  user: newUserId
8240
- }), errorMessage);
8572
+ }), errorMessage != null ? errorMessage : '');
8241
8573
  };
8242
8574
 
8243
8575
  const removeUser = async userToRemove => {
8244
8576
  const data = {};
8245
- Ctx.context.users.forEach(user => {
8577
+ groupDataContext.users.forEach(user => {
8246
8578
  data[user] = userToRemove !== user;
8247
8579
  });
8580
+ const response = await Ctx.client.rest.patch(`${Ctx.containerPath}@groups/${Ctx.context['@name']}`, {
8581
+ users: data
8582
+ });
8248
8583
  const {
8249
8584
  isError,
8250
8585
  errorMessage
8251
- } = await Ctx.client.rest.patch(`${Ctx.containerPath}@groups/${Ctx.context['@name']}`, {
8252
- users: data
8253
- });
8586
+ } = await processResponse(response);
8254
8587
  handleResponse(isError, intl.formatMessage({
8255
8588
  id: "user_removed_from_group",
8256
8589
  defaultMessage: [{
@@ -8265,7 +8598,7 @@ function GroupCtx() {
8265
8598
  }]
8266
8599
  }, {
8267
8600
  user: userToRemove
8268
- }), errorMessage);
8601
+ }), errorMessage != null ? errorMessage : '');
8269
8602
  };
8270
8603
 
8271
8604
  return jsxs("div", {
@@ -8315,10 +8648,10 @@ function GroupCtx() {
8315
8648
  }]
8316
8649
  })
8317
8650
  }), jsx(Select, {
8318
- options: roles.filter(role => !Ctx.context.user_roles.includes(role.value)),
8651
+ options: roles.filter(role => !groupDataContext.user_roles.includes(role.value)),
8319
8652
  appendDefault: true,
8320
- onChange: addRole
8321
- }), 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", {
8322
8655
  className: "control",
8323
8656
  children: jsx(Tag, {
8324
8657
  name: urole,
@@ -8346,7 +8679,7 @@ function GroupCtx() {
8346
8679
  traversal: Ctx,
8347
8680
  onChange: addUser,
8348
8681
  btnClass: "is-small"
8349
- }), jsx("hr", {}), Ctx.context.users.map(user => jsx("p", {
8682
+ }), jsx("hr", {}), groupDataContext.users.map(user => jsx("p", {
8350
8683
  className: "control",
8351
8684
  children: jsx(Tag, {
8352
8685
  name: user,
@@ -8477,7 +8810,7 @@ function Path() {
8477
8810
  const links = buildPaths(segments);
8478
8811
 
8479
8812
  if (segments.length === 1) {
8480
- return false;
8813
+ return null;
8481
8814
  }
8482
8815
 
8483
8816
  return jsx("nav", {
@@ -8603,11 +8936,13 @@ const get$2 = (key, param, fallback = undefined) => {
8603
8936
  };
8604
8937
 
8605
8938
  const getComponent = (context, path, fallback = undefined) => {
8606
- if (!context) return;
8939
+ if (!context) return; // console.log("Component for path", path)
8940
+ // lookup by path
8607
8941
 
8608
8942
  if (registry.paths[path]) {
8609
8943
  return registry.paths[path];
8610
- }
8944
+ } // by type
8945
+
8611
8946
 
8612
8947
  if (registry.views[context['@type']]) {
8613
8948
  return registry.views[context['@type']];
@@ -8630,11 +8965,15 @@ const getItemsColumn = type => {
8630
8965
  return undefined;
8631
8966
  };
8632
8967
 
8633
- const getForm = (type, fallback = BaseForm) => {
8634
- 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;
8635
8974
  };
8636
8975
 
8637
- const getAction = (type, fallback = undefined) => {
8976
+ const getAction = (type, fallback) => {
8638
8977
  return registry.actions[type] || fallback;
8639
8978
  };
8640
8979
 
@@ -8650,11 +8989,14 @@ const getSchemas = type => {
8650
8989
  return registry.schemas[type] || {};
8651
8990
  };
8652
8991
 
8653
- const getFieldsToFilter = (type, fallback) => {
8992
+ const getFieldsToFilter = (type, fallback = ['title']) => {
8654
8993
  return registry.fieldsToFilter[type] || fallback;
8655
8994
  };
8656
8995
 
8657
- const getDefaultSortValue = (type, fallback) => {
8996
+ const getDefaultSortValue = (type, fallback = {
8997
+ key: 'id',
8998
+ direction: 'des'
8999
+ }) => {
8658
9000
  return registry.defaultSortValue[type] || fallback;
8659
9001
  };
8660
9002
 
@@ -8662,11 +9004,15 @@ const defaultComponent = context => {
8662
9004
  return context.is_folderish ? FolderCtx : ItemCtx;
8663
9005
  };
8664
9006
  function useRegistry(data) {
9007
+ // if data is provided we need to merge it into actual registry
8665
9008
  const ref = React.useRef();
8666
9009
 
8667
9010
  if (data && !ref.current) {
8668
9011
  ref.current = true;
8669
- 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
+ });
8670
9016
  }
8671
9017
 
8672
9018
  return {
@@ -8680,86 +9026,26 @@ function useRegistry(data) {
8680
9026
  getItemsColumn,
8681
9027
  getFieldsToFilter,
8682
9028
  getDefaultSortValue,
8683
- getSchemas
9029
+ getSchemas,
9030
+ getView
8684
9031
  };
8685
9032
  }
9033
+ /*
8686
9034
 
8687
- const initialState$4 = {
8688
- path: '',
8689
- loading: false,
8690
- context: undefined,
8691
- flash: {
8692
- message: undefined,
8693
- type: undefined
8694
- },
8695
- action: {
8696
- action: undefined,
8697
- params: undefined
9035
+ const registry = {
9036
+ paths: {
9037
+ "/db/guillotina/tags/": TagsContext
8698
9038
  },
8699
- permissions: undefined,
8700
- errorStatus: undefined,
8701
- registry: {},
8702
- refresh: undefined
8703
- };
8704
- function guillotinaReducer(state, action) {
8705
- switch (action.type) {
8706
- case 'SET_PATH':
8707
- return _extends({}, state, {
8708
- path: action.payload,
8709
- loading: true
8710
- });
8711
-
8712
- case 'SET_CONTEXT':
8713
- return _extends({}, state, action.payload, {
8714
- errorStatus: undefined,
8715
- loading: false
8716
- });
8717
-
8718
- case 'SET_ERROR':
8719
- return _extends({}, state, {
8720
- errorStatus: action.payload,
8721
- loading: false
8722
- });
8723
-
8724
- case 'SET_FLASH':
8725
- return _extends({}, state, action.payload);
8726
-
8727
- case 'CLEAR_FLASH':
8728
- return _extends({}, state, {
8729
- flash: {
8730
- message: undefined,
8731
- type: undefined
8732
- }
8733
- });
8734
-
8735
- case 'SET_ACTION':
8736
- return _extends({}, state, {
8737
- action: action.payload
8738
- });
9039
+ forms: {
9040
+ Tag: AddTagForm
9041
+ }
9042
+ }
8739
9043
 
8740
- case 'CLEAR_ACTION':
8741
- return _extends({}, state, {
8742
- action: {
8743
- action: undefined,
8744
- params: undefined
8745
- }
8746
- });
8747
9044
 
8748
- case 'REFRESH':
8749
- return _extends({}, state, {
8750
- refresh: Date.now(),
8751
- loading: !action.payload.transparent
8752
- });
9045
+ <guillotina registry={registry} />
8753
9046
 
8754
- case 'APPLY':
8755
- return _extends({}, state, {
8756
- context: _extends({}, state.context, action.payload)
8757
- });
8758
9047
 
8759
- default:
8760
- return state;
8761
- }
8762
- }
9048
+ */
8763
9049
 
8764
9050
  var actions = [
8765
9051
  {
@@ -11572,29 +11858,34 @@ function Guillotina(_ref) {
11572
11858
  props = _objectWithoutPropertiesLoose(_ref, ["auth", "locale"]);
11573
11859
 
11574
11860
  const messages = loadLocaleData(locale);
11575
- const url = props.url || 'http://localhost:8080';
11861
+ const url = props.url || 'http://localhost:8080'; // without trailing slash
11862
+
11576
11863
  const config = props.config || {};
11577
11864
  const client = useGuillotinaClient();
11578
11865
  const {
11579
11866
  Permissions
11580
11867
  } = useConfig(config);
11581
- const registry = useRegistry(props.registry || {});
11582
- 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
+
11583
11872
  const searchPath = location.get('path') || '/';
11584
11873
 
11585
11874
  if (searchPath && searchPath !== '') {
11586
- initialState$4.path = searchPath;
11875
+ initialState.path = searchPath;
11587
11876
  }
11588
11877
 
11589
- const [state, dispatch] = useReducer(guillotinaReducer, initialState$4);
11878
+ const [state, dispatch] = useReducer(guillotinaReducer, initialState);
11590
11879
  const {
11591
11880
  path,
11592
11881
  refresh
11593
11882
  } = state;
11594
11883
  useEffect(() => {
11595
11884
  dispatch({
11596
- type: 'SET_PATH',
11597
- payload: searchPath
11885
+ type: GuillotinaReducerActionTypes.SET_PATH,
11886
+ payload: {
11887
+ path: searchPath
11888
+ }
11598
11889
  });
11599
11890
  }, [searchPath]);
11600
11891
  useEffect(() => {
@@ -11603,14 +11894,18 @@ function Guillotina(_ref) {
11603
11894
 
11604
11895
  if (data.status === 401) {
11605
11896
  dispatch({
11606
- type: 'SET_ERROR',
11607
- payload: 'notallowed'
11897
+ type: GuillotinaReducerActionTypes.SET_ERROR,
11898
+ payload: {
11899
+ errorStatus: 'notallowed'
11900
+ }
11608
11901
  });
11609
11902
  return;
11610
11903
  } else if (data.status === 404) {
11611
11904
  dispatch({
11612
- type: 'SET_ERROR',
11613
- payload: 'notfound'
11905
+ type: GuillotinaReducerActionTypes.SET_ERROR,
11906
+ payload: {
11907
+ errorStatus: 'notallowed'
11908
+ }
11614
11909
  });
11615
11910
  return;
11616
11911
  }
@@ -11619,7 +11914,7 @@ function Guillotina(_ref) {
11619
11914
  const pr = await client.canido(path, Permissions);
11620
11915
  const permissions = await pr.json();
11621
11916
  dispatch({
11622
- type: 'SET_CONTEXT',
11917
+ type: GuillotinaReducerActionTypes.SET_CONTEXT,
11623
11918
  payload: {
11624
11919
  context,
11625
11920
  permissions
@@ -11629,9 +11924,9 @@ function Guillotina(_ref) {
11629
11924
 
11630
11925
  initContext();
11631
11926
  }, [path, refresh, client]);
11632
- const ErrorBoundary = registry.get('views', 'ErrorBoundary');
11633
- const NotAllowed = registry.get('views', 'NotAllowed');
11634
- const NotFound = registry.get('views', 'NotFound');
11927
+ const ErrorBoundary = registry.getView('ErrorBoundary');
11928
+ const NotAllowed = registry.getView('NotAllowed');
11929
+ const NotFound = registry.getView('NotFound');
11635
11930
  const Path = registry.get('components', 'Path');
11636
11931
  const contextData = {
11637
11932
  url,
@@ -11656,7 +11951,7 @@ function Guillotina(_ref) {
11656
11951
  children: jsxs(ErrorBoundary, {
11657
11952
  children: [!errorStatus && jsx(TraversalProvider, _extends({}, contextData, {
11658
11953
  children: permissions && jsxs(React.Fragment, {
11659
- children: [action.action && jsx(Action, _extends({}, action.params)), jsx("div", {
11954
+ children: [action.action && Action !== null && jsx(Action, _extends({}, action.params)), jsx("div", {
11660
11955
  className: "level",
11661
11956
  children: jsx("div", {
11662
11957
  className: "level-left",
@@ -11665,7 +11960,7 @@ function Guillotina(_ref) {
11665
11960
  children: jsx(Path, {})
11666
11961
  })
11667
11962
  })
11668
- }), jsx(Flash, {}), Main && jsx(ErrorBoundary, {
11963
+ }), jsx(Flash, {}), Main !== undefined && jsx(ErrorBoundary, {
11669
11964
  children: jsxs("div", {
11670
11965
  className: "box main-panel",
11671
11966
  children: [state.loading && jsx(Loading, {}), !state.loading && jsx(Main, {
@@ -11771,7 +12066,7 @@ const ERRORS = {
11771
12066
  const initialState$5 = {
11772
12067
  username: '',
11773
12068
  password: '',
11774
- loading: undefined,
12069
+ loading: false,
11775
12070
  errors: undefined
11776
12071
  };
11777
12072
  const Login = ({
@@ -11784,7 +12079,7 @@ const Login = ({
11784
12079
  const [state, setState] = useSetState(initialState$5);
11785
12080
  const inputRef = useRef(null);
11786
12081
  useEffect(() => {
11787
- if (inputRef) {
12082
+ if (inputRef && inputRef.current) {
11788
12083
  inputRef.current.focus();
11789
12084
  }
11790
12085
  }, [inputRef]);
@@ -11961,28 +12256,28 @@ function RequiredFieldsForm({
11961
12256
  dataTest: dataTest,
11962
12257
  children: [schema && schema.data && !schema.loading && schema.formFields.map(key => {
11963
12258
  if (!ignoreFiels.includes(key)) {
11964
- var _value$title;
12259
+ var _schema$data, _value$title, _schema$data2;
11965
12260
 
11966
- const value = schema.data.properties[key];
12261
+ const value = (_schema$data = schema.data) == null ? void 0 : _schema$data.properties[key];
11967
12262
  return jsx(EditComponent, {
11968
12263
  id: key,
11969
12264
  placeholder: (_value$title = value == null ? void 0 : value.title) != null ? _value$title : '',
11970
12265
  className: "",
11971
12266
  required: true,
11972
- schema: schema.data.properties[key],
11973
- setValue: ev => {
12267
+ schema: (_schema$data2 = schema.data) == null ? void 0 : _schema$data2.properties[key],
12268
+ setValue: value => {
11974
12269
  if (key === 'title') {
11975
12270
  setFormData(_extends({}, formData, {
11976
- uuid: stringToSlug(ev),
11977
- [key]: ev
12271
+ uuid: stringToSlug(value),
12272
+ [key]: value
11978
12273
  }));
11979
12274
  } else if (key === 'uuid') {
11980
12275
  setFormData(_extends({}, formData, {
11981
- uuid: stringToSlug(ev)
12276
+ uuid: stringToSlug(value)
11982
12277
  }));
11983
12278
  } else {
11984
12279
  setFormData(_extends({}, formData, {
11985
- [key]: ev
12280
+ [key]: value
11986
12281
  }));
11987
12282
  }
11988
12283
  },
@@ -12108,6 +12403,7 @@ class Auth {
12108
12403
  });
12109
12404
 
12110
12405
  if (data.status === 401) {
12406
+ // invalid token
12111
12407
  this.cleanAuth();
12112
12408
  this.logout();
12113
12409
  return;
@@ -12158,7 +12454,7 @@ class Auth {
12158
12454
 
12159
12455
  if (!authToken) return {};
12160
12456
 
12161
- if (this.willExpire(expires) && this.retryRefresh < this.maxRetry) {
12457
+ if (this.willExpire(expires != null ? expires : '') && this.retryRefresh < this.maxRetry) {
12162
12458
 
12163
12459
  (async function () {
12164
12460
  return await _this.refreshToken();
@@ -12174,5 +12470,14 @@ class Auth {
12174
12470
 
12175
12471
  }
12176
12472
 
12177
- 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 };
12178
12483
  //# sourceMappingURL=react-gmi.modern.js.map