mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
UBER-871: Allow to hide/show archived and done in vacancies list (#3701)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
3ca0cff505
commit
b61b47a4c3
@ -56,7 +56,7 @@ import {
|
||||
} from '@hcengineering/recruit'
|
||||
import setting from '@hcengineering/setting'
|
||||
import { DoneState, State } from '@hcengineering/task'
|
||||
import { KeyBinding, ViewOptionsModel } from '@hcengineering/view'
|
||||
import { KeyBinding, ViewOptionModel, ViewOptionsModel } from '@hcengineering/view'
|
||||
import recruit from './plugin'
|
||||
import { createReviewModel, reviewTableConfig, reviewTableOptions } from './review'
|
||||
import { TOpinion, TReview } from './review-model'
|
||||
@ -674,7 +674,25 @@ export function createModel (builder: Builder): void {
|
||||
}
|
||||
}
|
||||
|
||||
const applicantViewOptions = (colors: boolean): ViewOptionsModel => {
|
||||
const applicationDoneOption: ViewOptionModel = {
|
||||
key: 'hideDoneState',
|
||||
type: 'toggle',
|
||||
defaultValue: true,
|
||||
actionTarget: 'query',
|
||||
action: recruit.function.HideDoneState,
|
||||
label: recruit.string.HideDoneState
|
||||
}
|
||||
|
||||
const vacancyHideOption: ViewOptionModel = {
|
||||
key: 'hideArchivedVacancies',
|
||||
type: 'toggle',
|
||||
defaultValue: true,
|
||||
actionTarget: 'query',
|
||||
action: recruit.function.HideArchivedVacancies,
|
||||
label: recruit.string.HideArchivedVacancies
|
||||
}
|
||||
|
||||
const applicantViewOptions = (colors: boolean, hides: boolean): ViewOptionsModel => {
|
||||
const model: ViewOptionsModel = {
|
||||
groupBy: ['status', 'doneState', 'assignee', 'space', 'createdBy', 'modifiedBy'],
|
||||
orderBy: [
|
||||
@ -698,6 +716,9 @@ export function createModel (builder: Builder): void {
|
||||
if (colors) {
|
||||
model.other.push(showColorsViewOption)
|
||||
}
|
||||
if (hides) {
|
||||
model.other.push(...[applicationDoneOption, vacancyHideOption])
|
||||
}
|
||||
return model
|
||||
}
|
||||
|
||||
@ -775,11 +796,7 @@ export function createModel (builder: Builder): void {
|
||||
strict: true,
|
||||
hiddenKeys: ['name', 'attachedTo']
|
||||
},
|
||||
baseQuery: {
|
||||
doneState: null,
|
||||
'$lookup.space.archived': false
|
||||
},
|
||||
viewOptions: applicantViewOptions(true)
|
||||
viewOptions: applicantViewOptions(true, true)
|
||||
},
|
||||
recruit.viewlet.ListApplicant
|
||||
)
|
||||
@ -912,7 +929,6 @@ export function createModel (builder: Builder): void {
|
||||
hiddenKeys: ['name', 'space', 'modifiedOn']
|
||||
},
|
||||
baseQuery: {
|
||||
doneState: null,
|
||||
'$lookup.space.archived': false
|
||||
},
|
||||
viewOptions: {
|
||||
@ -941,7 +957,7 @@ export function createModel (builder: Builder): void {
|
||||
'$lookup.space.archived': false
|
||||
},
|
||||
viewOptions: {
|
||||
...applicantViewOptions(false),
|
||||
...applicantViewOptions(false, false),
|
||||
groupDepth: 1
|
||||
},
|
||||
options: {
|
||||
|
@ -21,7 +21,7 @@ import { recruitId } from '@hcengineering/recruit'
|
||||
import recruit from '@hcengineering/recruit-resources/src/plugin'
|
||||
import { KanbanTemplate } from '@hcengineering/task'
|
||||
import type { AnyComponent, Location } from '@hcengineering/ui'
|
||||
import type { Action, ActionCategory, ViewAction, Viewlet } from '@hcengineering/view'
|
||||
import type { Action, ActionCategory, ViewAction, ViewQueryAction, Viewlet } from '@hcengineering/view'
|
||||
|
||||
export default mergeIds(recruitId, recruit, {
|
||||
action: {
|
||||
@ -45,7 +45,9 @@ export default mergeIds(recruitId, recruit, {
|
||||
GetObjectLinkFragment: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
|
||||
GetIdObjectLinkFragment: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
|
||||
GetObjectLink: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<string>>,
|
||||
GetTalentId: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<string>>
|
||||
GetTalentId: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<string>>,
|
||||
HideDoneState: '' as ViewQueryAction,
|
||||
HideArchivedVacancies: '' as ViewQueryAction
|
||||
},
|
||||
string: {
|
||||
ApplicationsShort: '' as IntlString,
|
||||
@ -66,7 +68,9 @@ export default mergeIds(recruitId, recruit, {
|
||||
GotoRecruitApplication: '' as IntlString,
|
||||
VacancyList: '' as IntlString,
|
||||
ConfigDescription: '' as IntlString,
|
||||
ShowApplications: '' as IntlString
|
||||
ShowApplications: '' as IntlString,
|
||||
HideDoneState: '' as IntlString,
|
||||
HideArchivedVacancies: '' as IntlString
|
||||
},
|
||||
validator: {
|
||||
ApplicantValidator: '' as Resource<<T extends Doc>(doc: T, client: Client) => Promise<Status>>
|
||||
|
@ -118,7 +118,9 @@
|
||||
"MyApplications": "My applications",
|
||||
|
||||
"ShowApplications": "Show applications",
|
||||
"GetTalentIds": "Get talents' ids"
|
||||
"GetTalentIds": "Get talents' ids",
|
||||
"HideDoneState": "Hide complete applications",
|
||||
"HideArchivedVacancies": "Hide from archived Vacancies"
|
||||
},
|
||||
"status": {
|
||||
"ApplicationExists": "Application already exists",
|
||||
|
@ -118,7 +118,9 @@
|
||||
"MyApplications": "Мои кандидаты",
|
||||
|
||||
"ShowApplications": "Показать кандидатов",
|
||||
"GetTalentIds": "Получить ID талантов"
|
||||
"GetTalentIds": "Получить ID талантов",
|
||||
"HideDoneState": "Скрыть завершенных кандидатов",
|
||||
"HideArchivedVacancies": "Скрыть архивные вакансии"
|
||||
},
|
||||
"status": {
|
||||
"ApplicationExists": "Кандидат уже существует",
|
||||
|
@ -24,7 +24,7 @@ import {
|
||||
toIdMap
|
||||
} from '@hcengineering/core'
|
||||
import { OK, Resources, Severity, Status } from '@hcengineering/platform'
|
||||
import { ObjectSearchResult } from '@hcengineering/presentation'
|
||||
import { ObjectSearchResult, createQuery } from '@hcengineering/presentation'
|
||||
import { Applicant, Candidate, Vacancy } from '@hcengineering/recruit'
|
||||
import task from '@hcengineering/task'
|
||||
import { showPopup } from '@hcengineering/ui'
|
||||
@ -277,6 +277,40 @@ async function noneApplicant (filter: Filter, onUpdate: () => void): Promise<Obj
|
||||
return { $in: result }
|
||||
}
|
||||
|
||||
export function hideDoneState (value: any, query: DocumentQuery<Doc>): DocumentQuery<Doc> {
|
||||
if (value as boolean) {
|
||||
return { ...query, doneState: null }
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
const activeVacancyQuery = createQuery(true)
|
||||
|
||||
let activeVacancies: Promise<Array<Ref<Vacancy>>> | Array<Ref<Vacancy>> | undefined
|
||||
|
||||
export async function hideArchivedVacancies (value: any, query: DocumentQuery<Doc>): Promise<DocumentQuery<Doc>> {
|
||||
if (activeVacancies === undefined) {
|
||||
activeVacancies = new Promise<Array<Ref<Vacancy>>>((resolve) => {
|
||||
activeVacancyQuery.query(
|
||||
recruit.class.Vacancy,
|
||||
{ archived: { $ne: true } },
|
||||
(res) => {
|
||||
activeVacancies = res.map((it) => it._id)
|
||||
resolve(activeVacancies)
|
||||
},
|
||||
{ projection: { _id: 1 } }
|
||||
)
|
||||
})
|
||||
}
|
||||
if (value as boolean) {
|
||||
if (activeVacancies instanceof Promise) {
|
||||
activeVacancies = await activeVacancies
|
||||
}
|
||||
return { ...query, space: { $in: activeVacancies } }
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
export default async (): Promise<Resources> => ({
|
||||
actionImpl: {
|
||||
CreateOpinion: createOpinion,
|
||||
@ -342,7 +376,9 @@ export default async (): Promise<Resources> => ({
|
||||
NoneApplications: noneApplicant,
|
||||
GetObjectLink: objectLinkProvider,
|
||||
GetObjectLinkFragment: getSequenceLink,
|
||||
GetIdObjectLinkFragment: getObjectLink
|
||||
GetIdObjectLinkFragment: getObjectLink,
|
||||
HideDoneState: hideDoneState,
|
||||
HideArchivedVacancies: hideArchivedVacancies
|
||||
},
|
||||
resolver: {
|
||||
Location: resolveLocation
|
||||
|
@ -69,10 +69,14 @@
|
||||
targets.clear()
|
||||
|
||||
const spaces = (
|
||||
await client.findAll(core.class.Space, { archived: true }, { projection: { _id: 1, archived: 1, _class: 1 } })
|
||||
await client.findAll(
|
||||
core.class.Space,
|
||||
{ archived: { $ne: true } },
|
||||
{ projection: { _id: 1, archived: 1, _class: 1 } }
|
||||
)
|
||||
).map((it) => it._id)
|
||||
|
||||
const baseObjects = await client.findAll(filter.key._class, space ? { space } : { space: { $nin: spaces } }, {
|
||||
const baseObjects = await client.findAll(filter.key._class, space ? { space } : { space: { $in: spaces } }, {
|
||||
projection: { [filter.key.key]: 1, space: 1 }
|
||||
})
|
||||
for (const object of baseObjects) {
|
||||
|
@ -74,17 +74,19 @@
|
||||
}
|
||||
const isDerivedFromSpace = hierarchy.isDerived(_class, core.class.Space)
|
||||
|
||||
const archived =
|
||||
const notArchived =
|
||||
space === undefined || isDerivedFromSpace
|
||||
? []
|
||||
: (await client.findAll(core.class.Space, { archived: true }, { projection: { _id: 1 } })).map((it) => it._id)
|
||||
: (await client.findAll(core.class.Space, { archived: { $ne: true } }, { projection: { _id: 1 } })).map(
|
||||
(it) => it._id
|
||||
)
|
||||
|
||||
async function doQuery (limit: number | undefined, first1000?: any[]): Promise<void> {
|
||||
async function doQuery (limit: number | undefined, first1000?: any[]): Promise<boolean> {
|
||||
const p = client.findAll(
|
||||
_class,
|
||||
{
|
||||
...resultQuery,
|
||||
...(space ? { space } : isDerivedFromSpace ? { archived: false } : { space: { $nin: archived } }),
|
||||
...(space ? { space } : isDerivedFromSpace ? { archived: false } : { space: { $in: notArchived } }),
|
||||
...(first1000 ? { [filter.key.key]: { $nin: first1000 } } : {})
|
||||
},
|
||||
{
|
||||
@ -111,17 +113,19 @@
|
||||
for (const object of filter.value.map((p) => p[0])) {
|
||||
values.add(object)
|
||||
}
|
||||
return res.length >= (limit ?? 0)
|
||||
}
|
||||
await doQuery(1000)
|
||||
const hasMore = await doQuery(1000)
|
||||
values = values
|
||||
sortedValues = sortFilterValues([...values.keys()], (v) => isSelected(v, selectedValues))
|
||||
objectsPromise = undefined
|
||||
|
||||
// Check if we have all possible values, in case of enumeration
|
||||
await doQuery(undefined, Array.from(values))
|
||||
|
||||
sortedValues = sortFilterValues([...values.keys()], (v) => isSelected(v, selectedValues))
|
||||
objectsPromise = undefined
|
||||
if (hasMore) {
|
||||
await doQuery(undefined, Array.from(values))
|
||||
sortedValues = sortFilterValues([...values.keys()], (v) => isSelected(v, selectedValues))
|
||||
objectsPromise = undefined
|
||||
}
|
||||
}
|
||||
|
||||
function getValue (obj: any): any {
|
||||
|
@ -157,12 +157,17 @@
|
||||
viewOptionsStore: ViewOptions
|
||||
): Promise<DocumentQuery<Doc>> {
|
||||
if (viewOptions === undefined) return query
|
||||
let result = hierarchy.clone(query)
|
||||
let result: DocumentQuery<Doc> = hierarchy.clone(query)
|
||||
for (const viewOption of viewOptions) {
|
||||
if (viewOption.actionTarget !== 'query') continue
|
||||
const queryOption = viewOption as ViewQueryOption
|
||||
const f = await getResource(queryOption.action)
|
||||
result = f(viewOptionsStore[queryOption.key] ?? queryOption.defaultValue, query)
|
||||
const resultP = f(viewOptionsStore[queryOption.key] ?? queryOption.defaultValue, result)
|
||||
if (resultP instanceof Promise) {
|
||||
result = await resultP
|
||||
} else {
|
||||
result = resultP
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -118,6 +118,10 @@
|
||||
<span class="text-base fs-bold overflow-label pointer-events-none">
|
||||
<Label label={view.string.NoGrouping} />
|
||||
</span>
|
||||
{:else if category === undefined}
|
||||
<span class="overflow-label pointer-events-none">
|
||||
<Label label={view.string.NotSpecified} />
|
||||
</span>
|
||||
{:else if headerComponent}
|
||||
<svelte:component
|
||||
this={headerComponent.presenter}
|
||||
|
@ -666,7 +666,9 @@ export interface CategoryOption extends ViewOption {
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type ViewQueryAction = Resource<(value: any, query: DocumentQuery<Doc>) => DocumentQuery<Doc>>
|
||||
export type ViewQueryAction = Resource<
|
||||
(value: any, query: DocumentQuery<Doc>) => DocumentQuery<Doc> | Promise<DocumentQuery<Doc>>
|
||||
>
|
||||
|
||||
/**
|
||||
* @public
|
||||
|
Loading…
Reference in New Issue
Block a user