@entryscape/rdforms 10.6.0 → 10.7.0

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 (49) hide show
  1. package/dist/rdforms.bmd.js +7 -5
  2. package/dist/rdforms.bootstrap.js +17 -15
  3. package/dist/rdforms.jquery.js +6 -4
  4. package/dist/rdforms.node.js +273 -3
  5. package/dist/rdforms.react.js +78 -76
  6. package/package.json +4 -2
  7. package/src/model/CODES.js +17 -0
  8. package/src/model/CardinalityTracker.js +2 -1
  9. package/src/model/ChoiceBinding.js +1 -1
  10. package/src/model/engine.js +1 -19
  11. package/src/model/validate.js +21 -20
  12. package/src/template/Item.js +2 -1
  13. package/src/view/Editor.js +4 -3
  14. package/src/view/Presenter.js +32 -3
  15. package/src/view/Registry.js +1 -1
  16. package/src/view/ValidationPresenter.js +3 -2
  17. package/src/view/View.js +52 -10
  18. package/src/view/bmd/DateTimeMD.js +12 -14
  19. package/src/view/bmd/Selectize.js +5 -4
  20. package/src/view/bmd/style.css +9 -1
  21. package/src/view/bootstrap/DateTimeBootstrapDatepicker.js +6 -4
  22. package/src/view/bootstrap/RadioButtonsEditor.js +5 -2
  23. package/src/view/bootstrap/Select2.js +8 -5
  24. package/src/view/bootstrap/buttons.js +9 -5
  25. package/src/view/bootstrap/choice.js +6 -4
  26. package/src/view/bootstrap/durationEditor.js +3 -2
  27. package/src/view/bootstrap/labels.js +26 -15
  28. package/src/view/bootstrap/style.css +9 -3
  29. package/src/view/bootstrap/text.js +7 -4
  30. package/src/view/jquery/labels.js +15 -0
  31. package/src/view/jquery/text.js +3 -3
  32. package/src/view/react/buttons.js +3 -0
  33. package/src/view/react/choiceEditors/CheckBoxesEditor.js +8 -3
  34. package/src/view/react/choiceEditors/ChoiceLookup.js +4 -2
  35. package/src/view/react/choiceEditors/ChoiceLookupAndInlineSearch.js +25 -16
  36. package/src/view/react/choiceEditors/ChoiceSelector.js +7 -4
  37. package/src/view/react/choiceEditors/RadioButtonsEditor.js +8 -4
  38. package/src/view/react/choiceEditors/ShowButton.js +1 -0
  39. package/src/view/react/date.js +7 -5
  40. package/src/view/react/duration.js +4 -2
  41. package/src/view/react/hooks.js +3 -0
  42. package/src/view/react/labels.js +41 -5
  43. package/src/view/react/style.css +6 -6
  44. package/src/view/react/text.js +2 -2
  45. package/src/view/react/textEditors.js +5 -0
  46. package/src/view/renderingContext.js +5 -0
  47. package/src/view/resources/rdforms.css +39 -17
  48. package/src/view/{jquery/util.js → viewUtils.js} +11 -0
  49. package/src/view/react/util.js +0 -31
@@ -2,7 +2,8 @@
2
2
  import React, { useState, useEffect, useMemo } from 'react';
3
3
  import TextField from '@mui/material/TextField';
4
4
  import renderingContext from '../renderingContext';
5
- import { toDuration, fromDuration } from './util';
5
+ import { toDuration, fromDuration } from '../viewUtils';
6
+ import { useNamedGraphId } from './hooks';
6
7
 
7
8
  const keys = ['years', 'months', 'days', 'hours', 'minutes'];
8
9
  const editors = renderingContext.editorRegistry;
@@ -44,11 +45,12 @@ editors.itemtype('text').datatype('xsd:duration').register((fieldDiv, binding, c
44
45
  }, {}));
45
46
 
46
47
  const descBy = context.view.getLabelIndex(binding);
