diff --git a/src/component/DualSpreadsheet/DualSpreadsheet.tsx b/src/component/DualSpreadsheet/DualSpreadsheet.tsx index f10456f..1a7ffcf 100644 --- a/src/component/DualSpreadsheet/DualSpreadsheet.tsx +++ b/src/component/DualSpreadsheet/DualSpreadsheet.tsx @@ -2,7 +2,14 @@ import { useMultiSheetEngine } from '@/hook/useMultiSheetEngine' import { useSheetAutoSave } from '@/hook/useSheetAutoSave' import { getFileData, getLatestFileForTemplate } from '@/service/fileApiService' import { produce } from 'immer' -import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react' +import React, { + FC, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react' // Импорты из новых модулей import { FormulaBar, Spreadsheet } from './components' @@ -720,6 +727,12 @@ const DualSpreadsheet: FC = ({ [templateId] ) + // Мемоизируем getAllModifiedCells для предотвращения частых ререндеров хука автосохранения + const memoizedGetAllModifiedCells = useCallback( + multiSheetEngine.getAllModifiedCells, + [multiSheetEngine.getAllModifiedCells] + ) + // Используем новый хук автосохранения const { isSaving, @@ -731,25 +744,12 @@ const DualSpreadsheet: FC = ({ loadSavedSheets, loadSheets, // Добавляем асинхронную функцию загрузки } = useSheetAutoSave( - multiSheetEngine.getAllModifiedCells, + memoizedGetAllModifiedCells, multiSheetEngine.isCalculating, revision, autoSaveOptions ) - // Отладка templateId - useEffect(() => { - // console.log('🆔 Текущий templateId в DualSpreadsheet:', { - //templateId, - //type: typeof templateId, - //isValid: templateId - // ? /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test( - // templateId - // ) - // : false, - //}) - }, [templateId]) - // Используем хук для перетаскивания разделителя const handleDividerDrag = useCallback((newLeftPercentage: number) => { // Используем requestAnimationFrame для более плавного обновления @@ -932,42 +932,45 @@ const DualSpreadsheet: FC = ({ style={{ transition: 'none' }} > {SHEET_TYPES.map((sheetType, index) => ( - + + + {index === 0 && ( +
+
+
+ )} + ))} -
-
-
) diff --git a/src/hook/adapters/apiSaveAdapter.ts b/src/hook/adapters/apiSaveAdapter.ts deleted file mode 100644 index 22e5b82..0000000 --- a/src/hook/adapters/apiSaveAdapter.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { - ApiSheet, - createSheet, - getSheetsByTemplate, - patchSheet, -} from '../../service/sheetApiService' -import { SaveAdapter } from '../useAutoSave' - -// Утилита для извлечения UUID из templateId -const extractUUID = (id: string): string => { - const uuidRegex = - /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i - if (uuidRegex.test(id)) { - return id - } - - const match = id.match( - /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i - ) - if (match) { - return match[0] - } - - return id -} - -/** - * Адаптер для сохранения через API - */ -export function createApiSaveAdapter(templateId: string): SaveAdapter { - let sheetsCache: Record = {} - - const cleanTemplateId = extractUUID(templateId) - const uuidRegex = - /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i - - if (!uuidRegex.test(cleanTemplateId)) { - throw new Error('Invalid template ID format') - } - - return { - async save(data: Record>) { - const sheetNames = Object.keys(data) - if (sheetNames.length === 0) return - - const savePromises = sheetNames.map(async sheetName => { - const sheetCells = data[sheetName] - const existingSheet = sheetsCache[sheetName] - - if (!sheetCells || Object.keys(sheetCells).length === 0) { - return - } - - if (existingSheet) { - // Обновляем существующий лист - const mergedCells = { - ...existingSheet.cells, - ...sheetCells, - } - - const isChanged = Object.keys(sheetCells).some( - key => existingSheet.cells[key] !== sheetCells[key] - ) - - if (!isChanged) return - - await patchSheet(existingSheet.id, { - cells: mergedCells, - }) - - sheetsCache[sheetName] = { - ...existingSheet, - cells: mergedCells, - updated_at: new Date().toISOString(), - } - } else { - // Создаем новый лист - const newSheet = await createSheet({ - name: sheetName, - cells: sheetCells, - template_id: cleanTemplateId, - }) - - sheetsCache[sheetName] = { - id: newSheet.id, - name: sheetName, - cells: sheetCells, - template_id: cleanTemplateId, - created_at: new Date().toISOString(), - updated_at: new Date().toISOString(), - deleted_at: null, - } - } - }) - - await Promise.all(savePromises) - }, - - async load() { - try { - const sheets = await getSheetsByTemplate(cleanTemplateId) - const sheetsMap: Record = {} - const result: Record> = {} - - sheets.forEach(sheet => { - sheetsMap[sheet.name] = sheet - if (sheet.cells && Object.keys(sheet.cells).length > 0) { - result[sheet.name] = sheet.cells - } - }) - - sheetsCache = sheetsMap - return result - } catch (error) { - console.error('Ошибка при загрузке листов:', error) - return {} - } - }, - - async clear() { - // Для API очистка может означать удаление всех листов - // Пока просто очищаем кеш - sheetsCache = {} - }, - } -} diff --git a/src/hook/adapters/localStorageSaveAdapter.ts b/src/hook/adapters/localStorageSaveAdapter.ts deleted file mode 100644 index 4e6dff6..0000000 --- a/src/hook/adapters/localStorageSaveAdapter.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { SaveAdapter } from '../useAutoSave' - -interface SavedLocalStorageData { - templateId: string - formulaData: Record> - timestamp: string - version: number -} - -// Ключ для localStorage -const getStorageKey = (templateId: string) => { - return `formula_data_${templateId}` -} - -/** - * Адаптер для сохранения в localStorage - */ -export function createLocalStorageSaveAdapter(templateId: string): SaveAdapter { - let versionCounter = 1 - - // Инициализируем версию из существующих данных - try { - const storageKey = getStorageKey(templateId) - const savedDataStr = localStorage.getItem(storageKey) - if (savedDataStr) { - const parsedData: SavedLocalStorageData = JSON.parse(savedDataStr) - versionCounter = parsedData.version + 1 - } - } catch (error) { - console.warn('⚠️ Ошибка при загрузке данных из localStorage:', error) - } - - return { - async save(data: Record>) { - // Имитируем задержку API для реалистичности - await new Promise(resolve => - setTimeout(resolve, 200 + Math.random() * 300) - ) - - // Иногда имитируем ошибку (2% вероятность) - if (Math.random() < 0.02) { - throw new Error('Ошибка записи в хранилище') - } - - const savedData: SavedLocalStorageData = { - templateId, - formulaData: data, - timestamp: new Date().toISOString(), - version: versionCounter++, - } - - const storageKey = getStorageKey(templateId) - localStorage.setItem(storageKey, JSON.stringify(savedData)) - }, - - async load() { - try { - const storageKey = getStorageKey(templateId) - const savedDataStr = localStorage.getItem(storageKey) - - if (savedDataStr) { - const parsedData: SavedLocalStorageData = JSON.parse(savedDataStr) - return parsedData.formulaData - } - - return {} - } catch (error) { - console.error( - '❌ Ошибка при загрузке сохраненных данных из localStorage:', - error - ) - return {} - } - }, - - async clear() { - try { - const storageKey = getStorageKey(templateId) - localStorage.removeItem(storageKey) - versionCounter = 1 - } catch (error) { - console.error('❌ Ошибка при очистке сохраненных данных:', error) - } - }, - } -} diff --git a/src/hook/useAutoSave.ts b/src/hook/useAutoSave.ts deleted file mode 100644 index 2bfd331..0000000 --- a/src/hook/useAutoSave.ts +++ /dev/null @@ -1,197 +0,0 @@ -import { useCallback, useEffect, useRef, useState } from 'react' - -/** - * Адаптер для различных способов сохранения - */ -export interface SaveAdapter { - save: (data: Record>) => Promise - load?: () => Promise>> - clear?: () => Promise -} - -export interface UseAutoSaveOptions { - templateId?: string - autoSaveDelay?: number - enableAutoSave?: boolean - adapter: SaveAdapter -} - -/** - * Универсальный хук автосохранения - * Поддерживает различные адаптеры сохранения (API, localStorage, etc.) - */ -export const useAutoSave = ( - getAllModifiedCells: () => Record>, - isCalculating: boolean, - revision: number, - options: UseAutoSaveOptions -) => { - const { - templateId, - autoSaveDelay = 2000, - enableAutoSave = true, - adapter, - } = options - - // Состояние - const [lastSavedRevision, setLastSavedRevision] = useState(0) - const [isSaving, setIsSaving] = useState(false) - const [lastSaveError, setLastSaveError] = useState(null) - const [isLoading, setIsLoading] = useState(false) - - // Refs - const saveTimeoutRef = useRef(null) - - // Основная функция сохранения - const performSave = useCallback( - async (data: Record>) => { - if (Object.keys(data).length === 0) { - return - } - - if (!templateId) { - console.warn('⚠️ Не указан templateId для сохранения') - return - } - - setIsSaving(true) - setLastSaveError(null) - - try { - await adapter.save(data) - setLastSavedRevision(revision) - } catch (error) { - const errorMessage = - error instanceof Error ? error.message : 'Неизвестная ошибка' - setLastSaveError(errorMessage) - } finally { - setIsSaving(false) - } - }, - [templateId, adapter, revision] - ) - - // Автосохранение с дебаунсом - const scheduleAutoSave = useCallback(() => { - if (!enableAutoSave || isCalculating || isSaving || !templateId) { - return - } - - // Очищаем предыдущий таймер - if (saveTimeoutRef.current) { - clearTimeout(saveTimeoutRef.current) - } - - saveTimeoutRef.current = setTimeout(() => { - const currentData = getAllModifiedCells() - performSave(currentData) - }, autoSaveDelay) - }, [ - enableAutoSave, - isCalculating, - isSaving, - templateId, - autoSaveDelay, - getAllModifiedCells, - performSave, - ]) - - // Эффект для автосохранения при изменениях - useEffect(() => { - if ( - enableAutoSave && - revision > lastSavedRevision && - !isCalculating && - !isSaving - ) { - scheduleAutoSave() - } - }, [ - enableAutoSave, - revision, - lastSavedRevision, - isCalculating, - isSaving, - scheduleAutoSave, - ]) - - // Ручное сохранение - const manualSave = useCallback(() => { - // Отменяем автосохранение если оно запланировано - if (saveTimeoutRef.current) { - clearTimeout(saveTimeoutRef.current) - saveTimeoutRef.current = null - } - - const currentData = getAllModifiedCells() - - if (Object.keys(currentData).length === 0) { - return - } - - performSave(currentData) - }, [getAllModifiedCells, performSave]) - - // Загрузка данных - const loadData = useCallback(async () => { - if (!adapter.load) return {} - - setIsLoading(true) - try { - return await adapter.load() - } catch (error) { - setLastSaveError( - error instanceof Error ? error.message : 'Ошибка загрузки' - ) - return {} - } finally { - setIsLoading(false) - } - }, [adapter]) - - // Очистка данных - const clearData = useCallback(async () => { - if (!adapter.clear) return - - try { - await adapter.clear() - setLastSavedRevision(0) - } catch (error) { - setLastSaveError( - error instanceof Error ? error.message : 'Ошибка очистки' - ) - } - }, [adapter]) - - // Очистка таймаута при размонтировании - useEffect(() => { - return () => { - if (saveTimeoutRef.current) { - clearTimeout(saveTimeoutRef.current) - } - } - }, []) - - // Вычисляемые значения - const isDataChanged = revision > lastSavedRevision - const hasUnsavedChanges = isDataChanged && !isSaving - - return { - // Состояние - isSaving, - isLoading, - isDataChanged, - hasUnsavedChanges, - lastSaveError, - lastSavedRevision, - - // Методы - manualSave, - loadData, - clearData, - - // Утилиты - getCurrentData: getAllModifiedCells, - clearError: () => setLastSaveError(null), - } -} diff --git a/src/hook/useFormulaAutoSave.ts b/src/hook/useFormulaAutoSave.ts deleted file mode 100644 index e920bb3..0000000 --- a/src/hook/useFormulaAutoSave.ts +++ /dev/null @@ -1,313 +0,0 @@ -import { useCallback, useEffect, useRef, useState } from 'react' - -export interface SavedFormulaData { - templateId?: string - formulaData: Record> - timestamp: string - version: number -} - -export interface UseFormulaAutoSaveOptions { - templateId?: string - autoSaveDelay?: number // задержка автосохранения в мс - enableAutoSave?: boolean -} - -// Ключ для localStorage -const getStorageKey = (templateId: string) => { - // console.log('🔑 Получен templateId:', templateId) - return `formula_data_${templateId}` -} - -/** - * Хук для автосохранения формул электронных таблиц в localStorage - * - * Функции: - * - Автоматическое сохранение с дебаунсом при изменениях - * - Ручное сохранение по требованию - * - Отслеживание состояния сохранения - * - Сохранение в localStorage (заглушка для API) - */ -export const useFormulaAutoSave = ( - getAllModifiedCells: () => Record>, - isCalculating: boolean, - revision: number, - options: UseFormulaAutoSaveOptions = {} -) => { - const { templateId, autoSaveDelay = 2000, enableAutoSave = true } = options - - // Состояние - const [lastSavedRevision, setLastSavedRevision] = useState(0) - const [isSaving, setIsSaving] = useState(false) - const [lastSaveError, setLastSaveError] = useState(null) - const [savedData, setSavedData] = useState(null) - - // Refs - const saveTimeoutRef = useRef(null) - const versionCounter = useRef(1) - - // Загрузка данных из localStorage при инициализации - useEffect(() => { - if (!templateId) return - - try { - const storageKey = getStorageKey(templateId) - const savedDataStr = localStorage.getItem(storageKey) - - if (savedDataStr) { - const parsedData: SavedFormulaData = JSON.parse(savedDataStr) - setSavedData(parsedData) - versionCounter.current = parsedData.version + 1 - // console.log( - '📂 Загружены сохраненные формулы (версия:', - parsedData.version, - ')' - ) - } - } catch (error) { - console.warn('⚠️ Ошибка при загрузке данных из localStorage:', error) - } - }, [templateId]) - - // Основная функция сохранения в localStorage - const performSave = useCallback( - async (data: Record>) => { - if (Object.keys(data).length === 0) { - // console.log('📭 Нет данных для сохранения') - return - } - - if (!templateId) { - console.warn('⚠️ Не указан templateId для сохранения формул') - return - } - - setIsSaving(true) - setLastSaveError(null) - - try { - // Имитируем задержку API для реалистичности - await new Promise(resolve => - setTimeout(resolve, 200 + Math.random() * 300) - ) - - // Иногда имитируем ошибку (2% вероятность) - if (Math.random() < 0.02) { - throw new Error('Ошибка записи в хранилище') - } - - const savedData: SavedFormulaData = { - templateId, - formulaData: data, - timestamp: new Date().toISOString(), - version: versionCounter.current++, - } - - // Сохраняем в localStorage - const storageKey = getStorageKey(templateId) - localStorage.setItem(storageKey, JSON.stringify(savedData)) - - setSavedData(savedData) - setLastSavedRevision(revision) - - // console.log( - '💾 Сохранено формул:', - Object.values(data).reduce( - (sum, sheet) => sum + Object.keys(sheet).length, - 0 - ) - ) - } catch (error) { - const errorMessage = - error instanceof Error ? error.message : 'Неизвестная ошибка' - setLastSaveError(errorMessage) - console.error( - '❌ Ошибка при сохранении формул в localStorage:', - errorMessage - ) - - // Не обновляем lastSavedRevision при ошибке, чтобы попытаться снова - } finally { - setIsSaving(false) - } - }, - [templateId, revision] - ) - - // Автосохранение с дебаунсом - const scheduleAutoSave = useCallback(() => { - // console.log('⏰ scheduleAutoSave вызван, проверяем условия:', { - enableAutoSave, - isCalculating, - isSaving, - templateId, - }) - - if (!enableAutoSave || isCalculating || isSaving || !templateId) { - // console.log('❌ Автосохранение отменено по условиям') - return - } - - // Очищаем предыдущий таймер - if (saveTimeoutRef.current) { - clearTimeout(saveTimeoutRef.current) - // console.log('🔄 Очищен предыдущий таймер автосохранения') - } - - // console.log(`⏳ Запланировано автосохранение через ${autoSaveDelay}ms`) - saveTimeoutRef.current = setTimeout(() => { - // console.log('🎯 Выполняем отложенное автосохранение') - const currentData = getAllModifiedCells() - // console.log('📋 Данные для автосохранения:', currentData) - performSave(currentData) - }, autoSaveDelay) - }, [ - enableAutoSave, - isCalculating, - isSaving, - templateId, - autoSaveDelay, - getAllModifiedCells, - performSave, - ]) - - // Эффект для автосохранения при изменениях - useEffect(() => { - // console.log('🔍 Проверка условий автосохранения:', { - enableAutoSave, - revision, - lastSavedRevision, - isCalculating, - isSaving, - templateId, - shouldSave: - enableAutoSave && - revision > lastSavedRevision && - !isCalculating && - !isSaving, - }) - - if ( - enableAutoSave && - revision > lastSavedRevision && - !isCalculating && - !isSaving - ) { - // console.log('✅ Планируем автосохранение...') - scheduleAutoSave() - } else { - // console.log('⏸️ Автосохранение пропущено по условиям') - } - }, [ - enableAutoSave, - revision, - lastSavedRevision, - isCalculating, - isSaving, - scheduleAutoSave, - ]) - - // Ручное сохранение - const manualSave = useCallback(() => { - // console.log('🖱️ Ручное сохранение вызвано') - - // Отменяем автосохранение если оно запланировано - if (saveTimeoutRef.current) { - clearTimeout(saveTimeoutRef.current) - saveTimeoutRef.current = null - // console.log('⏹️ Отменено запланированное автосохранение') - } - - const currentData = getAllModifiedCells() - // console.log('📋 Данные для сохранения:', currentData) - - if (Object.keys(currentData).length === 0) { - // console.log('📭 Нет измененных данных для сохранения') - return - } - - performSave(currentData) - }, [getAllModifiedCells, performSave]) - - // Функция загрузки сохраненных формул из localStorage - const loadSavedFormulas = useCallback((): Record< - string, - Record - > | null => { - if (!templateId) return null - - try { - const storageKey = getStorageKey(templateId) - const savedDataStr = localStorage.getItem(storageKey) - - if (savedDataStr) { - const parsedData: SavedFormulaData = JSON.parse(savedDataStr) - - // console.log('📂 Формулы загружены из localStorage:', { - templateId, - version: parsedData.version, - timestamp: parsedData.timestamp, - }) - - return parsedData.formulaData - } - - return null - } catch (error) { - console.error( - '❌ Ошибка при загрузке сохраненных формул из localStorage:', - error - ) - return null - } - }, [templateId]) - - // Функция очистки сохраненных данных - const clearSavedFormulas = useCallback(() => { - if (!templateId) return - - try { - const storageKey = getStorageKey(templateId) - localStorage.removeItem(storageKey) - setSavedData(null) - setLastSavedRevision(0) - versionCounter.current = 1 - - // console.log('🗑️ Сохраненные формулы очищены:', { templateId }) - } catch (error) { - console.error('❌ Ошибка при очистке сохраненных формул:', error) - } - }, [templateId]) - - // Очистка таймаута при размонтировании - useEffect(() => { - return () => { - if (saveTimeoutRef.current) { - clearTimeout(saveTimeoutRef.current) - } - } - }, []) - - // Вычисляемые значения - const isDataChanged = revision > lastSavedRevision - const hasUnsavedChanges = isDataChanged && !isSaving - - return { - // Состояние - isSaving, - isDataChanged, - hasUnsavedChanges, - lastSaveError, - lastSavedRevision, - savedData, - - // Методы - manualSave, - loadSavedFormulas, - clearSavedFormulas, - - // Утилиты - getCurrentData: getAllModifiedCells, - clearError: () => setLastSaveError(null), - } -} diff --git a/src/hook/useFormulaAutoSaveNew.ts b/src/hook/useFormulaAutoSaveNew.ts deleted file mode 100644 index 74527f8..0000000 --- a/src/hook/useFormulaAutoSaveNew.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { createLocalStorageSaveAdapter } from './adapters/localStorageSaveAdapter' -import { useAutoSave } from './useAutoSave' - -export interface UseFormulaAutoSaveOptions { - templateId?: string - autoSaveDelay?: number - enableAutoSave?: boolean -} - -/** - * Хук для автосохранения формул в localStorage - * Теперь использует универсальный хук с localStorage адаптером - */ -export const useFormulaAutoSave = ( - getAllModifiedCells: () => Record>, - isCalculating: boolean, - revision: number, - options: UseFormulaAutoSaveOptions = {} -) => { - const { templateId, autoSaveDelay = 2000, enableAutoSave = true } = options - - if (!templateId) { - // Возвращаем пустую реализацию если нет templateId - return { - isSaving: false, - isDataChanged: false, - hasUnsavedChanges: false, - lastSaveError: null, - lastSavedRevision: 0, - savedData: null, - manualSave: () => {}, - loadSavedFormulas: () => null, - clearSavedFormulas: () => {}, - getCurrentData: getAllModifiedCells, - clearError: () => {}, - } - } - - const adapter = createLocalStorageSaveAdapter(templateId) - - const autoSaveResult = useAutoSave( - getAllModifiedCells, - isCalculating, - revision, - { - templateId, - autoSaveDelay, - enableAutoSave, - adapter, - } - ) - - return { - ...autoSaveResult, - savedData: null, // Для совместимости - loadSavedFormulas: async () => autoSaveResult.loadData(), - clearSavedFormulas: async () => autoSaveResult.clearData(), - } -} diff --git a/src/hook/useSheetAutoSave.ts b/src/hook/useSheetAutoSave.ts index 92814e3..8d5b0ce 100644 --- a/src/hook/useSheetAutoSave.ts +++ b/src/hook/useSheetAutoSave.ts @@ -20,6 +20,10 @@ export const useSheetAutoSave = ( options: UseSheetAutoSaveOptions = {} ) => { console.log('getAllModifiedCells', getAllModifiedCells()) + const memoizedGetAllModifiedCells = useCallback(getAllModifiedCells, [ + getAllModifiedCells, + ]) + const { templateId, autoSaveDelay = 2000, enableAutoSave = true } = options // Состояние @@ -171,7 +175,7 @@ export const useSheetAutoSave = ( if (shouldAutoSave) { console.log('✅ Выполняем автосохранение для ревизии:', debouncedRevision) - performSave(getAllModifiedCells()) + performSave(memoizedGetAllModifiedCells()) } }, [ enableAutoSave, @@ -180,15 +184,15 @@ export const useSheetAutoSave = ( isCalculating, isSaving, templateId, - getAllModifiedCells, + memoizedGetAllModifiedCells, performSave, ]) // Ручное сохранение const manualSave = useCallback(() => { - const currentData = getAllModifiedCells() + const currentData = memoizedGetAllModifiedCells() performSave(currentData) - }, [getAllModifiedCells, performSave]) + }, [memoizedGetAllModifiedCells, performSave]) // Функция загрузки сохраненных листов const loadSavedSheets = useCallback((): Record< @@ -226,7 +230,7 @@ export const useSheetAutoSave = ( loadSheets, // Утилиты - getCurrentData: getAllModifiedCells, + getCurrentData: memoizedGetAllModifiedCells, clearError: () => setLastSaveError(null), } } diff --git a/src/hook/useSheetAutoSaveNew.ts b/src/hook/useSheetAutoSaveNew.ts deleted file mode 100644 index ca5e7f7..0000000 --- a/src/hook/useSheetAutoSaveNew.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { createApiSaveAdapter } from './adapters/apiSaveAdapter' -import { useAutoSave } from './useAutoSave' - -export interface UseSheetAutoSaveOptions { - templateId?: string - autoSaveDelay?: number - enableAutoSave?: boolean -} - -/** - * Хук для автосохранения листов через API - * Теперь использует универсальный хук с API адаптером - */ -export const useSheetAutoSave = ( - getAllModifiedCells: () => Record>, - isCalculating: boolean, - revision: number, - options: UseSheetAutoSaveOptions = {} -) => { - const { templateId, autoSaveDelay = 2000, enableAutoSave = true } = options - - if (!templateId) { - // Возвращаем пустую реализацию если нет templateId - return { - isSaving: false, - isLoading: false, - isDataChanged: false, - hasUnsavedChanges: false, - lastSaveError: null, - lastSavedRevision: 0, - sheets: {}, - manualSave: () => {}, - loadSavedSheets: () => ({}), - loadSheets: async () => ({}), - getCurrentData: getAllModifiedCells, - clearError: () => {}, - } - } - - const adapter = createApiSaveAdapter(templateId) - - const autoSaveResult = useAutoSave( - getAllModifiedCells, - isCalculating, - revision, - { - templateId, - autoSaveDelay, - enableAutoSave, - adapter, - } - ) - - return { - ...autoSaveResult, - sheets: {}, // Для совместимости - loadSavedSheets: async () => autoSaveResult.loadData(), - loadSheets: async () => autoSaveResult.loadData(), - } -} diff --git a/src/page/ProtocolCreation/Page.tsx b/src/page/ProtocolCreation/Page.tsx index 6cbfae7..62b37ef 100644 --- a/src/page/ProtocolCreation/Page.tsx +++ b/src/page/ProtocolCreation/Page.tsx @@ -441,16 +441,6 @@ const ProtocolForm: FC = ({ template, onSave, onBack }) => { } onSave(data) - // console.log( - // '[DBG] template elements', - // template.elements.map(e => ({ - // id: e.id, - // label: e.label, - // target: e.targetCells, - // type: e.type, - // })) - // ) - try { if (!engineRef.current) { alert('Движок ещё не инициализирован')