@onehat/ui 0.2.84 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onehat/ui",
3
- "version": "0.2.84",
3
+ "version": "0.3.1",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -25,11 +25,12 @@
25
25
  },
26
26
  "license": "UNLICENSED",
27
27
  "dependencies": {
28
- "@onehat/data": "^1.18.12",
28
+ "@onehat/data": "^1.19.0",
29
29
  "@hookform/resolvers": "^3.3.1",
30
30
  "@k-renwick/colour-mixer": "^1.2.1",
31
31
  "@reduxjs/toolkit": "^1.9.5",
32
32
  "js-cookie": "^3.0.5",
33
+ "inflector-js": "^1.0.1",
33
34
  "native-base": "^3.4.28",
34
35
  "react-hook-form": "^7.45.0",
35
36
  "react-redux": "^8.1.2",
@@ -15,9 +15,9 @@ const
15
15
  ellipsizeMode="head"
16
16
  flex={1}
17
17
  fontSize={styles.FORM_TEXT_FONTSIZE}
18
- bg={styles.FORM_TEXT_BG}
18
+ minHeight='40px'
19
19
  px={3}
20
- py={1}
20
+ py={2}
21
21
  {...props}
22
22
  >{props.value}</Text>;
23
23
  },
@@ -199,7 +199,8 @@ function Form(props) {
199
199
  } = fieldState;
200
200
  let editorProps = {};
