@movalib/movalib-commons 1.1.87 → 1.1.89

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/devIndex.tsx CHANGED
@@ -143,12 +143,13 @@ const App = () => {
143
143
  <div style={{ marginTop: '40px' }} />
144
144
 
145
145
  <div style={flexCenter}>
146
- <ScheduleFields
147
- schedules={garage?.schedules}
148
- size="small"
149
- timePickerStep={30}
150
- onChange={handleScheduleChange}
151
- />
146
+ <ScheduleFields
147
+ //schedules={undefined}
148
+ schedules={garage?.schedules}
149
+ size="small"
150
+ timePickerStep={15}
151
+ onChange={handleScheduleChange}
152
+ />
152
153
  </div>
153
154
 
154
155
  <Box sx={{width:'50%'}}>
package/dist/devIndex.js CHANGED
@@ -131,7 +131,11 @@ var App = function () {
131
131
  throw new Error('Function not implemented.');
132
132
  } }), (0, jsx_runtime_1.jsx)(MovaSignUp_1.default, { headerText: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(material_1.Alert, __assign({ severity: 'success', icon: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}), style: Tools_1.flexCenter, sx: { width: '100%', textTransform: 'none', textAlign: 'center' } }, { children: (0, jsx_runtime_1.jsx)("b", { children: "NOUVEAU COMPTE UTILISATEUR" }) })) }), darkMode: false, movaAppType: Enums_1.MovaAppType.INDIVIDUAL, onSubmit: function (form) {
133
133
  alert('Form Submitted !');
134
- } }), (0, jsx_runtime_1.jsx)(GaragePLV_1.default, { url: getQRCodeData() }), (0, jsx_runtime_1.jsx)(QRCode_1.default, { data: getQRCodeData(), showDownload: true, size: 400 }), (0, jsx_runtime_1.jsx)("div", { style: { marginTop: '40px' } }), (0, jsx_runtime_1.jsx)("div", __assign({ style: Tools_1.flexCenter }, { children: (0, jsx_runtime_1.jsx)(ScheduleFields_1.default, { schedules: garage === null || garage === void 0 ? void 0 : garage.schedules, size: "small", timePickerStep: 30, onChange: handleScheduleChange }) })), (0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ sx: { width: '50%' } }, { children: [(0, jsx_runtime_1.jsx)(AddressFields_1.default, { form: {
134
+ } }), (0, jsx_runtime_1.jsx)(GaragePLV_1.default, { url: getQRCodeData() }), (0, jsx_runtime_1.jsx)(QRCode_1.default, { data: getQRCodeData(), showDownload: true, size: 400 }), (0, jsx_runtime_1.jsx)("div", { style: { marginTop: '40px' } }), (0, jsx_runtime_1.jsx)("div", __assign({ style: Tools_1.flexCenter }, { children: (0, jsx_runtime_1.jsx)(ScheduleFields_1.default
135
+ //schedules={undefined}
136
+ , {
137
+ //schedules={undefined}
138
+ schedules: garage === null || garage === void 0 ? void 0 : garage.schedules, size: "small", timePickerStep: 15, onChange: handleScheduleChange }) })), (0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ sx: { width: '50%' } }, { children: [(0, jsx_runtime_1.jsx)(AddressFields_1.default, { form: {
135
139
  streetName: {
136
140
  value: undefined,
137
141
  error: undefined,
@@ -33,6 +33,7 @@ var theme_1 = __importDefault(require("../theme")); // Import du thème personna
33
33
  var Enums_1 = require("./helpers/Enums");
34
34
  var Logger_1 = __importDefault(require("./helpers/Logger"));
35
35
  var Tools_1 = require("./helpers/Tools");
36
+ var ContentCopy_1 = __importDefault(require("@mui/icons-material/ContentCopy"));
36
37
  var initialSchedules = [
37
38
  { day: Enums_1.DayOfWeek.MONDAY, checked: false, allDay: false, intervals: [{ startTime: null, endTime: null, countryCode: 'fr', error: null }] },
38
39
  { day: Enums_1.DayOfWeek.TUESDAY, checked: false, allDay: false, intervals: [{ startTime: null, endTime: null, countryCode: 'fr', error: null }] },
@@ -146,11 +147,34 @@ var ScheduleFields = function (_a) {
146
147
  newSchedule[dayIndex].intervals[intervalIndex].error = validateIntervals(newSchedule[dayIndex].intervals);
147
148
  }
148
149
  setSchedule(newSchedule);
149
- // On invoque la callback de mise à jour uniquement sur l'intervalle de fin
150
- if (type === 'endTime')
150
+ if (type === 'endTime') {
151
+ // On invoque la callback de mise à jour uniquement sur l'intervalle de fin
151
152
  onChange(newSchedule);
153
+ }
152
154
  };
153
155
  };
156
+ var copySchedule = function (dayIndex) { return function () {
157
+ // On duplique les intervals sur la journée suivante si disponible
158
+ var newSchedule = __spreadArray([], schedule, true);
159
+ // Si journée suivante existante, pas d'erreurs sur les intervalles du schedule et au moins un intervalle complet contenant des Date valides
160
+ if (dayIndex + 1 < schedule.length && !(newSchedule[dayIndex].intervals.filter(function (i) { return Boolean(i.error); }).length > 0)
161
+ && (newSchedule[dayIndex].intervals.filter(function (i) { return Boolean(i.startTime instanceof Date) && Boolean(i.endTime instanceof Date); }).length > 0)) {
162
+ // Dupliquer les intervalles vers la journée suivante
163
+ var nextDayIntervals = newSchedule[dayIndex].intervals.map(function (interval) {
164
+ var newStartTime = new Date(String(interval.startTime));
165
+ newStartTime.setDate(newStartTime.getDate() + 1);
166
+ var newEndTime = new Date(String(interval.endTime));
167
+ newEndTime.setDate(newEndTime.getDate() + 1);
168
+ return __assign(__assign({}, interval), { startTime: newStartTime, endTime: newEndTime });
169
+ });
170
+ // Ajouter ou remplacer les intervalles du jour suivant
171
+ newSchedule[dayIndex + 1].intervals = nextDayIntervals;
172
+ newSchedule[dayIndex + 1].checked = true; // On active automatiquement la journée suivante
173
+ setSchedule(newSchedule);
174
+ // On invoque la callback de mise à jour uniquement sur l'intervalle de fin
175
+ onChange(newSchedule);
176
+ }
177
+ }; };
154
178
  var addInterval = function (dayIndex) { return function () {
155
179
  Logger_1.default.info(dayIndex);
156
180
  var newSchedule = __spreadArray([], schedule, true);
@@ -164,7 +188,7 @@ var ScheduleFields = function (_a) {
164
188
  onChange(newSchedule);
165
189
  setSchedule(newSchedule);
166
190
  }; };
167
- return ((0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ container: true, spacing: 1, sx: { minWidth: '650px', maxWidth: '800px' } }, { children: schedule.map(function (daySchedule, dayIndex) { return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 2 }, { children: (0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(material_1.Checkbox, { checked: daySchedule.checked, onChange: handleDayChecked(dayIndex) }), label: (0, Tools_1.getDayOfWeekLabel)(daySchedule.day) }) }), dayIndex + 1), (0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 7 }, { children: daySchedule.intervals.map(function (interval, intervalIndex) { return ((0, jsx_runtime_1.jsxs)(material_1.Grid, __assign({ container: true, style: { paddingTop: intervalIndex > 0 ? theme_1.default.spacing(1) : 0 } }, { children: [(0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 6, sx: { textAlign: 'center' } }, { children: (0, jsx_runtime_1.jsx)(x_date_pickers_1.TimePicker, { views: ['hours', 'minutes'], minutesStep: timePickerStep !== null && timePickerStep !== void 0 ? timePickerStep : 30, disabled: !daySchedule.checked, value: interval.startTime, formatDensity: 'dense', onChange: handleIntervalChange(dayIndex, intervalIndex, 'startTime'), slotProps: {
191
+ return ((0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ container: true, spacing: 1, sx: { minWidth: '650px', maxWidth: '800px' } }, { children: schedule.map(function (daySchedule, dayIndex) { return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 2 }, { children: (0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(material_1.Checkbox, { checked: daySchedule.checked, onChange: handleDayChecked(dayIndex) }), label: (0, Tools_1.getDayOfWeekLabel)(daySchedule.day) }) }), dayIndex + 1), (0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 7 }, { children: daySchedule.intervals.map(function (interval, intervalIndex) { return ((0, jsx_runtime_1.jsxs)(material_1.Grid, __assign({ container: true, style: { paddingTop: intervalIndex > 0 ? theme_1.default.spacing(1) : 0 } }, { children: [(0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 6, sx: { textAlign: 'center' } }, { children: (0, jsx_runtime_1.jsx)(x_date_pickers_1.TimePicker, { views: ['hours', 'minutes'], minutesStep: timePickerStep !== null && timePickerStep !== void 0 ? timePickerStep : 30, disabled: !daySchedule.checked, value: interval.startTime, formatDensity: 'dense', closeOnSelect: false, onAccept: handleIntervalChange(dayIndex, intervalIndex, 'startTime'), slotProps: {
168
192
  textField: {
169
193
  size: 'small',
170
194
  sx: {
@@ -176,21 +200,19 @@ var ScheduleFields = function (_a) {
176
200
  actionBar: {
177
201
  sx: { display: 'none' },
178
202
  },
179
- } }) }), (intervalIndex + 1) * Math.random()), (0, jsx_runtime_1.jsxs)(material_1.Grid, __assign({ item: true, xs: 6, sx: { display: 'contents' } }, { children: [(0, jsx_runtime_1.jsx)(x_date_pickers_1.TimePicker, { minutesStep: timePickerStep !== null && timePickerStep !== void 0 ? timePickerStep : 30, disabled: !(interval.startTime instanceof Date), value: interval.endTime, formatDensity: 'dense', onChange: handleIntervalChange(dayIndex, intervalIndex, 'endTime'),
180
- //onClose={handleIntervalClose}
181
- closeOnSelect: false, slotProps: {
182
- textField: {
183
- size: 'small',
184
- sx: {
185
- width: '150px',
186
- minWidth: '100px',
187
- padding: 0,
188
- },
189
- },
190
- actionBar: {
191
- sx: { display: 'none' },
203
+ } }) }), (intervalIndex + 1) * Math.random()), (0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 6, sx: { display: 'contents' } }, { children: (0, jsx_runtime_1.jsx)(x_date_pickers_1.TimePicker, { minutesStep: timePickerStep !== null && timePickerStep !== void 0 ? timePickerStep : 30, disabled: !(interval.startTime instanceof Date), value: interval.endTime, formatDensity: 'dense', onAccept: handleIntervalChange(dayIndex, intervalIndex, 'endTime'), closeOnSelect: false, slotProps: {
204
+ textField: {
205
+ size: 'small',
206
+ sx: {
207
+ width: '150px',
208
+ minWidth: '100px',
209
+ padding: 0,
192
210
  },
193
- } }), intervalIndex > 0 &&
194
- (0, jsx_runtime_1.jsx)(material_1.IconButton, __assign({ onClick: deleteInterval(dayIndex, intervalIndex), disabled: !daySchedule.checked, sx: { ml: 2 } }, { children: (0, jsx_runtime_1.jsx)(DeleteRounded_1.default, {}) }))] }), (intervalIndex + 1) * Math.random()), (0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 12 }, { children: interval.error && (0, jsx_runtime_1.jsx)(material_1.FormHelperText, __assign({ error: true, sx: { mb: 1 } }, { children: interval.error })) }), (intervalIndex + 1) * Math.random())] }), intervalIndex + 1)); }) }), (dayIndex + 1) * Math.random()), (0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 1, sx: { pl: 0 } }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, __assign({ onClick: addInterval(dayIndex), disabled: !daySchedule.checked }, { children: (0, jsx_runtime_1.jsx)(AddRounded_1.default, {}) })) }), (dayIndex + 1) * Math.random()), (0, jsx_runtime_1.jsx)(material_1.Grid, { item: true, xs: 2 })] })); }) })));
211
+ },
212
+ actionBar: {
213
+ sx: { display: 'none' },
214
+ },
215
+ } }) }), (intervalIndex + 1) * Math.random()), (0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 1, sx: { pl: 0 }, style: { display: 'flex', justifyContent: 'center', alignItems: 'start' } }, { children: intervalIndex > 0 &&
216
+ (0, jsx_runtime_1.jsx)(material_1.Tooltip, __assign({ title: 'Supprimer intervalle', placement: 'top' }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, __assign({ onClick: deleteInterval(dayIndex, intervalIndex), disabled: !daySchedule.checked, sx: { ml: 2 } }, { children: (0, jsx_runtime_1.jsx)(DeleteRounded_1.default, {}) })) })) }), (dayIndex + 1) * Math.random()), (0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 12 }, { children: interval.error && (0, jsx_runtime_1.jsx)(material_1.FormHelperText, __assign({ error: true, sx: { mb: 1 } }, { children: interval.error })) }), (intervalIndex + 1) * Math.random())] }), intervalIndex + 1)); }) }), (dayIndex + 1) * Math.random()), (0, jsx_runtime_1.jsxs)(material_1.Grid, __assign({ item: true, xs: 1, sx: { pl: 0 }, style: { display: 'flex', justifyContent: 'center', alignItems: 'start' } }, { children: [(0, jsx_runtime_1.jsx)(material_1.Tooltip, __assign({ title: 'Dupliquer', placement: 'top' }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, __assign({ onClick: copySchedule(dayIndex), disabled: !daySchedule.checked }, { children: (0, jsx_runtime_1.jsx)(ContentCopy_1.default, {}) })) })), (0, jsx_runtime_1.jsx)(material_1.Tooltip, __assign({ title: 'Ajouter intervalle', placement: 'top' }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, __assign({ onClick: addInterval(dayIndex), disabled: !daySchedule.checked }, { children: (0, jsx_runtime_1.jsx)(AddRounded_1.default, {}) })) }))] }), (dayIndex + 1) * Math.random()), (0, jsx_runtime_1.jsx)(material_1.Grid, { item: true, xs: 1 })] })); }) })));
195
217
  };
