@myrtex-org/form 1.1.89 → 1.1.91

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.
@@ -2431,31 +2431,37 @@ class InputTableComponent {
2431
2431
  this._subscriptions$.push(this._store.select(selectValueModel(this.settings))
2432
2432
  .subscribe((result) => {
2433
2433
  const cloneResult = structuredClone(result);
2434
- // Наша проверка по sysName, которую мы добавили ранее
2435
2434
  if (cloneResult && !Array.isArray(cloneResult) && cloneResult.sysName === this.settings.sysName) {
2436
- // --- ВОТ ЭТОТ НОВЫЙ БЛОК ДЛЯ ВОССТАНОВЛЕНИЯ ДАТ ---
2437
- // Проверяем, есть ли вообще данные внутри пришедшей модели
2435
+ // --- ОБНОВЛЕННЫЙ БЛОК ПАРСИНГА И ЗАЩИТЫ ОТ NULL ---
2438
2436
  if (cloneResult.data && Array.isArray(cloneResult.data)) {
2439
2437
  cloneResult.data.forEach((row) => {
2440
2438
  if (row.data && Array.isArray(row.data)) {
2441
2439
  row.data.forEach((cell) => {
2442
- // Если тип компонента дата, значение строка и в ней есть наш разделитель '/'
2440
+ // 1. Если пришла строка со слэшемпарсим в массив
2443
2441
  if (cell.type === 'inputDate' && typeof cell.value === 'string' && cell.value.includes('/')) {
2444
- console.log(`[Table <- Store Parsing] Восстанавливаем range-дату из строки для ${cell.sysName}:`, cell.value);
2445
- // Разрезаем строку "2026-05-05/2026-05-07" обратно в массив ['2026-05-05', '2026-05-07']
2442
+ console.log(`[Table <- Store Parsing] Восстанавливаем range-дату:`, cell.value);
2446
2443
  cell.value = cell.value.split('/');
2447
2444
  }
2445
+ // 2. ЗАЩИТА: Если бэк прислал null, но у нас в текущей модели таблицы КУДА-ТО УЖЕ введена дата
2446
+ if (cell.type === 'inputDate' && cell.value === null) {
2447
+ // Ищем эту же ячейку в наших текущих строках на UI
2448
+ const currentRow = this._rows?.find((r) => r.id === row.id);
2449
+ const currentCell = currentRow?.data?.find((c) => c.sysName === cell.sysName);
2450
+ if (currentCell && currentCell.value) {
2451
+ console.warn(`[Table Protection] Бэк прислал null для ${cell.sysName}, но мы удерживаем текущее значение:`, currentCell.value);
2452
+ // Не даем занулить! Возвращаем ей текущее валидное значение из UI
2453
+ cell.value = structuredClone(currentCell.value);
2454
+ }
2455
+ }
2448
2456
  });
2449
2457
  }
2450
2458
  });
2451
2459
  }
2452
2460
  // -------------------------------------------------
2453
- // Проверяем, изменились ли данные по сравнению с текущими
2454
2461
  const isDataChanged = JSON.stringify(this.model?.data) !== JSON.stringify(cloneResult.data);
2455
2462
  if (isDataChanged) {
2456
2463
  console.log(`[Table -> Store Apply] [${this.settings.sysName}] Синхронизируем строки.`);
2457
2464
  this.model = structuredClone(cloneResult);
2458
- // Извлекаем строки (теперь внутри cell.value уже лежит правильный массив, и они не занулятся!)
2459
2465
  this._rows = this._extractRows(this.model.data);
2460
2466
  this._initDataSource(this._rows);
2461
2467
  }
@@ -2468,7 +2474,6 @@ class InputTableComponent {
2468
2474
  }
2469
2475
  createRow() {
2470
2476
  const initialRowModel = getRowModel(this.settings);
2471
- console.log('[Table -> Create Row] Исходная модель для новой строки:', structuredClone(initialRowModel));
2472
2477
  this._modalService.open(InputTableModalComponent, {
2473
2478
  title: 'Создание строки',
2474
2479
  okText: 'Создать',
@@ -2476,20 +2481,12 @@ class InputTableComponent {
2476
2481
  rowModel: getRowModel(this.settings),
2477
2482
  isCheckRequired: this._isCheckRequired
2478
2483
  }).afterClosed().subscribe(resolve => {
2479
- console.log('[Table <- Modal Closed (Create)] Результат из модалки:', structuredClone(resolve));
2480
2484
  if (resolve && resolve.result && resolve.rowModel) {
2481
- // КРИТИЧЕСКИЙ ХАК: Склеиваем массив диапазона дат в строку перед отправкой в Стор
2482
- if (resolve.rowModel.data && Array.isArray(resolve.rowModel.data)) {
2483
- resolve.rowModel.data.forEach((cell) => {
2484
- if (cell.type === 'inputDate' && Array.isArray(cell.value)) {
2485
- console.log(`[Table <- Modal] Найдена рендж-дата в ${cell.sysName}. Склеиваем в строку:`, cell.value);
2486
- cell.value = cell.value.join('/'); // Превращаем ['2026-05-05...', '2026-05-07...'] в "дата1/дата2"
2487
- }
2488
- });
2489
- }
2490
- // Накатываем обновленную модель в локальные строки
2485
+ // Накатываем модель из модалки (там внутри ДАТЫ ЕЩЕ В ВИДЕ МАССИВА Array(2))
2491
2486
  this._rows = [...structuredClone(this._rows), resolve.rowModel];
2487
+ // Инициализируем Грид МАССИВОМ — DevExtreme сразу отрендерит "дд.мм.гггг - дд.мм.гггг" без мигания!
2492
2488
  this._initDataSource(this._rows);
2489
+ // А вот теперь принудительно вызываем сборку модели, которая сама сожмет массивы в строки ДЛЯ СТОРА
2493
2490
  this._changeSubject$.next(this._buildTableValueModel());
2494
2491
  }
2495
2492
  });
@@ -2506,36 +2503,40 @@ class InputTableComponent {
2506
2503
  return !this._canEditObject;
2507
2504
  }
2508
2505
  editRow(event) {
2509
- const findRow = this._rows.find(item => item.id === event.row.data.id);
2510
- console.log('[Table -> Edit Row] Данные строки из клика (event.row.data):', event.row.data);
2511
- console.log('[Table -> Edit Row] Найдено в локальном rows:', structuredClone(findRow));
2512
- // const findRow: TableRowModel | undefined = this._rows.find(item => item.id === event.row.data.id);
2513
- if (findRow) {
2514
- const rowModelClone = structuredClone(findRow);
2515
- this._modalService.open(InputTableModalComponent, {
2516
- title: 'Редактирование строки',
2517
- okText: 'Сохранить',
2518
- settings: this.settings,
2519
- rowModel: rowModelClone
2520
- }).afterClosed().subscribe(resolve => {
2521
- console.log('[Table <- Modal Closed (Create)] Результат из модалки:', structuredClone(resolve));
2522
- if (resolve && resolve.result && resolve.rowModel) {
2523
- // КРИТИЧЕСКИЙ ХАК: Склеиваем массив диапазона дат в строку перед отправкой в Стор
2524
- if (resolve.rowModel.data && Array.isArray(resolve.rowModel.data)) {
2525
- resolve.rowModel.data.forEach((cell) => {
2526
- if (cell.type === 'inputDate' && Array.isArray(cell.value)) {
2527
- console.log(`[Table <- Modal] Найдена рендж-дата в ${cell.sysName}. Склеиваем в строку:`, cell.value);
2528
- cell.value = cell.value.join('/'); // Превращаем ['2026-05-05...', '2026-05-07...'] в "дата1/дата2"
2529
- }
2530
- });
2531
- }
2532
- // Накатываем обновленную модель в локальные строки
2533
- this._rows = [...structuredClone(this._rows), resolve.rowModel];
2534
- this._initDataSource(this._rows);
2535
- this._changeSubject$.next(this._buildTableValueModel());
2506
+ // 1. Находим исходную строку в нашем локальном массиве _rows
2507
+ const rowId = event.row?.data?.id || event.data?.id;
2508
+ const localRow = this._rows.find((r) => r.id === rowId);
2509
+ if (!localRow)
2510
+ return;
2511
+ const rowModel = structuredClone(localRow);
2512
+ const gridData = event.row?.data || event.data;
2513
+ // 2. СИНХРОНИЗАЦИЯ: Переносим актуальные значения из Грида (включая наш массив дат) внутрь rowModel для модалки
2514
+ if (rowModel.data && Array.isArray(rowModel.data)) {
2515
+ rowModel.data.forEach((cell) => {
2516
+ // Если в гриде есть значение для этого поля, берем его (особенно актуально для массивов дат)
2517
+ if (gridData && gridData[cell.sysName] !== undefined) {
2518
+ cell.value = structuredClone(gridData[cell.sysName]);
2536
2519
  }
2537
2520
  });
2538
2521
  }
2522
+ console.log('[Table -> Edit Row] Подготовленная rowModel для модалки с датами:', rowModel);
2523
+ // 3. Открываем модалку редактирования
2524
+ this._modalService.open(InputTableModalComponent, {
2525
+ title: 'Редактирование строки',
2526
+ okText: 'Сохранить', // или что там у тебя
2527
+ settings: this.settings,
2528
+ rowModel: rowModel, // Передаем уже пропатченную модель с массивом дат!
2529
+ isCheckRequired: this._isCheckRequired
2530
+ }).afterClosed().subscribe(resolve => {
2531
+ if (resolve && resolve.result && resolve.rowModel) {
2532
+ // Обновляем строку в локальном массиве
2533
+ this._rows = this._rows.map((r) => r.id === rowId ? resolve.rowModel : r);
2534
+ // Сразу обновляем UI грида массивами
2535
+ this._initDataSource(this._rows);
2536
+ // Отправляем сжатую строку в Стор
2537
+ this._changeSubject$.next(this._buildTableValueModel());
2538
+ }
2539
+ });
2539
2540
  }
2540
2541
  getFormat(component) {
2541
2542
  switch (component.type) {