diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 34e87cd110..59c89fd356 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -144,8 +144,20 @@ export async function createClient ( const txMap = new Map<Ref<Tx>, Ref<Tx>>() for (const tx of txes) txMap.set(tx._id, tx._id) - for (const tx of txes) hierarchy.tx(tx) - for (const tx of txes) await model.tx(tx) + for (const tx of txes) { + try { + hierarchy.tx(tx) + } catch (err: any) { + console.error('failed to apply model transaction, skipping', JSON.stringify(tx), err) + } + } + for (const tx of txes) { + try { + await model.tx(tx) + } catch (err: any) { + console.error('failed to apply model transaction, skipping', JSON.stringify(tx), err) + } + } txBuffer = txBuffer.filter((tx) => txMap.get(tx._id) === undefined) diff --git a/packages/core/src/hierarchy.ts b/packages/core/src/hierarchy.ts index 68f9970c6c..d99c807ff9 100644 --- a/packages/core/src/hierarchy.ts +++ b/packages/core/src/hierarchy.ts @@ -364,7 +364,7 @@ export class Hierarchy { const _cl = getClass(v as ToClassRefT<T, keyof T>) if (this.isMixin(_cl)) { const mval = (lookup as any)[k] - if (mval !== undefined) { + if (mval != null) { (lookup as any)[k] = this.as(mval, _cl) } } diff --git a/plugins/recruit-resources/src/components/Vacancies.svelte b/plugins/recruit-resources/src/components/Vacancies.svelte index dd892bb03a..d0c99f1c38 100644 --- a/plugins/recruit-resources/src/components/Vacancies.svelte +++ b/plugins/recruit-resources/src/components/Vacancies.svelte @@ -30,34 +30,45 @@ } let search: string = '' + let vquery: string = '' let resultQuery: DocumentQuery<Doc> = {} let vacancyQuery: DocumentQuery<Doc> = {} - async function updateResultQuery (search: string): Promise<void> { - resultQuery = search === '' ? {} : { $search: search } - } - let vacancies: Vacancy[] = [] const query = createQuery() + let appQuery = false $: query.query(recruit.class.Vacancy, { archived: false }, (res) => { vacancies = res }) - $: if (vacancies.length > 0) { + function lowerIncludes (a?: string, b: string): boolean { + return (a ?? '').toLowerCase().includes(b) + } + + $: if (vacancies.length > 0 && !appQuery) { vacancyQuery = { _id: { $in: vacancies - .filter((it) => it.name.includes(search) || it.description.includes(search) || it.company?.includes(search) || ((applications?.get(it._id) ?? 0) > 0)) + .filter( + (it) => + lowerIncludes(it.name, vquery) || + lowerIncludes(it.description, vquery) || + lowerIncludes(it.company, vquery) || + (applications?.get(it._id) ?? 0) > 0 + ) .map((it) => it._id) } } } + $: resultQuery = vquery === '' ? {} : { $search: vquery } + let applications: Map<Ref<Vacancy>, number> | undefined const applicantQuery = createQuery() $: if (vacancies.length > 0) { + appQuery = true applicantQuery.query( recruit.class.Applicant, { ...(resultQuery as DocumentQuery<Applicant>), space: { $in: vacancies.map((it) => it._id) } }, @@ -69,6 +80,7 @@ } applications = result + appQuery = false } ) } @@ -86,7 +98,7 @@ <SearchEdit bind:value={search} on:change={() => { - updateResultQuery(search) + vquery = search }} /> <Button label={recruit.string.Create} primary={true} size={'small'} on:click={(ev) => showCreateDialog(ev)} /> diff --git a/server/core/src/storage.ts b/server/core/src/storage.ts index db7b5fd35f..aa751dadc2 100644 --- a/server/core/src/storage.ts +++ b/server/core/src/storage.ts @@ -314,12 +314,20 @@ export async function createServerStorage (conf: DbConfiguration, options?: Serv const model = await txAdapter.getModel() for (const tx of model) { - hierarchy.tx(tx) - await triggers.tx(tx) + try { + hierarchy.tx(tx) + await triggers.tx(tx) + } catch (err: any) { + console.error('failed to apply model transaction, skipping', JSON.stringify(tx), err) + } } for (const tx of model) { - await modelDb.tx(tx) + try { + await modelDb.tx(tx) + } catch (err: any) { + console.error('failed to apply model transaction, skipping', JSON.stringify(tx), err) + } } for (const [, adapter] of adapters) {