@entryscape/rdforms 10.3.1 → 10.5.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.
@@ -1,116 +1,96 @@
1
1
  /* eslint-disable no-unused-vars */
2
2
  import React, { useState, useEffect, useMemo } from 'react';
3
- import Grid from '@material-ui/core/Grid';
4
- import { MuiPickersUtilsProvider, KeyboardDatePicker, KeyboardTimePicker } from '@material-ui/pickers';
5
- import MomentUtils from '@date-io/moment';
6
- import MenuItem from '@material-ui/core/MenuItem';
7
- import FormControl from '@material-ui/core/FormControl';
8
- import Select from '@material-ui/core/Select';
3
+ import { DatePicker, TimePicker, LocalizationProvider } from '@mui/lab';
4
+ import DateAdapter from '@mui/lab/AdapterMoment';
5
+ import MenuItem from '@mui/material/MenuItem';
6
+ import FormControl from '@mui/material/FormControl';
7
+ import { TextField } from '@mui/material';
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
-
83
24
  const datePresenter = (fieldDiv, binding, context) => {
84
- const data = binding.getValue();
85
- if (data != null && data !== '') {
86
- try {
87
- let str;
88
- if (data.indexOf('T') > 0) {
89
- str = moment(data).format('lll');
90
- } else if (data.length > 4) {
91
- str = moment(data).format('LL');
92
- } else {
93
- str = moment(data).format('YYYY');
94
- }
95
- fieldDiv.appendChild(<div key={binding.getHash()} >{str}</div>);
96
- } catch (e) {
97
- 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.`);
98
- }
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.`);
99
31
  }
100
32
  };
101
33
 
102
34
  const presenters = renderingContext.presenterRegistry;
35
+ presenters.itemtype('text').datatype('xsd:dateTime').register(datePresenter);
103
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);
104
41
  presenters.itemtype('text').datatype('dcterms:W3CDTF').register(datePresenter);
105
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
+
106
86
 
