From 38a8940a8b0224306b5f9f9d432c1226d7704c89 Mon Sep 17 00:00:00 2001 From: Artyom Grigorovich Date: Tue, 26 Apr 2022 15:46:35 +0700 Subject: [PATCH] Tracker: Add keyboard support for issues list (#1539) Signed-off-by: Artyom Grigorovich --- models/view/src/index.ts | 6 +- .../issues/AssigneePresenter.svelte | 19 +- .../issues/CategoryPresenter.svelte | 116 ------ .../src/components/issues/Issues.svelte | 144 +++++-- .../src/components/issues/IssuesList.svelte | 359 +++++++++++------- .../issues/IssuesListBrowser.svelte | 86 +++++ plugins/tracker-resources/src/utils.ts | 16 +- .../src/components/ActionHandler.svelte | 34 +- .../src/components/Table.svelte | 2 +- 9 files changed, 472 insertions(+), 310 deletions(-) delete mode 100644 plugins/tracker-resources/src/components/issues/CategoryPresenter.svelte create mode 100644 plugins/tracker-resources/src/components/issues/IssuesListBrowser.svelte diff --git a/models/view/src/index.ts b/models/view/src/index.ts index cdd5ab8a9c..89c1238621 100644 --- a/models/view/src/index.ts +++ b/models/view/src/index.ts @@ -241,7 +241,7 @@ export function createModel (builder: Builder): void { createAction(builder, view.action.Delete, view.string.Delete, view.actionImpl.Delete, { icon: view.icon.Delete, - keyBinding: ['Meta + Backspace'] + keyBinding: ['Meta + Backspace', 'Ctrl + Backspace'] }) actionTarget(builder, view.action.Delete, core.class.Doc, { mode: ['context', 'browser'], group: 'tools' }) @@ -280,7 +280,7 @@ export function createModel (builder: Builder): void { actionTarget(builder, view.action.SelectItem, core.class.Doc, { mode: 'browser' }) createAction(builder, view.action.SelectItemAll, view.string.SelectItemAll, view.actionImpl.SelectItemAll, { - keyBinding: ['meta + keyA'] + keyBinding: ['meta + keyA', 'ctrl + keyA'] }) actionTarget(builder, view.action.SelectItemAll, core.class.Doc, { mode: 'browser' }) @@ -290,7 +290,7 @@ export function createModel (builder: Builder): void { actionTarget(builder, view.action.SelectItemNone, core.class.Doc, { mode: 'browser' }) createAction(builder, view.action.ShowActions, view.string.ShowActions, view.actionImpl.ShowActions, { - keyBinding: ['meta + keyk'] + keyBinding: ['meta + keyK', 'ctrl + keyK'] }) actionTarget(builder, view.action.ShowActions, core.class.Doc, { mode: ['workbench', 'browser', 'popup', 'panel', 'editor'] diff --git a/plugins/tracker-resources/src/components/issues/AssigneePresenter.svelte b/plugins/tracker-resources/src/components/issues/AssigneePresenter.svelte index 2754d71495..de4bc34df6 100644 --- a/plugins/tracker-resources/src/components/issues/AssigneePresenter.svelte +++ b/plugins/tracker-resources/src/components/issues/AssigneePresenter.svelte @@ -24,6 +24,7 @@ import { onMount } from 'svelte' export let value: WithLookup + export let employees: (WithLookup | undefined)[] = [] export let currentSpace: Ref | undefined = undefined export let isEditable: boolean = true export let shouldShowLabel: boolean = false @@ -32,14 +33,12 @@ const client = getClient() let defaultNameString: string = '' - let assignee: Employee | undefined = undefined - $: employee = (value?.$lookup?.assignee ?? assignee) as Employee | undefined + $: employee = (value?.$lookup?.assignee ?? employees.find(x => x?._id === value?.assignee)) as Employee | undefined $: avatar = employee?.avatar $: formattedName = employee?.name ? formatName(employee.name) : defaultNameString $: label = employee ? tracker.string.AssignedTo : tracker.string.AssignTo - $: findEmployeeById(value.assignee) $: getDefaultNameString = async () => { if (!defaultName) { return @@ -58,20 +57,6 @@ getDefaultNameString() }) - const findEmployeeById = async (id: Ref | null) => { - if (!id) { - return undefined - } - - const current = await client.findOne(contact.class.Employee, { _id: id }) - - if (current === undefined) { - return - } - - assignee = current - } - const handleAssigneeChanged = async (result: Employee | null | undefined) => { if (!isEditable || result === undefined) { return diff --git a/plugins/tracker-resources/src/components/issues/CategoryPresenter.svelte b/plugins/tracker-resources/src/components/issues/CategoryPresenter.svelte deleted file mode 100644 index 5ea3ae3a93..0000000000 --- a/plugins/tracker-resources/src/components/issues/CategoryPresenter.svelte +++ /dev/null @@ -1,116 +0,0 @@ - - - -
- {#if headerComponent} -
-
- - {issuesAmount} -
-
- -
-
- {/if} - - { - issuesAmount = evt.detail.length - dispatch('content', issuesAmount) - }} - /> - -
- - diff --git a/plugins/tracker-resources/src/components/issues/Issues.svelte b/plugins/tracker-resources/src/components/issues/Issues.svelte index 9da7238c3d..fee4ba0fce 100644 --- a/plugins/tracker-resources/src/components/issues/Issues.svelte +++ b/plugins/tracker-resources/src/components/issues/Issues.svelte @@ -13,8 +13,8 @@ // limitations under the License. --> -{#await buildModel({ client, _class, keys: itemsConfig, options })} - {#if !isLoading} - - {/if} -{:then itemModels} -
- {#if docObjects} - {#each docObjects as docObject, rowIndex (docObject._id)} -
-
- {#each itemModels as attributeModel, attributeModelIndex} - {#if attributeModelIndex === 0} -
- -
- { - handleIssueSelected(docObject._id, event) - }} - /> +
+ {#each categories as category} + {#if headerComponent} +
+
+ + {(groupedIssues[category] ?? []).length} +
+
+ +
+
+ {/if} + {#await buildModel({ client, _class, keys: itemsConfig, options }) then itemModels} +
+ {#if groupedIssues[category]} + {#each groupedIssues[category] as docObject (docObject._id)} +
x === docObject)]} + class="listGrid" + class:mListGridChecked={selectedObjectIdsSet.has(docObject._id)} + class:mListGridFixed={selectedRowIndex === combinedGroupedIssues.findIndex((x) => x === docObject)} + class:mListGridSelected={selectedRowIndex === combinedGroupedIssues.findIndex((x) => x === docObject)} + on:contextmenu|preventDefault={(event) => + handleMenuOpened( + event, + docObject, + combinedGroupedIssues.findIndex((x) => x === docObject) + )} + on:focus={() => {}} + on:mouseover={() => handleRowFocused(docObject)} + > +
+ {#each itemModels as attributeModel, attributeModelIndex} + {#if attributeModelIndex === 0} +
+ +
+ { + onObjectChecked([docObject], event.detail) + }} + /> +
+
+
+ +
- -
+ {:else if attributeModelIndex === 1} +
+ +
+ handleMenuOpened( + event, + docObject, + combinedGroupedIssues.findIndex((x) => x === docObject) + )} + > + +
+
+ {:else if attributeModelIndex === 3} -
-
- {:else if attributeModelIndex === 1} -
- -
showMenu(event, docObject, rowIndex)} - > - -
-
- {:else if attributeModelIndex === 3} - -
- {:else} -
- -
- {/if} - {/each} -
-
- {/each} - {:else if loadingProps !== undefined} - {#each Array(getLoadingElementsLength(loadingProps, options)) as _, rowIndex} -
-
-
- -
- +
+ {:else} +
+ +
+ {/if} + {/each}
-
-
- {/each} - {/if} -
-{/await} - -{#if isLoading} - -{/if} + {/each} + {:else if loadingProps !== undefined} + {#each Array(getLoadingElementsLength(loadingProps, options)) as _, rowIndex} +
+
+
+ +
+ +
+
+
+
+ {/each} + {/if} +
+ {/await} + {/each} +