aurora-(1636, 1693): обновление справочника гк и юл и исправлена фильтрация юл без гк
This commit is contained in:
parent
ee43d5200a
commit
c64975241b
@ -4,7 +4,13 @@ import { useEffect, useState } from 'react';
|
|||||||
import { ApiError } from '../api/client';
|
import { ApiError } from '../api/client';
|
||||||
import PageTitle from '../components/PageTitle';
|
import PageTitle from '../components/PageTitle';
|
||||||
import { createCatalogueJur } from '../services/api/directories/catalogue_jur';
|
import { createCatalogueJur } from '../services/api/directories/catalogue_jur';
|
||||||
import { createCompanyGroup, fetchRelatedGroups } from '../services/api/directories/company_groups';
|
import {
|
||||||
|
archiveCompanyGroup,
|
||||||
|
createCompanyGroup,
|
||||||
|
editCompanyGroup,
|
||||||
|
fetchRelatedGroups,
|
||||||
|
unarchiveCompanyGroup,
|
||||||
|
} from '../services/api/directories/company_groups';
|
||||||
import { createRelatedGroup } from '../services/api/directories/related-groups';
|
import { createRelatedGroup } from '../services/api/directories/related-groups';
|
||||||
import { setActiveCompanyGroup } from '../store/slices/catalogueJurSlice/catalogueJurSlice';
|
import { setActiveCompanyGroup } from '../store/slices/catalogueJurSlice/catalogueJurSlice';
|
||||||
import { getCatalogueJurThunk } from '../store/slices/catalogueJurSlice/thunks';
|
import { getCatalogueJurThunk } from '../store/slices/catalogueJurSlice/thunks';
|
||||||
@ -12,7 +18,7 @@ import { getCompanyGroupsThunk } from '../store/slices/companyGroupsSlice/thunks
|
|||||||
import { useAppDispatch, useAppSelector } from '../store/store';
|
import { useAppDispatch, useAppSelector } from '../store/store';
|
||||||
import type { RelatedGroupOut } from '../types/api';
|
import type { RelatedGroupOut } from '../types/api';
|
||||||
import type { CatalogueJurFormProps } from '../types/catalogueJur/catalogueJur';
|
import type { CatalogueJurFormProps } from '../types/catalogueJur/catalogueJur';
|
||||||
import type { CreateCompanyGroupProps } from '../types/companyGroups/companyGroups';
|
import type { CompanyGroupFormProps } from '../types/companyGroups/companyGroups';
|
||||||
import type { CreateEntityKind, RelatedGroupFormType } from '../types/relatedGroup/relatedGroup';
|
import type { CreateEntityKind, RelatedGroupFormType } from '../types/relatedGroup/relatedGroup';
|
||||||
import { useNotificationApi } from '../utils/useNotification';
|
import { useNotificationApi } from '../utils/useNotification';
|
||||||
import { CataloguGroupTabs, type CatalogueGroupTabKey } from '../widgets/CataloguGroupTabs/CataloguGroupTabs';
|
import { CataloguGroupTabs, type CatalogueGroupTabKey } from '../widgets/CataloguGroupTabs/CataloguGroupTabs';
|
||||||
@ -24,6 +30,7 @@ import { CompanyGroupsList } from '../widgets/CompanyGroupsList/CompanyGroupsLis
|
|||||||
import { CreateEntityPickerModal } from '../widgets/CreateEntityPickerModal/CreateEntityPickerModal';
|
import { CreateEntityPickerModal } from '../widgets/CreateEntityPickerModal/CreateEntityPickerModal';
|
||||||
import { RelatedGroupForm } from '../widgets/RelatedGroupForm/RelatedGroupForm';
|
import { RelatedGroupForm } from '../widgets/RelatedGroupForm/RelatedGroupForm';
|
||||||
import { RelatedGroupTable } from '../widgets/RelatedGroupTable/RelatedGroupTable';
|
import { RelatedGroupTable } from '../widgets/RelatedGroupTable/RelatedGroupTable';
|
||||||
|
import { ArchiveCompanyGroupModal } from '../widgets/ArchiveCompanyGroupModal/ArchiveCompanyGroupModal';
|
||||||
|
|
||||||
export function CatalogueGroup() {
|
export function CatalogueGroup() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
@ -34,16 +41,20 @@ export function CatalogueGroup() {
|
|||||||
const [entityCreateModalOpen, setEntityCreateModalOpen] = useState(false);
|
const [entityCreateModalOpen, setEntityCreateModalOpen] = useState(false);
|
||||||
const [kindForm, setKindForm] = useState<CreateEntityKind | null>(null);
|
const [kindForm, setKindForm] = useState<CreateEntityKind | null>(null);
|
||||||
const [relatedGroupLoading, setRelatedGroupLoading] = useState(false);
|
const [relatedGroupLoading, setRelatedGroupLoading] = useState(false);
|
||||||
|
const [companyGroupEditFormOpen, setCompanyGroupEditFormOpen] = useState(false);
|
||||||
|
const [companyGroupDeleteOpen, setCompanyGroupDeleteOpen] = useState(false);
|
||||||
|
const [companyGroupDeleteLoading, setCompanyGroupDeleteLoading] = useState(false);
|
||||||
const [activeTab, setActiveTab] = useState<CatalogueGroupTabKey>('legal_entities');
|
const [activeTab, setActiveTab] = useState<CatalogueGroupTabKey>('legal_entities');
|
||||||
const [gskData, setGskData] = useState<RelatedGroupOut[]>([]);
|
const [gskData, setGskData] = useState<RelatedGroupOut[]>([]);
|
||||||
const [gszData, setGszData] = useState<RelatedGroupOut[]>([]);
|
const [gszData, setGszData] = useState<RelatedGroupOut[]>([]);
|
||||||
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
|
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
|
||||||
const relatedGroupFilter = useAppSelector((state) => state.catalogue_jur.relatedGroupFilter);
|
const relatedGroupFilter = useAppSelector((state) => state.catalogue_jur.relatedGroupFilter);
|
||||||
const rawRows = useAppSelector((state) => state.company_groups.raw_rows);
|
const rawRows = useAppSelector((state) => state.company_groups.raw_rows);
|
||||||
|
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
|
||||||
|
|
||||||
async function createJurHandler(values: CatalogueJurFormProps) {
|
async function createJurHandler(values: CatalogueJurFormProps) {
|
||||||
await createCatalogueJur(values);
|
await createCatalogueJur(values);
|
||||||
dispatch(getCompanyGroupsThunk());
|
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
||||||
dispatch(
|
dispatch(
|
||||||
getCatalogueJurThunk({
|
getCatalogueJurThunk({
|
||||||
closed: isGettingArchive,
|
closed: isGettingArchive,
|
||||||
@ -63,12 +74,43 @@ export function CatalogueGroup() {
|
|||||||
setKindForm(null);
|
setKindForm(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function createCompanyGroupHandler(values: CreateCompanyGroupProps) {
|
async function createCompanyGroupHandler(values: CompanyGroupFormProps) {
|
||||||
await createCompanyGroup(values);
|
await createCompanyGroup(values);
|
||||||
dispatch(getCompanyGroupsThunk());
|
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
||||||
getRelatedGroupsHandler();
|
|
||||||
setKindForm(null);
|
setKindForm(null);
|
||||||
}
|
}
|
||||||
|
async function editCompanyGroupHandler(values: CompanyGroupFormProps) {
|
||||||
|
if (activeCompanyGroup?.id) {
|
||||||
|
await editCompanyGroup(activeCompanyGroup?.id, values);
|
||||||
|
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
||||||
|
setCompanyGroupEditFormOpen(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function archiveCompanyGroupHandler() {
|
||||||
|
if (!activeCompanyGroup) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
setCompanyGroupDeleteLoading(true);
|
||||||
|
if (activeCompanyGroup?.is_archived) {
|
||||||
|
await unarchiveCompanyGroup(activeCompanyGroup?.id);
|
||||||
|
} else {
|
||||||
|
await archiveCompanyGroup(activeCompanyGroup.id);
|
||||||
|
}
|
||||||
|
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
||||||
|
|
||||||
|
setCompanyGroupDeleteOpen(false);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof ApiError) {
|
||||||
|
notification.error({
|
||||||
|
description: e.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setCompanyGroupDeleteLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function getRelatedGroupsHandler() {
|
async function getRelatedGroupsHandler() {
|
||||||
if (activeCompanyGroup?.id) {
|
if (activeCompanyGroup?.id) {
|
||||||
@ -93,7 +135,6 @@ export function CatalogueGroup() {
|
|||||||
getRelatedGroupsHandler();
|
getRelatedGroupsHandler();
|
||||||
}, [activeCompanyGroup]);
|
}, [activeCompanyGroup]);
|
||||||
|
|
||||||
// Без выбранной ГК таблица ЮЛ не грузится — выбираем первую ГК списка
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!activeCompanyGroup && rawRows?.length) {
|
if (!activeCompanyGroup && rawRows?.length) {
|
||||||
dispatch(setActiveCompanyGroup(rawRows[0]));
|
dispatch(setActiveCompanyGroup(rawRows[0]));
|
||||||
@ -140,7 +181,7 @@ export function CatalogueGroup() {
|
|||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
}}>
|
}}>
|
||||||
<CompanyGroupHeader />
|
<CompanyGroupHeader setDeleteConfirmOpen={setCompanyGroupDeleteOpen} setEditFormOpen={setCompanyGroupEditFormOpen} />
|
||||||
{activeTab === 'legal_entities' && (
|
{activeTab === 'legal_entities' && (
|
||||||
<CatalogueJurTable
|
<CatalogueJurTable
|
||||||
outside_group={false}
|
outside_group={false}
|
||||||
@ -200,6 +241,25 @@ export function CatalogueGroup() {
|
|||||||
onOk={createCompanyGroupHandler}
|
onOk={createCompanyGroupHandler}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{companyGroupEditFormOpen && (
|
||||||
|
<CompanyGroupForm
|
||||||
|
open={companyGroupEditFormOpen}
|
||||||
|
onCancel={() => {
|
||||||
|
setCompanyGroupEditFormOpen(false);
|
||||||
|
}}
|
||||||
|
onOk={editCompanyGroupHandler}
|
||||||
|
companyGroupId={activeCompanyGroup?.id}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{companyGroupDeleteOpen && activeCompanyGroup && (
|
||||||
|
<ArchiveCompanyGroupModal
|
||||||
|
open={companyGroupDeleteOpen}
|
||||||
|
loading={companyGroupDeleteLoading}
|
||||||
|
onCancel={() => setCompanyGroupDeleteOpen(false)}
|
||||||
|
onOk={archiveCompanyGroupHandler}
|
||||||
|
isArchived={activeCompanyGroup?.is_archived}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,20 @@
|
|||||||
import { api } from '../../../api/client';
|
import { api } from '../../../api/client';
|
||||||
|
import { GetCompanyGroupsPropsI } from '../../../store/slices/companyGroupsSlice/types';
|
||||||
import type { LegalEntityBrief, Page, RelatedGroupDetail, RelatedGroupOut } from '../../../types/api';
|
import type { LegalEntityBrief, Page, RelatedGroupDetail, RelatedGroupOut } from '../../../types/api';
|
||||||
import type { CreateCompanyGroupProps, ICompanyGroupOut } from '../../../types/companyGroups/companyGroups';
|
import type { CompanyGroupFormProps, ICompanyGroupOut } from '../../../types/companyGroups/companyGroups';
|
||||||
|
|
||||||
const CG_PAGE = 200;
|
const CG_PAGE = 200;
|
||||||
export const LE_PAGE = 200;
|
export const LE_PAGE = 200;
|
||||||
|
|
||||||
/** Все видимые ГК — дочитываем страницы, пока не получим total. */
|
/** Все видимые ГК — дочитываем страницы, пока не получим total. */
|
||||||
export async function fetchCompanyGroups(): Promise<ICompanyGroupOut[]> {
|
export async function fetchCompanyGroups(params: GetCompanyGroupsPropsI): Promise<ICompanyGroupOut[]> {
|
||||||
const all: ICompanyGroupOut[] = [];
|
const all: ICompanyGroupOut[] = [];
|
||||||
for (let offset = 0; ; offset += CG_PAGE) {
|
for (let offset = 0; ; offset += CG_PAGE) {
|
||||||
const page = await api.get<Page<ICompanyGroupOut>>(`/directories/company-groups?limit=${CG_PAGE}&offset=${offset}`);
|
const page = await api.get<Page<ICompanyGroupOut>>(`/directories/company-groups`, {
|
||||||
|
limit: CG_PAGE,
|
||||||
|
offset: offset,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
all.push(...page.items);
|
all.push(...page.items);
|
||||||
if (all.length >= page.total || page.items.length === 0) {
|
if (all.length >= page.total || page.items.length === 0) {
|
||||||
return all;
|
return all;
|
||||||
@ -37,6 +42,15 @@ export async function fetchAllLegalEntities(groupId: string): Promise<LegalEntit
|
|||||||
|
|
||||||
export const fetchLegalEntity = (id: string) => api.get<LegalEntityBrief>(`/directories/legal-entities/${id}`);
|
export const fetchLegalEntity = (id: string) => api.get<LegalEntityBrief>(`/directories/legal-entities/${id}`);
|
||||||
|
|
||||||
export function createCompanyGroup(body: CreateCompanyGroupProps): Promise<void> {
|
export function createCompanyGroup(body: CompanyGroupFormProps): Promise<void> {
|
||||||
return api.post<void>('/directories/company-groups', body);
|
return api.post<void>('/directories/company-groups', body);
|
||||||
}
|
}
|
||||||
|
export function editCompanyGroup(id: string, body: CompanyGroupFormProps): Promise<void> {
|
||||||
|
return api.patch<void>(`/directories/company-groups/${id}`, body);
|
||||||
|
}
|
||||||
|
export function archiveCompanyGroup(id: string): Promise<void> {
|
||||||
|
return api.post<void>(`/directories/company-groups/${id}/archive`);
|
||||||
|
}
|
||||||
|
export function unarchiveCompanyGroup(id: string): Promise<void> {
|
||||||
|
return api.post<void>(`/directories/company-groups/${id}/unarchive`);
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { getCompanyGroupsThunk } from './thunks';
|
import { getCompanyGroupsThunk } from './thunks';
|
||||||
import type { CompanyGroupSliceType } from './types';
|
import type { CompanyGroupSliceType } from './types';
|
||||||
|
|
||||||
@ -6,13 +6,18 @@ const initialState: CompanyGroupSliceType = {
|
|||||||
raw_rows: [],
|
raw_rows: [],
|
||||||
total_groups: 0,
|
total_groups: 0,
|
||||||
loading: false,
|
loading: false,
|
||||||
|
isGettingArchive: false,
|
||||||
error: null,
|
error: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const comGroupsSlice = createSlice({
|
const comGroupsSlice = createSlice({
|
||||||
name: 'company_groups',
|
name: 'company_groups',
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {},
|
reducers: {
|
||||||
|
setIsGettingArchive(state, action: PayloadAction<boolean>) {
|
||||||
|
state.isGettingArchive = action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
extraReducers: (builder) => {
|
extraReducers: (builder) => {
|
||||||
builder
|
builder
|
||||||
.addCase(getCompanyGroupsThunk.pending, (state) => {
|
.addCase(getCompanyGroupsThunk.pending, (state) => {
|
||||||
@ -30,4 +35,6 @@ const comGroupsSlice = createSlice({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
export const { setIsGettingArchive } = comGroupsSlice.actions;
|
||||||
|
|
||||||
export default comGroupsSlice.reducer;
|
export default comGroupsSlice.reducer;
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
import { createAsyncThunk } from '@reduxjs/toolkit';
|
import { createAsyncThunk } from '@reduxjs/toolkit';
|
||||||
import { fetchCompanyGroups } from '../../../services/api/directories/company_groups';
|
import { fetchCompanyGroups } from '../../../services/api/directories/company_groups';
|
||||||
import { type ICompanyGroup, toCompanyGroupRow } from '../../../types/companyGroups/companyGroups';
|
import { type ICompanyGroup, toCompanyGroupRow } from '../../../types/companyGroups/companyGroups';
|
||||||
|
import { GetCompanyGroupsPropsI } from './types';
|
||||||
|
|
||||||
export const getCompanyGroupsThunk = createAsyncThunk<ICompanyGroup[], void, { rejectValue: string }>(
|
export const getCompanyGroupsThunk = createAsyncThunk<ICompanyGroup[], GetCompanyGroupsPropsI | undefined, { rejectValue: string }>(
|
||||||
'company_groups/getAll',
|
'company_groups/getAll',
|
||||||
async (_, thunkApi) => {
|
async (args = {}, thunkApi) => {
|
||||||
try {
|
try {
|
||||||
return (await fetchCompanyGroups()).map(toCompanyGroupRow);
|
return (await fetchCompanyGroups(args)).map(toCompanyGroupRow);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return thunkApi.rejectWithValue(e instanceof Error ? e.message : 'Ошибка');
|
return thunkApi.rejectWithValue(e instanceof Error ? e.message : 'Ошибка');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
)
|
||||||
|
|||||||
@ -5,4 +5,9 @@ export interface CompanyGroupSliceType {
|
|||||||
raw_rows: ICompanyGroup[];
|
raw_rows: ICompanyGroup[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
error: string | null;
|
error: string | null;
|
||||||
|
isGettingArchive: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetCompanyGroupsPropsI {
|
||||||
|
is_archived?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ export interface ICatalogueJur {
|
|||||||
name: string;
|
name: string;
|
||||||
is_head_office: boolean;
|
is_head_office: boolean;
|
||||||
};
|
};
|
||||||
|
regional_name?:string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type KindType = 'gsk' | 'gsz';
|
export type KindType = 'gsk' | 'gsz';
|
||||||
|
|||||||
@ -6,6 +6,7 @@ export interface ICompanyGroupOut {
|
|||||||
base_regional_office_id: string | null;
|
base_regional_office_id: string | null;
|
||||||
base_regional_office: { id: string; name: string; is_head_office: boolean } | null;
|
base_regional_office: { id: string; name: string; is_head_office: boolean } | null;
|
||||||
legal_entities_count: number;
|
legal_entities_count: number;
|
||||||
|
is_archived:boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Строка таблицы ГК: имя филиала плоским полем — по нему работают поиск и фильтры GenericTable. */
|
/** Строка таблицы ГК: имя филиала плоским полем — по нему работают поиск и фильтры GenericTable. */
|
||||||
@ -18,7 +19,7 @@ export const toCompanyGroupRow = (g: ICompanyGroupOut): ICompanyGroup => ({
|
|||||||
base_regional_office_name: g.base_regional_office?.name ?? '—',
|
base_regional_office_name: g.base_regional_office?.name ?? '—',
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface CreateCompanyGroupProps {
|
export interface CompanyGroupFormProps {
|
||||||
name: string;
|
name: string;
|
||||||
crm_id: string;
|
crm_id: string;
|
||||||
base_regional_office_id: string | null;
|
base_regional_office_id: string | null;
|
||||||
|
|||||||
@ -0,0 +1,26 @@
|
|||||||
|
import { Modal } from 'antd';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
open: boolean;
|
||||||
|
onCancel: () => void;
|
||||||
|
onOk: () => void | Promise<void>;
|
||||||
|
loading?: boolean;
|
||||||
|
isArchived: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ArchiveCompanyGroupModal: React.FC<Props> = ({ open, onCancel, onOk, loading, isArchived }) => {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title={isArchived ? 'Разархивировать' : 'Архивировать'}
|
||||||
|
open={open}
|
||||||
|
onCancel={onCancel}
|
||||||
|
onOk={onOk}
|
||||||
|
okText='Подтвердить'
|
||||||
|
cancelText='Отмена'
|
||||||
|
okButtonProps={{ danger: true }}
|
||||||
|
confirmLoading={loading}
|
||||||
|
centered>
|
||||||
|
<p style={{ margin: 0, color: '#595959' }}>Группа компании будет {isArchived ? 'разархивированна' : 'архивированна'}</p>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -1,33 +1,74 @@
|
|||||||
import { Space } from 'antd';
|
import { Button, Dropdown, Space } from 'antd';
|
||||||
import Text from 'antd/es/typography/Text';
|
import Text from 'antd/es/typography/Text';
|
||||||
import Title from 'antd/es/typography/Title';
|
import Title from 'antd/es/typography/Title';
|
||||||
import { useAppSelector } from '../../store/store';
|
import { useAppSelector } from '../../store/store';
|
||||||
import { pluralRu } from '../../utils/labels';
|
import { pluralRu } from '../../utils/labels';
|
||||||
|
import { DeleteOutlined, EditOutlined, EllipsisOutlined, HistoryOutlined } from '@ant-design/icons';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
export const CompanyGroupHeader = () => {
|
interface CompanyGroupHeaderI {
|
||||||
|
setDeleteConfirmOpen: (el: boolean) => void;
|
||||||
|
setEditFormOpen: (el: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CompanyGroupHeader = ({ setEditFormOpen, setDeleteConfirmOpen }: CompanyGroupHeaderI) => {
|
||||||
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
|
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
|
||||||
const count = activeCompanyGroup?.legal_entities_count ?? 0;
|
const count = activeCompanyGroup?.legal_entities_count ?? 0;
|
||||||
|
const navigate = useNavigate();
|
||||||
const organizationWord = pluralRu(count, ['организация', 'организации', 'организаций']);
|
const organizationWord = pluralRu(count, ['организация', 'организации', 'организаций']);
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
key: 'edit',
|
||||||
|
icon: <EditOutlined />,
|
||||||
|
label: 'Изменить ГК',
|
||||||
|
onClick: () => {
|
||||||
|
setEditFormOpen(true);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'history',
|
||||||
|
icon: <HistoryOutlined />,
|
||||||
|
label: 'История изменений',
|
||||||
|
onClick: () => navigate('/logging'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'delete',
|
||||||
|
icon: <DeleteOutlined />,
|
||||||
|
label: activeCompanyGroup?.is_archived ? 'Разархивировать' : 'Архивировать',
|
||||||
|
danger: true,
|
||||||
|
onClick: () => {
|
||||||
|
setDeleteConfirmOpen(true);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<Space
|
||||||
style={{
|
style={{
|
||||||
padding: '6px 16px',
|
padding: '6px 16px',
|
||||||
borderBottom: '1px solid #0f172a0f',
|
borderBottom: '1px solid #0f172a0f',
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
|
justifyContent: 'space-between',
|
||||||
}}>
|
}}>
|
||||||
<Title level={5} style={{ margin: 0 }}>
|
<div>
|
||||||
{activeCompanyGroup?.name ?? ''}
|
<Title level={5} style={{ margin: 0 }}>
|
||||||
</Title>
|
{activeCompanyGroup?.name ?? ''}
|
||||||
<Space>
|
</Title>
|
||||||
<Text type='secondary' style={{ fontSize: 13 }}>
|
<Space>
|
||||||
{activeCompanyGroup?.base_regional_office_name ?? ''}
|
<Text type='secondary' style={{ fontSize: 13 }}>
|
||||||
</Text>
|
{activeCompanyGroup?.base_regional_office_name ?? ''}
|
||||||
<Text type='secondary' style={{ fontSize: 13 }}>
|
</Text>
|
||||||
{count ?? 0} {organizationWord}
|
<Text type='secondary' style={{ fontSize: 13 }}>
|
||||||
</Text>
|
{count ?? 0} {organizationWord}
|
||||||
</Space>
|
</Text>
|
||||||
</div>
|
</Space>
|
||||||
|
</div>
|
||||||
|
<Dropdown menu={{ items }} trigger={['click']}>
|
||||||
|
<Button type='default' style={{ width: '32px' }}>
|
||||||
|
<EllipsisOutlined />
|
||||||
|
</Button>
|
||||||
|
</Dropdown>
|
||||||
|
</Space>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -52,14 +52,16 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
const [editCatalogueFormOpen, setEditCatalogueFormOpen] = useState(false);
|
const [editCatalogueFormOpen, setEditCatalogueFormOpen] = useState(false);
|
||||||
const [withdrawCatalogueFormOpen, setWithdrawCatalogueFormOpen] = useState(false);
|
const [withdrawCatalogueFormOpen, setWithdrawCatalogueFormOpen] = useState(false);
|
||||||
const [jurId, setJurId] = useState('');
|
const [jurId, setJurId] = useState('');
|
||||||
|
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
|
||||||
|
|
||||||
const filterdData = useMemo(() => {
|
const filterdData = useMemo(() => {
|
||||||
|
let newData = rawRows
|
||||||
if (relatedGroupFilter?.id && !outside_group) {
|
if (relatedGroupFilter?.id && !outside_group) {
|
||||||
return rawRows?.filter((row) => {
|
newData = rawRows?.filter((row) => {
|
||||||
return row?.memberships?.some((member) => member.related_group_id === relatedGroupFilter.id);
|
return row?.memberships?.some((member) => member.related_group_id === relatedGroupFilter.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return rawRows;
|
return newData?.map((elem) => elem && { ...elem, regional_name: elem?.regional_office?.name });
|
||||||
}, [rawRows, relatedGroupFilter, outside_group]);
|
}, [rawRows, relatedGroupFilter, outside_group]);
|
||||||
|
|
||||||
const { visibleKeys, setVisibleKeys } = useVisibleColumns(catalogueJurConfig);
|
const { visibleKeys, setVisibleKeys } = useVisibleColumns(catalogueJurConfig);
|
||||||
@ -95,7 +97,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
try {
|
try {
|
||||||
await moveCatalogueJur(jurId, values);
|
await moveCatalogueJur(jurId, values);
|
||||||
getCatalogueJur();
|
getCatalogueJur();
|
||||||
dispatch(getCompanyGroupsThunk());
|
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
||||||
closeMoveCatalogueJurHandler();
|
closeMoveCatalogueJurHandler();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof ApiError) {
|
if (e instanceof ApiError) {
|
||||||
@ -109,7 +111,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
try {
|
try {
|
||||||
await withdrawCatalogueJur(jurId, values);
|
await withdrawCatalogueJur(jurId, values);
|
||||||
getCatalogueJur();
|
getCatalogueJur();
|
||||||
dispatch(getCompanyGroupsThunk());
|
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
||||||
|
|
||||||
closeWithdrawCatalogueJurHandler();
|
closeWithdrawCatalogueJurHandler();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -128,7 +130,6 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// «ЮЛ вне ГК» грузится без выбранной ГК; список ГК — только по выбранной (без неё запрос ушёл бы по всем ГК)
|
|
||||||
if (outside_group || activeCompanyGroup?.id) {
|
if (outside_group || activeCompanyGroup?.id) {
|
||||||
getCatalogueJur();
|
getCatalogueJur();
|
||||||
}
|
}
|
||||||
@ -244,7 +245,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
gap: 16,
|
gap: 16,
|
||||||
padding: '10px 16px',
|
padding: '10px 16px',
|
||||||
background: '#fff8e1', // светло-жёлтый фон
|
background: '#fff8e1',
|
||||||
borderTop: '1px solid #ffe58f',
|
borderTop: '1px solid #ffe58f',
|
||||||
borderBottom: '1px solid #ffe58f',
|
borderBottom: '1px solid #ffe58f',
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import type { ICatalogueJur } from '../../types/catalogueJur/catalogueJur';
|
|||||||
|
|
||||||
export const catalogueJurConfig: TableConfig<ICatalogueJur> = {
|
export const catalogueJurConfig: TableConfig<ICatalogueJur> = {
|
||||||
rowKey: 'id',
|
rowKey: 'id',
|
||||||
searchableKeys: ['closed', 'inn', 'kpp', 'name', 'entity_type'],
|
searchableKeys: ['closed', 'inn', 'crm_id', 'kpp', 'name', 'entity_type', 'regional_name'],
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
key: 'closed',
|
key: 'closed',
|
||||||
@ -18,6 +18,28 @@ export const catalogueJurConfig: TableConfig<ICatalogueJur> = {
|
|||||||
return <TableTag text={text} {...preset} />;
|
return <TableTag text={text} {...preset} />;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'crm_id',
|
||||||
|
title: 'Входит в ГСК',
|
||||||
|
render: (_: unknown, row) => {
|
||||||
|
const has = row?.memberships?.some((elem) => elem.kind === 'gsk');
|
||||||
|
const preset = has ? TAG_PRESETS.green : TAG_PRESETS.gray;
|
||||||
|
const text = has ? 'Входит' : 'Не входит';
|
||||||
|
|
||||||
|
return <TableTag text={text} {...preset} />;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'company_group_id',
|
||||||
|
title: 'Входит в ГСЗ',
|
||||||
|
render: (_: unknown, row) => {
|
||||||
|
const has = row?.memberships?.some((elem) => elem.kind === 'gsz');
|
||||||
|
const preset = has ? TAG_PRESETS.green : TAG_PRESETS.gray;
|
||||||
|
const text = has ? 'Входит' : 'Не входит';
|
||||||
|
|
||||||
|
return <TableTag text={text} {...preset} />;
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'inn',
|
key: 'inn',
|
||||||
title: 'ИНН',
|
title: 'ИНН',
|
||||||
@ -43,9 +65,9 @@ export const catalogueJurConfig: TableConfig<ICatalogueJur> = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'regional_office',
|
key: 'regional_name',
|
||||||
title: 'Основной РФ',
|
title: 'Основной РФ',
|
||||||
render: (val) => (val as ICatalogueJur['regional_office'] | null)?.name,
|
features: { search: true, multiselect: true, sort: true },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,26 +3,47 @@ import type React from 'react';
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { ApiError } from '../../api/client';
|
import { ApiError } from '../../api/client';
|
||||||
import { useMe } from '../../auth/useMe';
|
import { useMe } from '../../auth/useMe';
|
||||||
import { useAppSelector } from '../../store/store';
|
import type { CompanyGroupFormProps } from '../../types/companyGroups/companyGroups';
|
||||||
import type { CreateCompanyGroupProps } from '../../types/companyGroups/companyGroups';
|
|
||||||
import { useNotificationApi } from '../../utils/useNotification';
|
import { useNotificationApi } from '../../utils/useNotification';
|
||||||
import { loadOffices } from '../Admin/UsersTable';
|
import { loadOffices } from '../Admin/UsersTable';
|
||||||
|
import { fetchOneCompanyGroup } from '../../services/api/directories/company_groups';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
onOk: (values: CreateCompanyGroupProps) => void | Promise<void>;
|
onOk: (values: CompanyGroupFormProps) => void | Promise<void>;
|
||||||
|
companyGroupId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CompanyGroupForm: React.FC<Props> = ({ open, onCancel, onOk }) => {
|
export const CompanyGroupForm: React.FC<Props> = ({ open, onCancel, onOk, companyGroupId }) => {
|
||||||
const [form] = Form.useForm<CreateCompanyGroupProps>();
|
const [form] = Form.useForm<CompanyGroupFormProps>();
|
||||||
const { me } = useMe();
|
const { me } = useMe();
|
||||||
const notification = useNotificationApi();
|
const notification = useNotificationApi();
|
||||||
|
|
||||||
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
|
|
||||||
const [officesOptions, setOfficesOptions] = useState<{ value: string; label: string }[]>([]);
|
const [officesOptions, setOfficesOptions] = useState<{ value: string; label: string }[]>([]);
|
||||||
const [loadingOptions, setLoadingOptions] = useState(false);
|
const [loadingOptions, setLoadingOptions] = useState(false);
|
||||||
const [confirmLoading, setConfirmLoading] = useState(false);
|
const [confirmLoading, setConfirmLoading] = useState(false);
|
||||||
|
const [initialDataLoading, setInitialDataLoading] = useState(false);
|
||||||
|
|
||||||
|
async function getInitialData() {
|
||||||
|
if (companyGroupId) {
|
||||||
|
setInitialDataLoading(true);
|
||||||
|
try {
|
||||||
|
const data = await fetchOneCompanyGroup(companyGroupId);
|
||||||
|
form.setFieldsValue({
|
||||||
|
name: data.name,
|
||||||
|
crm_id: data.crm_id ?? undefined,
|
||||||
|
base_regional_office_id: data.base_regional_office_id,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof ApiError) {
|
||||||
|
notification.error({ description: e.message });
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setInitialDataLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function getOfficesOptionsHandler() {
|
async function getOfficesOptionsHandler() {
|
||||||
setLoadingOptions(true);
|
setLoadingOptions(true);
|
||||||
@ -45,6 +66,7 @@ export const CompanyGroupForm: React.FC<Props> = ({ open, onCancel, onOk }) => {
|
|||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
await onOk({
|
await onOk({
|
||||||
...values,
|
...values,
|
||||||
|
crm_id: values?.crm_id ?? null,
|
||||||
base_regional_office_id: values?.base_regional_office_id ? values?.base_regional_office_id : (me?.regional_office.id as string),
|
base_regional_office_id: values?.base_regional_office_id ? values?.base_regional_office_id : (me?.regional_office.id as string),
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -72,18 +94,20 @@ export const CompanyGroupForm: React.FC<Props> = ({ open, onCancel, onOk }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
getInitialData();
|
||||||
getOfficesOptionsHandler();
|
getOfficesOptionsHandler();
|
||||||
}, [activeCompanyGroup]);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title='Создать группу компаний'
|
title={`${companyGroupId ? 'Редактировать' : 'Создать'} группу компаний`}
|
||||||
open={open}
|
open={open}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
onOk={handleOk}
|
onOk={handleOk}
|
||||||
okText='Создать'
|
okText={`${companyGroupId ? 'Редактировать' : 'Создать'}`}
|
||||||
cancelText='Отмена'
|
cancelText='Отмена'
|
||||||
destroyOnHidden
|
destroyOnHidden
|
||||||
|
loading={initialDataLoading}
|
||||||
confirmLoading={confirmLoading}
|
confirmLoading={confirmLoading}
|
||||||
width={720}>
|
width={720}>
|
||||||
<Form form={form} layout='vertical'>
|
<Form form={form} layout='vertical'>
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
import { FolderOpenOutlined, SearchOutlined } from '@ant-design/icons';
|
import { FolderOpenOutlined, SearchOutlined } from '@ant-design/icons';
|
||||||
import { Empty, Input, List, Spin, Tag, Typography } from 'antd';
|
import { Checkbox, Empty, Input, List, Space, Spin, Tag, Typography } from 'antd';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useVirtualList } from '../../hooks/useVirtualList';
|
import { useVirtualList } from '../../hooks/useVirtualList';
|
||||||
import { setActiveCompanyGroup } from '../../store/slices/catalogueJurSlice/catalogueJurSlice';
|
import { setActiveCompanyGroup } from '../../store/slices/catalogueJurSlice/catalogueJurSlice';
|
||||||
import { getCompanyGroupsThunk } from '../../store/slices/companyGroupsSlice/thunks';
|
import { getCompanyGroupsThunk } from '../../store/slices/companyGroupsSlice/thunks';
|
||||||
import { useAppDispatch, useAppSelector } from '../../store/store';
|
import { useAppDispatch, useAppSelector } from '../../store/store';
|
||||||
|
import { setIsGettingArchive } from '../../store/slices/companyGroupsSlice/companyGroupsSlice';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ export const CompanyGroupsList = () => {
|
|||||||
const rawRows = useAppSelector((state) => state.company_groups.raw_rows);
|
const rawRows = useAppSelector((state) => state.company_groups.raw_rows);
|
||||||
const loading = useAppSelector((state) => state.company_groups.loading);
|
const loading = useAppSelector((state) => state.company_groups.loading);
|
||||||
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
|
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
|
||||||
|
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
|
||||||
const [query, setQuery] = useState('');
|
const [query, setQuery] = useState('');
|
||||||
|
|
||||||
const filtered = useMemo(() => {
|
const filtered = useMemo(() => {
|
||||||
@ -30,8 +31,8 @@ export const CompanyGroupsList = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(getCompanyGroupsThunk());
|
dispatch(getCompanyGroupsThunk({is_archived:isGettingArchiveCompany}));
|
||||||
}, [dispatch]);
|
}, [dispatch, isGettingArchiveCompany]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!activeCompanyGroup && rawRows?.length) {
|
if (!activeCompanyGroup && rawRows?.length) {
|
||||||
@ -57,7 +58,7 @@ export const CompanyGroupsList = () => {
|
|||||||
borderRight: '1px solid #f0f0f0',
|
borderRight: '1px solid #f0f0f0',
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
}}>
|
}}>
|
||||||
<div style={{ padding: 12 }}>
|
<Space style={{ padding: 12 }}>
|
||||||
<Input
|
<Input
|
||||||
allowClear
|
allowClear
|
||||||
prefix={<SearchOutlined style={{ color: '#bfbfbf' }} />}
|
prefix={<SearchOutlined style={{ color: '#bfbfbf' }} />}
|
||||||
@ -65,7 +66,10 @@ export const CompanyGroupsList = () => {
|
|||||||
value={query}
|
value={query}
|
||||||
onChange={(e) => setQuery(e.target.value)}
|
onChange={(e) => setQuery(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
<Checkbox checked={isGettingArchiveCompany} onChange={(e) =>dispatch(setIsGettingArchive(e.target.checked))}>
|
||||||
|
Архив
|
||||||
|
</Checkbox>
|
||||||
|
</Space>
|
||||||
|
|
||||||
<div ref={ref} onScroll={onScroll} style={{ flex: 1, overflowY: 'auto', padding: '0 8px 8px' }}>
|
<div ref={ref} onScroll={onScroll} style={{ flex: 1, overflowY: 'auto', padding: '0 8px 8px' }}>
|
||||||
{filtered.length === 0 ? (
|
{filtered.length === 0 ? (
|
||||||
|
|||||||
@ -29,6 +29,7 @@ export const MoveCatalogueJurForm: React.FC<Props> = ({ open, onCancel, onOk, ju
|
|||||||
const [form] = Form.useForm<FormValues>();
|
const [form] = Form.useForm<FormValues>();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const notification = useNotificationApi();
|
const notification = useNotificationApi();
|
||||||
|
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
|
||||||
|
|
||||||
const { raw_rows, loading } = useAppSelector((state) => state.company_groups);
|
const { raw_rows, loading } = useAppSelector((state) => state.company_groups);
|
||||||
const [initialDataLoading, setInitialDataLoading] = useState(false);
|
const [initialDataLoading, setInitialDataLoading] = useState(false);
|
||||||
@ -76,7 +77,7 @@ export const MoveCatalogueJurForm: React.FC<Props> = ({ open, onCancel, onOk, ju
|
|||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open && raw_rows.length === 0 && !loading) {
|
if (open && raw_rows.length === 0 && !loading) {
|
||||||
dispatch(getCompanyGroupsThunk());
|
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
||||||
}
|
}
|
||||||
}, [open, raw_rows.length, loading, dispatch]);
|
}, [open, raw_rows.length, loading, dispatch]);
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@ export const RelatedGroupForm: React.FC<Props> = ({ open, onCancel, onOk, relate
|
|||||||
const companyGrops = useAppSelector((state) => state.company_groups.raw_rows);
|
const companyGrops = useAppSelector((state) => state.company_groups.raw_rows);
|
||||||
const companyGropsLoading = useAppSelector((state) => state.company_groups.loading);
|
const companyGropsLoading = useAppSelector((state) => state.company_groups.loading);
|
||||||
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
|
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
|
||||||
|
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
|
||||||
|
|
||||||
async function getInitialData() {
|
async function getInitialData() {
|
||||||
if (!relatedGroupId) {
|
if (!relatedGroupId) {
|
||||||
@ -38,7 +39,8 @@ export const RelatedGroupForm: React.FC<Props> = ({ open, onCancel, onOk, relate
|
|||||||
setInitialDataLoading(true);
|
setInitialDataLoading(true);
|
||||||
try {
|
try {
|
||||||
const data = await fetchRelatedGroup(relatedGroupId);
|
const data = await fetchRelatedGroup(relatedGroupId);
|
||||||
await dispatch(getCompanyGroupsThunk());
|
await dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
||||||
|
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
crm_id: data?.crm_id,
|
crm_id: data?.crm_id,
|
||||||
name: data?.name,
|
name: data?.name,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { EllipsisOutlined } from '@ant-design/icons';
|
import { DeleteOutlined, EditOutlined, EllipsisOutlined } from '@ant-design/icons';
|
||||||
import { Button, Dropdown, Space } from 'antd';
|
import { Button, Dropdown, Space } from 'antd';
|
||||||
import type { ColumnsType } from 'antd/es/table';
|
import type { ColumnsType } from 'antd/es/table';
|
||||||
import { type ReactNode, useMemo, useState } from 'react';
|
import { type ReactNode, useMemo, useState } from 'react';
|
||||||
@ -77,6 +77,7 @@ export function RelatedGroupTable({ tabsComponent, data, loading, getData, activ
|
|||||||
const items = [
|
const items = [
|
||||||
{
|
{
|
||||||
key: 'edit',
|
key: 'edit',
|
||||||
|
icon: <EditOutlined />,
|
||||||
label: 'Изменить',
|
label: 'Изменить',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setGroupId(row.id);
|
setGroupId(row.id);
|
||||||
@ -85,6 +86,7 @@ export function RelatedGroupTable({ tabsComponent, data, loading, getData, activ
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'delete',
|
key: 'delete',
|
||||||
|
icon: <DeleteOutlined />,
|
||||||
label: 'Удалить',
|
label: 'Удалить',
|
||||||
danger: true,
|
danger: true,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user