mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 11:01:54 +03:00
TSK-924: Follow proper order for Tracker Kanban (#2815)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
a48012037d
commit
26052dca3e
@ -523,7 +523,7 @@ export function createModel (builder: Builder): void {
|
||||
key: 'shouldShowSubIssues',
|
||||
type: 'toggle',
|
||||
defaultValue: false,
|
||||
actionTartget: 'query',
|
||||
actionTarget: 'query',
|
||||
action: tracker.function.SubIssueQuery,
|
||||
label: tracker.string.SubIssues
|
||||
},
|
||||
@ -531,7 +531,7 @@ export function createModel (builder: Builder): void {
|
||||
key: 'shouldShowAll',
|
||||
type: 'toggle',
|
||||
defaultValue: false,
|
||||
actionTartget: 'category',
|
||||
actionTarget: 'category',
|
||||
action: view.function.ShowEmptyGroups,
|
||||
label: view.string.ShowEmptyGroups
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import { IntlString, mergeIds, Resource } from '@hcengineering/platform'
|
||||
import { trackerId } from '@hcengineering/tracker'
|
||||
import tracker from '@hcengineering/tracker-resources/src/plugin'
|
||||
import type { AnyComponent } from '@hcengineering/ui/src/types'
|
||||
import { Action, ViewAction, Viewlet, ViewletDescriptor } from '@hcengineering/view'
|
||||
import { Action, ViewAction, Viewlet } from '@hcengineering/view'
|
||||
import { Application } from '@hcengineering/workbench'
|
||||
|
||||
export default mergeIds(trackerId, tracker, {
|
||||
@ -51,9 +51,7 @@ export default mergeIds(trackerId, tracker, {
|
||||
IssueList: '' as Ref<Viewlet>,
|
||||
IssueTemplateList: '' as Ref<Viewlet>,
|
||||
IssueKanban: '' as Ref<Viewlet>,
|
||||
SprintList: '' as Ref<Viewlet>,
|
||||
List: '' as Ref<ViewletDescriptor>,
|
||||
Kanban: '' as Ref<ViewletDescriptor>
|
||||
SprintList: '' as Ref<Viewlet>
|
||||
},
|
||||
completion: {
|
||||
IssueQuery: '' as Resource<ObjectSearchFactory>,
|
||||
|
@ -41,7 +41,7 @@
|
||||
showPopup,
|
||||
tooltip
|
||||
} from '@hcengineering/ui'
|
||||
import { CategoryOption, ViewOptionModel, ViewOptions, ViewQueryOption } from '@hcengineering/view'
|
||||
import { CategoryOption, Viewlet, ViewOptionModel, ViewOptions, ViewQueryOption } from '@hcengineering/view'
|
||||
import {
|
||||
ActionContext,
|
||||
focusStore,
|
||||
@ -52,6 +52,7 @@
|
||||
SelectDirection,
|
||||
selectionStore
|
||||
} from '@hcengineering/view-resources'
|
||||
import { sortCategories } from '@hcengineering/view-resources/src/utils'
|
||||
import { onMount } from 'svelte'
|
||||
import tracker from '../../plugin'
|
||||
import { issuesGroupBySorting, mapKanbanCategories } from '../../utils'
|
||||
@ -71,6 +72,7 @@
|
||||
export let query: DocumentQuery<Issue> = {}
|
||||
export let viewOptionsConfig: ViewOptionModel[] | undefined
|
||||
export let viewOptions: ViewOptions
|
||||
export let viewlet: Viewlet
|
||||
|
||||
$: currentSpace = space || tracker.project.DefaultProject
|
||||
$: groupBy = (viewOptions.groupBy[0] ?? noCategory) as IssuesGrouping
|
||||
@ -99,7 +101,7 @@
|
||||
if (viewOptions === undefined) return query
|
||||
let result = hierarchy.clone(query)
|
||||
for (const viewOption of viewOptions) {
|
||||
if (viewOption.actionTartget !== 'query') continue
|
||||
if (viewOption.actionTarget !== 'query') continue
|
||||
const queryOption = viewOption as ViewQueryOption
|
||||
const f = await getResource(queryOption.action)
|
||||
result = f(viewOptionsStore[queryOption.key] ?? queryOption.defaultValue, query)
|
||||
@ -234,9 +236,9 @@
|
||||
sprints: Sprint[],
|
||||
assignee: Employee[]
|
||||
) {
|
||||
let categories = await getCategories(client, _class, docs, groupByKey)
|
||||
let categories = await getCategories(client, _class, docs, groupByKey, viewlet.descriptor)
|
||||
for (const viewOption of viewOptionsModel ?? []) {
|
||||
if (viewOption.actionTartget !== 'category') continue
|
||||
if (viewOption.actionTarget !== 'category') continue
|
||||
const categoryFunc = viewOption as CategoryOption
|
||||
if (viewOptions[viewOption.key] ?? viewOption.defaultValue) {
|
||||
const f = await getResource(categoryFunc.action)
|
||||
@ -247,7 +249,8 @@
|
||||
res.push(category)
|
||||
}
|
||||
}
|
||||
categories = res
|
||||
|
||||
categories = await sortCategories(client, _class, res, groupByKey, viewlet.descriptor)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -17,12 +17,14 @@ import type { IntlString, Metadata, Resource } from '@hcengineering/platform'
|
||||
import { mergeIds } from '@hcengineering/platform'
|
||||
import { IssueDraft } from '@hcengineering/tracker'
|
||||
import { AnyComponent, Location } from '@hcengineering/ui'
|
||||
import { SortFunc, Viewlet, ViewQueryAction } from '@hcengineering/view'
|
||||
import { SortFunc, Viewlet, ViewletDescriptor, ViewQueryAction } from '@hcengineering/view'
|
||||
import tracker, { trackerId } from '../../tracker/lib'
|
||||
|
||||
export default mergeIds(trackerId, tracker, {
|
||||
viewlet: {
|
||||
SubIssues: '' as Ref<Viewlet>
|
||||
SubIssues: '' as Ref<Viewlet>,
|
||||
List: '' as Ref<ViewletDescriptor>,
|
||||
Kanban: '' as Ref<ViewletDescriptor>
|
||||
},
|
||||
string: {
|
||||
More: '' as IntlString,
|
||||
|
@ -33,6 +33,8 @@ import { TypeState } from '@hcengineering/kanban'
|
||||
import { Asset, IntlString, translate } from '@hcengineering/platform'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import {
|
||||
Component,
|
||||
ComponentStatus,
|
||||
Issue,
|
||||
IssuePriority,
|
||||
IssuesDateModificationPeriod,
|
||||
@ -40,11 +42,9 @@ import {
|
||||
IssuesOrdering,
|
||||
IssueStatus,
|
||||
IssueTemplateData,
|
||||
Component,
|
||||
ComponentStatus,
|
||||
Project,
|
||||
Sprint,
|
||||
SprintStatus,
|
||||
Project,
|
||||
TimeReportDayType
|
||||
} from '@hcengineering/tracker'
|
||||
import {
|
||||
@ -55,10 +55,11 @@ import {
|
||||
isWeekend,
|
||||
MILLISECONDS_IN_WEEK
|
||||
} from '@hcengineering/ui'
|
||||
import { ViewletDescriptor } from '@hcengineering/view'
|
||||
import { CategoryQuery, ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
|
||||
import { writable } from 'svelte/store'
|
||||
import tracker from './plugin'
|
||||
import { defaultPriorities, defaultComponentStatuses, defaultSprintStatuses, issuePriorities } from './types'
|
||||
import { defaultComponentStatuses, defaultPriorities, defaultSprintStatuses, issuePriorities } from './types'
|
||||
|
||||
export * from './types'
|
||||
|
||||
@ -331,11 +332,33 @@ const listIssueStatusOrder = [
|
||||
tracker.issueStatusCategory.Canceled
|
||||
] as const
|
||||
|
||||
export async function issueStatusSort (value: Array<Ref<IssueStatus>>): Promise<Array<Ref<IssueStatus>>> {
|
||||
const listIssueKanbanStatusOrder = [
|
||||
tracker.issueStatusCategory.Backlog,
|
||||
tracker.issueStatusCategory.Unstarted,
|
||||
tracker.issueStatusCategory.Started,
|
||||
tracker.issueStatusCategory.Completed,
|
||||
tracker.issueStatusCategory.Canceled
|
||||
] as const
|
||||
|
||||
export async function issueStatusSort (
|
||||
value: Array<Ref<IssueStatus>>,
|
||||
viewletDescriptorId?: Ref<ViewletDescriptor>
|
||||
): Promise<Array<Ref<IssueStatus>>> {
|
||||
return await new Promise((resolve) => {
|
||||
// TODO: How we track category updates.
|
||||
const query = createQuery(true)
|
||||
query.query(tracker.class.IssueStatus, { _id: { $in: value } }, (res) => {
|
||||
res.sort((a, b) => listIssueStatusOrder.indexOf(a.category) - listIssueStatusOrder.indexOf(b.category))
|
||||
if (viewletDescriptorId === tracker.viewlet.Kanban) {
|
||||
res.sort((a, b) => {
|
||||
const res = listIssueKanbanStatusOrder.indexOf(a.category) - listIssueKanbanStatusOrder.indexOf(b.category)
|
||||
if (res === 0) {
|
||||
return a.rank.localeCompare(b.rank)
|
||||
}
|
||||
return res
|
||||
})
|
||||
} else {
|
||||
res.sort((a, b) => listIssueStatusOrder.indexOf(a.category) - listIssueStatusOrder.indexOf(b.category))
|
||||
}
|
||||
resolve(res.map((p) => p._id))
|
||||
query.unsubscribe()
|
||||
})
|
||||
|
@ -86,7 +86,7 @@
|
||||
if (viewOptions === undefined) return query
|
||||
let result = hierarchy.clone(query)
|
||||
for (const viewOption of viewOptions) {
|
||||
if (viewOption.actionTartget !== 'query') continue
|
||||
if (viewOption.actionTarget !== 'query') continue
|
||||
const queryOption = viewOption as ViewQueryOption
|
||||
const f = await getResource(queryOption.action)
|
||||
result = f(viewOptionsStore[queryOption.key] ?? queryOption.defaultValue, query)
|
||||
|
@ -74,7 +74,7 @@
|
||||
categories = await getCategories(client, _class, docs, groupByKey)
|
||||
if (level === 0) {
|
||||
for (const viewOption of viewOptionsModel ?? []) {
|
||||
if (viewOption.actionTartget !== 'category') continue
|
||||
if (viewOption.actionTarget !== 'category') continue
|
||||
const categoryFunc = viewOption as CategoryOption
|
||||
if (viewOptions[viewOption.key] ?? viewOption.defaultValue) {
|
||||
const f = await getResource(categoryFunc.action)
|
||||
|
@ -43,7 +43,7 @@ import {
|
||||
Location,
|
||||
locationToUrl
|
||||
} from '@hcengineering/ui'
|
||||
import type { BuildModelOptions, Viewlet } from '@hcengineering/view'
|
||||
import type { BuildModelOptions, Viewlet, ViewletDescriptor } from '@hcengineering/view'
|
||||
import view, { AttributeModel, BuildModelKey } from '@hcengineering/view'
|
||||
import { writable } from 'svelte/store'
|
||||
import plugin from './plugin'
|
||||
@ -528,11 +528,24 @@ export async function getCategories (
|
||||
client: TxOperations,
|
||||
_class: Ref<Class<Doc>>,
|
||||
docs: Doc[],
|
||||
key: string
|
||||
key: string,
|
||||
viewletDescriptorId?: Ref<ViewletDescriptor>
|
||||
): Promise<any[]> {
|
||||
if (key === noCategory) return [undefined]
|
||||
const existingCategories = Array.from(new Set(docs.map((x: any) => x[key] ?? undefined)))
|
||||
|
||||
return await sortCategories(client, _class, existingCategories, key, viewletDescriptorId)
|
||||
}
|
||||
|
||||
export async function sortCategories (
|
||||
client: TxOperations,
|
||||
_class: Ref<Class<Doc>>,
|
||||
existingCategories: any[],
|
||||
key: string,
|
||||
viewletDescriptorId?: Ref<ViewletDescriptor>
|
||||
): Promise<any[]> {
|
||||
if (key === noCategory) return [undefined]
|
||||
const hierarchy = client.getHierarchy()
|
||||
const existingCategories = Array.from(new Set(docs.map((x: any) => x[key] ?? undefined)))
|
||||
const attr = hierarchy.getAttribute(_class, key)
|
||||
if (attr === undefined) return existingCategories
|
||||
const attrClass = getAttributePresenterClass(hierarchy, attr).attrClass
|
||||
@ -541,7 +554,7 @@ export async function getCategories (
|
||||
if (sortFunc?.func === undefined) return existingCategories
|
||||
const f = await getResource(sortFunc.func)
|
||||
|
||||
return await f(existingCategories)
|
||||
return await f(existingCategories, viewletDescriptorId)
|
||||
}
|
||||
|
||||
export function getKeyLabel<T extends Doc> (
|
||||
|
@ -236,7 +236,7 @@ export interface ListHeaderExtra extends Class<Doc> {
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type SortFunc = Resource<(values: any[]) => Promise<any[]>>
|
||||
export type SortFunc = Resource<(values: any[], viewletDescriptorId?: Ref<ViewletDescriptor>) => Promise<any[]>>
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -483,7 +483,7 @@ export interface ViewOption {
|
||||
defaultValue: any
|
||||
label: IntlString
|
||||
hidden?: (viewOptions: ViewOptions) => boolean
|
||||
actionTartget?: 'query' | 'category'
|
||||
actionTarget?: 'query' | 'category'
|
||||
action?: Resource<(value: any, ...params: any) => any>
|
||||
}
|
||||
|
||||
@ -504,7 +504,7 @@ export type ViewCategoryAction = Resource<
|
||||
* @public
|
||||
*/
|
||||
export interface CategoryOption extends ViewOption {
|
||||
actionTartget: 'category'
|
||||
actionTarget: 'category'
|
||||
action: ViewCategoryAction
|
||||
}
|
||||
|
||||
@ -517,7 +517,7 @@ export type ViewQueryAction = Resource<(value: any, query: DocumentQuery<Doc>) =
|
||||
* @public
|
||||
*/
|
||||
export interface ViewQueryOption extends ViewOption {
|
||||
actionTartget: 'query'
|
||||
actionTarget: 'query'
|
||||
action: ViewQueryAction
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user