@entryscape/rdforms 10.4.0 → 10.5.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 +4 -4
- package/dist/rdforms.bootstrap.js +10 -10
- package/dist/rdforms.jquery.js +3 -3
- package/dist/rdforms.node.js +1 -1
- package/dist/rdforms.react.js +67 -67
- package/package.json +2 -2
- package/src/model/ChoiceBinding.js +0 -8
- package/src/template/Item.js +2 -0
- package/src/utils.js +1 -1
- package/src/view/Editor.js +15 -8
- package/src/view/View.js +13 -4
- package/src/view/jquery/text.js +17 -20
- package/src/view/jquery/util.js +170 -0
- package/src/view/react/buttons.js +13 -2
- package/src/view/react/choiceEditors/CheckBoxesEditor.js +87 -0
- package/src/view/react/choiceEditors/index.js +9 -0
- package/src/view/react/components.js +4 -2
- package/src/view/react/date.js +113 -120
- package/src/view/react/labels.js +18 -14
- package/src/view/react/textEditors.js +1 -1
- package/src/view/resources/nls.json +2 -0
package/src/view/react/date.js
CHANGED
|
@@ -8,107 +8,89 @@ import { TextField } from '@mui/material';
|
|
|
8
8
|
import Select from '@mui/material/Select';
|
|
9
9
|
import moment from 'moment';
|
|
10
10
|
import renderingContext from '../renderingContext';
|
|
11
|
+
import {
|
|
12
|
+
getDate,
|
|
13
|
+
getDatatype,
|
|
14
|
+
getDatatypeURI,
|
|
15
|
+
getDatatypeFromItem,
|
|
16
|
+
getDateValue,
|
|
17
|
+
getAllowedDateAlternatives,
|
|
18
|
+
getDatePresentation,
|
|
19
|
+
} from '../jquery/util';
|
|
11
20
|
|
|
12
|
-
const getDatatype = (datatype) => {
|
|
13
|
-
switch (datatype) {
|
|
14
|
-
case 'http://www.w3.org/2001/XMLSchema#dateTime':
|
|
15
|
-
case 'http://purl.org/dc/terms/W3CDTF':
|
|
16
|
-
return 'Datetime';
|
|
17
|
-
case 'http://www.w3.org/2001/XMLSchema#date':
|
|
18
|
-
return 'Date';
|
|
19
|
-
case 'http://www.w3.org/2001/XMLSchema#gYear':
|
|
20
|
-
return 'Year';
|
|
21
|
-
default:
|
|
22
|
-
return undefined;
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const getDatatypeFromItem = (item) => {
|
|
27
|
-
const dt = item.getDatatype();
|
|
28
|
-
if (Array.isArray(dt)) {
|
|
29
|
-
return getDatatype(dt[0]);
|
|
30
|
-
}
|
|
31
|
-
return getDatatype(dt);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const getAllowedDateAlternatives = (item) => {
|
|
35
|
-
const dateAllowedDataAlternatives = {};
|
|
36
|
-
const dt = item.getDatatype();
|
|
37
|
-
const alts = Array.isArray(dt) ? dt : [dt];
|
|
38
|
-
alts.forEach((datatype) => {
|
|
39
|
-
const alt = getDatatype(datatype);
|
|
40
|
-
if (alt) {
|
|
41
|
-
dateAllowedDataAlternatives[alt] = true;
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
return dateAllowedDataAlternatives;
|
|
45
|
-
};
|
|
46
21
|
|
|
47
22
|
const getDatatypeFromBinding = binding => getDatatype(binding.getDatatype()) || getDatatypeFromItem(binding.getItem());
|
|
48
23
|
|
|
49
|
-
const getDatatypeURI = (datatype) => {
|
|
50
|
-
switch (datatype) {
|
|
51
|
-
case 'Datetime':
|
|
52
|
-
return 'http://www.w3.org/2001/XMLSchema#dateTime';
|
|
53
|
-
case 'Date':
|
|
54
|
-
return 'http://www.w3.org/2001/XMLSchema#date';
|
|
55
|
-
case 'Year':
|
|
56
|
-
return 'http://www.w3.org/2001/XMLSchema#gYear';
|
|
57
|
-
default:
|
|
58
|
-
return '';
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const getDateValue = (value, datatype) => {
|
|
63
|
-
if (value) {
|
|
64
|
-
switch (datatype) {
|
|
65
|
-
case 'Datetime':
|
|
66
|
-
return value.toISOString();
|
|
67
|
-
case 'Date':
|
|
68
|
-
// Since we cut of the timezone section at the end we need to compensate for it
|
|
69
|
-
value.setMinutes(value.getMinutes() - value.getTimezoneOffset());
|
|
70
|
-
return value.toISOString().substr(0, 10);
|
|
71
|
-
case 'Year':
|
|
72
|
-
// Since we cut of the timezone section at the end we need to compensate for it
|
|
73
|
-
value.setMinutes(value.getMinutes() - value.getTimezoneOffset());
|
|
74
|
-
return value.toISOString().substr(0, 4);
|
|
75
|
-
default:
|
|
76
|
-
return '';
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return '';
|
|
80
|
-
};
|
|
81
|
-
|
|
82
24
|
const datePresenter = (fieldDiv, binding, context) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
} else if (data.length > 4) {
|
|
90
|
-
str = moment(data).format('LL');
|
|
91
|
-
} else {
|
|
92
|
-
str = moment(data).format('YYYY');
|
|
93
|
-
}
|
|
94
|
-
fieldDiv.appendChild(<div key={binding.getHash()} >{str}</div>);
|
|
95
|
-
} catch (e) {
|
|
96
|
-
console.warn(`Could not present date, expected ISO8601 format in the form 2001-01-01 (potentially with time given after a 'T' character as well) but found '${data}' instead.`);
|
|
97
|
-
}
|
|
25
|
+
try {
|
|
26
|
+
const pres = getDatePresentation(binding);
|
|
27
|
+
fieldDiv.appendChild(<div key={binding.getHash()} >{pres}</div>);
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.warn(`Could not present date, expected ISO8601 format in the form 2001-01-01
|
|
30
|
+
(potentially with time given after a 'T' character as well) but found '${binding.getValue()}' instead.`);
|
|
98
31
|
}
|
|
99
32
|
};
|
|
100
33
|
|
|
101
34
|
const presenters = renderingContext.presenterRegistry;
|
|
35
|
+
presenters.itemtype('text').datatype('xsd:dateTime').register(datePresenter);
|
|
102
36
|
presenters.itemtype('text').datatype('xsd:date').register(datePresenter);
|
|
37
|
+
presenters.itemtype('text').datatype('xsd:time').register(datePresenter);
|
|
38
|
+
presenters.itemtype('text').datatype('xsd:gYear').register(datePresenter);
|
|
39
|
+
presenters.itemtype('text').datatype('xsd:gYearMonth').register(datePresenter);
|
|
40
|
+
presenters.itemtype('text').datatype('xsd:gMonthDay').register(datePresenter);
|
|
103
41
|
presenters.itemtype('text').datatype('dcterms:W3CDTF').register(datePresenter);
|
|
104
42
|
|
|
43
|
+
const datePickerConfig = {
|
|
44
|
+
format: {
|
|
45
|
+
Year: 'YYYY',
|
|
46
|
+
DateTime: 'YYYY-MM-DD',
|
|
47
|
+
Date: 'YYYY-MM-DD',
|
|
48
|
+
YearMonth: 'YYYY-MM',
|
|
49
|
+
MonthDay: 'MM-DD',
|
|
50
|
+
Time: 'YYYY-MM-DD', // Since datepicker is sometimes visible but disabled
|
|
51
|
+
},
|
|
52
|
+
mask: {
|
|
53
|
+
Year: '____',
|
|
54
|
+
DateTime: '____-__-__',
|
|
55
|
+
Date: '____-__-__',
|
|
56
|
+
YearMonth: '____-__',
|
|
57
|
+
MonthDay: '__-__',
|
|
58
|
+
Time: '____-__-__', // Since datepicker is sometimes visible but disabled
|
|
59
|
+
},
|
|
60
|
+
views: {
|
|
61
|
+
Year: ['year'],
|
|
62
|
+
DateTime: ['day'],
|
|
63
|
+
Date: ['day'],
|
|
64
|
+
YearMonth: ['year', 'month'],
|
|
65
|
+
MonthDay: ['month', 'day'],
|
|
66
|
+
Time: ['day'], // Since datepicker is sometimes visible but disabled
|
|
67
|
+
},
|
|
68
|
+
labelKey: {
|
|
69
|
+
Year: 'date_year',
|
|
70
|
+
DateTime: 'date_date',
|
|
71
|
+
Date: 'date_date',
|
|
72
|
+
YearMonth: 'date_year_and_month', // TODO
|
|
73
|
+
MonthDay: 'date_month_and_day', // TODO
|
|
74
|
+
Time: 'date_date', // Since datepicker is sometimes visible but disabled
|
|
75
|
+
},
|
|
76
|
+
ariaLabelKey: {
|
|
77
|
+
Year: 'date_openYearPicker',
|
|
78
|
+
DateTime: 'date_openDatePicker',
|
|
79
|
+
Date: 'date_openDatePicker',
|
|
80
|
+
YearMonth: 'date_openDatePicker', // TODO
|
|
81
|
+
MonthDay: 'date_openDatePicker', // TODO
|
|
82
|
+
Time: 'date_openDatePicker', // Since datepicker is sometimes visible but disabled
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
|
|
105
87
|
const dateEditor = (fieldDiv, binding, context) => {
|
|
106
88
|
const bundle = context.view.messages;
|
|
107
89
|
const DateComp = () => {
|
|
108
90
|
const value = binding.getGist();
|
|
109
|
-
const alternatives = useMemo(() => getAllowedDateAlternatives(binding.getItem()));
|
|
91
|
+
const alternatives = useMemo(() => getAllowedDateAlternatives(binding.getItem()), []);
|
|
110
92
|
const onlyOneAlternative = Object.keys(alternatives).length === 1;
|
|
111
|
-
const [selectedDate, setSelectedDate] = useState(value === '' ? null :
|
|
93
|
+
const [selectedDate, setSelectedDate] = useState(value === '' ? null : getDate(value));
|
|
112
94
|
const [selectedDatatype, setDatatype] = useState(getDatatypeFromBinding(binding));
|
|
113
95
|
useEffect(() => {
|
|
114
96
|
context.clear = () => {
|
|
@@ -136,48 +118,47 @@ const dateEditor = (fieldDiv, binding, context) => {
|
|
|
136
118
|
'aria-labelledby': context.view.getLabelIndex(binding),
|
|
137
119
|
variant: renderingContext.materialVariant,
|
|
138
120
|
};
|
|
139
|
-
const
|
|
121
|
+
const visibleDatePicker = alternatives.Date || alternatives.DateTime || alternatives.Year
|
|
122
|
+
|| alternatives.YearMonth || alternatives.MonthDay;
|
|
123
|
+
const enabledDatePicker = selectedDatatype === 'DateTime' || selectedDatatype === 'Date'
|
|
124
|
+
|| selectedDatatype === 'Year' || selectedDatatype === 'YearMonth' || selectedDatatype === 'MonthDay';
|
|
140
125
|
return (
|
|
141
126
|
<LocalizationProvider dateAdapter={DateAdapter}>
|
|
142
127
|
<span className="rdformsDatePicker">
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
'aria-label':
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
selectedDatatype
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
],
|
|
170
|
-
}}
|
|
171
|
-
/>
|
|
172
|
-
{alternatives.Datetime && (
|
|
128
|
+
{visibleDatePicker && (
|
|
129
|
+
<DatePicker
|
|
130
|
+
renderInput={props => <TextField {...props} {...inputProps} />}
|
|
131
|
+
leftArrowButtonProps={{ 'aria-label': bundle.date_previousMonth }}
|
|
132
|
+
rightArrowButtonProps={{ 'aria-label': bundle.date_nextMonth }}
|
|
133
|
+
KeyboardButtonProps={{ 'aria-label': bundle[datePickerConfig.ariaLabelKey[selectedDatatype]] }}
|
|
134
|
+
label={bundle[datePickerConfig.labelKey[selectedDatatype]]}
|
|
135
|
+
{...(enabledDatePicker ? {} : { disabled: true })}
|
|
136
|
+
value={enabledDatePicker ? selectedDate : null}
|
|
137
|
+
minDate={moment(new Date('0000-01-01'))}
|
|
138
|
+
inputFormat={datePickerConfig.format[selectedDatatype]}
|
|
139
|
+
views={datePickerConfig.views[selectedDatatype]}
|
|
140
|
+
onChange={onDateChange}
|
|
141
|
+
autoOk={true}
|
|
142
|
+
mask={datePickerConfig.mask[selectedDatatype]}
|
|
143
|
+
PopperProps={{
|
|
144
|
+
modifiers: [
|
|
145
|
+
{
|
|
146
|
+
name: 'flip',
|
|
147
|
+
enabled: false,
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
}}
|
|
151
|
+
/>
|
|
152
|
+
)}
|
|
153
|
+
{(alternatives.DateTime || alternatives.Time) && (
|
|
173
154
|
<TimePicker
|
|
174
|
-
renderInput={
|
|
155
|
+
renderInput={props => <TextField {...props} {...inputProps} />}
|
|
175
156
|
label={bundle.date_time}
|
|
176
|
-
{...(selectedDatatype === '
|
|
157
|
+
{...(selectedDatatype === 'DateTime' || selectedDatatype === 'Time' ? {} : { disabled: true })}
|
|
177
158
|
KeyboardButtonProps={{
|
|
178
159
|
'aria-label': bundle.date_openTimePicker,
|
|
179
160
|
}}
|
|
180
|
-
value={selectedDatatype === '
|
|
161
|
+
value={selectedDatatype === 'DateTime' || selectedDatatype === 'Time' ? selectedDate : null}
|
|
181
162
|
onChange={onDateChange}
|
|
182
163
|
ampm={false}
|
|
183
164
|
autoOk={true}
|
|
@@ -204,11 +185,20 @@ const dateEditor = (fieldDiv, binding, context) => {
|
|
|
204
185
|
{alternatives.Date && (
|
|
205
186
|
<MenuItem value="Date">{bundle.date_date}</MenuItem>
|
|
206
187
|
)}
|
|
207
|
-
{alternatives.
|
|
208
|
-
<MenuItem value="
|
|
188
|
+
{alternatives.DateTime && (
|
|
189
|
+
<MenuItem value="DateTime">
|
|
209
190
|
{bundle.date_date_and_time}
|
|
210
191
|
</MenuItem>
|
|
211
192
|
)}
|
|
193
|
+
{alternatives.YearMonth && (
|
|
194
|
+
<MenuItem value="YearMonth">{bundle.date_year_and_month}</MenuItem>
|
|
195
|
+
)}
|
|
196
|
+
{alternatives.MonthDay && (
|
|
197
|
+
<MenuItem value="MonthDay">{bundle.date_month_and_day}</MenuItem>
|
|
198
|
+
)}
|
|
199
|
+
{alternatives.Time && (
|
|
200
|
+
<MenuItem value="Time">{bundle.date_time}</MenuItem>
|
|
201
|
+
)}
|
|
212
202
|
</Select>
|
|
213
203
|
</FormControl>
|
|
214
204
|
)}
|
|
@@ -223,4 +213,7 @@ const editors = renderingContext.editorRegistry;
|
|
|
223
213
|
editors.itemtype('text').datatype('http://www.w3.org/2001/XMLSchema#date').register(dateEditor);
|
|
224
214
|
editors.itemtype('text').datatype('http://www.w3.org/2001/XMLSchema#dateTime').register(dateEditor);
|
|
225
215
|
editors.itemtype('text').datatype('http://www.w3.org/2001/XMLSchema#gYear').register(dateEditor);
|
|
216
|
+
editors.itemtype('text').datatype('http://www.w3.org/2001/XMLSchema#gMonthDay').register(dateEditor);
|
|
217
|
+
editors.itemtype('text').datatype('http://www.w3.org/2001/XMLSchema#gYearMonth').register(dateEditor);
|
|
218
|
+
editors.itemtype('text').datatype('http://www.w3.org/2001/XMLSchema#time').register(dateEditor);
|
|
226
219
|
editors.itemtype('text').datatype('http://purl.org/dc/terms/W3CDTF').register(dateEditor);
|
package/src/view/react/labels.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/* eslint-disable no-unused-vars */
|
|
2
|
-
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import React, { useState, useEffect, forwardRef } from 'react';
|
|
3
3
|
import Tooltip, { tooltipClasses } from '@mui/material/Tooltip';
|
|
4
4
|
import { styled } from '@mui/material/styles';
|
|
5
5
|
import ClickAwayListener from '@mui/material/ClickAwayListener';
|
|
6
6
|
import renderingContext from '../renderingContext';
|
|
7
7
|
import { CODES } from '../../model/engine';
|
|
8
8
|
|
|
9
|
-
const StyledTooltip = styled(
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const StyledTooltip = styled(
|
|
10
|
+
forwardRef(({ className, ...props }, ref) => (
|
|
11
|
+
<Tooltip {...props} classes={{ popper: className }} />
|
|
12
|
+
))
|
|
13
|
+
)(({ theme }) => ({
|
|
12
14
|
[`& .${tooltipClasses.tooltip}`]: {
|
|
13
15
|
backgroundColor: theme.palette.background.default,
|
|
14
16
|
fontSize: 12,
|
|
@@ -148,16 +150,18 @@ const ERR = (props) => {
|
|
|
148
150
|
|
|
149
151
|
renderingContext.renderEditorLabelScopeEnd = (rowNode, binding, item, context) => {
|
|
150
152
|
if (!item.hasStyle('nonEditable') && !item.hasStyle('heading')) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
153
|
+
if (!context.view.isMultiValued(item)) {
|
|
154
|
+
let Button;
|
|
155
|
+
const card = item.getCardinality();
|
|
156
|
+
if (binding == null) {
|
|
157
|
+
Button = renderingContext.addExpandButton(rowNode, null, item, context);
|
|
158
|
+
} else if (binding.getPredicate() && !context.view.showAsTable(item) && card.max !== 1 &&
|
|
159
|
+
(card.max == null || card.max !== card.min)) {
|
|
160
|
+
Button = renderingContext.addCreateChildButton(rowNode, null, binding, context);
|
|
161
|
+
}
|
|
162
|
+
if (Button) {
|
|
163
|
+
rowNode.appendChild(<Button key={`${binding.getHash()}_labelEnd`}></Button>);
|
|
164
|
+
}
|
|
161
165
|
}
|
|
162
166
|
// If the item is deprecated and there are at least one matching value (binding),
|
|
163
167
|
// provide a message and make sure the entire row (including the label) is deleted when
|
|
@@ -45,7 +45,7 @@ const LanguageControl = (props) => {
|
|
|
45
45
|
onChange={onLangChange}>
|
|
46
46
|
{langs.map(langOption => (langOption === null ?
|
|
47
47
|
(<MenuItem key="_none" value="_none" disabled>─────</MenuItem>) :
|
|
48
|
-
(<MenuItem key={langOption.value} value={langOption.value}>{langOption.label}</MenuItem>)
|
|
48
|
+
(<MenuItem key={langOption.value} value={langOption.value}>{langOption.label || '\u00A0'}</MenuItem>)
|
|
49
49
|
))}
|
|
50
50
|
</Select>
|
|
51
51
|
</FormControl>;
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
"date_time": "Time",
|
|
32
32
|
"date_year": "Year",
|
|
33
33
|
"date_date_and_time": "Date and time",
|
|
34
|
+
"date_year_and_month": "Year and month",
|
|
35
|
+
"date_month_and_day": "Month and day",
|
|
34
36
|
"date_openDatePicker": "Open date picker dialog",
|
|
35
37
|
"date_openTimePicker": "Open time picker dialog",
|
|
36
38
|
"date_openYearPicker": "Open year picker dialog",
|