196
218
  exports.default = ScheduleFields;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@movalib/movalib-commons",
3
- "version": "1.1.87",
3
+ "version": "1.1.89",
4
4
  "description": "Bibliothèque d'objets communs à l'ensemble des projets React de Movalib",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { FunctionComponent, useEffect, useState } from 'react';
3
- import { Checkbox, FormControlLabel, Grid, IconButton, FormHelperText, FormControl, RadioGroup, Radio } from '@mui/material';
3
+ import { Checkbox, FormControlLabel, Grid, IconButton, FormHelperText, FormControl, RadioGroup, Radio, Tooltip } from '@mui/material';
4
4
  import AddIcon from '@mui/icons-material/AddRounded';
5
5
  import DeleteIcon from '@mui/icons-material/DeleteRounded';
6
6
  import { TimePicker } from '@mui/x-date-pickers';
@@ -10,6 +10,7 @@ import { DayOfWeek } from './helpers/Enums';
10
10
  import Logger from './helpers/Logger';
11
11
  import { flexCenter, getDayOfWeekIndex, getDayOfWeekLabel } from './helpers/Tools';
12
12
  import { toUTCToLocaleDate } from './helpers/DateUtils';
13
+ import ContentCopyIcon from '@mui/icons-material/ContentCopy';
13
14
 
