[UBER-329] Remove "Project" filter from a single project view (#3345)

Signed-off-by: Sergei Ogorelkov <sergei.ogorelkov@icloud.com>
This commit is contained in:
Sergei Ogorelkov 2023-06-06 15:18:32 +04:00 committed by GitHub
parent 36b7014327
commit 34147e980f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 76 additions and 57 deletions

View File

@ -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, {

View File

@ -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<Space>) => Promise<KeyFilter[]>>
}
@Mixin(view.mixin.AttributeFilter, core.class.Class)

View File

@ -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<Resources> => ({
SubIssueQuery: subIssueQuery,
GetAllPriority: getAllPriority,
GetAllComponents: getAllComponents,
GetAllMilestones: getAllMilestones
GetAllMilestones: getAllMilestones,
GetVisibleFilters: getVisibleFilters
},
actionImpl: {
Move: move,

View File

@ -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<Space>) => Promise<KeyFilter[]>>
},
aggregation: {
CreateComponentAggregationManager: '' as CreateAggregationManagerFunc,

View File

@ -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<Space>): Promise<KeyFilter[]> {
// Removes the "Project" filter if a specific space is provided
return space === undefined ? filters : filters.filter((f) => f.key !== 'space')
}

View File

@ -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<Class<Doc>>, nestedFrom: KeyFilter | undefined): KeyFilter[] {
async function getTypes (_class: Ref<Class<Doc>>, nestedFrom: KeyFilter | undefined): Promise<KeyFilter[]> {
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<KeyFilter[]> {
const targetClass = (hierarchy.getAttribute(type._class, type.key).type as RefTo<Doc>).to
return getOwnTypes(targetClass)
return await getOwnTypes(targetClass)
}
function getOwnTypes (_class: Ref<Class<Doc>>): KeyFilter[] {
async function getOwnTypes (_class: Ref<Class<Doc>>): Promise<KeyFilter[]> {
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 @@
</button>
<div class="divider" />
{/if}
{#each types as type, i}
{#if filter === undefined && hasNested(type)}
<Submenu
bind:element={elements[i]}
on:keydown={(event) => 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}
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<button
class="menu-item"
on:keydown={(event) => keyDown(event, i)}
on:mouseover={(event) => {
event.currentTarget.focus()
}}
on:click={() => {
click(type)
}}
>
<div class="overflow-label pr-1"><Label label={type.label} /></div>
</button>
{/if}
{#if nextDiffCat(types, i)}
<div class="menu-separator" />
{/if}
{/each}
{#await getTypes(_class, nestedFrom) then types}
{#each types as type, i}
{#if filter === undefined && hasNested(type)}
<Submenu
bind:element={elements[i]}
on:keydown={(event) => 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}
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<button
class="menu-item"
on:keydown={(event) => keyDown(event, i)}
on:mouseover={(event) => {
event.currentTarget.focus()
}}
on:click={() => {
click(type)
}}
>
<div class="overflow-label pr-1"><Label label={type.label} /></div>
</button>
{/if}
{#if nextDiffCat(types, i)}
<div class="menu-separator" />
{/if}
{/each}
{/await}
</Scroller>
<div class="menu-space" />
</div>

View File

@ -128,6 +128,8 @@ export interface ClassFilters extends Class<Doc> {
// Ignore attributes not specified in the "filters" array
strict?: boolean
// Allows to filter out the provided keys, leaving only the necessary ones
getVisibleFilters?: Resource<(filters: KeyFilter[], space?: Ref<Space>) => Promise<KeyFilter[]>>
}
/**