This commit is contained in:
2024-04-24 01:21:02 +03:00
parent 862f3fa3c1
commit c4e106576e
13 changed files with 205 additions and 86 deletions

View File

@@ -8,7 +8,7 @@
"build": "tsc && vite build", "build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview", "preview": "vite preview",
"generate-client": "openapi --input http://test.crm.denco.store/api/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes" "generate-client": "openapi --input http://127.0.0.1:8000/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes"
}, },
"dependencies": { "dependencies": {
"@hello-pangea/dnd": "^16.5.0", "@hello-pangea/dnd": "^16.5.0",

View File

@@ -45,6 +45,8 @@ export type { DealSchema } from './models/DealSchema';
export type { DealServiceSchema } from './models/DealServiceSchema'; export type { DealServiceSchema } from './models/DealServiceSchema';
export type { DealStatusHistorySchema } from './models/DealStatusHistorySchema'; export type { DealStatusHistorySchema } from './models/DealStatusHistorySchema';
export type { DealSummary } from './models/DealSummary'; export type { DealSummary } from './models/DealSummary';
export type { DealSummaryReorderRequest } from './models/DealSummaryReorderRequest';
export type { DealSummaryReorderResponse } from './models/DealSummaryReorderResponse';
export type { DealSummaryResponse } from './models/DealSummaryResponse'; export type { DealSummaryResponse } from './models/DealSummaryResponse';
export type { DealUpdateGeneralInfoRequest } from './models/DealUpdateGeneralInfoRequest'; export type { DealUpdateGeneralInfoRequest } from './models/DealUpdateGeneralInfoRequest';
export type { DealUpdateGeneralInfoResponse } from './models/DealUpdateGeneralInfoResponse'; export type { DealUpdateGeneralInfoResponse } from './models/DealUpdateGeneralInfoResponse';

View File

@@ -5,7 +5,7 @@
export type ClientDetailsSchema = { export type ClientDetailsSchema = {
address?: (string | null); address?: (string | null);
phoneNumber?: (string | null); phoneNumber?: (string | null);
inn?: (number | null); inn?: (string | null);
email?: (string | null); email?: (string | null);
}; };

View File

@@ -6,5 +6,6 @@ export type DealGeneralInfoSchema = {
name: string; name: string;
isDeleted: boolean; isDeleted: boolean;
isCompleted: boolean; isCompleted: boolean;
comment: string;
}; };

View File

@@ -18,5 +18,6 @@ export type DealSchema = {
isDeleted: boolean; isDeleted: boolean;
isCompleted: boolean; isCompleted: boolean;
client: ClientSchema; client: ClientSchema;
comment: string;
}; };

View File

@@ -9,5 +9,6 @@ export type DealSummary = {
changedAt: string; changedAt: string;
status: number; status: number;
totalPrice: number; totalPrice: number;
rank: number;
}; };

View File

@@ -0,0 +1,12 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type DealSummaryReorderRequest = {
dealId: number;
newStatus: number;
rank: number;
nextStatusDeadline: string;
comment: string;
};

View File

@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type DealSummaryReorderResponse = {
ok: boolean;
message: string;
};

View File