14
15
 
15
16
  export type DayInterval = {
@@ -44,7 +45,7 @@ interface ScheduleFieldsProps {
44
45
  }
45
46
 
46
47
  const ScheduleFields: FunctionComponent<ScheduleFieldsProps> = ({ timePickerStep, schedules, size, onChange }) => {
47
-
48
+
48
49
  const mergeSchedules = (apiSchedules: Schedule[]): DaySchedule[] => {
49
50
  // Créez une copie profonde du tableau initialSchedules pour éviter toute mutation accidentelle
50
51
  const mergedSchedules = JSON.parse(JSON.stringify(initialSchedules));
@@ -179,9 +180,44 @@ const ScheduleFields: FunctionComponent<ScheduleFieldsProps> = ({ timePickerStep
179
180
 
180
181
  setSchedule(newSchedule);
181
182
 
182
- // On invoque la callback de mise à jour uniquement sur l'intervalle de fin
183
- if(type === 'endTime')
183
+ if(type === 'endTime'){
184
+ // On invoque la callback de mise à jour uniquement sur l'intervalle de fin
184
185
  onChange(newSchedule);
186
+ }
187
+
188
+ };
189
+
190
+ const copySchedule = (dayIndex: number) => () => {
191
+ // On duplique les intervals sur la journée suivante si disponible
192
+ const newSchedule = [...schedule];
193
+
194
+ // Si journée suivante existante, pas d'erreurs sur les intervalles du schedule et au moins un intervalle complet contenant des Date valides
195
+ if (dayIndex + 1 < schedule.length && ! (newSchedule[dayIndex].intervals.filter(i => Boolean(i.error)).length > 0)
196
+ && (newSchedule[dayIndex].intervals.filter(i => Boolean(i.startTime instanceof Date) && Boolean(i.endTime instanceof Date)).length > 0)) {
197
+
198
+ // Dupliquer les intervalles vers la journée suivante
199
+ const nextDayIntervals = newSchedule[dayIndex].intervals.map(interval => {
200
+ const newStartTime = new Date(String(interval.startTime));
201
+ newStartTime.setDate(newStartTime.getDate() + 1);
202
+ const newEndTime = new Date(String(interval.endTime));
203
+ newEndTime.setDate(newEndTime.getDate() + 1);
204
+
205
+ return {
206
+ ...interval,
207
+ startTime: newStartTime,
208
+ endTime: newEndTime
209
+ };
210
+ });
211
+
212
+ // Ajouter ou remplacer les intervalles du jour suivant
213
+ newSchedule[dayIndex + 1].intervals = nextDayIntervals;
214
+ newSchedule[dayIndex + 1].checked = true // On active automatiquement la journée suivante
215
+
216
+ setSchedule(newSchedule);
217
+
218
+ // On invoque la callback de mise à jour uniquement sur l'intervalle de fin
219
+ onChange(newSchedule);
220
+ }
185
221
  };
186
222
 
187
223
  const addInterval = (dayIndex: number) => () => {
@@ -226,8 +262,9 @@ const ScheduleFields: FunctionComponent<ScheduleFieldsProps> = ({ timePickerStep
226
262
  minutesStep={timePickerStep ?? 30} // Valeur par défaut de 30 minutes au cas ou
227
263
  disabled={!daySchedule.checked}
228
264
  value={interval.startTime}
229
- formatDensity='dense'
230
- onChange={handleIntervalChange(dayIndex, intervalIndex, 'startTime')}
265
+ formatDensity='dense'
266
+ closeOnSelect={false}
267
+ onAccept={handleIntervalChange(dayIndex, intervalIndex, 'startTime')}
231
268
  slotProps={{
232
269
  textField: {
233
270
  size: 'small',
@@ -249,8 +286,7 @@ const ScheduleFields: FunctionComponent<ScheduleFieldsProps> = ({ timePickerStep
249
286
  disabled={!(interval.startTime instanceof Date)}
250
287
  value={interval.endTime}
251
288
  formatDensity='dense'
252
- onChange={handleIntervalChange(dayIndex, intervalIndex, 'endTime')}
253
- //onClose={handleIntervalClose}
289
+ onAccept={handleIntervalChange(dayIndex, intervalIndex, 'endTime')}
254
290
  closeOnSelect={false}
255
291
  slotProps={{
256
292
  textField: {
@@ -266,12 +302,17 @@ const ScheduleFields: FunctionComponent<ScheduleFieldsProps> = ({ timePickerStep
266
302
  },
267
303
  }}
268
304
  />
269
- {intervalIndex > 0 &&
270
- <IconButton onClick={deleteInterval(dayIndex, intervalIndex)} disabled={!daySchedule.checked} sx={{ ml: 2 }}>
271
- <DeleteIcon />
272
- </IconButton>
273
- }
274
305
  </Grid>
306
+ <Grid item xs={1} key={(dayIndex+1)*Math.random()} sx={{ pl: 0 }} style={{ display: 'flex', justifyContent: 'center', alignItems: 'start' }}>
307
+ {intervalIndex > 0 &&
308
+ <Tooltip title='Supprimer intervalle' placement='top' >
309
+ <IconButton onClick={deleteInterval(dayIndex, intervalIndex)} disabled={!daySchedule.checked} sx={{ ml: 2 }}>
310
+ <DeleteIcon />
311
+ </IconButton>
312
+ </Tooltip>
313
+ }
314
+ </Grid>
315
+
275
316
  <Grid item xs={12} key={(intervalIndex+1)*Math.random()} >
276
317
  {interval.error && <FormHelperText error sx={{mb:1}}>{interval.error}</FormHelperText>}
277
318
  </Grid>
@@ -279,13 +320,20 @@ const ScheduleFields: FunctionComponent<ScheduleFieldsProps> = ({ timePickerStep
279
320
  ))}
280
321
  </Grid>
281
322
 
282
- <Grid item xs={1} key={(dayIndex+1)*Math.random()} sx={{ pl: 0 }}>
283
- <IconButton onClick={addInterval(dayIndex)} disabled={!daySchedule.checked}>
284
- <AddIcon />
285
- </IconButton>
323
+ <Grid item xs={1} key={(dayIndex+1)*Math.random()} sx={{ pl: 0 }} style={{ display: 'flex', justifyContent: 'center', alignItems: 'start' }}>
324
+ <Tooltip title='Dupliquer' placement='top'>
325
+ <IconButton onClick={copySchedule(dayIndex)} disabled={!daySchedule.checked}>
326
+ <ContentCopyIcon />
327
+ </IconButton>
328
+ </Tooltip>
329
+ <Tooltip title='Ajouter intervalle' placement='top'>
330
+ <IconButton onClick={addInterval(dayIndex)} disabled={!daySchedule.checked}>
331
+ <AddIcon />
332
+ </IconButton>
333
+ </Tooltip>
286
334
  </Grid>
287
335
 
288
- <Grid item xs={2} />
336
+ <Grid item xs={1} />
289
337
  </>
290
338
  ))}
291
339
  </Grid>