@entryscape/rdforms 10.12.3 → 10.13.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
@@ -8,7 +8,7 @@
8
8
  "application profile",
9
9
  "linked data"
10
10
  ],
11
- "version": "10.12.3",
11
+ "version": "10.13.1",
12
12
  "main": "dist/rdforms.node.js",
13
13
  "browser": "dist/rdforms.react.js",
14
14
  "module": "main.js",
@@ -16,10 +16,10 @@
16
16
  "license": "LGPL-3.0-only",
17
17
  "homepage": "https://rdforms.org",
18
18
  "peerDependencies": {
19
- "@entryscape/rdfjson": "2.7.6"
19
+ "@entryscape/rdfjson": "2.7.7"
20
20
  },
21
21
  "dependencies": {
22
- "@entryscape/rdfjson": "2.7.6",
22
+ "@entryscape/rdfjson": "2.7.7",
23
23
  "@emotion/react": "^11.4.1",
24
24
  "@emotion/styled": "^11.3.0",
25
25
  "@fortawesome/fontawesome-free": "^5.8.1",
@@ -265,6 +265,11 @@ export default class ItemStore {
265
265
  }
266
266
  }
267
267
  if (id != null) {
268
+ if (this._registry[id]) {
269
+ console.log(`RDForms conflict with item id ${id}, overwriting item from bundle "${
270
+ this._registry[id].getBundle()?.getPath() || ''}" with item from bundle "${
271
+ item.getBundle()?.getPath() || ''}".`);
272
+ }
268
273
  this._registry[id] = item;
269
274
  if (bundle != null) {
270
275
  bundle.addItem(item);
@@ -18,7 +18,7 @@ const stopFetchingOrJustLog = (iteration, length, templateId) => {
18
18
  };
19
19
 
20
20
  /**
21
- * Return the first sucessfully fetched bundle from a list of urls or throw en error if none could be fetched
21
+ * Return the first successfully fetched bundle from a list of urls or throw en error if none could be fetched
22
22
  *
23
23
  * @param {Array<String>} urls
24
24
  * @returns {Promise<Response | never | void>}
@@ -27,14 +27,16 @@ const fetchBundle = async (urls) => {
27
27
  const totalUrls = urls.length;
28
28
  let response;
29
29
  let bundle;
30
+ let path;
30
31
 
31
32
 
32
33
  for (let i = 0; i < totalUrls; i++) {
33
34
  // try to fetch the bundle, fails only if there's some network error. A 404 is not an error
35
+ path = urls[i];
34
36
  try {
35
- response = await fetch(urls[i]);
37
+ response = await fetch(path);
36
38
  } catch (e) {
37
- throw Error(`A network error ocurred while trying to fetch bundle ${urls[i]}`);
39
+ throw Error(`A network error ocurred while trying to fetch bundle ${path}`);
38
40
  }
39
41
 
40
42
  // check if we got a 2xx
@@ -48,18 +50,18 @@ const fetchBundle = async (urls) => {
48
50
  bundle = await response.json();
49
51
  break;
50
52
  } else {
51
- throw new Error(`Failed fetching template ${urls[i]}. Expected a JSON file and got ${contentType}`);
53
+ throw new Error(`Failed fetching template ${path}. Expected a JSON file and got ${contentType}`);
52
54
  }
53
55
  } catch (e) {
54
- stopFetchingOrJustLog(i, totalUrls, urls[i]);
56
+ stopFetchingOrJustLog(i, totalUrls, path);
55
57
  }
56
58
  // got back something that's not a 2xx
57
59
  } else {
58
- stopFetchingOrJustLog(i, totalUrls, urls[i]);
60
+ stopFetchingOrJustLog(i, totalUrls, path);
59
61
  }
60
62
  }
61
63
 
62
- return bundle;
64
+ return {path, source: bundle};
63
65
  };
64
66
 
65
67
  /**
@@ -76,7 +78,7 @@ const promisifyBundles = bundles => bundles.map(bundle =>
76
78
  * @param {ItemStore} itemStore
77
79
  * @param {array} bundles
78
80
  */
79
- const registerBundles = (itemStore, bundles = []) => bundles.map(source => itemStore.registerBundle({ source }));
81
+ const registerBundles = (itemStore, bundles = []) => bundles.map(bundle => itemStore.registerBundle(bundle));
80
82
 
81
83
  /**
82
84
  *
package/src/view/View.js CHANGED
@@ -11,6 +11,7 @@ export default class View {
11
11
  constructor(params, srcNodeRef) {
12
12
  this._viewId = viewCounter;
13
13
  viewCounter += 1;
14
+ this.renderingParams = params.renderingParams || {};
14
15
  this.locale = params.locale;
15
16
  this.defaultTextLanguage = params.defaultTextLanguage;
16
17
  this.messages = params.messages;
@@ -23,6 +24,7 @@ export default class View {
23
24
  this.topLevel = params.topLevel !== false;
24
25
  this.compact = params.compact !== false;
25
26
  this.showDescription = params.showDescription === true;
27
+ this.popupOnLabel = params.popupOnLabel !== false;
26
28
  this.styleCls = params.styleCls || '';
27
29
  this.truncateLimit = params.truncateLimit !== undefined ? params.truncateLimit : 10;
28
30
  this.truncate = params.truncate !== undefined ? params.truncate : false;
@@ -67,7 +67,7 @@ renderingContext.renderEditorLabel = (rowNode, binding, item, context) => {
67
67
  let desc = utils.getLocalizedValue(descMap, context.view.getLocale()).value
68
68
 
69
69
  if (!compactField && desc) {
70
- jquery('<div class="rdformsDescription" tabindex="0">').text(desc).appendTo(rowNode);
70
+ jquery('<div class="rdformsDescription">').text(desc).appendTo(rowNode);
71
71
  }
72
72
  }
73
73
  renderingContext.attachItemInfo(item, $label[0], context);
@@ -76,6 +76,11 @@ renderingContext.renderEditorLabel = (rowNode, binding, item, context) => {
76
76
  };
77
77
 
78
78
  renderingContext.attachItemInfo = function (item, aroundNode, context) {
79
+ if (context.view.popupOnLabel === false) {
80
+ renderingContext.domClassToggle(aroundNode, 'rdformsNoPopup', true);
81
+ return;
82
+ }
83
+ renderingContext.domSetAttr(aroundNode, 'role', 'button');
79
84
  if (item == null || (item.getProperty() == null && item.getDescriptionMap() == null
80
85
  && item.getEditDescriptionMap() == null)) {
81
86
  jquery(aroundNode).addClass('noPointer');
@@ -102,7 +107,7 @@ renderingContext.attachItemInfo = function (item, aroundNode, context) {
102
107
  }
103
108
  const popoverOptions = {
104
109
  html: true,
105
- container: renderingContext.getPopoverContainer(),
110
+ container: aroundNode, // renderingContext.getPopoverContainer(),
106
111
  placement: 'auto',
107
112
  trigger: 'focus',
108
113
  title: label,
@@ -36,7 +36,7 @@ renderingContext.renderPresenterLabel = (rowNode, binding, item, context, labelR
36
36
  const desc = utils.getLocalizedValue(item.getDescriptionMap(), context.view.getLocale()).value
37
37
 
38
38
  if (!compactField && desc) {
39
- jquery('<div class="rdformsDescription" tabindex="0">').text(desc).appendTo(rowNode);
39
+ jquery('<div class="rdformsDescription">').text(desc).appendTo(rowNode);
40
40
  }
41
41
  }
42
42
 
@@ -122,6 +122,7 @@ export default (props) => {
122
122
  getOptionDisabled={option => option.mismatch === true}
123
123
  renderInput={renderInput}
124
124
  disablePortal
125
+ {...props.context.view.renderingParams.ChoiceLookupAndInlineSearch}
125
126
  />
126
127
  <ShowButton {...props} onClick={showHandler} disabled={!!ngId}/>
127
128
  {value && value.original.upgrade && (
@@ -66,6 +66,7 @@ export default (props) => {
66
66
  filterSelectedOptions
67
67
  renderInput={renderInput}
68
68
  disablePortal
69
+ {...props.context.view.renderingParams.ChoiceSelector}
69
70
  />
70
71
  {error && (
71
72
  <div key="warning" className="rdformsWarning">
@@ -2,7 +2,7 @@
2
2
  import React, { Fragment, useState, useEffect, forwardRef } from 'react';
3
3
  import Tooltip, { tooltipClasses } from '@mui/material/Tooltip';
4
4
  import { styled } from '@mui/material/styles';
5
- import ClickAwayListener from '@mui/material/ClickAwayListener';
5
+ import { ClickAwayListener } from '@mui/base/ClickAwayListener';
6
6
  import renderingContext from '../renderingContext';
7
7
  import utils from '../../utils';
8
8
  import { Editor } from './Wrappers';
@@ -26,6 +26,39 @@ const StyledTooltip = styled(
26
26
  },
27
27
  }));
28
28
 
29
+ const ItemTooltipTitle = ({description, propinfo, setOpen, tooltipId}) => {
30
+ useEffect(() => {
31
+ console.log("Inited useEffect");
32
+ const focusListener = (event) => {
33
+ console.log("Focuslistener called");
34
+ let el = event.target;
35
+ let external = true;
36
+ while (el) {
37
+ if (el.id === tooltipId) {
38
+ external = false;
39
+ break;
40
+ }
41
+ el = el.parentElement;
42
+ }
43
+ if (external) {
44
+ setOpen(false);
45
+ }
46
+ };
47
+ window.addEventListener('focusin', focusListener);
48
+ return () => {
49
+ console.log("Focuslistener removed");
50
+ window.removeEventListener('focusin', focusListener);
51
+ };
52
+ }, []);
53
+
54
+ return (<>
55
+ <p className="rdformsLinebreaks rdformsDescription">
56
+ {description}
57
+ </p>
58
+ {propinfo}
59
+ </>);
60
+ };
61
+
29
62
  const ItemTooltip = (props) => {
30
63
  const [open, setOpen] = useState(false);
31
64
  const handleTooltipClose = () => {
@@ -42,28 +75,31 @@ const ItemTooltip = (props) => {
42
75
  const descriptionMap = props.context.view instanceof Editor ?
43
76
  props.item.getEditDescriptionMap() || props.item.getDescriptionMap() : props.item.getDescriptionMap()
44
77
  || (property ? '' : props.context.view.messages.info_missing || '');
45
- const description = utils.getLocalizedValue(descriptionMap, props.context.view.getLocale()).value
78
+ const description = utils.getLocalizedValue(descriptionMap, props.context.view.getLocale()).value;
79
+ const tooltipId = `tt_${props.binding.getHash()}`;
46
80
 
47
81
  return (
48
82
  <ClickAwayListener onClickAway={handleTooltipClose}>
49
- <StyledTooltip
50
- title={
51
- <>
52
- <p className="rdformsLinebreaks rdformsDescription">
53
- {description}
54
- </p>
55
- {propinfo}
56
- </>
57
- }
58
- placement="bottom-start"
59
- disableHoverListener
60
- disableTouchListener
61
- onClose={handleTooltipClose}
62
- onOpen={handleTooltipOpen}
63
- open={open}
64
- >
65
- <span onClick={handleTooltipOpen}>{props.children}</span>
66
- </StyledTooltip>
83
+ <div id={tooltipId}>
84
+ <StyledTooltip
85
+ title={<ItemTooltipTitle description={description} propinfo={propinfo} setOpen={setOpen} tooltipId={tooltipId}></ItemTooltipTitle>}
86
+ placement="bottom-start"
87
+ disableHoverListener
88
+ disableTouchListener
89
+ disableFocusListener
90
+ onFocus={handleTooltipOpen}
91
+ onOpen={handleTooltipOpen}
92
+ onClose={handleTooltipClose}
93
+ open={open}
94
+ slotProps={{
95
+ popper: {
96
+ disablePortal: true
97
+ },
98
+ }}
99
+ >
100
+ <span onClick={handleTooltipOpen}>{props.children}</span>
101
+ </StyledTooltip>
102
+ </div>
67
103
  </ClickAwayListener>
68
104
  );
69
105
  };
@@ -92,16 +128,22 @@ renderingContext.renderPresenterLabel = (rowNode, binding, item, context) => {
92
128
  item.getDescriptionMap();
93
129
  const desc = utils.getLocalizedValue(descMap, context.view.getLocale()).value;
94
130
  if (!compactField && desc) {
95
- description = <div className="rdformsDescription" tabIndex="0">{desc}</div>;
131
+ description = <div className="rdformsDescription">{desc}</div>;
96
132
  }
97
133
  }
98
134
 
99
135
  const labelId = binding ? context.view.createLabelIndex(binding) : undefined;
136
+ const rdformsLabel = context.view.popupOnLabel ? 'rdformsLabel' : 'rdformsLabel rdformsNoPopup';
137
+ const role = context.view.popupOnLabel ? 'button' : null;
100
138
  label = item.hasStyle('heading') ?
101
- <h2 tabIndex="0" id={labelId} className="rdformsLabelRow"><span className="rdformsLabel">{label}</span></h2> :
102
- <span tabIndex="0" id={labelId} className="rdformsLabelRow"><span className="rdformsLabel">{label}</span></span>;
103
- rowNode.appendChild(<Fragment key={`${binding ? binding.getHash() : item._internalId}_label` }><ItemTooltip
104
- context={context} item={item}>{label}</ItemTooltip>{description}</Fragment>);
139
+ <h2 tabIndex="0" id={labelId} className="rdformsLabelRow"><span className={rdformsLabel} role={role}>{label}</span></h2> :
140
+ <span tabIndex="0" id={labelId} className="rdformsLabelRow"><span className={rdformsLabel} role={role}>{label}</span></span>;
141
+ if (context.view.popupOnLabel) {
142
+ rowNode.appendChild(<Fragment key={`${binding ? binding.getHash() : item._internalId}_label` }><ItemTooltip
143
+ context={context} item={item} binding={binding}>{label}</ItemTooltip>{description}</Fragment>);
144
+ } else {
145
+ rowNode.appendChild(<Fragment key={`${binding ? binding.getHash() : item._internalId}_label` }>{label}{description}</Fragment>);
146
+ }
105
147
  };
106
148
 
107
149
  renderingContext.renderEditorLabel = (rowNode, binding, item, context) => {
@@ -115,9 +157,13 @@ renderingContext.renderEditorLabel = (rowNode, binding, item, context) => {
115
157
  } else {
116
158
  label = '';
117
159
  }
118
- label = item.hasStyle('heading') ? <h2 tabIndex="0" className="rdformsLabel">{label}</h2> :
119
- <span tabIndex="0" className="rdformsLabel">{label}</span>;
120
- label = <ItemTooltip item={item} context={context}>{label}</ItemTooltip>;
160
+ const rdformsLabel = context.view.popupOnLabel ? 'rdformsLabel' : 'rdformsLabel rdformsNoPopup';
161
+ const role = context.view.popupOnLabel ? 'button' : null;
162
+ label = item.hasStyle('heading') ? <h2 tabIndex="0" className={rdformsLabel} role={role}>{label}</h2> :
163
+ <span tabIndex="0" className={rdformsLabel} role={role}>{label}</span>;
164
+ if (context.view.popupOnLabel) {
165
+ label = <ItemTooltip item={item} context={context} binding={binding}>{label}</ItemTooltip>;
166
+ }
121
167
 
122
168
  const card = item.getCardinality();
123
169
  const b = context.view.messages;
@@ -328,6 +328,7 @@ const groupPresenter = (fieldDiv, binding, context) => {
328
328
  // eslint-disable-next-line no-new
329
329
  new Cls({
330
330
  parentView: context.view,
331
+ renderingParams: context.view.renderingParams,
331
332
  messages: context.view.messages,
332
333
  binding,
333
334
  topLevel: false,
@@ -336,6 +337,7 @@ const groupPresenter = (fieldDiv, binding, context) => {
336
337
  showDescription: context.view.showDescription,
337
338
  defaultLanguage: context.view.defaultLanguage,
338
339
  filterTranslations: context.view.filterTranslations,
340
+ popupOnLabel: context.view.popupOnLabel,
339
341
  truncate: context.view.truncate,
340
342
  truncateLimit: context.view.truncateLimit,
341
343
  includeLevel: context.view.includeLevel, // Copied from groupEditor, was this.includeLevel but that 'this' does not make sense here
@@ -349,11 +351,13 @@ const groupEditor = (fieldDiv, binding, context) => {
349
351
  const Cls = context.view.constructor;
350
352
  const subView = new Cls({
351
353
  parentView: context.view,
354
+ renderingParams: context.view.renderingParams,
352
355
  messages: context.view.messages,
353
356
  languages: context.view.languages,
354
357
  binding,
355
358
  topLevel: false,
356
359
  compact: context.view.compact,
360
+ popupOnLabel: context.view.popupOnLabel,
357
361
  showDescription: context.view.showDescription,
358
362
  truncate: context.view.truncate,
359
363
  truncateLimit: context.view.truncateLimit,
@@ -204,6 +204,15 @@ a.rdformsUrl:hover {
204
204
  cursor: pointer;
205
205
  }
206
206
 
207
+ .rdformsLabel.rdformsNoPopup:hover {
208
+ text-decoration: initial;
209
+ cursor: initial;
210
+ }
211
+
212
+ .rdformsLabel .popover:hover {
213
+ cursor: initial;
214
+ }
215
+
207
216
  .rdformsLabel.noPointer:hover {
208
217
  text-decoration: none;
209
218
  cursor: default;