mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-23 08:48:01 +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
|
label: recruit.string.HideArchivedVacancies
|
||||||
}
|
}
|
||||||
|
|
||||||
const applicantViewOptions = (colors: boolean, hides: boolean): ViewOptionsModel => {
|
const applicantViewOptions = (colors: boolean): ViewOptionsModel => {
|
||||||
const model: ViewOptionsModel = {
|
const model: ViewOptionsModel = {
|
||||||
groupBy: ['status', 'assignee', 'space', 'createdBy', 'modifiedBy'],
|
groupBy: ['status', 'assignee', 'space', 'createdBy', 'modifiedBy'],
|
||||||
orderBy: [
|
orderBy: [
|
||||||
@ -725,15 +725,14 @@ export function createModel (builder: Builder): void {
|
|||||||
actionTarget: 'category',
|
actionTarget: 'category',
|
||||||
action: view.function.ShowEmptyGroups,
|
action: view.function.ShowEmptyGroups,
|
||||||
label: view.string.ShowEmptyGroups
|
label: view.string.ShowEmptyGroups
|
||||||
}
|
},
|
||||||
|
applicationDoneOption,
|
||||||
|
vacancyHideOption
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
if (colors) {
|
if (colors) {
|
||||||
model.other.push(showColorsViewOption)
|
model.other.push(showColorsViewOption)
|
||||||
}
|
}
|
||||||
if (hides) {
|
|
||||||
model.other.push(...[applicationDoneOption, vacancyHideOption])
|
|
||||||
}
|
|
||||||
return model
|
return model
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -811,7 +810,7 @@ export function createModel (builder: Builder): void {
|
|||||||
strict: true,
|
strict: true,
|
||||||
hiddenKeys: ['name', 'attachedTo']
|
hiddenKeys: ['name', 'attachedTo']
|
||||||
},
|
},
|
||||||
viewOptions: applicantViewOptions(true, true)
|
viewOptions: applicantViewOptions(true)
|
||||||
},
|
},
|
||||||
recruit.viewlet.ListApplicant
|
recruit.viewlet.ListApplicant
|
||||||
)
|
)
|
||||||
@ -978,12 +977,8 @@ export function createModel (builder: Builder): void {
|
|||||||
attachTo: recruit.class.Applicant,
|
attachTo: recruit.class.Applicant,
|
||||||
descriptor: task.viewlet.Kanban,
|
descriptor: task.viewlet.Kanban,
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
baseQuery: {
|
|
||||||
isDone: { $ne: true },
|
|
||||||
'$lookup.space.archived': false
|
|
||||||
},
|
|
||||||
viewOptions: {
|
viewOptions: {
|
||||||
...applicantViewOptions(false, false),
|
...applicantViewOptions(false),
|
||||||
groupDepth: 1
|
groupDepth: 1
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
|
@ -412,6 +412,10 @@ export function createModel (builder: Builder): void {
|
|||||||
func: task.function.StatusSort
|
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, {
|
builder.mixin(core.class.Status, core.class.Class, view.mixin.AllValuesFunc, {
|
||||||
func: task.function.GetAllStates
|
func: task.function.GetAllStates
|
||||||
})
|
})
|
||||||
|
@ -753,10 +753,6 @@ export function createModel (builder: Builder): void {
|
|||||||
component: view.component.ObjectFilter
|
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, {
|
builder.mixin(core.class.TypeTimestamp, core.class.Class, view.mixin.AttributeFilter, {
|
||||||
component: view.component.DateFilter,
|
component: view.component.DateFilter,
|
||||||
group: 'bottom'
|
group: 'bottom'
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
import core, { Doc, FindResult, IdMap, Ref, RefTo, Space, Status, toIdMap } from '@hcengineering/core'
|
import core, { Doc, FindResult, IdMap, Ref, RefTo, Space, Status, toIdMap } from '@hcengineering/core'
|
||||||
import { translate } from '@hcengineering/platform'
|
import { translate } from '@hcengineering/platform'
|
||||||
import presentation, { createQuery, getClient } from '@hcengineering/presentation'
|
import presentation, { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import task, { Project, ProjectType, getStates } from '@hcengineering/task'
|
import task, { Project, ProjectType } from '@hcengineering/task'
|
||||||
import ui, {
|
import ui, {
|
||||||
EditWithIcon,
|
EditWithIcon,
|
||||||
Icon,
|
Icon,
|
||||||
@ -30,10 +30,16 @@
|
|||||||
themeStore
|
themeStore
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import { Filter } from '@hcengineering/view'
|
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 { createEventDispatcher } from 'svelte'
|
||||||
import { FILTER_DEBOUNCE_MS, FilterRemovedNotification, sortFilterValues, statusStore } from '../..'
|
import { selectedTypeStore, typeStore } from '..'
|
||||||
import view from '../../plugin'
|
|
||||||
import { buildConfigLookup, getPresenter } from '../../utils'
|
|
||||||
|
|
||||||
export let filter: Filter
|
export let filter: Filter
|
||||||
export let space: Ref<Space> | undefined = undefined
|
export let space: Ref<Space> | undefined = undefined
|
||||||
@ -65,7 +71,12 @@
|
|||||||
|
|
||||||
let filterUpdateTimeout: any | undefined
|
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) {
|
if (objectsPromise) {
|
||||||
await objectsPromise
|
await objectsPromise
|
||||||
}
|
}
|
||||||
@ -74,16 +85,14 @@
|
|||||||
for (const object of filter.value) {
|
for (const object of filter.value) {
|
||||||
targets.add(object)
|
targets.add(object)
|
||||||
}
|
}
|
||||||
if (space !== undefined) {
|
const type = selectedType ? typeStore.get(selectedType) : undefined
|
||||||
const _space = await client.findOne(task.class.Project, { _id: space as Ref<Project> })
|
if (type !== undefined) {
|
||||||
if (_space) {
|
values = type?.statuses?.map((p) => statusStore.get(p._id))
|
||||||
values = getStates(_space, typeStore, statusStore)
|
for (const value of values) {
|
||||||
for (const value of values) {
|
targets.add(value?._id)
|
||||||
targets.add(value?._id)
|
}
|
||||||
}
|
if (search !== '') {
|
||||||
if (search !== '') {
|
values = values.filter((p) => p?.name.includes(search))
|
||||||
values = values.filter((p) => p?.name.includes(search))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const statuses: Status[] = []
|
const statuses: Status[] = []
|
||||||
@ -162,13 +171,7 @@
|
|||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
const typesQuery = createQuery()
|
$: if (targetClass) getValues(search, $selectedTypeStore, $typeStore, $statusStore.byId)
|
||||||
let types: IdMap<ProjectType> = new Map()
|
|
||||||
typesQuery.query(task.class.ProjectType, {}, (res) => {
|
|
||||||
types = toIdMap(res)
|
|
||||||
})
|
|
||||||
|
|
||||||
$: if (targetClass) getValues(search, types, $statusStore.byId)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="selectPopup" use:resizeObserver={() => dispatch('changeContent')}>
|
<div class="selectPopup" use:resizeObserver={() => dispatch('changeContent')}>
|
@ -33,6 +33,8 @@
|
|||||||
import { ViewOptions, Viewlet, ViewletDescriptor, ViewletPreference } from '@hcengineering/view'
|
import { ViewOptions, Viewlet, ViewletDescriptor, ViewletPreference } from '@hcengineering/view'
|
||||||
import { FilterBar, FilterButton, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources'
|
import { FilterBar, FilterButton, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources'
|
||||||
import task from '../plugin'
|
import task from '../plugin'
|
||||||
|
import { onDestroy } from 'svelte'
|
||||||
|
import { selectedTypeStore } from '..'
|
||||||
|
|
||||||
export let _class: Ref<Class<Doc>>
|
export let _class: Ref<Class<Doc>>
|
||||||
export let space: Ref<Space> | undefined = undefined
|
export let space: Ref<Space> | undefined = undefined
|
||||||
@ -82,6 +84,7 @@
|
|||||||
let modeSelectorProps: IModeSelector | undefined = undefined
|
let modeSelectorProps: IModeSelector | undefined = undefined
|
||||||
$: if (mode === undefined && config.length > 0) {
|
$: if (mode === undefined && config.length > 0) {
|
||||||
;[[mode]] = config
|
;[[mode]] = config
|
||||||
|
selectedTypeStore.set(mode as Ref<ProjectType>)
|
||||||
}
|
}
|
||||||
$: if (mode !== undefined) {
|
$: if (mode !== undefined) {
|
||||||
modeSelectorProps = {
|
modeSelectorProps = {
|
||||||
@ -89,9 +92,14 @@
|
|||||||
config,
|
config,
|
||||||
onChange: (_mode: string) => {
|
onChange: (_mode: string) => {
|
||||||
mode = _mode
|
mode = _mode
|
||||||
|
selectedTypeStore.set(mode as Ref<ProjectType>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
selectedTypeStore.set(undefined)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="ac-header full divide caption-height">
|
<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 { Attribute, Class, Doc, DocumentQuery, IdMap, Ref, Status, TxOperations, toIdMap } from '@hcengineering/core'
|
||||||
import { IntlString, Resources } from '@hcengineering/platform'
|
import { IntlString, Resources } from '@hcengineering/platform'
|
||||||
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import task, { Project, ProjectType, Task, calcRank } from '@hcengineering/task'
|
import task, { Project, ProjectType, Task, calcRank } from '@hcengineering/task'
|
||||||
import { getCurrentLocation, navigate, showPopup } from '@hcengineering/ui'
|
import { getCurrentLocation, navigate, showPopup } from '@hcengineering/ui'
|
||||||
import { ViewletDescriptor } from '@hcengineering/view'
|
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 { get, writable } from 'svelte/store'
|
||||||
import AssignedTasks from './components/AssignedTasks.svelte'
|
import AssignedTasks from './components/AssignedTasks.svelte'
|
||||||
import CreateStatePopup from './components/CreateStatePopup.svelte'
|
import CreateStatePopup from './components/CreateStatePopup.svelte'
|
||||||
import Dashboard from './components/Dashboard.svelte'
|
import Dashboard from './components/Dashboard.svelte'
|
||||||
import DueDateEditor from './components/DueDateEditor.svelte'
|
import DueDateEditor from './components/DueDateEditor.svelte'
|
||||||
import KanbanTemplatePresenter from './components/KanbanTemplatePresenter.svelte'
|
import KanbanTemplatePresenter from './components/KanbanTemplatePresenter.svelte'
|
||||||
|
import StatusFilter from './components/StatusFilter.svelte'
|
||||||
import StatusSelector from './components/StatusSelector.svelte'
|
import StatusSelector from './components/StatusSelector.svelte'
|
||||||
import StatusTableView from './components/StatusTableView.svelte'
|
import StatusTableView from './components/StatusTableView.svelte'
|
||||||
import TaskHeader from './components/TaskHeader.svelte'
|
import TaskHeader from './components/TaskHeader.svelte'
|
||||||
import TaskPresenter from './components/TaskPresenter.svelte'
|
import TaskPresenter from './components/TaskPresenter.svelte'
|
||||||
import TemplatesIcon from './components/TemplatesIcon.svelte'
|
import TemplatesIcon from './components/TemplatesIcon.svelte'
|
||||||
|
import TypesView from './components/TypesView.svelte'
|
||||||
import KanbanView from './components/kanban/KanbanView.svelte'
|
import KanbanView from './components/kanban/KanbanView.svelte'
|
||||||
import ProjectEditor from './components/kanban/ProjectEditor.svelte'
|
import ProjectEditor from './components/kanban/ProjectEditor.svelte'
|
||||||
import ProjectTypeSelector from './components/kanban/ProjectTypeSelector.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 TodoItemsPopup from './components/todos/TodoItemsPopup.svelte'
|
||||||
import TodoStatePresenter from './components/todos/TodoStatePresenter.svelte'
|
import TodoStatePresenter from './components/todos/TodoStatePresenter.svelte'
|
||||||
import Todos from './components/todos/Todos.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 { default as AssigneePresenter } from './components/AssigneePresenter.svelte'
|
||||||
export { StateRefPresenter }
|
export { StateRefPresenter }
|
||||||
@ -106,7 +107,8 @@ export default async (): Promise<Resources> => ({
|
|||||||
CreateStatePopup,
|
CreateStatePopup,
|
||||||
StatusSelector,
|
StatusSelector,
|
||||||
TemplatesIcon,
|
TemplatesIcon,
|
||||||
TypesView
|
TypesView,
|
||||||
|
StatusFilter
|
||||||
},
|
},
|
||||||
actionImpl: {
|
actionImpl: {
|
||||||
EditStatuses: editStatuses,
|
EditStatuses: editStatuses,
|
||||||
@ -124,29 +126,14 @@ async function getAllStates (
|
|||||||
queryId: Ref<Doc>,
|
queryId: Ref<Doc>,
|
||||||
attr: Attribute<Status>
|
attr: Attribute<Status>
|
||||||
): Promise<any[]> {
|
): Promise<any[]> {
|
||||||
const _space = query?.space
|
const typeId = get(selectedTypeStore)
|
||||||
if (_space !== undefined) {
|
const type = typeId !== undefined ? get(typeStore).get(typeId) : undefined
|
||||||
const promise = new Promise<Array<Ref<Doc>>>((resolve, reject) => {
|
if (type !== undefined) {
|
||||||
let refresh: boolean = false
|
const statusMap = get(statusStore).byId
|
||||||
const lq = CategoryQuery.getLiveQuery(queryId)
|
const statuses = (type.statuses?.map((p) => statusMap.get(p._id)) as Status[]) ?? []
|
||||||
refresh = lq.query(task.class.Project, { _id: _space as Ref<Project> }, (res) => {
|
return statuses
|
||||||
const typeId = res[0]?.type
|
.filter((p) => p?.category !== task.statusCategory.Lost && p?.category !== task.statusCategory.Won)
|
||||||
const type = get(typeStore).get(typeId)
|
.map((p) => p?._id)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
return get(statusStore)
|
return get(statusStore)
|
||||||
.array.filter(
|
.array.filter(
|
||||||
@ -162,19 +149,8 @@ async function statusSort (
|
|||||||
space: Ref<Project> | undefined,
|
space: Ref<Project> | undefined,
|
||||||
viewletDescriptorId?: Ref<ViewletDescriptor>
|
viewletDescriptorId?: Ref<ViewletDescriptor>
|
||||||
): Promise<Array<Ref<Status>>> {
|
): Promise<Array<Ref<Status>>> {
|
||||||
let type: ProjectType | undefined
|
const typeId = get(selectedTypeStore)
|
||||||
if (space !== undefined) {
|
const type = typeId !== undefined ? get(typeStore).get(typeId) : undefined
|
||||||
const _space = await client.findOne(
|
|
||||||
task.class.Project,
|
|
||||||
{ _id: space },
|
|
||||||
{
|
|
||||||
lookup: {
|
|
||||||
type: task.class.ProjectType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
type = _space?.$lookup?.type
|
|
||||||
}
|
|
||||||
const statuses = get(statusStore).byId
|
const statuses = get(statusStore).byId
|
||||||
|
|
||||||
if (type !== undefined) {
|
if (type !== undefined) {
|
||||||
@ -238,3 +214,5 @@ function fillStores (): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fillStores()
|
fillStores()
|
||||||
|
|
||||||
|
export const selectedTypeStore = writable<Ref<ProjectType> | undefined>(undefined)
|
||||||
|
@ -79,6 +79,7 @@ export default mergeIds(taskId, task, {
|
|||||||
AssigneeRequired: '' as IntlString
|
AssigneeRequired: '' as IntlString
|
||||||
},
|
},
|
||||||
component: {
|
component: {
|
||||||
|
StatusFilter: '' as AnyComponent,
|
||||||
TodoStatePresenter: '' as AnyComponent,
|
TodoStatePresenter: '' as AnyComponent,
|
||||||
AssignedTasks: '' as AnyComponent,
|
AssignedTasks: '' as AnyComponent,
|
||||||
DueDateEditor: '' as AnyComponent
|
DueDateEditor: '' as AnyComponent
|
||||||
|
@ -40,7 +40,6 @@ import FilterTypePopup from './components/filter/FilterTypePopup.svelte'
|
|||||||
import ObjectFilter from './components/filter/ObjectFilter.svelte'
|
import ObjectFilter from './components/filter/ObjectFilter.svelte'
|
||||||
import StringFilter from './components/filter/StringFilter.svelte'
|
import StringFilter from './components/filter/StringFilter.svelte'
|
||||||
import StringFilterPresenter from './components/filter/StringFilterPresenter.svelte'
|
import StringFilterPresenter from './components/filter/StringFilterPresenter.svelte'
|
||||||
import StatusFilter from './components/filter/StatusFilter.svelte'
|
|
||||||
import TimestampFilter from './components/filter/TimestampFilter.svelte'
|
import TimestampFilter from './components/filter/TimestampFilter.svelte'
|
||||||
import ValueFilter from './components/filter/ValueFilter.svelte'
|
import ValueFilter from './components/filter/ValueFilter.svelte'
|
||||||
import HTMLEditor from './components/HTMLEditor.svelte'
|
import HTMLEditor from './components/HTMLEditor.svelte'
|
||||||
@ -206,7 +205,6 @@ export default async (): Promise<Resources> => ({
|
|||||||
DateFilter,
|
DateFilter,
|
||||||
ValueFilter,
|
ValueFilter,
|
||||||
StringFilter,
|
StringFilter,
|
||||||
StatusFilter,
|
|
||||||
TimestampFilter,
|
TimestampFilter,
|
||||||
TableBrowser,
|
TableBrowser,
|
||||||
SpacePresenter,
|
SpacePresenter,
|
||||||
|
@ -25,7 +25,6 @@ export default mergeIds(viewId, view, {
|
|||||||
DateFilter: '' as AnyComponent,
|
DateFilter: '' as AnyComponent,
|
||||||
ValueFilter: '' as AnyComponent,
|
ValueFilter: '' as AnyComponent,
|
||||||
ArrayFilter: '' as AnyComponent,
|
ArrayFilter: '' as AnyComponent,
|
||||||
StatusFilter: '' as AnyComponent,
|
|
||||||
StringFilter: '' as AnyComponent,
|
StringFilter: '' as AnyComponent,
|
||||||
TimestampFilter: '' as AnyComponent,
|
TimestampFilter: '' as AnyComponent,
|
||||||
FilterTypePopup: '' as AnyComponent,
|
FilterTypePopup: '' as AnyComponent,
|
||||||
|
Loading…
Reference in New Issue
Block a user