Skip to content

Commit

Permalink
Информация о дедлайне на карточке
Browse files Browse the repository at this point in the history
  • Loading branch information
DeDxYk594 committed Dec 3, 2024
1 parent ff7a3f7 commit dacbe1a
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 45 deletions.
6 changes: 6 additions & 0 deletions src/api/mocks/activeBoard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,19 @@ export const activeBoardMock: ActiveBoard = {
id: 228,
title: 'Пример задачи, для которой не задана обложка',
deadline: undefined,
hasAssignedUsers: false,
hasAttachments: false,
hasCheckList: false,
},
{
type: 'real',
id: 1337,
title: 'Пример задачи, для которой задана обложка',
coverImageUrl: '/static/img/lada_vesta.png',
deadline: undefined,
hasAssignedUsers: false,
hasAttachments: false,
hasCheckList: false,
},
],
},
Expand Down
43 changes: 32 additions & 11 deletions src/components/KanbanCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ import { Button } from './Button';
import { getCardDetails } from '@/api/cardDetails';
import { setCardDetailsStore } from '@/stores/cardDetailsStore';
import { Card, RealCard } from '@/types/card';
import { cardHeights, setDndStore, useDndStore } from '@/stores/dndStore';
import {
cardHeights,
setEditLock,
setDndStore,
useDndStore,
editLock,
} from '@/stores/dndStore';

interface KanbanCardProps extends ComponentProps {
card: Card;
Expand All @@ -27,33 +33,46 @@ interface EditableProps extends ComponentProps {
const Editable = (props: EditableProps) => {
const [init, setInit] = useState(true);
const [newText, setNewText] = useState(props.initialText);
let textAreaElement: HTMLTextAreaElement | undefined = undefined;

const recalculateHeight = () => {
if (textAreaElement !== undefined) {
textAreaElement.style.height = 25 + textAreaElement.scrollHeight + 'px';
}
};

useEffectRefs((refs) => {
textAreaElement = refs.get('textarea') as HTMLTextAreaElement;
recalculateHeight();
if (init) {
const ta = refs.get('textarea') as HTMLTextAreaElement;
ta.focus();
ta.value = props.initialText;
setEditLock(true);
setTimeout(() => {
setInit(false);
textAreaElement?.focus();
}, 100);
textAreaElement.value = props.initialText;
setInit(false);
}
});

const submit = () => {
updateCard(props.cardId, { title: newText }).then((newCard) => {
if (newCard !== undefined) {
setEditLock(false);
props.onNewCard(newCard);
}
});
};

return (
<div>
<div style="width: 100%">
<textarea
className="kanban-card__textarea"
ref="textarea"
ON_input={(ev: InputEvent) => {
setNewText((ev.target as HTMLInputElement).value);
recalculateHeight();
}}
ON_blur={submit}
/>
<Button
key="save_text"
Expand Down Expand Up @@ -101,9 +120,9 @@ export const KanbanCard = (props: KanbanCardProps) => {
return (
<div
ref="card"
class="kanban-card"
className="kanban-card"
ON_mousedown={(ev: PointerEvent) => {
if (!isInput) {
if (!isInput && !editLock) {
setDragStart([ev.x, ev.y]);
setDragOffset([ev.offsetX, ev.offsetY]);
}
Expand Down Expand Up @@ -138,7 +157,7 @@ export const KanbanCard = (props: KanbanCardProps) => {
>
{activeBoard.myRole !== 'viewer' && (
<div
class="kanban-card__delete-button"
className="kanban-card__delete-button"
ON_click={() => {
deleteCard(card.id).then(() => {
activeBoard.columns.forEach((column) => {
Expand Down Expand Up @@ -192,10 +211,12 @@ export const KanbanCard = (props: KanbanCardProps) => {
}, 300);
}}
>
{card.title}
<div>{card.title}</div>
<div>
{card.deadline !== undefined && <i className="bi-clock" />}
</div>
</div>
)}
{}
</div>
);
}
Expand Down
69 changes: 35 additions & 34 deletions src/components/KanbanColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,42 +51,43 @@ export const KanbanColumn = (props: KanbanColumnProps) => {
}, 200);
});
return (
<div
class="kanban-column"
ON_mousedown={(ev: PointerEvent) => {
setDragStart([ev.x, ev.y]);
setDragOffset([ev.offsetX, ev.offsetY]);
}}
ON_mousemove={(ev: PointerEvent) => {
if (dragStart !== undefined) {
if (
Math.sqrt(
Math.pow(dragStart[0] - ev.x, 2) +
Math.pow(dragStart[1] - ev.y, 2)
) > DND_THRESHOLD
) {
const dndStore = useDndStore();
if (dndStore === undefined) {
setDndStore({
type: 'column',
activeColumnIdx: props.columnIndex,
offset: dragOffset,
activeColumn: activeBoard.columns[props.columnIndex],
});
console.log('offset', dragOffset);
setDragStart(undefined);
<div class="kanban-column">
<div
class="kanban-column__header"
ref="header"
ON_mousedown={(ev: PointerEvent) => {
setDragStart([ev.x, ev.y]);
setDragOffset([ev.offsetX, ev.offsetY]);
}}
ON_mousemove={(ev: PointerEvent) => {
if (dragStart !== undefined) {
if (
Math.sqrt(
Math.pow(dragStart[0] - ev.x, 2) +
Math.pow(dragStart[1] - ev.y, 2)
) > DND_THRESHOLD
) {
const dndStore = useDndStore();
if (dndStore === undefined) {
setDndStore({
type: 'column',
activeColumnIdx: props.columnIndex,
offset: dragOffset,
activeColumn: activeBoard.columns[props.columnIndex],
});
console.log('offset', dragOffset);
setDragStart(undefined);
}
}
}
}
}}
ON_mouseleave={() => {
setDragStart(undefined);
}}
ON_mouseup={() => {
setDragStart(undefined);
}}
>
<div class="kanban-column__header" ref="header">
}}
ON_mouseleave={() => {
setDragStart(undefined);
}}
ON_mouseup={() => {
setDragStart(undefined);
}}
>
<EditableText
readOnly={activeBoard.myRole === 'viewer'}
text={columnData.title}
Expand Down
9 changes: 9 additions & 0 deletions src/components/kanbanCard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,12 @@
.kanban-card__title {
user-select: none;
}

.kanban-card__textarea {
display: block;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
resize: none;
}
8 changes: 8 additions & 0 deletions src/stores/dndStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,11 @@ export const cardHeights = new Map<number, number>();
// Это нужно для того, чтобы колонки с длинным названием работали корректно.
// Ключ - порядковый индекс колонки
export const colHeaderHeights = new Map<number, number>();

// Этот лок нужен только для того, чтобы предотвратить действия, когда где-то редактируется текст.
// В других целях она не должна использоваться
export let editLock = false;

export const setEditLock = (newValue: boolean) => {
editLock = newValue;
};
3 changes: 3 additions & 0 deletions src/types/card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export interface RealCard {
title: string;
coverImageUrl?: string;
deadline: Date | undefined;
hasCheckList: boolean;
hasAttachments: boolean;
hasAssignedUsers: boolean;
}

export interface CardDetails {
Expand Down

0 comments on commit dacbe1a

Please sign in to comment.