fix: fixed columns draggables and styles
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
@ -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)",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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>
|
||||
)}
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
|
||||
.header {
|
||||
border-bottom: solid dodgerblue 3px;
|
||||
}
|
||||
@ -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;
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user