From bbcbb7722aad4c1c04d49ce384c5473371effcc7 Mon Sep 17 00:00:00 2001 From: Anna No Date: Thu, 26 May 2022 16:36:44 +0700 Subject: [PATCH] Board: Checklist item dnd support (#1873) Signed-off-by: Anna No --- models/task/src/index.ts | 4 +- .../components/editor/CardChecklist.svelte | 68 ++++++++++++++++--- .../src/components/popups/AddChecklist.svelte | 15 ++-- .../src/components/todos/CreateTodo.svelte | 29 ++++++-- .../src/components/todos/Todos.svelte | 5 +- plugins/task/src/index.ts | 2 +- 6 files changed, 100 insertions(+), 23 deletions(-) diff --git a/models/task/src/index.ts b/models/task/src/index.ts index f294d96145..30268d5526 100644 --- a/models/task/src/index.ts +++ b/models/task/src/index.ts @@ -125,7 +125,7 @@ export class TTask extends TAttachedDoc implements Task { todoItems!: number } -@Model(task.class.TodoItem, core.class.AttachedDoc, DOMAIN_TASK) +@Model(task.class.TodoItem, core.class.AttachedDoc, DOMAIN_TASK, [task.interface.DocWithRank]) @UX(task.string.Todo) export class TTodoItem extends TAttachedDoc implements TodoItem { @Prop(TypeMarkup(), task.string.TodoName, task.icon.Task) @@ -143,6 +143,8 @@ export class TTodoItem extends TAttachedDoc implements TodoItem { @Prop(Collection(task.class.TodoItem), task.string.Todos) items!: number + + declare rank: string } @Model(task.class.SpaceWithStates, core.class.Space) diff --git a/plugins/board-resources/src/components/editor/CardChecklist.svelte b/plugins/board-resources/src/components/editor/CardChecklist.svelte index 2b21d96957..c8fe43b72c 100644 --- a/plugins/board-resources/src/components/editor/CardChecklist.svelte +++ b/plugins/board-resources/src/components/editor/CardChecklist.svelte @@ -16,7 +16,7 @@ import { Ref } from '@anticrm/core' import { createQuery, getClient, UserBox, MessageBox } from '@anticrm/presentation' import type { TodoItem } from '@anticrm/task' - import task from '@anticrm/task' + import task, { calcRank } from '@anticrm/task' import { Button, CheckBox, @@ -45,7 +45,9 @@ let hideDoneItems: boolean = false let newItemName = '' let editingItemId: Ref | undefined = undefined - let hovered: Ref | undefined + let hovered: Ref | undefined = undefined + let dragItem: TodoItem | undefined = undefined + let dragOverItem: TodoItem | undefined = undefined function deleteChecklist () { if (!value) { @@ -79,11 +81,13 @@ async function addItem (event: CustomEvent) { newItemName = '' + const prev = checklistItems && checklistItems.length > 0 ? checklistItems[checklistItems.length - 1] : undefined const item = { name: event.detail ?? '', assignee: null, dueTo: null, - done: false + done: false, + rank: calcRank(prev, undefined) } if (item.name.length <= 0) { return @@ -121,16 +125,49 @@ showPopup(ContextMenu, { object: item }, getEventPopupPositionElement(e)) } - $: checklistItemsQuery.query(task.class.TodoItem, { space: value.space, attachedTo: value._id }, (result) => { - checklistItems = result - done = checklistItems.reduce((result: number, current: TodoItem) => { - return current.done ? result + 1 : result - }, 0) - }) + function itemDrop (): void { + if (dragItem === undefined || dragOverItem === undefined || dragItem._id === dragOverItem._id) { + return + } + const index = checklistItems.findIndex((item) => item._id === dragOverItem?._id) + const dragIndex = checklistItems.findIndex((item) => item._id === dragItem?._id) + if (dragIndex > index) { + const prev = index - 1 >= 0 ? checklistItems[index - 1] : undefined + dragItem.rank = calcRank(prev, dragOverItem) + client.update(dragItem, { rank: dragItem.rank }) + } else { + const next = index + 1 < checklistItems.length ? checklistItems[index + 1] : undefined + dragItem.rank = calcRank(dragOverItem, next) + client.update(dragItem, { rank: dragItem.rank }) + } + } + + $: checklistItemsQuery.query( + task.class.TodoItem, + { space: value.space, attachedTo: value._id }, + (result) => { + checklistItems = result + done = checklistItems.reduce((result: number, current: TodoItem) => { + return current.done ? result + 1 : result + }, 0) + }, + { + sort: { + rank: 1 + } + } + ) {#if value !== undefined} -
+
{ + itemDrop() + }} + on:dragover|preventDefault + on:dragleave + >
{#if isEditingName}
@@ -178,6 +215,17 @@
{ + dragItem = item + }} + on:dragend={() => { + dragItem = undefined + dragOverItem = undefined + }} + on:dragover={() => { + dragOverItem = item + }} on:mouseover={() => { hovered = item._id }} diff --git a/plugins/board-resources/src/components/popups/AddChecklist.svelte b/plugins/board-resources/src/components/popups/AddChecklist.svelte index d5a97791b0..ae9d377dac 100644 --- a/plugins/board-resources/src/components/popups/AddChecklist.svelte +++ b/plugins/board-resources/src/components/popups/AddChecklist.svelte @@ -3,7 +3,7 @@ import { Card } from '@anticrm/board' import { WithLookup } from '@anticrm/core' - import task, { TodoItem } from '@anticrm/task' + import task, { calcRank, TodoItem } from '@anticrm/task' import { translate } from '@anticrm/platform' import presentation, { createQuery, getClient } from '@anticrm/presentation' import { Label, Button, Dropdown, EditBox, IconClose } from '@anticrm/ui' @@ -18,6 +18,7 @@ label: '' } + let lastCardList: TodoItem | undefined = undefined let name: string | undefined let selectedTemplate: ListItem | undefined = undefined let templateListItems: ListItem[] = [noneListItem] @@ -51,7 +52,8 @@ name, done: false, dueTo: null, - assignee: null + assignee: null, + rank: calcRank(lastCardList) } ) if (items.length > 0) { @@ -61,7 +63,8 @@ name: item.name, dueTo: item.dueTo, done: item.done, - assignee: item.assignee + assignee: item.assignee, + rank: item.rank }) ) ) @@ -75,13 +78,17 @@ (result: WithLookup[]) => { templateListItems = [noneListItem] templatesMap = new Map() + lastCardList = undefined for (const card of result) { const todoItems = card.$lookup?.todoItems as TodoItem[] if (!todoItems) { continue } - + if (card._id === value?._id && todoItems.length > 0) { + todoItems.sort((a, b) => a.rank?.localeCompare(b.rank)) + lastCardList = todoItems[todoItems.length - 1] + } templateListItems.push({ _id: card._id, label: card.title, diff --git a/plugins/task-resources/src/components/todos/CreateTodo.svelte b/plugins/task-resources/src/components/todos/CreateTodo.svelte index 2a34f1ef0c..966f52b317 100644 --- a/plugins/task-resources/src/components/todos/CreateTodo.svelte +++ b/plugins/task-resources/src/components/todos/CreateTodo.svelte @@ -14,9 +14,9 @@ --> diff --git a/plugins/task/src/index.ts b/plugins/task/src/index.ts index 6469b1ee34..b938c6650d 100644 --- a/plugins/task/src/index.ts +++ b/plugins/task/src/index.ts @@ -89,7 +89,7 @@ export interface Task extends AttachedDoc, DocWithRank { /** * @public */ -export interface TodoItem extends AttachedDoc { +export interface TodoItem extends AttachedDoc, DocWithRank { name: Markup assignee: Ref | null done: boolean