feature(RulerManager): ColumnRulerManager,HideColumnController

This commit is contained in:
Dushusir
2023-07-13 15:56:07 +08:00
parent 5521c6a743
commit 677e1ebf2c
28 changed files with 478 additions and 11 deletions
+33
View File
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<title>UniverDoc</title>
<link rel="stylesheet" href="./main.css" />
<style>
html,
body {
height: 100%;
margin: 0;
}
</style>
<script>
new EventSource('/esbuild').addEventListener('change', () => {
location.reload()
})
</script>
</head>
<body>
<div id="app" style="z-index: 1; position: fixed; font-size: 20px; color: green;"></div>
<div id="univerdoc" style="height: 100%;"></div>
<script src="./main.js"></script>
</body>
</html>
+1 -4
View File
@@ -4,8 +4,7 @@
<head>
<meta charset="utf-8" />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<title>Esbuild example app</title>
<meta name="author" content="Christoffer Jahren" />
<title>UniverSheet</title>
<link rel="stylesheet" href="./main.css" />
<style>
@@ -19,7 +18,6 @@
<script>
new EventSource('/esbuild').addEventListener('change', () => {
console.info('reload--')
location.reload()
})
</script>
@@ -27,7 +25,6 @@
<body>
<div id="app" style="z-index: 1; position: fixed; font-size: 20px; color: green;"></div>
<!-- <div id="universheet" style="height: 225px;width: 400px;"></div> -->
<div id="universheet" style="height: 100%;"></div>
<script src="./main.js"></script>
+1 -4
View File
@@ -4,8 +4,7 @@
<head>
<meta charset="utf-8" />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<title>Esbuild example app</title>
<meta name="author" content="Christoffer Jahren" />
<title>UniverSheet</title>
<link rel="stylesheet" href="./main.css" />
<style>
@@ -19,7 +18,6 @@
<script>
new EventSource('/esbuild').addEventListener('change', () => {
console.info('reload--')
location.reload()
})
</script>
@@ -27,7 +25,6 @@
<body>
<div id="app" style="z-index: 1; position: fixed; font-size: 20px; color: green;"></div>
<!-- <div id="universheet" style="height: 225px;width: 400px;"></div> -->
<div id="universheet" style="height: 100%;"></div>
<script src="./main.js"></script>
+8
View File
@@ -74,3 +74,11 @@ universheet.installPlugin(new OperationPlugin());
universheet.installPlugin(new ImportXlsxPlugin());
universheet.installPlugin(new OverGridImagePlugin());
universheet.installPlugin(new NumfmtPlugin());
// use for console test
declare global {
interface Window {
univer?: any;
}
}
window.univer = univer;
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<title>UniverSlide</title>
<link rel="stylesheet" href="./main.css" />
<style>
html,
body {
height: 100%;
margin: 0;
}
</style>
<script>
new EventSource('/esbuild').addEventListener('change', () => {
location.reload()
})
</script>
</head>
<body>
<div id="app" style="z-index: 1; position: fixed; font-size: 20px; color: green;"></div>
<div id="universlide" style="height: 100%;"></div>
<script src="./main.js"></script>
</body>
</html>
@@ -0,0 +1,8 @@
import { BooleanNumber } from '@univerjs/core';
/**
* Column ruler data type
*/
export interface IColumnRulerData {
hd: BooleanNumber;
}
@@ -0,0 +1,49 @@
import { ObjectArray, Plugin } from '@univerjs/core';
import { IColumnRulerData } from '../../Interfaces/IRulerManager';
/**
* Modify cell value
*/
export class BaseColumnRuler<T extends Plugin = Plugin> {
constructor(protected _sheetId: string, protected _columnIndex: number, protected _numColumns: number, protected _plugin: T) {
//
}
/**
* Execute the core logic after the check is successful
*/
getUpdatedHidden(): ObjectArray<IColumnRulerData> {
return new ObjectArray();
}
}
/**
* Determine whether to intercept and create BaseColumnRuler
*/
export class BaseColumnRulerFactory<T extends Plugin = Plugin> {
constructor(protected _plugin: T) {}
get zIndex() {
return 0;
}
/**
* Generate Cell Extension
* @param value
* @returns
*/
create(sheetId: string, columnIndex: number, numColumns: number): BaseColumnRuler<T> {
return new BaseColumnRuler(sheetId, columnIndex, numColumns, this._plugin);
}
/**
* Check if this cell needs to be intercepted currently
* @param row
* @param column
* @param value
* @returns
*/
check(sheetId: string, columnIndex: number, numColumns: number): BaseColumnRuler {
return this.create(sheetId, columnIndex, numColumns);
}
}
@@ -0,0 +1,95 @@
import { Command, ISetColumnHideActionData, ISetColumnShowActionData, SetColumnHideAction, SetColumnShowAction, SheetContext } from '@univerjs/core';
import { ISheetContext } from '../../../Services/tokens';
import { BaseColumnRulerFactory } from './ColumnRulerFactory';
import { ColumnRulerRegister } from './ColumnRulerRegister';
/**
* ColumnRulerManager
Features that affect column state: grouping, hiding columns, etc.
Idea:
Set: plugin update => RulerManager setHidden => RulerList result => worksheet column data update
Get: Whether to support copy, get worksheet column data to determine whether a column is hidden
*
*/
export class ColumnRulerManager {
private _register: ColumnRulerRegister;
private _columnRulerFactoryList: BaseColumnRulerFactory[];
constructor(@ISheetContext private readonly _sheetContext: SheetContext) {
this._register = new ColumnRulerRegister();
}
getRegister(): ColumnRulerRegister {
return this._register;
}
/**
* set hidden state by all rulers
* @returns
*/
setHidden(sheetId: string, columnIndex: number, numColumns: number) {
const columnRulerFactoryList = this._register.columnRulerFactoryList;
if (!columnRulerFactoryList) return false;
this._columnRulerFactoryList = columnRulerFactoryList;
this._checkExtension(sheetId, columnIndex, numColumns);
}
/**
* Traverse all rulers
* @returns
*/
private _checkExtension(sheetId: string, columnIndex: number, numColumns: number) {
if (!this._columnRulerFactoryList) return false;
const hiddenDataList = [];
for (let i = 0; i < this._columnRulerFactoryList.length; i++) {
const extensionFactory = this._columnRulerFactoryList[i];
const extension = extensionFactory.check(sheetId, columnIndex, numColumns);
const hiddenArray = extension.getUpdatedHidden();
hiddenDataList.push(hiddenArray);
}
const actionDataList = [];
for (let i = columnIndex; i < columnIndex + numColumns; i++) {
for (let j = 0; j < hiddenDataList.length; j++) {
const hiddenArray = hiddenDataList[j];
const column = hiddenArray.get(i);
if (column && column.hd) {
const actionData: ISetColumnHideActionData = {
actionName: SetColumnHideAction.NAME,
sheetId,
columnCount: 1,
columnIndex: i,
};
actionDataList.push(actionData);
} else {
const actionData: ISetColumnShowActionData = {
actionName: SetColumnShowAction.NAME,
sheetId,
columnCount: 1,
columnIndex: i,
};
actionDataList.push(actionData);
}
}
}
if (actionDataList.length > 0) {
const _commandManager = this._sheetContext.getCommandManager();
const _workBook = this._sheetContext.getWorkBook();
const command = new Command(
{
WorkBookUnit: _workBook,
},
...actionDataList
);
_commandManager.invoke(command);
}
}
}
@@ -0,0 +1,29 @@
import { sortRules } from '@univerjs/core';
import { BaseColumnRulerFactory } from './ColumnRulerFactory';
import { REGISTRY_COLUMN_RULER_FACTORY } from './RegistryFactory';
export class ColumnRulerRegister {
private _columnRulerFactoryList: BaseColumnRulerFactory[] = [];
get columnRulerFactoryList(): BaseColumnRulerFactory[] {
return this._columnRulerFactoryList;
}
initialize() {
this._initExtensions();
}
add(...extensionFactoryList: BaseColumnRulerFactory[]) {
this._columnRulerFactoryList.push(...extensionFactoryList);
this._columnRulerFactoryList.sort(sortRules);
}
delete(extensionFactory: BaseColumnRulerFactory) {
const index = this._columnRulerFactoryList.indexOf(extensionFactory);
this._columnRulerFactoryList.splice(index, 1);
}
private _initExtensions() {
this._columnRulerFactoryList.push(...REGISTRY_COLUMN_RULER_FACTORY.getData().sort(sortRules));
}
}
@@ -0,0 +1,23 @@
// import { Registry } from '../Basics';
class Registry {
private _data: any[] = [];
static create() {
return new Registry();
}
add(dataInstance: any) {
this._data.push(dataInstance);
}
delete(dataInstance: any) {
const index = this._data.indexOf(dataInstance);
this._data.splice(index, 1);
}
getData() {
return this._data;
}
}
export const REGISTRY_COLUMN_RULER_FACTORY = Registry.create();
@@ -0,0 +1,6 @@
// @index(['./*.ts','./**/index.ts'], f => `export * from '${f.path}'`)
export * from './ColumnRulerFactory';
export * from './ColumnRulerManager';
export * from './ColumnRulerRegister';
// @endindex
@@ -0,0 +1,34 @@
import { BooleanNumber, ObjectArray } from '@univerjs/core';
import { SheetPlugin } from '../../SheetPlugin';
import { BaseColumnRuler, BaseColumnRulerFactory } from './ColumnRegister';
import { IColumnRulerData } from '../Interfaces/IRulerManager';
/**
* TODO insertColumn/insertRange/insertRange/deleteRange
*/
export class HideColumnRuler extends BaseColumnRuler<SheetPlugin> {
override getUpdatedHidden(): ObjectArray<IColumnRulerData> {
const columnIndex = this._columnIndex;
const numColumns = this._numColumns;
const sheetId = this._sheetId;
const columnData = this._plugin.getHideColumnController().getColumnData(sheetId);
const newColumnData: ObjectArray<IColumnRulerData> = new ObjectArray();
for (let i = columnIndex; i < columnIndex + numColumns; i++) {
const data = columnData.get(i) || { hd: BooleanNumber.FALSE };
newColumnData.set(i, data);
}
return newColumnData;
}
}
export class HideColumnRulerFactory extends BaseColumnRulerFactory<SheetPlugin> {
override get zIndex(): number {
return 0;
}
override create(sheetId: string, columnIndex: number, numColumns: number): HideColumnRuler {
return new HideColumnRuler(sheetId, columnIndex, numColumns, this._plugin);
}
}
@@ -0,0 +1,28 @@
/**
* TODO@jerry
* RowRulerManager
*
* en:
* Maintain the display/hidden state, support plug-ins to register rulers, plug-ins provide methods to modify the display and hidden states, and determine whether rows and columns can be copied and pasted or other operations,
* When copying, you can know which rows can be copied and which ones do not.
*
* Functions that affect row state: filter, group, hide row, filter view, etc.
*
* zh:
* 维护显示/隐藏的状态,支持插件注册ruler进去,插件提供方法修改显示、隐藏状态,决定行列是否可以被复制粘贴 或者 其他操作,
* 复制的时候,就可以知道哪些行可以被复制,哪些不用复制。
*
* 影响行状态的功能:筛选、分组、隐藏行、筛选视图 等等
*
*
*
* TODO@jerry
* AuthRulerManager
* en:
* Auth (registration permission ruler, consumption for other plug-ins, type: user information, rank, range, entire table, chart, pivot table, etc.)
*
* zh:
* 权限(注册权限ruler,给其他插件消费,类型:用户信息 行列 范围 整表 图表 数据透视表 等)
*
*
*/
@@ -0,0 +1,47 @@
import { BooleanNumber, ObjectArray } from '@univerjs/core';
import { Inject } from '@wendellhu/redi';
import { IColumnRulerData } from '../Basics/Interfaces/IRulerManager';
import { ColumnRulerManager } from '../Basics/Register/ColumnRegister';
export interface IHideColumnData {
[sheetId: string]: ObjectArray<IColumnRulerData>;
}
export class HideColumnController {
// TODO workbook worksheet
private _columnData: IHideColumnData = {};
constructor(@Inject(ColumnRulerManager) private readonly _columnRulerManager: ColumnRulerManager) {}
getColumnData(sheetId: string) {
return this._columnData[sheetId];
}
/**
* Set hidden columns and store them in RulerManager
* @param columnIndex
* @param numColumns
*/
hideColumns(sheetId: string, columnIndex: number, numColumns: number) {
for (let i = columnIndex; i < columnIndex + numColumns; i++) {
let sheetData = this._columnData[sheetId];
if (!sheetData) {
this._columnData[sheetId] = new ObjectArray();
}
let column = this._columnData[sheetId].get(i);
if (column) {
column.hd = BooleanNumber.TRUE;
} else {
const create = {
hd: BooleanNumber.TRUE,
};
this._columnData[sheetId].set(i, create);
}
}
this._columnRulerManager.setHidden(sheetId, columnIndex, numColumns);
}
}
@@ -1,14 +1,17 @@
import { Context, SheetContext, UIObserver } from '@univerjs/core';
import { Inject } from '@wendellhu/redi';
import { SelectionController } from './Selection/SelectionController';
import { SelectionModel } from '../Model/SelectionModel';
import { IGlobalContext, ISelectionManager, ISheetContext } from '../Services/tokens';
import { SelectionManager } from './Selection';
import { HideColumnController } from './HideColumnController';
export class RightMenuController {
constructor(
@ISelectionManager private readonly _selectionManager: SelectionManager,
@ISheetContext private readonly _sheetContext: SheetContext,
@IGlobalContext private readonly _globalContext: Context
@IGlobalContext private readonly _globalContext: Context,
@Inject(HideColumnController) private readonly _hideColumnController: HideColumnController
) {}
listenEventManager() {
@@ -29,6 +32,9 @@ export class RightMenuController {
case 'deleteColumn':
this.deleteColumn();
break;
case 'hideColumn':
this.hideColumn();
break;
case 'moveTop':
this.deleteCellTop();
break;
@@ -80,6 +86,14 @@ export class RightMenuController {
}
};
hideColumn = () => {
const selections = this._getSelections();
if (selections?.length === 1) {
const sheet = this._sheetContext.getWorkBook().getActiveSheet();
this._hideColumnController.hideColumns(sheet.getSheetId(), selections[0].startColumn, selections[0].endColumn - selections[0].startColumn + 1);
}
};
clearContent = () => {
const selections = this._getSelections();
if (selections?.length === 1) {
@@ -8,4 +8,5 @@ export * from './SheetBarController';
export * from './SheetContainerController';
export * from './ToolbarController';
export * from './EditTooltipsController';
export * from './HideColumnController';
// @endindex
+27
View File
@@ -14,6 +14,7 @@ import {
CountBarController,
EditTooltipsController,
SelectionManager,
HideColumnController,
} from './Controller';
import { DEFAULT_SPREADSHEET_PLUGIN_DATA, install, ISheetPluginConfig } from './Basics';
import { FormulaBarController } from './Controller/FormulaBarController';
@@ -23,6 +24,8 @@ import { IGlobalContext, IRenderingEngine, ISelectionManager, ISheetContext, ISh
import { DragLineController } from './Controller/Selection/DragLineController';
import { ColumnTitleController } from './Controller/Selection/ColumnTitleController';
import { RowTitleController } from './Controller/Selection/RowTitleController';
import { ColumnRulerManager } from './Basics/Register/ColumnRegister';
import { HideColumnRulerFactory } from './Basics/Register/HideColumnRuler';
/**
* The main sheet base, construct the sheet container and layout, mount the rendering engine
@@ -50,10 +53,16 @@ export class SheetPlugin extends Plugin<SheetPluginObserve, SheetContext> {
private _countBarController: CountBarController;
private _hideColumnController: HideColumnController;
private _sheetContainerController: SheetContainerController;
private _namedRangeActionExtensionFactory: NamedRangeActionExtensionFactory;
private _columnRulerManager: ColumnRulerManager;
private _hideColumnRulerFactory: HideColumnRulerFactory;
constructor(config?: Partial<ISheetPluginConfig>) {
super(PLUGIN_NAMES.SPREADSHEET);
@@ -113,6 +122,7 @@ export class SheetPlugin extends Plugin<SheetPluginObserve, SheetContext> {
this._toolbarController = this._injector.get(ToolbarController);
this._rightMenuController = this._injector.get(RightMenuController);
this._countBarController = this._injector.get(CountBarController);
this._hideColumnController = this._injector.get(HideColumnController);
}
initCanvasView() {
@@ -130,12 +140,20 @@ export class SheetPlugin extends Plugin<SheetPluginObserve, SheetContext> {
const actionRegister = this.context.getCommandManager().getActionExtensionManager().getRegister();
actionRegister.delete(this._namedRangeActionExtensionFactory);
const rulerRegister = this._columnRulerManager.getRegister();
rulerRegister.delete(this._hideColumnRulerFactory);
}
registerExtension() {
const actionRegister = this.context.getCommandManager().getActionExtensionManager().getRegister();
this._namedRangeActionExtensionFactory = new NamedRangeActionExtensionFactory(this);
actionRegister.add(this._namedRangeActionExtensionFactory);
this._columnRulerManager = this._injector.get(ColumnRulerManager);
const rulerRegister = this._columnRulerManager.getRegister();
this._hideColumnRulerFactory = new HideColumnRulerFactory(this);
rulerRegister.add(this._hideColumnRulerFactory);
}
listenEventManager() {
@@ -241,6 +259,11 @@ export class SheetPlugin extends Plugin<SheetPluginObserve, SheetContext> {
return this._countBarController;
}
/** @deprecated DI */
getHideColumnController() {
return this._hideColumnController;
}
protected _getCoreObserver<T>(type: string) {
return this.getGlobalContext().getObserverManager().requiredObserver<UIObserver<T>>(type, 'core');
}
@@ -279,6 +302,10 @@ export class SheetPlugin extends Plugin<SheetPluginObserve, SheetContext> {
[RowTitleController],
[ColumnTitleController],
[DragLineController],
[HideColumnController],
// RulerManager
[ColumnRulerManager],
// #endregion Controllers
]);
}
@@ -21,7 +21,7 @@ export class BaseCellEditExtension {
/**
* Execute the core logic after the check is successful
*/
// execute() { }
execute() {}
}
/**
@@ -24153,6 +24153,32 @@ export const DEFAULT_WORKBOOK_DATA_DEMO: IWorkbookConfig = {
rightToLeft: BooleanNumber.FALSE,
pluginMeta: {},
},
'sheet-0011': {
type: SheetTypes.GRID,
id: 'sheet-0011',
name: 'sheet11',
columnData: {
1: {
hd: BooleanNumber.FALSE,
},
},
cellData: {
0: {
0: {
v: 1,
m: '1',
},
1: {
v: 2,
m: '2',
},
2: {
v: 3,
m: '3',
},
},
},
},
},
namedRanges: [
{
@@ -2,6 +2,8 @@ import { SheetContext, IRangeData, UniverSheet, Plugin } from '@univerjs/core';
import { FILTER_PLUGIN_NAME } from './Const';
import { Filter, FilterList, IFilterPluginConfig } from './Domain';
// TODO@jerry
// Filtering affects row hiding, registered to RowRulerManager
export class FilterPlugin extends Plugin {
private _filterList: FilterList;
@@ -3,6 +3,8 @@ import { GROUP_PLUGIN_NAME } from './Basics/Const/PLUGIN_NAME';
export interface IGroupPluginConfig {}
// TODO@jerry
// Group affects row and column hiding, registered to RowRulerManager, ColumnRulerManager
export class GroupPlugin extends Plugin {
constructor(config?: IGroupPluginConfig) {
super(GROUP_PLUGIN_NAME);
@@ -312,6 +312,7 @@ export class UniverCopy extends Copy {
for (let copyR = r1; copyR <= r2; copyR++) {
const rowItem = rowManager.get(copyR);
if (rowItem && rowItem.hd) {
continue;
}
@@ -130,6 +130,7 @@ export class RightMenuUIController {
},
{
label: 'rightClick.hideSelectedColumn',
onClick: () => this.hideColumn(),
show: this._config.HideColumn,
},
{
@@ -333,6 +334,13 @@ export class RightMenuUIController {
this.setUIObserve(msg);
}
hideColumn() {
const msg = {
name: 'hideColumn',
};
this.setUIObserve(msg);
}
setRowHeight(e: Event) {
console.dir(this._plugin.getContext().getUniver().getCurrentUniverSheetInstance().getWorkBook().getActiveSheet().getConfig());
console.dir(this._plugin.getContext().getUniver().getCurrentUniverSheetInstance().getWorkBook().getStyles());
-1
View File
@@ -15,7 +15,6 @@ const { Bright, FgCyan, FgGreen, Reset } = require('./color');
(async () => {
const args = minimist(process.argv.slice(2));
const target = args.t;
console.info('target====', target);
const paths = {
entry: resolve(__dirname, `../examples/univer-${target}-ts/src/main.tsx`),
// cssEntry: resolve(root, "./src/index.css"),