Skip to content

Commit

Permalink
fix: improve task realtime update handling
Browse files Browse the repository at this point in the history
  • Loading branch information
iamrishupatel committed Jun 13, 2023
1 parent 7825183 commit 926edfd
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 31 deletions.
12 changes: 12 additions & 0 deletions src/lib/api/appwrite/tasks.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,13 @@ export const updateTaskTitle = async (
taskId: string,
taskTitle: string,
boardId: string,
prevStatusId: string,
): Promise<void> => {
try {
await checkForBoardAccess(boardId);
await db.updateDocument(KRELLO_DB_ID, TASK_COLLECTION_ID, taskId, {
title: taskTitle,
prevStatusId,
});
} catch (e: any) {
console.error(e);
Expand All @@ -127,11 +129,13 @@ export const updateTaskPriority = async (
taskId: string,
priority: string,
boardId: string,
prevStatusId: string,
): Promise<void> => {
try {
await checkForBoardAccess(boardId);
await db.updateDocument(KRELLO_DB_ID, TASK_COLLECTION_ID, taskId, {
priority,
prevStatusId,
});
} catch (e: any) {
console.error(e);
Expand All @@ -143,11 +147,13 @@ export const updateTaskDescription = async (
taskId: string,
description: string,
boardId: string,
prevStatusId: string,
): Promise<void> => {
try {
await checkForBoardAccess(boardId);
await db.updateDocument(KRELLO_DB_ID, TASK_COLLECTION_ID, taskId, {
description,
prevStatusId,
});
toast.success('Task description updated successfully');
} catch (e) {
Expand All @@ -161,11 +167,13 @@ export const addLabelInTask = async (
newLabelId: string,
labels: CardLabel[],
boardId: string,
prevStatusId: string,
): Promise<void> => {
try {
await checkForBoardAccess(boardId);
await db.updateDocument(KRELLO_DB_ID, TASK_COLLECTION_ID, taskId, {
labels: [...labels.map((label) => label.id), newLabelId],
prevStatusId,
});
toast.success('Task updated successfully');
} catch (e) {
Expand All @@ -179,11 +187,13 @@ export const removeLabelInTask = async (
removedLabelId: string,
labels: CardLabel[],
boardId: string,
prevStatusId: string,
): Promise<void> => {
try {
await checkForBoardAccess(boardId);
await db.updateDocument(KRELLO_DB_ID, TASK_COLLECTION_ID, taskId, {
labels: labels.filter((oldLabel) => oldLabel.id !== removedLabelId).map((label) => label.id),
prevStatusId,
});
toast.success('Task updated successfully');
} catch (e) {
Expand All @@ -196,6 +206,7 @@ export const updateTaskCoverUrl = async (
taskDocId: string,
cover: string | File,
boardId: string,
prevStatusId: string,
): Promise<string> => {
await checkForBoardAccess(boardId);
let coverUrl;
Expand All @@ -207,6 +218,7 @@ export const updateTaskCoverUrl = async (

await db.updateDocument(KRELLO_DB_ID, TASK_COLLECTION_ID, taskDocId, {
coverUrl,
prevStatusId,
});
return coverUrl;
};
Expand Down
65 changes: 51 additions & 14 deletions src/lib/components/TaskDetails/TaskDetails.component.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script lang="ts">
import { Badge, Button, Dropzone, Modal, Spinner } from 'flowbite-svelte';
import type { Task } from '$types/kanban';
import TaskTitle from './TaskTitle.component.svelte';
import TaskStatus from './TaskStatus.component.svelte';
import TaskDescription from './TaskDescription.component.svelte';
import TaskPriority from './TaskPriority.component.svelte';
import TaskTitle from './components/TaskTitle.component.svelte';
import TaskStatus from './components/TaskStatus.component.svelte';
import TaskDescription from './components/TaskDescription.component.svelte';
import TaskPriority from './components/TaskPriority.component.svelte';
import SelectLabel from '$components/NewTask/SelectLabel.component.svelte';
import {
addLabelInTask,
Expand All @@ -13,17 +13,37 @@
} from '$lib/api/appwrite/tasks.api';
import type { CardLabel } from '$types/card';
import Icon from '@iconify/svelte';
import CoverUploader from './CoverUploader.component.svelte';
import CoverUploader from './components/CoverUploader.component.svelte';
import { Status } from '$enums/Status.enums';
import toast from 'svelte-french-toast';
import TaskActivity from './TaskActivity.component.svelte';
import TaskActivity from './components/TaskActivity.component.svelte';
import { onDestroy } from 'svelte';
import type { Board } from '$lib/types/board';
import boardStore from '$lib/store/boards.store';
import { kanbanStore } from '$lib/store';
export let taskDetails: Task | null,
isModalOpen = false;
const unsubscribe = kanbanStore.subscribe((store) => {
store.kanbanBoard;
// Iterate over each column in the kanban board
for (const columnId in store.kanbanBoard) {
const columnData = store.kanbanBoard[columnId];
const { tasks } = columnData;
// Iterate over the tasks in the current column
for (const task of tasks) {
if (task.id === taskDetails?.id) {
taskDetails = task;
}
}
}
});
onDestroy(unsubscribe);
let currentBoard: Board;
const unsub = boardStore.subscribe((store) => {
currentBoard = store.currentBoard as Board;
Expand All @@ -34,13 +54,25 @@
const hanldeAddLabel = async (e: CustomEvent): Promise<void> => {
if (!taskDetails) return;
const newLabel = e.detail as CardLabel;
await addLabelInTask(taskDetails.id, newLabel.id, taskDetails.labels, currentBoard.id);
await addLabelInTask(
taskDetails.id,
newLabel.id,
taskDetails.labels,
currentBoard.id,
taskDetails.status.id,
);
};
const hanldeRemoveLabel = async (e: MouseEvent): Promise<void> => {
if (!taskDetails) return;
const removedLabelId = (e.currentTarget as HTMLButtonElement).id;
await removeLabelInTask(taskDetails?.id, removedLabelId, taskDetails.labels, currentBoard.id);
await removeLabelInTask(
taskDetails?.id,
removedLabelId,
taskDetails.labels,
currentBoard.id,
taskDetails.status.id,
);
};
// file uploads
Expand Down Expand Up @@ -76,7 +108,12 @@
coverUplaodStatus = Status.LOADING;
try {
if (taskDetails && taskDetails.id && imageFile) {
await updateTaskCoverUrl(taskDetails?.id, imageFile, currentBoard.id);
await updateTaskCoverUrl(
taskDetails?.id,
imageFile,
currentBoard.id,
taskDetails.status.id,
);
}
toast.success('Cover updated successfully');
} catch (e: any) {
Expand Down Expand Up @@ -138,9 +175,9 @@
{/if}

<div class="flex flex-col gap-y-2">
<TaskTitle taskId={taskDetails.id} title={taskDetails.title} />
<TaskStatus status={taskDetails.status} taskId={taskDetails.id} />
<TaskPriority priority={taskDetails.priority} taskId={taskDetails.id} />
<TaskTitle {taskDetails} />
<TaskStatus {taskDetails} />
<TaskPriority {taskDetails} />

{#if taskDetails.labels.length > 0}
<div class="flex mt-2 items-center gap-4">
Expand Down Expand Up @@ -171,7 +208,7 @@

<div class="flex gap-8">
<section class="flex-1 flex flex-col gap-y-4">
<TaskDescription taskDescription={taskDetails.description} taskId={taskDetails.id} />
<TaskDescription {taskDetails} />
</section>

<section class="w-80 flex flex-col gap-4">
Expand All @@ -180,7 +217,7 @@
</section>
</div>

<TaskActivity taskId={taskDetails.id} />
<TaskActivity {taskDetails} />
</div>
</Modal>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@
import type { CommentDoc } from '$types/appwriteDocs.types';
import type { AuthState, UserDetails } from '$types/authStore';
import type { CreateCommentFormValues } from '$types/formValues';
import type { CommentType } from '$types/kanban';
import type { CommentType, Task } from '$types/kanban';
import { createCommentValidationSchema } from '$lib/validations/task.validations';
import Icon from '@iconify/svelte';
import { Avatar, Helper, Spinner } from 'flowbite-svelte';
import { Textarea, Button } from 'flowbite-svelte';
import { onDestroy, onMount } from 'svelte';
import { createForm } from 'svelte-forms-lib';
export let taskId: string;
export let taskDetails: Task;
let taskId = taskDetails.id;
let userDetails: UserDetails = $authStore.userDetails;
let isAnonymous: boolean = $authStore.isAnonymous;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
import { onDestroy } from 'svelte';
import type { Board } from '$lib/types/board';
import boardStore from '$lib/store/boards.store';
import type { Task } from '$lib/types/kanban';
export let taskDescription = '',
taskId: string;
export let taskDetails: Task;
let taskDescription = taskDetails.description;
let markdownContent = taskDetails.description;
const taskId = taskDetails.id;
let isEditing = false;
let currentBoard: Board;
Expand All @@ -29,13 +33,22 @@
description: taskDescription ?? '',
},
onSubmit: async (values) => {
await updateTaskDescription(taskId, values.description, currentBoard.id);
await updateTaskDescription(
taskId,
values.description,
currentBoard.id,
taskDetails.status.id,
);
markdownContent = values.description;
isEditing = false;
},
});
const handleCancel = (): void => {
form.update((prev) => ({ ...prev, description: taskDescription ?? '' }));
isEditing = false;
// markdownContent = taskDescription ?? '';
};
</script>

Expand Down Expand Up @@ -98,7 +111,7 @@
</div>
</form>
{:else}
<div class={`${styles.markdown} mt-4`}>
<SvelteMarkdown source={taskDescription ?? ''} />
<div class={`${styles.markdown}`}>
<SvelteMarkdown source={markdownContent ?? ''} />
</div>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import { updateTaskPriority } from '$lib/api/appwrite/tasks.api';
import boardStore from '$lib/store/boards.store';
import type { Board } from '$lib/types/board';
import type { TaskPriority } from '$types/kanban';
import type { Task } from '$types/kanban';
import { Select } from 'flowbite-svelte';
import { onDestroy } from 'svelte';
export let taskId: string;
export let priority: TaskPriority | null;
export let taskDetails: Task;
let priority = taskDetails.priority;
let currentBoard: Board;
const unsub = boardStore.subscribe((store) => {
Expand All @@ -26,7 +27,7 @@
const hanldeChange = async (e: Event): Promise<void> => {
const target = e.target as HTMLSelectElement;
await updateTaskPriority(taskId, target.value, currentBoard.id);
await updateTaskPriority(taskDetails.id, target.value, currentBoard.id, taskDetails.status.id);
};
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import { kanbanStore } from '$lib/store';
import boardStore from '$lib/store/boards.store';
import type { Board } from '$lib/types/board';
import type { TaskStatus } from '$types/kanban';
import type { Task, TaskStatus } from '$types/kanban';
import { Select } from 'flowbite-svelte';
import { onDestroy } from 'svelte';
export let taskId: string;
export let status: TaskStatus;
export let taskDetails: Task;
let taskId: string = taskDetails.id;
let status: TaskStatus = taskDetails.status;
let currentBoard: Board;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@
import { updateTaskTitle } from '$lib/api/appwrite/tasks.api';
import type { Board } from '$lib/types/board';
import boardStore from '$lib/store/boards.store';
import type { Task } from '$lib/types/kanban';
export let taskId: string, title: string;
export let taskDetails: Task;
const taskId = taskDetails.id,
title = taskDetails.title;
let currentBoard: Board;
const unsub = boardStore.subscribe((store) => {
currentBoard = store.currentBoard as Board;
});
onDestroy(unsub);
let isEditing = false;
Expand Down Expand Up @@ -47,7 +52,13 @@
const hanldeTaskTitleChange = (e: Event): void => {
const target = e.target as HTMLInputElement;
const update = updateTaskTitle.bind(null, taskId, target.value, currentBoard.id);
const update = updateTaskTitle.bind(
null,
taskId,
target.value,
currentBoard.id,
taskDetails.status.id,
);
lodash.debounce(update, 100)();
};
</script>
Expand Down
2 changes: 1 addition & 1 deletion src/lib/sass/markdown.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

/* Paragraph */
p {
margin: 1em 0;
line-height: 16px;
}

/* Links */
Expand Down
1 change: 1 addition & 0 deletions src/lib/store/kanbanBoard.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const addNewTaskInStore = (newTask: Task): void => {
};

export const updateTask = (updatedTask: Task): void => {
console.log('updateTask', updatedTask);
kanbanStore.update((prevStore) => {
const canUpdate =
Object.hasOwn(prevStore.kanbanBoard, updatedTask.prevStatusId) &&
Expand Down

0 comments on commit 926edfd

Please sign in to comment.