107
87
  const dateEditor = (fieldDiv, binding, context) => {
108
88
  const bundle = context.view.messages;
109
89
  const DateComp = () => {
110
90
  const value = binding.getGist();
111
- const alternatives = useMemo(() => getAllowedDateAlternatives(binding.getItem()));
91
+ const alternatives = useMemo(() => getAllowedDateAlternatives(binding.getItem()), []);
112
92
  const onlyOneAlternative = Object.keys(alternatives).length === 1;
113
- const [selectedDate, setSelectedDate] = useState(value === '' ? null : new Date(value));
93
+ const [selectedDate, setSelectedDate] = useState(value === '' ? null : getDate(value));
114
94
  const [selectedDatatype, setDatatype] = useState(getDatatypeFromBinding(binding));
115
95
  useEffect(() => {
116
96
  context.clear = () => {
@@ -134,41 +114,96 @@ const dateEditor = (fieldDiv, binding, context) => {
134
114
  binding.setValue(getDateValue(selectedDate, event.target.value));
135
115
  setDatatype(event.target.value);
136
116
  };
137
- const inputProps = { 'aria-labelledby': context.view.getLabelIndex(binding) };
138
- const dateFormat = selectedDatatype === 'Year' ? 'YYYY' : 'YYYY-MM-DD';
117
+ const inputProps = {
118
+ 'aria-labelledby': context.view.getLabelIndex(binding),
119
+ variant: renderingContext.materialVariant,
120
+ };
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';
139
125
  return (
140
- <MuiPickersUtilsProvider utils={MomentUtils}>
126
+ <LocalizationProvider dateAdapter={DateAdapter}>
141
127
  <span className="rdformsDatePicker">
142
- <KeyboardDatePicker
143
- leftArrowButtonProps={{ 'aria-label': bundle.date_previousMonth }}
144
- rightArrowButtonProps={{ 'aria-label': bundle.date_nextMonth }}
145
- KeyboardButtonProps={{ 'aria-label': selectedDatatype === 'Year' ?
146
- bundle.date_openYearPicker : bundle.date_openDatePicker }}
147
- label={selectedDatatype === 'Year' ? bundle.date_year : bundle.date_date}
148
- value={selectedDate} minDate={new Date('0000-01-01')} format={dateFormat}
149
- views={selectedDatatype === 'Year' ? ['year'] : ['date']}
150
- inputProps={inputProps}
151
- onChange={onDateChange} autoOk={true} inputVariant={renderingContext.materialVariant}/>
152
- {alternatives.Datetime && (<KeyboardTimePicker
153
- label={bundle.date_time}
154
- { ...(selectedDatatype === 'Datetime' ? {} : { disabled: true })}
155
- KeyboardButtonProps={{ 'aria-label': bundle.date_openTimePicker }}
156
- value={selectedDatatype === 'Datetime' ? selectedDate : null}
157
- onChange={onDateChange} ampm={false} autoOk={true}
158
- inputProps={inputProps}
159
- inputVariant={renderingContext.materialVariant}/>)}
160
- {!onlyOneAlternative && (<FormControl variant={renderingContext.materialVariant}>
161
- <Select
162
- value={selectedDatatype}
163
- inputProps={inputProps}
164
- onChange={onDatatypeChange}>
165
- {alternatives.Year && (<MenuItem value="Year">{bundle.date_year}</MenuItem>)}
166
- {alternatives.Date && (<MenuItem value="Date">{bundle.date_date}</MenuItem>)}
167
- {alternatives.Datetime && (<MenuItem value="Datetime">{bundle.date_date_and_time}</MenuItem>)}
168
- </Select>
169
- </FormControl>)}
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) && (
154
+ <TimePicker
155
+ renderInput={props => <TextField {...props} {...inputProps} />}
156
+ label={bundle.date_time}
157
+ {...(selectedDatatype === 'DateTime' || selectedDatatype === 'Time' ? {} : { disabled: true })}
158
+ KeyboardButtonProps={{
159
+ 'aria-label': bundle.date_openTimePicker,
160
+ }}
161
+ value={selectedDatatype === 'DateTime' || selectedDatatype === 'Time' ? selectedDate : null}
162
+ onChange={onDateChange}
163
+ ampm={false}
164
+ autoOk={true}
165
+ PopperProps={{
166
+ modifiers: [
167
+ {
168
+ name: 'flip',
169
+ enabled: false,
170
+ },
171
+ ],
172
+ }}
173
+ />
174
+ )}
175
+ {!onlyOneAlternative && (
176
+ <FormControl variant={renderingContext.materialVariant}>
177
+ <Select
178
+ value={selectedDatatype}
179
+ inputProps={inputProps}
180
+ onChange={onDatatypeChange}
181
+ >
182
+ {alternatives.Year && (
183
+ <MenuItem value="Year">{bundle.date_year}</MenuItem>
184
+ )}
185
+ {alternatives.Date && (
186
+ <MenuItem value="Date">{bundle.date_date}</MenuItem>
187
+ )}
188
+ {alternatives.DateTime && (
189
+ <MenuItem value="DateTime">
190
+ {bundle.date_date_and_time}
191
+ </MenuItem>
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
+ )}
202
+ </Select>
203
+ </FormControl>
204
+ )}
170
205
  </span>
171
- </MuiPickersUtilsProvider>
206
+ </LocalizationProvider>
172
207
  );
173
208
  };
174
209
  fieldDiv.appendChild(<DateComp key={binding.getHash()}></DateComp>);
@@ -178,4 +213,7 @@ const editors = renderingContext.editorRegistry;
178
213
  editors.itemtype('text').datatype('http://www.w3.org/2001/XMLSchema#date').register(dateEditor);
179
214
  editors.itemtype('text').datatype('http://www.w3.org/2001/XMLSchema#dateTime').register(dateEditor);
180
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);
181
219
  editors.itemtype('text').datatype('http://purl.org/dc/terms/W3CDTF').register(dateEditor);
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-unused-vars */
2
2
  import React, { useState, useEffect, useMemo } from 'react';
3
- import TextField from '@material-ui/core/TextField';
3
+ import TextField from '@mui/material/TextField';
4
4
  import renderingContext from '../renderingContext';
5
5
  import { toDuration, fromDuration } from './util';
6
6
 
@@ -1,25 +1,28 @@
1
1
  /* eslint-disable no-unused-vars */
2
- import React, { useState, useEffect } from 'react';
3
- import Tooltip from '@material-ui/core/Tooltip';
4
- import { withStyles } from '@material-ui/core/styles';
5
- import ClickAwayListener from '@material-ui/core/ClickAwayListener';
2
+ import React, { useState, useEffect, forwardRef } from 'react';
3
+ import Tooltip, { tooltipClasses } from '@mui/material/Tooltip';
4
+ import { styled } from '@mui/material/styles';
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 = withStyles(theme => ({
10
- tooltip: {
9
+ const StyledTooltip = styled(
10
+ forwardRef(({ className, ...props }, ref) => (
11
+ <Tooltip {...props} classes={{ popper: className }} />
12
+ ))
13
+ )(({ theme }) => ({
14
+ [`& .${tooltipClasses.tooltip}`]: {
11
15
  backgroundColor: theme.palette.background.default,
12
16
  fontSize: 12,
13
17
  color: 'black',
14
18
  boxShadow: theme.shadows[10],
19
+ pointerEvents: 'auto',
15
20
  },
16
- tooltipPlacementBottom: {
21
+ [`& .${tooltipClasses.tooltipPlacementBottom}`]: {
17
22
  margin: '2px 0 24px 0',
23
+ marginTop: '0px !important',
18
24
  },
19
- popper: {
20
- pointerEvents: 'auto',
21
- },
22
- }))(Tooltip);
25
+ }));
23
26
 
24
27
  const ItemTooltip = (props) => {
25
28
  const [open, setOpen] = useState(false);
@@ -36,14 +39,28 @@ const ItemTooltip = (props) => {
36
39
  }
37
40
  const description = props.item.getDescription() || (property ? '' : props.context.view.messages.info_missing || '');
38
41
 
39
- return <ClickAwayListener onClickAway={handleTooltipClose}>
40
- <StyledTooltip title={(<><p className="rdformsLinebreaks rdformsDescription">{description}</p>{propinfo}</>)}
41
- placement="bottom-start" disableHoverListener disableTouchListener
42
- onClose={handleTooltipClose}
43
- onOpen={handleTooltipOpen}
44
- open={open}
45
- ><span onClick={handleTooltipOpen}>{
46
- props.children}</span></StyledTooltip></ClickAwayListener>;
42
+ return (
43
+ <ClickAwayListener onClickAway={handleTooltipClose}>
44
+ <StyledTooltip
45
+ title={
46
+ <>
47
+ <p className="rdformsLinebreaks rdformsDescription">
48
+ {description}
49
+ </p>
50
+ {propinfo}
51
+ </>
52
+ }
53
+ placement="bottom-start"
54
+ disableHoverListener
55
+ disableTouchListener
56
+ onClose={handleTooltipClose}
57
+ onOpen={handleTooltipOpen}
58
+ open={open}
59
+ >
60
+ <span onClick={handleTooltipOpen}>{props.children}</span>
61
+ </StyledTooltip>
62
+ </ClickAwayListener>
63
+ );
47
64
  };
48
65
 
49
66
  renderingContext.renderPresenterLabel = (rowNode, binding, item, context) => {
@@ -133,16 +150,18 @@ const ERR = (props) => {
133
150
 
134
151
  renderingContext.renderEditorLabelScopeEnd = (rowNode, binding, item, context) => {
135
152
  if (!item.hasStyle('nonEditable') && !item.hasStyle('heading')) {
136
- let Button;
137
- const card = item.getCardinality();
138
- if (binding == null) {
139
- Button = renderingContext.addExpandButton(rowNode, null, item, context);
140
- } else if (binding.getPredicate() && !context.view.showAsTable(item) && card.max !== 1 &&
141
- (card.max == null || card.max !== card.min)) {
142
- Button = renderingContext.addCreateChildButton(rowNode, null, binding, context);
143
- }
144
- if (Button) {
145
- 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
+ }
146
165
  }
147
166
  // If the item is deprecated and there are at least one matching value (binding),
148
167
  // provide a message and make sure the entire row (including the label) is deleted when
@@ -1,12 +1,12 @@
1
1
  /* eslint-disable no-unused-vars */
2
2
  // eslint-disable-next-line no-unused-vars
3
3
  import React, { useState, useEffect, useMemo } from 'react';
4
- import TextField from '@material-ui/core/TextField';
5
- import OpenInNewIcon from '@material-ui/icons/OpenInNew';
6
- import IconButton from '@material-ui/core/IconButton';
7
- import MenuItem from '@material-ui/core/MenuItem';
8
- import FormControl from '@material-ui/core/FormControl';
9
- import Select from '@material-ui/core/Select';
4
+ import TextField from '@mui/material/TextField';
5
+ import OpenInNewIcon from '@mui/icons-material/OpenInNew';
6
+ import IconButton from '@mui/material/IconButton';
7
+ import MenuItem from '@mui/material/MenuItem';
8
+ import FormControl from '@mui/material/FormControl';
9
+ import Select from '@mui/material/Select';
10
10
  import moment from 'moment';
11
11
  import renderingContext from '../renderingContext';
12
12
  import utils from '../../utils';
@@ -41,12 +41,11 @@ const LanguageControl = (props) => {
41
41
  return <FormControl className="rdformsLangControl" variant={renderingContext.materialVariant}>
42
42
  <Select
43
43
  inputProps={{ 'aria-labelledby': props.labelledby }}
44
-
45
44
  value={lang}
46
45
  onChange={onLangChange}>
47
46
  {langs.map(langOption => (langOption === null ?
48
47
  (<MenuItem key="_none" value="_none" disabled>─────</MenuItem>) :
49
- (<MenuItem key={langOption.value} value={langOption.value}>{langOption.label}</MenuItem>)
48
+ (<MenuItem key={langOption.value} value={langOption.value}>{langOption.label || '\u00A0'}</MenuItem>)
50
49
  ))}
51
50
  </Select>
52
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",