pcm-shared-components 2.1.388 → 2.1.389

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.
@@ -85,6 +85,7 @@ export const AnimalVehicleDetailsEditor = props => {
85
85
  onRemoveItem,
86
86
  canAddMore,
87
87
  maxItems,
88
+ showHistoricalAnswers,
88
89
  className,
89
90
  theme,
90
91
  i18next
@@ -115,6 +116,28 @@ export const AnimalVehicleDetailsEditor = props => {
115
116
  setPendingRemoveId(null);
116
117
  };
117
118
 
119
+ // Historical answers have no live field config left (see the Historical answers block below),
120
+ // so there's no field.type to route through a type-specific "clear" -- but classifyAnimalFieldValue
121
+ // treats an empty string as 'unanswered' regardless of what type the value used to be (a retired
122
+ // boolean/array/number all read back through the exact same generic-stringify branch above), so
123
+ // routing every deletion through the one existing onFieldChange callback with value '' is enough
124
+ // to make the entry disappear next render. No new prop needed on top of the ones this component
125
+ // already takes. Holds an array of keys so one dialog/confirm serves both a single delete and
126
+ // "Clear" (all of them at once) -- the array just has one entry for a single delete.
127
+ const [pendingHistoricalDelete, setPendingHistoricalDelete] = useState(null);
128
+ const requestDeleteHistorical = (itemId, deleteKeys) => setPendingHistoricalDelete({
129
+ itemId,
130
+ keys: deleteKeys
131
+ });
132
+ const confirmDeleteHistorical = () => {
133
+ const {
134
+ itemId,
135
+ keys: deleteKeys
136
+ } = pendingHistoricalDelete;
137
+ deleteKeys.forEach(k => onFieldChange(itemId, k, ''));
138
+ setPendingHistoricalDelete(null);
139
+ };
140
+
118
141
  // A drifted field (its stored value no longer matches this field's current type/options -- see
119
142
  // isFieldDrifted) renders read-only instead of feeding a mismatched value into a live
120
143
  // type-specific control (e.g. never shove a raw string into a date picker). "Replace" reveals
@@ -280,8 +303,12 @@ export const AnimalVehicleDetailsEditor = props => {
280
303
  // replaceable. Not drifted (or already revealed): behaves exactly as before.
281
304
  const value = showAsDrifted ? rawValue : wasDrifted ? field.type === 'select_multiple' ? [] : '' : rawValue;
282
305
  const showError = field.required && !isFieldAnswered(field.type, value);
283
- const labelText = field.required ? `${field.label} *` : `${field.label} (${i18next.t('common.app.optional')})`;
284
- const wrapperClassName = ['select', 'textarea', 'select_multiple', 'yes_no'].includes(field.type) ? 'col-span-full' : undefined;
306
+ // No "(Optional)" suffix -- required fields already say so via the asterisk, so
307
+ // spelling out the alternative on every other field was redundant noise, and the
308
+ // extra length was long enough to wrap onto a second line in a narrow column,
309
+ // throwing that field's input out of vertical alignment with its paired neighbor.
310
+ const labelText = field.required ? `${field.label} *` : field.label;
311
+ const wrapperClassName = ['select', 'textarea', 'select_multiple'].includes(field.type) ? 'col-span-full' : undefined;
285
312
  let control;
286
313
  if (showAsDrifted) {
287
314
  // Generic stringify -- this renders whatever type the field used to be, which
@@ -425,7 +452,8 @@ export const AnimalVehicleDetailsEditor = props => {
425
452
  if (val !== null) onFieldChange(selectedItem.id, field.key, val === 'yes');
426
453
  },
427
454
  fullWidth: true,
428
- size: "small"
455
+ size: "small",
456
+ color: showError ? 'error' : 'standard'
429
457
  }, /*#__PURE__*/React.createElement(ToggleButton, {
430
458
  value: "yes"
431
459
  }, i18next.t('common.app.yes')), /*#__PURE__*/React.createElement(ToggleButton, {
@@ -484,7 +512,7 @@ export const AnimalVehicleDetailsEditor = props => {
484
512
  color: "error",
485
513
  className: "block mt-4"
486
514
  }, requiredErrorText(field.type)));
487
- })))), selectedItem && (() => {
515
+ })))), showHistoricalAnswers && selectedItem && (() => {
488
516
  const liveKeys = new Set(fieldConfig.map(f => f.key));
489
517
  const historicalEntries = Object.keys(selectedItem.values || {}).filter(k => !liveKeys.has(k)).map(k => ({
490
518
  key: k,
@@ -500,11 +528,15 @@ export const AnimalVehicleDetailsEditor = props => {
500
528
  bgcolor: 'action.hover'
501
529
  }
502
530
  }, /*#__PURE__*/React.createElement("div", {
503
- className: "flex items-center",
531
+ className: "flex items-center justify-between",
504
532
  style: {
505
- gap: 6,
506
533
  marginBottom: 4
507
534
  }
535
+ }, /*#__PURE__*/React.createElement("div", {
536
+ className: "flex items-center",
537
+ style: {
538
+ gap: 6
539
+ }
508
540
  }, /*#__PURE__*/React.createElement(WarningAmberIcon, {
509
541
  fontSize: "small",
510
542
  color: "warning"
@@ -512,7 +544,15 @@ export const AnimalVehicleDetailsEditor = props => {
512
544
  sx: {
513
545
  fontWeight: 700
514
546
  }
515
- }, i18next.t('animal.historical_answers_title'))), /*#__PURE__*/React.createElement(Typography, {
547
+ }, i18next.t('animal.historical_answers_title'))), /*#__PURE__*/React.createElement(Button, {
548
+ size: "small",
549
+ color: "error",
550
+ onClick: () => requestDeleteHistorical(selectedItem.id, historicalEntries.map(e => e.key)),
551
+ sx: {
552
+ textTransform: 'none',
553
+ minWidth: 0
554
+ }
555
+ }, i18next.t('common.app.clear'))), /*#__PURE__*/React.createElement(Typography, {
516
556
  variant: "caption",
517
557
  color: "text.secondary",
518
558
  sx: {
@@ -535,7 +575,15 @@ export const AnimalVehicleDetailsEditor = props => {
535
575
  const label = k.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
536
576
  return /*#__PURE__*/React.createElement("div", {
537
577
  key: k,
538
- className: "flex flex-col"
578
+ className: "flex items-start justify-between",
579
+ style: {
580
+ gap: 4
581
+ }
582
+ }, /*#__PURE__*/React.createElement("div", {
583
+ className: "flex flex-col",
584
+ style: {
585
+ minWidth: 0
586
+ }
539
587
  }, /*#__PURE__*/React.createElement(Typography, {
540
588
  variant: "body2",
541
589
  sx: {
@@ -545,9 +593,21 @@ export const AnimalVehicleDetailsEditor = props => {
545
593
  }, label), /*#__PURE__*/React.createElement(Typography, {
546
594
  variant: "body2",
547
595
  sx: {
548
- color: 'text.primary'
596
+ color: 'text.primary',
597
+ wordBreak: 'break-word'
598
+ }
599
+ }, displayText)), /*#__PURE__*/React.createElement(IconButton, {
600
+ size: "small",
601
+ color: "error",
602
+ "aria-label": i18next.t('common.app.delete'),
603
+ onClick: () => requestDeleteHistorical(selectedItem.id, [k]),
604
+ sx: {
605
+ flexShrink: 0,
606
+ mt: -0.5
549
607
  }
550
- }, displayText));
608
+ }, /*#__PURE__*/React.createElement(DeleteOutlineIcon, {
609
+ fontSize: "small"
610
+ })));
551
611
  })));
552
612
  })(), (() => {
553
613
  const incompleteCount = items.filter(item => missingRequiredFields(item).length > 0).length;
@@ -590,7 +650,18 @@ export const AnimalVehicleDetailsEditor = props => {
590
650
  color: "error",
591
651
  variant: "contained",
592
652
  onClick: confirmRemove
593
- }, i18next.t('common.app.remove'))))));
653
+ }, i18next.t('common.app.remove')))), /*#__PURE__*/React.createElement(Dialog, {
654
+ open: pendingHistoricalDelete !== null,
655
+ onClose: () => setPendingHistoricalDelete(null),
656
+ maxWidth: "xs",
657
+ fullWidth: true
658
+ }, /*#__PURE__*/React.createElement(DialogTitle, null, i18next.t('common.app.delete')), /*#__PURE__*/React.createElement(DialogContent, null, /*#__PURE__*/React.createElement(DialogContentText, null, i18next.t('common.app.generic_delete_message'))), /*#__PURE__*/React.createElement(DialogActions, null, /*#__PURE__*/React.createElement(Button, {
659
+ onClick: () => setPendingHistoricalDelete(null)
660
+ }, i18next.t('common.app.cancel')), /*#__PURE__*/React.createElement(Button, {
661
+ color: "error",
662
+ variant: "contained",
663
+ onClick: confirmDeleteHistorical
664
+ }, i18next.t('common.app.delete'))))));
594
665
  };
