pcm-shared-components 2.1.406 → 2.1.407

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.
@@ -22,6 +22,22 @@ const isFullWidthField = field => ['select', 'textarea', 'select_multiple', 'not
22
22
  // through unflattened still works.
23
23
  const readFieldProp = (field, key) => field[key] !== undefined ? field[key] : field.meta?.[key];
24
24
 
25
+ // Same type-aware required-field wording as AnimalVehicleDetailsEditor's tab-per-animal grid
26
+ // (index.jsx, this directory) -- duplicated rather than shared, matching the small amount of
27
+ // tolerated duplication already elsewhere in this feature (e.g. each host app keeps its own copy
28
+ // for its live-preview sandbox). Falls back to animal.required_error for text/textarea. 'notice'
29
+ // gets its own message rather than the generic one -- its required-satisfying condition is
30
+ // stricter than every other type (see isFieldAnswered below): only a CHECKED "I have read this"
31
+ // box counts, so "please fill this in" would read wrong for what's actually a checkbox.
32
+ const REQUIRED_ERROR_KEY_BY_TYPE = {
33
+ select: 'animal.required_error_select',
34
+ select_multiple: 'animal.required_error_select_multiple',
35
+ number: 'animal.required_error_number',
36
+ date: 'animal.required_error_date',
37
+ yes_no: 'animal.required_error_yes_no',
38
+ notice: 'animal.required_error_notice'
39
+ };
40
+
25
41
  /**
26
42
  * Flat, non-tabbed block for a lot's "once per reservation" animal fields: no tabs, no per-animal
27
43
  * chrome, no add/remove -- these are single shared values/notices for the whole reservation, not
@@ -59,12 +75,14 @@ export const AnimalFieldsOnceBlock = props => {
59
75
  fields,
60
76
  values,
61
77
  onChange,
78
+ isFieldAnswered,
62
79
  className,
63
80
  theme,
64
81
  i18next
65
82
  } = props;
66
83
  const compTheme = theme || useTheme();
67
84
  const defaultTheme = createTheme(compTheme);
85
+ const requiredErrorText = fieldType => i18next.t(REQUIRED_ERROR_KEY_BY_TYPE[fieldType] || 'animal.required_error');
68
86
  const relevantFields = fields.filter(field => readFieldProp(field, 'once_per_reservation') === true);
69
87
  if (relevantFields.length === 0) return null;
70
88
  return /*#__PURE__*/React.createElement(ThemeProvider, {
@@ -80,6 +98,14 @@ export const AnimalFieldsOnceBlock = props => {
80
98
  }
81
99
  }, relevantFields.map(field => {
82
100
  const rawValue = values?.[field.key] ?? (field.type === 'select_multiple' ? [] : '');
101
+ // Required-and-not-yet-answered gets the same red label + control error state the
102
+ // per-animal grid already shows (index.jsx, this directory) -- this block previously
103
+ // hardcoded error: false/helperText: '' unconditionally, so a required once-per-
104
+ // reservation field (e.g. a mandatory "I have read this" notice, or a required yes_no
105
+ // asked once) never visibly indicated it was outstanding. isFieldAnswered is supplied
106
+ // by the caller (same prop AnimalVehicleDetailsEditor already requires), since it's
107
+ // app-specific logic this shared package doesn't own.
108
+ const showError = field.required && !isFieldAnswered(field.type, rawValue);
83
109
  const labelText = field.required ? `${field.label} *` : field.label;
84
110
  return /*#__PURE__*/React.createElement("div", {
85
111
  key: field.key,
@@ -88,7 +114,8 @@ export const AnimalFieldsOnceBlock = props => {
88
114
  variant: "body2",
89
115
  sx: {
90
116
  fontWeight: 500,
91
- mb: 0.5
117
+ mb: 0.5,
118
+ color: showError ? 'error.main' : 'text.primary'
92
119
  }
93
120
  }, labelText), renderFieldTypeControl({
94
121
  field,
@@ -98,8 +125,8 @@ export const AnimalFieldsOnceBlock = props => {
98
125
  // consumer's own event wiring calls it directly in a test.
99
126
  onChange: onChange ? newValue => onChange(field.key, newValue) : () => {},
100
127
  disabled: !onChange,
101
- error: false,
102
- helperText: '',
128
+ error: showError,
129
+ helperText: showError ? requiredErrorText(field.type) : '',
103
130
  i18next
104
131
  }));
105
132
  }))));
@@ -138,6 +165,10 @@ AnimalFieldsOnceBlock.propTypes = {
138
165
  /** (fieldKey, value) => void. Omit entirely to render every input control disabled/read-only
139
166
  * (review-screen usage) -- see the component doc above. */
140
167
  onChange: PropTypes.func,
168
+ /** (fieldType, value) => boolean. Same function each host app already passes into
169
+ * AnimalVehicleDetailsEditor's isFieldAnswered prop -- required so a required-but-unanswered
170
+ * once-per-reservation field can show the same red label/error state the per-animal grid does. */
171
+ isFieldAnswered: PropTypes.func.isRequired,
141
172
  /** Classes applied to the component's own wrapper div. */
142
173
  className: PropTypes.string,
143
174
  /** Theme object to use on this component, if none provided then the MUI5 theme provider theme is used. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pcm-shared-components",
3
- "version": "2.1.406",
3
+ "version": "2.1.407",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "babel": {