@entryscape/rdforms 10.6.2 → 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.
- package/dist/rdforms.bmd.js +7 -5
- package/dist/rdforms.bootstrap.js +17 -15
- package/dist/rdforms.jquery.js +6 -4
- package/dist/rdforms.node.js +273 -3
- package/dist/rdforms.react.js +79 -77
- package/package.json +4 -3
- package/src/template/Item.js +2 -1
- package/src/view/Presenter.js +32 -3
- package/src/view/Registry.js +1 -1
- package/src/view/ValidationPresenter.js +2 -2
- package/src/view/View.js +52 -10
- package/src/view/bmd/DateTimeMD.js +12 -14
- package/src/view/bmd/Selectize.js +5 -4
- package/src/view/bmd/style.css +9 -1
- package/src/view/bootstrap/DateTimeBootstrapDatepicker.js +6 -4
- package/src/view/bootstrap/RadioButtonsEditor.js +5 -2
- package/src/view/bootstrap/Select2.js +8 -5
- package/src/view/bootstrap/buttons.js +9 -5
- package/src/view/bootstrap/choice.js +6 -4
- package/src/view/bootstrap/durationEditor.js +3 -2
- package/src/view/bootstrap/labels.js +26 -15
- package/src/view/bootstrap/style.css +9 -3
- package/src/view/bootstrap/text.js +7 -4
- package/src/view/jquery/labels.js +15 -0
- package/src/view/jquery/text.js +3 -3
- package/src/view/react/buttons.js +3 -0
- package/src/view/react/choiceEditors/CheckBoxesEditor.js +8 -3
- package/src/view/react/choiceEditors/ChoiceLookup.js +4 -2
- package/src/view/react/choiceEditors/ChoiceLookupAndInlineSearch.js +24 -15
- package/src/view/react/choiceEditors/ChoiceSelector.js +7 -4
- package/src/view/react/choiceEditors/RadioButtonsEditor.js +8 -4
- package/src/view/react/choiceEditors/ShowButton.js +1 -0
- package/src/view/react/date.js +7 -5
- package/src/view/react/duration.js +4 -2
- package/src/view/react/hooks.js +3 -0
- package/src/view/react/labels.js +40 -4
- package/src/view/react/style.css +6 -6
- package/src/view/react/text.js +2 -2
- package/src/view/react/textEditors.js +5 -0
- package/src/view/renderingContext.js +5 -0
- package/src/view/resources/rdforms.css +39 -17
- package/src/view/{jquery/util.js → viewUtils.js} +11 -0
- package/src/view/react/util.js +0 -31
|
@@ -108,13 +108,14 @@
|
|
|
108
108
|
font-size: small;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
.rdformsFieldControl>.
|
|
111
|
+
.rdformsFieldControl>.fas.action {
|
|
112
112
|
float: right;
|
|
113
113
|
position: initial;
|
|
114
114
|
margin-top: 8px;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
.
|
|
117
|
+
.fas.action:disabled,
|
|
118
|
+
.fas.action.disabled {
|
|
118
119
|
cursor: default;
|
|
119
120
|
}
|
|
120
121
|
|
|
@@ -185,7 +186,6 @@
|
|
|
185
186
|
/* Autoexpand style */
|
|
186
187
|
.rdforms .rdformsFields textarea.form-control {
|
|
187
188
|
display: block;
|
|
188
|
-
box-sizing: padding-box;
|
|
189
189
|
overflow-x: hidden;
|
|
190
190
|
overflow-y: auto;
|
|
191
191
|
}
|
|
@@ -248,4 +248,10 @@
|
|
|
248
248
|
|
|
249
249
|
.rdformsValidator .rdformsValidationMessageWrapper {
|
|
250
250
|
margin-left: -22px;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.rdformsActionButton {
|
|
254
|
+
border: none;
|
|
255
|
+
background: transparent;
|
|
256
|
+
padding: 0;
|
|
251
257
|
}
|
|
@@ -2,6 +2,8 @@ import moment from 'moment';
|
|
|
2
2
|
import durationEditor from './durationEditor';
|
|
3
3
|
import renderingContext from '../renderingContext';
|
|
4
4
|
import utils from '../../utils';
|
|
5
|
+
import { getNamedGraphId } from '../viewUtils';
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Try to guess the number of rows needed for a textarea element by looking at the value of the element
|
|
@@ -107,9 +109,10 @@ registerPattern('^(\\d+(\\.\\d+)?)$', 'xsd:decimal');
|
|
|
107
109
|
editors.itemtype('text').register((fieldDiv, binding, context) => {
|
|
108
110
|
const item = binding.getItem();
|
|
109
111
|
let $input;
|
|
112
|
+
const disabledAttr = getNamedGraphId(binding, context) ? 'disabled' : '';
|
|
110
113
|
if (item.hasStyle('multiline')) {
|
|
111
114
|
const originalNrOfLines = countLines(binding.getGist());
|
|
112
|
-
$input = jquery(`<textarea class="form-control rdformsFieldInput autoExpand" placeholder="${item.getPlaceholder() || ''}" rows="${originalNrOfLines}">`);
|
|
115
|
+
$input = jquery(`<textarea ${disabledAttr} class="form-control rdformsFieldInput autoExpand" placeholder="${item.getPlaceholder() || ''}" rows="${originalNrOfLines}">`);
|
|
113
116
|
$input.on('input focus', function () {
|
|
114
117
|
if (this.baseScrollHeight === undefined) {
|
|
115
118
|
const originalHeight = $input.height();
|
|
@@ -121,9 +124,9 @@ editors.itemtype('text').register((fieldDiv, binding, context) => {
|
|
|
121
124
|
this.rows = rows;
|
|
122
125
|
});
|
|
123
126
|
} else if (item.hasStyle('email')) {
|
|
124
|
-
$input = jquery(`<input type="email" class="form-control rdformsFieldInput" placeholder="${item.getPlaceholder() || ''}">`);
|
|
127
|
+
$input = jquery(`<input ${disabledAttr} type="email" class="form-control rdformsFieldInput" placeholder="${item.getPlaceholder() || ''}">`);
|
|
125
128
|
} else {
|
|
126
|
-
$input = jquery(`<input type="text" class="form-control rdformsFieldInput" placeholder="${item.getPlaceholder() || ''}">`);
|
|
129
|
+
$input = jquery(`<input ${disabledAttr} type="text" class="form-control rdformsFieldInput" placeholder="${item.getPlaceholder() || ''}">`);
|
|
127
130
|
}
|
|
128
131
|
$input.val(binding.getGist())
|
|
129
132
|
.appendTo(fieldDiv);
|
|
@@ -156,7 +159,7 @@ editors.itemtype('text').register((fieldDiv, binding, context) => {
|
|
|
156
159
|
if (nodeType === 'LANGUAGE_LITERAL' || nodeType === 'PLAIN_LITERAL') {
|
|
157
160
|
jquery(fieldDiv).addClass('rdformsLangcontrolledfield');
|
|
158
161
|
jquery(context.controlDiv).addClass('rdformsLangFieldControl');
|
|
159
|
-
const $lselect = jquery(
|
|
162
|
+
const $lselect = jquery(`<select ${disabledAttr} class="form-control rdformsLanguage">`)
|
|
160
163
|
.appendTo(context.controlDiv);
|
|
161
164
|
let primaryLangs = renderingContext.getPrimaryLanguageList();
|
|
162
165
|
let langList = renderingContext.getNonPrimaryLanguageList();
|
|
@@ -20,6 +20,21 @@ renderingContext.renderPresenterLabel = (rowNode, binding, item, context, labelR
|
|
|
20
20
|
if (context) {
|
|
21
21
|
context.labelNode = $labelDiv[0];
|
|
22
22
|
}
|
|
23
|
+
const view = context.view;
|
|
24
|
+
if (item.hasStyle('showDescriptionInPresent') || view.showDescription) {
|
|
25
|
+
// An item is compact if it is exclicitly set as compact or
|
|
26
|
+
// the view is set as compact and the item is not explicitly set as not compact AND
|
|
27
|
+
// we are at the top
|
|
28
|
+
const compactField = item.hasStyle('compact') ||
|
|
29
|
+
(view.compact && !item.hasStyle('nonCompact') && (
|
|
30
|
+
(view.topLevel && item.getType() !== 'group') ||
|
|
31
|
+
(view.parentView && view.parentView.topLevel && view.binding.getItem().hasStyle('heading'))));
|
|
32
|
+
const desc = item.getDescription();
|
|
33
|
+
if (!compactField && desc) {
|
|
34
|
+
jquery('<div class="rdformsDescription" tabindex="0">').text(desc).appendTo(rowNode);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
23
38
|
renderingContext.attachItemInfo(item, $labelDiv[0], context);
|
|
24
39
|
};
|
|
25
40
|
|
package/src/view/jquery/text.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import moment from 'moment';
|
|
2
2
|
import { escape } from 'lodash-es';
|
|
3
|
-
import { getDatePresentation, fromDuration } from '
|
|
3
|
+
import { getDatePresentation, fromDuration } from '../viewUtils';
|
|
4
4
|
import renderingContext from '../renderingContext';
|
|
5
5
|
import utils from '../../utils';
|
|
6
6
|
import system from '../../model/system';
|
|
@@ -122,7 +122,7 @@ presenters.itemtype('text').datatype('xsd:duration').register((fieldDiv, binding
|
|
|
122
122
|
const node = jquery('<div>').appendTo(fieldDiv)[0];
|
|
123
123
|
['years', 'months', 'days', 'hours', 'minutes'].forEach((key) => {
|
|
124
124
|
if (data.hasOwnProperty(key)) {
|
|
125
|
-
jquery(`<span class="
|
|
125
|
+
jquery(`<span class="durationLabel">${bundle[`duration_${key}`]}:</span><span class="durationValue">${data[key]}</span>`)
|
|
126
126
|
.appendTo(node);
|
|
127
127
|
}
|
|
128
128
|
});
|
|
@@ -143,4 +143,4 @@ presenters.itemtype('text').datatype('xsd:time').register(datePresenter);
|
|
|
143
143
|
presenters.itemtype('text').datatype('xsd:gYear').register(datePresenter);
|
|
144
144
|
presenters.itemtype('text').datatype('xsd:gYearMonth').register(datePresenter);
|
|
145
145
|
presenters.itemtype('text').datatype('xsd:gMonthDay').register(datePresenter);
|
|
146
|
-
presenters.itemtype('text').datatype('dcterms:W3CDTF').register(datePresenter);
|
|
146
|
+
presenters.itemtype('text').datatype('dcterms:W3CDTF').register(datePresenter);
|
|
@@ -7,6 +7,7 @@ import AddIcon from '@mui/icons-material/Add';
|
|
|
7
7
|
import IconButton from '@mui/material/IconButton';
|
|
8
8
|
import renderingContext from '../renderingContext';
|
|
9
9
|
import * as engine from '../../model/engine';
|
|
10
|
+
import { useNamedGraphId } from './hooks';
|
|
10
11
|
|
|
11
12
|
renderingContext.addExpandButton = (rowDiv, labelDiv, item, context) => {
|
|
12
13
|
console.log('Expand button not yet supported');
|
|
@@ -78,10 +79,12 @@ renderingContext.addRemoveButton = (rowDiv, binding, context) => () => {
|
|
|
78
79
|
}
|
|
79
80
|
});
|
|
80
81
|
|
|
82
|
+
const ngId = useNamedGraphId(binding, context);
|
|
81
83
|
const title = clear ? context.view.messages.edit_clear : context.view.messages.edit_remove;
|
|
82
84
|
return <IconButton
|
|
83
85
|
size="small"
|
|
84
86
|
aria-label={title}
|
|
87
|
+
disabled={!!ngId}
|
|
85
88
|
title={title}
|
|
86
89
|
onClick={onClick}
|
|
87
90
|
>{clear ? (<CancelIcon fontSize="small"/>) : (<RemoveCircleIcon fontSize="small"/>)}</IconButton>;
|
|
@@ -3,9 +3,11 @@ import React, { useState, useEffect, useMemo } from 'react';
|
|
|
3
3
|
import FormControlLabel from '@mui/material/FormControlLabel';
|
|
4
4
|
import Checkbox from '@mui/material/Checkbox';
|
|
5
5
|
import { FormGroup } from '@mui/material';
|
|
6
|
-
import { useLocalizedSortedChoices,
|
|
6
|
+
import { useLocalizedSortedChoices, useNamedGraphId } from '../hooks';
|
|
7
|
+
import { getNamedGraphId } from '../../viewUtils';
|
|
7
8
|
import * as engine from '../../../model/engine';
|
|
8
9
|
|
|
10
|
+
|
|
9
11
|
const CheckOption = (props) => {
|
|
10
12
|
const { choice, binding, onChoiceChange } = props;
|
|
11
13
|
const [checked, setChecked] = React.useState(choice.value === binding.getValue());
|
|
@@ -16,6 +18,7 @@ const CheckOption = (props) => {
|
|
|
16
18
|
onChoiceChange();
|
|
17
19
|
};
|
|
18
20
|
return <FormControlLabel
|
|
21
|
+
disabled={props.disabled}
|
|
19
22
|
label={choice.label} control={<Checkbox checked={checked} onChange={handleChange}/>}
|
|
20
23
|
{...(choice.mismatch ? { className: 'mismatch' } : {})}
|
|
21
24
|
title={choice.description || choice.seeAlso || choice.value}/>;
|
|
@@ -35,9 +38,9 @@ export default function CheckBoxesEditor(props) {
|
|
|
35
38
|
const existingbinding = val2binding[c.value];
|
|
36
39
|
if (existingbinding) {
|
|
37
40
|
delete val2binding[c.value];
|
|
38
|
-
return [c, existingbinding];
|
|
41
|
+
return [c, existingbinding, getNamedGraphId(existingbinding, props.context)];
|
|
39
42
|
}
|
|
40
|
-
return [c, engine.create(parentBinding, item)];
|
|
43
|
+
return [c, engine.create(parentBinding, item), undefined];
|
|
41
44
|
});
|
|
42
45
|
// Add checks for values that are non-conforming (should have mismatch on their choices).
|
|
43
46
|
Object.values(val2binding).forEach((b) => {
|
|
@@ -70,12 +73,14 @@ export default function CheckBoxesEditor(props) {
|
|
|
70
73
|
setResetCount(resetCount + 1);
|
|
71
74
|
};
|
|
72
75
|
|
|
76
|
+
const ngId = useNamedGraphId(binding, props.context);
|
|
73
77
|
return (
|
|
74
78
|
<><FormGroup {...row}>
|
|
75
79
|
{choiceBindingPairs.map(pair => (
|
|
76
80
|
<CheckOption key={`${resetCount}-${pair[1].getHash()}`}
|
|
77
81
|
choice={pair[0]}
|
|
78
82
|
binding={pair[1]}
|
|
83
|
+
disabled={!!pair[2] || !!ngId}
|
|
79
84
|
onChoiceChange={onChoiceChange} />
|
|
80
85
|
))}
|
|
81
86
|
</FormGroup>{error && (
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import React, { useState, useEffect } from 'react';
|
|
3
3
|
import TextField from '@mui/material/TextField';
|
|
4
4
|
import renderingContext from '../../renderingContext';
|
|
5
|
-
import { loadLocalizedChoice } from '../hooks';
|
|
5
|
+
import { loadLocalizedChoice, useNamedGraphId } from '../hooks';
|
|
6
6
|
import utils from '../../../utils';
|
|
7
7
|
import ShowButton from './ShowButton';
|
|
8
8
|
|
|
@@ -38,10 +38,11 @@ export default (props) => {
|
|
|
38
38
|
}, props.field);
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
+
const ngId = useNamedGraphId(binding, props.context);
|
|
41
42
|
return <><TextField
|
|
42
43
|
inputProps={{ 'aria-labelledby': labelledBy }}
|
|
43
44
|
className="rdformsSearch"
|
|
44
|
-
disabled {...(choice && choice.mismatch ? { mismatch: true } : {})}
|
|
45
|
+
disabled {...(!!ngId || (choice && choice.mismatch) ? { mismatch: true } : {})}
|
|
45
46
|
title={title}
|
|
46
47
|
value={label}
|
|
47
48
|
placeholder={binding.getItem().getPlaceholder()}
|
|
@@ -49,6 +50,7 @@ export default (props) => {
|
|
|
49
50
|
variant={renderingContext.materialVariant}
|
|
50
51
|
/><ShowButton
|
|
51
52
|
{... props}
|
|
53
|
+
disabled={!!ngId}
|
|
52
54
|
onClick={choiceSelectorHandler}/>{ error && (<div key="warning" className="rdformsWarning">{
|
|
53
55
|
props.context.view.messages.wrongValueField}</div>)}</>;
|
|
54
56
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
/* eslint-disable no-unused-vars */
|
|
1
|
+
/* eslint-disable no-unused-vars,quotes */
|
|
2
2
|
import React, { useState, useEffect } from 'react';
|
|
3
3
|
import TextField from '@mui/material/TextField';
|
|
4
4
|
import Autocomplete from '@mui/material/Autocomplete';
|
|
5
5
|
import BuildIcon from '@mui/icons-material/Build';
|
|
6
6
|
import IconButton from '@mui/material/IconButton';
|
|
7
7
|
import renderingContext from '../../renderingContext';
|
|
8
|
-
import { editLocalizedChoice, loadLocalizedChoice } from '../hooks';
|
|
8
|
+
import { editLocalizedChoice, loadLocalizedChoice, useNamedGraphId } from '../hooks';
|
|
9
9
|
import ShowButton from './ShowButton';
|
|
10
10
|
|
|
11
11
|
let globalChoiceQueryThrottle;
|
|
@@ -78,7 +78,8 @@ export default (props) => {
|
|
|
78
78
|
setOpen(true);
|
|
79
79
|
}
|
|
80
80
|
}}
|
|
81
|
-
variant={renderingContext.materialVariant}
|
|
81
|
+
variant={renderingContext.materialVariant}
|
|
82
|
+
/>
|
|
82
83
|
);
|
|
83
84
|
};
|
|
84
85
|
|
|
@@ -97,6 +98,8 @@ export default (props) => {
|
|
|
97
98
|
});
|
|
98
99
|
};
|
|
99
100
|
|
|
101
|
+
const ngId = useNamedGraphId(binding, props.context);
|
|
102
|
+
const UpgradeComponent = value && value.original.upgradeComponent;
|
|
100
103
|
return (
|
|
101
104
|
<>
|
|
102
105
|
<Autocomplete
|
|
@@ -105,29 +108,35 @@ export default (props) => {
|
|
|
105
108
|
fullWidth={false}
|
|
106
109
|
value={value}
|
|
107
110
|
options={options}
|
|
108
|
-
filterOptions={
|
|
111
|
+
filterOptions={fopts => fopts}
|
|
109
112
|
open={open}
|
|
110
113
|
onOpen={() => setOpen(true)}
|
|
111
114
|
onClose={() => setOpen(false)}
|
|
112
115
|
onInputChange={(event, newInputValue) => setInputValue(newInputValue)}
|
|
113
116
|
onChange={onChange}
|
|
117
|
+
disabled={!!ngId}
|
|
114
118
|
isOptionEqualToValue={(option, choice) => option.value === choice.value}
|
|
115
|
-
getOptionLabel={
|
|
119
|
+
getOptionLabel={choice =>
|
|
116
120
|
choice === null ? '' : choice.label || choice.value
|
|
117
121
|
}
|
|
118
|
-
getOptionDisabled={
|
|
122
|
+
getOptionDisabled={option => option.mismatch === true}
|
|
119
123
|
renderInput={renderInput}
|
|
124
|
+
disablePortal
|
|
120
125
|
/>
|
|
121
|
-
<ShowButton {...props} onClick={showHandler} />
|
|
126
|
+
<ShowButton {...props} onClick={showHandler} disabled={!!ngId}/>
|
|
122
127
|
{value && value.original.upgrade && (
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
<>
|
|
129
|
+
<IconButton
|
|
130
|
+
aria-label={props.context.view.messages.edit_upgrade}
|
|
131
|
+
title={props.context.view.messages.edit_upgrade}
|
|
132
|
+
disabled={!!ngId}
|
|
133
|
+
onClick={upgradeHandler}
|
|
134
|
+
>
|
|
135
|
+
<BuildIcon />
|
|
136
|
+
</IconButton>
|
|
137
|
+
{UpgradeComponent}
|
|
138
|
+
</>
|
|
139
|
+
)}
|
|
131
140
|
{error && (
|
|
132
141
|
<div key="warning" className="rdformsWarning">
|
|
133
142
|
{props.context.view.messages.wrongValueField}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/* eslint-disable no-unused-vars */
|
|
1
|
+
/* eslint-disable no-unused-vars,quotes */
|
|
2
2
|
import React, { useState, useEffect } from 'react';
|
|
3
3
|
import TextField from '@mui/material/TextField';
|
|
4
4
|
import Autocomplete from '@mui/material/Autocomplete';
|
|
5
5
|
import renderingContext from '../../renderingContext';
|
|
6
|
-
import { useLocalizedSortedChoices, useLocalizedChoice } from '../hooks';
|
|
6
|
+
import { useLocalizedSortedChoices, useLocalizedChoice, useNamedGraphId } from '../hooks';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Autocomplete with fixed choices.
|
|
@@ -50,6 +50,7 @@ export default (props) => {
|
|
|
50
50
|
setError(newChoice.original.mismatch === true);
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
+
const ngId = useNamedGraphId(binding, props.context);
|
|
53
54
|
return (
|
|
54
55
|
<>
|
|
55
56
|
<Autocomplete
|
|
@@ -58,11 +59,13 @@ export default (props) => {
|
|
|
58
59
|
value={value}
|
|
59
60
|
options={choices}
|
|
60
61
|
onChange={handleChange}
|
|
62
|
+
disabled={!!ngId}
|
|
61
63
|
isOptionEqualToValue={(option, choice) => option.value === choice.value}
|
|
62
|
-
getOptionLabel={
|
|
63
|
-
getOptionDisabled={
|
|
64
|
+
getOptionLabel={choice => (choice === null ? '' : choice.label)}
|
|
65
|
+
getOptionDisabled={option => option.mismatch === true}
|
|
64
66
|
filterSelectedOptions
|
|
65
67
|
renderInput={renderInput}
|
|
68
|
+
disablePortal
|
|
66
69
|
/>
|
|
67
70
|
{error && (
|
|
68
71
|
<div key="warning" className="rdformsWarning">
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
/* eslint-disable no-unused-vars */
|
|
1
|
+
/* eslint-disable no-unused-vars,quotes */
|
|
2
2
|
import React, { useState, useEffect } from 'react';
|
|
3
3
|
import Radio from '@mui/material/Radio';
|
|
4
4
|
import RadioGroup from '@mui/material/RadioGroup';
|
|
5
5
|
import FormControlLabel from '@mui/material/FormControlLabel';
|
|
6
6
|
import FormControl from '@mui/material/FormControl';
|
|
7
|
-
import { useLocalizedSortedChoices, useName } from '../hooks';
|
|
7
|
+
import { useLocalizedSortedChoices, useName, useNamedGraphId } from '../hooks';
|
|
8
8
|
|
|
9
9
|
const ChoiceOption = props => <FormControlLabel
|
|
10
|
+
disabled={props.disabled}
|
|
10
11
|
label={props.choice.label} value={props.choice.value} control={<Radio/>}
|
|
11
12
|
{...(props.choice.mismatch ? { className: 'mismatch' } : {})}
|
|
12
13
|
title={props.choice.description || props.choice.seeAlso || props.choice.value}/>;
|
|
@@ -46,6 +47,7 @@ export default function RadioButtonsEditor(props) {
|
|
|
46
47
|
};
|
|
47
48
|
}, []);
|
|
48
49
|
|
|
50
|
+
const ngId = useNamedGraphId(binding, props.context);
|
|
49
51
|
return (
|
|
50
52
|
<>
|
|
51
53
|
<FormControl component="fieldset">
|
|
@@ -57,8 +59,10 @@ export default function RadioButtonsEditor(props) {
|
|
|
57
59
|
value={value}
|
|
58
60
|
onChange={handleChange}
|
|
59
61
|
>
|
|
60
|
-
{choices.map(
|
|
61
|
-
<ChoiceOption key={choice.value}
|
|
62
|
+
{choices.map(choice => (
|
|
63
|
+
<ChoiceOption key={choice.value}
|
|
64
|
+
disabled={!!ngId}
|
|
65
|
+
choice={choice} />
|
|
62
66
|
))}
|
|
63
67
|
</RadioGroup>
|
|
64
68
|
</FormControl>
|
package/src/view/react/date.js
CHANGED
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
getDateValue,
|
|
17
17
|
getAllowedDateAlternatives,
|
|
18
18
|
getDatePresentation,
|
|
19
|
-
} from '../
|
|
20
|
-
|
|
19
|
+
} from '../viewUtils';
|
|
20
|
+
import { useNamedGraphId } from './hooks';
|
|
21
21
|
|
|
22
22
|
const getDatatypeFromBinding = binding => getDatatype(binding.getDatatype()) || getDatatypeFromItem(binding.getItem());
|
|
23
23
|
|
|
@@ -118,10 +118,11 @@ const dateEditor = (fieldDiv, binding, context) => {
|
|
|
118
118
|
'aria-labelledby': context.view.getLabelIndex(binding),
|
|
119
119
|
variant: renderingContext.materialVariant,
|
|
120
120
|
};
|
|
121
|
+
const ngId = useNamedGraphId(binding, context);
|
|
121
122
|
const visibleDatePicker = alternatives.Date || alternatives.DateTime || alternatives.Year
|
|
122
123
|
|| alternatives.YearMonth || alternatives.MonthDay;
|
|
123
|
-
const enabledDatePicker = selectedDatatype === 'DateTime' || selectedDatatype === 'Date'
|
|
124
|
-
|| selectedDatatype === 'Year' || selectedDatatype === 'YearMonth' || selectedDatatype === 'MonthDay';
|
|
124
|
+
const enabledDatePicker = !ngId && (selectedDatatype === 'DateTime' || selectedDatatype === 'Date'
|
|
125
|
+
|| selectedDatatype === 'Year' || selectedDatatype === 'YearMonth' || selectedDatatype === 'MonthDay');
|
|
125
126
|
return (
|
|
126
127
|
<LocalizationProvider dateAdapter={DateAdapter}>
|
|
127
128
|
<span className="rdformsDatePicker">
|
|
@@ -146,7 +147,7 @@ const dateEditor = (fieldDiv, binding, context) => {
|
|
|
146
147
|
<TimePicker
|
|
147
148
|
renderInput={props => <TextField {...props} {...inputProps} />}
|
|
148
149
|
label={bundle.date_time}
|
|
149
|
-
{...(selectedDatatype === 'DateTime' || selectedDatatype === 'Time' ? {} : { disabled: true })}
|
|
150
|
+
{...(!ngId && (selectedDatatype === 'DateTime' || selectedDatatype === 'Time') ? {} : { disabled: true })}
|
|
150
151
|
KeyboardButtonProps={{
|
|
151
152
|
'aria-label': bundle.date_openTimePicker,
|
|
152
153
|
}}
|
|
@@ -162,6 +163,7 @@ const dateEditor = (fieldDiv, binding, context) => {
|
|
|
162
163
|
value={selectedDatatype}
|
|
163
164
|
inputProps={inputProps}
|
|
164
165
|
onChange={onDatatypeChange}
|
|
166
|
+
disabled={!!ngId}
|
|
165
167
|
>
|
|
166
168
|
{alternatives.Year && (
|
|
167
169
|
<MenuItem value="Year">{bundle.date_year}</MenuItem>
|
|
@@ -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 '
|
|
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]}
|
package/src/view/react/hooks.js
CHANGED
|
@@ -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));
|
package/src/view/react/labels.js
CHANGED
|
@@ -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(
|
|
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(
|
|
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
|
|
package/src/view/react/style.css
CHANGED
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
.rdformsEditor .rdformsLangControl {
|
|
136
|
-
width: calc(33.33% -
|
|
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
|
+
}
|
package/src/view/react/text.js
CHANGED
|
@@ -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 '
|
|
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="
|
|
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);
|