mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-14 20:39:03 +00:00
Board: Add convert checklist to card action (#1805)
This commit is contained in:
parent
549949b392
commit
0e11085407
@ -420,6 +420,24 @@ export function createModel (builder: Builder): void {
|
||||
builder.mixin(board.class.Card, core.class.Class, view.mixin.IgnoreActions, {
|
||||
actions: [view.action.Delete, task.action.Move]
|
||||
})
|
||||
|
||||
// TODO: update query when nested query is available
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
action: board.actionImpl.ConvertToCard,
|
||||
label: board.string.ConvertToCard,
|
||||
icon: board.icon.Card,
|
||||
category: board.category.Card,
|
||||
query: {
|
||||
attachedToClass: task.class.TodoItem
|
||||
},
|
||||
input: 'any',
|
||||
target: task.class.TodoItem,
|
||||
context: { mode: ['context', 'browser'] }
|
||||
},
|
||||
board.action.ConvertToCard
|
||||
)
|
||||
}
|
||||
|
||||
export { boardOperation } from './migration'
|
||||
|
@ -20,7 +20,7 @@ import type { Ref, Space } from '@anticrm/core'
|
||||
import { IntlString, mergeIds } from '@anticrm/platform'
|
||||
import { KanbanTemplate, Sequence } from '@anticrm/task'
|
||||
import type { AnyComponent } from '@anticrm/ui'
|
||||
import { ViewletDescriptor } from '@anticrm/view'
|
||||
import { Action, ViewAction, ViewletDescriptor } from '@anticrm/view'
|
||||
|
||||
export default mergeIds(boardId, board, {
|
||||
component: {
|
||||
@ -55,6 +55,13 @@ export default mergeIds(boardId, board, {
|
||||
Table: '' as Ref<ViewletDescriptor>
|
||||
},
|
||||
string: {
|
||||
CommonBoardPreference: '' as IntlString
|
||||
CommonBoardPreference: '' as IntlString,
|
||||
ConvertToCard: '' as IntlString
|
||||
},
|
||||
action: {
|
||||
ConvertToCard: '' as Ref<Action>
|
||||
},
|
||||
actionImpl: {
|
||||
ConvertToCard: '' as ViewAction
|
||||
}
|
||||
})
|
||||
|
@ -106,6 +106,7 @@
|
||||
"Size": "Size",
|
||||
"RemoveCover": "Remove cover",
|
||||
"DeleteChecklist": "Delete checklist",
|
||||
"DeleteChecklistConfirm": "Deleting a checklist is permanent and there is no way to get it back."
|
||||
"DeleteChecklistConfirm": "Deleting a checklist is permanent and there is no way to get it back.",
|
||||
"ConvertToCard": "Convert to card"
|
||||
}
|
||||
}
|
||||
|
@ -106,6 +106,7 @@
|
||||
"Size": "Размер",
|
||||
"RemoveCover": "Удалить обложку",
|
||||
"DeleteChecklist": "Удалить список задач",
|
||||
"DeleteChecklistConfirm": "Удаление списка задач необратимо, и не будет возможности его вернуть."
|
||||
"DeleteChecklistConfirm": "Удаление списка задач необратимо, и не будет возможности его вернуть.",
|
||||
"ConvertToCard": "Конвертировать в карточку"
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@
|
||||
}
|
||||
|
||||
function showItemMenu (item: TodoItem, e?: Event) {
|
||||
showPopup(ContextMenu, { object: item, baseMenuClass: board.class.Card }, getPopupAlignment(e))
|
||||
showPopup(ContextMenu, { object: item }, getPopupAlignment(e))
|
||||
}
|
||||
|
||||
$: checklistItemsQuery.query(task.class.TodoItem, { space: value.space, attachedTo: value._id }, (result) => {
|
||||
|
@ -10,7 +10,7 @@
|
||||
export let size: 'small' | 'medium' | 'large' = 'small'
|
||||
|
||||
const todoListQuery = createQuery()
|
||||
let todoLists: Ref<TodoItem>[]
|
||||
let todoLists: Ref<TodoItem>[] = []
|
||||
$: todoListQuery.query(task.class.TodoItem, { space: value.space, attachedTo: value._id }, (result) => {
|
||||
todoLists = result.map(({ _id }) => _id)
|
||||
})
|
||||
@ -19,6 +19,7 @@
|
||||
$: query.query(task.class.TodoItem, { space: value.space, attachedTo: { $in: todoLists } }, (result) => {
|
||||
total = result.total
|
||||
done = result.filter((t) => t.done).length
|
||||
if (!total) return
|
||||
item = result.reduce((min, cur) =>
|
||||
cur.dueTo === null ? min : min.dueTo === null || cur.dueTo < min.dueTo ? cur : min
|
||||
)
|
||||
|
@ -14,6 +14,9 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
import { Resources } from '@anticrm/platform'
|
||||
import { TodoItem } from '@anticrm/task'
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import board from '@anticrm/board'
|
||||
|
||||
import BoardPresenter from './components/BoardPresenter.svelte'
|
||||
import CardPresenter from './components/CardPresenter.svelte'
|
||||
@ -37,6 +40,23 @@ import TableView from './components/TableView.svelte'
|
||||
import UserBoxList from './components/UserBoxList.svelte'
|
||||
import CardLabels from './components/editor/CardLabels.svelte'
|
||||
import CardCoverEditor from './components/popups/CardCoverEditor.svelte'
|
||||
import { createCard, getCardFromTodoItem } from './utils/CardUtils'
|
||||
|
||||
async function ConvertToCard (object: TodoItem): Promise<void> {
|
||||
const client = getClient()
|
||||
const todoItemCard = await getCardFromTodoItem(client, object)
|
||||
if (todoItemCard === undefined) return
|
||||
const date =
|
||||
object.dueTo === null
|
||||
? {}
|
||||
: { date: { _class: board.class.CardDate, dueDate: object.dueTo, isChecked: object.done } }
|
||||
await createCard(client, todoItemCard.space, todoItemCard.state, {
|
||||
title: object.name,
|
||||
assignee: object.assignee,
|
||||
...date
|
||||
})
|
||||
await client.remove(object)
|
||||
}
|
||||
|
||||
export default async (): Promise<Resources> => ({
|
||||
component: {
|
||||
@ -63,5 +83,8 @@ export default async (): Promise<Resources> => ({
|
||||
CoverActionPopup: CardCoverEditor,
|
||||
MoveActionPopup: MoveCard,
|
||||
CopyActionPopup: CopyCard
|
||||
},
|
||||
actionImpl: {
|
||||
ConvertToCard
|
||||
}
|
||||
})
|
||||
|
@ -1,10 +1,58 @@
|
||||
import { Card } from '@anticrm/board'
|
||||
import { Employee, EmployeeAccount } from '@anticrm/contact'
|
||||
import { TxOperations as Client, TxResult, getCurrentAccount, Ref } from '@anticrm/core'
|
||||
import {
|
||||
TxOperations as Client,
|
||||
TxResult,
|
||||
getCurrentAccount,
|
||||
Ref,
|
||||
Space,
|
||||
AttachedData,
|
||||
SortingOrder
|
||||
} from '@anticrm/core'
|
||||
import { showPanel } from '@anticrm/ui'
|
||||
|
||||
import task, { calcRank, State, TodoItem } from '@anticrm/task'
|
||||
import board from '../plugin'
|
||||
|
||||
export async function createCard (
|
||||
client: Client,
|
||||
space: Ref<Space>,
|
||||
state: Ref<State>,
|
||||
attribues: Partial<AttachedData<Card>>
|
||||
): Promise<Ref<Card>> {
|
||||
const sequence = await client.findOne(task.class.Sequence, { attachedTo: board.class.Card })
|
||||
if (sequence === undefined) {
|
||||
throw new Error('sequence object not found')
|
||||
}
|
||||
|
||||
const lastOne = await client.findOne(board.class.Card, { state }, { sort: { rank: SortingOrder.Descending } })
|
||||
const incResult = await client.update(sequence, { $inc: { sequence: 1 } }, true)
|
||||
|
||||
const value: AttachedData<Card> = {
|
||||
title: '',
|
||||
state,
|
||||
doneState: null,
|
||||
number: (incResult as any).object.sequence,
|
||||
rank: calcRank(lastOne, undefined),
|
||||
assignee: null,
|
||||
description: '',
|
||||
labels: [],
|
||||
...attribues
|
||||
}
|
||||
|
||||
return await client.addCollection(board.class.Card, space, space, board.class.Board, 'cards', value)
|
||||
}
|
||||
|
||||
export async function getCardFromTodoItem (client: Client, todoItem: TodoItem | undefined): Promise<Card | undefined> {
|
||||
if (todoItem === undefined) return
|
||||
if (todoItem.attachedToClass === todoItem._class) {
|
||||
return await getCardFromTodoItem(
|
||||
client,
|
||||
await client.findOne(todoItem._class, { _id: todoItem.attachedTo as Ref<TodoItem> })
|
||||
)
|
||||
}
|
||||
return await client.findOne(board.class.Card, { _id: todoItem.attachedTo as Ref<Card> })
|
||||
}
|
||||
|
||||
export function updateCard (client: Client, card: Card, field: string, value: any): Promise<TxResult> | undefined {
|
||||
if (card === undefined) {
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user