fix: fixed columns draggables and styles

This commit is contained in:
2025-08-17 10:38:28 +04:00
parent 4ff663536e
commit c405c802aa
14 changed files with 188 additions and 93 deletions

View File

@ -29,7 +29,8 @@ const BoardsMobile = () => {
scrollbars={"x"}
scrollbarSize={0}
w={"100vw"}
mt={5}>
mt={5}
mb={"sm"}>
<Group
wrap={"nowrap"}
gap={0}>

View File

@ -1,10 +1,16 @@
.container {
border-radius: var(--mantine-spacing-md);
flex-wrap: nowrap;
border-bottom: solid dodgerblue 3px;
margin-bottom: 3px;
cursor: pointer;
@mixin light {
background-color: var(--color-light-aqua);
}
@mixin dark {
background-color: var(--mantine-color-dark-6);
}
@media (max-width: 48em) {
width: 80vw;
}

View File

@ -12,7 +12,9 @@ const CreateStatusButton = () => {
return (
<Stack>
<Box className={styles.container}>
<Box
className={styles.container}
style={{ width: "fit-content", minWidth: "auto" }}>
<InPlaceInput
placeholder={"Название колонки"}
onComplete={onCreateStatus}
@ -32,7 +34,8 @@ const CreateStatusButton = () => {
modalTitle={"Создание колонки"}
inputStyles={{
wrapper: {
padding: 4,
paddingInline: "var(--mantine-spacing-md)",
paddingBlock: "var(--mantine-spacing-xs)",
},
}}
/>

View File

@ -1,7 +1,7 @@
.container {
@mixin light {
background-color: var(--color-light-aqua);
background-color: var(--color-light-white-blue);
}
@mixin dark {
background-color: var(--mantine-color-dark-7);

View File

@ -3,6 +3,7 @@
import React, { FC, ReactNode } from "react";
import DealCard from "@/app/deals/components/shared/DealCard/DealCard";
import DealContainer from "@/app/deals/components/shared/DealContainer/DealContainer";
import StatusColumnHeader from "@/app/deals/components/shared/StatusColumnHeader/StatusColumnHeader";
import StatusColumnWrapper from "@/app/deals/components/shared/StatusColumnWrapper/StatusColumnWrapper";
import { useBoardsContext } from "@/app/deals/contexts/BoardsContext";
import { useDealsContext } from "@/app/deals/contexts/DealsContext";
@ -43,14 +44,21 @@ const Funnel: FC = () => {
}
renderContainer={(
status: StatusSchema,
funnelColumnComponent: ReactNode
funnelColumnComponent: ReactNode,
renderDraggable
) => (
<StatusColumnWrapper
status={status}
isDragging={activeStatus?.id === status.id}>
renderHeader={renderDraggable}>
{funnelColumnComponent}
</StatusColumnWrapper>
)}
renderContainerHeader={status => (
<StatusColumnHeader
status={status}
isDragging={activeStatus?.id === status.id}
/>
)}
renderItem={(deal: DealSchema) => (
<DealContainer
key={deal.id}
@ -63,7 +71,12 @@ const Funnel: FC = () => {
renderContainerOverlay={(status: StatusSchema, children) => (
<StatusColumnWrapper
status={status}
isDragging>
renderHeader={() => (
<StatusColumnHeader
status={status}
isDragging={activeStatus?.id === status.id}
/>
)}>
{children}
</StatusColumnWrapper>
)}

View File

@ -0,0 +1,4 @@
.header {
border-bottom: solid dodgerblue 3px;
}

View File

@ -0,0 +1,62 @@
import React, { FC } from "react";
import { Group, Text } from "@mantine/core";
import styles from "./StatusColumnHeader.module.css";
import StatusMenu from "@/app/deals/components/shared/StatusMenu/StatusMenu";
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
import InPlaceInput from "@/components/ui/InPlaceInput/InPlaceInput";
import { StatusSchema } from "@/lib/client";
type Props = {
status: StatusSchema;
isDragging: boolean;
};
const StatusColumnHeader: FC<Props> = ({ status, isDragging }) => {
const { onUpdateStatus } = useStatusesContext();
const handleSave = (value: string) => {
const newValue = value.trim();
if (newValue && newValue !== status.name) {
onUpdateStatus(status.id, { name: newValue });
}
};
return (
<Group
justify={"space-between"}
p={"sm"}
wrap={"nowrap"}
mb={"xs"}
className={styles.header}>
<InPlaceInput
defaultValue={status.name}
onComplete={value => handleSave(value)}
inputStyles={{
input: {
height: 25,
minHeight: 25,
},
}}
getChildren={startEditing => (
<>
<Text
style={{
cursor: "grab",
userSelect: "none",
opacity: isDragging ? 0.5 : 1,
}}>
{status.name}
</Text>
<StatusMenu
status={status}
handleEdit={startEditing}
/>
</>
)}
modalTitle={"Редактирование статуса"}
/>
</Group>
);
};
export default StatusColumnHeader;

View File

@ -1,10 +1,20 @@
.container {
height: calc(100vh - 150px);
@media (max-width: 48em) {
width: 80vw;
}
}
.header {
border-bottom: solid dodgerblue 3px;
.inner-container {
border-radius: var(--mantine-spacing-md);
gap: 0;
@mixin light {
background-color: var(--color-light-aqua);
}
@mixin dark {
background-color: var(--mantine-color-dark-6);
}
}

View File

@ -1,68 +1,24 @@
import React, { ReactNode } from "react";
import { Box, Group, Text } from "@mantine/core";
import StatusMenu from "@/app/deals/components/shared/StatusMenu/StatusMenu";
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
import InPlaceInput from "@/components/ui/InPlaceInput/InPlaceInput";
import { Box, Stack } from "@mantine/core";
import { StatusSchema } from "@/lib/client";
import styles from "./StatusColumnWrapper.module.css";
type Props = {
status: StatusSchema;
isDragging?: boolean;
renderHeader: () => ReactNode;
children: ReactNode;
};
const StatusColumnWrapper = ({
status,
children,
isDragging = false,
}: Props) => {
const { onUpdateStatus } = useStatusesContext();
const handleSave = (value: string) => {
const newValue = value.trim();
if (newValue && newValue !== status.name) {
onUpdateStatus(status.id, { name: newValue });
}
};
const StatusColumnWrapper = ({ renderHeader, children }: Props) => {
return (
<Box className={styles.container}>
<Group
justify={"space-between"}
p={"sm"}
wrap={"nowrap"}
mb={"xs"}
className={styles.header}>
<InPlaceInput
defaultValue={status.name}
onComplete={value => handleSave(value)}
inputStyles={{
input: {
height: 25,
minHeight: 25,
},
}}
getChildren={startEditing => (
<>
<Text
style={{
cursor: "grab",
userSelect: "none",
opacity: isDragging ? 0.5 : 1,
}}>
{status.name}
</Text>
<StatusMenu
status={status}
handleEdit={startEditing}
/>
</>
)}
modalTitle={"Редактирование статуса"}
/>
</Group>
{children}
<Stack
px={"xs"}
pb={"xs"}
className={styles["inner-container"]}>
{renderHeader()}
{children}
</Stack>
</Box>
);
};