From f0a4edee490f05413df764db0f5486520fad2d84 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Sun, 23 Apr 2023 10:50:41 +0700 Subject: [PATCH] TSK-1309, TSK-1310, TSK-571 (#3048) Signed-off-by: Andrey Sobolev --- packages/kanban/src/components/Kanban.svelte | 4 +- .../kanban/src/components/KanbanRow.svelte | 4 +- .../ui/src/components/PanelInstance.svelte | 19 +-- packages/ui/src/utils.ts | 18 +++ .../src/components/KanbanView.svelte | 8 +- .../src/components/kanban/KanbanView.svelte | 6 +- .../src/components/issues/KanbanView.svelte | 7 +- .../timereport/TimeSpendReportsList.svelte | 2 +- .../src/components/Table.svelte | 2 +- .../src/components/list/List.svelte | 39 ++---- .../src/components/list/ListCategories.svelte | 118 +++++++++++++++--- .../src/components/list/ListCategory.svelte | 46 ++++--- .../src/components/list/ListItem.svelte | 17 ++- .../src/components/list/ListView.svelte | 10 +- 14 files changed, 199 insertions(+), 101 deletions(-) diff --git a/packages/kanban/src/components/Kanban.svelte b/packages/kanban/src/components/Kanban.svelte index 8e04fb415a..159c308129 100644 --- a/packages/kanban/src/components/Kanban.svelte +++ b/packages/kanban/src/components/Kanban.svelte @@ -210,7 +210,7 @@ } export function select (offset: 1 | -1 | 0, of?: Doc, dir?: 'vertical' | 'horizontal'): void { - let pos = (of !== undefined ? objects.findIndex((it) => it._id === of._id) : selection) ?? -1 + let pos = (of != null ? objects.findIndex((it) => it._id === of._id) : selection) ?? -1 if (pos === -1) { for (const st of categories) { const stateObjs = getGroupByValues(groupByDocs, st) ?? [] @@ -237,7 +237,7 @@ if (objState === -1) { return } - const stateObjs = getGroupByValues(groupByDocs, categories.indexOf(objState)) ?? [] + const stateObjs = getGroupByValues(groupByDocs, categories[objState]) ?? [] const statePos = stateObjs.findIndex((it) => it._id === obj._id) if (statePos === undefined) { return diff --git a/packages/kanban/src/components/KanbanRow.svelte b/packages/kanban/src/components/KanbanRow.svelte index c01b59e8a6..d5fda1741a 100644 --- a/packages/kanban/src/components/KanbanRow.svelte +++ b/packages/kanban/src/components/KanbanRow.svelte @@ -14,7 +14,7 @@ -->
(space ? { space } : {})} - {elementByIndex} - {indexById} {docs} {_class} {space} + {selection} query={resultQuery} {lookup} loadingPropsLength={getLoadingElementsLength(loadingProps, options)} {baseMenuClass} {config} {viewOptions} - {docByIndex} {viewOptionsConfig} {selectedObjectIds} level={0} @@ -167,6 +145,9 @@ {props} {listDiv} bind:dragItem + on:select={(evt) => { + select(0, evt.detail) + }} />
diff --git a/plugins/view-resources/src/components/list/ListCategories.svelte b/plugins/view-resources/src/components/list/ListCategories.svelte index 713db288e2..11a4136fb3 100644 --- a/plugins/view-resources/src/components/list/ListCategories.svelte +++ b/plugins/view-resources/src/components/list/ListCategories.svelte @@ -18,7 +18,7 @@ import { getClient, statusStore } from '@hcengineering/presentation' import { AnyComponent } from '@hcengineering/ui' import { AttributeModel, BuildModelKey, CategoryOption, ViewOptionModel, ViewOptions } from '@hcengineering/view' - import { createEventDispatcher, onDestroy } from 'svelte' + import { createEventDispatcher, onDestroy, SvelteComponentTyped } from 'svelte' import { buildModel, concatCategories, @@ -31,8 +31,6 @@ import { CategoryQuery, noCategory } from '../../viewOptions' import ListCategory from './ListCategory.svelte' - export let elementByIndex: Map - export let indexById: Map, number> export let docs: Doc[] export let _class: Ref> export let space: Ref | undefined @@ -51,13 +49,13 @@ export let level: number export let initIndex = 0 export let newObjectProps: (doc: Doc) => Record | undefined - export let docByIndex: Map export let viewOptionsConfig: ViewOptionModel[] | undefined export let dragItem: { doc?: Doc revert?: () => void } export let listDiv: HTMLDivElement + export let selection: number | undefined = undefined $: groupByKey = viewOptions.groupBy[level] ?? noCategory let categories: CategoryType[] = [] @@ -129,25 +127,118 @@ $: extraHeaders = getAdditionalHeader(client, _class) const dispatch = createEventDispatcher() + + function getState (doc: Doc): number { + let pos = 0 + for (const st of categories) { + const stateObjs = getGroupByValues(groupByDocs, st) ?? [] + if (stateObjs.findIndex((it) => it._id === doc._id) !== -1) { + return pos + } + pos++ + } + return -1 + } + + export function select (offset: 1 | -1 | 0, of?: Doc, dir?: 'vertical' | 'horizontal'): void { + let pos = (of != null ? docs.findIndex((it) => it._id === of._id) : selection) ?? -1 + if (pos === -1) { + for (const st of categories) { + const stateObjs = getGroupByValues(groupByDocs, st) ?? [] + if (stateObjs.length > 0) { + pos = docs.findIndex((it) => it._id === stateObjs[0]._id) + break + } + } + } + + if (pos < 0) { + pos = 0 + } + if (pos >= docs.length) { + pos = docs.length - 1 + } + + const obj = docs[pos] + if (obj === undefined) { + return + } + + // We found group + const objState = getState(obj) + if (objState === -1) { + return + } + + if (level + 1 >= viewOptions.groupBy.length) { + const stateObjs = getGroupByValues(groupByDocs, categories[objState]) ?? [] + + const statePos = stateObjs.findIndex((it) => it._id === obj._id) + if (statePos === undefined) { + return + } + + console.log(statePos, objState, offset) + if (offset === -1) { + if (dir === undefined || dir === 'vertical') { + if (statePos - 1 < 0 && objState > 0) { + const pstateObjs = getGroupByValues(groupByDocs, categories[objState - 1]) ?? [] + dispatch('select', pstateObjs[pstateObjs.length - 1]) + } else { + const obj = stateObjs[statePos - 1] ?? stateObjs[0] + scrollInto(objState, obj) + dispatch('row-focus', obj) + } + return + } + } + if (offset === 1) { + if (dir === undefined || dir === 'vertical') { + if (statePos + 1 >= stateObjs.length && objState < categories.length) { + const pstateObjs = getGroupByValues(groupByDocs, categories[objState + 1]) ?? [] + if (pstateObjs[0] !== undefined) { + dispatch('select', pstateObjs[0]) + } + } else { + const obj = stateObjs[statePos + 1] ?? stateObjs[stateObjs.length - 1] + scrollInto(objState, obj) + dispatch('row-focus', obj) + } + return + } + } + if (offset === 0) { + // scrollInto(objState, obj) + dispatch('row-focus', obj) + } + } else { + listCategory[objState]?.select(offset, of, dir) + } + } + function scrollInto (statePos: number, obj: Doc): void { + // listCategory[statePos]?.scrollIntoView({ behavior: 'auto', block: 'nearest' }) + listListCategory[statePos]?.scroll(obj) + listCategory[statePos]?.scroll(obj) + } + + const listCategory: SvelteComponentTyped[] = [] + const listListCategory: ListCategory[] = [] {#each categories as category, i (typeof category === 'object' ? category.name : category)} {@const items = groupByKey === noCategory ? docs : getGroupByValues(groupByDocs, category)} { + select(0, evt.detail) + }} /> diff --git a/plugins/view-resources/src/components/list/ListCategory.svelte b/plugins/view-resources/src/components/list/ListCategory.svelte index 1c6e87ada5..1723369209 100644 --- a/plugins/view-resources/src/components/list/ListCategory.svelte +++ b/plugins/view-resources/src/components/list/ListCategory.svelte @@ -16,17 +16,18 @@ import { Class, Doc, DocumentUpdate, Lookup, PrimitiveType, Ref, Space, StatusValue } from '@hcengineering/core' import { IntlString } from '@hcengineering/platform' import { getClient } from '@hcengineering/presentation' - import { calcRank, DocWithRank } from '@hcengineering/task' + import { DocWithRank, calcRank } from '@hcengineering/task' import { AnyComponent, CheckBox, ExpandCollapse, + Spinner, getEventPositionElement, - showPopup, - Spinner + mouseAttractor, + showPopup } from '@hcengineering/ui' import { AttributeModel, BuildModelKey, ViewOptionModel, ViewOptions } from '@hcengineering/view' - import { createEventDispatcher } from 'svelte' + import { createEventDispatcher, tick } from 'svelte' import { FocusSelection, focusStore } from '../../selection' import Menu from '../Menu.svelte' import ListHeader from './ListHeader.svelte' @@ -39,7 +40,6 @@ export let space: Ref | undefined export let baseMenuClass: Ref> | undefined export let items: Doc[] - export let initIndex: number export let createItemDialog: AnyComponent | undefined export let createItemLabel: IntlString | undefined export let loadingPropsLength: number | undefined @@ -50,14 +50,11 @@ export let disableHeader = false export let props: Record = {} export let level: number - export let elementByIndex: Map - export let indexById: Map, number> export let lookup: Lookup export let _class: Ref> export let config: (string | BuildModelKey)[] export let viewOptions: ViewOptions export let newObjectProps: (doc: Doc) => Record | undefined - export let docByIndex: Map export let viewOptionsConfig: ViewOptionModel[] | undefined export let dragItem: { doc?: Doc @@ -92,7 +89,7 @@ dispatch('row-focus', object) } - const handleMenuOpened = async (event: MouseEvent, object: Doc, rowIndex: number) => { + const handleMenuOpened = async (event: MouseEvent, object: Doc) => { event.preventDefault() handleRowFocused(object) @@ -300,6 +297,24 @@ index: i }) } + export function scroll (item: Doc): void { + const pos = items.findIndex((it) => it._id === item._id) + if (pos >= 0) { + if (collapsed) { + collapsed = false + tick().then(() => scroll(item)) + return + } + if (pos >= limited.length) { + limit = (limit ?? 0) + 20 + + tick().then(() => scroll(item)) + } else { + listItems[pos]?.scroll() + } + } + } + const listItems: ListItem[] = []
dragover(e, i)} on:drop={dropItemHandle} on:check={(ev) => dispatch('check', { docs: ev.detail.docs, value: ev.detail.value })} - on:contextmenu={(event) => handleMenuOpened(event, docObject, initIndex + i)} + on:contextmenu={(event) => handleMenuOpened(event, docObject)} on:focus={() => {}} - on:mouseover={() => handleRowFocused(docObject)} + on:mouseover={mouseAttractor(() => handleRowFocused(docObject))} {props} /> {/each} diff --git a/plugins/view-resources/src/components/list/ListItem.svelte b/plugins/view-resources/src/components/list/ListItem.svelte index 60b5564fa5..d0f5533874 100644 --- a/plugins/view-resources/src/components/list/ListItem.svelte +++ b/plugins/view-resources/src/components/list/ListItem.svelte @@ -13,25 +13,25 @@ // limitations under the License. -->