AURORA-1636/1693: правки ревью — архив ГК только фильтр списка справочника
- список ГК в сторе снова общий и полный (с архивными); «Архив» фильтрует только список справочника, выбор ГК — первая показанная, пустой список — «Группа компаний не выбрана» - перенос ЮЛ и новая консолидация не предлагают архивные ГК - «Входит в ГСК/ГСЗ» — поля строки in_gsk/in_gsz, колонки только в карточке ГК (не в «ЮЛ вне ГК») - «Архивировать» красным, а не «Разархивировать»; тексты модалки и кнопка «Сохранить» в изменении ГК - вернул поясняющие комментарии; поиск ГК не сжимается галочкой «Архив» - тесты: selectors (видимые ГК, выбор ГК), toCatalogueJurRow Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7e72a63b16
commit
57e54e4055
@ -1,6 +1,6 @@
|
|||||||
import { PlusOutlined } from '@ant-design/icons';
|
import { PlusOutlined } from '@ant-design/icons';
|
||||||
import { Button, Space } from 'antd';
|
import { Button, Empty, Space } from 'antd';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useMemo, 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';
|
||||||
@ -14,6 +14,7 @@ import {
|
|||||||
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';
|
||||||
|
import { nextActiveCompanyGroup, visibleCompanyGroups } from '../store/slices/companyGroupsSlice/selectors';
|
||||||
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 type { RelatedGroupOut } from '../types/api';
|
import type { RelatedGroupOut } from '../types/api';
|
||||||
@ -50,11 +51,13 @@ export function CatalogueGroup() {
|
|||||||
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 companyGroupsLoading = useAppSelector((state) => state.company_groups.loading);
|
||||||
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
|
const isGettingArchiveCompany = useAppSelector((state) => state.company_groups.isGettingArchive);
|
||||||
|
const visibleGroups = useMemo(() => visibleCompanyGroups(rawRows, isGettingArchiveCompany), [rawRows, isGettingArchiveCompany]);
|
||||||
|
|
||||||
async function createJurHandler(values: CatalogueJurFormProps) {
|
async function createJurHandler(values: CatalogueJurFormProps) {
|
||||||
await createCatalogueJur(values);
|
await createCatalogueJur(values);
|
||||||
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
dispatch(getCompanyGroupsThunk());
|
||||||
dispatch(
|
dispatch(
|
||||||
getCatalogueJurThunk({
|
getCatalogueJurThunk({
|
||||||
closed: isGettingArchive,
|
closed: isGettingArchive,
|
||||||
@ -76,13 +79,13 @@ export function CatalogueGroup() {
|
|||||||
}
|
}
|
||||||
async function createCompanyGroupHandler(values: CompanyGroupFormProps) {
|
async function createCompanyGroupHandler(values: CompanyGroupFormProps) {
|
||||||
await createCompanyGroup(values);
|
await createCompanyGroup(values);
|
||||||
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
dispatch(getCompanyGroupsThunk());
|
||||||
setKindForm(null);
|
setKindForm(null);
|
||||||
}
|
}
|
||||||
async function editCompanyGroupHandler(values: CompanyGroupFormProps) {
|
async function editCompanyGroupHandler(values: CompanyGroupFormProps) {
|
||||||
if (activeCompanyGroup?.id) {
|
if (activeCompanyGroup?.id) {
|
||||||
await editCompanyGroup(activeCompanyGroup?.id, values);
|
await editCompanyGroup(activeCompanyGroup?.id, values);
|
||||||
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
dispatch(getCompanyGroupsThunk());
|
||||||
setCompanyGroupEditFormOpen(false);
|
setCompanyGroupEditFormOpen(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,11 +97,11 @@ export function CatalogueGroup() {
|
|||||||
try {
|
try {
|
||||||
setCompanyGroupDeleteLoading(true);
|
setCompanyGroupDeleteLoading(true);
|
||||||
if (activeCompanyGroup?.is_archived) {
|
if (activeCompanyGroup?.is_archived) {
|
||||||
await unarchiveCompanyGroup(activeCompanyGroup?.id);
|
await unarchiveCompanyGroup(activeCompanyGroup.id);
|
||||||
} else {
|
} else {
|
||||||
await archiveCompanyGroup(activeCompanyGroup.id);
|
await archiveCompanyGroup(activeCompanyGroup.id);
|
||||||
}
|
}
|
||||||
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
dispatch(getCompanyGroupsThunk());
|
||||||
|
|
||||||
setCompanyGroupDeleteOpen(false);
|
setCompanyGroupDeleteOpen(false);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -135,11 +138,18 @@ export function CatalogueGroup() {
|
|||||||
getRelatedGroupsHandler();
|
getRelatedGroupsHandler();
|
||||||
}, [activeCompanyGroup]);
|
}, [activeCompanyGroup]);
|
||||||
|
|
||||||
|
// Без выбранной ГК таблица ЮЛ не грузится — выбираем первую ГК показанного списка; выбранная, ушедшая в архив
|
||||||
|
// (или из архива) или скрытая переключением «Архива», заменяется первой показанной, пустой список — без выбора
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!activeCompanyGroup && rawRows?.length) {
|
// список ГК ещё не загружен — выбор не трогаем (при возврате на экран остаётся прежняя ГК)
|
||||||
dispatch(setActiveCompanyGroup(rawRows[0]));
|
if (companyGroupsLoading || rawRows.length === 0) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}, [rawRows, activeCompanyGroup, dispatch]);
|
const next = nextActiveCompanyGroup(activeCompanyGroup, visibleGroups);
|
||||||
|
if (next?.id !== activeCompanyGroup?.id) {
|
||||||
|
dispatch(setActiveCompanyGroup(next));
|
||||||
|
}
|
||||||
|
}, [visibleGroups, activeCompanyGroup, companyGroupsLoading, rawRows.length, dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setActiveTab('legal_entities');
|
setActiveTab('legal_entities');
|
||||||
@ -181,8 +191,13 @@ export function CatalogueGroup() {
|
|||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
}}>
|
}}>
|
||||||
<CompanyGroupHeader setDeleteConfirmOpen={setCompanyGroupDeleteOpen} setEditFormOpen={setCompanyGroupEditFormOpen} />
|
{!activeCompanyGroup && (
|
||||||
{activeTab === 'legal_entities' && (
|
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description='Группа компаний не выбрана' style={{ marginTop: 64 }} />
|
||||||
|
)}
|
||||||
|
{activeCompanyGroup && (
|
||||||
|
<CompanyGroupHeader setDeleteConfirmOpen={setCompanyGroupDeleteOpen} setEditFormOpen={setCompanyGroupEditFormOpen} />
|
||||||
|
)}
|
||||||
|
{activeCompanyGroup && activeTab === 'legal_entities' && (
|
||||||
<CatalogueJurTable
|
<CatalogueJurTable
|
||||||
outside_group={false}
|
outside_group={false}
|
||||||
tabsComponent={
|
tabsComponent={
|
||||||
@ -190,7 +205,7 @@ export function CatalogueGroup() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{(activeTab === 'gsk' || activeTab === 'gsz') && (
|
{activeCompanyGroup && (activeTab === 'gsk' || activeTab === 'gsz') && (
|
||||||
<RelatedGroupTable
|
<RelatedGroupTable
|
||||||
activeTab={activeTab}
|
activeTab={activeTab}
|
||||||
data={activeTab === 'gsz' ? gszData : gskData}
|
data={activeTab === 'gsz' ? gszData : gskData}
|
||||||
@ -241,14 +256,14 @@ export function CatalogueGroup() {
|
|||||||
onOk={createCompanyGroupHandler}
|
onOk={createCompanyGroupHandler}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{companyGroupEditFormOpen && (
|
{companyGroupEditFormOpen && activeCompanyGroup && (
|
||||||
<CompanyGroupForm
|
<CompanyGroupForm
|
||||||
open={companyGroupEditFormOpen}
|
open={companyGroupEditFormOpen}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setCompanyGroupEditFormOpen(false);
|
setCompanyGroupEditFormOpen(false);
|
||||||
}}
|
}}
|
||||||
onOk={editCompanyGroupHandler}
|
onOk={editCompanyGroupHandler}
|
||||||
companyGroupId={activeCompanyGroup?.id}
|
companyGroupId={activeCompanyGroup.id}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{companyGroupDeleteOpen && activeCompanyGroup && (
|
{companyGroupDeleteOpen && activeCompanyGroup && (
|
||||||
@ -257,7 +272,7 @@ export function CatalogueGroup() {
|
|||||||
loading={companyGroupDeleteLoading}
|
loading={companyGroupDeleteLoading}
|
||||||
onCancel={() => setCompanyGroupDeleteOpen(false)}
|
onCancel={() => setCompanyGroupDeleteOpen(false)}
|
||||||
onOk={archiveCompanyGroupHandler}
|
onOk={archiveCompanyGroupHandler}
|
||||||
isArchived={activeCompanyGroup?.is_archived}
|
isArchived={activeCompanyGroup.is_archived}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,20 +1,15 @@
|
|||||||
import { api } from '../../../api/client';
|
import { api } from '../../../api/client';
|
||||||
import type { 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 { CompanyGroupFormProps, 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. */
|
/** Все видимые ГК, в том числе архивные (`is_archived`), — дочитываем страницы, пока не получим total. */
|
||||||
export async function fetchCompanyGroups(params: GetCompanyGroupsPropsI): Promise<ICompanyGroupOut[]> {
|
export async function fetchCompanyGroups(): 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', {
|
const page = await api.get<Page<ICompanyGroupOut>>(`/directories/company-groups?limit=${CG_PAGE}&offset=${offset}`);
|
||||||
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;
|
||||||
|
|||||||
45
web/src/store/slices/companyGroupsSlice/selectors.test.ts
Normal file
45
web/src/store/slices/companyGroupsSlice/selectors.test.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import type { ICompanyGroup } from '../../../types/companyGroups/companyGroups';
|
||||||
|
import { nextActiveCompanyGroup, visibleCompanyGroups } from './selectors';
|
||||||
|
|
||||||
|
const group = (id: string, is_archived: boolean): ICompanyGroup => ({
|
||||||
|
id,
|
||||||
|
name: id,
|
||||||
|
crm_id: null,
|
||||||
|
base_regional_office_id: null,
|
||||||
|
base_regional_office: null,
|
||||||
|
legal_entities_count: 0,
|
||||||
|
is_archived,
|
||||||
|
base_regional_office_name: '—',
|
||||||
|
});
|
||||||
|
|
||||||
|
const active1 = group('a1', false);
|
||||||
|
const active2 = group('a2', false);
|
||||||
|
const archived1 = group('z1', true);
|
||||||
|
const rows = [active1, archived1, active2];
|
||||||
|
|
||||||
|
describe('visibleCompanyGroups', () => {
|
||||||
|
it('без «Архива» — только действующие ГК, с «Архивом» — только архивные', () => {
|
||||||
|
expect(visibleCompanyGroups(rows, false)).toEqual([active1, active2]);
|
||||||
|
expect(visibleCompanyGroups(rows, true)).toEqual([archived1]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('nextActiveCompanyGroup', () => {
|
||||||
|
it('выбранная ГК в показанном списке остаётся', () => {
|
||||||
|
expect(nextActiveCompanyGroup(active2, [active1, active2])).toBe(active2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('без выбранной ГК берётся первая показанная', () => {
|
||||||
|
expect(nextActiveCompanyGroup(null, [active1, active2])).toBe(active1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ГК ушла в архив — выбирается первая действующая', () => {
|
||||||
|
expect(nextActiveCompanyGroup({ ...active1, is_archived: true }, [active2])).toBe(active2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('пустой список — ГК не выбрана', () => {
|
||||||
|
expect(nextActiveCompanyGroup(active1, [])).toBeNull();
|
||||||
|
expect(nextActiveCompanyGroup(null, [])).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
17
web/src/store/slices/companyGroupsSlice/selectors.ts
Normal file
17
web/src/store/slices/companyGroupsSlice/selectors.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import type { ICompanyGroup } from '../../../types/companyGroups/companyGroups';
|
||||||
|
|
||||||
|
/** ГК списка справочника: действующие или, при включённом «Архиве», только архивные. */
|
||||||
|
export function visibleCompanyGroups(rows: ICompanyGroup[], archived: boolean): ICompanyGroup[] {
|
||||||
|
return rows.filter((group) => group.is_archived === archived);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Какая ГК должна быть выбрана в справочнике: выбранная — пока она в показанном списке; иначе (ушла в архив, вернулась
|
||||||
|
* из архива, скрыта переключением «Архива») — первая показанная, а в пустом списке — никакая.
|
||||||
|
*/
|
||||||
|
export function nextActiveCompanyGroup(active: ICompanyGroup | null | undefined, visible: ICompanyGroup[]): ICompanyGroup | null {
|
||||||
|
if (active && visible.some((group) => group.id === active.id)) {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
return visible[0] ?? null;
|
||||||
|
}
|
||||||
@ -1,13 +1,12 @@
|
|||||||
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 type { GetCompanyGroupsPropsI } from './types';
|
|
||||||
|
|
||||||
export const getCompanyGroupsThunk = createAsyncThunk<ICompanyGroup[], GetCompanyGroupsPropsI | undefined, { rejectValue: string }>(
|
export const getCompanyGroupsThunk = createAsyncThunk<ICompanyGroup[], void, { rejectValue: string }>(
|
||||||
'company_groups/getAll',
|
'company_groups/getAll',
|
||||||
async (args, thunkApi) => {
|
async (_, thunkApi) => {
|
||||||
try {
|
try {
|
||||||
return (await fetchCompanyGroups(args || {})).map(toCompanyGroupRow);
|
return (await fetchCompanyGroups()).map(toCompanyGroupRow);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return thunkApi.rejectWithValue(e instanceof Error ? e.message : 'Ошибка');
|
return thunkApi.rejectWithValue(e instanceof Error ? e.message : 'Ошибка');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,9 +5,6 @@ export interface CompanyGroupSliceType {
|
|||||||
raw_rows: ICompanyGroup[];
|
raw_rows: ICompanyGroup[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
error: string | null;
|
error: string | null;
|
||||||
|
/** Список справочника показывает архивные ГК вместо действующих; `raw_rows` при этом не меняется. */
|
||||||
isGettingArchive: boolean;
|
isGettingArchive: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GetCompanyGroupsPropsI {
|
|
||||||
is_archived?: boolean;
|
|
||||||
}
|
|
||||||
|
|||||||
34
web/src/types/catalogueJur/catalogueJur.test.ts
Normal file
34
web/src/types/catalogueJur/catalogueJur.test.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { type ICatalogueJur, type MemberShips, toCatalogueJurRow } from './catalogueJur';
|
||||||
|
|
||||||
|
const member = (kind: MemberShips['kind']): MemberShips => ({
|
||||||
|
related_group_id: kind,
|
||||||
|
code: kind,
|
||||||
|
kind,
|
||||||
|
name: kind,
|
||||||
|
valid_from: new Date('2026-01-01'),
|
||||||
|
});
|
||||||
|
|
||||||
|
const row = (memberships?: MemberShips[]): ICatalogueJur =>
|
||||||
|
({
|
||||||
|
id: 'le-1',
|
||||||
|
inn: '7701000040',
|
||||||
|
entity_type: 'ЮЛ',
|
||||||
|
name: 'ООО «Тест»',
|
||||||
|
company_group_name: null,
|
||||||
|
closed: false,
|
||||||
|
regional_office: { id: 'ro-1', name: 'Ростовский РФ', is_head_office: false },
|
||||||
|
memberships,
|
||||||
|
}) as ICatalogueJur;
|
||||||
|
|
||||||
|
describe('toCatalogueJurRow', () => {
|
||||||
|
it('имя РФ — плоским полем для поиска и фильтра', () => {
|
||||||
|
expect(toCatalogueJurRow(row()).regional_name).toBe('Ростовский РФ');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('признаки ГСК и ГСЗ — по видам членства', () => {
|
||||||
|
expect(toCatalogueJurRow(row([member('gsk')]))).toMatchObject({ in_gsk: true, in_gsz: false });
|
||||||
|
expect(toCatalogueJurRow(row([member('gsz')]))).toMatchObject({ in_gsk: false, in_gsz: true });
|
||||||
|
expect(toCatalogueJurRow(row())).toMatchObject({ in_gsk: false, in_gsz: false });
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -21,9 +21,19 @@ export interface ICatalogueJur {
|
|||||||
name: string;
|
name: string;
|
||||||
is_head_office: boolean;
|
is_head_office: boolean;
|
||||||
};
|
};
|
||||||
|
/** Плоские поля строки таблицы (`toCatalogueJurRow`): по ним работают поиск, фильтры и колонки GenericTable. */
|
||||||
regional_name?: string;
|
regional_name?: string;
|
||||||
|
in_gsk?: boolean;
|
||||||
|
in_gsz?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const toCatalogueJurRow = (row: ICatalogueJur): ICatalogueJur => ({
|
||||||
|
...row,
|
||||||
|
regional_name: row.regional_office?.name,
|
||||||
|
in_gsk: row.memberships?.some((member) => member.kind === 'gsk') ?? false,
|
||||||
|
in_gsz: row.memberships?.some((member) => member.kind === 'gsz') ?? false,
|
||||||
|
});
|
||||||
|
|
||||||
export type KindType = 'gsk' | 'gsz';
|
export type KindType = 'gsk' | 'gsz';
|
||||||
|
|
||||||
export type MemberShips = {
|
export type MemberShips = {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ type Props = {
|
|||||||
export const ArchiveCompanyGroupModal: React.FC<Props> = ({ open, onCancel, onOk, loading, isArchived }) => {
|
export const ArchiveCompanyGroupModal: React.FC<Props> = ({ open, onCancel, onOk, loading, isArchived }) => {
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={isArchived ? 'Разархивировать' : 'Архивировать'}
|
title={isArchived ? 'Разархивировать ГК' : 'Архивировать ГК'}
|
||||||
open={open}
|
open={open}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
onOk={onOk}
|
onOk={onOk}
|
||||||
@ -20,7 +20,9 @@ export const ArchiveCompanyGroupModal: React.FC<Props> = ({ open, onCancel, onOk
|
|||||||
okButtonProps={isArchived ? undefined : { danger: true }}
|
okButtonProps={isArchived ? undefined : { danger: true }}
|
||||||
confirmLoading={loading}
|
confirmLoading={loading}
|
||||||
centered>
|
centered>
|
||||||
<p style={{ margin: 0, color: '#595959' }}>Группа компании будет {isArchived ? 'разархивированна' : 'архивированна'}</p>
|
<p style={{ margin: 0, color: '#595959' }}>
|
||||||
|
{isArchived ? 'Группа компаний вернётся из архива в список действующих.' : 'Группа компаний будет перенесена в архив.'}
|
||||||
|
</p>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -36,7 +36,7 @@ export const CompanyGroupHeader = ({ setEditFormOpen, setDeleteConfirmOpen }: Co
|
|||||||
key: 'delete',
|
key: 'delete',
|
||||||
icon: activeCompanyGroup?.is_archived ? <CheckCircleOutlined /> : <DeleteOutlined />,
|
icon: activeCompanyGroup?.is_archived ? <CheckCircleOutlined /> : <DeleteOutlined />,
|
||||||
label: activeCompanyGroup?.is_archived ? 'Разархивировать' : 'Архивировать',
|
label: activeCompanyGroup?.is_archived ? 'Разархивировать' : 'Архивировать',
|
||||||
danger: activeCompanyGroup?.is_archived,
|
danger: !activeCompanyGroup?.is_archived,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setDeleteConfirmOpen(true);
|
setDeleteConfirmOpen(true);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -19,18 +19,19 @@ import { setIsGettingArchive, setRelatedGroupFilter } from '../../store/slices/c
|
|||||||
import { getCatalogueJurThunk } from '../../store/slices/catalogueJurSlice/thunks';
|
import { getCatalogueJurThunk } from '../../store/slices/catalogueJurSlice/thunks';
|
||||||
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 type {
|
import {
|
||||||
CatalogueJurFormProps,
|
type CatalogueJurFormProps,
|
||||||
ICatalogueJur,
|
type ICatalogueJur,
|
||||||
MoveCatalogueJurProps,
|
type MoveCatalogueJurProps,
|
||||||
WithdrawCatalogueJurProps,
|
type WithdrawCatalogueJurProps,
|
||||||
|
toCatalogueJurRow,
|
||||||
} from '../../types/catalogueJur/catalogueJur';
|
} from '../../types/catalogueJur/catalogueJur';
|
||||||
import { pluralRu } from '../../utils/labels';
|
import { pluralRu } from '../../utils/labels';
|
||||||
import { useNotificationApi } from '../../utils/useNotification';
|
import { useNotificationApi } from '../../utils/useNotification';
|
||||||
import { CatalogueJurForm } from '../CatalogueJurForm/CatalogueJurForm';
|
import { CatalogueJurForm } from '../CatalogueJurForm/CatalogueJurForm';
|
||||||
import { MoveCatalogueJurForm } from '../MoveCatalogueJurForm/MoveCatalogueJurForm';
|
import { MoveCatalogueJurForm } from '../MoveCatalogueJurForm/MoveCatalogueJurForm';
|
||||||
import { WithdrawCatalogueJurForm } from '../WithdrawCatalogueJurForm/WithdrawCatalogueJurForm';
|
import { WithdrawCatalogueJurForm } from '../WithdrawCatalogueJurForm/WithdrawCatalogueJurForm';
|
||||||
import { catalogueJurConfig } from './config';
|
import { catalogueJurConfig, companyGroupJurConfig } from './config';
|
||||||
|
|
||||||
interface CatalogueJurTableI {
|
interface CatalogueJurTableI {
|
||||||
outside_group: boolean;
|
outside_group: boolean;
|
||||||
@ -52,7 +53,7 @@ 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 tableConfig = outside_group ? catalogueJurConfig : companyGroupJurConfig;
|
||||||
|
|
||||||
const filterdData = useMemo(() => {
|
const filterdData = useMemo(() => {
|
||||||
let newData = rawRows;
|
let newData = rawRows;
|
||||||
@ -61,14 +62,14 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
return row?.memberships?.some((member) => member.related_group_id === relatedGroupFilter.id);
|
return row?.memberships?.some((member) => member.related_group_id === relatedGroupFilter.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return newData?.map((elem) => elem && { ...elem, regional_name: elem?.regional_office?.name });
|
return newData?.map((elem) => elem && toCatalogueJurRow(elem));
|
||||||
}, [rawRows, relatedGroupFilter, outside_group]);
|
}, [rawRows, relatedGroupFilter, outside_group]);
|
||||||
|
|
||||||
const { visibleKeys, setVisibleKeys } = useVisibleColumns(catalogueJurConfig);
|
const { visibleKeys, setVisibleKeys } = useVisibleColumns(tableConfig);
|
||||||
const { rawQuery, setRawQuery, columnFilters, setColumnFilters, sort, setSort, resetAll, hasActiveFilters } =
|
const { rawQuery, setRawQuery, columnFilters, setColumnFilters, sort, setSort, resetAll, hasActiveFilters } =
|
||||||
useTableFilters<ICatalogueJur>();
|
useTableFilters<ICatalogueJur>();
|
||||||
// single filtered array — title count and table share it
|
// single filtered array — title count and table share it
|
||||||
const { rows } = useFilteredRows(filterdData, catalogueJurConfig, rawQuery, columnFilters, sort);
|
const { rows } = useFilteredRows(filterdData, tableConfig, rawQuery, columnFilters, sort);
|
||||||
|
|
||||||
function getCatalogueJur() {
|
function getCatalogueJur() {
|
||||||
dispatch(
|
dispatch(
|
||||||
@ -97,7 +98,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
try {
|
try {
|
||||||
await moveCatalogueJur(jurId, values);
|
await moveCatalogueJur(jurId, values);
|
||||||
getCatalogueJur();
|
getCatalogueJur();
|
||||||
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
dispatch(getCompanyGroupsThunk());
|
||||||
closeMoveCatalogueJurHandler();
|
closeMoveCatalogueJurHandler();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof ApiError) {
|
if (e instanceof ApiError) {
|
||||||
@ -111,7 +112,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
try {
|
try {
|
||||||
await withdrawCatalogueJur(jurId, values);
|
await withdrawCatalogueJur(jurId, values);
|
||||||
getCatalogueJur();
|
getCatalogueJur();
|
||||||
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
dispatch(getCompanyGroupsThunk());
|
||||||
|
|
||||||
closeWithdrawCatalogueJurHandler();
|
closeWithdrawCatalogueJurHandler();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -130,6 +131,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// «ЮЛ вне ГК» грузится без выбранной ГК; список ГК — только по выбранной (без неё запрос ушёл бы по всем ГК)
|
||||||
if (outside_group || activeCompanyGroup?.id) {
|
if (outside_group || activeCompanyGroup?.id) {
|
||||||
getCatalogueJur();
|
getCatalogueJur();
|
||||||
}
|
}
|
||||||
@ -234,7 +236,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
<Checkbox checked={isGettingArchive} onChange={(e) => dispatch(setIsGettingArchive(e.target.checked))}>
|
<Checkbox checked={isGettingArchive} onChange={(e) => dispatch(setIsGettingArchive(e.target.checked))}>
|
||||||
Архив
|
Архив
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
<ColumnSettings defs={catalogueJurConfig.columns} visibleKeys={visibleKeys} onChange={setVisibleKeys} />
|
<ColumnSettings defs={tableConfig.columns} visibleKeys={visibleKeys} onChange={setVisibleKeys} />
|
||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
{relatedGroupFilter?.id && !outside_group && (
|
{relatedGroupFilter?.id && !outside_group && (
|
||||||
@ -245,7 +247,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,
|
||||||
@ -282,7 +284,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
<DataTable
|
<DataTable
|
||||||
sortState={sort}
|
sortState={sort}
|
||||||
onSortChange={setSort}
|
onSortChange={setSort}
|
||||||
config={catalogueJurConfig}
|
config={tableConfig}
|
||||||
rows={rows}
|
rows={rows}
|
||||||
allRows={rawRows}
|
allRows={rawRows}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { TableTag } from '../../components/TableTag/TableTag';
|
|||||||
import { TAG_PRESETS } from '../../components/TableTag/presets';
|
import { TAG_PRESETS } from '../../components/TableTag/presets';
|
||||||
import type { ICatalogueJur } from '../../types/catalogueJur/catalogueJur';
|
import type { ICatalogueJur } from '../../types/catalogueJur/catalogueJur';
|
||||||
|
|
||||||
|
/** ЮЛ вне ГК (монозаёмщики): в ГСК/ГСЗ они не входят, колонок членства нет. */
|
||||||
export const catalogueJurConfig: TableConfig<ICatalogueJur> = {
|
export const catalogueJurConfig: TableConfig<ICatalogueJur> = {
|
||||||
rowKey: 'id',
|
rowKey: 'id',
|
||||||
searchableKeys: ['closed', 'inn', 'crm_id', 'kpp', 'name', 'entity_type', 'regional_name'],
|
searchableKeys: ['closed', 'inn', 'crm_id', 'kpp', 'name', 'entity_type', 'regional_name'],
|
||||||
@ -18,28 +19,6 @@ 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: 'ИНН',
|
||||||
@ -71,3 +50,23 @@ export const catalogueJurConfig: TableConfig<ICatalogueJur> = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const membershipColumn = (key: 'in_gsk' | 'in_gsz', title: string) => ({
|
||||||
|
key,
|
||||||
|
title,
|
||||||
|
render: (value: unknown) => {
|
||||||
|
const preset = value ? TAG_PRESETS.green : TAG_PRESETS.gray;
|
||||||
|
return <TableTag text={value ? 'Входит' : 'Не входит'} {...preset} />;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/** ЮЛ карточки ГК: после статуса — признаки «Входит в ГСК» / «Входит в ГСЗ» (поля строки из `toCatalogueJurRow`). */
|
||||||
|
export const companyGroupJurConfig: TableConfig<ICatalogueJur> = {
|
||||||
|
...catalogueJurConfig,
|
||||||
|
columns: [
|
||||||
|
catalogueJurConfig.columns[0],
|
||||||
|
membershipColumn('in_gsk', 'Входит в ГСК'),
|
||||||
|
membershipColumn('in_gsz', 'Входит в ГСЗ'),
|
||||||
|
...catalogueJurConfig.columns.slice(1),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|||||||
@ -100,11 +100,11 @@ export const CompanyGroupForm: React.FC<Props> = ({ open, onCancel, onOk, compan
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={`${companyGroupId ? 'Редактировать' : 'Создать'} группу компаний`}
|
title={companyGroupId ? 'Изменить группу компаний' : 'Создать группу компаний'}
|
||||||
open={open}
|
open={open}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
onOk={handleOk}
|
onOk={handleOk}
|
||||||
okText={`${companyGroupId ? 'Редактировать' : 'Создать'}`}
|
okText={companyGroupId ? 'Сохранить' : 'Создать'}
|
||||||
cancelText='Отмена'
|
cancelText='Отмена'
|
||||||
destroyOnHidden
|
destroyOnHidden
|
||||||
loading={initialDataLoading}
|
loading={initialDataLoading}
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import { FolderOpenOutlined, SearchOutlined } from '@ant-design/icons';
|
import { FolderOpenOutlined, SearchOutlined } from '@ant-design/icons';
|
||||||
import { Checkbox, Empty, Input, List, Space, Spin, Tag, Typography } from 'antd';
|
import { Checkbox, Empty, Input, List, 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 { setIsGettingArchive } from '../../store/slices/companyGroupsSlice/companyGroupsSlice';
|
import { setIsGettingArchive } from '../../store/slices/companyGroupsSlice/companyGroupsSlice';
|
||||||
|
import { visibleCompanyGroups } from '../../store/slices/companyGroupsSlice/selectors';
|
||||||
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';
|
||||||
|
|
||||||
@ -19,10 +20,11 @@ export const CompanyGroupsList = () => {
|
|||||||
const [query, setQuery] = useState('');
|
const [query, setQuery] = useState('');
|
||||||
|
|
||||||
const filtered = useMemo(() => {
|
const filtered = useMemo(() => {
|
||||||
|
const rows = visibleCompanyGroups(rawRows, isGettingArchiveCompany);
|
||||||
const q = query.trim().toLowerCase();
|
const q = query.trim().toLowerCase();
|
||||||
if (!q) return rawRows;
|
if (!q) return rows;
|
||||||
return rawRows.filter((g) => g.name.toLowerCase().includes(q) || g.crm_id?.toLowerCase().includes(q));
|
return rows.filter((g) => g.name.toLowerCase().includes(q) || g.crm_id?.toLowerCase().includes(q));
|
||||||
}, [rawRows, query]);
|
}, [rawRows, isGettingArchiveCompany, query]);
|
||||||
|
|
||||||
const { ref, onScroll, visibleItems, totalHeight, offsetY } = useVirtualList(filtered, {
|
const { ref, onScroll, visibleItems, totalHeight, offsetY } = useVirtualList(filtered, {
|
||||||
itemHeight: 56,
|
itemHeight: 56,
|
||||||
@ -31,14 +33,8 @@ export const CompanyGroupsList = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(getCompanyGroupsThunk({ is_archived: isGettingArchiveCompany }));
|
dispatch(getCompanyGroupsThunk());
|
||||||
}, [dispatch, isGettingArchiveCompany]);
|
}, [dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!activeCompanyGroup && rawRows?.length) {
|
|
||||||
dispatch(setActiveCompanyGroup(rawRows?.[0]));
|
|
||||||
}
|
|
||||||
}, [rawRows, activeCompanyGroup, dispatch]);
|
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
@ -58,18 +54,19 @@ export const CompanyGroupsList = () => {
|
|||||||
borderRight: '1px solid #f0f0f0',
|
borderRight: '1px solid #f0f0f0',
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
}}>
|
}}>
|
||||||
<Space style={{ padding: 12 }}>
|
<div style={{ padding: 12, display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||||
<Input
|
<Input
|
||||||
allowClear
|
allowClear
|
||||||
prefix={<SearchOutlined style={{ color: '#bfbfbf' }} />}
|
prefix={<SearchOutlined style={{ color: '#bfbfbf' }} />}
|
||||||
placeholder='Поиск по ГК или CRM ID'
|
placeholder='Поиск по ГК или CRM ID'
|
||||||
value={query}
|
value={query}
|
||||||
onChange={(e) => setQuery(e.target.value)}
|
onChange={(e) => setQuery(e.target.value)}
|
||||||
|
style={{ flex: 1 }}
|
||||||
/>
|
/>
|
||||||
<Checkbox checked={isGettingArchiveCompany} onChange={(e) => dispatch(setIsGettingArchive(e.target.checked))}>
|
<Checkbox checked={isGettingArchiveCompany} onChange={(e) => dispatch(setIsGettingArchive(e.target.checked))}>
|
||||||
Архив
|
Архив
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
</Space>
|
</div>
|
||||||
|
|
||||||
<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,7 +29,6 @@ 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);
|
||||||
@ -77,7 +76,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({ is_archived: isGettingArchiveCompany }));
|
dispatch(getCompanyGroupsThunk());
|
||||||
}
|
}
|
||||||
}, [open, raw_rows.length, loading, dispatch]);
|
}, [open, raw_rows.length, loading, dispatch]);
|
||||||
|
|
||||||
@ -110,7 +109,7 @@ export const MoveCatalogueJurForm: React.FC<Props> = ({ open, onCancel, onOk, ju
|
|||||||
showSearch
|
showSearch
|
||||||
allowClear
|
allowClear
|
||||||
options={raw_rows
|
options={raw_rows
|
||||||
.filter((row) => row.id !== form.getFieldValue('old_company_group_id'))
|
.filter((row) => !row.is_archived && row.id !== form.getFieldValue('old_company_group_id'))
|
||||||
.map((g) => ({ value: g.id, label: g.name }))}
|
.map((g) => ({ value: g.id, label: g.name }))}
|
||||||
notFoundContent={loading ? 'Загрузка' : 'Нет вариантов'}
|
notFoundContent={loading ? 'Загрузка' : 'Нет вариантов'}
|
||||||
optionFilterProp='label'
|
optionFilterProp='label'
|
||||||
|
|||||||
@ -167,7 +167,7 @@ export const NewConsolidationModal: React.FC<Props> = ({ open, onCancel, onOk })
|
|||||||
showSearch
|
showSearch
|
||||||
allowClear
|
allowClear
|
||||||
filterOption={(input, option) => (option?.label as string)?.toLowerCase().includes(input.toLowerCase())}
|
filterOption={(input, option) => (option?.label as string)?.toLowerCase().includes(input.toLowerCase())}
|
||||||
options={raw_rows.map((g) => ({ value: g.id, label: g.name }))}
|
options={raw_rows.filter((g) => !g.is_archived).map((g) => ({ value: g.id, label: g.name }))}
|
||||||
onChange={handleGroupChange}
|
onChange={handleGroupChange}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@ -27,7 +27,6 @@ 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) {
|
||||||
@ -39,7 +38,7 @@ 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({ is_archived: isGettingArchiveCompany }));
|
await dispatch(getCompanyGroupsThunk());
|
||||||
|
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
crm_id: data?.crm_id,
|
crm_id: data?.crm_id,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user