Files
huly-platform/plugins/board-resources/src/components/KanbanView.svelte
T

160 lines
4.4 KiB
Svelte

<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { Card } from '@hcengineering/board'
import {
CategoryType,
Class,
Doc,
DocumentQuery,
DocumentUpdate,
FindOptions,
Ref,
Status,
WithLookup
} from '@hcengineering/core'
import { Kanban as KanbanUI } from '@hcengineering/kanban'
import { ActionContext, createQuery } from '@hcengineering/presentation'
import type { DocWithRank, Project } from '@hcengineering/task'
import task, { getStates } from '@hcengineering/task'
import { typeStore } from '@hcengineering/task-resources'
import {
ListSelectionProvider,
SelectDirection,
focusStore,
getCategoryQueryNoLookup,
getGroupByValues,
groupBy,
setGroupByValues,
showMenu,
statusStore
} from '@hcengineering/view-resources'
import { onMount } from 'svelte'
import KanbanCard from './KanbanCard.svelte'
import ListHeader from './ListHeader.svelte'
import AddCard from './add-card/AddCard.svelte'
export let _class: Ref<Class<Card>>
export let space: Ref<Project>
export let query: DocumentQuery<Card>
export let options: FindOptions<Card> | undefined
let _space: Project
let states: Status[] = []
const spaceQuery = createQuery()
$: spaceQuery.query(task.class.Project, { _id: space }, (result) => {
_space = result[0]
})
$: states = getStates(_space, $typeStore, $statusStore.byId)
function castObject (object: any): WithLookup<Card> {
return object as WithLookup<Card>
}
let kanbanUI: KanbanUI
const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => {
kanbanUI?.select(offset, of, dir)
})
onMount(() => {
;(document.activeElement as HTMLElement)?.blur()
})
const selection = listProvider.selection
let resultQuery: DocumentQuery<Card>
$: resultQuery = { ...query, isArchived: { $ne: true }, space }
const cardQuery = createQuery()
let cards: Card[] = []
$: cardQuery.query<Card>(
_class,
getCategoryQueryNoLookup(resultQuery),
(result) => {
cards = result
},
{
...options
}
)
$: listProvider.update(cards)
$: groupByDocs = groupBy(cards, 'status')
const getUpdateProps = (doc: Doc, category: CategoryType): DocumentUpdate<DocWithRank> | undefined => {
const groupValue =
typeof category === 'object' ? category.values.find((it) => it.space === doc.space)?._id : category
if (groupValue === undefined) {
return undefined
}
return {
status: groupValue,
space: doc.space
} as any
}
</script>
<ActionContext
context={{
mode: 'browser'
}}
/>
{states.length}
<KanbanUI
bind:this={kanbanUI}
objects={cards}
getGroupByValues={(groupByDocs, category) => getGroupByValues(groupByDocs, category)}
{setGroupByValues}
categories={states.map((it) => it._id)}
on:obj-focus={(evt) => {
listProvider.updateFocus(evt.detail.object)
}}
{groupByDocs}
{getUpdateProps}
{_class}
query={resultQuery}
{options}
groupByKey={'status'}
checked={$selection ?? []}
on:check={(evt) => {
listProvider.updateSelection(evt.detail.docs, evt.detail.value)
}}
on:contextmenu={(evt) => {
showMenu(evt.detail.evt, { object: evt.detail.objects })
}}
selection={listProvider.current($focusStore)}
>
<svelte:fragment slot="card" let:object>
<KanbanCard object={castObject(object)} />
</svelte:fragment>
<svelte:fragment slot="header" let:state>
{@const st = states.find((it) => it._id === state)}
{#if st}
<ListHeader state={st} />
{/if}
</svelte:fragment>
<svelte:fragment slot="afterCard" let:state={targetState}>
{@const st = states.find((it) => it._id === targetState)}
{#if st}
<AddCard {space} state={st} />
{/if}
</svelte:fragment>
</KanbanUI>