@onehat/ui 0.4.75 → 0.4.77

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onehat/ui",
3
- "version": "0.4.75",
3
+ "version": "0.4.77",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -185,7 +185,27 @@ function Form(props) {
185
185
  }),
186
186
  initialValues = _.merge(startingValues, (record && !record.isDestroyed ? record.submitValues : {})),
187
187
  defaultValues = isMultiple ? getNullFieldValues(initialValues, Repository) : initialValues, // when multiple entities, set all default values to null
188
- validatorToUse = validator || (isMultiple ? disableRequiredYupFields(Repository?.schema?.model?.validator) : Repository?.schema?.model?.validator) || yup.object(),
188
+ validatorToUse = (() => {
189
+ // If a custom validator is provided, use it
190
+ if (validator) {
191
+ return validator;
192
+ }
193
+
194
+ // If we have a Repository with a schema, use it (with modifications for multiple records)
195
+ if (Repository?.schema?.model?.validator) {
196
+ return isMultiple
197
+ ? disableRequiredYupFields(Repository.schema.model.validator)
198
+ : Repository.schema.model.validator;
199
+ }
200
+
201
+ // For forms with no fields (like reports), create a schema that defaults to valid
202
+ if (!items || items.length === 0) {
203
+ return yup.object().default({}); // This will make the form valid by default
204
+ }
205
+
206
+ // Fallback to empty schema that allows any fields and defaults to valid
207
+ return yup.object().noUnknown(false).default({});
208
+ })(),
189
209
  {
190
210
  control,
191
211
  formState,
@@ -1131,6 +1151,20 @@ function Form(props) {
1131
1151
  }, [formState.isDirty]);
1132
1152
  }
1133
1153
 
1154
+ useEffect(() => {
1155
+ // For forms with no items (like some reports), manually trigger validation to set valid state
1156
+ if ((!items || items.length === 0) && !columnsConfig) {
1157
+ setTimeout(() => { // ensure the form is fully initialized
1158
+ trigger().then(() => {
1159
+ // Force validity to true for empty forms
1160
+ if (onValidityChange) {
1161
+ onValidityChange(true);
1162
+ }
1163
+ });
1164
+ }, 0);
1165
+ }
1166
+ }, [items, columnsConfig, trigger, onValidityChange]);
1167
+
1134
1168
  if (skipAll) {
1135
1169
  return null;
1136
1170
  }
@@ -10,6 +10,7 @@ import {
10
10
  UPLOAD_DOWNLOAD,
11
11
  DOWNLOAD,
12
12
  } from '../../Constants/Commands.js';
13
+ import Inflector from 'inflector-js';
13
14
  import Clipboard from '../Icons/Clipboard.js';
14
15
  import Duplicate from '../Icons/Duplicate.js';
15
16
  import Edit from '../Icons/Edit.js';
@@ -78,7 +79,10 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
78
79
  disableDuplicate = !isEditor,
79
80
  disablePrint = !isGrid,
80
81
  protectedValues, // records with these values cannot be edited or deleted
81
-
82
+ addDisplayMsg,
83
+ editDisplayMsg,
84
+ deleteDisplayMsg,
85
+
82
86
  // withAlert
83
87
  showInfo,
84
88
 
@@ -90,6 +94,7 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
90
94
  self,
91
95
 
92
96
  // withData
97
+ model,
93
98
  Repository,
94
99
 
95
100
  // withPermissions
@@ -219,7 +224,16 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
219
224
  switch(type) {
220
225
  case ADD:
221
226
  key = 'addBtn';
222
- text = 'Add';
227
+ if (addDisplayMsg) {
228
+ text = addDisplayMsg;
229
+ } else {
230
+ text = 'Add';
231
+ if (model) {
232
+ let inflected = Inflector.singularize(model); // can only add one at a time
233
+ inflected = Inflector.camel2words(Inflector.humanize(Inflector.underscore(inflected))); // Separate with spaces, capitalize each word
234
+ text += ' ' + inflected;
235
+ }
236
+ }
223
237
  handler = (parent, e) => {
224
238
  onAdd();
225
239
  };
@@ -232,7 +246,21 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
232
246
  break;
233
247
  case EDIT:
234
248
  key = 'editBtn';
235
- text = 'Edit';
249
+ if (editDisplayMsg) {
250
+ text = editDisplayMsg;
251
+ } else {
252
+ text = 'Edit';
253
+ if (model) {
254
+ let inflected = model;
255
+ if (selection.length <= 1) {
256
+ inflected = Inflector.singularize(inflected);
257
+ } else {
258
+ inflected = Inflector.pluralize(inflected);
259
+ }
260
+ inflected = Inflector.camel2words(Inflector.humanize(Inflector.underscore(inflected))); // Separate with spaces, capitalize each word
261
+ text += ' ' + inflected;
262
+ }
263
+ }
236
264
  handler = (parent, e) => {
237
265
  onEdit();
238
266
  };
@@ -248,7 +276,21 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
248
276
  break;
249
277
  case DELETE:
250
278
  key = 'deleteBtn';
251
- text = 'Delete';
279
+ if (deleteDisplayMsg) {
280
+ text = deleteDisplayMsg;
281
+ } else {
282
+ text = 'Delete';
283
+ if (model) {
284
+ let inflected = model;
285
+ if (selection.length <= 1) {
286
+ inflected = Inflector.singularize(inflected);
287
+ } else {
288
+ inflected = Inflector.pluralize(inflected);
289
+ }
290
+ inflected = Inflector.camel2words(Inflector.humanize(Inflector.underscore(inflected))); // Separate with spaces, capitalize each word
291
+ text += ' ' + inflected;
292
+ }
293
+ }
252
294
  handler = onDelete;
253
295
  handler = (parent, e) => {
254
296
  onDelete();