feat: setting parent for department section

This commit is contained in:
2025-01-24 15:18:02 +04:00
parent 4500422f82
commit 5005565851
8 changed files with 266 additions and 57 deletions

View File

@@ -0,0 +1,66 @@
import { DepartmentCrud } from "../hooks/useDepartmentCrud.tsx";
import { DepartmentSchema } from "../../../../../client";
import { DepartmentModalForm } from "../types/DepartmentModalForm.tsx";
import { useForm } from "@mantine/form";
import { Button, Flex, rem, TextInput } from "@mantine/core";
type Props = {
departmentsCrud: DepartmentCrud;
department?: DepartmentSchema;
closeModal: () => void;
}
const DepartmentForm = ({
departmentsCrud,
department,
closeModal,
}: Props) => {
const initialValues: Partial<DepartmentModalForm> = {
name: department?.name ?? "",
};
const form = useForm<Partial<DepartmentModalForm>>({
initialValues,
validate: {
name: name => !name && "Необходимо указать название",
},
});
const isChanged = (): boolean => {
return initialValues.name !== form.values.name;
};
const onSubmit = () => {
if (department) {
if (isChanged()) {
departmentsCrud.onChange({ name: form.values.name ?? "", id: department?.id });
}
} else {
departmentsCrud.onCreate({ name: form.values.name ?? "" });
}
closeModal();
};
return (
<form onSubmit={form.onSubmit(() => onSubmit())}>
<Flex
direction={"column"}
gap={rem(10)}
>
<TextInput
label={"Название"}
{...form.getInputProps("name")}
/>
<Button
variant={"default"}
type={"submit"}
>
Сохранить
</Button>
</Flex>
</form>
);
};
export default DepartmentForm;

View File

@@ -0,0 +1,90 @@
import { DepartmentSchema, DepartmentSectionSchema } from "../../../../../client";
import { DepartmentSectionCrud } from "../hooks/useDepartmentSectionCrud.tsx";
import { DepartmentSectionModalForm } from "../types/DepartmentModalForm.tsx";
import { useForm } from "@mantine/form";
import { Button, Flex, rem, TextInput } from "@mantine/core";
import DepartmentSelect from "./DepartmentSelect.tsx";
type Props = {
departmentSectionsCrud: DepartmentSectionCrud;
departmentSection?: DepartmentSectionSchema;
allDepartments: DepartmentSchema[];
closeModal: () => void;
}
const DepartmentSectionForm = ({
departmentSectionsCrud,
departmentSection,
allDepartments,
closeModal,
}: Props) => {
const initialValues: DepartmentSectionModalForm = {
name: departmentSection?.name ?? "",
departmentId: departmentSection?.departmentId ?? null,
parentDepartmentSectionId: departmentSection?.parentDepartmentSectionId ?? null,
};
const form = useForm<DepartmentSectionModalForm>({
initialValues,
validate: {
name: name => !name && "Необходимо указать название",
},
});
const isChanged = (): boolean => {
return (
initialValues.name !== form.values.name ||
initialValues.departmentId !== form.values.departmentId ||
initialValues.parentDepartmentSectionId !== form.values.parentDepartmentSectionId
);
};
const onSubmit = () => {
const sectionData = { ...departmentSection, ...form.values };
const sectionName = form.values.name;
if (!sectionName) return;
if (departmentSection?.id) {
if (isChanged()) {
departmentSectionsCrud.onChange({
id: departmentSection.id,
name: form.values.name ?? "",
departmentId: form.values.departmentId,
parentDepartmentSectionId: form.values.parentDepartmentSectionId,
});
}
} else {
console.log(sectionData);
departmentSectionsCrud.onCreate(sectionData);
}
closeModal();
};
return (
<form onSubmit={form.onSubmit(() => onSubmit())}>
<Flex
direction={"column"}
gap={rem(10)}
>
<TextInput
label={"Название"}
{...form.getInputProps("name")}
/>
<DepartmentSelect
allDepartments={allDepartments}
form={form}
parentDepartmentSectionId={departmentSection?.id}
/>
<Button
variant={"default"}
type={"submit"}
>
Сохранить
</Button>
</Flex>
</form>
);
};
export default DepartmentSectionForm;

View File

@@ -0,0 +1,80 @@
import { DepartmentSchema, DepartmentSectionSchema } from "../../../../../client";
import { Select } from "@mantine/core";
import { DepartmentSectionModalForm } from "../types/DepartmentModalForm.tsx";
import { UseFormReturnType } from "@mantine/form";
type Props = {
allDepartments: DepartmentSchema[];
form: UseFormReturnType<DepartmentSectionModalForm>;
parentDepartmentSectionId?: number;
}
const DepartmentSelect = ({
allDepartments,
form,
parentDepartmentSectionId,
}: Props) => {
const getDepartmentValue = () => {
if (form.values.departmentId) {
return "D" + form.values.departmentId;
}
return "O" + form.values.parentDepartmentSectionId;
};
const setDepartmentValue = (value: string | null) => {
if (!value) {
form.setFieldValue("departmentId", null);
form.setFieldValue("parentDepartmentSectionId", null);
return;
}
const isDepartmentSection = value && value[0] === "O";
const id = Number.parseInt(value.substring(1));
if (isDepartmentSection) {
form.setFieldValue("departmentId", null);
form.setFieldValue("parentDepartmentSectionId", id);
} else {
form.setFieldValue("departmentId", id);
form.setFieldValue("parentDepartmentSectionId", null);
}
};
const getDepartmentSections = (section: DepartmentSectionSchema | DepartmentSchema): DepartmentSectionSchema[] => {
const sections: DepartmentSectionSchema[] = [];
section.sections?.forEach((section) => {
sections.push(section);
sections.push(...getDepartmentSections(section));
});
return sections;
};
let departmentSections: DepartmentSectionSchema[] = [];
allDepartments.forEach(department => {
departmentSections.push(...getDepartmentSections(department));
});
if (parentDepartmentSectionId) {
departmentSections = departmentSections.filter(section => section.id !== parentDepartmentSectionId);
}
return (
<Select
data={[
{
group: "Департаменты",
items: allDepartments.map(d => ({ label: d.name, value: "D" + d.id.toString() })),
},
{
group: "Отделы",
items: departmentSections.map(d => ({ label: d.name, value: "O" + d.id.toString() })),
},
]}
value={getDepartmentValue()}
onChange={setDepartmentValue}
label={"Родительский департамент/отдел"}
/>
);
};
export default DepartmentSelect;

