mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-23 16:56:07 +00:00
Fix status filter (#3937)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
9f82ec3b7f
commit
66915d29e3
@ -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: {
|
||||
|
@ -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
|
||||
})
|
||||
|
@ -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'
|
||||
|
@ -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<Space> | undefined = undefined
|
||||
@ -65,7 +71,12 @@
|
||||
|
||||
let filterUpdateTimeout: any | undefined
|
||||
|
||||
async function getValues (search: string, typeStore: IdMap<ProjectType>, statusStore: IdMap<Status>): Promise<void> {
|
||||
async function getValues (
|
||||
search: string,
|
||||
selectedType: Ref<ProjectType> | undefined,
|
||||
typeStore: IdMap<ProjectType>,
|
||||
statusStore: IdMap<Status>
|
||||
): Promise<void> {
|
||||
if (objectsPromise) {
|
||||
await objectsPromise
|
||||
}
|
||||
@ -74,17 +85,15 @@
|
||||
for (const object of filter.value) {
|
||||
targets.add(object)
|
||||
}
|
||||
if (space !== undefined) {
|
||||
const _space = await client.findOne(task.class.Project, { _id: space as Ref<Project> })
|
||||
if (_space) {
|
||||
values = getStates(_space, typeStore, statusStore)
|
||||
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[] = []
|
||||
for (const status of statusStore.values()) {
|
||||
@ -162,13 +171,7 @@
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const typesQuery = createQuery()
|
||||
let types: IdMap<ProjectType> = 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)
|
||||
</script>
|
||||
|
||||
<div class="selectPopup" use:resizeObserver={() => dispatch('changeContent')}>
|
@ -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<Class<Doc>>
|
||||
export let space: Ref<Space> | undefined = undefined
|
||||
@ -82,6 +84,7 @@
|
||||
let modeSelectorProps: IModeSelector | undefined = undefined
|
||||
$: if (mode === undefined && config.length > 0) {
|
||||
;[[mode]] = config
|
||||
selectedTypeStore.set(mode as Ref<ProjectType>)
|
||||
}
|
||||
$: if (mode !== undefined) {
|
||||
modeSelectorProps = {
|
||||
@ -89,9 +92,14 @@
|
||||
config,
|
||||
onChange: (_mode: string) => {
|
||||
mode = _mode
|
||||
selectedTypeStore.set(mode as Ref<ProjectType>)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
selectedTypeStore.set(undefined)
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="ac-header full divide caption-height">
|
||||
|
@ -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<Resources> => ({
|
||||
CreateStatePopup,
|
||||
StatusSelector,
|
||||
TemplatesIcon,
|
||||
TypesView
|
||||
TypesView,
|
||||
StatusFilter
|
||||
},
|
||||
actionImpl: {
|
||||
EditStatuses: editStatuses,
|
||||
@ -124,29 +126,14 @@ async function getAllStates (
|
||||
queryId: Ref<Doc>,
|
||||
attr: Attribute<Status>
|
||||
): Promise<any[]> {
|
||||
const _space = query?.space
|
||||
if (_space !== undefined) {
|
||||
const promise = new Promise<Array<Ref<Doc>>>((resolve, reject) => {
|
||||
let refresh: boolean = false
|
||||
const lq = CategoryQuery.getLiveQuery(queryId)
|
||||
refresh = lq.query(task.class.Project, { _id: _space as Ref<Project> }, (res) => {
|
||||
const typeId = res[0]?.type
|
||||
const type = get(typeStore).get(typeId)
|
||||
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[]) ?? []
|
||||
const result = statuses
|
||||
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)
|
||||
CategoryQuery.results.set(queryId, result)
|
||||
resolve(result)
|
||||
onUpdate()
|
||||
})
|
||||
|
||||
if (!refresh) {
|
||||
resolve(CategoryQuery.results.get(queryId) ?? [])
|
||||
}
|
||||
})
|
||||
return await promise
|
||||
}
|
||||
return get(statusStore)
|
||||
.array.filter(
|
||||
@ -162,19 +149,8 @@ async function statusSort (
|
||||
space: Ref<Project> | undefined,
|
||||
viewletDescriptorId?: Ref<ViewletDescriptor>
|
||||
): Promise<Array<Ref<Status>>> {
|
||||
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<Ref<ProjectType> | undefined>(undefined)
|
||||
|
@ -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
|
||||
|
@ -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<Resources> => ({
|
||||
DateFilter,
|
||||
ValueFilter,
|
||||
StringFilter,
|
||||
StatusFilter,
|
||||
TimestampFilter,
|
||||
TableBrowser,
|
||||
SpacePresenter,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user