47
-
48
+ const ngId = useNamedGraphId(binding, context);
48
49
  return <>{keys.map(key => (<TextField
49
50
  key={key}
50
51
  className="rdformsDurationInput"
51
52
  value={`${duration[key] || ''}`}
53
+ disabled={!!ngId}
52
54
  label={bundle[`duration_${key}`]}
53
55
  type="number"
54
56
  onChange={onChange[key]}
@@ -1,5 +1,6 @@
1
1
  import { useState, useEffect, useMemo } from 'react';
2
2
  import utils from '../../utils';
3
+ import { getNamedGraphId } from '../viewUtils';
3
4
 
4
5
  /**
5
6
  * Wraps a choice in an object where the current label, and description is localized.
@@ -91,3 +92,5 @@ export const useName = () => useMemo(() => {
91
92
  nameCounter += 1;
92
93
  return `_rdforms_${nameCounter}`;
93
94
  }, []);
95
+
96
+ export const useNamedGraphId = (binding, context) => useMemo(() => getNamedGraphId(binding, context));
@@ -5,7 +5,7 @@ import { styled } from '@mui/material/styles';
5
5
  import ClickAwayListener from '@mui/material/ClickAwayListener';
6
6
  import renderingContext from '../renderingContext';
7
7
  import { Editor } from './Wrappers';
8
- import { CODES } from '../../model/engine';
8
+ import CODES from '../../model/CODES';
9
9
 
10
10
  const StyledTooltip = styled(
11
11
  forwardRef(({ className, ...props }, ref) => (
@@ -74,12 +74,30 @@ renderingContext.renderPresenterLabel = (rowNode, binding, item, context) => {
74
74
  } else {
75
75
  label = '';
76
76
  }
77
+
78
+ const view = context.view;
79
+ let description;
80
+ if (item.hasStyle('showDescriptionInPresent') || view.showDescription) {
81
+ // An item is compact if it is exclicitly set as compact or
82
+ // the view is set as compact and the item is not explicitly set as not compact AND
83
+ // we are at the top
84
+ const compactField = item.hasStyle('compact') ||
85
+ (view.compact && !item.hasStyle('nonCompact') && (
86
+ (view.topLevel && item.getType() !== 'group') ||
87
+ (view.parentView && view.parentView.topLevel && view.binding.getItem().hasStyle('heading'))));
88
+ const desc = view instanceof Editor ? item.getEditDescription() || item.getDescription() :
89
+ item.getDescription();
90
+ if (!compactField && desc) {
91
+ description = <div className="rdformsDescription" tabIndex="0">{desc}</div>;
92
+ }
93
+ }
94
+
77
95
  const labelId = binding ? context.view.createLabelIndex(binding) : undefined;
78
96
  label = item.hasStyle('heading') ?
79
97
  <h2 tabIndex="0" id={labelId} className="rdformsLabelRow"><span className="rdformsLabel">{label}</span></h2> :
80
98
  <span tabIndex="0" id={labelId} className="rdformsLabelRow"><span className="rdformsLabel">{label}</span></span>;
81
- rowNode.appendChild(<ItemTooltip key={`${binding ? binding.getHash() : item._internalId}_label` }
82
- context={context} item={item}>{label}</ItemTooltip>);
99
+ rowNode.appendChild(<><ItemTooltip key={`${binding ? binding.getHash() : item._internalId}_label` }
100
+ context={context} item={item}>{label}</ItemTooltip>{description}</>);
83
101
  };
84
102
 
85
103
  renderingContext.renderEditorLabel = (rowNode, binding, item, context) => {
@@ -113,9 +131,27 @@ renderingContext.renderEditorLabel = (rowNode, binding, item, context) => {
113
131
  } else if (item.getType() === 'group' && !context.view.showAsTable(item)) {
114
132
  Button = renderingContext.addRemoveButton(rowNode, binding, context);
115
133
  }
134
+
135
+ const view = context.view;
136
+ let description;
137
+ if (item.hasStyle('showDescriptionInEdit') || view.showDescription) {
138
+ // An item is compact if it is exclicitly set as compact or
139
+ // the view is set as compact and the item is not explicitly set as not compact AND
140
+ // we are at the top
141
+ const compactField = item.hasStyle('compact') ||
142
+ (view.compact && !item.hasStyle('nonCompact') && (
143
+ (view.topLevel && item.getType() !== 'group') ||
144
+ (view.parentView && view.parentView.topLevel && view.binding.getItem().hasStyle('heading'))));
145
+ const desc = view instanceof Editor ? item.getEditDescription() || item.getDescription() :
146
+ item.getDescription();
147
+ if (!compactField && desc) {
148
+ description = <div className="rdformsDescription" tabIndex="0">{desc}</div>;
149
+ }
150
+ }
151
+
116
152
  const labelId = context.view.createLabelIndex(binding);
117
- rowNode.appendChild(<div key={`${binding.getHash()}_label`} id={labelId} className="rdformsLabelRow">{
118
- label}{mark}{Button && <Button></Button>}</div>);
153
+ rowNode.appendChild(<><div key={`${binding.getHash()}_label`} id={labelId} className="rdformsLabelRow">{
154
+ label}{mark}{Button && <Button></Button>}</div>{description}</>);
119
155
  }
120
156
  };
121
157
 
@@ -133,7 +133,7 @@
133
133
  }
134
134
 
135
135
  .rdformsEditor .rdformsLangControl {
136
- width: calc(33.33% - 8px);
136
+ width: calc(33.33% - 4px);
137
137
  }
138
138
 
139
139
  /* Duration */
@@ -205,10 +205,6 @@ div.MuiTooltip-tooltip {
205
205
  margin-right: 11px;
206
206
  }
207
207
 
208
- .rdformsEditor .rdformsLangControl {
209
- width: calc(33.33% - 8px);
210
- }
211
-
212
208
  .rdformsDependency {
213
209
  display: none;
214
210
  }
@@ -227,4 +223,8 @@ div.MuiTooltip-tooltip {
227
223
  font-size: 10px;
228
224
  font-weight: bolder;
229
225
  font-family: sans-serif;
230
- }
226
+ }
227
+
228
+ .rdformsHeading>.rdformsDescription {
229
+ margin: -20px 0 20px;
230
+ }
@@ -3,7 +3,7 @@ import React, { useState, useEffect, useMemo } from 'react';
3
3
  import moment from 'moment';
4
4
  import system from '../../model/system';
5
5
  import renderingContext from '../renderingContext';
6
- import { fromDuration } from './util';
6
+ import { fromDuration } from '../viewUtils';
7
7
  import utils from '../../utils';
8
8
 
9
9
 
@@ -13,7 +13,7 @@ presenters.itemtype('text').datatype('xsd:duration').register((fieldDiv, binding
13
13
  const data = fromDuration(binding.getValue());
14
14
  const keys = ['years', 'months', 'days', 'hours', 'minutes'];
15
15
  fieldDiv.appendChild(<div key={binding.getHash()}>{keys.map(key => (
16
- data[key] && <React.Fragment key={key}><span className="durationlabel">{
16
+ data[key] && <React.Fragment key={key}><span className="durationLabel">{
17
17
  context.view.messages[`duration_${key}`]}:</span><span className="durationValue">{data[key]}</span></React.Fragment>
18
18
  ))}</div>);
19
19
  });
@@ -10,6 +10,7 @@ import Select from '@mui/material/Select';
10
10
  import moment from 'moment';
11
11
  import renderingContext from '../renderingContext';
12
12
  import utils from '../../utils';
13
+ import { useNamedGraphId } from './hooks';
13
14
 
14
15
  const LanguageControl = (props) => {
15
16
  const [lang, setLang] = useState(props.binding.getLanguage() || '');
@@ -38,10 +39,12 @@ const LanguageControl = (props) => {
38
39
  };
39
40
  }, []);
40
41
 
42
+ const ngId = useNamedGraphId(props.binding, props.context);
41
43
  return <FormControl className="rdformsLangControl" variant={renderingContext.materialVariant}>
42
44
  <Select
43
45
  inputProps={{ 'aria-labelledby': props.labelledby }}
44
46
  value={lang}
47
+ disabled={!!ngId}
45
48
  onChange={onLangChange}>
46
49
  {langs.map(langOption => (langOption === null ?
47
50
  (<MenuItem key="_none" value="_none" disabled>─────</MenuItem>) :
@@ -90,11 +93,13 @@ editors.itemtype('text').register((fieldDiv, binding, context) => {
90
93
  },
91
94
  };
92
95
  const bundle = context.view.messages;
96
+ const ngId = useNamedGraphId(binding, context);
93
97
  return <><TextField
94
98
  className={extLink || langlit ? 'rdformsTwoThirds' : ''}
95
99
  multiline={multiline}
96
100
  placeholder={item.getPlaceholder()}
97
101
  error={!valid}
102
+ disabled={!!ngId}
98
103
  helperText={!valid ? item.getHelp() || '' : ''}
99
104
  variant={renderingContext.materialVariant} inputProps={iprops}
100
105
  />{extLink && (value != null || value === '') &&
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-unused-vars */
1
2
  import Registry from './Registry';
2
3
  import system from '../model/system';
3
4
  import nls from './resources/nls';
@@ -328,7 +329,9 @@ const groupPresenter = (fieldDiv, binding, context) => {
328
329
  messages: context.view.messages,
329
330
  binding,
330
331
  topLevel: false,
332
+ compact: context.view.compact,
331
333
  showLanguage: context.view.showLanguage,
334
+ showDescription: context.view.showDescription,
332
335
  defaultLanguage: context.view.defaultLanguage,
333
336
  filterTranslations: context.view.filterTranslations,
334
337
  includeLevel: context.view.includeLevel, // Copied from groupEditor, was this.includeLevel but that 'this' does not make sense here
@@ -346,6 +349,8 @@ const groupEditor = (fieldDiv, binding, context) => {
346
349
  languages: context.view.languages,
347
350
  binding,
348
351
  topLevel: false,
352
+ compact: context.view.compact,
353
+ showDescription: context.view.showDescription,
349
354
  includeLevel: context.view.includeLevel,
350
355
  }, fieldDiv);
351
356
  context.view._subEditors.push(subView);
@@ -136,11 +136,11 @@ a.rdformsUrl:hover {
136
136
 
137
137
  /* compact anyway for first level*/
138
138
  .compact .rdformsTopLevel.rdformsRow.notCompact {
139
- display: table;
139
+ display: inherit;
140
140
  width: 98%;
141
141
  }
142
142
  .compact .rdformsTopLevel.rdformsRow.notCompact>div {
143
- display: table-cell;
143
+ display: block;
144
144
  }
145
145
 
146
146
  .compact .rdformsTopLevel.rdformsRow.rdformsHeading.notCompact>div {
@@ -151,6 +151,27 @@ a.rdformsUrl:hover {
151
151
  margin-left: 0px;
152
152
  }
153
153
 
154
+ .compact .rdformsRow.notCompact {
155
+ display: block;
156
+ width: auto;
157
+ }
158
+
159
+ .compact .rdformsRow.notCompact>div {
160
+ display: inherit;
161
+ }
162
+
163
+ .rdformsPresenter .rdformsRow.rdformsCompactItem {
164
+ display: table;
165
+ width: 98%;
166
+ }
167
+
168
+ .rdformsPresenter .rdformsRow.rdformsCompactItem>.rdformsLabel {
169
+ width: 10em;
170
+ }
171
+ .rdformsPresenter .rdformsRow.rdformsCompactItem>div {
172
+ display: table-cell;
173
+ }
174
+
154
175
  /* compact anyway for first level*/
155
176
  .compact .rdformsTopLevel.rdformsRow.rdformsHeading>.rdformsFields>.rdformsGroup>.rdformsRow {
156
177
  display: table;
@@ -161,6 +182,16 @@ a.rdformsUrl:hover {
161
182
  display: table-cell;
162
183
  }
163
184
 
185
+ .compact .rdformsTopLevel.rdformsRow.rdformsHeading>.rdformsFields>.rdformsGroup>.rdformsRow.notCompact {
186
+ display: inherit;
187
+ width: auto;
188
+ }
189
+
190
+ .compact .rdformsTopLevel.rdformsRow.rdformsHeading>.rdformsFields>.rdformsGroup>.rdformsRow.notCompact>div {
191
+ display: inherit;
192
+ }
193
+
194
+
164
195
 
165
196
 
166
197
  .rdformsImage {
@@ -420,10 +451,6 @@ a.rdformsUrl:hover {
420
451
  padding-left: 0px;
421
452
  }
422
453
 
423
- .rdformsValidator .rdformsValidationMessageWrapper {
424
- margin-left: -30px;
425
- }
426
-
427
454
  .rdformsValidator .rdformsField.error {
428
455
  color: red;
429
456
  }
@@ -484,18 +511,8 @@ a.rdformsUrl:hover {
484
511
  padding-left: 0px;
485
512
  }
486
513
 
487
- .compact .rdformsRow.notCompact {
488
- display: block;
489
- width: auto;
490
- }
491
-
492
- .compact .rdformsRow.notCompact>div {
493
- display: inherit;
494
- }
495
-
496
514
  .compact .rdformsRow>.rdformsLabelRow {
497
- width: 1px;
498
- white-space: nowrap;
515
+ white-space: nowrap;
499
516
  }
500
517
 
501
518
  .compact .rdformsTopLevel.rdformsRow>.rdformsLabelRow .action {
@@ -717,4 +734,9 @@ a.rdformsUrl:hover {
717
734
  .rdformsDeprecated {
718
735
  border: 2px solid red;
719
736
  padding: 12px;
737
+ }
738
+
739
+ .rdformsDescription {
740
+ font-style: italic;
741
+ margin-bottom: 10px;
720
742
  }
@@ -32,6 +32,7 @@ export const toDuration = (data) => {
32
32
  return null;
33
33
  };
34
34
 
35
+
35
36
  export const getDate = (value) => {
36
37
  try {
37
38
  // xsd:time
@@ -199,3 +200,13 @@ export const getDatePresentation = (binding) => {
199
200
  }
200
201
  return undefined;
201
202
  };
203
+
204
+ export const getNamedGraphId = (binding, context) => {
205
+ const ng = (binding.getStatement() || binding.getParent().getStatement())?.getNamedGraph();
206
+ if (ng) {
207
+ let view = context.view;
208
+ while (view.getParentView()) view = view.getParentView();
209
+ return view.getNamedGraphId(ng);
210
+ }
211
+ return undefined;
212
+ };
@@ -1,31 +0,0 @@
1
- export const fromDuration = (value) => {
2
- const f = val => (val && val.length > 1 ? parseInt(val[0], 10) : 0);
3
- const years = f(value.match(/([0-9])*Y/));
4
- const days = f(value.match(/([0-9])*D/));
5
- const hours = f(value.match(/([0-9])*H/));
6
- let months;
7
- let minutes;
8
- if (value.indexOf('T') === -1) {
9
- months = f(value.match(/([0-9])*M/));
10
- } else {
11
- const arr = value.split('T');
12
- months = f(arr[0].match(/([0-9])*M/));
13
- minutes = f(arr[1].match(/([0-9])*M/));
14
- }
15
- return { years, months, days, hours, minutes };
16
- };
17
-
18
- export const toDuration = (data) => {
19
- if (data.years || data.months || data.days || data.hours || data.minutes) {
20
- let str = `P${data.years ? `${data.years}Y` : ''
21
- }${data.months ? `${data.months}M` : ''
22
- }${data.days ? `${data.days}D` : ''}`;
23
- if (data.hours || data.minutes) {
24
- str = `${str}T${
25
- data.hours ? `${data.hours}H` : ''
26
- }${data.minutes ? `${data.minutes}M` : ''}`;
27
- }
28
- return str;
29
- }
30
- return null;
31
- };