Skip to content

Commit

Permalink
Приглашение на доску
Browse files Browse the repository at this point in the history
  • Loading branch information
DeDxYk594 committed Dec 15, 2024
1 parent 3abb45e commit 820a441
Show file tree
Hide file tree
Showing 14 changed files with 322 additions and 37 deletions.
20 changes: 12 additions & 8 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { getFlagRoutes } from './routes/routesFlag';
import { CsatPoll } from './screens/CsatPoll';
import { CsatResults } from './screens/CsatResults';
import { setCsatStore, useCsatStore } from './stores/csatStore';
import { loadBoard, useActiveBoardStore } from './stores/activeBoardStore';
import { useDndStore } from './stores/dndStore';

const App: IComponentFunction = () => {
const routerStore = useRouterStore();
Expand All @@ -37,7 +39,6 @@ setTimeout(() => {

window.addEventListener('message', (ev: MessageEvent<string>) => {
if (ev.data === 'close_csat') {
console.log('should output');
setTimeout(() => {
setCsatStore({ ...useCsatStore(), isOpened: false });
}, 0);
Expand All @@ -62,11 +63,14 @@ if ('serviceWorker' in navigator) {
console.error('Service Worker is not available');
}

// const REFETCH_DELAY = 5000;
const REFETCH_DELAY = 5000;

// setInterval(() => {
// const activeBoard = useActiveBoardStore();
// if (activeBoard !== undefined) {
// loadBoard(activeBoard.id, true);
// }
// }, REFETCH_DELAY);
setInterval(() => {
const activeBoard = useActiveBoardStore();
const dnd = useDndStore();
if (dnd === undefined) {
if (activeBoard !== undefined) {
loadBoard(activeBoard.board.id, true);
}
}
}, REFETCH_DELAY);
21 changes: 21 additions & 0 deletions src/api/cardDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
apiPost,
apiPut,
HTTP_STATUS_CREATED,
HTTP_STATUS_NOT_FOUND,
HTTP_STATUS_OK,
} from './apiHelper';
import {
Expand All @@ -25,6 +26,7 @@ import {
CardDetailsResponse,
CheckListFieldResponse,
CommentResponse,
SharedCardResponse,
UserResponse,
} from './responseTypes';
import {
Expand Down Expand Up @@ -191,3 +193,22 @@ export const addAttachment = async (
showToast('Ошибка при добавлении файла', 'error');
}
};

export const getCardByLink = async (
cardUuid: string
): Promise<SharedCardResponse | undefined> => {
const response = await apiGet(`/sharedCard/${cardUuid}`);
switch (response.status) {
case HTTP_STATUS_CREATED:
case HTTP_STATUS_OK: {
const res = response.body as SharedCardResponse;
return res;
}
case HTTP_STATUS_NOT_FOUND:
showToast('Карточка удалена или ссылка повреждена', 'error');
return undefined;
default:
showToast('Неизвестная ошибка при получении карточки', 'error');
return undefined;
}
};
81 changes: 78 additions & 3 deletions src/api/members.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { UserToBoard } from '@/types/types';
import { Board, UserToBoard } from '@/types/types';
import {
apiDelete,
apiGet,
apiPost,
apiPut,
HTTP_STATUS_CREATED,
HTTP_STATUS_NOT_FOUND,
HTTP_STATUS_OK,
} from './apiHelper';
import { showToast } from '@/stores/toastNotificationStore';
import { MemberWithPermissionsResponse } from './responseTypes';
import { decodeMember } from './decode';
import { BoardResponse, MemberWithPermissionsResponse } from './responseTypes';
import { decodeBoard, decodeMember } from './decode';

export const getBoardPermissions = async (
boardId: number
Expand Down Expand Up @@ -57,3 +60,75 @@ export const updateMember = async (
throw new Error('Неизвестная ошибка');
}
};

export const createInviteLink = async (
boardId: number
): Promise<string | undefined> => {
const response = await apiPut(`/inviteLink/board_${boardId}`);
switch (response.status) {
case HTTP_STATUS_OK:
case HTTP_STATUS_CREATED:
return response.body.inviteLinkUuid as string;
default:
showToast('Ошибка при задании ссылки-приглашения', 'error');
return;
}
};

export const deleteInviteLink = async (boardId: number): Promise<boolean> => {
const response = await apiDelete(`/inviteLink/board_${boardId}`);
switch (response.status) {
case HTTP_STATUS_OK:
case HTTP_STATUS_CREATED:
return true;
default:
showToast('Ошибка при задании ссылки-приглашения', 'error');
return false;
}
};

export const fetchInviteLink = async (
inviteLinkUuid: string
): Promise<Board | undefined> => {
const response = await apiGet(`/joinBoard/${inviteLinkUuid}`);
switch (response.status) {
case HTTP_STATUS_OK:
case HTTP_STATUS_CREATED:
return decodeBoard(response.body as BoardResponse);
case HTTP_STATUS_NOT_FOUND:
showToast(
'Возможно, ссылка-приглашение была удалена или повреждена',
'error'
);
return undefined;
default:
showToast(
'Неизвестная ошибка при получении приглашения на доску',
'error'
);
return undefined;
}
};

export const joinInviteLink = async (
inviteLinkUuid: string
): Promise<Board | undefined> => {
const response = await apiPost(`/joinBoard/${inviteLinkUuid}`);
switch (response.status) {
case HTTP_STATUS_OK:
case HTTP_STATUS_CREATED:
return decodeBoard(response.body as BoardResponse);
case HTTP_STATUS_NOT_FOUND:
showToast(
'Возможно, ссылка-приглашение была удалена или повреждена',
'error'
);
return undefined;
default:
showToast(
'Неизвестная ошибка при получении приглашения на доску',
'error'
);
return undefined;
}
};
18 changes: 17 additions & 1 deletion src/api/responseTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CsatQuestion } from "@/types/types";
import { CsatQuestion } from '@/types/types';

export interface BoardContentResponse {
myRole: 'viewer' | 'editor' | 'editor_chief' | 'admin';
Expand Down Expand Up @@ -92,3 +92,19 @@ export interface CardDetailsResponse {
comments: CommentResponse[];
assignedUsers: UserResponse[];
}

export type SharedCardResponse =
| MySharedCardResponse
| ForeignSharedCardResponse;

export interface MySharedCardResponse {
type: 'my';
boardId: number;
cardId: number;
}

export interface ForeignSharedCardResponse {
type: 'foreign';
board: BoardResponse;
card: CardDetailsResponse;
}
18 changes: 16 additions & 2 deletions src/containers/BoardSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
useActiveBoardStore,
} from '@/stores/activeBoardStore';
import { Input } from '@/components/Input';
import { removeMember, updateMember } from '@/api/members';
import { createInviteLink, removeMember, updateMember } from '@/api/members';
import { setMembersStore, useMembersStore } from '@/stores/members';
import { showToast } from '@/stores/toastNotificationStore';
import { useMeStore } from '@/stores/meStore';
Expand Down Expand Up @@ -142,7 +142,7 @@ export const BoardSettings = () => {
<h1>Ссылка-приглашение</h1>
<Input
key="invite_link_input"
initialValue="https://kanban-pumpkin.ru/card/228"
initialValue={`${window.location.origin}/inviteBoard/${activeBoard.board.myInviteLinkUuid}`}
/>
</div>
) : (
Expand All @@ -151,6 +151,20 @@ export const BoardSettings = () => {
key="create_invite_link"
text="Создать ссылку-приглашение"
icon="bi-link-45deg"
callback={() => {
createInviteLink(activeBoard.board.id).then(
(linkUuid) => {
if (linkUuid !== undefined) {
showToast(
'Успешно задана ссылка-приглашение!',
'success'
);
activeBoard.board.myInviteLinkUuid = linkUuid;
setActiveBoardStore(activeBoard);
}
}
);
}}
/>
</div>
)}
Expand Down
6 changes: 4 additions & 2 deletions src/containers/CardDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ export const CardDetailsContainer = (props: ComponentProps) => {
)}
</div>
<div class="card-details_block">
<h1>Комментарии</h1>
{cardDetails.comments.length && <h1>Комментарии</h1>}
{commentInput ? (
<>
<Input
Expand Down Expand Up @@ -366,7 +366,9 @@ export const CardDetailsContainer = (props: ComponentProps) => {
/>
</div>
<div class="card-details_block">
<h1>Назначенные пользователи</h1>
{cardDetails.assignedUsers.length && (
<h1>Назначенные пользователи</h1>
)}
{cardDetails.assignedUsers.map((u) => {
return (
<div className="assigned-user">
Expand Down
5 changes: 0 additions & 5 deletions src/containers/cardDetails.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@
gap: 20px;
}

.card-details_block {
min-height: 140px;
max-width: 450px;
}

.card-details__left-section {
width: 60%;
display: flex;
Expand Down
11 changes: 0 additions & 11 deletions src/routes/routes.ts

This file was deleted.

38 changes: 35 additions & 3 deletions src/routes/routesFlag.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,65 @@
import { loadBoard } from '@/stores/activeBoardStore';
import { updateBoards } from '@/stores/boardsStore';
import {
loadBoardInvitePreview,
loadCardPreview,
} from '@/stores/previewStore';

export interface RouterFlags {
isHome: boolean;
isApp: boolean;
isPoll: boolean;
isPreview: boolean; // Является ли просмотром карточки по ссылке или просмотром приглашения
isCardPreview: boolean;
isBoardPreview: boolean;
cardUuid: string | undefined;
boardInviteUuid: string | undefined;
isCsatResults: boolean;
boardId: number | undefined;
}

export const getFlagRoutes = (currentPath: string): RouterFlags => {
let boardId: number | undefined = undefined;
if (currentPath.startsWith('/app')) {
let cardUuid: string | undefined;
let boardInviteUuid: string | undefined;

const isBoardPreview = currentPath.startsWith('/inviteBoard');
const isCardPreview = currentPath.startsWith('/card');
const isApp =
currentPath.startsWith('/app') || isBoardPreview || isCardPreview;
if (isApp) {
if (currentPath.startsWith('/app/board_')) {
boardId = parseInt(currentPath.slice('/app/board_'.length));
} else {
boardId = undefined;
}
}
if (currentPath.startsWith('/app')) {

if (isApp && !(isCardPreview || isBoardPreview)) {
updateBoards();
loadBoard(boardId);
}

if (isCardPreview) {
cardUuid = currentPath.slice('/card/'.length);
loadCardPreview(cardUuid);
}

if (isBoardPreview) {
boardInviteUuid = currentPath.slice('/inviteBoard/'.length);
loadBoardInvitePreview(boardInviteUuid);
}

return {
isHome: ['/login', '/register', '/'].indexOf(currentPath) !== -1,
isCsatResults: currentPath === '/csat_results',
isPoll: currentPath === '/csat_poll',
isApp: currentPath.startsWith('/app'),
isApp,
boardId,
boardInviteUuid,
cardUuid,
isPreview: isBoardPreview || isCardPreview,
isBoardPreview,
isCardPreview,
};
};
Loading

0 comments on commit 820a441

Please sign in to comment.