aurora-(1636, 1693): обновление справочника гк и юл и исправлена фильтрация юл без гк

This commit is contained in:
Grog 2026-10-27 17:04:18 +03:00
parent ee43d5200a
commit c64975241b
16 changed files with 275 additions and 63 deletions

View File

@ -4,7 +4,13 @@ import { useEffect, useState } from 'react';
import { ApiError } from '../api/client';
import PageTitle from '../components/PageTitle';
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 { setActiveCompanyGroup } from '../store/slices/catalogueJurSlice/catalogueJurSlice';
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 type { RelatedGroupOut } from '../types/api';
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 { useNotificationApi } from '../utils/useNotification';
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 { RelatedGroupForm } from '../widgets/RelatedGroupForm/RelatedGroupForm';
import { RelatedGroupTable } from '../widgets/RelatedGroupTable/RelatedGroupTable';
import { ArchiveCompanyGroupModal } from '../widgets/ArchiveCompanyGroupModal/ArchiveCompanyGroupModal';
export function CatalogueGroup() {
const dispatch = useAppDispatch();
@ -34,16 +41,20 @@ export function CatalogueGroup() {
const [entityCreateModalOpen, setEntityCreateModalOpen] = useState(false);
const [kindForm, setKindForm] = useState<CreateEntityKind | null>(null);
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 [gskData, setGskData] = useState<RelatedGroupOut[]>([]);
const [gszData, setGszData] = useState<RelatedGroupOut[]>([]);
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
const relatedGroupFilter = useAppSelector((state) => state.catalogue_jur.relatedGroupFilter);
const rawRows = useAppSelector((state) => state.company_groups.raw_rows);
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
async function createJurHandler(values: CatalogueJurFormProps) {
await createCatalogueJur(values);
dispatch(getCompanyGroupsThunk());
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
dispatch(
getCatalogueJurThunk({
closed: isGettingArchive,
@ -63,12 +74,43 @@ export function CatalogueGroup() {
setKindForm(null);
}
}
async function createCompanyGroupHandler(values: CreateCompanyGroupProps) {
async function createCompanyGroupHandler(values: CompanyGroupFormProps) {
await createCompanyGroup(values);
dispatch(getCompanyGroupsThunk());
getRelatedGroupsHandler();
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
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() {
if (activeCompanyGroup?.id) {
@ -93,7 +135,6 @@ export function CatalogueGroup() {
getRelatedGroupsHandler();
}, [activeCompanyGroup]);
// Без выбранной ГК таблица ЮЛ не грузится — выбираем первую ГК списка
useEffect(() => {
if (!activeCompanyGroup && rawRows?.length) {
dispatch(setActiveCompanyGroup(rawRows[0]));
@ -140,7 +181,7 @@ export function CatalogueGroup() {
flexDirection: 'column',
overflow: 'hidden',
}}>
<CompanyGroupHeader />
<CompanyGroupHeader setDeleteConfirmOpen={setCompanyGroupDeleteOpen} setEditFormOpen={setCompanyGroupEditFormOpen} />
{activeTab === 'legal_entities' && (
<CatalogueJurTable
outside_group={false}
@ -200,6 +241,25 @@ export function CatalogueGroup() {
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>
);
}

View File

@ -1,15 +1,20 @@
import { api } from '../../../api/client';
import { GetCompanyGroupsPropsI } from '../../../store/slices/companyGroupsSlice/types';
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;
export const LE_PAGE = 200;
/** Все видимые ГК — дочитываем страницы, пока не получим total. */
export async function fetchCompanyGroups(): Promise<ICompanyGroupOut[]> {
export async function fetchCompanyGroups(params: GetCompanyGroupsPropsI): Promise<ICompanyGroupOut[]> {
const all: ICompanyGroupOut[] = [];
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);
if (all.length >= page.total || page.items.length === 0) {
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 function createCompanyGroup(body: CreateCompanyGroupProps): Promise<void> {
export function createCompanyGroup(body: CompanyGroupFormProps): Promise<void> {
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`);
}

View File

@ -1,4 +1,4 @@
import { createSlice } from '@reduxjs/toolkit';
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { getCompanyGroupsThunk } from './thunks';
import type { CompanyGroupSliceType } from './types';
@ -6,13 +6,18 @@ const initialState: CompanyGroupSliceType = {
raw_rows: [],
total_groups: 0,
loading: false,
isGettingArchive: false,
error: null,
};
const comGroupsSlice = createSlice({
name: 'company_groups',
initialState,
reducers: {},
reducers: {
setIsGettingArchive(state, action: PayloadAction<boolean>) {
state.isGettingArchive = action.payload;
},
},
extraReducers: (builder) => {
builder
.addCase(getCompanyGroupsThunk.pending, (state) => {
@ -30,4 +35,6 @@ const comGroupsSlice = createSlice({
});
},
});
export const { setIsGettingArchive } = comGroupsSlice.actions;
export default comGroupsSlice.reducer;

View File

@ -1,14 +1,15 @@
import { createAsyncThunk } from '@reduxjs/toolkit';
import { fetchCompanyGroups } from '../../../services/api/directories/company_groups';
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',
async (_, thunkApi) => {
async (args = {}, thunkApi) => {
try {
return (await fetchCompanyGroups()).map(toCompanyGroupRow);
return (await fetchCompanyGroups(args)).map(toCompanyGroupRow);
} catch (e) {
return thunkApi.rejectWithValue(e instanceof Error ? e.message : 'Ошибка');
}
},
);
)

View File

@ -5,4 +5,9 @@ export interface CompanyGroupSliceType {
raw_rows: ICompanyGroup[];
loading: boolean;
error: string | null;
isGettingArchive: boolean;
}
export interface GetCompanyGroupsPropsI {
is_archived?: boolean;
}

View File

@ -21,6 +21,7 @@ export interface ICatalogueJur {
name: string;
is_head_office: boolean;
};
regional_name?:string;
}
export type KindType = 'gsk' | 'gsz';

View File

@ -6,6 +6,7 @@ export interface ICompanyGroupOut {
base_regional_office_id: string | null;
base_regional_office: { id: string; name: string; is_head_office: boolean } | null;
legal_entities_count: number;
is_archived:boolean;
}
/** Строка таблицы ГК: имя филиала плоским полем — по нему работают поиск и фильтры GenericTable. */
@ -18,7 +19,7 @@ export const toCompanyGroupRow = (g: ICompanyGroupOut): ICompanyGroup => ({
base_regional_office_name: g.base_regional_office?.name ?? '—',
});
export interface CreateCompanyGroupProps {
export interface CompanyGroupFormProps {
name: string;
crm_id: string;
base_regional_office_id: string | null;

View File

@ -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>
);
};

View File

@ -1,33 +1,74 @@
import { Space } from 'antd';
import { Button, Dropdown, Space } from 'antd';
import Text from 'antd/es/typography/Text';
import Title from 'antd/es/typography/Title';
import { useAppSelector } from '../../store/store';
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 count = activeCompanyGroup?.legal_entities_count ?? 0;
const navigate = useNavigate();
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 (
<div
<Space
style={{
padding: '6px 16px',
borderBottom: '1px solid #0f172a0f',
flexShrink: 0,
justifyContent: 'space-between',
}}>
<Title level={5} style={{ margin: 0 }}>
{activeCompanyGroup?.name ?? ''}
</Title>
<Space>
<Text type='secondary' style={{ fontSize: 13 }}>
{activeCompanyGroup?.base_regional_office_name ?? ''}
</Text>
<Text type='secondary' style={{ fontSize: 13 }}>
{count ?? 0} {organizationWord}
</Text>
</Space>
</div>
<div>
<Title level={5} style={{ margin: 0 }}>
{activeCompanyGroup?.name ?? ''}
</Title>
<Space>
<Text type='secondary' style={{ fontSize: 13 }}>
{activeCompanyGroup?.base_regional_office_name ?? ''}
</Text>
<Text type='secondary' style={{ fontSize: 13 }}>
{count ?? 0} {organizationWord}
</Text>
</Space>
</div>
<Dropdown menu={{ items }} trigger={['click']}>
<Button type='default' style={{ width: '32px' }}>
<EllipsisOutlined />
</Button>
</Dropdown>
</Space>
);
};

View File

@ -52,14 +52,16 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
const [editCatalogueFormOpen, setEditCatalogueFormOpen] = useState(false);
const [withdrawCatalogueFormOpen, setWithdrawCatalogueFormOpen] = useState(false);
const [jurId, setJurId] = useState('');
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
const filterdData = useMemo(() => {
let newData = rawRows
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 rawRows;
return newData?.map((elem) => elem && { ...elem, regional_name: elem?.regional_office?.name });
}, [rawRows, relatedGroupFilter, outside_group]);
const { visibleKeys, setVisibleKeys } = useVisibleColumns(catalogueJurConfig);
@ -67,7 +69,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
useTableFilters<ICatalogueJur>();
// single filtered array — title count and table share it
const { rows } = useFilteredRows(filterdData, catalogueJurConfig, rawQuery, columnFilters, sort);
function getCatalogueJur() {
dispatch(
getCatalogueJurThunk({
@ -95,7 +97,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
try {
await moveCatalogueJur(jurId, values);
getCatalogueJur();
dispatch(getCompanyGroupsThunk());
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
closeMoveCatalogueJurHandler();
} catch (e) {
if (e instanceof ApiError) {
@ -109,7 +111,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
try {
await withdrawCatalogueJur(jurId, values);
getCatalogueJur();
dispatch(getCompanyGroupsThunk());
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
closeWithdrawCatalogueJurHandler();
} catch (e) {
@ -128,7 +130,6 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
}
useEffect(() => {
// «ЮЛ вне ГК» грузится без выбранной ГК; список ГК — только по выбранной (без неё запрос ушёл бы по всем ГК)
if (outside_group || activeCompanyGroup?.id) {
getCatalogueJur();
}
@ -244,7 +245,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
justifyContent: 'space-between',
gap: 16,
padding: '10px 16px',
background: '#fff8e1', // светло-жёлтый фон
background: '#fff8e1',
borderTop: '1px solid #ffe58f',
borderBottom: '1px solid #ffe58f',
borderRadius: 8,

View File

@ -5,7 +5,7 @@ import type { ICatalogueJur } from '../../types/catalogueJur/catalogueJur';
export const catalogueJurConfig: TableConfig<ICatalogueJur> = {
rowKey: 'id',
searchableKeys: ['closed', 'inn', 'kpp', 'name', 'entity_type'],
searchableKeys: ['closed', 'inn', 'crm_id', 'kpp', 'name', 'entity_type', 'regional_name'],
columns: [
{
key: 'closed',
@ -18,6 +18,28 @@ export const catalogueJurConfig: TableConfig<ICatalogueJur> = {
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',
title: 'ИНН',
@ -43,9 +65,9 @@ export const catalogueJurConfig: TableConfig<ICatalogueJur> = {
},
},
{
key: 'regional_office',
key: 'regional_name',
title: 'Основной РФ',
render: (val) => (val as ICatalogueJur['regional_office'] | null)?.name,
features: { search: true, multiselect: true, sort: true },
},
],
};

View File

@ -3,26 +3,47 @@ import type React from 'react';
import { useEffect, useState } from 'react';
import { ApiError } from '../../api/client';
import { useMe } from '../../auth/useMe';
import { useAppSelector } from '../../store/store';
import type { CreateCompanyGroupProps } from '../../types/companyGroups/companyGroups';
import type { CompanyGroupFormProps } from '../../types/companyGroups/companyGroups';
import { useNotificationApi } from '../../utils/useNotification';
import { loadOffices } from '../Admin/UsersTable';
import { fetchOneCompanyGroup } from '../../services/api/directories/company_groups';
type Props = {
open: boolean;
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 }) => {
const [form] = Form.useForm<CreateCompanyGroupProps>();
export const CompanyGroupForm: React.FC<Props> = ({ open, onCancel, onOk, companyGroupId }) => {
const [form] = Form.useForm<CompanyGroupFormProps>();
const { me } = useMe();
const notification = useNotificationApi();
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
const [officesOptions, setOfficesOptions] = useState<{ value: string; label: string }[]>([]);
const [loadingOptions, setLoadingOptions] = 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() {
setLoadingOptions(true);
@ -45,6 +66,7 @@ export const CompanyGroupForm: React.FC<Props> = ({ open, onCancel, onOk }) => {
const values = await form.validateFields();
await onOk({
...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),
});
} catch (e) {
@ -72,18 +94,20 @@ export const CompanyGroupForm: React.FC<Props> = ({ open, onCancel, onOk }) => {
};
useEffect(() => {
getInitialData();
getOfficesOptionsHandler();
}, [activeCompanyGroup]);
}, []);
return (
<Modal
title='Создать группу компаний'
title={`${companyGroupId ? 'Редактировать' : 'Создать'} группу компаний`}
open={open}
onCancel={handleCancel}
onOk={handleOk}
okText='Создать'
okText={`${companyGroupId ? 'Редактировать' : 'Создать'}`}
cancelText='Отмена'
destroyOnHidden
loading={initialDataLoading}
confirmLoading={confirmLoading}
width={720}>
<Form form={form} layout='vertical'>

View File

@ -1,10 +1,11 @@
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 { useVirtualList } from '../../hooks/useVirtualList';
import { setActiveCompanyGroup } from '../../store/slices/catalogueJurSlice/catalogueJurSlice';
import { getCompanyGroupsThunk } from '../../store/slices/companyGroupsSlice/thunks';
import { useAppDispatch, useAppSelector } from '../../store/store';
import { setIsGettingArchive } from '../../store/slices/companyGroupsSlice/companyGroupsSlice';
const { Text } = Typography;
@ -14,7 +15,7 @@ export const CompanyGroupsList = () => {
const rawRows = useAppSelector((state) => state.company_groups.raw_rows);
const loading = useAppSelector((state) => state.company_groups.loading);
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
const [query, setQuery] = useState('');
const filtered = useMemo(() => {
@ -30,8 +31,8 @@ export const CompanyGroupsList = () => {
});
useEffect(() => {
dispatch(getCompanyGroupsThunk());
}, [dispatch]);
dispatch(getCompanyGroupsThunk({is_archived:isGettingArchiveCompany}));
}, [dispatch, isGettingArchiveCompany]);
useEffect(() => {
if (!activeCompanyGroup && rawRows?.length) {
@ -57,7 +58,7 @@ export const CompanyGroupsList = () => {
borderRight: '1px solid #f0f0f0',
borderRadius: 12,
}}>
<div style={{ padding: 12 }}>
<Space style={{ padding: 12 }}>
<Input
allowClear
prefix={<SearchOutlined style={{ color: '#bfbfbf' }} />}
@ -65,7 +66,10 @@ export const CompanyGroupsList = () => {
value={query}
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' }}>
{filtered.length === 0 ? (

View File

@ -29,6 +29,7 @@ export const MoveCatalogueJurForm: React.FC<Props> = ({ open, onCancel, onOk, ju
const [form] = Form.useForm<FormValues>();
const dispatch = useAppDispatch();
const notification = useNotificationApi();
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
const { raw_rows, loading } = useAppSelector((state) => state.company_groups);
const [initialDataLoading, setInitialDataLoading] = useState(false);
@ -76,7 +77,7 @@ export const MoveCatalogueJurForm: React.FC<Props> = ({ open, onCancel, onOk, ju
};
useEffect(() => {
if (open && raw_rows.length === 0 && !loading) {
dispatch(getCompanyGroupsThunk());
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
}
}, [open, raw_rows.length, loading, dispatch]);

View File

@ -27,6 +27,7 @@ export const RelatedGroupForm: React.FC<Props> = ({ open, onCancel, onOk, relate
const companyGrops = useAppSelector((state) => state.company_groups.raw_rows);
const companyGropsLoading = useAppSelector((state) => state.company_groups.loading);
const activeCompanyGroup = useAppSelector((state) => state.catalogue_jur.activeCompanyGroup);
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
async function getInitialData() {
if (!relatedGroupId) {
@ -38,7 +39,8 @@ export const RelatedGroupForm: React.FC<Props> = ({ open, onCancel, onOk, relate
setInitialDataLoading(true);
try {
const data = await fetchRelatedGroup(relatedGroupId);
await dispatch(getCompanyGroupsThunk());
await dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
form.setFieldsValue({
crm_id: data?.crm_id,
name: data?.name,

View File

@ -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 type { ColumnsType } from 'antd/es/table';
import { type ReactNode, useMemo, useState } from 'react';
@ -77,6 +77,7 @@ export function RelatedGroupTable({ tabsComponent, data, loading, getData, activ
const items = [
{
key: 'edit',
icon: <EditOutlined />,
label: 'Изменить',
onClick: () => {
setGroupId(row.id);
@ -85,6 +86,7 @@ export function RelatedGroupTable({ tabsComponent, data, loading, getData, activ
},
{
key: 'delete',
icon: <DeleteOutlined />,
label: 'Удалить',
danger: true,
onClick: () => {