Kanban keyboard shortcuts (#1469)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev
2022-04-21 14:40:15 +07:00
committed by GitHub
parent 1371131c4d
commit ea6d9d1517
14 changed files with 420 additions and 163 deletions
@@ -13,14 +13,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { Class, FindOptions, Ref, SortingOrder } from '@anticrm/core'
import { Class, Doc, FindOptions, Ref, SortingOrder } from '@anticrm/core'
import { Kanban as KanbanUI } from '@anticrm/kanban'
import { getResource } from '@anticrm/platform'
import { createQuery, getClient } from '@anticrm/presentation'
import type { Kanban, SpaceWithStates, State, Task } from '@anticrm/task'
import task from '@anticrm/task'
import { showPopup } from '@anticrm/ui'
import { ActionContext, focusStore, ListSelectionProvider, selectionStore } from '@anticrm/view-resources'
import Menu from '@anticrm/view-resources/src/components/Menu.svelte'
import { onMount } from 'svelte'
import KanbanDragDone from './KanbanDragDone.svelte'
export let _class: Ref<Class<Task>>
@@ -28,6 +31,7 @@
// export let open: AnyComponent
export let search: string
export let options: FindOptions<Task> | undefined
export let baseMenuClass: Ref<Class<Doc>> | undefined = undefined
// export let config: string[]
let kanban: Kanban
@@ -36,35 +40,107 @@
const client = getClient()
const kanbanQuery = createQuery()
$: kanbanQuery.query(task.class.Kanban, { attachedTo: space }, result => { kanban = result[0] })
$: kanbanQuery.query(task.class.Kanban, { attachedTo: space }, (result) => {
kanban = result[0]
})
const statesQuery = createQuery()
$: if (kanban !== undefined) {
statesQuery.query(task.class.State, { space: kanban.space }, result => { states = result }, {
sort: {
rank: SortingOrder.Ascending
statesQuery.query(
task.class.State,
{ space: kanban.space },
(result) => {
states = result
},
{
sort: {
rank: SortingOrder.Ascending
}
}
})
)
}
$: clazz = client.getHierarchy().getClass(_class)
$: presenterMixin = client.getHierarchy().as(clazz, task.mixin.KanbanCard)
$: cardPresenter = getResource(presenterMixin.card)
/* eslint-disable no-undef */
let kanbanUI: KanbanUI
const listProvider = new ListSelectionProvider(
(pos, dir) => {
if (dir === 'vertical') {
// Select next
kanbanUI.selectStatePosition(pos, 'down')
} else {
kanbanUI.selectStatePosition(pos, 'right')
}
},
(pos, dir) => {
// Select prev
if (dir === 'vertical') {
kanbanUI.selectStatePosition(pos, 'up')
} else {
kanbanUI.selectStatePosition(pos, 'left')
}
}
)
onMount(() => {
(document.activeElement as HTMLElement)?.blur()
})
const showMenu = async (ev: MouseEvent, items: Doc[]): Promise<void> => {
ev.preventDefault()
showPopup(Menu, { object: items, baseMenuClass }, {
getBoundingClientRect: () => DOMRect.fromRect({ width: 1, height: 1, x: ev.clientX, y: ev.clientY })
}, () => {
// selection = undefined
})
}
</script>
{#await cardPresenter then presenter}
<KanbanUI {_class} {space} {search} {options} query={{ doneState: null }} states={states}
fieldName={'state'} rankFieldName={'rank'}>
<svelte:fragment slot='card' let:object let:dragged>
<svelte:component this={presenter} {object} {dragged}/>
<ActionContext
context={{
mode: 'browser'
}}
/>
<KanbanUI
bind:this={kanbanUI}
{_class}
{space}
{search}
{options}
query={{ doneState: null }}
{states}
fieldName={'state'}
rankFieldName={'rank'}
on:content={(evt) => {
listProvider.update(evt.detail)
}}
on:obj-focus={(evt) => {
listProvider.updateFocus(evt.detail)
}}
checked={$selectionStore ?? []}
on:check={(evt) => {
listProvider.updateSelection(evt.detail.docs, evt.detail.value)
}}
on:contextmenu={(evt) => showMenu(evt.detail.evt, evt.detail.objects)}
selection={listProvider.current($focusStore)}
>
<svelte:fragment slot="card" let:object let:dragged>
<svelte:component this={presenter} {object} {dragged} />
</svelte:fragment>
// eslint-disable-next-line no-undef
<svelte:fragment slot='doneBar' let:onDone>
<KanbanDragDone {kanban} on:done={(e) => {
// eslint-disable-next-line no-undef
onDone({ doneState: e.detail._id })
}} />
<svelte:fragment slot="doneBar" let:onDone>
<KanbanDragDone
{kanban}
on:done={(e) => {
// eslint-disable-next-line no-undef
onDone({ doneState: e.detail._id })
}}
/>
</svelte:fragment>
</KanbanUI>
{/await}