@onehat/ui 0.4.62 → 0.4.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onehat/ui",
3
- "version": "0.4.62",
3
+ "version": "0.4.64",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -61,8 +61,8 @@ function TagComponent(props) {
61
61
  await repository.waitUntilDoneLoading();
62
62
  }
63
63
  let record = repository.getById(id); // first try to get from entities in memory
64
- if (!record && repository.getSingleEntityFromServer) {
65
- record = await repository.getSingleEntityFromServer(id);
64
+ if (!record && repository.loadOneAdditionalEntity) {
65
+ record = await repository.loadOneAdditionalEntity(id);
66
66
  }
67
67
 
68
68
  if (!record) {
@@ -83,6 +83,7 @@ function Form(props) {
83
83
  editorType = EDITOR_TYPE__WINDOWED, // EDITOR_TYPE__INLINE | EDITOR_TYPE__WINDOWED | EDITOR_TYPE__SIDE | EDITOR_TYPE__SMART | EDITOR_TYPE__PLAIN
84
84
  startingValues = {},
85
85
  items = [], // Columns, FieldSets, Fields, etc to define the form
86
+ isItemsCustomLayout = false,
86
87
  ancillaryItems = [], // additional items which are not controllable form elements, but should appear in the form
87
88
  showAncillaryButtons = false,
88
89
  columnDefaults = {}, // defaults for each Column defined in items (above)
@@ -1187,8 +1188,8 @@ function Form(props) {
1187
1188
  formComponents = buildFromItems();
1188
1189
  const formAncillaryComponents = buildAncillary();
1189
1190
  editor = <>
1190
- {containerWidth >= styles.FORM_ONE_COLUMN_THRESHOLD ? <HStack className="Form-formComponents-HStack p-4 gap-4 justify-center">{formComponents}</HStack> : null}
1191
- {containerWidth < styles.FORM_ONE_COLUMN_THRESHOLD ? <VStack className="Form-formComponents-VStack p-4">{formComponents}</VStack> : null}
1191
+ {containerWidth >= styles.FORM_ONE_COLUMN_THRESHOLD && !isItemsCustomLayout ? <HStack className="Form-formComponents-HStack p-4 gap-4 justify-center">{formComponents}</HStack> : null}
1192
+ {containerWidth < styles.FORM_ONE_COLUMN_THRESHOLD || isItemsCustomLayout ? <VStack className="Form-formComponents-VStack p-4">{formComponents}</VStack> : null}
1192
1193
  {formAncillaryComponents.length ? <VStack className="Form-AncillaryComponents m-2 pt-4 px-2">{formAncillaryComponents}</VStack> : null}
1193
1194
  </>;
1194
1195
 
@@ -29,6 +29,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
29
29
  userCanEdit = true, // not permissions, but capability
30
30
  userCanView = true,
31
31
  canEditorViewOnly = false, // whether the editor can *ever* change state out of 'View' mode
32
+ canProceedWithCrud, // fn returns bool on if the CRUD operation can proceed
32
33
  disableAdd = false,
33
34
  disableEdit = false,
34
35
  disableDelete = false,
@@ -153,6 +154,9 @@ export default function withEditor(WrappedComponent, isTree = false) {
153
154
  showPermissionsError(ADD);
154
155
  return;
155
156
  }
157
+ if (canProceedWithCrud && !canProceedWithCrud()) {
158
+ return;
159
+ }
156
160
 
157
161
  const selection = getSelection();
158
162
  let addValues = values;
@@ -252,6 +256,9 @@ export default function withEditor(WrappedComponent, isTree = false) {
252
256
  showPermissionsError(EDIT);
253
257
  return;
254
258
  }
259
+ if (canProceedWithCrud && !canProceedWithCrud()) {
260
+ return;
261
+ }
255
262
  const selection = getSelection();
256
263
  if (_.isEmpty(selection) || (_.isArray(selection) && (selection.length > 1 || selection[0]?.isDestroyed))) {
257
264
  return;
@@ -271,6 +278,9 @@ export default function withEditor(WrappedComponent, isTree = false) {
271
278
  showPermissionsError(DELETE);
272
279
  return;
273
280
  }
281
+ if (canProceedWithCrud && !canProceedWithCrud()) {
282
+ return;
283
+ }
274
284
  let cb = null;
275
285
  if (_.isFunction(args)) {
276
286
  cb = args;
@@ -368,6 +378,9 @@ export default function withEditor(WrappedComponent, isTree = false) {
368
378
  showPermissionsError(VIEW);
369
379
  return;
370
380
  }
381
+ if (canProceedWithCrud && !canProceedWithCrud()) {
382
+ return;
383
+ }
371
384
  if (editorType === EDITOR_TYPE__INLINE) {
372
385
  alert('Cannot view in inline editor.');
373
386
  return; // inline editor doesn't have a view mode
@@ -395,6 +408,9 @@ export default function withEditor(WrappedComponent, isTree = false) {
395
408
  showPermissionsError(DUPLICATE);
396
409
  return;
397
410
  }
411
+ if (canProceedWithCrud && !canProceedWithCrud()) {
412
+ return;
413
+ }
398
414
 
399
415
  const selection = getSelection();
400
416
  if (selection.length !== 1) {
@@ -8,6 +8,7 @@ import {
8
8
  DUPLICATE,
9
9
  PRINT,
10
10
  UPLOAD_DOWNLOAD,
11
+ DOWNLOAD,
11
12
  } from '../../Constants/Commands.js';
12
13
  import Clipboard from '../Icons/Clipboard.js';
13
14
  import Duplicate from '../Icons/Duplicate.js';
@@ -17,6 +18,7 @@ import Trash from '../Icons/Trash.js';
17
18
  import Plus from '../Icons/Plus.js';
18
19
  import Print from '../Icons/Print.js';
19
20
  import UploadDownload from '../Icons/UploadDownload.js';
21
+ import Download from '../Icons/Download.js';
20
22
  import inArray from '../../Functions/inArray.js';
21
23
  import UploadsDownloadsWindow from '../Window/UploadsDownloadsWindow.js';
22
24
  import _ from 'lodash';
@@ -33,6 +35,7 @@ const presetButtons = [
33
35
  DUPLICATE,
34
36
  // PRINT,
35
37
  UPLOAD_DOWNLOAD,
38
+ DOWNLOAD,
36
39
  ];
37
40
 
38
41
  export default function withPresetButtons(WrappedComponent, isGrid = false) {
@@ -48,6 +51,7 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
48
51
  contextMenuItems = [],
49
52
  additionalToolbarButtons = [],
50
53
  useUploadDownload = false,
54
+ useDownload = false,
51
55
  uploadHeaders,
52
56
  uploadParams,
53
57
  onUpload,
@@ -57,7 +61,6 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
57
61
  canRecordBeEdited,
58
62
  canRecordBeDeleted,
59
63
  canRecordBeDuplicated,
60
- canProceedWithCrud, // fn returns bool on if the CRUD operation can proceed
61
64
  ...propsToPass
62
65
  } = props,
63
66
  {
@@ -177,6 +180,13 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
177
180
  isDisabled = true;
178
181
  }
179
182
  break;
183
+ case DOWNLOAD:
184
+ if (!useDownload) {
185
+ isDisabled = true;
186
+ } else if (canUser && !(canUser(DOWNLOAD) || canUser(UPLOAD_DOWNLOAD))) { // check Permissions
187
+ isDisabled = true;
188
+ }
189
+ break;
180
190
  default:
181
191
  }
182
192
  return isDisabled;
@@ -211,9 +221,6 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
211
221
  key = 'addBtn';
212
222
  text = 'Add';
213
223
  handler = (parent, e) => {
214
- if (canProceedWithCrud && !canProceedWithCrud()) {
215
- return;
216
- }
217
224
  onAdd();
218
225
  };
219
226
  icon = Plus;
@@ -227,9 +234,6 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
227
234
  key = 'editBtn';
228
235
  text = 'Edit';
229
236
  handler = (parent, e) => {
230
- if (canProceedWithCrud && !canProceedWithCrud()) {
231
- return;
232
- }
233
237
  onEdit();
234
238
  };
235
239
  icon = Edit;
@@ -247,9 +251,6 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
247
251
  text = 'Delete';
248
252
  handler = onDelete;
249
253
  handler = (parent, e) => {
250
- if (canProceedWithCrud && !canProceedWithCrud()) {
251
- return;
252
- }
253
254
  onDelete();
254
255
  };
255
256
  icon = Trash;
@@ -297,9 +298,6 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
297
298
  key = 'duplicateBtn';
298
299
  text = 'Duplicate';
299
300
  handler = (parent, e) => {
300
- if (canProceedWithCrud && !canProceedWithCrud()) {
301
- return;
302
- }
303
301
  onDuplicate();
304
302
  };
305
303
  icon = Duplicate;
@@ -323,6 +321,12 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
323
321
  handler = (parent, e) => onUploadDownload();
324
322
  icon = UploadDownload;
325
323
  break;
324
+ case DOWNLOAD:
325
+ key = 'downloadBtn';
326
+ text = 'Download';
327
+ handler = (parent, e) => onDownload();
328
+ icon = Download;
329
+ break;
326
330
  default:
327
331
  }
328
332
  return {
@@ -397,6 +401,20 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
397
401
  />,
398
402
  onCancel: hideModal,
399
403
  });
404
+ },
405
+ onDownload = () => {
406
+ showModal({
407
+ body: <UploadsDownloadsWindow
408
+ reference="downloads"
409
+ onClose={hideModal}
410
+ isDownloadOnly={true}
411
+ Repository={Repository}
412
+ columnsConfig={props.columnsConfig}
413
+ downloadHeaders={downloadHeaders}
414
+ downloadParams={downloadParams}
415
+ />,
416
+ onCancel: hideModal,
417
+ });
400
418
  };
401
419
  // onPrint = () => {
402
420
  // debugger;
@@ -25,6 +25,7 @@ function UploadsDownloadsWindow(props) {
25
25
  downloadHeaders,
26
26
  uploadParams = {},
27
27
  downloadParams = {},
28
+ isDownloadOnly = false,
28
29
  onUpload,
29
30
 
30
31
  // withComponent
@@ -124,6 +125,61 @@ function UploadsDownloadsWindow(props) {
124
125
  }
125
126
  }
126
127
  };
128
+
129
+ const items = [
130
+ {
131
+ type: 'DisplayField',
132
+ text: 'Download an Excel file of the current grid contents.',
133
+ },
134
+ {
135
+ type: 'Button',
136
+ text: 'Download',
137
+ isEditable: false,
138
+ icon: Excel,
139
+ _icon: {
140
+ size: 'md',
141
+ },
142
+ onPress: () => onDownload(),
143
+ className: 'mb-5',
144
+ },
145
+ ];
146
+ if (!isDownloadOnly) {
147
+ items.push({
148
+ type: 'DisplayField',
149
+ text: 'Upload an Excel file to the current grid.',
150
+ });
151
+ items.push({
152
+ type: 'File',
153
+ name: 'file',
154
+ onChangeValue: setImportFile,
155
+ accept: '.xlsx',
156
+ });
157
+ items.push({
158
+ type: 'Row',
159
+ className: 'mt-2',
160
+ items: [
161
+ {
162
+ type: 'Button',
163
+ text: 'Upload',
164
+ isEditable: false,
165
+ icon: Upload,
166
+ _icon: {
167
+ size: 'md',
168
+ },
169
+ isDisabled: !importFile,
170
+ onPress: onUploadLocal,
171
+ },
172
+ {
173
+ type: 'Button',
174
+ text: 'Get Template',
175
+ icon: Download,
176
+ isEditable: false,
177
+ onPress: onDownloadTemplate,
178
+ },
179
+
180
+ ],
181
+ });
182
+ }
127
183
 
128
184
  return <Panel
129
185
  {...props}
@@ -151,58 +207,7 @@ function UploadsDownloadsWindow(props) {
151
207
  "type": "Column",
152
208
  "flex": 1,
153
209
  "defaults": {},
154
- "items": [
155
- {
156
- type: 'DisplayField',
157
- text: 'Download an Excel file of the current grid contents.',
158
- },
159
- {
160
- type: 'Button',
161
- text: 'Download',
162
- isEditable: false,
163
- icon: Excel,
164
- _icon: {
165
- size: 'md',
166
- },
167
- onPress: () => onDownload(),
168
- className: 'mb-5',
169
- },
170
- {
171
- type: 'DisplayField',
172
- text: 'Upload an Excel file to the current grid.',
173
- },
174
- {
175
- type: 'File',
176
- name: 'file',
177
- onChangeValue: setImportFile,
178
- accept: '.xlsx',
179
- },
180
- {
181
- type: 'Row',
182
- className: 'mt-2',
183
- items: [
184
- {
185
- type: 'Button',
186
- text: 'Upload',
187
- isEditable: false,
188
- icon: Upload,
189
- _icon: {
190
- size: 'md',
191
- },
192
- isDisabled: !importFile,
193
- onPress: onUploadLocal,
194
- },
195
- {
196
- type: 'Button',
197
- text: 'Get Template',
198
- icon: Download,
199
- isEditable: false,
200
- onPress: onDownloadTemplate,
201
- },
202
-
203
- ],
204
- },
205
- ]
210
+ "items": items,
206
211
  },
207
212
  ]}
208
213
  // record={selection}
@@ -6,3 +6,4 @@ export const COPY = 'copy';
6
6
  export const DUPLICATE = 'duplicate';
7
7
  export const PRINT = 'print';
8
8
  export const UPLOAD_DOWNLOAD = 'uploadDownload';
9
+ export const DOWNLOAD = 'download';