Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
143 lines
5.6 KiB
TypeScript
143 lines
5.6 KiB
TypeScript
/**
|
|
* Copyright 2023-present DreamNum Co., Ltd.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import type { ICommandInfo } from '@univerjs/core';
|
|
import type {
|
|
ISetFormulaCalculationNotificationMutation,
|
|
ISetFormulaCalculationResultMutation,
|
|
} from '../commands/mutations/set-formula-calculation.mutation';
|
|
import { Disposable, ICommandService, Inject, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
|
import {
|
|
SetFormulaCalculationNotificationMutation,
|
|
SetFormulaCalculationResultMutation,
|
|
SetFormulaCalculationStartMutation,
|
|
} from '../commands/mutations/set-formula-calculation.mutation';
|
|
import {
|
|
FormulaCalculationSessionService,
|
|
FormulaResultApplicationType,
|
|
} from '../services/formula/formula-calculation-session.service';
|
|
import { RegisterOtherFormulaService } from '../services/register-other-formula.service';
|
|
|
|
function isFormulaCalculationNotification(
|
|
params: object | undefined
|
|
): params is ISetFormulaCalculationNotificationMutation {
|
|
return params != null;
|
|
}
|
|
|
|
function isFormulaCalculationResult(
|
|
params: object | undefined
|
|
): params is ISetFormulaCalculationResultMutation {
|
|
return params != null && 'unitData' in params && 'unitOtherData' in params;
|
|
}
|
|
|
|
export class FormulaCalculationSessionController extends Disposable {
|
|
constructor(
|
|
@ICommandService private readonly _commandService: ICommandService,
|
|
@IUniverInstanceService private readonly _univerInstanceService: IUniverInstanceService,
|
|
@Inject(FormulaCalculationSessionService) private readonly _sessionService: FormulaCalculationSessionService,
|
|
@Inject(RegisterOtherFormulaService) private readonly _registerOtherFormulaService: RegisterOtherFormulaService
|
|
) {
|
|
super();
|
|
|
|
this._sessionService.initialize();
|
|
this._initialize();
|
|
}
|
|
|
|
private _initialize(): void {
|
|
this.disposeWithMe(this._registerOtherFormulaService.otherFormulaResultApplied$.subscribe((result) => {
|
|
this._sessionService.markResultApplied(FormulaResultApplicationType.OTHER_FORMULA, result);
|
|
}));
|
|
|
|
this.disposeWithMe(
|
|
this._commandService.onCommandExecuted((command: ICommandInfo) => {
|
|
if (command.id === SetFormulaCalculationStartMutation.id) {
|
|
this._sessionService.start();
|
|
return;
|
|
}
|
|
|
|
if (command.id === SetFormulaCalculationNotificationMutation.id) {
|
|
if (isFormulaCalculationNotification(command.params)) {
|
|
this._handleNotification(command.params);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (command.id === SetFormulaCalculationResultMutation.id) {
|
|
if (isFormulaCalculationResult(command.params)) {
|
|
this._handleResult(command.params);
|
|
}
|
|
}
|
|
})
|
|
);
|
|
}
|
|
|
|
private _handleNotification(params: ISetFormulaCalculationNotificationMutation): void {
|
|
if (params.stageInfo != null) {
|
|
this._sessionService.updateProgress(params.stageInfo);
|
|
}
|
|
|
|
if (params.functionsExecutedState !== undefined) {
|
|
this._sessionService.markCompleted(params.functionsExecutedState);
|
|
}
|
|
}
|
|
|
|
private _handleResult(params: ISetFormulaCalculationResultMutation): void {
|
|
const pendingApplications: FormulaResultApplicationType[] = [];
|
|
|
|
if (this._hasSheetResultToApply(params)) {
|
|
pendingApplications.push(FormulaResultApplicationType.SHEET);
|
|
}
|
|
|
|
if (this._hasBaseResultToApply(params)) {
|
|
pendingApplications.push(FormulaResultApplicationType.BASE);
|
|
}
|
|
|
|
if (this._hasOtherFormulaResultToApply(params)) {
|
|
pendingApplications.push(FormulaResultApplicationType.OTHER_FORMULA);
|
|
}
|
|
|
|
this._sessionService.markResultEmitted(params, pendingApplications);
|
|
}
|
|
|
|
private _hasSheetResultToApply(result: ISetFormulaCalculationResultMutation): boolean {
|
|
return this._hasUnitResultToApply(result, UniverInstanceType.UNIVER_SHEET);
|
|
}
|
|
|
|
private _hasBaseResultToApply(result: ISetFormulaCalculationResultMutation): boolean {
|
|
return this._hasUnitResultToApply(result, UniverInstanceType.UNIVER_BASE);
|
|
}
|
|
|
|
private _hasUnitResultToApply(
|
|
result: ISetFormulaCalculationResultMutation,
|
|
unitType: UniverInstanceType
|
|
): boolean {
|
|
// Only registered host units have a matching result applicator. Unknown units must not keep the session pending.
|
|
return Object.entries(result.unitData).some(([unitId, sheetData]) =>
|
|
this._univerInstanceService.getUnit(unitId, unitType) != null
|
|
&& sheetData != null
|
|
&& Object.values(sheetData).some((cellData) => cellData != null)
|
|
);
|
|
}
|
|
|
|
private _hasOtherFormulaResultToApply(result: ISetFormulaCalculationResultMutation): boolean {
|
|
return Object.values(result.unitOtherData).some((subUnitData) =>
|
|
subUnitData != null && Object.values(subUnitData).some((formulaData) =>
|
|
formulaData != null && Object.keys(formulaData).length > 0
|
|
)
|
|
);
|
|
}
|
|
}
|