diff --git a/plugins/tracker-resources/src/components/issues/edit/EditIssue.svelte b/plugins/tracker-resources/src/components/issues/edit/EditIssue.svelte index 8413594d7c..f9d83e33c5 100644 --- a/plugins/tracker-resources/src/components/issues/edit/EditIssue.svelte +++ b/plugins/tracker-resources/src/components/issues/edit/EditIssue.svelte @@ -264,6 +264,7 @@ {#if currentTeam !== undefined && issueStatuses !== undefined} <SubIssues {issue} + {parentIssue} issueStatuses={new Map([[currentTeam._id, issueStatuses]])} teams={new Map([[currentTeam?._id, currentTeam]])} /> diff --git a/plugins/tracker-resources/src/components/issues/edit/SubIssueList.svelte b/plugins/tracker-resources/src/components/issues/edit/SubIssueList.svelte index c93b64af3c..60dc0f0909 100644 --- a/plugins/tracker-resources/src/components/issues/edit/SubIssueList.svelte +++ b/plugins/tracker-resources/src/components/issues/edit/SubIssueList.svelte @@ -13,16 +13,10 @@ // limitations under the License. --> <script lang="ts"> - import { Doc, Ref, WithLookup } from '@hcengineering/core' + import { Ref, WithLookup } from '@hcengineering/core' import { Issue, IssueStatus, Team } from '@hcengineering/tracker' import { getEventPositionElement, showPanel, showPopup } from '@hcengineering/ui' - import { - ActionContext, - ContextMenu, - FixedColumn, - ListSelectionProvider, - SelectDirection - } from '@hcengineering/view-resources' + import { ActionContext, ContextMenu, FixedColumn } from '@hcengineering/view-resources' import { createEventDispatcher } from 'svelte' import { flip } from 'svelte/animate' import { getIssueId } from '../../../issues' @@ -45,6 +39,7 @@ let hoveringIndex: number | null = null function openIssue (target: Issue) { + dispatch('issue-focus', target) showPanel(tracker.component.EditIssue, target._id, target._class, 'content') } @@ -75,8 +70,6 @@ showPopup(ContextMenu, { object }, getEventPositionElement(ev)) } - const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => {}) - let varsStyle: string = '' const propsWidth: Record<string, number> = { issue: 0 } $: if (propsWidth) { @@ -96,6 +89,7 @@ {#each issues as issue, index (issue._id)} {@const currentTeam = teams.get(issue.space)} + {@const openIssueCall = () => openIssue(issue)} <div class="flex-between row" class:is-dragging={index === draggingIndex} @@ -104,26 +98,20 @@ style={varsStyle} animate:flip={{ duration: 400 }} draggable={true} - on:click|self={() => openIssue(issue)} + on:click|self={openIssueCall} on:contextmenu|preventDefault={(ev) => showContextMenu(ev, issue)} on:dragstart={(ev) => handleDragStart(ev, index)} on:dragover|preventDefault={() => false} on:dragenter={() => (hoveringIndex = index)} on:drop|preventDefault={(ev) => handleDrop(ev, index)} on:dragend={resetDrag} - on:mouseover={() => { - listProvider.updateFocus(issue) - }} - on:focus={() => { - listProvider.updateFocus(issue) - }} > <div class="draggable-container"> <div class="draggable-mark"><Circles /></div> </div> <div class="flex-row-center ml-6 clear-mins gap-2"> <PriorityEditor value={issue} isEditable kind={'list'} size={'small'} justify={'center'} /> - <span class="issuePresenter" on:click={() => openIssue(issue)}> + <span class="issuePresenter" on:click={openIssueCall}> <FixedColumn width={propsWidth.issue} key={'issue'} @@ -143,7 +131,7 @@ size={'small'} tooltipAlignment="bottom" /> - <span class="text name" title={issue.title} on:click={() => openIssue(issue)}> + <span class="text name" title={issue.title} on:click={openIssueCall}> {issue.title} </span> </div> diff --git a/plugins/tracker-resources/src/components/issues/edit/SubIssues.svelte b/plugins/tracker-resources/src/components/issues/edit/SubIssues.svelte index 3e45e31f8a..1bab7f83f6 100644 --- a/plugins/tracker-resources/src/components/issues/edit/SubIssues.svelte +++ b/plugins/tracker-resources/src/components/issues/edit/SubIssues.svelte @@ -13,10 +13,11 @@ // limitations under the License. --> <script lang="ts"> - import { Ref, SortingOrder, WithLookup } from '@hcengineering/core' + import { Doc, Ref, SortingOrder, WithLookup } from '@hcengineering/core' import { createQuery, getClient } from '@hcengineering/presentation' import { calcRank, Issue, IssueStatus, Team } from '@hcengineering/tracker' import { Button, Spinner, ExpandCollapse, closeTooltip, IconAdd } from '@hcengineering/ui' + import { focusStore, ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources' import tracker from '../../../plugin' import Collapsed from '../../icons/Collapsed.svelte' import Expanded from '../../icons/Expanded.svelte' @@ -24,6 +25,7 @@ import SubIssueList from './SubIssueList.svelte' export let issue: Issue + export let parentIssue: Doc | undefined export let teams: Map<Ref<Team>, Team> export let issueStatuses: Map<Ref<Team>, WithLookup<IssueStatus>[]> @@ -31,6 +33,7 @@ const client = getClient() let subIssues: Issue[] | undefined + let neighbourIssues: Issue[] | undefined let isCollapsed = false let isCreating = false @@ -47,10 +50,42 @@ } } + const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => { + if (dir === 'vertical') { + if (neighbourIssues) { + const selectedRowIndex = listProvider.current($focusStore) + let position = (of !== undefined ? neighbourIssues.findIndex((x) => x._id === of?._id) : selectedRowIndex) ?? -1 + + position += offset + + if (position < 0) { + position = 0 + } + + if (position >= neighbourIssues.length) { + position = neighbourIssues.length - 1 + } + + listProvider.updateFocus(neighbourIssues[position]) + } + } + }) + $: hasSubIssues = issue.subIssues > 0 $: subIssuesQuery.query(tracker.class.Issue, { attachedTo: issue._id }, async (result) => (subIssues = result), { sort: { rank: SortingOrder.Ascending } }) + $: if (parentIssue) { + subIssuesQuery.query( + tracker.class.Issue, + { attachedTo: parentIssue?._id }, + async (result) => (neighbourIssues = result), + { + sort: { rank: SortingOrder.Ascending } + } + ) + } + $: if (neighbourIssues && neighbourIssues.length > 0) listProvider.update(neighbourIssues) </script> <div class="flex-between"> @@ -90,7 +125,15 @@ <ExpandCollapse isExpanded={!isCollapsed} duration={400}> {#if hasSubIssues} <div class="list" class:collapsed={isCollapsed}> - <SubIssueList issues={subIssues} {issueStatuses} {teams} on:move={handleIssueSwap} /> + <SubIssueList + issues={subIssues} + {issueStatuses} + {teams} + on:move={handleIssueSwap} + on:issue-focus={(event) => { + listProvider.updateFocus(event.detail ?? undefined) + }} + /> </div> {/if} </ExpandCollapse>