feat: attributes in cards and projects

This commit is contained in:
2025-02-27 18:34:15 +04:00
parent 8083bdf3d0
commit d37dce7980
75 changed files with 1674 additions and 281 deletions

View File

@@ -1,8 +1,7 @@
import { AttributeSchema } from "../../../client";
import { Checkbox, Tooltip } from "@mantine/core";
import { Checkbox, NumberInput, TextInput } from "@mantine/core";
import { UseFormReturnType } from "@mantine/form";
import { ReactNode } from "react";
import { DatePickerInput } from "@mantine/dates";
import { DatePickerInput, DateTimePicker } from "@mantine/dates";
import { CardGeneralFormType } from "../../../pages/CardsPage/tabs/GeneralTab/GeneralTab.tsx";
type Props = {
@@ -11,41 +10,65 @@ type Props = {
}
const CardAttributeField = ({ attribute, form }: Props) => {
const tooltipLabel = attribute.isApplicableToGroup
? "Применяется ко всей группе"
: "Применяется только к данной сделке";
const type = attribute.type.type;
let component: ReactNode;
const getDateValue = (): Date | null => {
const value = form.getInputProps(attribute.name).value;
if (!value) return null;
return new Date(value);
};
if (attribute.type.type === "bool") {
component = (
const labelData = {
label: attribute.label,
description: attribute.description,
};
if (type === "bool") {
return (
<Checkbox
label={attribute.label}
{...labelData}
{...form.getInputProps(attribute.name, { type: "checkbox" })}
// defaultChecked={form.getInputProps(attribute.name, { type: "checkbox"}).value}
/>
);
}
else if (attribute.type.type === "datetime" || attribute.type.type === "date") {
console.log("value = ");
console.log(form.getInputProps(attribute.name).value);
console.log("type = ")
console.log(typeof form.getInputProps(attribute.name).value);
component = (
} else if (type === "date") {
return (
<DatePickerInput
label={attribute.label}
{...labelData}
{...form.getInputProps(attribute.name)}
value={getDateValue()}
clearable
locale={"ru-RU"}
valueFormat="DD.MM.YYYY"
/>
);
} else if (type === "datetime") {
return (
<DateTimePicker
{...labelData}
{...form.getInputProps(attribute.name)}
value={getDateValue()}
clearable
locale={"ru-RU"}
valueFormat="DD.MM.YYYY HH:mm"
/>
);
} else if (type === "str") {
return (
<TextInput
{...labelData}
{...form.getInputProps(attribute.name)}
value={form.getInputProps(attribute.name).value ?? ""}
/>
);
} else if (type === "int" || type === "float") {
return (
<NumberInput
allowDecimal={type === "float"}
{...labelData}
{...form.getInputProps(attribute.name)}
clearable={attribute.isNullable}
/>
);
}
return (
<Tooltip label={tooltipLabel}>
{component}
</Tooltip>
);
};
export default CardAttributeField;

View File

@@ -28,7 +28,9 @@ const useCardsDnd = ({
cardId,
},
}).then(({ ok, message }) => {
notifications.guess(ok, { message });
if (!ok) {
notifications.guess(ok, { message });
}
});
};
@@ -144,7 +146,7 @@ const useCardsDnd = ({
});
};
const onDealDragEnd = async (result: DropResult) => {
const onCardDragEnd = async (result: DropResult) => {
if (result.combine) {
return onCombine(result);
}
@@ -206,7 +208,7 @@ const useCardsDnd = ({
return {
summaries,
onDealDragEnd,
onCardDragEnd,
};
};

View File

@@ -1,7 +1,7 @@
import styles from "../../../../pages/CardsPage/ui/CardsPage.module.css";
import { Divider, Text, Title } from "@mantine/core";
import getColumnColor from "../../Cards/CardsDndColumn/utils/getColumnColor.ts";
import { CardSummary, StatusSchema } from "../../../../client";
import { BoardSchema, CardSummary, StatusSchema } from "../../../../client";
import { getPluralForm } from "../../../../shared/lib/utils.ts";
import { sum } from "lodash";
import { Draggable, Droppable } from "@hello-pangea/dnd";
@@ -9,18 +9,21 @@ import DragState from "../../../../pages/CardsPage/enums/DragState.ts";
import { useContextMenu } from "mantine-contextmenu";
import { IconEdit, IconTrash } from "@tabler/icons-react";
import useStatus from "./hooks/useStatus.tsx";
import isModuleInProject, { Modules } from "../../../../pages/CardsPage/utils/isModuleInProject.ts";
type Props = {
status: StatusSchema;
board: BoardSchema | null;
index: number;
summaries: CardSummary[];
dragState: DragState;
refetch: () => void;
}
const Status = ({ summaries, status, dragState, index, refetch }: Props) => {
const isDropDisabled = dragState === DragState.DRAG_DEAL;
const Status = ({ summaries, status, board, dragState, index, refetch }: Props) => {
const isDropDisabled = dragState === DragState.DRAG_CARD;
const isServicesAndProductsIncluded = isModuleInProject(Modules.SERVICES_AND_PRODUCTS, board?.project);
const {
onEditStatusClick,
@@ -34,7 +37,10 @@ const Status = ({ summaries, status, dragState, index, refetch }: Props) => {
"сделки",
"сделок",
);
return `${summaries.length} ${pluralForm}: ${sum(summaries.map(summary => summary.totalPrice)).toLocaleString("ru-RU")}`;
const priceLabel = isServicesAndProductsIncluded
? `: ${sum(summaries.map(summary => summary.totalPrice)).toLocaleString("ru-RU")}`
: "";
return `${summaries.length} ${pluralForm}` + priceLabel;
};
const { showContextMenu } = useContextMenu();

View File

@@ -44,6 +44,7 @@ const Statuses = ({
summaries={filteredSummaries}
index={index}
status={status}
board={selectedBoard}
dragState={dragState}
refetch={refetchBoards}
/>