View File

@@ -4,7 +4,7 @@ import { UserSchema } from "../../../../../client";
import useAvailableUsersList from "../hooks/useAvailableUsersList.tsx";
type SectionData = {
sectionId: number;
sectionid: number;
}
type Props = SectionData & Omit<
@@ -13,7 +13,7 @@ type Props = SectionData & Omit<
>;
const UserForDepartmentSelect: FC<Props> = props => {
const { objects: users } = useAvailableUsersList({ sectionId: props.sectionId });
const { objects: users } = useAvailableUsersList({ sectionId: props.sectionid });
return (
<ObjectSelect

View File

@@ -55,6 +55,7 @@ const useDepartmentContextState = () => {
departmentSectionsCrud,
isDepartmentSection,
element,
allDepartments: departments,
},
});
};

View File

@@ -53,7 +53,7 @@ const AddUserToDepartmentModal = ({
<UserForDepartmentSelect
label={"Пользователь"}
{...form.getInputProps("user")}
sectionId={innerProps.departmentSection.id}
sectionid={innerProps.departmentSection.id}
/>
<Checkbox
label={"Является руководителем"}

View File

@@ -1,16 +1,16 @@
import { useForm } from "@mantine/form";
import { ContextModalProps } from "@mantine/modals";
import { Button, Flex, rem, TextInput } from "@mantine/core";
import { DepartmentModalForm } from "../types/DepartmentModalForm.tsx";
import { DepartmentSchema, DepartmentSectionBaseSchema, DepartmentSectionSchema } from "../../../../../client";
import { DepartmentCrud } from "../hooks/useDepartmentCrud.tsx";
import { DepartmentSectionCrud } from "../hooks/useDepartmentSectionCrud.tsx";
import DepartmentForm from "../components/DepartmentForm.tsx";
import DepartmentSectionForm from "../components/DepartmentSectionForm.tsx";
type Props = {
departmentsCrud: DepartmentCrud;
departmentSectionsCrud: DepartmentSectionCrud;
element?: DepartmentSchema | DepartmentSectionSchema | DepartmentSectionBaseSchema;
isDepartmentSection: boolean;
allDepartments: DepartmentSchema[];
}
const DepartmentModal = ({
@@ -18,61 +18,27 @@ const DepartmentModal = ({
id,
innerProps,
}: ContextModalProps<Props>) => {
const {
departmentsCrud,
departmentSectionsCrud,
element,
isDepartmentSection,
} = innerProps;
const initialValues: DepartmentModalForm = {
name: element?.name ?? "",
};
const form = useForm<DepartmentModalForm>({
initialValues,
validate: {
name: name => !name && "Необходимо указать название",
},
});
const onSubmit = () => {
if (isDepartmentSection) {
const sectionData = { ...element as DepartmentSectionSchema, ...form.values };
if (sectionData.id) {
departmentSectionsCrud.onChange(sectionData);
} else {
departmentSectionsCrud.onCreate(sectionData);
}
} else {
const departmentData = element as DepartmentSchema;
if (element) {
departmentsCrud.onChange({ ...form.values, id: departmentData.id });
} else {
departmentsCrud.onCreate(form.values);
}
}
const closeModal = () => {
context.closeContextModal(id);
};
return (
<form onSubmit={form.onSubmit(() => onSubmit())}>
<Flex
direction={"column"}
gap={rem(10)}
>
<TextInput
label={"Название"}
{...form.getInputProps("name")}
/>
if (innerProps.isDepartmentSection) {
return (
<DepartmentSectionForm
departmentSectionsCrud={innerProps.departmentSectionsCrud}
allDepartments={innerProps.allDepartments}
departmentSection={innerProps.element as DepartmentSectionSchema}
closeModal={closeModal}
/>
);
}
<Button
variant={"default"}
type={"submit"}
>
Сохранить
</Button>
</Flex>
</form>
return (
<DepartmentForm
departmentsCrud={innerProps.departmentsCrud}
department={innerProps.element as DepartmentSchema}
closeModal={closeModal}
/>
);
};

View File

@@ -1,3 +1,9 @@
export type DepartmentModalForm = {
name: string;
}
export type DepartmentSectionModalForm = {
name: string;
parentDepartmentSectionId: number | null;
departmentId: number | null;
}