595
666
  AnimalVehicleDetailsEditor.defaultProps = {
596
667
  items: [],
@@ -601,6 +672,7 @@ AnimalVehicleDetailsEditor.defaultProps = {
601
672
  isFieldDrifted: () => false,
602
673
  canAddMore: true,
603
674
  maxItems: 0,
675
+ showHistoricalAnswers: true,
604
676
  className: 'w-full',
605
677
  theme: undefined,
606
678
  i18next: i18nextLocal
@@ -642,6 +714,11 @@ AnimalVehicleDetailsEditor.propTypes = {
642
714
  canAddMore: PropTypes.bool,
643
715
  /** Shown in the "max reached" message once canAddMore is false. */
644
716
  maxItems: PropTypes.number,
717
+ /** Whether the read-only "Historical Answers" block (retired field keys still holding a value)
718
+ * can render at all. Defaults to true for the admin edit screen, where reviewing/clearing a
719
+ * since-retired answer on an EXISTING reservation is legitimate. A guest-facing booking widget
720
+ * creating a brand-new reservation has no history to show and should pass false. */
721
+ showHistoricalAnswers: PropTypes.bool,
645
722
  /** Classes applied to the component's own wrapper div. */
646
723
  className: PropTypes.string,
647
724
  /** Theme object to use on this component, if none provided then the MUI5 theme provider theme is used. */
@@ -2475,7 +2475,8 @@
2475
2475
  "online_booking_title": "Animal details for online booking",
2476
2476
  "manage_fields": "Manage fields",
2477
2477
  "fields_configured_count_one": "{{count}} field configured",
2478
- "fields_configured_count_other": "{{count}} fields configured"
2478
+ "fields_configured_count_other": "{{count}} fields configured",
2479
+ "fields_configured_count_plural": "{{count}} fields configured"
2479
2480
  },
2480
2481
  "edit_lot": "Edit Lot",
2481
2482
  "lot_id_exist": "Lot number already exist",
@@ -2475,7 +2475,8 @@
2475
2475
  "online_booking_title": "Detalles de los animales para la reserva en línea",
2476
2476
  "manage_fields": "Administrar campos",
2477
2477
  "fields_configured_count_one": "{{count}} campo configurado",
2478
- "fields_configured_count_other": "{{count}} campos configurados"
2478
+ "fields_configured_count_other": "{{count}} campos configurados",
2479
+ "fields_configured_count_plural": "{{count}} campos configurados"
2479
2480
  },
2480
2481
  "edit_lot": "Editar lote",
2481
2482
  "lot_id_exist": "El número de lote ya existe",
@@ -2475,7 +2475,8 @@
2475
2475
  "online_booking_title": "Détails sur les animaux pour la réservation en ligne",
2476
2476
  "manage_fields": "Gérer les champs",
2477
2477
  "fields_configured_count_one": "{{count}} champ configuré",
2478
- "fields_configured_count_other": "{{count}} champs configurés"
2478
+ "fields_configured_count_other": "{{count}} champs configurés",
2479
+ "fields_configured_count_plural": "{{count}} champs configurés"
2479
2480
  },
2480
2481
  "edit_lot": "Editer le lot",
2481
2482
  "lot_id_exist": "Le numéro de lot existe déjà",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pcm-shared-components",
3
- "version": "2.1.388",
3
+ "version": "2.1.389",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "babel": {