form-4-add-row #54

Merged
PotapovaA merged 6 commits from form-4-add-row into test 2026-07-29 10:56:41 +03:00
4 changed files with 173 additions and 8 deletions
Showing only changes of commit d257c3f1c1 - Show all commits

View File

View File

@ -24,9 +24,11 @@ import {
import { useRealtime } from './contexts/RealtimeContext';
import { toast } from 'react-toastify';
import { CircularProgress } from '@mui/material';
import { additionVspRowTable } from './constants/addingRowConfig';
import { additionExpenseRowTable, additionVspRowTable } from './constants/addingRowConfig';
import { SelectVspModal } from './Modals/SelectVspModal';
import { SelectExpenseItemModal } from './Modals/SelectExpenseItemModal';
import { getRowId } from './utils/rowUtils';
import { FORM_TYPE_OPTIONS } from '../../constants/constants';
import { debounce } from '@mui/material';
const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
@ -40,6 +42,7 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
const [editingCell, setEditingCell] = useState(null);
const [isOpenModalSelectVsp, setIsOpenModalSelectVsp] = useState(false);
const [isOpenModalSelectExpenseItem, setIsOpenModalSelectExpenseItem] = useState(false);
const isVspAdditionRow = useMemo(() => {
if (!formType || !sheetName) return false;
@ -47,6 +50,12 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
return additionVspRowTable[formType].includes(sheetName);
}, [formType, sheetName]);
const isAdditionExpenseItem = useMemo(() => {
if (!formType || !sheetName) return false;
if (!additionExpenseRowTable[formType]) return false;
return additionExpenseRowTable[formType].includes(sheetName);
}, [formType, sheetName]);
const handleGlobalFilterChange = useCallback(
debounce((value) => {
startTransition(() => {
@ -66,6 +75,8 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
addRow: contextAddRow,
deleteRow: contextDeleteRow,
startEditing: contextStartEditing,
addProgram: contextAddProgram,
addProject: contextAddProject,
} = useRealtime();
const {
@ -113,6 +124,7 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
setColumnsConfig({ columns: [], colors: {} });
}
};
loadConfig();
}, [formType, sheetName]);
@ -363,11 +375,19 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
const handleAddVspRow = useCallback((vsp_id) => {
contextAddRow({ vsp_id: vsp_id });
}, [rowSelection, table]);
}, []);
const handleAddExpenseItemRow = useCallback((expense_item) => {
contextAddRow({ expense_item_id: expense_item.id });
}, []);
const handleOpenModalSelectVsp = useCallback(() => {
setIsOpenModalSelectVsp(true);
}, [rowSelection, table])
}, [])
const handleOpenModalSelectExpenseItem = useCallback(() => {
setIsOpenModalSelectExpenseItem(true);
}, [])
const handleDeleteRow = useCallback(() => {
const allRows = table.getRowModel().rows;
@ -383,6 +403,17 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
setRowSelection({});
}, [rowSelection, table])
const addRow = useCallback(() => {
if (isVspAdditionRow) {
return handleOpenModalSelectVsp();
}
if (isAdditionExpenseItem) {
return handleOpenModalSelectExpenseItem();
}
return handleAddRow();
}, [isVspAdditionRow, isAdditionExpenseItem, handleOpenModalSelectVsp, handleAddRow]);
useEffect(() => {
return () => {
setData([]);
@ -409,7 +440,7 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
onGlobalFilterChange={handleGlobalFilterChange}
sizeMult={sizeMult}
onChangeShowColumnFilters={setShowColumnFilters}
onAddRow={isVspAdditionRow ? handleOpenModalSelectVsp : handleAddRow}
onAddRow={addRow}
onDeleteRow={handleDeleteRow}
isLoadingData={isLoadingData}
formId={formId}
@ -479,6 +510,14 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
onSelect={handleAddVspRow}
title="Выбор ВСП"
/>
<SelectExpenseItemModal
isOpen={isOpenModalSelectExpenseItem}
onClose={() => setIsOpenModalSelectExpenseItem(false)}
formId={formId}
onSelect={handleAddExpenseItemRow}
title="Добавление строки"
sheet={sheetName}
/>
</>
);
};

View File

@ -88,19 +88,33 @@ export const RealtimeProvider = ({
}
break;
case "program_added":
console.log("Program added:", data);
if (data.result && onProgramAddRef.current) {
onProgramAddRef.current(data);
}
break;
case "project_added":
console.log("Project added:", data);
if (data.result && onProjectAddRef.current) {
onProjectAddRef.current(data);
}
break;
default:
console.log("Unknown event:", data.event);
}
}, []);
const { isConnectedRef, isConnected, sendMessage, disconnect, lastError } = useWebSocket(
wsUrl,
handleMessage,
);
const { isConnectedRef, isConnected, sendMessage, disconnect, lastError } =
useWebSocket(wsUrl, handleMessage);
const onCellUpdateRef = useRef(null);
const onRowAddRef = useRef(null);
const onRowDeleteRef = useRef(null);
const onProgramAddRef = useRef(null);
const onProjectAddRef = useRef(null);
const onErrorRef = useRef(null);
const onAuthSuccessRef = useRef(null);
const onCellEditStartRef = useRef(null);
@ -283,6 +297,42 @@ export const RealtimeProvider = ({
[isConnected, sendMessage, sheetName, formId, direction],
);
const addProject = useCallback(
async (rowData) => {
if (!isConnectedRef) {
onErrorRef.current?.("Нет подключения или авторизации");
return false;
}
const message = {
event: "row_added",
data: rowData,
};
addCommonField(message);
return sendMessage(message);
},
[isConnected, sendMessage, sheetName, formId, direction],
);
const addProgram = useCallback(
async (rowData) => {
if (!isConnectedRef) {
onErrorRef.current?.("Нет подключения или авторизации");
return false;
}
const message = {
event: "row_added",
data: rowData,
};
addCommonField(message);
return sendMessage(message);
},
[isConnected, sendMessage, sheetName, formId, direction],
);
const deleteRow = useCallback(
async (rowId) => {
if (!isConnectedRef) {
@ -322,6 +372,20 @@ export const RealtimeProvider = ({
};
}, []);
const subscribeToProgramAdds = useCallback((callback) => {
onProgramAddRef.current = callback;
return () => {
onProgramAddRef.current = null;
};
}, []);
const subscribeToProjectAdds = useCallback((callback) => {
onProjectAddRef.current = callback;
return () => {
onProjectAddRef.current = null;
};
}, []);
const subscribeToErrors = useCallback((callback) => {
onErrorRef.current = callback;
return () => {
@ -366,9 +430,13 @@ export const RealtimeProvider = ({
endEditing,
updateCell,
addRow,
addProgram,
addProject,
deleteRow,
subscribeToRowAdds,
subscribeToRowDeletes,
subscribeToProgramAdds,
subscribeToProjectAdds,
subscribeToErrors,
subscribeToAuthSuccess,
subscribeToCellEditStart,

View File

@ -19,6 +19,8 @@ const useRealtimeData = (formId, sheetName, direction, formType, year) => {
error: wsError,
subscribeToCellUpdates,
subscribeToRowAdds,
subscribeToProgramAdds,
subscribeToProjectAdds,
subscribeToRowDeletes,
subscribeToErrors,
subscribeToCellEditStart,
@ -206,6 +208,58 @@ const useRealtimeData = (formId, sheetName, direction, formType, year) => {
});
});
const unsubscribeProjectAdds = subscribeToProjectAdds((data) => {
const updates = data.result.data;
const expense_item_id = data.data.expense_item_id || null;
const newLineId = data.result.new_line_id;
const [updatedCells, newRow] = updates.reduce(
(res, row) => {
if (row[3]?.line_id === newLineId || isVspNewRow(row)) {
res[1] = row;
} else {
res[0].push(row);
}
return res;
},
[[], null],
);
if (newRow === null) {
toast.error("Ошибка получения данных");
return;
}
setData((prevData) => {
const updateData = updateCells(prevData, updatedCells);
const newData = insertCell(updateData, newRow, expense_item_id);
return newData;
});
});
const unsubscribeProgramAdds = subscribeToProgramAdds((data) => {
const updates = data.result.data;
const expense_item_id = data.data.expense_item_id || null;
const newLineId = data.result.new_line_id;
const [updatedCells, newRow] = updates.reduce(
(res, row) => {
if (row[3]?.line_id === newLineId || isVspNewRow(row)) {
res[1] = row;
} else {
res[0].push(row);
}
return res;
},
[[], null],
);
if (newRow === null) {
toast.error("Ошибка получения данных");
return;
}
setData((prevData) => {
const updateData = updateCells(prevData, updatedCells);
const newData = insertCell(updateData, newRow, expense_item_id);
return newData;
});
});
const unsubscribeRowDeletes = subscribeToRowDeletes((data) => {
const updatedCells = data.result;
const lineIdForDelete = data.data.row_id;
@ -255,6 +309,8 @@ const useRealtimeData = (formId, sheetName, direction, formType, year) => {
return () => {
unsubscribeCellUpdates();
unsubscribeRowAdds();
unsubscribeProgramAdds();
unsubscribeProjectAdds();
unsubscribeRowDeletes();
unsubscribeErrors();
unsubscribeCellEditStart();
@ -268,6 +324,8 @@ const useRealtimeData = (formId, sheetName, direction, formType, year) => {
subscribeToErrors,
subscribeToCellEditStart,
subscribeToCellEditEnd,
subscribeToProgramAdds,
subscribeToProjectAdds,
formatedToSubRows,
]);