@@ -23,6 +23,8 @@ import type { DealGetAllResponse } from '../models/DealGetAllResponse';
import type { DealQuickCreateRequest } from '../models/DealQuickCreateRequest'; import type { DealQuickCreateRequest } from '../models/DealQuickCreateRequest';
import type { DealQuickCreateResponse } from '../models/DealQuickCreateResponse'; import type { DealQuickCreateResponse } from '../models/DealQuickCreateResponse';
import type { DealSchema } from '../models/DealSchema'; import type { DealSchema } from '../models/DealSchema';
import type { DealSummaryReorderRequest } from '../models/DealSummaryReorderRequest';
import type { DealSummaryReorderResponse } from '../models/DealSummaryReorderResponse';
import type { DealSummaryResponse } from '../models/DealSummaryResponse'; import type { DealSummaryResponse } from '../models/DealSummaryResponse';
import type { DealUpdateGeneralInfoRequest } from '../models/DealUpdateGeneralInfoRequest'; import type { DealUpdateGeneralInfoRequest } from '../models/DealUpdateGeneralInfoRequest';
import type { DealUpdateGeneralInfoResponse } from '../models/DealUpdateGeneralInfoResponse'; import type { DealUpdateGeneralInfoResponse } from '../models/DealUpdateGeneralInfoResponse';
@@ -105,6 +107,26 @@ export class DealService {
url: '/deal/summaries', url: '/deal/summaries',
}); });
} }
/**
* Reorder
* @returns DealSummaryReorderResponse Successful Response
* @throws ApiError
*/
public static reorderDealSummaries({
requestBody,
}: {
requestBody: DealSummaryReorderRequest,
}): CancelablePromise<DealSummaryReorderResponse> {
return __request(OpenAPI, {
method: 'POST',
url: '/deal/summaries/reorder',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/** /**
* Get All * Get All
* @returns DealGetAllResponse Successful Response * @returns DealGetAllResponse Successful Response

View File

@@ -46,7 +46,7 @@ export const Board: FC<Props> = ({droppableId, title, summaries, withCreateButto
( (
<Draggable <Draggable
draggableId={summary.id.toString()} draggableId={summary.id.toString()}
index={1} index={summary.rank}
key={summary.id} key={summary.id}
> >
{(provided) => ( {(provided) => (

View File

@@ -1,19 +1,69 @@
import {ContextModalProps} from "@mantine/modals"; import {ContextModalProps} from "@mantine/modals";
import {Button, Text} from "@mantine/core"; import {Button, Flex, rem, Textarea} from "@mantine/core";
import {DateTimePicker, DateValue} from "@mantine/dates";
import {useForm} from "@mantine/form";
import {DealSummaryReorderRequest} from "../../client";
type Deadline = {
datetime: DateValue,
comment: string
}
type Props = {
request:DealSummaryReorderRequest,
onSubmit: (
deadline: Deadline,
request: DealSummaryReorderRequest,
) => void;
}
const EnterDeadlineModal = ({ const EnterDeadlineModal = ({
context, context,
id, id,
innerProps, innerProps,
}: ContextModalProps<{ modalBody: string }>) => { }: ContextModalProps<Props>) => {
const form = useForm<Deadline>({
initialValues: {
datetime: null,
comment: '',
},
validate: {
datetime: (datetime) => datetime !== null ? null : 'Необходимо ввести дедлайн',
}
})
const onCancelClick = () => {
context.closeModal(id);
}
const onSubmit = (values: Deadline) => {
innerProps.onSubmit(values, innerProps.request);
}
return ( return (
<> <form onSubmit={form.onSubmit((values) => onSubmit(values))}>
<Text size="sm">{innerProps.modalBody}</Text> <Flex direction={'column'} gap={10}>
<Button fullWidth mt="md" onClick={() => context.closeModal(id)}> <Flex direction={'column'} gap={rem(10)}>
Close modal <DateTimePicker
</Button> required
</> label={'Дата и время'}
placeholder={'Введите дату и время'}
{...form.getInputProps('date')}
/>
<Textarea
label={'Коментарий'}
placeholder={'Введите коментарий'}
{...form.getInputProps('comment')}
/>
</Flex>
<Flex justify={'flex-end'} gap={rem(10)}>
<Button
variant={'default'}
onClick={onCancelClick}
>Отменить</Button>
<Button>Сохранить</Button>
</Flex>
</Flex>
</form>
) )
}; };
export default EnterDeadlineModal; export default EnterDeadlineModal;

View File

@@ -1,6 +1,6 @@
import {FC} from "react"; import {FC} from "react";
import {useDealPageContext} from "../../../contexts/DealPageContext.tsx"; import {useDealPageContext} from "../../../contexts/DealPageContext.tsx";
import {Button, Checkbox, Fieldset, Flex, Group, rem, TextInput} from "@mantine/core"; import {Button, Checkbox, Divider, Fieldset, Flex, Group, rem, Textarea, TextInput} from "@mantine/core";
import {useForm} from "@mantine/form"; import {useForm} from "@mantine/form";
import {ClientService, DealSchema, DealService} from "../../../../../client"; import {ClientService, DealSchema, DealService} from "../../../../../client";
import {DealStatus, DealStatusDictionary} from "../../../../../shared/enums/DealStatus.ts"; import {DealStatus, DealStatusDictionary} from "../../../../../shared/enums/DealStatus.ts";
@@ -63,6 +63,8 @@ const Content: FC<Props> = ({deal}) => {
} }
return ( return (
<form onSubmit={form.onSubmit((values) => handleSubmit(values))}> <form onSubmit={form.onSubmit((values) => handleSubmit(values))}>
<Flex direction={'column'}>
<Fieldset legend={"Общие параметры"}> <Fieldset legend={"Общие параметры"}>
<Flex direction={"column"} gap={rem(10)}> <Flex direction={"column"} gap={rem(10)}>
<TextInput <TextInput
@@ -81,16 +83,12 @@ const Content: FC<Props> = ({deal}) => {
placeholder={"Текущий статус"} placeholder={"Текущий статус"}
label={"Текущий статус"} label={"Текущий статус"}
value={DealStatusDictionary[deal.currentStatus as DealStatus]}/> value={DealStatusDictionary[deal.currentStatus as DealStatus]}/>
<Checkbox
label={"Сделка завершена"}
{...form.getInputProps('isCompleted')}
/>
<Checkbox <Textarea
label={"Сделка удалена"} label={'Коментарий к сделке'}
{...form.getInputProps('isDeleted')} placeholder={'Введите коментарий к сделке'}
{...form.getInputProps('comment')}
/> />
</Flex> </Flex>
</Fieldset> </Fieldset>
<Fieldset legend={"Клиент"}> <Fieldset legend={"Клиент"}>
@@ -121,7 +119,22 @@ const Content: FC<Props> = ({deal}) => {
{...form.getInputProps('client.details.inn')} {...form.getInputProps('client.details.inn')}
/> />
</Fieldset> </Fieldset>
<Group justify={"flex-end"} mt={"md"}> <Flex mt={'md'} gap={rem(10)} align={'center'} justify={'flex-end'}>
<Flex align={'center'} gap={rem(10)} justify={'center'}>
<Checkbox
label={"Сделка завершена"}
{...form.getInputProps('isCompleted')}
/>
<Checkbox
label={"Сделка удалена"}
{...form.getInputProps('isDeleted')}
/>
</Flex>
<Divider
orientation={'vertical'}
/>
<Group align={'center'} justify={'center'}>
<Button <Button
color={"red"} color={"red"}
type={"reset"} type={"reset"}
@@ -134,6 +147,9 @@ const Content: FC<Props> = ({deal}) => {
disabled={isEqual(initialValues, form.values)} disabled={isEqual(initialValues, form.values)}
>Сохранить изменения</Button> >Сохранить изменения</Button>
</Group> </Group>
</Flex>
</Flex>
</form> </form>
) )

View File

@@ -1,12 +1,14 @@
import {FC, useEffect, useState} from "react"; import {FC, useEffect, useState} from "react";
import styles from './LeadsPage.module.css'; import styles from './LeadsPage.module.css';
import Board from "../../../components/Dnd/Board/Board.tsx"; import Board from "../../../components/Dnd/Board/Board.tsx";
import {DragDropContext} from "@hello-pangea/dnd"; import {DragDropContext, DropResult, OnDragEndResponder, ResponderProvided} from "@hello-pangea/dnd";
import {useDealSummaries} from "../hooks/useDealSummaries.tsx"; import {useDealSummaries} from "../hooks/useDealSummaries.tsx";
import {DealStatus} from "../../../shared/enums/DealStatus.ts"; import {DealStatus} from "../../../shared/enums/DealStatus.ts";
import PageBlock from "../../../components/PageBlock/PageBlock.tsx"; import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
import DealEditDrawer from "../drawers/DealEditDrawer/DealEditDrawer.tsx"; import DealEditDrawer from "../drawers/DealEditDrawer/DealEditDrawer.tsx";
import {DealPageContextProvider} from "../contexts/DealPageContext.tsx"; import {DealPageContextProvider} from "../contexts/DealPageContext.tsx";
import {modals} from "@mantine/modals";
import {DealSummaryReorderRequest} from "../../../client";
export const LeadsPage: FC = () => { export const LeadsPage: FC = () => {
@@ -15,15 +17,18 @@ export const LeadsPage: FC = () => {
useEffect(() => { useEffect(() => {
setSummaries(summariesRaw); setSummaries(summariesRaw);
}, [summariesRaw]); }, [summariesRaw]);
const onDragEnd = () => { const onDragEnd = async (result: DropResult, provided: ResponderProvided) => {
// if (!result.destination) return; const dealId = parseInt(result.draggableId);
//
// const newStatus = getDealStatusByName( const request: DealSummaryReorderRequest = {}
// result.destination.droppableId modals.openContextModal({
// ); modal: 'enterDeadline',
// const summaryId = parseInt(result.draggableId); title: "Необходимо указать дедлайн",
// innerProps: {
// return; onSubmit: (event) => console.log(event)
}
});
} }
return ( return (
<> <>