@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/dist/rdforms.bmd.js +2 -2
- package/dist/rdforms.bootstrap.js +10 -10
- package/dist/rdforms.jquery.js +5 -5
- package/dist/rdforms.node.js +1 -1
- package/dist/rdforms.react.js +3 -3
- package/package.json +3 -3
- package/src/template/ItemStore.js +5 -0
- package/src/template/bundleLoader.js +10 -8
- package/src/view/View.js +2 -0
- package/src/view/bootstrap/labels.js +7 -2
- package/src/view/jquery/labels.js +1 -1
- package/src/view/react/choiceEditors/ChoiceLookupAndInlineSearch.js +1 -0
- package/src/view/react/choiceEditors/ChoiceSelector.js +1 -0
- package/src/view/react/labels.js +74 -28
- package/src/view/renderingContext.js +4 -0
- package/src/view/resources/rdforms.css +9 -0
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"application profile",
|
|
9
9
|
"linked data"
|
|
10
10
|
],
|
|
11
|
-
"version": "10.
|
|
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.
|
|
19
|
+
"@entryscape/rdfjson": "2.7.7"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@entryscape/rdfjson": "2.7.
|
|
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
|
|
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(
|
|
37
|
+
response = await fetch(path);
|
|
36
38
|
} catch (e) {
|
|
37
|
-
throw Error(`A network error ocurred while trying to fetch bundle ${
|
|
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 ${
|
|
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,
|
|
56
|
+
stopFetchingOrJustLog(i, totalUrls, path);
|
|
55
57
|
}
|
|
56
58
|
// got back something that's not a 2xx
|
|
57
59
|
} else {
|
|
58
|
-
stopFetchingOrJustLog(i, totalUrls,
|
|
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(
|
|
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"
|
|
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"
|
|
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 && (
|
package/src/view/react/labels.js
CHANGED
|
@@ -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/
|
|
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
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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"
|
|
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=
|
|
102
|
-
<span tabIndex="0" id={labelId} className="rdformsLabelRow"><span className=
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
label = <
|
|
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;
|