@entryscape/rdforms 10.4.0 → 10.5.2

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.
@@ -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
- const data = binding.getValue();
84
- if (data != null && data !== '') {
85
- try {
86
- let str;
87
- if (data.indexOf('T') > 0) {
88
- str = moment(data).format('lll');
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 : new Date(value));
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 dateFormat = selectedDatatype === 'Year' ? 'YYYY' : 'YYYY-MM-DD';
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
- <DatePicker
144
- renderInput={(props) => <TextField {...props} {...inputProps} />}
145
- leftArrowButtonProps={{ 'aria-label': bundle.date_previousMonth }}
146
- rightArrowButtonProps={{ 'aria-label': bundle.date_nextMonth }}
147
- KeyboardButtonProps={{
148
- 'aria-label':
149
- selectedDatatype === 'Year'
150
- ? bundle.date_openYearPicker
151
- : bundle.date_openDatePicker,
152
- }}
153
- label={
154
- selectedDatatype === 'Year' ? bundle.date_year : bundle.date_date
155
- }
156
- value={selectedDate}
157
- minDate={moment(new Date('0000-01-01'))}
158
- inputFormat={dateFormat}
159
- views={selectedDatatype === 'Year' ? ['year'] : ['day']}
160
- onChange={onDateChange}
161
- autoOk={true}
162
- mask={selectedDatatype === 'Year' ? '____' : '____-__-__'}
163
- PopperProps={{
164
- modifiers: [
165
- {
166
- name: 'flip',
167
- enabled: false,
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={(props) => <TextField {...props} {...inputProps} />}
155
+ renderInput={props => <TextField {...props} {...inputProps} />}
175
156
  label={bundle.date_time}
176
- {...(selectedDatatype === 'Datetime' ? {} : { disabled: true })}
157
+ {...(selectedDatatype === 'DateTime' || selectedDatatype === 'Time' ? {} : { disabled: true })}
177
158
  KeyboardButtonProps={{
178
159
  'aria-label': bundle.date_openTimePicker,
179
160
  }}
180
- value={selectedDatatype === 'Datetime' ? selectedDate : null}
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.Datetime && (
208
- <MenuItem value="Datetime">
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);
@@ -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(({ className, ...props }) => (
10
- <Tooltip {...props} classes={{ popper: className }} />
11
- ))(({ theme }) => ({
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
- let Button;
152
- const card = item.getCardinality();
153
- if (binding == null) {
154
- Button = renderingContext.addExpandButton(rowNode, null, item, context);
155
- } else if (binding.getPredicate() && !context.view.showAsTable(item) && card.max !== 1 &&
156
- (card.max == null || card.max !== card.min)) {
157
- Button = renderingContext.addCreateChildButton(rowNode, null, binding, context);
158
- }
159
- if (Button) {
160
- rowNode.appendChild(<Button key={`${binding.getHash()}_labelEnd`}></Button>);
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",