mirror of
https://github.com/dream-num/univer.git
synced 2026-09-24 15:32:18 +08:00
feat(sheets-data-validation): daily bugfix for data-validation (#2637)
* fix: #1267 * fix: checkbox formula #1363 * fix: checkbox * fix: data-validation checkbox * feat: update * feat: update * feat: update remove-sheet * feat: lint * feat: update * feat: update * fix: #1391 * fix: univer-pro #1407 * feat: update sidebar * fix: code-review issues * feat: update
This commit is contained in:
@@ -276,27 +276,31 @@ export class CommandService implements ICommandService {
|
||||
params?: P,
|
||||
options?: IExecutionOptions
|
||||
): Promise<R> {
|
||||
const item = this._commandRegistry.getCommand(id);
|
||||
if (item) {
|
||||
const [command] = item;
|
||||
const commandInfo: ICommandInfo = {
|
||||
id: command.id,
|
||||
type: command.type,
|
||||
params,
|
||||
};
|
||||
try {
|
||||
const item = this._commandRegistry.getCommand(id);
|
||||
if (item) {
|
||||
const [command] = item;
|
||||
const commandInfo: ICommandInfo = {
|
||||
id: command.id,
|
||||
type: command.type,
|
||||
params,
|
||||
};
|
||||
|
||||
const stackItemDisposable = this._pushCommandExecutionStack(commandInfo);
|
||||
const stackItemDisposable = this._pushCommandExecutionStack(commandInfo);
|
||||
|
||||
this._beforeCommandExecutionListeners.forEach((listener) => listener(commandInfo, options));
|
||||
const result = await this._execute<P, R>(command as ICommand<P, R>, params, options);
|
||||
this._commandExecutedListeners.forEach((listener) => listener(commandInfo, options));
|
||||
this._beforeCommandExecutionListeners.forEach((listener) => listener(commandInfo, options));
|
||||
const result = await this._execute<P, R>(command as ICommand<P, R>, params, options);
|
||||
this._commandExecutedListeners.forEach((listener) => listener(commandInfo, options));
|
||||
|
||||
stackItemDisposable.dispose();
|
||||
stackItemDisposable.dispose();
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
throw new Error(`[CommandService]: command "${id}" is not registered.`);
|
||||
} catch (error) {
|
||||
this._logService.error(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw new Error(`[CommandService]: command "${id}" is not registered.`);
|
||||
}
|
||||
|
||||
syncExecuteCommand<P extends object = object, R = boolean>(
|
||||
|
||||
@@ -400,7 +400,9 @@ export class ObjectMatrix<T> {
|
||||
insertColumns(start: number, count: number): void {
|
||||
for (let c = start; c < start + count; c++) {
|
||||
this.forEach((row, data) => {
|
||||
insertMatrixArray(c, undefined, data);
|
||||
if (data) {
|
||||
insertMatrixArray(c, undefined, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -411,7 +413,9 @@ export class ObjectMatrix<T> {
|
||||
|
||||
removeColumns(start: number, count: number): void {
|
||||
this.forEach((row, value) => {
|
||||
spliceArray(start, count, value);
|
||||
if (value) {
|
||||
spliceArray(start, count, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export interface ICellRenderContext {
|
||||
data: ICellDataForSheetInterceptor;
|
||||
style: Nullable<IStyleData>;
|
||||
primaryWithCoord: ISelectionCellWithCoord;
|
||||
unitId?: string;
|
||||
unitId: string;
|
||||
subUnitId: string;
|
||||
row: number;
|
||||
col: number;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommandType, ICommandService, IUndoRedoService } from '@univerjs/core';
|
||||
import { CommandType, ICommandService, ILogService, IUndoRedoService } from '@univerjs/core';
|
||||
import type { ICommand, IDataValidationRule, IDataValidationRuleBase, IDataValidationRuleOptions, IMutationInfo, IRange, ISheetDataValidationRule } from '@univerjs/core';
|
||||
import type { Injector } from '@wendellhu/redi';
|
||||
import type { ISheetCommandSharedParams } from '@univerjs/sheets';
|
||||
@@ -32,10 +32,15 @@ export interface IAddDataValidationCommandParams extends ISheetCommandSharedPara
|
||||
index?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export const AddDataValidationCommand: ICommand<IAddDataValidationCommandParams> = {
|
||||
type: CommandType.COMMAND,
|
||||
id: 'data-validation.command.addRule',
|
||||
async handler(accessor, params) {
|
||||
const logService = accessor.get(ILogService);
|
||||
logService.warn('[Deprecated] AddDataValidationCommand is deprecated, please use AddSheetDataValidationCommand in @univerjs/sheets-data-validation instead!');
|
||||
if (!params) {
|
||||
return false;
|
||||
}
|
||||
@@ -151,10 +156,15 @@ export interface IUpdateDataValidationOptionsCommandParams extends ISheetCommand
|
||||
options: IDataValidationRuleOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export const UpdateDataValidationOptionsCommand: ICommand<IUpdateDataValidationOptionsCommandParams> = {
|
||||
type: CommandType.COMMAND,
|
||||
id: 'data-validation.command.updateDataValidationSetting',
|
||||
handler(accessor, params) {
|
||||
const logService = accessor.get(ILogService);
|
||||
logService.warn('[Deprecated] UpdateDataValidationOptionsCommand is deprecated, please use UpdateSheetDataValidationOptionsCommand in @univerjs/sheets-data-validation instead!');
|
||||
if (!params) {
|
||||
return false;
|
||||
}
|
||||
@@ -213,10 +223,15 @@ export interface IUpdateDataValidationSettingCommandParams extends ISheetCommand
|
||||
setting: IDataValidationRuleBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export const UpdateDataValidationSettingCommand: ICommand<IUpdateDataValidationSettingCommandParams> = {
|
||||
type: CommandType.COMMAND,
|
||||
id: 'data-validation.command.updateDataValidationOptions',
|
||||
handler(accessor, params) {
|
||||
const logService = accessor.get(ILogService);
|
||||
logService.warn('[Deprecated] UpdateDataValidationSettingCommand is deprecated, please use UpdateSheetDataValidationSettingCommand in @univerjs/sheets-data-validation instead!');
|
||||
if (!params) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,6 @@ export { DataValidationModel } from './models/data-validation-model';
|
||||
export type {
|
||||
IRemoveDataValidationCommandParams,
|
||||
IAddDataValidationCommandParams,
|
||||
IUpdateDataValidationOptionsCommandParams,
|
||||
IUpdateDataValidationSettingCommandParams,
|
||||
IRemoveAllDataValidationCommandParams,
|
||||
} from './commands/commands/data-validation.command';
|
||||
|
||||
@@ -30,7 +28,6 @@ export {
|
||||
AddDataValidationMutation,
|
||||
RemoveDataValidationMutation,
|
||||
UpdateDataValidationMutation,
|
||||
|
||||
} from './commands/mutations/data-validation.mutation';
|
||||
|
||||
export type {
|
||||
|
||||
@@ -86,6 +86,7 @@ export class Custom extends SheetExtension {
|
||||
row,
|
||||
col,
|
||||
worksheet,
|
||||
unitId: worksheet.unitId,
|
||||
};
|
||||
|
||||
// current cell is hidden
|
||||
|
||||
@@ -14,14 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommandType, ICommandService, IUndoRedoService, IUniverInstanceService, sequenceExecuteAsync } from '@univerjs/core';
|
||||
import type { ICommand, IMutationInfo, IRange, ISheetDataValidationRule } from '@univerjs/core';
|
||||
import { CommandType, DataValidationType, ICommandService, IUndoRedoService, IUniverInstanceService, ObjectMatrix, Range, sequenceExecute, sequenceExecuteAsync, Tools } from '@univerjs/core';
|
||||
import type { CellValue, ICellData, ICommand, IDataValidationRuleBase, IDataValidationRuleOptions, IMutationInfo, IRange, ISheetDataValidationRule, Nullable } from '@univerjs/core';
|
||||
import type { IAddDataValidationMutationParams, IUpdateDataValidationMutationParams } from '@univerjs/data-validation';
|
||||
import { AddDataValidationMutation, createDefaultNewRule, DataValidationModel, RemoveDataValidationMutation, UpdateDataValidationMutation, UpdateRuleType } from '@univerjs/data-validation';
|
||||
import { getSheetCommandTarget } from '@univerjs/sheets';
|
||||
import { AddDataValidationMutation, createDefaultNewRule, DataValidationModel, DataValidatorRegistryService, getRuleOptions, getRuleSetting, RemoveDataValidationMutation, UpdateDataValidationMutation, UpdateRuleType } from '@univerjs/data-validation';
|
||||
import type { ISetRangeValuesMutationParams, ISheetCommandSharedParams } from '@univerjs/sheets';
|
||||
import { getSheetCommandTarget, SetRangeValuesMutation, SetRangeValuesUndoMutationFactory } from '@univerjs/sheets';
|
||||
import type { IAccessor } from '@wendellhu/redi';
|
||||
import type { SheetDataValidationManager } from '../../models/sheet-data-validation-manager';
|
||||
import { OpenValidationPanelOperation } from '../operations/data-validation.operation';
|
||||
import type { RangeMutation } from '../../models/rule-matrix';
|
||||
import { CHECKBOX_FORMULA_1, CHECKBOX_FORMULA_2, type CheckboxValidator } from '../../validators';
|
||||
import { getStringCellValue } from '../../utils/get-cell-data-origin';
|
||||
|
||||
export interface IUpdateSheetDataValidationRangeCommandParams {
|
||||
unitId: string;
|
||||
@@ -30,12 +34,57 @@ export interface IUpdateSheetDataValidationRangeCommandParams {
|
||||
ranges: IRange[];
|
||||
}
|
||||
|
||||
function isBlankCell(cellData: Nullable<ICellData>) {
|
||||
if (!cellData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!cellData.p) {
|
||||
return Tools.isBlank(cellData.v);
|
||||
}
|
||||
|
||||
const dataStream = (cellData.p.body?.dataStream ?? '').slice(0, -2).trim();
|
||||
return !dataStream;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line max-lines-per-function
|
||||
export function getDataValidationDiffMutations(unitId: string, subUnitId: string, diffs: RangeMutation[]) {
|
||||
export function getDataValidationDiffMutations(
|
||||
unitId: string,
|
||||
subUnitId: string,
|
||||
diffs: RangeMutation[],
|
||||
accessor: IAccessor
|
||||
) {
|
||||
const redoMutations: IMutationInfo[] = [];
|
||||
|
||||
const undoMutations: IMutationInfo[] = [];
|
||||
const model = accessor.get(DataValidationModel);
|
||||
const manager = model.ensureManager(unitId, subUnitId) as SheetDataValidationManager;
|
||||
const univerInstanceService = accessor.get(IUniverInstanceService);
|
||||
const target = getSheetCommandTarget(univerInstanceService, { unitId, subUnitId });
|
||||
if (!target) {
|
||||
return {
|
||||
redoMutations,
|
||||
undoMutations,
|
||||
};
|
||||
}
|
||||
const { worksheet } = target;
|
||||
const redoMatrix = new ObjectMatrix<ICellData>();
|
||||
|
||||
function setRangesDefaultValue(ranges: IRange[], defaultValue: CellValue) {
|
||||
ranges.forEach((range) => {
|
||||
Range.foreach(range, (row, column) => {
|
||||
const cellData = worksheet.getCellRaw(row, column);
|
||||
const value = getStringCellValue(cellData);
|
||||
if (isBlankCell(cellData) || value === defaultValue) {
|
||||
redoMatrix.setValue(row, column, {
|
||||
v: defaultValue,
|
||||
p: null,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line max-lines-per-function
|
||||
diffs.forEach((diff) => {
|
||||
switch (diff.type) {
|
||||
case 'delete':
|
||||
@@ -82,6 +131,12 @@ export function getDataValidationDiffMutations(unitId: string, subUnitId: string
|
||||
},
|
||||
} as IUpdateDataValidationMutationParams,
|
||||
});
|
||||
const rule = manager.getRuleById(diff.ruleId);
|
||||
if (rule && rule.type === DataValidationType.CHECKBOX) {
|
||||
const validator = manager.getValidator(DataValidationType.CHECKBOX) as CheckboxValidator;
|
||||
const formula = validator.parseFormulaSync(rule, unitId, subUnitId);
|
||||
setRangesDefaultValue(diff.newRanges, formula.formula2!);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'add': {
|
||||
@@ -101,6 +156,11 @@ export function getDataValidationDiffMutations(unitId: string, subUnitId: string
|
||||
ruleId: diff.rule.uid,
|
||||
},
|
||||
});
|
||||
if (diff.rule.type === DataValidationType.CHECKBOX) {
|
||||
const validator = manager.getValidator(DataValidationType.CHECKBOX) as CheckboxValidator;
|
||||
const formula = validator.parseFormulaSync(diff.rule, unitId, subUnitId);
|
||||
setRangesDefaultValue(diff.rule.ranges, formula.formula2!);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -108,6 +168,23 @@ export function getDataValidationDiffMutations(unitId: string, subUnitId: string
|
||||
}
|
||||
});
|
||||
|
||||
const redoSetRangeValues = {
|
||||
id: SetRangeValuesMutation.id,
|
||||
params: {
|
||||
unitId,
|
||||
subUnitId,
|
||||
cellValue: redoMatrix.getData(),
|
||||
} as ISetRangeValuesMutationParams,
|
||||
};
|
||||
|
||||
const undoSetRangeValues = {
|
||||
id: SetRangeValuesMutation.id,
|
||||
params: SetRangeValuesUndoMutationFactory(accessor, redoSetRangeValues.params),
|
||||
};
|
||||
|
||||
redoMutations.push(redoSetRangeValues);
|
||||
undoMutations.push(undoSetRangeValues);
|
||||
|
||||
return {
|
||||
redoMutations,
|
||||
undoMutations,
|
||||
@@ -117,7 +194,7 @@ export function getDataValidationDiffMutations(unitId: string, subUnitId: string
|
||||
export const UpdateSheetDataValidationRangeCommand: ICommand<IUpdateSheetDataValidationRangeCommandParams> = {
|
||||
type: CommandType.COMMAND,
|
||||
id: 'sheet.command.updateDataValidationRuleRange',
|
||||
async handler(accessor, params) {
|
||||
async handler(accessor, params) {
|
||||
if (!params) {
|
||||
return false;
|
||||
}
|
||||
@@ -135,7 +212,7 @@ export const UpdateSheetDataValidationRangeCommand: ICommand<IUpdateSheetDataVal
|
||||
matrix.updateRange(ruleId, oldRanges, ranges);
|
||||
const diffs = matrix.diff(manager.getDataValidations());
|
||||
|
||||
const { redoMutations, undoMutations } = getDataValidationDiffMutations(unitId, subUnitId, diffs);
|
||||
const { redoMutations, undoMutations } = getDataValidationDiffMutations(unitId, subUnitId, diffs, accessor);
|
||||
|
||||
undoRedoService.pushUndoRedo({
|
||||
undoMutations,
|
||||
@@ -176,7 +253,7 @@ export const AddSheetDataValidationCommand: ICommand<IAddSheetDataValidationComm
|
||||
rule,
|
||||
};
|
||||
|
||||
const { redoMutations, undoMutations } = getDataValidationDiffMutations(unitId, subUnitId, diffs);
|
||||
const { redoMutations, undoMutations } = getDataValidationDiffMutations(unitId, subUnitId, diffs, accessor);
|
||||
|
||||
redoMutations.push({
|
||||
id: AddDataValidationMutation.id,
|
||||
@@ -236,3 +313,185 @@ export const AddSheetDataValidationAndOpenCommand: ICommand = {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
export interface IUpdateSheetDataValidationSettingCommandParams extends ISheetCommandSharedParams {
|
||||
ruleId: string;
|
||||
setting: IDataValidationRuleBase;
|
||||
}
|
||||
|
||||
export const UpdateSheetDataValidationSettingCommand: ICommand<IUpdateSheetDataValidationSettingCommandParams> = {
|
||||
type: CommandType.COMMAND,
|
||||
id: 'sheets.command.update-data-validation-setting',
|
||||
// eslint-disable-next-line max-lines-per-function
|
||||
handler(accessor, params) {
|
||||
if (!params) {
|
||||
return false;
|
||||
}
|
||||
const commandService = accessor.get(ICommandService);
|
||||
const redoUndoService = accessor.get(IUndoRedoService);
|
||||
const dataValidationModel = accessor.get(DataValidationModel);
|
||||
const dataValidatorRegistryService = accessor.get(DataValidatorRegistryService);
|
||||
|
||||
const { unitId, subUnitId, ruleId, setting } = params;
|
||||
const validator = dataValidatorRegistryService.getValidatorItem(setting.type);
|
||||
|
||||
if (!validator) {
|
||||
return false;
|
||||
}
|
||||
const rule = dataValidationModel.getRuleById(unitId, subUnitId, ruleId);
|
||||
if (!rule) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!validator.validatorFormula({ ...rule, ...setting }, unitId, subUnitId).success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const mutationParams: IUpdateDataValidationMutationParams = {
|
||||
unitId,
|
||||
subUnitId,
|
||||
ruleId,
|
||||
payload: {
|
||||
type: UpdateRuleType.SETTING,
|
||||
payload: setting,
|
||||
},
|
||||
};
|
||||
|
||||
const redoMutations: IMutationInfo[] = [{
|
||||
id: UpdateDataValidationMutation.id,
|
||||
params: mutationParams,
|
||||
}];
|
||||
const undoMutationParams: IUpdateDataValidationMutationParams = {
|
||||
unitId,
|
||||
subUnitId,
|
||||
ruleId,
|
||||
payload: {
|
||||
type: UpdateRuleType.SETTING,
|
||||
payload: getRuleSetting(rule),
|
||||
},
|
||||
};
|
||||
const undoMutations: IMutationInfo[] = [{
|
||||
id: UpdateDataValidationMutation.id,
|
||||
params: undoMutationParams,
|
||||
}];
|
||||
|
||||
if (setting.type === DataValidationType.CHECKBOX) {
|
||||
const ranges = rule.ranges as IRange[];
|
||||
const univerInstanceService = accessor.get(IUniverInstanceService);
|
||||
const target = getSheetCommandTarget(univerInstanceService, { unitId, subUnitId });
|
||||
if (target) {
|
||||
const redoMatrix = new ObjectMatrix<ICellData>();
|
||||
const { worksheet } = target;
|
||||
const { formula2: oldFormula2 = CHECKBOX_FORMULA_2, formula1: oldFormula1 = CHECKBOX_FORMULA_1 } = rule;
|
||||
const { formula2 = CHECKBOX_FORMULA_2, formula1 = CHECKBOX_FORMULA_1 } = setting;
|
||||
ranges.forEach((range) => {
|
||||
Range.foreach(range, (row, column) => {
|
||||
const cellData = worksheet.getCellRaw(row, column);
|
||||
const value = getStringCellValue(cellData);
|
||||
if (isBlankCell(cellData) || value === String(oldFormula2)) {
|
||||
redoMatrix.setValue(row, column, {
|
||||
v: formula2,
|
||||
p: null,
|
||||
});
|
||||
} else if (value === String(oldFormula1)) {
|
||||
redoMatrix.setValue(row, column, {
|
||||
v: formula1,
|
||||
p: null,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const redoSetRangeValues = {
|
||||
id: SetRangeValuesMutation.id,
|
||||
params: {
|
||||
unitId,
|
||||
subUnitId,
|
||||
cellValue: redoMatrix.getData(),
|
||||
} as ISetRangeValuesMutationParams,
|
||||
};
|
||||
|
||||
const undoSetRangeValues = {
|
||||
id: SetRangeValuesMutation.id,
|
||||
params: SetRangeValuesUndoMutationFactory(accessor, redoSetRangeValues.params),
|
||||
};
|
||||
redoMutations.push(redoSetRangeValues);
|
||||
undoMutations.push(undoSetRangeValues);
|
||||
}
|
||||
}
|
||||
const res = sequenceExecute(redoMutations, commandService);
|
||||
if (res.result) {
|
||||
redoUndoService.pushUndoRedo({
|
||||
unitID: unitId,
|
||||
redoMutations,
|
||||
undoMutations,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
export interface IUpdateSheetDataValidationOptionsCommandParams extends ISheetCommandSharedParams {
|
||||
ruleId: string;
|
||||
options: IDataValidationRuleOptions;
|
||||
}
|
||||
|
||||
export const UpdateSheetDataValidationOptionsCommand: ICommand<IUpdateSheetDataValidationOptionsCommandParams> = {
|
||||
type: CommandType.COMMAND,
|
||||
id: 'sheets.command.update-data-validation-options',
|
||||
handler(accessor, params) {
|
||||
if (!params) {
|
||||
return false;
|
||||
}
|
||||
const commandService = accessor.get(ICommandService);
|
||||
const redoUndoService = accessor.get(IUndoRedoService);
|
||||
const dataValidationModel = accessor.get(DataValidationModel);
|
||||
|
||||
const { unitId, subUnitId, ruleId, options } = params;
|
||||
|
||||
const rule = dataValidationModel.getRuleById(unitId, subUnitId, ruleId);
|
||||
if (!rule) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const mutationParams: IUpdateDataValidationMutationParams = {
|
||||
unitId,
|
||||
subUnitId,
|
||||
ruleId,
|
||||
payload: {
|
||||
type: UpdateRuleType.OPTIONS,
|
||||
payload: options,
|
||||
},
|
||||
};
|
||||
|
||||
const redoMutations: IMutationInfo[] = [{
|
||||
id: UpdateDataValidationMutation.id,
|
||||
params: mutationParams,
|
||||
}];
|
||||
const undoMutationParams: IUpdateDataValidationMutationParams = {
|
||||
unitId,
|
||||
subUnitId,
|
||||
ruleId,
|
||||
payload: {
|
||||
type: UpdateRuleType.OPTIONS,
|
||||
payload: getRuleOptions(rule),
|
||||
},
|
||||
};
|
||||
const undoMutations: IMutationInfo[] = [{
|
||||
id: UpdateDataValidationMutation.id,
|
||||
params: undoMutationParams,
|
||||
}];
|
||||
|
||||
redoUndoService.pushUndoRedo({
|
||||
unitID: unitId,
|
||||
redoMutations,
|
||||
undoMutations,
|
||||
});
|
||||
|
||||
commandService.executeCommand(UpdateDataValidationMutation.id, mutationParams);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import { DataValidationType, Disposable, LifecycleStages, OnLifecycle, Range, Rectangle } from '@univerjs/core';
|
||||
import type { IAutoFillLocation, ISheetAutoFillHook } from '@univerjs/sheets-ui';
|
||||
import { APPLY_TYPE, getAutoFillRepeatRange, IAutoFillService, virtualizeDiscreteRanges } from '@univerjs/sheets-ui';
|
||||
import { Inject } from '@wendellhu/redi';
|
||||
import { Inject, Injector } from '@wendellhu/redi';
|
||||
import { DataValidationModel } from '@univerjs/data-validation';
|
||||
import { DATA_VALIDATION_PLUGIN_NAME } from '../common/const';
|
||||
import type { SheetDataValidationManager } from '../models/sheet-data-validation-manager';
|
||||
@@ -27,7 +27,8 @@ import { getDataValidationDiffMutations } from '../commands/commands/data-valida
|
||||
export class DataValidationAutoFillController extends Disposable {
|
||||
constructor(
|
||||
@IAutoFillService private readonly _autoFillService: IAutoFillService,
|
||||
@Inject(DataValidationModel) private readonly _dataValidationModel: DataValidationModel
|
||||
@Inject(DataValidationModel) private readonly _dataValidationModel: DataValidationModel,
|
||||
@Inject(Injector) private readonly _injector: Injector
|
||||
) {
|
||||
super();
|
||||
this._initAutoFill();
|
||||
@@ -95,7 +96,7 @@ export class DataValidationAutoFillController extends Disposable {
|
||||
});
|
||||
|
||||
const diffs = ruleMatrixCopy.diff(manager.getDataValidations());
|
||||
const { redoMutations, undoMutations } = getDataValidationDiffMutations(unitId, subUnitId, diffs);
|
||||
const { redoMutations, undoMutations } = getDataValidationDiffMutations(unitId, subUnitId, diffs, this._injector);
|
||||
return {
|
||||
undos: undoMutations,
|
||||
redos: redoMutations,
|
||||
|
||||
@@ -153,7 +153,8 @@ export class DataValidationCopyPasteController extends Disposable {
|
||||
const { redoMutations, undoMutations } = getDataValidationDiffMutations(
|
||||
copyInfo.unitId,
|
||||
copyInfo.subUnitId,
|
||||
ruleMatrix.diffWithAddition(manager.getDataValidations(), additionRules.values())
|
||||
ruleMatrix.diffWithAddition(manager.getDataValidations(), additionRules.values()),
|
||||
this._injector
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -187,7 +188,8 @@ export class DataValidationCopyPasteController extends Disposable {
|
||||
const { redoMutations, undoMutations } = getDataValidationDiffMutations(
|
||||
unitId,
|
||||
subUnitId,
|
||||
ruleMatrix.diff(manager.getDataValidations())
|
||||
ruleMatrix.diff(manager.getDataValidations()),
|
||||
this._injector
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -27,7 +27,7 @@ import { INTERCEPTOR_POINT, SheetInterceptorService } from '@univerjs/sheets';
|
||||
import { DataValidationPanel, DATE_DROPDOWN_KEY, DateDropdown, LIST_DROPDOWN_KEY, ListDropDown } from '../views';
|
||||
import { FORMULA_INPUTS } from '../views/formula-input';
|
||||
import { getCellValueOrigin } from '../utils/get-cell-data-origin';
|
||||
import type { CheckboxValidator, ListValidator } from '../validators';
|
||||
import type { ListValidator } from '../validators';
|
||||
import type { SheetDataValidationManager } from '../models/sheet-data-validation-manager';
|
||||
import { CellDropdown, DROP_DOWN_KEY } from '../views/drop-down';
|
||||
import { DataValidationDropdownManagerService } from '../services/dropdown-manager.service';
|
||||
@@ -256,18 +256,12 @@ export class SheetsDataValidationRenderController extends RxDisposable {
|
||||
}
|
||||
|
||||
if (rule.type === DataValidationType.CHECKBOX) {
|
||||
const { formula2 } = (validator as CheckboxValidator).parseFormulaSync(rule, pos.unitId, pos.subUnitId);
|
||||
if (!cellValue) {
|
||||
extra = {
|
||||
v: formula2,
|
||||
t: 1,
|
||||
p: null,
|
||||
interceptorStyle: {
|
||||
...cell?.interceptorStyle,
|
||||
tb: WrapStrategy.CLIP,
|
||||
},
|
||||
};
|
||||
}
|
||||
extra = {
|
||||
interceptorStyle: {
|
||||
...cell?.interceptorStyle,
|
||||
tb: WrapStrategy.CLIP,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (rule.type === DataValidationType.LIST && (rule.renderMode === DataValidationRenderMode.ARROW || rule.renderMode === DataValidationRenderMode.TEXT)) {
|
||||
@@ -454,18 +448,13 @@ export class SheetsDataValidationMobileRenderController extends RxDisposable {
|
||||
}
|
||||
|
||||
if (rule.type === DataValidationType.CHECKBOX) {
|
||||
const { formula2 } = (validator as CheckboxValidator).parseFormulaSync(rule, pos.unitId, pos.subUnitId);
|
||||
if (!cellValue) {
|
||||
extra = {
|
||||
v: formula2,
|
||||
t: 1,
|
||||
p: null,
|
||||
interceptorStyle: {
|
||||
...cell?.interceptorStyle,
|
||||
tb: WrapStrategy.CLIP,
|
||||
},
|
||||
};
|
||||
}
|
||||
extra = {
|
||||
|
||||
interceptorStyle: {
|
||||
...cell?.interceptorStyle,
|
||||
tb: WrapStrategy.CLIP,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (rule.type === DataValidationType.LIST && (rule.renderMode === DataValidationRenderMode.ARROW || rule.renderMode === DataValidationRenderMode.TEXT)) {
|
||||
|
||||
@@ -123,7 +123,7 @@ export class DataValidationController extends RxDisposable {
|
||||
|
||||
selections && ruleMatrix.removeRange(selections);
|
||||
const diffs = ruleMatrix.diff(manager.getDataValidations());
|
||||
const { redoMutations, undoMutations } = getDataValidationDiffMutations(unitId, subUnitId, diffs);
|
||||
const { redoMutations, undoMutations } = getDataValidationDiffMutations(unitId, subUnitId, diffs, this._injector);
|
||||
|
||||
return {
|
||||
undos: undoMutations,
|
||||
|
||||
@@ -20,6 +20,7 @@ const locale: typeof zhCN = {
|
||||
dataValidation: {
|
||||
title: 'Data validation',
|
||||
validFail: {
|
||||
value: 'Please input a value',
|
||||
common: 'Please input value or formula',
|
||||
number: 'Please input number or formula',
|
||||
formula: 'Please input formula',
|
||||
@@ -30,6 +31,7 @@ const locale: typeof zhCN = {
|
||||
checkboxEqual: 'Enter different values for ticked and unticked cell contents.',
|
||||
formulaError: 'The reference range contains invisible data, please readjust the range',
|
||||
listIntersects: 'The selected range cannot intersect with the scope of the rules',
|
||||
primitive: 'Formulas are not permitted for custom ticked and unticked values.',
|
||||
},
|
||||
panel: {
|
||||
title: 'Data validation management',
|
||||
@@ -43,6 +45,7 @@ const locale: typeof zhCN = {
|
||||
removeRule: 'Remove',
|
||||
done: 'Done',
|
||||
formulaPlaceholder: 'Please input value or formula',
|
||||
valuePlaceholder: 'Please input value',
|
||||
formulaAnd: 'and',
|
||||
invalid: 'Invalid',
|
||||
showWarning: 'Show warning',
|
||||
|
||||
@@ -20,6 +20,7 @@ const locale: typeof zhCN = {
|
||||
dataValidation: {
|
||||
title: 'Проверка данных',
|
||||
validFail: {
|
||||
value: 'Пожалуйста, введите значение',
|
||||
common: 'Пожалуйста, введите значение или формулу',
|
||||
number: 'Пожалуйста, введите число или формулу',
|
||||
formula: 'Пожалуйста, введите формулу',
|
||||
@@ -30,6 +31,7 @@ const locale: typeof zhCN = {
|
||||
checkboxEqual: 'Для выбранных и не выбранных ячеек введите разные значения',
|
||||
formulaError: 'Диапазон ссылок содержит невидимые данные, пожалуйста, пересмотрите диапазон',
|
||||
listIntersects: 'Выбранный диапазон не может пересекаться с диапазоном правила.',
|
||||
primitive: 'Formulas are not permitted for custom ticked and unticked values.',
|
||||
},
|
||||
panel: {
|
||||
title: 'Управление проверкой данных',
|
||||
@@ -43,6 +45,7 @@ const locale: typeof zhCN = {
|
||||
removeRule: 'Удалить',
|
||||
done: 'Готово',
|
||||
formulaPlaceholder: 'Пожалуйста, введите значение или формулу',
|
||||
valuePlaceholder: 'Пожалуйста, введите значение',
|
||||
formulaAnd: 'и',
|
||||
invalid: 'Недопустимо',
|
||||
showWarning: 'Показать предупреждение',
|
||||
|
||||
@@ -18,9 +18,10 @@ const locale = {
|
||||
dataValidation: {
|
||||
title: '数据验证',
|
||||
validFail: {
|
||||
value: '请输入一个合法值',
|
||||
common: '请输入值或公式',
|
||||
number: '请输入合法的数字或公式',
|
||||
formula: '请输入合法的公式或公式',
|
||||
formula: '请输入合法的公式',
|
||||
integer: '请输入合法的整数或公式',
|
||||
date: '请输入合法的日期或公式',
|
||||
list: '请输入至少一个合法选项',
|
||||
@@ -28,6 +29,7 @@ const locale = {
|
||||
checkboxEqual: '为勾选和未勾选的单元格内容输入不同的值。',
|
||||
formulaError: '引用范围内包含不可见的数据,请重新调整范围',
|
||||
listIntersects: '所选范围不能和规则范围相交',
|
||||
primitive: '自定义勾选和未勾选值不允许使用公式。',
|
||||
},
|
||||
panel: {
|
||||
title: '管理数据验证',
|
||||
@@ -41,6 +43,7 @@ const locale = {
|
||||
removeRule: '删除规则',
|
||||
done: '确认',
|
||||
formulaPlaceholder: '请输入值或公式',
|
||||
valuePlaceholder: '请输入值',
|
||||
formulaAnd: '与',
|
||||
invalid: '数据无效时',
|
||||
showWarning: '显示警告',
|
||||
|
||||
@@ -126,6 +126,10 @@ export class SheetDataValidationManager extends DataValidationManager<ISheetData
|
||||
super.removeRule(ruleId);
|
||||
}
|
||||
|
||||
getValidator(type: DataValidationType) {
|
||||
return this._dataValidatorRegistryService.getValidatorItem(type);
|
||||
}
|
||||
|
||||
getRuleIdByLocation(row: number, col: number): string | undefined {
|
||||
return this._ruleMatrix.getValue(row, col);
|
||||
}
|
||||
@@ -142,7 +146,7 @@ export class SheetDataValidationManager extends DataValidationManager<ISheetData
|
||||
override validator(cellValue: Nullable<CellValue>, rule: ISheetDataValidationRule, pos: ISheetLocationBase, onCompete: (status: DataValidationStatus, changed: boolean) => void): DataValidationStatus {
|
||||
const { col, row, unitId, subUnitId } = pos;
|
||||
const ruleId = rule.uid;
|
||||
const validator = this._dataValidatorRegistryService.getValidatorItem(rule.type);
|
||||
const validator = this.getValidator(rule.type);
|
||||
if (validator) {
|
||||
const current = this._cache.getValue(row, col);
|
||||
if (!current || current.value !== cellValue) {
|
||||
|
||||
@@ -24,7 +24,7 @@ import { DefaultSheetsDataValidation, SheetsDataValidationRenderController } fro
|
||||
import { DataValidationController } from './controllers/dv.controller';
|
||||
import { SheetDataValidationService } from './services/dv.service';
|
||||
import { DataValidationAlertController } from './controllers/dv-alert.controller';
|
||||
import { AddSheetDataValidationAndOpenCommand, AddSheetDataValidationCommand, UpdateSheetDataValidationRangeCommand } from './commands/commands/data-validation.command';
|
||||
import { AddSheetDataValidationAndOpenCommand, AddSheetDataValidationCommand, UpdateSheetDataValidationOptionsCommand, UpdateSheetDataValidationRangeCommand, UpdateSheetDataValidationSettingCommand } from './commands/commands/data-validation.command';
|
||||
import { DataValidationCacheService } from './services/dv-cache.service';
|
||||
import { DataValidationFormulaService } from './services/dv-formula.service';
|
||||
import { DataValidationCustomFormulaService } from './services/dv-custom-formula.service';
|
||||
@@ -91,6 +91,8 @@ export class UniverSheetsDataValidationPlugin extends Plugin {
|
||||
AddSheetDataValidationCommand,
|
||||
AddSheetDataValidationAndOpenCommand,
|
||||
UpdateSheetDataValidationRangeCommand,
|
||||
UpdateSheetDataValidationSettingCommand,
|
||||
UpdateSheetDataValidationOptionsCommand,
|
||||
|
||||
// operation
|
||||
ShowDataValidationDropdown,
|
||||
|
||||
@@ -37,3 +37,7 @@ export function getCellValueOrigin(cell: Nullable<ICellData>) {
|
||||
|
||||
return cell?.v;
|
||||
}
|
||||
|
||||
export function getStringCellValue(cell: Nullable<ICellData>) {
|
||||
return String(getCellValueOrigin(cell) ?? '');
|
||||
}
|
||||
|
||||
@@ -15,10 +15,9 @@
|
||||
*/
|
||||
|
||||
import { DataValidationType, isFormulaString, Tools } from '@univerjs/core';
|
||||
import type { CellValue, DataValidationOperator, IDataValidationRule, IDataValidationRuleBase, ISheetDataValidationRule, Nullable } from '@univerjs/core';
|
||||
import type { CellValue, DataValidationOperator, IDataValidationRule, IDataValidationRuleBase, ISheetDataValidationRule, LocaleService, Nullable } from '@univerjs/core';
|
||||
import { BaseDataValidator } from '@univerjs/data-validation';
|
||||
import type { IFormulaResult, IFormulaValidResult, IValidatorCellInfo } from '@univerjs/data-validation';
|
||||
import type { ISheetLocation } from '@univerjs/sheets';
|
||||
import { CheckboxRender } from '../widgets/checkbox-widget';
|
||||
import { DataValidationFormulaService } from '../services/dv-formula.service';
|
||||
import { getFormulaResult } from '../utils/formula';
|
||||
@@ -27,6 +26,18 @@ import { CHECKBOX_FORMULA_INPUT_NAME } from '../views/formula-input';
|
||||
export const CHECKBOX_FORMULA_1 = 1;
|
||||
export const CHECKBOX_FORMULA_2 = 0;
|
||||
|
||||
function getFailMessage(formula: string | undefined, localeService: LocaleService) {
|
||||
if (Tools.isBlank(formula)) {
|
||||
return localeService.t('dataValidation.validFail.value');
|
||||
}
|
||||
|
||||
if (isFormulaString(formula)) {
|
||||
return localeService.t('dataValidation.validFail.primitive');
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
export class CheckboxValidator extends BaseDataValidator {
|
||||
override id: string = DataValidationType.CHECKBOX;
|
||||
override title: string = 'dataValidation.checkbox.title';
|
||||
@@ -38,31 +49,40 @@ export class CheckboxValidator extends BaseDataValidator {
|
||||
|
||||
private _formulaService = this.injector.get(DataValidationFormulaService);
|
||||
|
||||
override skipDefaultFontRender(rule: ISheetDataValidationRule, cellValue: Nullable<CellValue>, pos: ISheetLocation) {
|
||||
override skipDefaultFontRender(rule: ISheetDataValidationRule, cellValue: Nullable<CellValue>, pos: { unitId: string; subUnitId: string }) {
|
||||
const { formula1, formula2 } = this.parseFormulaSync(rule, pos.unitId, pos.subUnitId);
|
||||
|
||||
const valueStr = `${cellValue ?? ''}`;
|
||||
return !valueStr || (valueStr === (`${formula1}`) || valueStr === `${formula2}`);
|
||||
|
||||
const res = !valueStr || (valueStr === (`${formula1}`) || valueStr === `${formula2}`);
|
||||
return res;
|
||||
}
|
||||
|
||||
override validatorFormula(rule: IDataValidationRule, unitId: string, subUnitId: string): IFormulaValidResult {
|
||||
const { formula1, formula2 } = rule;
|
||||
const formula1Success = !Tools.isBlank(formula1);
|
||||
const formula2Success = !Tools.isBlank(formula2);
|
||||
const isEqual = formula1 === formula2;
|
||||
|
||||
if (Tools.isBlank(formula1) && Tools.isBlank(formula2)) {
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
}
|
||||
|
||||
if (isEqual) {
|
||||
return {
|
||||
success: false,
|
||||
formula1: this.localeService.t('dataValidation.validFail.checkboxEqual'),
|
||||
formula2: this.localeService.t('dataValidation.validFail.checkboxEqual'),
|
||||
};
|
||||
}
|
||||
|
||||
const error1 = getFailMessage(formula1, this.localeService);
|
||||
const error2 = getFailMessage(formula2, this.localeService);
|
||||
|
||||
return {
|
||||
success: (formula1Success && formula2Success && !isEqual) || (!formula1Success && !formula2Success),
|
||||
formula1: !formula1Success ?
|
||||
this.localeService.t('dataValidation.validFail.common')
|
||||
: isEqual ?
|
||||
this.localeService.t('dataValidation.validFail.checkboxEqual')
|
||||
: '',
|
||||
formula2: !formula2Success ?
|
||||
this.localeService.t('dataValidation.validFail.common')
|
||||
: isEqual ?
|
||||
this.localeService.t('dataValidation.validFail.checkboxEqual')
|
||||
: '',
|
||||
success: (!error1 && !error2),
|
||||
formula1: error1,
|
||||
formula2: error2,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
|
||||
import type { DataValidationOperator, DataValidationType, IDataValidationRuleBase, IDataValidationRuleOptions, IExecutionOptions, ISheetDataValidationRule, IUnitRange } from '@univerjs/core';
|
||||
import { createInternalEditorID, debounce, ICommandService, isUnitRangesEqual, isValidRange, LocaleService, RedoCommand, shallowEqual, UndoCommand } from '@univerjs/core';
|
||||
import type { IUpdateDataValidationSettingCommandParams } from '@univerjs/data-validation';
|
||||
import { DataValidationModel, DataValidatorRegistryScope, DataValidatorRegistryService, getRuleOptions, getRuleSetting, RemoveDataValidationCommand, TWO_FORMULA_OPERATOR_COUNT, UpdateDataValidationOptionsCommand, UpdateDataValidationSettingCommand } from '@univerjs/data-validation';
|
||||
import { DataValidationModel, DataValidatorRegistryScope, DataValidatorRegistryService, getRuleOptions, getRuleSetting, RemoveDataValidationCommand, TWO_FORMULA_OPERATOR_COUNT } from '@univerjs/data-validation';
|
||||
import { Button, FormLayout, Select } from '@univerjs/design';
|
||||
import { ComponentManager, RangeSelector, useEvent, useObservable } from '@univerjs/ui';
|
||||
import { useDependency } from '@wendellhu/redi/react-bindings';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { serializeRange } from '@univerjs/engine-formula';
|
||||
import type { IUpdateSheetDataValidationRangeCommandParams } from '../../commands/commands/data-validation.command';
|
||||
import { UpdateSheetDataValidationRangeCommand } from '../../commands/commands/data-validation.command';
|
||||
import { UpdateSheetDataValidationOptionsCommand, UpdateSheetDataValidationRangeCommand, UpdateSheetDataValidationSettingCommand } from '../../commands/commands/data-validation.command';
|
||||
import { DataValidationOptions } from '../options';
|
||||
import { DataValidationPanelService } from '../../services/data-validation-panel.service';
|
||||
import styles from './index.module.less';
|
||||
@@ -124,7 +123,7 @@ export function DataValidationDetail() {
|
||||
...localRule,
|
||||
...setting,
|
||||
});
|
||||
const params: IUpdateDataValidationSettingCommandParams = {
|
||||
const params = {
|
||||
unitId,
|
||||
subUnitId,
|
||||
ruleId,
|
||||
@@ -132,7 +131,7 @@ export function DataValidationDetail() {
|
||||
};
|
||||
|
||||
debounceExecute(
|
||||
UpdateDataValidationSettingCommand.id,
|
||||
UpdateSheetDataValidationSettingCommand.id,
|
||||
params,
|
||||
undefined
|
||||
);
|
||||
@@ -176,7 +175,7 @@ export function DataValidationDetail() {
|
||||
};
|
||||
setLocalRule(newRule);
|
||||
|
||||
commandService.executeCommand(UpdateDataValidationSettingCommand.id, {
|
||||
commandService.executeCommand(UpdateSheetDataValidationSettingCommand.id, {
|
||||
unitId,
|
||||
subUnitId,
|
||||
ruleId: localRule.uid,
|
||||
@@ -199,7 +198,7 @@ export function DataValidationDetail() {
|
||||
});
|
||||
|
||||
debounceExecute(
|
||||
UpdateDataValidationOptionsCommand.id,
|
||||
UpdateSheetDataValidationOptionsCommand.id,
|
||||
{
|
||||
unitId,
|
||||
subUnitId,
|
||||
|
||||
@@ -55,7 +55,7 @@ export function CheckboxFormulaInput(props: IFormulaInputProps) {
|
||||
<FormLayout label={localeService.t('dataValidation.checkbox.checked')} error={formula1Res}>
|
||||
<Input
|
||||
className={styles.dataValidationFormula}
|
||||
placeholder={localeService.t('dataValidation.panel.formulaPlaceholder')}
|
||||
placeholder={localeService.t('dataValidation.panel.valuePlaceholder')}
|
||||
value={value?.formula1}
|
||||
onChange={(newValue) => {
|
||||
onChange?.({
|
||||
@@ -72,7 +72,7 @@ export function CheckboxFormulaInput(props: IFormulaInputProps) {
|
||||
<FormLayout label={localeService.t('dataValidation.checkbox.unchecked')} error={formula2Res}>
|
||||
<Input
|
||||
className={styles.dataValidationFormula}
|
||||
placeholder={localeService.t('dataValidation.panel.formulaPlaceholder')}
|
||||
placeholder={localeService.t('dataValidation.panel.valuePlaceholder')}
|
||||
value={value?.formula2}
|
||||
onChange={(newValue) => {
|
||||
onChange?.({
|
||||
|
||||
@@ -28,7 +28,6 @@ import { DataValidationItem } from '../item';
|
||||
import type { IAddSheetDataValidationCommandParams } from '../../commands/commands/data-validation.command';
|
||||
import { AddSheetDataValidationCommand } from '../../commands/commands/data-validation.command';
|
||||
import { DataValidationPanelService } from '../../services/data-validation-panel.service';
|
||||
import { DataValidationController } from '../../controllers/dv.controller';
|
||||
import styles from './index.module.less';
|
||||
|
||||
export function DataValidationList() {
|
||||
@@ -50,8 +49,6 @@ function DataValidationListWithWorkbook(props: { workbook: Workbook }) {
|
||||
const commandService = useDependency(ICommandService);
|
||||
const injector = useDependency(Injector);
|
||||
const dataValidationPanelService = useDependency(DataValidationPanelService);
|
||||
const dataValidationController = useDependency(DataValidationController);
|
||||
|
||||
const localeService = useDependency(LocaleService);
|
||||
const [rules, setRules] = useState<ISheetDataValidationRule[]>([]);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import type { ISetRangeValuesCommandParams } from '@univerjs/sheets';
|
||||
import { SetRangeValuesCommand } from '@univerjs/sheets';
|
||||
import type { BaseDataValidator, IBaseDataValidationWidget, IFormulaResult } from '@univerjs/data-validation';
|
||||
import { Inject } from '@wendellhu/redi';
|
||||
import type { CheckboxValidator } from '../validators/checkbox-validator';
|
||||
import { CHECKBOX_FORMULA_1, CHECKBOX_FORMULA_2 } from '../validators/checkbox-validator';
|
||||
import { DataValidationFormulaService } from '../services/dv-formula.service';
|
||||
import { getFormulaResult } from '../utils/formula';
|
||||
@@ -97,18 +98,18 @@ export class CheckboxRender implements IBaseDataValidationWidget {
|
||||
const cellBounding = primaryWithCoord.isMergedMainCell ? primaryWithCoord.mergeInfo : primaryWithCoord;
|
||||
const value = getCellValueOrigin(data);
|
||||
const rule = data.dataValidation?.rule;
|
||||
const validator = data.dataValidation?.validator as BaseDataValidator;
|
||||
const validator = data.dataValidation?.validator as CheckboxValidator;
|
||||
if (!rule || !validator) {
|
||||
return;
|
||||
}
|
||||
|
||||
const colors = this._themeService.getCurrentTheme();
|
||||
if (!validator.skipDefaultFontRender(rule, value, { unitId, subUnitId })) {
|
||||
if (!validator.skipDefaultFontRender(rule, value, { unitId: unitId!, subUnitId })) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { formula1 = CHECKBOX_FORMULA_1 } = rule;
|
||||
|
||||
const result = validator.parseFormulaSync(rule, unitId, subUnitId);
|
||||
const { formula1 } = result;
|
||||
const layout = this._calc(cellBounding, style);
|
||||
const { a: scaleX, d: scaleY } = ctx.getTransform();
|
||||
const left = fixLineWidthByScale(layout.left, scaleX);
|
||||
|
||||
@@ -91,7 +91,7 @@ export function getClearContentMutationParamsForRanges(
|
||||
|
||||
function getClearContentMutationParamForRange(worksheet: Worksheet, range: IRange): ObjectMatrix<Nullable<ICellData>> {
|
||||
const { startRow, startColumn, endColumn, endRow } = range;
|
||||
const cellMatrix = worksheet.getMatrixWithMergedCells(startRow, startColumn, endRow, endColumn);
|
||||
const cellMatrix = worksheet.getMatrixWithMergedCells(startRow, startColumn, endRow, endColumn, true);
|
||||
const redoMatrix = new ObjectMatrix<Nullable<ICellData>>();
|
||||
let leftTopCellValue: Nullable<ICellData> = null;
|
||||
cellMatrix.forValue((row, col, cellData) => {
|
||||
|
||||
@@ -56,6 +56,7 @@ export class CellCustomRenderController extends Disposable implements IRenderMod
|
||||
const currentRender = this._renderManagerService.getRenderById(unitId);
|
||||
if (currentRender && currentRender.mainComponent) {
|
||||
const spreadsheet = currentRender.mainComponent as Spreadsheet;
|
||||
// eslint-disable-next-line max-lines-per-function
|
||||
const getActiveRender = (evt: IPointerEvent | IMouseEvent) => {
|
||||
const { offsetX, offsetY } = evt;
|
||||
const scene = currentRender.scene;
|
||||
|
||||
@@ -14,10 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Nullable, Workbook, Worksheet } from '@univerjs/core';
|
||||
import { Disposable, type Nullable, type Workbook, type Worksheet } from '@univerjs/core';
|
||||
import type { IRenderContext, IRenderModule } from '@univerjs/engine-render';
|
||||
import { SpreadsheetSkeleton } from '@univerjs/engine-render';
|
||||
import type { IDisposable } from '@wendellhu/redi';
|
||||
import { Inject, Injector } from '@wendellhu/redi';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
@@ -43,7 +42,7 @@ export interface ISheetSkeletonManagerSearch {
|
||||
* The viewModel is also a temporary storage variable, which does not need to be persisted,
|
||||
* so it is managed uniformly through the service.
|
||||
*/
|
||||
export class SheetSkeletonManagerService implements IDisposable, IRenderModule {
|
||||
export class SheetSkeletonManagerService extends Disposable implements IRenderModule {
|
||||
private _currentSkeletonSearchParam: ISheetSkeletonManagerSearch = {
|
||||
sheetId: '',
|
||||
};
|
||||
@@ -64,12 +63,23 @@ export class SheetSkeletonManagerService implements IDisposable, IRenderModule {
|
||||
@Inject(Injector) private readonly _injector: Injector
|
||||
) {
|
||||
// empty
|
||||
super();
|
||||
|
||||
this.disposeWithMe(() => {
|
||||
this._currentSkeletonBefore$.complete();
|
||||
this._currentSkeleton$.complete();
|
||||
this._sheetSkeletonParam = [];
|
||||
});
|
||||
|
||||
this._initRemoveSheet();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._currentSkeletonBefore$.complete();
|
||||
this._currentSkeleton$.complete();
|
||||
this._sheetSkeletonParam = [];
|
||||
private _initRemoveSheet() {
|
||||
this.disposeWithMe(this._context.unit.sheetDisposed$.subscribe((sheet) => {
|
||||
this.disposeSkeleton({
|
||||
sheetId: sheet.getSheetId(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
getCurrentSkeleton(): SpreadsheetSkeleton {
|
||||
@@ -162,6 +172,15 @@ export class SheetSkeletonManagerService implements IDisposable, IRenderModule {
|
||||
return newSkeleton;
|
||||
}
|
||||
|
||||
disposeSkeleton(searchParm: ISheetSkeletonManagerSearch) {
|
||||
const index = this._sheetSkeletonParam.findIndex((param) => param.sheetId === searchParm.sheetId);
|
||||
if (index > -1) {
|
||||
const skeleton = this._sheetSkeletonParam[index];
|
||||
skeleton.skeleton.dispose();
|
||||
this._sheetSkeletonParam.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private _getSkeleton(searchParm: ISheetSkeletonManagerSearch): Nullable<ISheetSkeletonManagerParam> {
|
||||
const item = this._sheetSkeletonParam.find((param) => param.sheetId === searchParm.sheetId);
|
||||
if (item != null) {
|
||||
|
||||
@@ -150,6 +150,7 @@ export class UniverSheetsUIPlugin extends Plugin {
|
||||
[SheetPermissionInterceptorBaseController],
|
||||
[SheetPermissionInitController],
|
||||
[MoveRangeController],
|
||||
|
||||
] as Dependency[]
|
||||
).forEach((d) => injector.add(d));
|
||||
|
||||
@@ -218,6 +219,7 @@ export class UniverSheetsUIPlugin extends Plugin {
|
||||
SheetPermissionInterceptorCanvasRenderController,
|
||||
SheetPermissionInterceptorFormulaRenderController,
|
||||
SheetPermissionRenderController,
|
||||
|
||||
]).forEach((m) => {
|
||||
this.disposeWithMe(this._renderManagerService.registerRenderModule(UniverInstanceType.UNIVER_SHEET, m));
|
||||
});
|
||||
|
||||
@@ -104,7 +104,7 @@ function getClearContentMutationParamsForRanges(
|
||||
|
||||
function getClearContentMutationParamForRange(worksheet: Worksheet, range: IRange): ObjectMatrix<Nullable<ICellData>> {
|
||||
const { startRow, startColumn, endColumn, endRow } = range;
|
||||
const cellMatrix = worksheet.getMatrixWithMergedCells(startRow, startColumn, endRow, endColumn);
|
||||
const cellMatrix = worksheet.getMatrixWithMergedCells(startRow, startColumn, endRow, endColumn, true);
|
||||
const redoMatrix = new ObjectMatrix<Nullable<ICellData>>();
|
||||
cellMatrix.forValue((row, col, cellData) => {
|
||||
if (cellData && (row !== startRow || col !== startColumn)) {
|
||||
|
||||
@@ -68,7 +68,6 @@ class WatchRange extends Disposable {
|
||||
if (mutation.params.unitId !== this._unitId || mutation.params.subUnitId !== this._subUnitId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._range) {
|
||||
return;
|
||||
}
|
||||
@@ -122,7 +121,6 @@ export class RefRangeService extends Disposable {
|
||||
if (this._watchRanges.size === 0) {
|
||||
watchRangesListener = this._commandService.onCommandExecuted((command) => {
|
||||
if (command.type !== CommandType.MUTATION) return false;
|
||||
|
||||
for (const watchRange of this._watchRanges) {
|
||||
watchRange.onMutation(command as IMutationInfo<ISheetCommandSharedParams>);
|
||||
}
|
||||
|
||||
@@ -17,51 +17,49 @@
|
||||
import { CloseSingle } from '@univerjs/icons';
|
||||
import { useDependency } from '@wendellhu/redi/react-bindings';
|
||||
import clsx from 'clsx';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import { CustomLabel } from '../../../components/custom-label/CustomLabel';
|
||||
import { ISidebarService } from '../../../services/sidebar/sidebar.service';
|
||||
import { useObservable } from '../../../components/hooks/observable';
|
||||
import styles from './index.module.less';
|
||||
import type { ISidebarMethodOptions } from './interface';
|
||||
|
||||
export function Sidebar() {
|
||||
const sidebarService = useDependency(ISidebarService);
|
||||
const sidebarOptions = useObservable<ISidebarMethodOptions>(sidebarService.sidebarOptions$);
|
||||
|
||||
const [sidebarOptions, setSidebarOptions] = useState<ISidebarMethodOptions>({});
|
||||
const options = useMemo(() => {
|
||||
if (!sidebarOptions) {
|
||||
return null;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const subscribtion = sidebarService.sidebarOptions$.subscribe((options: ISidebarMethodOptions) => {
|
||||
setSidebarOptions(options);
|
||||
});
|
||||
|
||||
return () => {
|
||||
subscribtion.unsubscribe();
|
||||
const copy = { ...sidebarOptions } as Omit<ISidebarMethodOptions, 'children'> & {
|
||||
children?: React.ReactNode;
|
||||
header?: React.ReactNode;
|
||||
footer?: React.ReactNode;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const options = sidebarOptions as Omit<ISidebarMethodOptions, 'children'> & {
|
||||
children?: React.ReactNode;
|
||||
header?: React.ReactNode;
|
||||
footer?: React.ReactNode;
|
||||
};
|
||||
for (const key of ['children', 'header', 'footer']) {
|
||||
const k = key as keyof ISidebarMethodOptions;
|
||||
for (const key of ['children', 'header', 'footer']) {
|
||||
const k = key as keyof ISidebarMethodOptions;
|
||||
|
||||
if (sidebarOptions[k]) {
|
||||
const props = sidebarOptions[k] as any;
|
||||
if (sidebarOptions[k]) {
|
||||
const props = sidebarOptions[k] as any;
|
||||
|
||||
if (props) {
|
||||
(options as any)[k] = <CustomLabel {...props} />;
|
||||
if (props) {
|
||||
(copy as any)[k] = <CustomLabel {...props} />;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return copy;
|
||||
}, [sidebarOptions]);
|
||||
|
||||
const _className = clsx(styles.sidebar, {
|
||||
[styles.sidebarOpen]: options.visible,
|
||||
[styles.sidebarOpen]: options?.visible,
|
||||
});
|
||||
|
||||
const width = useMemo(() => {
|
||||
if (!options.visible) return 0;
|
||||
if (!options?.visible) return 0;
|
||||
|
||||
if (typeof options.width === 'number') {
|
||||
return `${options.width}px`;
|
||||
@@ -76,7 +74,6 @@ export function Sidebar() {
|
||||
visible: false,
|
||||
};
|
||||
|
||||
setSidebarOptions(options);
|
||||
sidebarService.sidebarOptions$.next(options);
|
||||
options?.onClose?.();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user