diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 4a4fa156a7..b9948709fe 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -707,7 +707,7 @@ export function createModel (builder: Builder): void { label: recruit.string.HideArchivedVacancies } - const applicantViewOptions = (colors: boolean, hides: boolean): ViewOptionsModel => { + const applicantViewOptions = (colors: boolean): ViewOptionsModel => { const model: ViewOptionsModel = { groupBy: ['status', 'assignee', 'space', 'createdBy', 'modifiedBy'], orderBy: [ @@ -725,15 +725,14 @@ export function createModel (builder: Builder): void { actionTarget: 'category', action: view.function.ShowEmptyGroups, label: view.string.ShowEmptyGroups - } + }, + applicationDoneOption, + vacancyHideOption ] } if (colors) { model.other.push(showColorsViewOption) } - if (hides) { - model.other.push(...[applicationDoneOption, vacancyHideOption]) - } return model } @@ -811,7 +810,7 @@ export function createModel (builder: Builder): void { strict: true, hiddenKeys: ['name', 'attachedTo'] }, - viewOptions: applicantViewOptions(true, true) + viewOptions: applicantViewOptions(true) }, recruit.viewlet.ListApplicant ) @@ -978,12 +977,8 @@ export function createModel (builder: Builder): void { attachTo: recruit.class.Applicant, descriptor: task.viewlet.Kanban, // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - baseQuery: { - isDone: { $ne: true }, - '$lookup.space.archived': false - }, viewOptions: { - ...applicantViewOptions(false, false), + ...applicantViewOptions(false), groupDepth: 1 }, options: { diff --git a/models/task/src/index.ts b/models/task/src/index.ts index 852476f291..f08055c24b 100644 --- a/models/task/src/index.ts +++ b/models/task/src/index.ts @@ -412,6 +412,10 @@ export function createModel (builder: Builder): void { func: task.function.StatusSort }) + builder.mixin(core.class.Status, core.class.Class, view.mixin.AttributeFilter, { + component: task.component.StatusFilter + }) + builder.mixin(core.class.Status, core.class.Class, view.mixin.AllValuesFunc, { func: task.function.GetAllStates }) diff --git a/models/view/src/index.ts b/models/view/src/index.ts index a1e2c0ee9a..dc1b2f8116 100644 --- a/models/view/src/index.ts +++ b/models/view/src/index.ts @@ -753,10 +753,6 @@ export function createModel (builder: Builder): void { component: view.component.ObjectFilter }) - builder.mixin(core.class.Status, core.class.Class, view.mixin.AttributeFilter, { - component: view.component.StatusFilter - }) - builder.mixin(core.class.TypeTimestamp, core.class.Class, view.mixin.AttributeFilter, { component: view.component.DateFilter, group: 'bottom' diff --git a/plugins/view-resources/src/components/filter/StatusFilter.svelte b/plugins/task-resources/src/components/StatusFilter.svelte similarity index 86% rename from plugins/view-resources/src/components/filter/StatusFilter.svelte rename to plugins/task-resources/src/components/StatusFilter.svelte index 16e9f2f0b8..6085e6dba1 100644 --- a/plugins/view-resources/src/components/filter/StatusFilter.svelte +++ b/plugins/task-resources/src/components/StatusFilter.svelte @@ -16,7 +16,7 @@ import core, { Doc, FindResult, IdMap, Ref, RefTo, Space, Status, toIdMap } from '@hcengineering/core' import { translate } from '@hcengineering/platform' import presentation, { createQuery, getClient } from '@hcengineering/presentation' - import task, { Project, ProjectType, getStates } from '@hcengineering/task' + import task, { Project, ProjectType } from '@hcengineering/task' import ui, { EditWithIcon, Icon, @@ -30,10 +30,16 @@ themeStore } from '@hcengineering/ui' import { Filter } from '@hcengineering/view' + import { + FILTER_DEBOUNCE_MS, + FilterRemovedNotification, + sortFilterValues, + statusStore + } from '@hcengineering/view-resources' + import view from '@hcengineering/view-resources/src/plugin' + import { buildConfigLookup, getPresenter } from '@hcengineering/view-resources/src/utils' import { createEventDispatcher } from 'svelte' - import { FILTER_DEBOUNCE_MS, FilterRemovedNotification, sortFilterValues, statusStore } from '../..' - import view from '../../plugin' - import { buildConfigLookup, getPresenter } from '../../utils' + import { selectedTypeStore, typeStore } from '..' export let filter: Filter export let space: Ref | undefined = undefined @@ -65,7 +71,12 @@ let filterUpdateTimeout: any | undefined - async function getValues (search: string, typeStore: IdMap, statusStore: IdMap): Promise { + async function getValues ( + search: string, + selectedType: Ref | undefined, + typeStore: IdMap, + statusStore: IdMap + ): Promise { if (objectsPromise) { await objectsPromise } @@ -74,16 +85,14 @@ for (const object of filter.value) { targets.add(object) } - if (space !== undefined) { - const _space = await client.findOne(task.class.Project, { _id: space as Ref }) - if (_space) { - values = getStates(_space, typeStore, statusStore) - for (const value of values) { - targets.add(value?._id) - } - if (search !== '') { - values = values.filter((p) => p?.name.includes(search)) - } + const type = selectedType ? typeStore.get(selectedType) : undefined + if (type !== undefined) { + values = type?.statuses?.map((p) => statusStore.get(p._id)) + for (const value of values) { + targets.add(value?._id) + } + if (search !== '') { + values = values.filter((p) => p?.name.includes(search)) } } else { const statuses: Status[] = [] @@ -162,13 +171,7 @@ const dispatch = createEventDispatcher() - const typesQuery = createQuery() - let types: IdMap = new Map() - typesQuery.query(task.class.ProjectType, {}, (res) => { - types = toIdMap(res) - }) - - $: if (targetClass) getValues(search, types, $statusStore.byId) + $: if (targetClass) getValues(search, $selectedTypeStore, $typeStore, $statusStore.byId)
dispatch('changeContent')}> diff --git a/plugins/task-resources/src/components/TypesView.svelte b/plugins/task-resources/src/components/TypesView.svelte index f4e409d313..13c337f4b6 100644 --- a/plugins/task-resources/src/components/TypesView.svelte +++ b/plugins/task-resources/src/components/TypesView.svelte @@ -33,6 +33,8 @@ import { ViewOptions, Viewlet, ViewletDescriptor, ViewletPreference } from '@hcengineering/view' import { FilterBar, FilterButton, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources' import task from '../plugin' + import { onDestroy } from 'svelte' + import { selectedTypeStore } from '..' export let _class: Ref> export let space: Ref | undefined = undefined @@ -82,6 +84,7 @@ let modeSelectorProps: IModeSelector | undefined = undefined $: if (mode === undefined && config.length > 0) { ;[[mode]] = config + selectedTypeStore.set(mode as Ref) } $: if (mode !== undefined) { modeSelectorProps = { @@ -89,9 +92,14 @@ config, onChange: (_mode: string) => { mode = _mode + selectedTypeStore.set(mode as Ref) } } } + + onDestroy(() => { + selectedTypeStore.set(undefined) + })
diff --git a/plugins/task-resources/src/index.ts b/plugins/task-resources/src/index.ts index 3cc31b72fc..4e5646caeb 100644 --- a/plugins/task-resources/src/index.ts +++ b/plugins/task-resources/src/index.ts @@ -16,21 +16,24 @@ import { Attribute, Class, Doc, DocumentQuery, IdMap, Ref, Status, TxOperations, toIdMap } from '@hcengineering/core' import { IntlString, Resources } from '@hcengineering/platform' +import { createQuery, getClient } from '@hcengineering/presentation' import task, { Project, ProjectType, Task, calcRank } from '@hcengineering/task' import { getCurrentLocation, navigate, showPopup } from '@hcengineering/ui' import { ViewletDescriptor } from '@hcengineering/view' -import { CategoryQuery, statusStore } from '@hcengineering/view-resources' +import { statusStore } from '@hcengineering/view-resources' import { get, writable } from 'svelte/store' import AssignedTasks from './components/AssignedTasks.svelte' import CreateStatePopup from './components/CreateStatePopup.svelte' import Dashboard from './components/Dashboard.svelte' import DueDateEditor from './components/DueDateEditor.svelte' import KanbanTemplatePresenter from './components/KanbanTemplatePresenter.svelte' +import StatusFilter from './components/StatusFilter.svelte' import StatusSelector from './components/StatusSelector.svelte' import StatusTableView from './components/StatusTableView.svelte' import TaskHeader from './components/TaskHeader.svelte' import TaskPresenter from './components/TaskPresenter.svelte' import TemplatesIcon from './components/TemplatesIcon.svelte' +import TypesView from './components/TypesView.svelte' import KanbanView from './components/kanban/KanbanView.svelte' import ProjectEditor from './components/kanban/ProjectEditor.svelte' import ProjectTypeSelector from './components/kanban/ProjectTypeSelector.svelte' @@ -41,8 +44,6 @@ import TodoItemPresenter from './components/todos/TodoItemPresenter.svelte' import TodoItemsPopup from './components/todos/TodoItemsPopup.svelte' import TodoStatePresenter from './components/todos/TodoStatePresenter.svelte' import Todos from './components/todos/Todos.svelte' -import TypesView from './components/TypesView.svelte' -import { createQuery, getClient } from '@hcengineering/presentation' export { default as AssigneePresenter } from './components/AssigneePresenter.svelte' export { StateRefPresenter } @@ -106,7 +107,8 @@ export default async (): Promise => ({ CreateStatePopup, StatusSelector, TemplatesIcon, - TypesView + TypesView, + StatusFilter }, actionImpl: { EditStatuses: editStatuses, @@ -124,29 +126,14 @@ async function getAllStates ( queryId: Ref, attr: Attribute ): Promise { - const _space = query?.space - if (_space !== undefined) { - const promise = new Promise>>((resolve, reject) => { - let refresh: boolean = false - const lq = CategoryQuery.getLiveQuery(queryId) - refresh = lq.query(task.class.Project, { _id: _space as Ref }, (res) => { - const typeId = res[0]?.type - const type = get(typeStore).get(typeId) - const statusMap = get(statusStore).byId - const statuses = (type?.statuses?.map((p) => statusMap.get(p._id)) as Status[]) ?? [] - const result = statuses - .filter((p) => p?.category !== task.statusCategory.Lost && p?.category !== task.statusCategory.Won) - .map((p) => p?._id) - CategoryQuery.results.set(queryId, result) - resolve(result) - onUpdate() - }) - - if (!refresh) { - resolve(CategoryQuery.results.get(queryId) ?? []) - } - }) - return await promise + const typeId = get(selectedTypeStore) + const type = typeId !== undefined ? get(typeStore).get(typeId) : undefined + if (type !== undefined) { + const statusMap = get(statusStore).byId + const statuses = (type.statuses?.map((p) => statusMap.get(p._id)) as Status[]) ?? [] + return statuses + .filter((p) => p?.category !== task.statusCategory.Lost && p?.category !== task.statusCategory.Won) + .map((p) => p?._id) } return get(statusStore) .array.filter( @@ -162,19 +149,8 @@ async function statusSort ( space: Ref | undefined, viewletDescriptorId?: Ref ): Promise>> { - let type: ProjectType | undefined - if (space !== undefined) { - const _space = await client.findOne( - task.class.Project, - { _id: space }, - { - lookup: { - type: task.class.ProjectType - } - } - ) - type = _space?.$lookup?.type - } + const typeId = get(selectedTypeStore) + const type = typeId !== undefined ? get(typeStore).get(typeId) : undefined const statuses = get(statusStore).byId if (type !== undefined) { @@ -238,3 +214,5 @@ function fillStores (): void { } fillStores() + +export const selectedTypeStore = writable | undefined>(undefined) diff --git a/plugins/task-resources/src/plugin.ts b/plugins/task-resources/src/plugin.ts index b2bb5c5c3e..1a103e45b1 100644 --- a/plugins/task-resources/src/plugin.ts +++ b/plugins/task-resources/src/plugin.ts @@ -79,6 +79,7 @@ export default mergeIds(taskId, task, { AssigneeRequired: '' as IntlString }, component: { + StatusFilter: '' as AnyComponent, TodoStatePresenter: '' as AnyComponent, AssignedTasks: '' as AnyComponent, DueDateEditor: '' as AnyComponent diff --git a/plugins/view-resources/src/index.ts b/plugins/view-resources/src/index.ts index 459eb37aca..549d40b1ae 100644 --- a/plugins/view-resources/src/index.ts +++ b/plugins/view-resources/src/index.ts @@ -40,7 +40,6 @@ import FilterTypePopup from './components/filter/FilterTypePopup.svelte' import ObjectFilter from './components/filter/ObjectFilter.svelte' import StringFilter from './components/filter/StringFilter.svelte' import StringFilterPresenter from './components/filter/StringFilterPresenter.svelte' -import StatusFilter from './components/filter/StatusFilter.svelte' import TimestampFilter from './components/filter/TimestampFilter.svelte' import ValueFilter from './components/filter/ValueFilter.svelte' import HTMLEditor from './components/HTMLEditor.svelte' @@ -206,7 +205,6 @@ export default async (): Promise => ({ DateFilter, ValueFilter, StringFilter, - StatusFilter, TimestampFilter, TableBrowser, SpacePresenter, diff --git a/plugins/view-resources/src/plugin.ts b/plugins/view-resources/src/plugin.ts index a9b8f36a3a..3c6ae76dfe 100644 --- a/plugins/view-resources/src/plugin.ts +++ b/plugins/view-resources/src/plugin.ts @@ -25,7 +25,6 @@ export default mergeIds(viewId, view, { DateFilter: '' as AnyComponent, ValueFilter: '' as AnyComponent, ArrayFilter: '' as AnyComponent, - StatusFilter: '' as AnyComponent, StringFilter: '' as AnyComponent, TimestampFilter: '' as AnyComponent, FilterTypePopup: '' as AnyComponent,