201
201
  if (!editor) {
202
- editor = model.editorTypes[fieldName];
202
+ const propertyDef = fieldName && Repository?.getSchema().getPropertyDefinition(fieldName);
203
+ editor = propertyDef[fieldName].editoType;
203
204
  if (_.isPlainObject(editor)) {
204
205
  const {
205
206
  type,
@@ -259,14 +260,16 @@ function Form(props) {
259
260
  } = item;
260
261
  let editorTypeProps = {};
261
262
 
262
- const model = Repository?.getSchema().model;
263
- if (!type && Repository) {
264
- const
265
- editorTypes = model.editorTypes,
263
+ const propertyDef = name && Repository?.getSchema().getPropertyDefinition(name);
264
+ if (propertyDef?.isEditingDisabled) {
265
+ isEditable = false;
266
+ }
267
+ if (isEditable && !type && Repository) {
268
+ const
266
269
  {
267
270
  type: t,
268
271
  ...p
269
- } = editorTypes[name];
272
+ } = propertyDef.editorType;
270
273
  type = t;
271
274
  editorTypeProps = p;
272
275
  }
@@ -287,12 +290,14 @@ function Form(props) {
287
290
  return <Element key={ix} title={title} {...defaults} {...propsToPass} {...editorTypeProps}>{children}</Element>;
288
291
  }
289
292
 
293
+ if (!label && Repository && propertyDef.title) {
294
+ label = propertyDef.title;
295
+ }
296
+
290
297
  if (isViewOnly || !isEditable) {
291
- const Text = getComponentFromType('Text');
292
- if (!label && Repository && model.titles?.[name]) {
293
- label = model.titles[name];
294
- }
295
- const value = (record && record[name]) || (startingValues && startingValues[name]) || null;
298
+ const
299
+ Text = getComponentFromType('Text'),
300
+ value = (record && record[name]) || (startingValues && startingValues[name]) || null;
296
301
  let element = <Text
297
302
  value={value}
298
303
  {...propsToPass}
@@ -307,9 +312,6 @@ function Form(props) {
307
312
  return <Row key={ix} px={2} pb={1}>{element}</Row>;
308
313
  }
309
314
 
310
- if (!label && Repository && model.titles?.[name]) {
311
- label = model.titles[name];
312
- }
313
315
 
314
316
 
315
317
  // // These rules are for fields *outside* the model
@@ -483,7 +485,6 @@ function Form(props) {
483
485
  let formComponents,
484
486
  editor;
485
487
  if (editorType === EDITOR_TYPE__INLINE) {
486
- // for inline editor
487
488
  formComponents = buildFromColumnsConfig();
488
489
  editor = <ScrollView
489
490
  horizontal={true}
@@ -495,8 +496,14 @@ function Form(props) {
495
496
  borderTopColor="primary.100"
496
497
  borderBottomColor="primary.100"
497
498
  >{formComponents}</ScrollView>;
499
+ } else if (editorType === EDITOR_TYPE__PLAIN) {
500
+ formComponents = buildFromItems();
501
+ const formAncillaryComponents = buildAncillary();
502
+ editor = <>
503
+ <Row>{formComponents}</Row>
504
+ <Column pt={4}>{formAncillaryComponents}</Column>
505
+ </>;
498
506
  } else {
499
- // for all other editor types
500
507
  formComponents = buildFromItems();
501
508
  const formAncillaryComponents = buildAncillary();
502
509
  editor = <ScrollView _web={{ height: 1 }} width="100%" pb={1}>
@@ -5,6 +5,12 @@ import {
5
5
  Row,
6
6
  Text,
7
7
  } from 'native-base';
8
+ import {
9
+ EDITOR_TYPE__PLAIN,
10
+ } from '../../Constants/Editor.js';
11
+ import {
12
+ FILTER_TYPE_ANCILLARY
13
+ } from '../../Constants/Filters.js';
8
14
  import inArray from '../../Functions/inArray.js';
9
15
  import getComponentFromType from '../../Functions/getComponentFromType.js';
10
16
  import IconButton from '../Buttons/IconButton.js';
@@ -50,11 +56,7 @@ export default function withFilters(WrappedComponent) {
50
56
  // aliases
51
57
  {
52
58
  defaultFilters: modelDefaultFilters,
53
- filterTypes: modelFilterTypes,
54
- titles: modelTitles,
55
- virtualFields: modelVirtualFields,
56
- excludeFields: modelExcludeFields,
57
- filteringDisabled: modelFilteringDisabled,
59
+ ancillaryFilters: modelAncillaryFilters,
58
60
  } = Repository.getSchema().model,
59
61
  id = useId(),
60
62
 
@@ -68,11 +70,30 @@ export default function withFilters(WrappedComponent) {
68
70
  getFormattedFilter = (filter) => {
69
71
  let formatted = null;
70
72
  if (_.isString(filter)) {
71
- const field = filter;
73
+ const
74
+ field = filter,
75
+ propertyDef = Repository.getSchema().getPropertyDefinition(field);
76
+
77
+ let title, type;
78
+ if (propertyDef) {
79
+ title = propertyDef.title;
80
+ type = propertyDef.filterType;
81
+ } else {
82
+ const modelFilterTypes = Repository.getSchema().getFilterTypes();
83
+ if (!modelFilterTypes[field]) {
84
+ throw Error('not a propertyDef, and not an ancillaryFilter!');
85
+ }
86
+
87
+ const ancillaryFilter = modelFilterTypes[field];
88
+ title = ancillaryFilter.title;
89
+ type = FILTER_TYPE_ANCILLARY;
90
+ }
91
+
92
+
72
93
  formatted = {
73
94
  field,
74
- title: modelTitles[field],
75
- type: modelFilterTypes[field],
95
+ title,
96
+ type,
76
97
  value: null, // value starts as null
77
98
  };
78
99
  } else if (_.isPlainObject(filter)) {
@@ -221,12 +242,19 @@ export default function withFilters(WrappedComponent) {
221
242
  _.each(filters, (filter, ix) => {
222
243
  let Element,
223
244
  elementProps = {};
224
- const {
245
+ let {
225
246
  field,
226
247
  type: filterType,
227
- } = filter;
248
+ } = filter,
249
+ propertyDef = Repository.getSchema().getPropertyDefinition(field);
228
250
 
229
251
  if (_.isString(filterType)) {
252
+ if (filterType === FILTER_TYPE_ANCILLARY) {
253
+ // Convert field to PluralCamelGrid
254
+ debugger;
255
+
256
+
257
+ }
230
258
  Element = getComponentFromType(filterType);
231
259
  if (filterType === 'Input') {
232
260
  elementProps.autoSubmit = true;
@@ -247,7 +275,7 @@ export default function withFilters(WrappedComponent) {
247
275
  elementProps.minWidth = 100;
248
276
  }
249
277
 
250
- const tooltip = filter.tooltip || filter.title || modelTitles[filter.field];
278
+ const tooltip = filter.tooltip || filter.title || propertyDef.title;
251
279
  let filterElement = <Element
252
280
  key={'filter-' + field}
253
281
  tooltip={tooltip}
@@ -259,7 +287,7 @@ export default function withFilters(WrappedComponent) {
259
287
  />;
260
288
  if (showLabels && field !== 'q') {
261
289
  filterElement = <Row key={'label-' + ix} alignItems="center">
262
- <Text ml={2} mr={1} fontSize={UiGlobals.styles.FILTER_LABEL_FONTSIZE}>{modelTitles[field]}</Text>
290
+ <Text ml={2} mr={1} fontSize={UiGlobals.styles.FILTER_LABEL_FONTSIZE}>{propertyDef.title}</Text>
263
291
  {filterElement}
264
292
  </Row>;
265
293
  }
@@ -383,17 +411,28 @@ export default function withFilters(WrappedComponent) {
383
411
  usedFields = _.filter(_.map(modalFilters, (filter) => {
384
412
  return filter?.field;
385
413
  }), el => !_.isNil(el)),
386
- formStartingValues = {};
414
+ formStartingValues = {},
415
+ modelFilterTypes = Repository.getSchema().getFilterTypes();
387
416
 
388
417
  _.each(modalSlots, (field, ix) => {
389
418
 
390
- // Create the data for the combobox.
419
+ // Create the data for the combobox. (i.e. List all the possible filters for this slot)
391
420
  const data = [];
392
421
  _.each(modelFilterTypes, (filterType, filterField) => {
393
422
  if (inArray(filterField, usedFields) && field !== filterField) { // Show all filters not yet applied, but include the current filter
394
423
  return; // skip, since it's already been used
395
424
  }
396
- data.push([ filterField, modelTitles[filterField] ]);
425
+
426
+ // Is it an ancillary filter?
427
+ const isAncillary = _.isPlainObject(filterType) && filterType.isAncillary;
428
+ if (isAncillary) {
429
+ data.push([ filterField, filterType.title ]);
430
+ return;
431
+ }
432
+
433
+ // basic property filter
434
+ const propertyDef = Repository.getSchema().getPropertyDefinition(filterField);
435
+ data.push([ filterField, propertyDef.title ]);
397
436
  });
398
437
 
399
438
  const
@@ -447,6 +486,7 @@ export default function withFilters(WrappedComponent) {
447
486
  <FormPanel
448
487
  title="Filter Selector"
449
488
  instructions="Please select which fields to filter by."
489
+ editorType={EDITOR_TYPE__PLAIN}
450
490
  flex={1}
451
491
  startingValues={formStartingValues}
452
492
  items={[
@@ -0,0 +1 @@
1
+ export const FILTER_TYPE_ANCILLARY = 'FILTER_TYPE_ANCILLARY';
@@ -38,7 +38,6 @@ const defaults = {
38
38
  FORM_LABEL_FONTSIZE: DEFAULT_FONTSIZE,
39
39
  FORM_NUMBER_FONTSIZE: DEFAULT_FONTSIZE,
40
40
  FORM_TEXT_FONTSIZE: DEFAULT_FONTSIZE,
41
- FORM_TEXT_BG: WHITE,
42
41
  FORM_TEXTAREA_BG: WHITE,
43
42
  FORM_TEXTAREA_FONTSIZE: DEFAULT_FONTSIZE,
44
43
  FORM_TEXTAREA_HEIGHT: 130,