mobx-formkit 1.1.2 → 1.1.3

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.
@@ -129,6 +129,8 @@
129
129
  class ArrayMap {
130
130
  /** Duck-typing marker for utility code */
131
131
  _isArrayMap = true;
132
+ /** Called after a successful `move()` — used to flag the change as dirty */
133
+ onMove;
132
134
  /** Internal observable array: entries stored as [key, value] pairs */
133
135
  _entries = mobx.observable.array([]);
134
136
  constructor(entries) {
@@ -246,6 +248,7 @@
246
248
  return;
247
249
  const [entry] = this._entries.splice(fromIndex, 1);
248
250
  this._entries.splice(toIndex, 0, entry);
251
+ this.onMove?.();
249
252
  });
250
253
  }
251
254
  /**
@@ -963,7 +966,14 @@
963
966
  set: mobx.action,
964
967
  add: mobx.action,
965
968
  del: mobx.action,
969
+ move: mobx.action,
966
970
  });
971
+ // Any reorder of the fields (also when `fields.move()` is called
972
+ // directly) flags the field and the form as changed. (#657)
973
+ this.fields.onMove = () => {
974
+ this.$changed++;
975
+ this.state.form.$changed++;
976
+ };
967
977
  }
968
978
  execHook = (name, fallback = {}, ...args) => $try(fallback[name], this.$hooks[name], this.noop).apply(this, [this, ...args]);
969
979
  execHandler = (name, args, fallback = undefined, hook = null, execHook = true) => [
@@ -1204,10 +1214,21 @@
1204
1214
  deepCheck(type, prop, fields) {
1205
1215
  const $fields = getObservableMapValues(fields);
1206
1216
  return lodash.transform($fields, (check, field) => {
1207
- if (!field.fields.size ||
1208
- !Array.isArray(field.initial) ||
1209
- prop === FieldPropsEnum.isValid ||
1210
- prop === FieldPropsEnum.hasError) {
1217
+ // Array containers are skipped because most of their props are
1218
+ // computed recursively on their nested fields. Some props are not
1219
+ // recursive (isDirty/isPristine compare the container value with
1220
+ // its initial value) or must aggregate the container itself
1221
+ // (isValid/hasError), so they are taken into account for array
1222
+ // containers too. (#656, #657)
1223
+ const isContainerProp = [
1224
+ FieldPropsEnum.isValid,
1225
+ FieldPropsEnum.hasError,
1226
+ FieldPropsEnum.isDirty,
1227
+ FieldPropsEnum.isPristine,
1228
+ ].includes(prop);
1229
+ if (isContainerProp ||
1230
+ !field.fields.size ||
1231
+ !Array.isArray(field.initial)) {
1211
1232
  check.push(field[prop]);
1212
1233
  }
1213
1234
  check.push(checkPropOccurrence({
@@ -1474,17 +1495,41 @@
1474
1495
  return this;
1475
1496
  }
1476
1497
  let key;
1498
+ const tree = pathToFieldsTree(this.state.struct(), this.path ?? "", 0, true);
1499
+ const nestedFields = tree[0]?.fields ?? null;
1500
+ // An object without field-definition props, whose keys match the
1501
+ // nested fields of the container, holds the values of the new item
1502
+ // (e.g. add({ name: 'John', qty: 1 })). The 'name' prop is ambiguous:
1503
+ // it is treated as a value only when the container defines a nested
1504
+ // field called 'name'. (#657)
1505
+ const payloadKeys = lodash.isPlainObject(obj)
1506
+ ? Object.keys(obj).filter((k) => k !== FieldPropsEnum.key)
1507
+ : [];
1508
+ const isValuesPayload = !!nestedFields &&
1509
+ lodash.isPlainObject(obj) &&
1510
+ !lodash.has(obj, FieldPropsEnum.value) &&
1511
+ !lodash.has(obj, FieldPropsEnum.fields) &&
1512
+ payloadKeys.length > 0 &&
1513
+ (!lodash.has(obj, FieldPropsEnum.name) ||
1514
+ Object.prototype.hasOwnProperty.call(nestedFields, FieldPropsEnum.name));
1477
1515
  if (lodash.has(obj, FieldPropsEnum.key))
1478
1516
  key = obj.key;
1479
- if (lodash.has(obj, FieldPropsEnum.name))
1517
+ if (!isValuesPayload && lodash.has(obj, FieldPropsEnum.name))
1480
1518
  key = obj.name;
1481
1519
  if (!key)
1482
1520
  key = maxKey(this.fields);
1483
1521
  const $path = ($key) => [this.path, $key].join(".").replace(/^\.+/, "");
1484
- const tree = pathToFieldsTree(this.state.struct(), this.path ?? "", 0, true);
1485
- const field = this.initField(key, $path(key), lodash.merge(tree[0], obj));
1522
+ const field = this.initField(key, $path(key), isValuesPayload ? tree[0] : lodash.merge(tree[0], obj));
1486
1523
  const hasValues = lodash.has(obj, FieldPropsEnum.value) || lodash.has(obj, FieldPropsEnum.fields);
1487
- if (!hasValues) {
1524
+ if (isValuesPayload) {
1525
+ lodash.each(payloadKeys, (fieldName) => {
1526
+ const nestedField = field.select(fieldName);
1527
+ if (nestedField && !nestedField.hasNestedFields) {
1528
+ nestedField.set(FieldPropsEnum.value, obj[fieldName]);
1529
+ }
1530
+ });
1531
+ }
1532
+ else if (!hasValues) {
1488
1533
  // When the struct defines nested fields and obj is a plain object
1489
1534
  // without field-definition props (key, name), treat obj properties
1490
1535
  // directly as nested field values (e.g. add({ firstname: 'John' }))
@@ -2526,11 +2571,12 @@
2526
2571
  }
2527
2572
  get isDirty() {
2528
2573
  const value = this.changed ? this.value : this.initial;
2529
- return !lodash.isEqual(this.initial, value);
2574
+ // a soft deleted field differs from its initial state
2575
+ return !lodash.isEqual(this.initial, value) || this.deleted;
2530
2576
  }
2531
2577
  get isPristine() {
2532
2578
  const value = this.changed ? this.value : this.initial;
2533
- return lodash.isEqual(this.initial, value);
2579
+ return lodash.isEqual(this.initial, value) && !this.deleted;
2534
2580
  }
2535
2581
  get isEmpty() {
2536
2582
  if (this.hasNestedFields)
@@ -2561,9 +2607,10 @@
2561
2607
  : this.$touched;
2562
2608
  }
2563
2609
  get deleted() {
2564
- return this.hasNestedFields
2565
- ? this.check(FieldPropsEnum.deleted, true)
2566
- : this.$deleted;
2610
+ // an explicit flag on the field itself always wins
2611
+ if (this.$deleted)
2612
+ return true;
2613
+ return this.hasNestedFields ? this.check(FieldPropsEnum.deleted, true) : false;
2567
2614
  }
2568
2615
  /* ------------------------------------------------------------------ */
2569
2616
  /* EVENTS HANDLERS */