Skip to content

Commit

Permalink
Доработки
Browse files Browse the repository at this point in the history
  • Loading branch information
DeDxYk594 committed Dec 13, 2024
1 parent d533001 commit 9b69206
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 38 deletions.
46 changes: 46 additions & 0 deletions src/api/dnd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { showToast } from '@/stores/toastNotificationStore';
import { apiPut, HTTP_STATUS_CREATED, HTTP_STATUS_OK } from './apiHelper';
import { CardMoveRequest, ColumnMoveRequest } from './requestTypes';

export const moveCard = async (
cardId: number,
newColumnId: number,
previousCardId: number,
nextCardId: number
) => {
const req: CardMoveRequest = {
newColumnId: newColumnId,
previousCardId: previousCardId,
nextCardId: nextCardId,
};
const response = await apiPut(`/cardOrder/${cardId}`, req);
switch (response.status) {
case HTTP_STATUS_OK:
case HTTP_STATUS_CREATED:
showToast('Успешно перемещена карточка!', 'success');
return;

default:
showToast('Неизвестная ошибка', 'error');
}
};
export const moveColumn = async (
columnId: number,
nextColumnId: number,
previousColumnId: number
) => {
const req: ColumnMoveRequest = {
nextColumnId: nextColumnId,
previousColumnId: previousColumnId,
};
const response = await apiPut(`/columnOrder/${columnId}`, req);
switch (response.status) {
case HTTP_STATUS_OK:
case HTTP_STATUS_CREATED:
showToast('Успешно перемещена колонка!', 'success');
return;

default:
showToast('Неизвестная ошибка', 'error');
}
};
11 changes: 11 additions & 0 deletions src/api/requestTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,14 @@ export interface CheckListFieldPutRequest {
export interface CheckListFieldPostRequest {
title: string;
}

export interface CardMoveRequest {
newColumnId: number;
previousCardId: number;
nextCardId: number;
}

export interface ColumnMoveRequest {
previousColumnId: number;
nextColumnId: number;
}
118 changes: 90 additions & 28 deletions src/components/KanbanCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import { useEffectRefs, useState } from '@/jsxCore/hooks';
import { Button } from './Button';
import { getCardDetails } from '@/api/cardDetails';
import { setCardDetailsStore } from '@/stores/cardDetailsStore';
import { Card, RealCard } from '@/types/card';
import { Card } from '@/types/card';
import {
cardHeights,
setEditLock,
setDndStore,
useDndStore,
editLock,
} from '@/stores/dndStore';
import { showToast } from '@/stores/toastNotificationStore';

interface KanbanCardProps extends ComponentProps {
card: Card;
Expand Down Expand Up @@ -87,20 +88,16 @@ const Editable = (props: EditableProps) => {

const DND_THRESHOLD = 10;

let timer: number;

export const KanbanCard = (props: KanbanCardProps) => {
const activeBoard = useActiveBoardStore() as ActiveBoard;
const card = props.card;
const [isInput, setIsInput] = useState(false);
const [menuOpened, setMenuOpened] = useState(false);
const [menuPos, setMenuPos] = useState([0, 0]);
const [dragStart, setDragStart] = useState<
[x: number, y: number] | undefined
>(undefined);
const [dragOffset, setDragOffset] = useState<[x: number, y: number]>([0, 0]);
const editCallback = () => {
clearTimeout(timer);
setIsInput(true);
};
const cancelDnd = () => {
setDragStart(undefined);
};
Expand All @@ -122,12 +119,11 @@ export const KanbanCard = (props: KanbanCardProps) => {
ref="card"
className="kanban-card"
ON_click={() => {
clearTimeout(timer);
timer = setTimeout(() => {
if (!isInput) {
getCardDetails(card.id).then((val) => {
setCardDetailsStore(val);
});
}, 300);
}
}}
ON_mousedown={(ev: PointerEvent) => {
if (!isInput && !editLock) {
Expand Down Expand Up @@ -163,18 +159,91 @@ export const KanbanCard = (props: KanbanCardProps) => {
ON_mouseleave={cancelDnd}
ON_mouseup={cancelDnd}
>
{activeBoard.myRole !== 'viewer' && (
{menuOpened && (
<div
className="kanban-card__delete-button"
ON_click={() => {
deleteCard(card.id).then(() => {
activeBoard.columns.forEach((column) => {
column.cards = column.cards.filter((cardToFilter) => {
return (cardToFilter as RealCard).id !== card.id;
className="full-screen-dark"
ON_click={(ev: Event) => {
setMenuOpened(false);
ev.stopPropagation();
}}
>
<div
className="kanban-card__menu"
style={`top: ${menuPos[1]}px; left:${menuPos[0] - 100}px`}
>
{activeBoard.myRole !== 'viewer' && (
<>
<div
class="kanban-card__menu-item"
ON_click={() => {
setMenuOpened(false);
setIsInput(true);
}}
>
<i class="bi-pencil" />
Редактировать
</div>
<div
class="kanban-card__menu-item"
style="color: var(--color-negative)"
ON_click={() => {
setMenuOpened(false);
deleteCard(props.card.id).then(() => {
showToast('Карточка успешно удалена!', 'success');
activeBoard.columns[props.columnIdx].cards =
activeBoard.columns[props.columnIdx].cards.filter(
(a) => {
return a.id !== props.card.id;
}
);
setActiveBoardStore(activeBoard);
});
}}
>
<i class="bi-trash" />
Удалить
</div>
</>
)}
<div
class="kanban-card__menu-item"
ON_click={() => {
getCardDetails(card.id).then((val) => {
setCardDetailsStore(val);
});
});
setActiveBoardStore(activeBoard);
});
}}
>
<i class="bi-three-dots" />
Подробности
</div>
{activeBoard.myRole !== 'viewer' && (
<>
<div class="kanban-card__menu-item">
<i class="bi-caret-down-fill" />
Переместить ниже
</div>
<div class="kanban-card__menu-item">
<i class="bi-caret-up-fill" />
Переместить выше
</div>
<div class="kanban-card__menu-item">
<i class="bi-caret-left-fill" />В левую колонку
</div>
<div class="kanban-card__menu-item">
<i class="bi-caret-right-fill" />В правую колонку
</div>
</>
)}
</div>
</div>
)}
{!isInput && (
<div
className="kanban-card__dots-button"
ON_click={(ev: PointerEvent) => {
setMenuOpened(true);
ev.stopPropagation();
setMenuPos([ev.x, ev.y]);
}}
>
<i class="bi-three-dots" />
Expand Down Expand Up @@ -204,14 +273,7 @@ export const KanbanCard = (props: KanbanCardProps) => {
}}
/>
) : (
<div
className="kanban-card__title"
ON_dblclick={editCallback}
ON_contextmenu={(ev: Event) => {
editCallback();
ev.stopPropagation();
}}
>
<div className="kanban-card__title">
<div>{card.title}</div>
<div>
{card.deadline !== undefined && <i className="bi-clock" />}
Expand Down
46 changes: 37 additions & 9 deletions src/components/kanbanCard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,42 +24,70 @@
max-height: 150px;
}

.kanban-card__delete-button {
.kanban-card__dots-button {
position: absolute;
width: 32px;
right: 0;
top: 0;
padding-left: 8px;
padding-top: 6px;
height: 32px;
border-radius: 9px;
cursor: pointer;
transition: background-color 0.3s ease;
backdrop-filter: blur(10px);
}

.kanban-card__delete-button:hover {
.kanban-card__dots-button:hover {
background-color: rgba(0, 0, 0, 0.1);
}

@media screen and (min-width: 800px) {
.kanban-card__delete-button {
opacity: 0;
}
.kanban-card__dots-button {
opacity: 0;
}

.kanban-card:hover .kanban-card__delete-button {
.kanban-card:hover .kanban-card__dots-button {
opacity: 100;
}

.kanban-card__title {
user-select: none;
cursor: text;
}

.kanban-card__textarea {
all: unset;
border: 2px solid black;
border-radius: 3px;
display: block;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
resize: none;
padding: 3px;
}

.kanban-card__menu {
position: fixed;
background-color: white;
display: flex;
flex-direction: column;
border-radius: 12px;
overflow: hidden;
}

.kanban-card__menu-item {
padding-left: 15px;
padding-right: 20px;
padding-top: 6px;
padding-bottom: 6px;
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
column-gap: 8px;
transition: background-color 0.3s ease;
}

.kanban-card__menu-item:hover {
background-color: rgba(0, 0, 0, 0.1);
}
2 changes: 1 addition & 1 deletion src/components/kanbanColumn.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
padding-bottom: 5px;
padding-left: 8px;
padding-right: 8px;
margin-bottom: 50px;
margin-bottom: 220px;
}
@media screen and (min-width: 800px) {
.kanban-column {
Expand Down
1 change: 1 addition & 0 deletions src/containers/userPopup.scss
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
display: flex;
justify-content: flex-start;
cursor: pointer;
transition: background-color 0.3s ease;
}

.user-popup__button:hover {
Expand Down
3 changes: 3 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ module.exports = {
static: [path.resolve(__dirname)],
liveReload: true,
historyApiFallback: true,
client: {
overlay: false,
},
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
Expand Down

0 comments on commit 9b69206

Please sign in to comment.