From 34147e980f59dd8c4cf2e9b73f84a6d514a6bef3 Mon Sep 17 00:00:00 2001 From: Sergei Ogorelkov Date: Tue, 6 Jun 2023 15:18:32 +0400 Subject: [PATCH] [UBER-329] Remove "Project" filter from a single project view (#3345) Signed-off-by: Sergei Ogorelkov --- models/tracker/src/index.ts | 3 +- models/view/src/index.ts | 2 + plugins/tracker-resources/src/index.ts | 6 +- plugins/tracker-resources/src/plugin.ts | 8 +- plugins/tracker-resources/src/utils.ts | 8 +- .../components/filter/FilterTypePopup.svelte | 104 +++++++++--------- plugins/view/src/index.ts | 2 + 7 files changed, 76 insertions(+), 57 deletions(-) diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts index f9089c62e9..c0145b5bd2 100644 --- a/models/tracker/src/index.ts +++ b/models/tracker/src/index.ts @@ -1467,7 +1467,8 @@ export function createModel (builder: Builder): void { showNested: false } ], - ignoreKeys: ['number', 'estimation', 'attachedTo'] + ignoreKeys: ['number', 'estimation', 'attachedTo'], + getVisibleFilters: tracker.function.GetVisibleFilters }) builder.mixin(tracker.class.IssueTemplate, core.class.Class, view.mixin.ClassFilters, { diff --git a/models/view/src/index.ts b/models/view/src/index.ts index aeb783a242..a6145d0b73 100644 --- a/models/view/src/index.ts +++ b/models/view/src/index.ts @@ -52,6 +52,7 @@ import { IgnoreActions, InlineAttributEditor, KeyBinding, + KeyFilter, KeyFilterPreset, LinkPresenter, LinkProvider, @@ -153,6 +154,7 @@ export class TClassFilters extends TClass implements ClassFilters { filters!: (string | KeyFilterPreset)[] ignoreKeys?: string[] | undefined strict?: boolean | undefined + getVisibleFilters?: Resource<(filters: KeyFilter[], space?: Ref) => Promise> } @Mixin(view.mixin.AttributeFilter, core.class.Class) diff --git a/plugins/tracker-resources/src/index.ts b/plugins/tracker-resources/src/index.ts index 44d3bcf2b4..f55dfb8220 100644 --- a/plugins/tracker-resources/src/index.ts +++ b/plugins/tracker-resources/src/index.ts @@ -117,7 +117,8 @@ import { issueStatusSort, moveIssuesToAnotherMilestone, milestoneSort, - subIssueQuery + subIssueQuery, + getVisibleFilters } from './utils' import { EmployeeAccount } from '@hcengineering/contact' @@ -497,7 +498,8 @@ export default async (): Promise => ({ SubIssueQuery: subIssueQuery, GetAllPriority: getAllPriority, GetAllComponents: getAllComponents, - GetAllMilestones: getAllMilestones + GetAllMilestones: getAllMilestones, + GetVisibleFilters: getVisibleFilters }, actionImpl: { Move: move, diff --git a/plugins/tracker-resources/src/plugin.ts b/plugins/tracker-resources/src/plugin.ts index 63504a2ecf..8cc0ded299 100644 --- a/plugins/tracker-resources/src/plugin.ts +++ b/plugins/tracker-resources/src/plugin.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -import { Client, Doc, Ref } from '@hcengineering/core' +import { Client, Doc, Ref, Space } from '@hcengineering/core' import type { Asset, IntlString, Metadata, Resource } from '@hcengineering/platform' import { mergeIds } from '@hcengineering/platform' import { IssueDraft } from '@hcengineering/tracker' @@ -24,7 +24,8 @@ import { SortFunc, Viewlet, ViewletDescriptor, - ViewQueryAction + ViewQueryAction, + KeyFilter } from '@hcengineering/view' import tracker, { trackerId } from '../../tracker/lib' @@ -392,7 +393,8 @@ export default mergeIds(trackerId, tracker, { SubIssueQuery: '' as ViewQueryAction, GetAllPriority: '' as GetAllValuesFunc, GetAllComponents: '' as GetAllValuesFunc, - GetAllMilestones: '' as GetAllValuesFunc + GetAllMilestones: '' as GetAllValuesFunc, + GetVisibleFilters: '' as Resource<(filters: KeyFilter[], space?: Ref) => Promise> }, aggregation: { CreateComponentAggregationManager: '' as CreateAggregationManagerFunc, diff --git a/plugins/tracker-resources/src/utils.ts b/plugins/tracker-resources/src/utils.ts index 5423f5fe1b..9345386234 100644 --- a/plugins/tracker-resources/src/utils.ts +++ b/plugins/tracker-resources/src/utils.ts @@ -25,6 +25,7 @@ import core, { DocumentUpdate, Ref, SortingOrder, + Space, Status, StatusCategory, StatusManager, @@ -58,7 +59,7 @@ import { MILLISECONDS_IN_WEEK, PaletteColorIndexes } from '@hcengineering/ui' -import { ViewletDescriptor } from '@hcengineering/view' +import { KeyFilter, ViewletDescriptor } from '@hcengineering/view' import { CategoryQuery, groupBy, ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources' import tracker from './plugin' import { defaultPriorities, defaultMilestoneStatuses } from './types' @@ -654,3 +655,8 @@ export const IssuePriorityColor = { [IssuePriority.Medium]: PaletteColorIndexes.Ocean, [IssuePriority.Low]: PaletteColorIndexes.Cloud } + +export async function getVisibleFilters (filters: KeyFilter[], space?: Ref): Promise { + // Removes the "Project" filter if a specific space is provided + return space === undefined ? filters : filters.filter((f) => f.key !== 'space') +} diff --git a/plugins/view-resources/src/components/filter/FilterTypePopup.svelte b/plugins/view-resources/src/components/filter/FilterTypePopup.svelte index 66aff116e7..91da7b364c 100644 --- a/plugins/view-resources/src/components/filter/FilterTypePopup.svelte +++ b/plugins/view-resources/src/components/filter/FilterTypePopup.svelte @@ -17,6 +17,7 @@ import { getClient } from '@hcengineering/presentation' import { Label, Scroller, Submenu, closePopup, closeTooltip, resizeObserver, showPopup } from '@hcengineering/ui' import { ClassFilters, Filter, KeyFilter, KeyFilterPreset } from '@hcengineering/view' + import { getResource } from '@hcengineering/platform' import { createEventDispatcher } from 'svelte' import { FilterQuery, buildFilterKey } from '../../filter' import view from '../../plugin' @@ -101,12 +102,12 @@ } } - function getTypes (_class: Ref>, nestedFrom: KeyFilter | undefined): KeyFilter[] { + async function getTypes (_class: Ref>, nestedFrom: KeyFilter | undefined): Promise { let res: KeyFilter[] = [] if (nestedFrom !== undefined) { - res = getNestedTypes(nestedFrom) + res = await getNestedTypes(nestedFrom) } else { - res = getOwnTypes(_class) + res = await getOwnTypes(_class) } res.sort((a, b) => { if (a.group === b.group) return 0 @@ -119,20 +120,23 @@ return res } - function getNestedTypes (type: KeyFilter): KeyFilter[] { + async function getNestedTypes (type: KeyFilter): Promise { const targetClass = (hierarchy.getAttribute(type._class, type.key).type as RefTo).to - return getOwnTypes(targetClass) + return await getOwnTypes(targetClass) } - function getOwnTypes (_class: Ref>): KeyFilter[] { + async function getOwnTypes (_class: Ref>): Promise { const mixin = hierarchy.classHierarchyMixin(_class, view.mixin.ClassFilters) if (mixin === undefined) return [] _class = hierarchy.getBaseClass(_class) const result = getFilters(_class, mixin) + const getVisibleFilters = mixin.getVisibleFilters + ? await getResource(mixin.getVisibleFilters) + : async (filters: KeyFilter[]) => filters if (mixin.strict) { - // Attributes not specified in "mixing.filters" are ignored - return result + // Attributes not specified in "mixin.filters" are ignored in "strict" mode + return await getVisibleFilters(result, space) } const allAttributes = hierarchy.getAllAttributes(_class) @@ -166,7 +170,7 @@ } } - return result + return await getVisibleFilters(result, space) } const actionElements: HTMLButtonElement[] = [] @@ -260,8 +264,6 @@ const elements: HTMLElement[] = [] - $: types = getTypes(_class, nestedFrom) - function nextDiffCat (types: KeyFilter[], i: number): boolean { if (types[i + 1] === undefined) return false return types[i].group !== types[i + 1].group @@ -289,45 +291,47 @@
{/if} - {#each types as type, i} - {#if filter === undefined && hasNested(type)} - keyDown(event, i)} - on:mouseover={() => { - elements[i]?.focus() - }} - label={type.label} - props={{ - _class, - space, - index, - target, - onChange, - nestedFrom: type - }} - options={{ component: view.component.FilterTypePopup }} - withHover - /> - {:else} - - - {/if} - {#if nextDiffCat(types, i)} -