@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
|
|
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
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
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) {
|