Add none filter (#2238)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2022-07-17 23:56:01 +07:00 committed by GitHub
parent e7c0740b62
commit 8600e82243
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 83 additions and 24 deletions

View File

@ -750,6 +750,16 @@ export function createModel (builder: Builder): void {
}, },
recruit.filter.NoActive recruit.filter.NoActive
) )
builder.createDoc(
view.class.FilterMode,
core.space.Model,
{
label: recruit.string.NoneApplications,
result: recruit.function.NoneApplications,
disableValueSelector: true
},
recruit.filter.None
)
} }
export { recruitOperation } from './migration' export { recruitOperation } from './migration'

View File

@ -91,7 +91,8 @@
"CopyId": "Copy ID", "CopyId": "Copy ID",
"CopyLink": "Copy link", "CopyLink": "Copy link",
"HasActiveApplicant":"Active Only", "HasActiveApplicant":"Active Only",
"HasNoActiveApplicant": "No Active" "HasNoActiveApplicant": "No Active",
"NoneApplications": "None"
}, },
"status": { "status": {
"TalentRequired": "Please select talent", "TalentRequired": "Please select talent",

View File

@ -93,7 +93,8 @@
"CopyId": "Копировать ID", "CopyId": "Копировать ID",
"CopyLink": "Копировать ссылку", "CopyLink": "Копировать ссылку",
"HasActiveApplicant":"Только активные", "HasActiveApplicant":"Только активные",
"HasNoActiveApplicant": "Не активные" "HasNoActiveApplicant": "Не активные",
"NoneApplications": "Отсутствуют"
}, },
"status": { "status": {
"TalentRequired": "Пожалуйста выберите таланта", "TalentRequired": "Пожалуйста выберите таланта",

View File

@ -14,8 +14,9 @@
--> -->
<script lang="ts"> <script lang="ts">
import { Class, Doc, Ref } from '@anticrm/core' import { Class, Doc, Ref } from '@anticrm/core'
import { Button } from '@anticrm/ui' import { getClient } from '@anticrm/presentation'
import { Filter } from '@anticrm/view' import { SelectPopup } from '@anticrm/ui'
import view, { Filter, FilterMode } from '@anticrm/view'
import { FilterQuery } from '@anticrm/view-resources' import { FilterQuery } from '@anticrm/view-resources'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import recruit from '../plugin' import recruit from '../plugin'
@ -23,28 +24,28 @@
export let _class: Ref<Class<Doc>> export let _class: Ref<Class<Doc>>
export let filter: Filter export let filter: Filter
export let onChange: (e: Filter) => void export let onChange: (e: Filter) => void
const client = getClient()
filter.onRemove = () => { filter.onRemove = () => {
FilterQuery.remove(filter.index) FilterQuery.remove(filter.index)
} }
filter.modes = [recruit.filter.HasActive, recruit.filter.NoActive] filter.modes = [recruit.filter.HasActive, recruit.filter.NoActive, recruit.filter.None]
filter.mode = filter.mode === undefined ? filter.modes[0] : filter.mode filter.mode = filter.mode === undefined ? filter.modes[0] : filter.mode
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let modes: FilterMode[] = []
client.findAll(view.class.FilterMode, { _id: { $in: filter.modes } }).then((res) => {
modes = res
})
</script> </script>
<div class="selectPopup"> <div class="selectPopup">
<Button <SelectPopup
label={recruit.string.HasActiveApplicant} value={modes.map((it) => ({ ...it, id: it._id }))}
on:click={async () => { on:close={(evt) => {
filter.mode = recruit.filter.HasActive filter.mode = evt.detail
onChange(filter)
dispatch('close')
}}
/>
<Button
label={recruit.string.HasNoActiveApplicant}
on:click={async () => {
filter.mode = recruit.filter.NoActive
onChange(filter) onChange(filter)
dispatch('close') dispatch('close')
}} }}

View File

@ -16,7 +16,7 @@
import type { Client, Doc, FindResult, ObjQueryType, Ref } from '@anticrm/core' import type { Client, Doc, FindResult, ObjQueryType, Ref } from '@anticrm/core'
import { IntlString, OK, Resources, Severity, Status, translate } from '@anticrm/platform' import { IntlString, OK, Resources, Severity, Status, translate } from '@anticrm/platform'
import { ObjectSearchResult } from '@anticrm/presentation' import { ObjectSearchResult } from '@anticrm/presentation'
import { Applicant } from '@anticrm/recruit' import { Applicant, Candidate } from '@anticrm/recruit'
import task from '@anticrm/task' import task from '@anticrm/task'
import { showPopup } from '@anticrm/ui' import { showPopup } from '@anticrm/ui'
import { Filter } from '@anticrm/view' import { Filter } from '@anticrm/view'
@ -114,10 +114,9 @@ export async function queryApplication (client: Client, search: string): Promise
})) }))
} }
export async function getActiveTalants (filter: Filter, onUpdate: () => void): Promise<Array<Ref<Doc>>> { async function getActiveTalants (filter: Filter, onUpdate: () => void): Promise<Array<Ref<Doc>>> {
const promise = new Promise<Array<Ref<Doc>>>((resolve, reject) => { const promise = new Promise<Array<Ref<Doc>>>((resolve, reject) => {
let refresh: boolean = false let refresh: boolean = false
const lq = FilterQuery.getLiveQuery(filter.index) const lq = FilterQuery.getLiveQuery(filter.index)
refresh = lq.query( refresh = lq.query(
recruit.class.Applicant, recruit.class.Applicant,
@ -129,6 +128,45 @@ export async function getActiveTalants (filter: Filter, onUpdate: () => void): P
FilterQuery.results.set(filter.index, result) FilterQuery.results.set(filter.index, result)
resolve(result) resolve(result)
onUpdate() onUpdate()
},
{
projection: {
_id: 1,
_class: 1,
doneState: 1,
attachedTo: 1
}
}
)
if (!refresh) {
resolve(FilterQuery.results.get(filter.index) ?? [])
}
})
return await promise
}
async function getNoApplicantCandidates (filter: Filter, onUpdate: () => void): Promise<Array<Ref<Doc>>> {
const promise = new Promise<Array<Ref<Doc>>>((resolve, reject) => {
let refresh: boolean = false
const lq = FilterQuery.getLiveQuery(filter.index)
refresh = lq.query(
recruit.mixin.Candidate,
{
applications: { $in: [0, undefined] }
},
(refs: FindResult<Candidate>) => {
const result = Array.from(refs.map((p) => p._id))
FilterQuery.results.set(filter.index, result)
resolve(result)
onUpdate()
},
{
projection: {
_id: 1,
_class: 1,
applications: 1
}
} }
) )
@ -147,6 +185,10 @@ async function hasNoActiveApplicant (filter: Filter, onUpdate: () => void): Prom
const result = await getActiveTalants(filter, onUpdate) const result = await getActiveTalants(filter, onUpdate)
return { $nin: result } return { $nin: result }
} }
async function noneApplicant (filter: Filter, onUpdate: () => void): Promise<ObjQueryType<any>> {
const result = await getNoApplicantCandidates(filter, onUpdate)
return { $in: result }
}
export default async (): Promise<Resources> => ({ export default async (): Promise<Resources> => ({
actionImpl: { actionImpl: {
@ -192,6 +234,7 @@ export default async (): Promise<Resources> => ({
function: { function: {
ApplicationTitleProvider: getApplicationTitle, ApplicationTitleProvider: getApplicationTitle,
HasActiveApplicant: hasActiveApplicant, HasActiveApplicant: hasActiveApplicant,
HasNoActiveApplicant: hasNoActiveApplicant HasNoActiveApplicant: hasNoActiveApplicant,
NoneApplications: noneApplicant
} }
}) })

View File

@ -104,7 +104,8 @@ export default mergeIds(recruitId, recruit, {
TalentSelect: '' as IntlString, TalentSelect: '' as IntlString,
FullDescription: '' as IntlString, FullDescription: '' as IntlString,
HasActiveApplicant: '' as IntlString, HasActiveApplicant: '' as IntlString,
HasNoActiveApplicant: '' as IntlString HasNoActiveApplicant: '' as IntlString,
NoneApplications: '' as IntlString
}, },
space: { space: {
CandidatesPublic: '' as Ref<Space> CandidatesPublic: '' as Ref<Space>
@ -124,10 +125,12 @@ export default mergeIds(recruitId, recruit, {
function: { function: {
ApplicationTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>) => Promise<string>>, ApplicationTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>) => Promise<string>>,
HasActiveApplicant: '' as Resource<(filter: Filter, onUpdate: () => void) => Promise<ObjQueryType<any>>>, HasActiveApplicant: '' as Resource<(filter: Filter, onUpdate: () => void) => Promise<ObjQueryType<any>>>,
HasNoActiveApplicant: '' as Resource<(filter: Filter, onUpdate: () => void) => Promise<ObjQueryType<any>>> HasNoActiveApplicant: '' as Resource<(filter: Filter, onUpdate: () => void) => Promise<ObjQueryType<any>>>,
NoneApplications: '' as Resource<(filter: Filter, onUpdate: () => void) => Promise<ObjQueryType<any>>>
}, },
filter: { filter: {
HasActive: '' as Ref<FilterMode>, HasActive: '' as Ref<FilterMode>,
NoActive: '' as Ref<FilterMode> NoActive: '' as Ref<FilterMode>,
None: '' as Ref<FilterMode>
} }
}) })