mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 11:01:54 +03:00
parent
565b823847
commit
79121cb8b0
@ -17,7 +17,7 @@ import activity from '@hcengineering/activity'
|
||||
import chunter from '@hcengineering/chunter'
|
||||
import type { EmployeeAccount } from '@hcengineering/contact'
|
||||
import contact from '@hcengineering/contact'
|
||||
import { Doc, Domain, IndexKind, Ref, TxCUD } from '@hcengineering/core'
|
||||
import { Domain, IndexKind, Ref, Tx } from '@hcengineering/core'
|
||||
import {
|
||||
ArrOf,
|
||||
Builder,
|
||||
@ -33,12 +33,12 @@ import {
|
||||
} from '@hcengineering/model'
|
||||
import { TComment } from '@hcengineering/model-chunter'
|
||||
import core, { TAttachedDoc, TClass } from '@hcengineering/model-core'
|
||||
import { generateClassNotificationTypes } from '@hcengineering/model-notification'
|
||||
import view from '@hcengineering/model-view'
|
||||
import notification from '@hcengineering/notification'
|
||||
import { Request, RequestDecisionComment, RequestPresenter, RequestStatus } from '@hcengineering/request'
|
||||
import { AnyComponent } from '@hcengineering/ui'
|
||||
import request from './plugin'
|
||||
import notification from '@hcengineering/notification'
|
||||
import { generateClassNotificationTypes } from '@hcengineering/model-notification'
|
||||
|
||||
export { requestId } from '@hcengineering/request'
|
||||
export { default } from './plugin'
|
||||
@ -62,7 +62,7 @@ export class TRequest extends TAttachedDoc implements Request {
|
||||
@Index(IndexKind.Indexed)
|
||||
status!: RequestStatus
|
||||
|
||||
tx!: TxCUD<Doc>
|
||||
tx!: Tx
|
||||
|
||||
@Prop(TypeRef(contact.class.EmployeeAccount), request.string.Rejected)
|
||||
@ReadOnly()
|
||||
|
@ -13,12 +13,12 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Comment } from '@hcengineering/chunter'
|
||||
import { EmployeeAccount } from '@hcengineering/contact'
|
||||
import type { AttachedDoc, Class, Doc, Mixin, Ref, TxCUD } from '@hcengineering/core'
|
||||
import type { AttachedDoc, Class, Doc, Mixin, Ref, Tx } from '@hcengineering/core'
|
||||
import type { Asset, IntlString, Plugin } from '@hcengineering/platform'
|
||||
import { plugin } from '@hcengineering/platform'
|
||||
import { AnyComponent } from '@hcengineering/ui'
|
||||
import { Comment } from '@hcengineering/chunter'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -29,7 +29,7 @@ export interface Request extends AttachedDoc {
|
||||
requiredApprovesCount: number
|
||||
rejected?: Ref<EmployeeAccount>
|
||||
status: RequestStatus
|
||||
tx: TxCUD<Doc>
|
||||
tx: Tx
|
||||
comments?: number
|
||||
}
|
||||
|
||||
|
@ -606,110 +606,99 @@ class TServerStorage implements ServerStorage {
|
||||
return { passed, onEnd }
|
||||
}
|
||||
|
||||
async apply (ctx: MeasureContext, tx: Tx[], broadcast: boolean): Promise<Tx[]> {
|
||||
const triggerFx = new Effects()
|
||||
const _findAll = createFindAll(this)
|
||||
async apply (ctx: MeasureContext, txes: Tx[], broadcast: boolean): Promise<Tx[]> {
|
||||
const result = await this.processTxes(ctx, txes)
|
||||
let derived: Tx[] = []
|
||||
|
||||
const txToStore = tx.filter(
|
||||
(it) => it.space !== core.space.DerivedTx && !this.hierarchy.isDerived(it._class, core.class.TxApplyIf)
|
||||
)
|
||||
await ctx.with('domain-tx', {}, async () => await this.getAdapter(DOMAIN_TX).tx(...txToStore))
|
||||
derived = result[1]
|
||||
|
||||
const removedMap = new Map<Ref<Doc>, Doc>()
|
||||
await ctx.with('apply', {}, (ctx) => this.routeTx(ctx, removedMap, ...tx))
|
||||
|
||||
// send transactions
|
||||
if (broadcast) {
|
||||
this.options?.broadcast?.(tx)
|
||||
}
|
||||
// invoke triggers and store derived objects
|
||||
const derived = await this.processDerived(ctx, tx, triggerFx, _findAll, removedMap)
|
||||
|
||||
// index object
|
||||
for (const _tx of tx) {
|
||||
await ctx.with('fulltext', {}, (ctx) => this.fulltext.tx(ctx, _tx))
|
||||
}
|
||||
|
||||
// index derived objects
|
||||
for (const tx of derived) {
|
||||
await ctx.with('derived-processor', { _class: txClass(tx) }, (ctx) => this.fulltext.tx(ctx, tx))
|
||||
}
|
||||
|
||||
for (const fx of triggerFx.effects) {
|
||||
await fx()
|
||||
}
|
||||
if (broadcast && derived.length > 0) {
|
||||
this.options?.broadcast?.(txes)
|
||||
this.options?.broadcast?.(derived)
|
||||
}
|
||||
return [...tx, ...derived]
|
||||
|
||||
return [...txes, ...derived]
|
||||
}
|
||||
|
||||
async tx (ctx: MeasureContext, tx: Tx): Promise<[TxResult, Tx[]]> {
|
||||
// store tx
|
||||
const _class = txClass(tx)
|
||||
const _findAll = createFindAll(this)
|
||||
const objClass = txObjectClass(tx)
|
||||
const removedDocs = new Map<Ref<Doc>, Doc>()
|
||||
return await ctx.with('tx', { _class, objClass }, async (ctx) => {
|
||||
if (tx.space !== core.space.DerivedTx && !this.hierarchy.isDerived(tx._class, core.class.TxApplyIf)) {
|
||||
await ctx.with('domain-tx', { _class, objClass }, async () => await this.getAdapter(DOMAIN_TX).tx(tx))
|
||||
fillTxes (txes: Tx[], txToStore: Tx[], modelTx: Tx[], txToProcess: Tx[], applyTxes: Tx[]): void {
|
||||
for (const tx of txes) {
|
||||
if (!this.hierarchy.isDerived(tx._class, core.class.TxApplyIf)) {
|
||||
if (tx.space !== core.space.DerivedTx) {
|
||||
txToStore.push(tx)
|
||||
}
|
||||
if (tx.objectSpace === core.space.Model) {
|
||||
modelTx.push(tx)
|
||||
}
|
||||
txToProcess.push(tx)
|
||||
} else {
|
||||
applyTxes.push(tx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx.objectSpace === core.space.Model) {
|
||||
async processTxes (ctx: MeasureContext, txes: Tx[]): Promise<[TxResult, Tx[]]> {
|
||||
// store tx
|
||||
const _findAll = createFindAll(this)
|
||||
const txToStore: Tx[] = []
|
||||
const modelTx: Tx[] = []
|
||||
const applyTxes: Tx[] = []
|
||||
const txToProcess: Tx[] = []
|
||||
const triggerFx = new Effects()
|
||||
const removedMap = new Map<Ref<Doc>, Doc>()
|
||||
const onEnds: (() => void)[] = []
|
||||
let result: TxResult = {}
|
||||
let derived: Tx[] = []
|
||||
|
||||
try {
|
||||
this.fillTxes(txes, txToStore, modelTx, txToProcess, applyTxes)
|
||||
for (const tx of applyTxes) {
|
||||
const applyIf = tx as TxApplyIf
|
||||
// Wait for scope promise if found
|
||||
const passed = await this.verifyApplyIf(ctx, applyIf, _findAll)
|
||||
onEnds.push(passed.onEnd)
|
||||
if (passed.passed) {
|
||||
this.fillTxes(applyIf.txes, txToStore, modelTx, txToProcess, applyTxes)
|
||||
derived = [...applyIf.txes]
|
||||
}
|
||||
}
|
||||
for (const tx of modelTx) {
|
||||
// maintain hierarchy and triggers
|
||||
this.hierarchy.tx(tx)
|
||||
await this.triggers.tx(tx)
|
||||
await this.modelDb.tx(tx)
|
||||
this.model.push(tx)
|
||||
}
|
||||
await ctx.with('domain-tx', {}, async () => await this.getAdapter(DOMAIN_TX).tx(...txToStore))
|
||||
result = await ctx.with('apply', {}, (ctx) => this.routeTx(ctx, removedMap, ...txToProcess))
|
||||
|
||||
const triggerFx = new Effects()
|
||||
// invoke triggers and store derived objects
|
||||
derived = derived.concat(await this.processDerived(ctx, txToProcess, triggerFx, _findAll, removedMap))
|
||||
|
||||
let result: TxResult = {}
|
||||
let derived: Tx[] = []
|
||||
let onEnd = (): void => {}
|
||||
|
||||
try {
|
||||
if (this.hierarchy.isDerived(tx._class, core.class.TxApplyIf)) {
|
||||
const applyIf = tx as TxApplyIf
|
||||
// Wait for scope promise if found
|
||||
let passed: boolean
|
||||
;({ passed, onEnd } = await this.verifyApplyIf(ctx, applyIf, _findAll))
|
||||
result = passed
|
||||
if (passed) {
|
||||
// Store apply if transaction's if required
|
||||
await ctx.with('domain-tx', { _class, objClass }, async () => {
|
||||
const atx = await this.getAdapter(DOMAIN_TX)
|
||||
await atx.tx(...applyIf.txes)
|
||||
})
|
||||
derived = await this.processDerivedTxes(applyIf.txes, ctx, triggerFx, _findAll, removedDocs)
|
||||
}
|
||||
} else {
|
||||
// store object
|
||||
result = await ctx.with('route-tx', { _class, objClass }, (ctx) => this.routeTx(ctx, removedDocs, tx))
|
||||
// invoke triggers and store derived objects
|
||||
derived = await this.processDerived(ctx, [tx], triggerFx, _findAll, removedDocs)
|
||||
}
|
||||
|
||||
// index object
|
||||
await ctx.with('fulltext', { _class, objClass }, (ctx) => this.fulltext.tx(ctx, tx))
|
||||
// index derived objects
|
||||
for (const tx of derived) {
|
||||
await ctx.with('derived-fulltext', { _class: txClass(tx) }, (ctx) => this.fulltext.tx(ctx, tx))
|
||||
}
|
||||
|
||||
for (const fx of triggerFx.effects) {
|
||||
await fx()
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.log(err)
|
||||
throw err
|
||||
} finally {
|
||||
onEnd()
|
||||
// index object
|
||||
for (const _tx of txToProcess) {
|
||||
await ctx.with('fulltext', {}, (ctx) => this.fulltext.tx(ctx, _tx))
|
||||
}
|
||||
|
||||
return [result, derived]
|
||||
})
|
||||
// index derived objects
|
||||
for (const tx of derived) {
|
||||
await ctx.with('derived-processor', { _class: txClass(tx) }, (ctx) => this.fulltext.tx(ctx, tx))
|
||||
}
|
||||
|
||||
for (const fx of triggerFx.effects) {
|
||||
await fx()
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.log(err)
|
||||
throw err
|
||||
} finally {
|
||||
onEnds.forEach((p) => p())
|
||||
}
|
||||
|
||||
return [result, derived]
|
||||
}
|
||||
|
||||
async tx (ctx: MeasureContext, tx: Tx): Promise<[TxResult, Tx[]]> {
|
||||
return await this.processTxes(ctx, [tx])
|
||||
}
|
||||
|
||||
find (domain: Domain): StorageIterator {
|
||||
@ -742,12 +731,6 @@ class Effects {
|
||||
}
|
||||
}
|
||||
|
||||
function txObjectClass (tx: Tx): string {
|
||||
return tx._class === core.class.TxCollectionCUD
|
||||
? (tx as TxCollectionCUD<Doc, AttachedDoc>).tx.objectClass
|
||||
: (tx as TxCUD<Doc>).objectClass
|
||||
}
|
||||
|
||||
function txClass (tx: Tx): Ref<Class<Tx>> {
|
||||
return tx._class === core.class.TxCollectionCUD ? (tx as TxCollectionCUD<Doc, AttachedDoc>).tx._class : tx._class
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user