/
diloytd
/
shield
Обзор
Документация
Войти
/
diloytd
/
shield
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/ui/scripts/app.js
311 строк
10 KB
diloytd
Разделить импорт заказа и ручное присвоение шильда.
15 июл 2026, 18:23
15 июл 2026, 18:23
860cf37
Код
Авторство
О чём код?
import { createInstancesTable, getDefaultInstanceSortState, updateInstanceRowInTable } from './table.js'; import { StatusBar, STATUS_MESSAGES } from './statusbar.js'; import { Toolbar } from './toolbar.js'; import { Workspace } from './workspace.js'; /** * Формирует сообщение об успешном формировании журнала. * @param {number} rowCount - Количество строк журнала. * @returns {string} Текст для строки состояния. */ const formatJournalSuccessMessage = (rowCount) => { return `Журнал сформирован. Строк: ${rowCount}`; }; /** * Формирует сообщение об успешном импорте заказа. * @param {string} orderNumber - Номер заказа. * @param {number} instancesCount - Количество экземпляров изделий. * @returns {string} Текст для строки состояния. */ const formatImportSuccessMessage = (orderNumber, instancesCount) => { return `Заказ ${orderNumber} импортирован. Экземпляров: ${instancesCount}`; }; /** * Инициализирует пользовательский интерфейс приложения. * @returns {void} */ const initApp = () => { const workspaceContainer = document.getElementById('workspace'); const statusText = document.getElementById('status-text'); if (!workspaceContainer || !statusText) { return; } const workspace = new Workspace(workspaceContainer); const statusBar = new StatusBar(statusText); let selectedInstanceId = null; let currentTableWrapper = null; let toolbar = null; let instanceSortState = getDefaultInstanceSortState(); statusBar.setMessage(STATUS_MESSAGES.ready); /** * Обновляет доступность кнопки присвоения шильда. * @returns {void} */ const updateAssignShieldButtonState = () => { if (!toolbar) { return; } if (!Number.isInteger(selectedInstanceId) || selectedInstanceId <= 0) { toolbar.setAssignShieldEnabled(false); return; } const selectedRow = currentTableWrapper?.querySelector( `[data-instance-id="${selectedInstanceId}"]`, ); const hasShield = selectedRow instanceof HTMLElement && selectedRow.dataset.hasShield === 'true'; toolbar.setAssignShieldEnabled(!hasShield); }; /** * Обрабатывает выбор экземпляра изделия в таблице. * @param {number|null} instanceId - Идентификатор выбранного экземпляра. * @returns {void} */ const handleInstanceSelect = (instanceId) => { selectedInstanceId = instanceId; updateAssignShieldButtonState(); }; /** * Обрабатывает удаление экземпляра изделия из таблицы. * @param {number} instanceId - Идентификатор удаляемого экземпляра. * @returns {Promise<void>} */ const handleInstanceDelete = async (instanceId) => { if (!Number.isInteger(instanceId) || instanceId <= 0) { return; } if (!window.electronAPI?.deleteInstance) { statusBar.setMessage('Удаление недоступно.'); return; } statusBar.setMessage('Удаление строки...'); const result = await window.electronAPI.deleteInstance(instanceId); if (!result?.success) { statusBar.setMessage(result?.error || 'Ошибка при удалении строки.'); return; } if (selectedInstanceId === instanceId) { selectedInstanceId = null; updateAssignShieldButtonState(); } const { loaded, rowCount } = await showInstances(); if (!loaded) { return; } statusBar.setMessage(rowCount === 0 ? 'Экземпляры изделий отсутствуют' : `Строка удалена. Осталось: ${rowCount}`); }; /** * Запрашивает экземпляры изделий из SQLite и отображает их в рабочей области. * @param {number|null} [preferredInstanceId=null] - Экземпляр, который нужно выделить после обновления. * @returns {Promise<{ loaded: boolean, rowCount: number }>} Результат загрузки таблицы. */ const showInstances = async (preferredInstanceId = null) => { if (!window.electronAPI?.getInstances) { statusBar.setMessage('Просмотр экземпляров недоступен.'); return { loaded: false, rowCount: 0 }; } const result = await window.electronAPI.getInstances(); if (!result?.success) { statusBar.setMessage(result?.error || 'Ошибка при получении экземпляров.'); return { loaded: false, rowCount: 0 }; } selectedInstanceId = null; updateAssignShieldButtonState(); const tableElement = createInstancesTable(result.rows, handleInstanceSelect, handleInstanceDelete, { sortState: instanceSortState, onSortChange: (nextSortState) => { instanceSortState = nextSortState; }, }); currentTableWrapper = tableElement; workspace.showTable(tableElement); if (preferredInstanceId) { const preferredRow = tableElement.querySelector( `[data-instance-id="${preferredInstanceId}"][data-has-shield="false"]`, ); if (preferredRow instanceof HTMLTableRowElement) { preferredRow.click(); } } return { loaded: true, rowCount: result.rowCount ?? 0, }; }; /** * Отображает журнал в формате рабочей таблицы (Заказ + Шильд). * @returns {Promise<void>} */ const showJournal = async () => { const { loaded, rowCount } = await showInstances(); if (!loaded) { return; } if (rowCount === 0) { statusBar.setMessage('Журнал пуст.'); return; } statusBar.setMessage(formatJournalSuccessMessage(rowCount)); }; void showInstances(); /** * Импортирует JSON-файл в базу и обновляет таблицу. * @param {string} filePath - Абсолютный путь к JSON-файлу. * @returns {Promise<boolean>} true, если импорт выполнен успешно. */ const importJsonFile = async (filePath) => { if (!window.electronAPI?.importJson) { statusBar.setMessage('Импорт недоступен.'); return false; } statusBar.setMessage('Загрузка данных...'); const result = await window.electronAPI.importJson(filePath); if (!result?.success) { const errorMessage = result?.error || 'Ошибка при импорте данных.'; if (result?.code === 'DUPLICATE_ORDER' && window.electronAPI?.showWarning) { await window.electronAPI.showWarning(errorMessage); } statusBar.setMessage(errorMessage); return false; } const { loaded: instancesLoaded } = await showInstances(); if (!instancesLoaded) { return false; } statusBar.setMessage( formatImportSuccessMessage(result.orderNumber, result.stats?.instances ?? 0), ); return true; }; toolbar = new Toolbar({ selectJsonButton: document.getElementById('btn-select-json'), journalButton: document.getElementById('btn-journal'), assignShieldButton: document.getElementById('btn-assign-shield'), exportButton: document.getElementById('btn-export'), onSelectJson: async () => { if (!window.electronAPI?.selectJsonFile) { statusBar.setMessage('Загрузка JSON недоступна.'); return; } statusBar.setMessage(STATUS_MESSAGES.waiting); const selectedPath = await window.electronAPI.selectJsonFile(); if (!selectedPath) { statusBar.setMessage(STATUS_MESSAGES.ready); return; } await importJsonFile(selectedPath); }, onShowJournal: async () => { await showJournal(); }, onAssignShield: async () => { if (!Number.isInteger(selectedInstanceId) || selectedInstanceId <= 0) { statusBar.setMessage('Выберите экземпляр изделия в таблице.'); return; } const selectedRow = currentTableWrapper?.querySelector( `[data-instance-id="${selectedInstanceId}"]`, ); const hasShield = selectedRow instanceof HTMLElement && selectedRow.dataset.hasShield === 'true'; if (hasShield) { statusBar.setMessage('Шильд уже присвоен выбранному экземпляру.'); return; } if (!window.electronAPI?.assignShield) { statusBar.setMessage('Присвоение шильда недоступно.'); return; } statusBar.setMessage('Присвоение шильда...'); const assignedInstanceId = selectedInstanceId; const result = await window.electronAPI.assignShield(assignedInstanceId); if (!result?.success) { statusBar.setMessage(result?.error || 'Ошибка при присвоении шильда.'); return; } if (!window.electronAPI?.getInstances) { statusBar.setMessage('Не удалось обновить строку таблицы.'); return; } const instancesResult = await window.electronAPI.getInstances(); if (!instancesResult?.success) { statusBar.setMessage(instancesResult?.error || 'Не удалось обновить строку таблицы.'); return; } const updatedRow = instancesResult.rows.find( (row) => row.instanceId === assignedInstanceId, ); if (!updatedRow || !currentTableWrapper) { statusBar.setMessage('Не удалось обновить строку таблицы.'); return; } updateInstanceRowInTable(currentTableWrapper, updatedRow); selectedInstanceId = null; updateAssignShieldButtonState(); statusBar.setMessage(`Шильд присвоен. Создано записей: ${result.shieldsCount ?? 0}`); }, }); }; document.addEventListener('DOMContentLoaded', initApp);