mirror of
https://github.com/hcengineering/platform.git
synced 2026-10-01 14:05:05 +02:00
Kanban keyboard shortcuts (#1469)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user