Compare commits
No commits in common. "761a435b989f7a4de46a47ddd5130abf8bbf4272" and "cc766238f24c5bafe04b018855df93cf79d82fac" have entirely different histories.
761a435b98
...
cc766238f2
@ -1,4 +1,4 @@
|
|||||||
import api from "./client";
|
import api from './client';
|
||||||
|
|
||||||
export const FormsSheetApi = {
|
export const FormsSheetApi = {
|
||||||
get(formId, sheetName, params) {
|
get(formId, sheetName, params) {
|
||||||
@ -9,10 +9,7 @@ export const FormsSheetApi = {
|
|||||||
export(formId, sheetName, params = {}) {
|
export(formId, sheetName, params = {}) {
|
||||||
return api.get(`export/form/${formId}/sheet/${sheetName}`, {
|
return api.get(`export/form/${formId}/sheet/${sheetName}`, {
|
||||||
params,
|
params,
|
||||||
responseType: "blob",
|
responseType: 'blob',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getExpenseItem(itemId) {
|
|
||||||
return api.get(`/expense-item/${itemId}`).then((r) => r.data);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,10 +5,13 @@ export const StagesApi = {
|
|||||||
return api.post(`/stages/form/${formId}`, payload).then((r) => r.data);
|
return api.post(`/stages/form/${formId}`, payload).then((r) => r.data);
|
||||||
},
|
},
|
||||||
updateStage(payload) {
|
updateStage(payload) {
|
||||||
const { budget_form_id, sheet, phase_code } = payload;
|
const { budget_form_id, sheet, phase_code, opens_at, closes_at } = payload;
|
||||||
|
|
||||||
return api
|
return api
|
||||||
.patch(`/stages/form/${budget_form_id}/${sheet}/${phase_code}`, payload)
|
.patch(`/stages/form/${budget_form_id}/${sheet}/${phase_code}`, {
|
||||||
|
opens_at,
|
||||||
|
closes_at,
|
||||||
|
})
|
||||||
.then((r) => r.data);
|
.then((r) => r.data);
|
||||||
},
|
},
|
||||||
deleteStage(formId, sheet, phaseCode) {
|
deleteStage(formId, sheet, phaseCode) {
|
||||||
|
|||||||
@ -151,7 +151,7 @@ const RealtimeTable = ({ formType, formId, sheetName, direction }) => {
|
|||||||
if (isPinned) {
|
if (isPinned) {
|
||||||
const colId = table.getState().columnPinning.left[index];
|
const colId = table.getState().columnPinning.left[index];
|
||||||
const column = table.getColumn(colId);
|
const column = table.getColumn(colId);
|
||||||
return column?.getSize() ?? 150;
|
return column.columnDef.size;
|
||||||
}
|
}
|
||||||
const allCols = [...table.getLeftVisibleLeafColumns(), ...table.getCenterVisibleLeafColumns()]
|
const allCols = [...table.getLeftVisibleLeafColumns(), ...table.getCenterVisibleLeafColumns()]
|
||||||
return allCols[index]?.getSize() ?? 150;
|
return allCols[index]?.getSize() ?? 150;
|
||||||
@ -243,6 +243,7 @@ const RealtimeTable = ({ formType, formId, sheetName, direction }) => {
|
|||||||
toast.error('Ошибка редактирования ячейки');
|
toast.error('Ошибка редактирования ячейки');
|
||||||
}
|
}
|
||||||
}, [dataEditingCells, editingCell]);
|
}, [dataEditingCells, editingCell]);
|
||||||
|
console.log(editingCell)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (table && data && columns.length !== 0) {
|
if (table && data && columns.length !== 0) {
|
||||||
|
|||||||
@ -55,9 +55,17 @@ export const AddStagesModal = ({
|
|||||||
try {
|
try {
|
||||||
const { config } = await import(`../RealtimeTable/constants/${formType}/${sheetObj.sheet}.js`);
|
const { config } = await import(`../RealtimeTable/constants/${formType}/${sheetObj.sheet}.js`);
|
||||||
setColumnsConfig(config.config);
|
setColumnsConfig(config.config);
|
||||||
|
|
||||||
|
// Если есть сохраненные выбранные колонки для этого листа
|
||||||
|
if (stage?.column_keys) {
|
||||||
|
setSelectedColumns(stage.column_keys);
|
||||||
|
} else {
|
||||||
|
setSelectedColumns([]);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to load config for ${formType}/${selectedSheet}:`, error);
|
console.error(`Failed to load config for ${formType}/${selectedSheet}:`, error);
|
||||||
setColumnsConfig({ columns: [], colors: {} });
|
setColumnsConfig({ columns: [], colors: {} });
|
||||||
|
setSelectedColumns([]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,7 +79,10 @@ export const AddStagesModal = ({
|
|||||||
setStageName(stage.phase_code ?? '');
|
setStageName(stage.phase_code ?? '');
|
||||||
setSelectedSheet(stage.sheet ?? null);
|
setSelectedSheet(stage.sheet ?? null);
|
||||||
setSelectedRole(stage.role ?? null);
|
setSelectedRole(stage.role ?? null);
|
||||||
setSelectedColumns(stage.column_keys.map(c => 'data.' + c));
|
|
||||||
|
if (stage.column_keys) {
|
||||||
|
setSelectedColumns(stage.column_keys.map(c => 'data.' + c));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setStartDate(null);
|
setStartDate(null);
|
||||||
setEndDate(null);
|
setEndDate(null);
|
||||||
@ -190,7 +201,6 @@ export const AddStagesModal = ({
|
|||||||
placeholder="Введите название этапа"
|
placeholder="Введите название этапа"
|
||||||
fullWidth
|
fullWidth
|
||||||
size="small"
|
size="small"
|
||||||
disabled={stage !== null}
|
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import { formatDate } from '../../utils/formatDate';
|
|||||||
import { IconWithContent } from './IconWithContent';
|
import { IconWithContent } from './IconWithContent';
|
||||||
import { Chip } from '../styles/StyledChip';
|
import { Chip } from '../styles/StyledChip';
|
||||||
import { ExportButton } from '../common/Buttons/ButtonsActions';
|
import { ExportButton } from '../common/Buttons/ButtonsActions';
|
||||||
import { FORM_TYPE_TRANSLATE } from '../../constants';
|
import { FROM_TYPE_TRANSLATE } from '../../constants';
|
||||||
|
|
||||||
const TaskCard = styled.div`
|
const TaskCard = styled.div`
|
||||||
width: 26.8rem;
|
width: 26.8rem;
|
||||||
@ -100,7 +100,7 @@ export const TaskCardComponent = ({
|
|||||||
|
|
||||||
const [isEditModalOpen, setEditModalOpen] = useState(false);
|
const [isEditModalOpen, setEditModalOpen] = useState(false);
|
||||||
const [editedTitle, setEditedTitle] = useState('');
|
const [editedTitle, setEditedTitle] = useState('');
|
||||||
const [currentTitle, setCurrentTitle] = useState(FORM_TYPE_TRANSLATE[form_type_code] ||'');
|
const [currentTitle, setCurrentTitle] = useState(FROM_TYPE_TRANSLATE[form_type_code] ||'');
|
||||||
const [isChecked, setIsChecked] = useState(false);
|
const [isChecked, setIsChecked] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -36,7 +36,7 @@ export const EDIT_ACCESS_RUSSIAN = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const FORM_TYPE_OPTIONS = ['FORM_1', 'FORM_2', 'FORM_3', 'FORM_4'];
|
export const FORM_TYPE_OPTIONS = ['FORM_1', 'FORM_2', 'FORM_3', 'FORM_4'];
|
||||||
export const FORM_TYPE_TRANSLATE = { 'FORM_1': 'Смета ССП', 'FORM_2': 'Смета РФ', 'FORM_3': 'Программа развитие ПРРС', 'FORM_4': 'Проектная деятельность' };
|
export const FROM_TYPE_TRANSLATE = { 'FORM_1': 'Смета ССП', 'FORM_2': 'Смета РФ', 'FORM_3': 'Программа развитие ПРРС', 'FORM_4': 'Проектная деятельность' };
|
||||||
export const DIRECTION_TRANSLATE = { 'Support': 'Поддержка', 'Development': 'Развитие' };
|
export const DIRECTION_TRANSLATE = { 'Support': 'Поддержка', 'Development': 'Развитие' };
|
||||||
|
|
||||||
export const ORG_UNIT_TYPE_OPTIONS = [
|
export const ORG_UNIT_TYPE_OPTIONS = [
|
||||||
|
|||||||
@ -70,7 +70,7 @@ const AuditLogsPage = () => {
|
|||||||
limit: rowsPerPage,
|
limit: rowsPerPage,
|
||||||
user_id: selectedUser?.id,
|
user_id: selectedUser?.id,
|
||||||
org_unit_id: selectedSsp?.id,
|
org_unit_id: selectedSsp?.id,
|
||||||
event: selectedEventType?.id,
|
event_type: selectedEventType?.id,
|
||||||
date_from: dateFrom ? dateFrom.toISOString() : undefined,
|
date_from: dateFrom ? dateFrom.toISOString() : undefined,
|
||||||
date_to: dateTo ? dateTo.toISOString() : undefined,
|
date_to: dateTo ? dateTo.toISOString() : undefined,
|
||||||
task_id: taskId ? taskId : undefined,
|
task_id: taskId ? taskId : undefined,
|
||||||
@ -137,9 +137,7 @@ const AuditLogsPage = () => {
|
|||||||
return (
|
return (
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<HeaderSwitch />
|
<HeaderSwitch />
|
||||||
<Box sx={{
|
<Box display="flex" justifyContent="space-between">
|
||||||
display: "flex", justifyContent: "space-between"
|
|
||||||
}} >
|
|
||||||
<SwitchUserSsp />
|
<SwitchUserSsp />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|||||||
@ -177,6 +177,32 @@ const AuditLogsFilters = ({
|
|||||||
spacing={'1rem'}
|
spacing={'1rem'}
|
||||||
sx={{ width: '100%', alignItems: 'end' }}
|
sx={{ width: '100%', alignItems: 'end' }}
|
||||||
>
|
>
|
||||||
|
<FilterFieldWrapper>
|
||||||
|
<FormLabelStyled>Поиск по контексту (ID задачи)</FormLabelStyled>
|
||||||
|
<SearchComponent
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
height={'2.56rem'}
|
||||||
|
placeholder="Например: #1234"
|
||||||
|
debounceMs={400}
|
||||||
|
onChange={onTaskIdChange}
|
||||||
|
value={taskId}
|
||||||
|
/>
|
||||||
|
</FilterFieldWrapper>
|
||||||
|
<FilterFieldWrapper>
|
||||||
|
<FormLabelStyled>Поиск по контексту (ID формы)</FormLabelStyled>
|
||||||
|
<SearchComponent
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
height={'2.56rem'}
|
||||||
|
placeholder="Например: #1234"
|
||||||
|
debounceMs={400}
|
||||||
|
onChange={onFormIdChange}
|
||||||
|
value={formId}
|
||||||
|
/>
|
||||||
|
</FilterFieldWrapper>
|
||||||
|
|
||||||
<DefaultOutlinedButton
|
<DefaultOutlinedButton
|
||||||
onClick={onResetFilters}
|
onClick={onResetFilters}
|
||||||
|
|||||||
@ -77,9 +77,9 @@ const AuditLogsTable = ({
|
|||||||
<Typography component="div" fontWeight="medium">
|
<Typography component="div" fontWeight="medium">
|
||||||
{row.original.user
|
{row.original.user
|
||||||
? row.original.user.full_name +
|
? row.original.user.full_name +
|
||||||
' (' +
|
' (' +
|
||||||
row.original.user.email +
|
row.original.user.email +
|
||||||
')'
|
')'
|
||||||
: '-'}
|
: '-'}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
@ -118,7 +118,8 @@ const AuditLogsTable = ({
|
|||||||
size: 250,
|
size: 250,
|
||||||
Cell: ({ row }) => (
|
Cell: ({ row }) => (
|
||||||
<Typography>
|
<Typography>
|
||||||
{getRussianNamesForType(row.original.action) }
|
{getRussianNamesForType(row.original.action) ||
|
||||||
|
row.original.event_type}
|
||||||
</Typography>
|
</Typography>
|
||||||
),
|
),
|
||||||
enableColumnActions: false,
|
enableColumnActions: false,
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
CircularProgress,
|
CircularProgress,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { EVENT_CONFIGS, EVENT_CONFIGS_MULT_DEPENDENTS } from '../constants/configEvent';
|
import { EVENT_CONFIGS } from '../constants/configEvent';
|
||||||
import { VALUE_TRANSFORMERS } from '../utils/transformers';
|
import { VALUE_TRANSFORMERS } from '../utils/transformers';
|
||||||
|
|
||||||
const JsonViewModal = ({ open, onClose, jsonData, eventType }) => {
|
const JsonViewModal = ({ open, onClose, jsonData, eventType }) => {
|
||||||
@ -36,7 +36,6 @@ const JsonViewModal = ({ open, onClose, jsonData, eventType }) => {
|
|||||||
async function extractInfo(data, type) {
|
async function extractInfo(data, type) {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
const config = EVENT_CONFIGS[type] || {};
|
const config = EVENT_CONFIGS[type] || {};
|
||||||
const configForMultDependents = EVENT_CONFIGS_MULT_DEPENDENTS[type] || {};
|
|
||||||
const result = {};
|
const result = {};
|
||||||
|
|
||||||
// Функция для рекурсивного обхода всех узлов
|
// Функция для рекурсивного обхода всех узлов
|
||||||
@ -47,33 +46,16 @@ const JsonViewModal = ({ open, onClose, jsonData, eventType }) => {
|
|||||||
const currentPath = path ? `${path}.${key}` : key;
|
const currentPath = path ? `${path}.${key}` : key;
|
||||||
|
|
||||||
if (config[currentPath] || config[key]) {
|
if (config[currentPath] || config[key]) {
|
||||||
let value = obj[key];
|
|
||||||
const configKey = config[currentPath] || config[key];
|
const configKey = config[currentPath] || config[key];
|
||||||
|
let value = obj[key];
|
||||||
|
|
||||||
// Применяем преобразование, если есть функция для этого ключа
|
// Применяем преобразование, если есть функция для этого ключа
|
||||||
if (VALUE_TRANSFORMERS[configKey] && value) {
|
if (VALUE_TRANSFORMERS[configKey] && value) {
|
||||||
try {
|
const transformer = VALUE_TRANSFORMERS[configKey];
|
||||||
// Собираем зависимости для трансформера
|
if (transformer.constructor.name === 'AsyncFunction') {
|
||||||
// По умолчанию передаём только текущее значение
|
value = await transformer(value);
|
||||||
const dependents = [value];
|
} else {
|
||||||
|
value = transformer(value);
|
||||||
// Если для этого ключа есть дополнительные зависимости (другие поля)
|
|
||||||
if (configForMultDependents[configKey] || configForMultDependents[configKey]) {
|
|
||||||
configForMultDependents[configKey].forEach(d => {
|
|
||||||
// Добавляем значения из зависимых полей (в корне data)
|
|
||||||
dependents.push(data[d]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const transformer = VALUE_TRANSFORMERS[configKey];
|
|
||||||
if (transformer.constructor.name === 'AsyncFunction') {
|
|
||||||
value = await transformer(...dependents);
|
|
||||||
} else {
|
|
||||||
value = transformer(...dependents);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Ошибка в трансформере для ключа "${configKey}":`, error);
|
|
||||||
value = '—';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,11 +69,8 @@ const JsonViewModal = ({ open, onClose, jsonData, eventType }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
// Начинаем обход с основного объекта
|
||||||
await traverseAndExtract(data);
|
await traverseAndExtract(data);
|
||||||
} catch (error) {
|
|
||||||
return JSON.stringify({ error: 'Ошибка при извлечении данных' }, null, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSON.stringify(result, null, 2);
|
return JSON.stringify(result, null, 2);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,21 @@
|
|||||||
export const DEFAULT_ACTIONS = {
|
export const DEFAULT_ACTIONS = {
|
||||||
ROW_CREATE: 'Создание строки',
|
ROW_CREATE: 'Создание строки',
|
||||||
ROW_DELETE: 'Удаление строки',
|
ROW_DELETE: 'Удаление строки',
|
||||||
ACCESS_EXTEND: 'Продление этапа',
|
ACCESS_WINDOW_CHANGE: 'Изменение окна доступа',
|
||||||
ACCESS_WINDOW_CHANGE: 'Изменение этапа',
|
ACCESS_EXTEND: 'Расширение доступа',
|
||||||
USER_ROLE_CHANGE: 'Изменение роли пользователя',
|
USER_ROLE_CHANGE: 'Изменение роли пользователя',
|
||||||
CREATE_TASK: 'Создание задачи',
|
CREATE_TASK: 'Создание задачи',
|
||||||
// UPDATE_TASK: 'Обновление задачи', //сейчас нет события
|
UPDATE_TASK: 'Обновление задачи',
|
||||||
// DELETE_TASK: 'Удаление задачи',
|
DELETE_TASK: 'Удаление задачи',
|
||||||
USER_CREATE: 'Создание пользователя',
|
USER_CREATE: 'Создание пользователя',
|
||||||
|
LOGIN: 'Вход в систему',
|
||||||
USER_ACCESS_GRANTED: 'Предоставление доступа к ССП/РФ',
|
USER_ACCESS_GRANTED: 'Предоставление доступа к ССП/РФ',
|
||||||
USER_ACCESS_REVOKED: 'Отмена доступа к ССП/РФ',
|
USER_ACCESS_REVOKED: 'Отмена доступа к ССП/РФ',
|
||||||
VSP_CREATE: 'Создание ВСП',
|
VSP_CREATE: 'Создание ВСП',
|
||||||
VSP_UPDATE: 'Обновление ВСП',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ENTITY_RUSSIAN_NAMES = {
|
export const ENTITY_RUSSIAN_NAMES = {
|
||||||
|
LOGIN: 'Вход в систему',
|
||||||
ROW: 'строки',
|
ROW: 'строки',
|
||||||
PROJECT: 'проекта',
|
PROJECT: 'проекта',
|
||||||
TABLE: 'таблицы',
|
TABLE: 'таблицы',
|
||||||
@ -24,8 +25,7 @@ export const ENTITY_RUSSIAN_NAMES = {
|
|||||||
TASK: 'задачи',
|
TASK: 'задачи',
|
||||||
USER_ACCESS: 'доступа к ССП/РФ',
|
USER_ACCESS: 'доступа к ССП/РФ',
|
||||||
USER: 'пользователя',
|
USER: 'пользователя',
|
||||||
ACCESS_WINDOW: 'этапа',
|
ACCESS_WINDOW: 'окна доступа',
|
||||||
ACCESS: 'этапа',
|
|
||||||
USER_ROLE: 'роли пользователя',
|
USER_ROLE: 'роли пользователя',
|
||||||
VSP: 'ВСП',
|
VSP: 'ВСП',
|
||||||
};
|
};
|
||||||
@ -38,7 +38,6 @@ export const ACTION_RUSSIAN_NAMES = {
|
|||||||
GET: 'Получение',
|
GET: 'Получение',
|
||||||
GRANTED: 'Предоставление',
|
GRANTED: 'Предоставление',
|
||||||
REVOKED: 'Отмена',
|
REVOKED: 'Отмена',
|
||||||
EXTEND: 'Продление',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getRussianNamesForType = (name) => {
|
export const getRussianNamesForType = (name) => {
|
||||||
|
|||||||
@ -6,11 +6,12 @@ export const EVENT_CONFIGS = {
|
|||||||
entity_id: 'Пользователь',
|
entity_id: 'Пользователь',
|
||||||
},
|
},
|
||||||
VSP_CREATE: {
|
VSP_CREATE: {
|
||||||
|
ssp_id: 'Региональный филиал',
|
||||||
reg_number: 'Регистрационный номер ВСП',
|
reg_number: 'Регистрационный номер ВСП',
|
||||||
vsp_type: 'Вид ВСП',
|
vsp_type: 'Вид ВСП',
|
||||||
address: 'Адрес ВСП',
|
address: 'Адрес ВСП',
|
||||||
format: 'Утвержденный формат',
|
approved_format: 'Утвержденный формат',
|
||||||
opened_at: 'Дата открытия ВСП',
|
open_date: 'Дата открытия ВСП',
|
||||||
notes: 'Примечания',
|
notes: 'Примечания',
|
||||||
location_form: 'Форма расположения ВСП',
|
location_form: 'Форма расположения ВСП',
|
||||||
numbers: 'Штатная численность ВСП',
|
numbers: 'Штатная численность ВСП',
|
||||||
@ -21,16 +22,14 @@ export const EVENT_CONFIGS = {
|
|||||||
branch_name: 'Региональный филиал ',
|
branch_name: 'Региональный филиал ',
|
||||||
closed_at: 'Дата закрытия ВСП',
|
closed_at: 'Дата закрытия ВСП',
|
||||||
user_email: 'Почта пользователя',
|
user_email: 'Почта пользователя',
|
||||||
staff_count: 'Кол-во работников',
|
|
||||||
placement_type: 'Тип размещение',
|
|
||||||
is_active: 'Активный',
|
|
||||||
},
|
},
|
||||||
VSP_UPDATE: {
|
VSP_UPDATE: {
|
||||||
|
ssp_id: 'Региональный филиал',
|
||||||
reg_number: 'Регистрационный номер ВСП',
|
reg_number: 'Регистрационный номер ВСП',
|
||||||
vsp_type: 'Вид ВСП',
|
vsp_type: 'Вид ВСП',
|
||||||
address: 'Адрес ВСП',
|
address: 'Адрес ВСП',
|
||||||
format: 'Утвержденный формат',
|
approved_format: 'Утвержденный формат',
|
||||||
opened_at: 'Дата открытия ВСП',
|
open_date: 'Дата открытия ВСП',
|
||||||
notes: 'Примечания',
|
notes: 'Примечания',
|
||||||
location_form: 'Форма расположения ВСП',
|
location_form: 'Форма расположения ВСП',
|
||||||
numbers: 'Штатная численность ВСП',
|
numbers: 'Штатная численность ВСП',
|
||||||
@ -38,12 +37,9 @@ export const EVENT_CONFIGS = {
|
|||||||
rent_contract_num: 'Номер договора аренды',
|
rent_contract_num: 'Номер договора аренды',
|
||||||
rent_end_date: 'Срок окончания договора аренды',
|
rent_end_date: 'Срок окончания договора аренды',
|
||||||
system_code: 'Код РФ',
|
system_code: 'Код РФ',
|
||||||
'changes.branch_name': 'Региональный филиал ',
|
branch_name: 'Региональный филиал ',
|
||||||
closed_at: 'Дата закрытия ВСП',
|
closed_at: 'Дата закрытия ВСП',
|
||||||
user_email: 'Почта пользователя',
|
user_email: 'Почта пользователя',
|
||||||
staff_count: 'Кол-во работников',
|
|
||||||
placement_type: 'Тип размещение',
|
|
||||||
is_active: 'Активный',
|
|
||||||
},
|
},
|
||||||
USER_ACCESS_GRANTED: {
|
USER_ACCESS_GRANTED: {
|
||||||
entity_id: 'Пользователь',
|
entity_id: 'Пользователь',
|
||||||
@ -60,15 +56,11 @@ export const EVENT_CONFIGS = {
|
|||||||
},
|
},
|
||||||
ROW_CREATE: {
|
ROW_CREATE: {
|
||||||
sheet: "Лист",
|
sheet: "Лист",
|
||||||
expense_item_id: 'Статья расходов',
|
expense_item_id: 'Статья расходов'
|
||||||
form_id: 'Информация о задаче',
|
|
||||||
direction: 'Направление',
|
|
||||||
},
|
},
|
||||||
ROW_DELETE: {
|
ROW_DELETE: {
|
||||||
sheet: "Лист",
|
sheet: "Лист",
|
||||||
expense_item_id: 'Статья расходов',
|
expense_item_id: 'Статья расходов'
|
||||||
form_id: 'Информация о задаче',
|
|
||||||
direction: 'Направление',
|
|
||||||
},
|
},
|
||||||
PROJECT_CREATE: {
|
PROJECT_CREATE: {
|
||||||
"name": "Название",
|
"name": "Название",
|
||||||
@ -79,27 +71,5 @@ export const EVENT_CONFIGS = {
|
|||||||
"name": "Название",
|
"name": "Название",
|
||||||
"year": "Год",
|
"year": "Год",
|
||||||
"org_unit_id": "СПП/РФ",
|
"org_unit_id": "СПП/РФ",
|
||||||
},
|
}
|
||||||
ACCESS_EXTEND: {
|
|
||||||
form_id: 'Информация о задаче',
|
|
||||||
closes_at_after: 'Дата закрытия',
|
|
||||||
closes_at_before: 'Дата открытия',
|
|
||||||
phase_name: 'Названия этапа',
|
|
||||||
sheet: "Лист",
|
|
||||||
},
|
|
||||||
ACCESS_WINDOW_CHANGE: {
|
|
||||||
form_id: 'Информация о задаче',
|
|
||||||
closes_at: 'Дата закрытия',
|
|
||||||
open_at: 'Дата открытия',
|
|
||||||
phase_name: 'Названия этапа',
|
|
||||||
role: 'Для роли',
|
|
||||||
column_keys: 'Колонки в этапе',
|
|
||||||
action: 'Действие',
|
|
||||||
sheet: "Лист",
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
export const EVENT_CONFIGS_MULT_DEPENDENTS = {
|
|
||||||
ACCESS_WINDOW_CHANGE: {
|
|
||||||
'Колонки в этапе': ['form_id', 'sheet']
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@ -1,10 +1,8 @@
|
|||||||
import { DictVspApi } from '../../../../api/dict-vsp';
|
import { DictVspApi } from '../../../../api/dict-vsp';
|
||||||
import { FormsSheetApi } from '../../../../api/form_sheet';
|
|
||||||
import { FormsApi } from '../../../../api/forms';
|
|
||||||
import { SspApi } from '../../../../api/ssp';
|
import { SspApi } from '../../../../api/ssp';
|
||||||
import { TasksApi } from '../../../../api/tasks';
|
import { TasksApi } from '../../../../api/tasks';
|
||||||
import { UsersApi } from '../../../../api/users';
|
import { UsersApi } from '../../../../api/users';
|
||||||
import { DIRECTION_TRANSLATE, FORM_TYPE_TRANSLATE, ROLES_ID_RUSSIAN_NAME, SHEET_NAME, STAGE_ROLE_RUSSIAN_NAME } from '../../../../constants';
|
import { ROLES_ID_RUSSIAN_NAME, SHEET_NAME } from '../../../../constants';
|
||||||
|
|
||||||
export const VALUE_TRANSFORMERS = {
|
export const VALUE_TRANSFORMERS = {
|
||||||
Роль: transformRole,
|
Роль: transformRole,
|
||||||
@ -16,30 +14,11 @@ export const VALUE_TRANSFORMERS = {
|
|||||||
'Создана для СПП/РФ': transformSspsDict,
|
'Создана для СПП/РФ': transformSspsDict,
|
||||||
'Лист': transformSheet,
|
'Лист': transformSheet,
|
||||||
'СПП/РФ': transformSsp,
|
'СПП/РФ': transformSsp,
|
||||||
'Статья расходов': transformExpense,
|
|
||||||
'Информация о задаче': transformForm,
|
|
||||||
'Направление': transformDirection,
|
|
||||||
'Для роли': transformRoleChanges,
|
|
||||||
'Колонки в этапе': transformColumns,
|
|
||||||
'Форма': transformFormType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function transformRole(value) {
|
export function transformRole(value) {
|
||||||
return ROLES_ID_RUSSIAN_NAME[value] || 'Роль не найдена';
|
return ROLES_ID_RUSSIAN_NAME[value] || 'Роль не найдена';
|
||||||
}
|
}
|
||||||
export function transformFormType(value) {
|
|
||||||
return FORM_TYPE_TRANSLATE[value] || 'Форма не найдена';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformRoleChanges(value) {
|
|
||||||
if (typeof value === 'string') {
|
|
||||||
return STAGE_ROLE_RUSSIAN_NAME[value]
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
before: STAGE_ROLE_RUSSIAN_NAME[value.before],
|
|
||||||
after: STAGE_ROLE_RUSSIAN_NAME[value.after],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function transformUser(userId) {
|
export async function transformUser(userId) {
|
||||||
try {
|
try {
|
||||||
@ -104,107 +83,3 @@ export async function transformSspsDict(ssps) {
|
|||||||
export function transformSheet(value) {
|
export function transformSheet(value) {
|
||||||
return SHEET_NAME[value] || 'Лист не найден';
|
return SHEET_NAME[value] || 'Лист не найден';
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function transformExpense(itemId) {
|
|
||||||
if (!itemId) {
|
|
||||||
return 'нет информации'
|
|
||||||
}
|
|
||||||
const res = await FormsSheetApi.getExpenseItem(itemId);
|
|
||||||
const expense = res.result;
|
|
||||||
return expense.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function transformForm(formId) {
|
|
||||||
if (!formId) {
|
|
||||||
return 'нет информации'
|
|
||||||
}
|
|
||||||
const res = await FormsApi.getForm(formId);
|
|
||||||
const form = res.result;
|
|
||||||
const formInfo = {
|
|
||||||
'название': FORM_TYPE_TRANSLATE[form.form_type_code],
|
|
||||||
'ССП/РФ': form.org_unit.title,
|
|
||||||
'Год': form.year,
|
|
||||||
}
|
|
||||||
return formInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformDirection(direction) {
|
|
||||||
if (!direction) {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
return DIRECTION_TRANSLATE[direction];
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function transformColumns(cols, formId, sheet) {
|
|
||||||
if (!formId || !sheet) return cols;
|
|
||||||
const res = await FormsApi.getForm(formId);
|
|
||||||
const form = res.result;
|
|
||||||
const formType = form.form_type_code;
|
|
||||||
|
|
||||||
const { config } = await import(`../../../../components/RealtimeTable/constants/${formType}/${sheet}.js`);
|
|
||||||
const columns = config.config.columns;
|
|
||||||
function findColumnAndHeaders(columns, targetAccessorKey) {
|
|
||||||
|
|
||||||
// Рекурсивная функция для поиска колонки и сбора родителей
|
|
||||||
function searchRecursively(columnsArray, path = []) {
|
|
||||||
for (let column of columnsArray) {
|
|
||||||
// Проверяем текущую колонку
|
|
||||||
if (column.accessorKey === targetAccessorKey) {
|
|
||||||
// Нашли целевую колонку, возвращаем путь с заголовками
|
|
||||||
return {
|
|
||||||
found: true,
|
|
||||||
headers: [...path, column.header],
|
|
||||||
column: column
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Если у колонки есть вложенные колонки, ищем в них
|
|
||||||
if (column.columns && Array.isArray(column.columns)) {
|
|
||||||
const result = searchRecursively(column.columns, [...path, column.header]);
|
|
||||||
if (result.found) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { found: false };
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = searchRecursively(columns);
|
|
||||||
|
|
||||||
if (result.found) {
|
|
||||||
return {
|
|
||||||
headers: result.headers,
|
|
||||||
column: result.column,
|
|
||||||
path: result.headers.join(' → ')
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
headers: [],
|
|
||||||
column: null,
|
|
||||||
path: null,
|
|
||||||
error: `Колонка с accessorKey "${targetAccessorKey}" не найдена`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Array.isArray(cols)) {
|
|
||||||
const res = [];
|
|
||||||
cols.forEach(c => {
|
|
||||||
res.push(findColumnAndHeaders(columns, "data." + c).path || '');
|
|
||||||
})
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
const translateColsAfter = [];
|
|
||||||
const translateColsBefore = [];
|
|
||||||
|
|
||||||
cols.after.forEach(c => {
|
|
||||||
translateColsAfter.push(findColumnAndHeaders(columns, "data." + c).path || '');
|
|
||||||
})
|
|
||||||
cols.before.forEach(c => {
|
|
||||||
translateColsBefore.push(findColumnAndHeaders(columns, "data." + c).path || '');
|
|
||||||
})
|
|
||||||
|
|
||||||
// Пример использования:
|
|
||||||
return { after: translateColsAfter, before: translateColsBefore };
|
|
||||||
}
|
|
||||||
@ -20,10 +20,6 @@ export const ModalEditUserSsp = ({
|
|||||||
const [selectedType, setSelectedType] = useState('rf'); // 'rf' или 'ssp'
|
const [selectedType, setSelectedType] = useState('rf'); // 'rf' или 'ssp'
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
|
||||||
setCurUser(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setCurUser(user);
|
setCurUser(user);
|
||||||
try {
|
try {
|
||||||
if (user && user.role_id == ROLES_NAME_ID.executor_rf) {
|
if (user && user.role_id == ROLES_NAME_ID.executor_rf) {
|
||||||
@ -33,7 +29,7 @@ export const ModalEditUserSsp = ({
|
|||||||
} catch {
|
} catch {
|
||||||
setSelectedType('rf');
|
setSelectedType('rf');
|
||||||
}
|
}
|
||||||
}, [user, open]);
|
}, [user]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!deps) return;
|
if (!deps) return;
|
||||||
@ -79,9 +75,14 @@ export const ModalEditUserSsp = ({
|
|||||||
}, [depsData]);
|
}, [depsData]);
|
||||||
|
|
||||||
const sspForDfip = useMemo(() => {
|
const sspForDfip = useMemo(() => {
|
||||||
if (!curUser|| !open) return [];
|
if (!curUser) return [];
|
||||||
|
if (newDepsData.update.length > 0) {
|
||||||
|
return newDepsData.update.map(
|
||||||
|
(sId) => deps.filter((dep) => dep.id == sId)[0],
|
||||||
|
);
|
||||||
|
}
|
||||||
return curUser.org_units ?? [];
|
return curUser.org_units ?? [];
|
||||||
}, [curUser, deps, newDepsData, open]);
|
}, [curUser, deps, newDepsData]);
|
||||||
|
|
||||||
const handleTypeChange = (value) => {
|
const handleTypeChange = (value) => {
|
||||||
setSelectedType(value);
|
setSelectedType(value);
|
||||||
|
|||||||
@ -359,8 +359,8 @@ export const EditUserModal = ({
|
|||||||
customSize={58.13}
|
customSize={58.13}
|
||||||
>
|
>
|
||||||
<FormStack>
|
<FormStack>
|
||||||
<Box sx={{ display: 'flex', gap: '1.5rem', flexDirection: 'column' }} >
|
<Box display={'flex'} gap={'1.5rem'} flexDirection={'column'}>
|
||||||
<Box sx={{ display: 'flex', gap: '.5rem', flexDirection: 'column' }} >
|
<Box display={'flex'} gap={'.5rem'} flexDirection={'column'}>
|
||||||
{renderField('ФИО', 'full_name', editUser.full_name)}
|
{renderField('ФИО', 'full_name', editUser.full_name)}
|
||||||
{renderField('Почта', 'email', editUser.email, 'email')}
|
{renderField('Почта', 'email', editUser.email, 'email')}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -105,7 +105,7 @@ export const AutocompleteForChangeOptions = ({
|
|||||||
if (option.email) {
|
if (option.email) {
|
||||||
label += ` (${option.email})`;
|
label += ` (${option.email})`;
|
||||||
}
|
}
|
||||||
return label ?? '-';
|
return label;
|
||||||
}}
|
}}
|
||||||
onChange={handleSelect}
|
onChange={handleSelect}
|
||||||
inputValue={inputValue}
|
inputValue={inputValue}
|
||||||
|
|||||||
@ -95,9 +95,7 @@ const TableFooter = ({
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Stack sx={{
|
<Stack direction="row" spacing={2} alignItems="center">
|
||||||
direction: "row", spacing: 2, alignItems: "center"
|
|
||||||
}}>
|
|
||||||
<Pagination
|
<Pagination
|
||||||
count={Math.max(1, totalPages)}
|
count={Math.max(1, totalPages)}
|
||||||
page={page + 1}
|
page={page + 1}
|
||||||
|
|||||||
@ -142,7 +142,7 @@ function DictVspPage() {
|
|||||||
<DictVspInfo />
|
<DictVspInfo />
|
||||||
{/* <HeaderSwitch /> */}
|
{/* <HeaderSwitch /> */}
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<Stack sx={{ alignItems: 'stretch' }} width="100%">
|
<Stack alignItems={'stretch'} width="100%">
|
||||||
<Box width="100%">
|
<Box width="100%">
|
||||||
{user.role_id !== ROLES_NAME_ID.executor_rf && (
|
{user.role_id !== ROLES_NAME_ID.executor_rf && (
|
||||||
<DictVspFilters
|
<DictVspFilters
|
||||||
|
|||||||
@ -106,12 +106,9 @@ function DictsNavigatorPage() {
|
|||||||
</FeatureList>
|
</FeatureList>
|
||||||
<PrimaryButton height={'2.75rem'} onClick={handleNavigateToVSP}>
|
<PrimaryButton height={'2.75rem'} onClick={handleNavigateToVSP}>
|
||||||
<Stack
|
<Stack
|
||||||
sx={{
|
spacing={'.25rem'}
|
||||||
spacing: '.25rem',
|
direction={'row'}
|
||||||
direction: 'row',
|
alignItems={'center'}
|
||||||
alignItems: 'center',
|
|
||||||
}}
|
|
||||||
|
|
||||||
>
|
>
|
||||||
<TransitionSvg />
|
<TransitionSvg />
|
||||||
<p>Открыть справочник объектов</p>
|
<p>Открыть справочник объектов</p>
|
||||||
|
|||||||
@ -22,13 +22,13 @@ import { ModalCreateProject } from './ModalCreateProject';
|
|||||||
import { ExportWithTextButton } from '../../components/common/Buttons/ButtonsActions';
|
import { ExportWithTextButton } from '../../components/common/Buttons/ButtonsActions';
|
||||||
import { exportSingleForm } from '../../utils/exportForm';
|
import { exportSingleForm } from '../../utils/exportForm';
|
||||||
import TablesList from '../../components/common/TableList/TableList';
|
import TablesList from '../../components/common/TableList/TableList';
|
||||||
import { DIRECTION_TRANSLATE, FORM_TYPE_TRANSLATE, SHEET_NAME } from '../../constants';
|
import { DIRECTION_TRANSLATE, FROM_TYPE_TRANSLATE, SHEET_NAME } from '../../constants';
|
||||||
|
|
||||||
const TaskInfo = ({ task }) => {
|
const TaskInfo = ({ task }) => {
|
||||||
const portalContent = (
|
const portalContent = (
|
||||||
<TaskInfoContainer>
|
<TaskInfoContainer>
|
||||||
<BackButton to="/tasks" />
|
<BackButton to="/tasks" />
|
||||||
<NameTask>{FORM_TYPE_TRANSLATE[task.form_type_code] || ''}</NameTask>
|
<NameTask>{FROM_TYPE_TRANSLATE[task.form_type_code] || ''}</NameTask>
|
||||||
</TaskInfoContainer>
|
</TaskInfoContainer>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import {
|
|||||||
FORM_TYPE_OPTIONS,
|
FORM_TYPE_OPTIONS,
|
||||||
ORG_UNIT_TYPE_OPTIONS,
|
ORG_UNIT_TYPE_OPTIONS,
|
||||||
ROLES_NAME_ID,
|
ROLES_NAME_ID,
|
||||||
FORM_TYPE_TRANSLATE
|
FROM_TYPE_TRANSLATE
|
||||||
} from '../../constants';
|
} from '../../constants';
|
||||||
import { useAuth } from '../../app/context/AuthProvider';
|
import { useAuth } from '../../app/context/AuthProvider';
|
||||||
import { SspApi } from '../../api/ssp';
|
import { SspApi } from '../../api/ssp';
|
||||||
@ -414,7 +414,7 @@ export default function TasksPage() {
|
|||||||
onChange={(e) => handleFormChange('formTypeCode', e.target.value)}
|
onChange={(e) => handleFormChange('formTypeCode', e.target.value)}
|
||||||
renderValue={(selected) =>
|
renderValue={(selected) =>
|
||||||
selected ? (
|
selected ? (
|
||||||
FORM_TYPE_TRANSLATE[selected]
|
FROM_TYPE_TRANSLATE[selected]
|
||||||
) : (
|
) : (
|
||||||
<span style={{ color: 'rgba(0,0,0,0.6)' }}>Не выбрана</span>
|
<span style={{ color: 'rgba(0,0,0,0.6)' }}>Не выбрана</span>
|
||||||
)
|
)
|
||||||
@ -424,7 +424,7 @@ export default function TasksPage() {
|
|||||||
>
|
>
|
||||||
{FORM_TYPE_OPTIONS.map((formType) => (
|
{FORM_TYPE_OPTIONS.map((formType) => (
|
||||||
<MenuItem key={formType} value={formType}>
|
<MenuItem key={formType} value={formType}>
|
||||||
{FORM_TYPE_TRANSLATE[formType]}
|
{FROM_TYPE_TRANSLATE[formType]}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user