mirror of
https://github.com/dream-num/univer.git
synced 2026-09-24 15:32:18 +08:00
refactor(debugger): refactor debugger plugin (#5213)
This commit is contained in:
@@ -72,10 +72,16 @@ univer.registerPlugin(UniverDocsQuickInsertUIPlugin);
|
||||
|
||||
if (!IS_E2E) {
|
||||
univer.createUnit(UniverInstanceType.UNIVER_DOC, DEFAULT_DOCUMENT_DATA_SIMPLE);
|
||||
univer.registerPlugin(UniverDebuggerPlugin);
|
||||
} else {
|
||||
univer.registerPlugin(UniverDebuggerPlugin, {
|
||||
fab: false,
|
||||
performanceMonitor: {
|
||||
enabled: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
univer.registerPlugin(UniverDebuggerPlugin);
|
||||
|
||||
// use for console test
|
||||
declare global {
|
||||
// eslint-disable-next-line ts/naming-convention
|
||||
|
||||
@@ -138,6 +138,7 @@ function createNewInstance() {
|
||||
// If we are running in e2e platform, we should immediately register the debugger plugin.
|
||||
if (IS_E2E) {
|
||||
univer.registerPlugin(UniverDebuggerPlugin, {
|
||||
fab: false,
|
||||
performanceMonitor: {
|
||||
enabled: false,
|
||||
},
|
||||
|
||||
@@ -29,7 +29,6 @@ const IS_E2E: boolean = !!process.env.IS_E2E;
|
||||
|
||||
export default function getVeryLazyPlugins() {
|
||||
const plugins: Array<[PluginCtor<Plugin>] | [PluginCtor<Plugin>, unknown]> = [
|
||||
|
||||
[UniverActionRecorderPlugin],
|
||||
[UniverSheetsHyperLinkUIPlugin],
|
||||
[UniverSheetsSortUIPlugin],
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
"@univerjs/core": "workspace:*",
|
||||
"@univerjs/design": "workspace:*",
|
||||
"@univerjs/docs-drawing-ui": "workspace:*",
|
||||
"@univerjs/docs-ui": "workspace:*",
|
||||
"@univerjs/engine-render": "workspace:*",
|
||||
"@univerjs/icons": "^0.3.24",
|
||||
"@univerjs/mockdata": "workspace:*",
|
||||
@@ -76,9 +75,6 @@
|
||||
"@univerjs/ui": "workspace:*",
|
||||
"@univerjs/watermark": "workspace:*"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"vue": ">=3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"postcss": "^8.5.3",
|
||||
@@ -87,7 +83,6 @@
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.5",
|
||||
"vitest": "^3.1.3",
|
||||
"vue": "^3.5.13"
|
||||
"vitest": "^3.1.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/**
|
||||
* 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 { ICommand, IWorkbookData, Univer, Workbook } from '@univerjs/core';
|
||||
import type { FUniver } from '@univerjs/core/facade';
|
||||
import { CommandType, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { ILocalFileService } from '@univerjs/ui';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line ts/naming-convention
|
||||
interface Window {
|
||||
univer?: Univer;
|
||||
univerAPI?: ReturnType<typeof FUniver.newAPI>;
|
||||
}
|
||||
}
|
||||
|
||||
export const DisposeUniverCommand: ICommand = {
|
||||
id: 'debugger.command.dispose-unit',
|
||||
type: CommandType.COMMAND,
|
||||
handler: () => {
|
||||
window.univer?.dispose();
|
||||
window.univer = undefined;
|
||||
window.univerAPI = undefined;
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
export const DisposeCurrentUnitCommand: ICommand = {
|
||||
id: 'debugger.command.dispose-current-unit',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor) => {
|
||||
const univerInstanceService = accessor.get(IUniverInstanceService);
|
||||
const focused = univerInstanceService.getFocusedUnit();
|
||||
if (!focused) return false;
|
||||
|
||||
return univerInstanceService.disposeUnit(focused.getUnitId());
|
||||
},
|
||||
};
|
||||
|
||||
export const CreateEmptySheetCommand: ICommand = {
|
||||
id: 'debugger.command.create-empty-sheet',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor) => {
|
||||
const univerInstanceService = accessor.get(IUniverInstanceService);
|
||||
univerInstanceService.createUnit(UniverInstanceType.UNIVER_SHEET, {});
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
export const LoadSheetSnapshotCommand: ICommand = {
|
||||
id: 'debugger.command.load-sheet-snapshot',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor) => {
|
||||
const fileOpenerService = accessor.get(ILocalFileService);
|
||||
const snapshotFile = await fileOpenerService.openFile({ multiple: false, accept: '.json' });
|
||||
if (snapshotFile.length !== 1) return false;
|
||||
|
||||
const text = await snapshotFile[0].text();
|
||||
const instanceService = accessor.get(IUniverInstanceService);
|
||||
instanceService.createUnit<IWorkbookData, Workbook>(UniverInstanceType.UNIVER_SHEET, JSON.parse(text));
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
* 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 { CommandType, createDefaultUser, IPermissionService, IUniverInstanceService, UniverInstanceType, UserManagerService } from '@univerjs/core';
|
||||
import { WorkbookManageCollaboratorPermission } from '@univerjs/sheets';
|
||||
import type { IAccessor, ICommand, Workbook } from '@univerjs/core';
|
||||
|
||||
export enum UnitRole {
|
||||
Reader = 0,
|
||||
Editor = 1,
|
||||
Owner = 2,
|
||||
UNRECOGNIZED = -1,
|
||||
}
|
||||
|
||||
interface IChangeUserParams {
|
||||
value: UnitRole.Reader | UnitRole.Owner;
|
||||
|
||||
}
|
||||
|
||||
export const ChangeUserCommand: ICommand = {
|
||||
id: 'debugger.operation.changeUser',
|
||||
type: CommandType.OPERATION,
|
||||
handler: async (accessor: IAccessor, params: IChangeUserParams) => {
|
||||
const userManagerService = accessor.get(UserManagerService);
|
||||
const univerInstanceService = accessor.get(IUniverInstanceService);
|
||||
userManagerService.setCurrentUser(createDefaultUser(params.value));
|
||||
const workbook = univerInstanceService.getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET)!;
|
||||
const permissionService = accessor.get(IPermissionService);
|
||||
const unitId = workbook.getUnitId();
|
||||
if (params.value === UnitRole.Owner) {
|
||||
permissionService.updatePermissionPoint(new WorkbookManageCollaboratorPermission(unitId).id, true);
|
||||
} else {
|
||||
permissionService.updatePermissionPoint(new WorkbookManageCollaboratorPermission(unitId).id, false);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
* 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 { IAccessor, ICommand } from '@univerjs/core';
|
||||
import { CommandType } from '@univerjs/core';
|
||||
import { IConfirmService } from '@univerjs/ui';
|
||||
|
||||
export interface IUIComponentCommandParams {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export const ConfirmOperation: ICommand = {
|
||||
id: 'debugger.operation.confirm',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor: IAccessor, params: IUIComponentCommandParams) => {
|
||||
const confirmService = accessor.get(IConfirmService);
|
||||
|
||||
confirmService.open({
|
||||
id: 'confirm1',
|
||||
children: { title: 'Confirm Content' },
|
||||
title: { title: 'Confirm Title' },
|
||||
confirmText: 'hello',
|
||||
cancelText: 'world',
|
||||
onClose() {
|
||||
confirmService.close('confirm1');
|
||||
},
|
||||
});
|
||||
|
||||
confirmService.open({
|
||||
id: 'confirm2',
|
||||
children: { title: 'Confirm2 Content' },
|
||||
title: { title: 'Confirm2 Title' },
|
||||
onClose() {
|
||||
confirmService.close('confirm2');
|
||||
},
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
* 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 { IAccessor, ICommand } from '@univerjs/core';
|
||||
import { CommandType, ThemeService } from '@univerjs/core';
|
||||
|
||||
export interface IDarkModeCommandParams {
|
||||
value?: 'dark' | 'light';
|
||||
}
|
||||
|
||||
export const DarkModeOperation: ICommand = {
|
||||
id: 'debugger.operation.dark-mode',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor: IAccessor, params: IDarkModeCommandParams) => {
|
||||
const themeService = accessor.get(ThemeService);
|
||||
themeService.setDarkMode(params.value === 'dark');
|
||||
localStorage.setItem('local.darkMode', params.value ?? 'light');
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
/**
|
||||
* 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 { CommandType, LocaleService } from '@univerjs/core';
|
||||
import type { IAccessor, ICommand, LocaleType } from '@univerjs/core';
|
||||
|
||||
export interface ILocaleCommandParams {
|
||||
value: LocaleType;
|
||||
}
|
||||
|
||||
export const LocaleOperation: ICommand = {
|
||||
id: 'debugger.operation.locale',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor: IAccessor, params: ILocaleCommandParams) => {
|
||||
const localeService = accessor.get(LocaleService);
|
||||
localeService.setLocale(params.value);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* 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 { IAccessor, ICommand } from '@univerjs/core';
|
||||
import { CommandType } from '@univerjs/core';
|
||||
import { INotificationService } from '@univerjs/ui';
|
||||
|
||||
export interface IUIComponentCommandParams {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export const NotificationOperation: ICommand = {
|
||||
id: 'debugger.operation.notification',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor: IAccessor, params: IUIComponentCommandParams) => {
|
||||
const notificationService = accessor.get(INotificationService);
|
||||
const { value = '' } = params;
|
||||
const type =
|
||||
value.indexOf('Success') > -1
|
||||
? 'success'
|
||||
: value.indexOf('Info') > -1
|
||||
? 'info'
|
||||
: value.indexOf('Warning') > -1
|
||||
? 'warning'
|
||||
: 'error';
|
||||
notificationService.show({
|
||||
type,
|
||||
content: value || 'Notification Content',
|
||||
title: 'Notification Title',
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
* 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 { CommandType, ICommandService } from '@univerjs/core';
|
||||
import type { IAccessor, ICommand } from '@univerjs/core';
|
||||
|
||||
export interface INumfmtOperationCommandParams {
|
||||
value: 'close' | 'open';
|
||||
}
|
||||
|
||||
export const NumfmtOperation: ICommand = {
|
||||
id: 'debugger.operation.numfmt',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor: IAccessor, params: INumfmtOperationCommandParams) => {
|
||||
const confirmService = accessor.get(ICommandService);
|
||||
if (params.value === 'open') {
|
||||
confirmService.executeCommand('sheet.operation.open.numfmt.panel');
|
||||
} else {
|
||||
confirmService.executeCommand('sheet.operation.close.numfmt.panel');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,120 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* eslint-disable node/prefer-global/process */
|
||||
|
||||
import { CommandType, IResourceLoaderService, IUniverInstanceService, ObjectMatrix, UniverInstanceType } from '@univerjs/core';
|
||||
import { ILocalFileService } from '@univerjs/ui';
|
||||
import type { DocumentDataModel, IAccessor, ICommand, IStyleData, IWorkbookData, Workbook } from '@univerjs/core';
|
||||
import { RecordController } from '../../controllers/local-save/record.controller';
|
||||
|
||||
export interface ISaveSnapshotParams {
|
||||
value: 'sheet' | 'workbook' | 'record';
|
||||
}
|
||||
|
||||
const filterStyle = (workbookData: IWorkbookData) => {
|
||||
const sheets = workbookData.sheets;
|
||||
const cacheStyle: Record<string, IStyleData> = {};
|
||||
Object.keys(sheets).forEach((sheetId) => {
|
||||
const sheet = sheets[sheetId];
|
||||
new ObjectMatrix(sheet.cellData).forValue((_r, _c, value) => {
|
||||
const s = value?.s;
|
||||
if (s && typeof s === 'string') {
|
||||
const style = workbookData.styles[s];
|
||||
if (style) {
|
||||
cacheStyle[s] = style;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
workbookData.styles = cacheStyle;
|
||||
return workbookData;
|
||||
};
|
||||
|
||||
export const SaveSnapshotOptions: ICommand = {
|
||||
id: 'debugger.operation.saveSnapshot',
|
||||
type: CommandType.OPERATION,
|
||||
handler: async (accessor: IAccessor, params: ISaveSnapshotParams) => {
|
||||
const univerInstanceService = accessor.get(IUniverInstanceService);
|
||||
const resourceLoaderService = accessor.get(IResourceLoaderService);
|
||||
const localFileService = accessor.get(ILocalFileService);
|
||||
const recordController = accessor.get(RecordController);
|
||||
|
||||
const preName = new Date().toLocaleString();
|
||||
const workbook = univerInstanceService.getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET)!;
|
||||
if (!workbook) {
|
||||
const doc = univerInstanceService.getCurrentUnitForType<DocumentDataModel>(UniverInstanceType.UNIVER_DOC)!;
|
||||
const snapshot = resourceLoaderService.saveUnit(doc.getUnitId());
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
const gitHash = process.env.GIT_COMMIT_HASH;
|
||||
const gitBranch = process.env.GIT_REF_NAME;
|
||||
const buildTime = process.env.BUILD_TIME;
|
||||
(snapshot as any).__env__ = { gitHash, gitBranch, buildTime };
|
||||
}
|
||||
const text = JSON.stringify(snapshot, null, 2);
|
||||
localFileService.downloadFile(new Blob([text]), `${preName} snapshot.json`);
|
||||
return true;
|
||||
}
|
||||
|
||||
const worksheet = workbook.getActiveSheet();
|
||||
if (!worksheet) {
|
||||
return false;
|
||||
}
|
||||
const snapshot = resourceLoaderService.saveUnit<ReturnType<typeof workbook.getSnapshot>>(workbook.getUnitId())!;
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
const gitHash = process.env.GIT_COMMIT_HASH;
|
||||
const gitBranch = process.env.GIT_REF_NAME;
|
||||
const buildTime = process.env.BUILD_TIME;
|
||||
(snapshot as any).__env__ = { gitHash, gitBranch, buildTime };
|
||||
}
|
||||
|
||||
switch (params.value) {
|
||||
case 'sheet': {
|
||||
const sheetId = worksheet.getSheetId();
|
||||
const sheet = snapshot.sheets[sheetId];
|
||||
snapshot.sheets = { [sheetId]: sheet };
|
||||
snapshot.sheetOrder = [sheetId];
|
||||
const text = JSON.stringify(filterStyle(snapshot), null, 2);
|
||||
localFileService.downloadFile(new Blob([text]), `${preName} snapshot.json`);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'workbook': {
|
||||
const text = JSON.stringify(filterStyle(snapshot), null, 2);
|
||||
localFileService.downloadFile(new Blob([text]), `${preName} snapshot.json`);
|
||||
|
||||
break;
|
||||
}
|
||||
case 'record': {
|
||||
let endCommands = () => [];
|
||||
|
||||
recordController.record().subscribe((v) => {
|
||||
if (v.type === 'start') {
|
||||
endCommands = recordController.startSaveCommands() as any;
|
||||
}
|
||||
if (v.type === 'finish') {
|
||||
const commands = endCommands();
|
||||
localFileService.downloadFile(v.data, `${preName} video.webm`);
|
||||
localFileService.downloadFile(new Blob([JSON.stringify(commands, null, 2)]), `${preName} commands.json`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
* 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 { IAccessor, ICommand, Workbook } from '@univerjs/core';
|
||||
import { CommandType, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { IEditorService } from '@univerjs/docs-ui';
|
||||
import { ISidebarService } from '@univerjs/ui';
|
||||
import { TEST_EDITOR_CONTAINER_COMPONENT } from '../../views/test-editor/component-name';
|
||||
|
||||
export interface IUIComponentCommandParams {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export const SidebarOperation: ICommand = {
|
||||
id: 'debugger.operation.sidebar',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor: IAccessor, params: IUIComponentCommandParams) => {
|
||||
const sidebarService = accessor.get(ISidebarService);
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const univerInstanceService = accessor.get(IUniverInstanceService);
|
||||
const unit = univerInstanceService.getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET)!;
|
||||
switch (params.value) {
|
||||
case 'open':
|
||||
sidebarService.open({
|
||||
header: { title: 'Sidebar title' },
|
||||
children: { label: TEST_EDITOR_CONTAINER_COMPONENT },
|
||||
footer: { title: 'Sidebar Footer' },
|
||||
onClose: () => {
|
||||
},
|
||||
});
|
||||
break;
|
||||
|
||||
case 'close':
|
||||
default:
|
||||
sidebarService.close();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
* 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 { IAccessor, ICommand } from '@univerjs/core';
|
||||
import type { Theme } from '@univerjs/themes';
|
||||
import { CommandType, ThemeService } from '@univerjs/core';
|
||||
|
||||
export interface IThemeCommandParams {
|
||||
value?: Theme;
|
||||
}
|
||||
|
||||
export const ThemeOperation: ICommand = {
|
||||
id: 'debugger.operation.theme',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor: IAccessor, params: IThemeCommandParams) => {
|
||||
const themeService = accessor.get(ThemeService);
|
||||
|
||||
params.value && themeService.setTheme(params.value);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
<template>
|
||||
<section>
|
||||
🌍
|
||||
</section>
|
||||
</template>
|
||||
@@ -22,9 +22,15 @@ export const configSymbol = Symbol(DEBUGGER_PLUGIN_CONFIG_KEY);
|
||||
|
||||
export interface IUniverDebuggerConfig {
|
||||
menu?: MenuConfig;
|
||||
fab?: boolean;
|
||||
performanceMonitor?: {
|
||||
enabled: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export const defaultPluginConfig: IUniverDebuggerConfig = {};
|
||||
export const defaultPluginConfig: IUniverDebuggerConfig = {
|
||||
fab: true,
|
||||
performanceMonitor: {
|
||||
enabled: true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -14,79 +14,41 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Disposable, ICommandService, Inject, Injector } from '@univerjs/core';
|
||||
import { ComponentManager, IMenuManagerService } from '@univerjs/ui';
|
||||
import { CreateFloatDomCommand } from '../commands/commands/float-dom.command';
|
||||
import { CreateEmptySheetCommand, DisposeCurrentUnitCommand, DisposeUniverCommand, LoadSheetSnapshotCommand } from '../commands/commands/unit.command';
|
||||
import { ShowCellContentOperation } from '../commands/operations/cell.operation';
|
||||
import { ChangeUserCommand } from '../commands/operations/change-user.operation';
|
||||
import { ConfirmOperation } from '../commands/operations/confirm.operation';
|
||||
import { DarkModeOperation } from '../commands/operations/dark-mode.operation';
|
||||
import { DialogOperation } from '../commands/operations/dialog.operation';
|
||||
import { LocaleOperation } from '../commands/operations/locale.operation';
|
||||
import { MessageOperation } from '../commands/operations/message.operation';
|
||||
import { NotificationOperation } from '../commands/operations/notification.operation';
|
||||
import { OpenWatermarkPanelOperation } from '../commands/operations/open-watermark-panel.operation';
|
||||
import { SaveSnapshotOptions } from '../commands/operations/save-snapshot.operations';
|
||||
import { SetEditable } from '../commands/operations/set.editable.operation';
|
||||
import { SidebarOperation } from '../commands/operations/sidebar.operation';
|
||||
import { ThemeOperation } from '../commands/operations/theme.operation';
|
||||
import type { IUniverDebuggerConfig } from './config.schema';
|
||||
import { Disposable, IConfigService, Inject, Injector } from '@univerjs/core';
|
||||
import { BuiltInUIPart, ComponentManager, connectInjector, IUIPartsService } from '@univerjs/ui';
|
||||
import { AIButton, FloatButton } from '../components/FloatButton';
|
||||
import { ImageDemo } from '../components/Image';
|
||||
import { RangeLoading } from '../components/RangeLoading';
|
||||
// @ts-ignore
|
||||
import VueI18nIcon from '../components/VueI18nIcon.vue';
|
||||
import { Fab } from '../views/Fab';
|
||||
import { DEBUGGER_PLUGIN_CONFIG_KEY } from './config.schema';
|
||||
import { RecordController } from './local-save/record.controller';
|
||||
import { menuSchema } from './menu.schema';
|
||||
|
||||
export class DebuggerController extends Disposable {
|
||||
constructor(
|
||||
@Inject(Injector) private readonly _injector: Injector,
|
||||
@IMenuManagerService private readonly _menuManagerService: IMenuManagerService,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@IConfigService private readonly _configService: IConfigService,
|
||||
@IUIPartsService protected readonly _uiPartsService: IUIPartsService,
|
||||
@Inject(ComponentManager) private readonly _componentManager: ComponentManager
|
||||
) {
|
||||
super();
|
||||
|
||||
this._initializeMenu();
|
||||
this._initCustomComponents();
|
||||
|
||||
[
|
||||
LocaleOperation,
|
||||
DarkModeOperation,
|
||||
ThemeOperation,
|
||||
NotificationOperation,
|
||||
DialogOperation,
|
||||
ConfirmOperation,
|
||||
MessageOperation,
|
||||
SidebarOperation,
|
||||
SetEditable,
|
||||
SaveSnapshotOptions,
|
||||
DisposeUniverCommand,
|
||||
DisposeCurrentUnitCommand,
|
||||
CreateEmptySheetCommand,
|
||||
LoadSheetSnapshotCommand,
|
||||
CreateFloatDomCommand,
|
||||
ChangeUserCommand,
|
||||
ShowCellContentOperation,
|
||||
OpenWatermarkPanelOperation,
|
||||
].forEach((command) => this.disposeWithMe(this._commandService.registerCommand(command)));
|
||||
|
||||
this._injector.add([RecordController]);
|
||||
}
|
||||
|
||||
private _initializeMenu() {
|
||||
this._menuManagerService.mergeMenu(menuSchema);
|
||||
}
|
||||
|
||||
private _initCustomComponents(): void {
|
||||
const componentManager = this._componentManager;
|
||||
this.disposeWithMe(componentManager.register('VueI18nIcon', VueI18nIcon, {
|
||||
framework: 'vue3',
|
||||
}));
|
||||
this.disposeWithMe(componentManager.register('ImageDemo', ImageDemo));
|
||||
this.disposeWithMe(componentManager.register('RangeLoading', RangeLoading));
|
||||
this.disposeWithMe(componentManager.register('FloatButton', FloatButton));
|
||||
this.disposeWithMe(componentManager.register('AIButton', AIButton));
|
||||
|
||||
const configs = this._configService.getConfig<IUniverDebuggerConfig>(DEBUGGER_PLUGIN_CONFIG_KEY);
|
||||
|
||||
if (configs?.fab) {
|
||||
this._uiPartsService.registerComponent(BuiltInUIPart.GLOBAL, () => connectInjector(Fab, this._injector));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { awaitTime, Disposable, ICommandService, Inject, IUniverInstanceService, ThemeService, UniverInstanceType } from '@univerjs/core';
|
||||
|
||||
import type { Univer } from '@univerjs/core';
|
||||
import type { FUniver } from '@univerjs/core/facade';
|
||||
import { awaitTime, Disposable, Inject, IUniverInstanceService, ThemeService, UniverInstanceType } from '@univerjs/core';
|
||||
import { DEFAULT_WORKBOOK_DATA_DEMO, DEFAULT_WORKBOOK_DATA_DEMO_DEFAULT_STYLE } from '@univerjs/mockdata';
|
||||
import { DisposeUniverCommand } from '../../commands/commands/unit.command';
|
||||
import { getDefaultDocData } from './data/default-doc';
|
||||
import { getDefaultWorkbookData } from './data/default-sheet';
|
||||
|
||||
@@ -42,6 +42,8 @@ declare global {
|
||||
// eslint-disable-next-line ts/naming-convention
|
||||
interface Window {
|
||||
E2EControllerAPI: IE2EControllerAPI;
|
||||
univer?: Univer;
|
||||
univerAPI?: FUniver;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +53,6 @@ declare global {
|
||||
export class E2EController extends Disposable {
|
||||
constructor(
|
||||
@IUniverInstanceService private readonly _univerInstanceService: IUniverInstanceService,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@Inject(ThemeService) private readonly _themeService: ThemeService
|
||||
) {
|
||||
super();
|
||||
@@ -126,7 +127,9 @@ export class E2EController extends Disposable {
|
||||
}
|
||||
|
||||
private async _disposeUniver(): Promise<void> {
|
||||
await this._commandService.executeCommand(DisposeUniverCommand.id);
|
||||
window.univer?.dispose();
|
||||
window.univer = undefined;
|
||||
window.univerAPI = undefined;
|
||||
}
|
||||
|
||||
private async _disposeDefaultSheetUnit(disposingTimeout: number = AWAIT_DISPOSING_TIMEOUT): Promise<void> {
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
/**
|
||||
* 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 { MenuSchemaType } from '@univerjs/ui';
|
||||
import { RibbonOthersGroup } from '@univerjs/ui';
|
||||
import { CreateFloatDomCommand } from '../commands/commands/float-dom.command';
|
||||
import { CreateEmptySheetCommand, DisposeCurrentUnitCommand, DisposeUniverCommand, LoadSheetSnapshotCommand } from '../commands/commands/unit.command';
|
||||
import { ShowCellContentOperation } from '../commands/operations/cell.operation';
|
||||
import { ChangeUserCommand } from '../commands/operations/change-user.operation';
|
||||
import { ConfirmOperation } from '../commands/operations/confirm.operation';
|
||||
import { DarkModeOperation } from '../commands/operations/dark-mode.operation';
|
||||
import { DialogOperation } from '../commands/operations/dialog.operation';
|
||||
import { LocaleOperation } from '../commands/operations/locale.operation';
|
||||
import { MessageOperation } from '../commands/operations/message.operation';
|
||||
import { NotificationOperation } from '../commands/operations/notification.operation';
|
||||
import { OpenWatermarkPanelOperation } from '../commands/operations/open-watermark-panel.operation';
|
||||
import { SaveSnapshotOptions } from '../commands/operations/save-snapshot.operations';
|
||||
import { SetEditable } from '../commands/operations/set.editable.operation';
|
||||
import { SidebarOperation } from '../commands/operations/sidebar.operation';
|
||||
import { ThemeOperation } from '../commands/operations/theme.operation';
|
||||
import {
|
||||
ChangeUserMenuItemFactory,
|
||||
ConfirmMenuItemFactory,
|
||||
CreateEmptySheetMenuItemFactory,
|
||||
CreateFloatDOMMenuItemFactory,
|
||||
DarkModeMenuItemFactory,
|
||||
DialogMenuItemFactory,
|
||||
DisposeCurrentUnitMenuItemFactory,
|
||||
DisposeUniverItemFactory,
|
||||
FLOAT_DOM_ITEM_MENU_ID,
|
||||
FloatDomMenuItemFactory,
|
||||
LoadSheetSnapshotMenuItemFactory,
|
||||
LocaleMenuItemFactory,
|
||||
MessageMenuItemFactory,
|
||||
NotificationMenuItemFactory,
|
||||
SaveSnapshotSetEditableMenuItemFactory,
|
||||
SetEditableMenuItemFactory,
|
||||
ShowCellContentMenuItemFactory,
|
||||
SidebarMenuItemFactory,
|
||||
ThemeMenuItemFactory,
|
||||
UNIT_ITEM_MENU_ID,
|
||||
UnitMenuItemFactory,
|
||||
WatermarkMenuItemFactory,
|
||||
} from '../controllers/menu';
|
||||
|
||||
export const menuSchema: MenuSchemaType = {
|
||||
[RibbonOthersGroup.OTHERS]: {
|
||||
[LocaleOperation.id]: {
|
||||
order: 0,
|
||||
menuItemFactory: LocaleMenuItemFactory,
|
||||
},
|
||||
[DarkModeOperation.id]: {
|
||||
order: 0.9,
|
||||
menuItemFactory: DarkModeMenuItemFactory,
|
||||
},
|
||||
[ThemeOperation.id]: {
|
||||
order: 1,
|
||||
menuItemFactory: ThemeMenuItemFactory,
|
||||
},
|
||||
[NotificationOperation.id]: {
|
||||
order: 2,
|
||||
menuItemFactory: NotificationMenuItemFactory,
|
||||
},
|
||||
[DialogOperation.id]: {
|
||||
order: 3,
|
||||
menuItemFactory: DialogMenuItemFactory,
|
||||
},
|
||||
[ConfirmOperation.id]: {
|
||||
order: 4,
|
||||
menuItemFactory: ConfirmMenuItemFactory,
|
||||
},
|
||||
[MessageOperation.id]: {
|
||||
order: 5,
|
||||
menuItemFactory: MessageMenuItemFactory,
|
||||
},
|
||||
[SidebarOperation.id]: {
|
||||
order: 6,
|
||||
menuItemFactory: SidebarMenuItemFactory,
|
||||
},
|
||||
[SetEditable.id]: {
|
||||
order: 7,
|
||||
menuItemFactory: SetEditableMenuItemFactory,
|
||||
},
|
||||
[SaveSnapshotOptions.id]: {
|
||||
order: 8,
|
||||
menuItemFactory: SaveSnapshotSetEditableMenuItemFactory,
|
||||
[LoadSheetSnapshotCommand.id]: {
|
||||
order: 3,
|
||||
menuItemFactory: LoadSheetSnapshotMenuItemFactory,
|
||||
},
|
||||
},
|
||||
[UNIT_ITEM_MENU_ID]: {
|
||||
order: 9,
|
||||
menuItemFactory: UnitMenuItemFactory,
|
||||
[DisposeUniverCommand.id]: {
|
||||
order: 0,
|
||||
menuItemFactory: DisposeUniverItemFactory,
|
||||
},
|
||||
[DisposeCurrentUnitCommand.id]: {
|
||||
order: 1,
|
||||
menuItemFactory: DisposeCurrentUnitMenuItemFactory,
|
||||
},
|
||||
[CreateEmptySheetCommand.id]: {
|
||||
order: 2,
|
||||
menuItemFactory: CreateEmptySheetMenuItemFactory,
|
||||
},
|
||||
},
|
||||
[FLOAT_DOM_ITEM_MENU_ID]: {
|
||||
order: 10,
|
||||
menuItemFactory: FloatDomMenuItemFactory,
|
||||
[CreateFloatDomCommand.id]: {
|
||||
order: 0,
|
||||
menuItemFactory: CreateFloatDOMMenuItemFactory,
|
||||
},
|
||||
[ShowCellContentOperation.id]: {
|
||||
order: 1,
|
||||
menuItemFactory: ShowCellContentMenuItemFactory,
|
||||
},
|
||||
},
|
||||
[ChangeUserCommand.id]: {
|
||||
order: 11,
|
||||
menuItemFactory: ChangeUserMenuItemFactory,
|
||||
},
|
||||
[OpenWatermarkPanelOperation.id]: {
|
||||
order: 12,
|
||||
menuItemFactory: WatermarkMenuItemFactory,
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,365 +0,0 @@
|
||||
/**
|
||||
* 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 { IAccessor } from '@univerjs/core';
|
||||
import type { IMenuButtonItem, IMenuSelectorItem } from '@univerjs/ui';
|
||||
import { LocaleType } from '@univerjs/core';
|
||||
import { defaultTheme, greenTheme } from '@univerjs/themes';
|
||||
// import { defaultTheme } from '@univerjs/themes';
|
||||
import { MenuItemType } from '@univerjs/ui';
|
||||
import { CreateFloatDomCommand } from '../commands/commands/float-dom.command';
|
||||
import { CreateEmptySheetCommand, DisposeCurrentUnitCommand, DisposeUniverCommand, LoadSheetSnapshotCommand } from '../commands/commands/unit.command';
|
||||
import { ShowCellContentOperation } from '../commands/operations/cell.operation';
|
||||
import { ChangeUserCommand, UnitRole } from '../commands/operations/change-user.operation';
|
||||
import { ConfirmOperation } from '../commands/operations/confirm.operation';
|
||||
import { DarkModeOperation } from '../commands/operations/dark-mode.operation';
|
||||
import { DialogOperation } from '../commands/operations/dialog.operation';
|
||||
import { LocaleOperation } from '../commands/operations/locale.operation';
|
||||
import { MessageOperation } from '../commands/operations/message.operation';
|
||||
import { NotificationOperation } from '../commands/operations/notification.operation';
|
||||
import { OpenWatermarkPanelOperation } from '../commands/operations/open-watermark-panel.operation';
|
||||
import { SaveSnapshotOptions } from '../commands/operations/save-snapshot.operations';
|
||||
import { SetEditable } from '../commands/operations/set.editable.operation';
|
||||
import { SidebarOperation } from '../commands/operations/sidebar.operation';
|
||||
import { ThemeOperation } from '../commands/operations/theme.operation';
|
||||
import { UNIVER_WATERMARK_MENU } from './watermark.menu.controller';
|
||||
|
||||
export function LocaleMenuItemFactory(): IMenuSelectorItem {
|
||||
return {
|
||||
id: LocaleOperation.id,
|
||||
icon: 'VueI18nIcon',
|
||||
tooltip: 'i18n',
|
||||
type: MenuItemType.SELECTOR,
|
||||
selections: [
|
||||
{
|
||||
label: 'English',
|
||||
value: LocaleType.EN_US,
|
||||
},
|
||||
{
|
||||
label: 'Français',
|
||||
value: LocaleType.FR_FR,
|
||||
},
|
||||
{
|
||||
label: '简体中文',
|
||||
value: LocaleType.ZH_CN,
|
||||
},
|
||||
{
|
||||
label: 'Русский',
|
||||
value: LocaleType.RU_RU,
|
||||
},
|
||||
{
|
||||
label: '繁體中文',
|
||||
value: LocaleType.ZH_TW,
|
||||
},
|
||||
{
|
||||
label: 'Tiếng Việt',
|
||||
value: LocaleType.VI_VN,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function DarkModeMenuItemFactory(): IMenuSelectorItem {
|
||||
return {
|
||||
id: DarkModeOperation.id,
|
||||
title: '🌓',
|
||||
tooltip: 'Dark Mode',
|
||||
type: MenuItemType.SELECTOR,
|
||||
selections: [
|
||||
{
|
||||
label: 'Light',
|
||||
value: 'light',
|
||||
},
|
||||
{
|
||||
label: 'Dark',
|
||||
value: 'dark',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function ThemeMenuItemFactory(): IMenuSelectorItem {
|
||||
return {
|
||||
id: ThemeOperation.id,
|
||||
title: 'Theme',
|
||||
tooltip: 'Theme',
|
||||
type: MenuItemType.SELECTOR,
|
||||
selections: [
|
||||
{
|
||||
label: '🟢',
|
||||
value: greenTheme as any,
|
||||
},
|
||||
{
|
||||
label: '🔵',
|
||||
value: defaultTheme as any,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function NotificationMenuItemFactory(): IMenuSelectorItem {
|
||||
return {
|
||||
id: NotificationOperation.id,
|
||||
title: 'Notification',
|
||||
tooltip: 'Notification',
|
||||
type: MenuItemType.SELECTOR,
|
||||
selections: [
|
||||
{
|
||||
label: 'Notification Success',
|
||||
value: 'Notification Success random string to test Notification Success random string to test Notification Success random string to test Notification Success random string to test Notification Success random string to test',
|
||||
},
|
||||
{
|
||||
label: 'Notification Info',
|
||||
value: 'Notification Info',
|
||||
},
|
||||
{
|
||||
label: 'Notification Warning',
|
||||
value: 'Notification Warning',
|
||||
},
|
||||
{
|
||||
label: 'Notification Error',
|
||||
value: 'Notification Error',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function DialogMenuItemFactory(): IMenuSelectorItem {
|
||||
return {
|
||||
id: DialogOperation.id,
|
||||
title: 'Dialog',
|
||||
tooltip: 'Dialog',
|
||||
type: MenuItemType.SELECTOR,
|
||||
selections: [
|
||||
{
|
||||
label: 'Open Dialog',
|
||||
value: 'dialog',
|
||||
},
|
||||
{
|
||||
label: 'Draggable Dialog',
|
||||
value: 'draggable',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function ConfirmMenuItemFactory(): IMenuSelectorItem {
|
||||
return {
|
||||
id: ConfirmOperation.id,
|
||||
title: 'Confirm',
|
||||
tooltip: 'Confirm',
|
||||
type: MenuItemType.SELECTOR,
|
||||
selections: [
|
||||
{
|
||||
label: 'Open confirm',
|
||||
value: 'confirm',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function MessageMenuItemFactory(): IMenuSelectorItem {
|
||||
return {
|
||||
id: MessageOperation.id,
|
||||
title: 'Message',
|
||||
tooltip: 'Message',
|
||||
type: MenuItemType.SELECTOR,
|
||||
selections: [
|
||||
{
|
||||
label: 'Open message',
|
||||
value: '',
|
||||
},
|
||||
{
|
||||
label: 'Open loading message',
|
||||
value: 'loading',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function SidebarMenuItemFactory(accessor: IAccessor): IMenuSelectorItem {
|
||||
return {
|
||||
id: SidebarOperation.id,
|
||||
title: 'Sidebar',
|
||||
tooltip: 'Sidebar',
|
||||
type: MenuItemType.SELECTOR,
|
||||
selections: [
|
||||
{
|
||||
label: 'Open sidebar',
|
||||
value: 'open',
|
||||
},
|
||||
{
|
||||
label: 'Close sidebar',
|
||||
value: 'close',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function SetEditableMenuItemFactory(accessor: IAccessor): IMenuSelectorItem {
|
||||
return {
|
||||
id: SetEditable.id,
|
||||
title: 'Editable',
|
||||
tooltip: 'Editable',
|
||||
type: MenuItemType.SELECTOR,
|
||||
selections: [
|
||||
{
|
||||
label: 'changeUniverEditable',
|
||||
value: 'univer',
|
||||
},
|
||||
{
|
||||
label: 'changeSheetEditable',
|
||||
value: 'sheet',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function SaveSnapshotSetEditableMenuItemFactory(accessor: IAccessor): IMenuSelectorItem {
|
||||
return {
|
||||
id: SaveSnapshotOptions.id,
|
||||
type: MenuItemType.SELECTOR,
|
||||
title: 'Snapshot',
|
||||
selections: [
|
||||
{
|
||||
label: 'saveWorkbook',
|
||||
value: 'workbook',
|
||||
},
|
||||
{
|
||||
label: 'saveSheet',
|
||||
value: 'sheet',
|
||||
},
|
||||
{
|
||||
label: 'record',
|
||||
value: 'record',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export const UNIT_ITEM_MENU_ID = 'debugger.unit-menu-item';
|
||||
|
||||
export function UnitMenuItemFactory(): IMenuSelectorItem {
|
||||
return {
|
||||
id: UNIT_ITEM_MENU_ID,
|
||||
title: 'Dispose',
|
||||
tooltip: 'Lifecycle Related Commands',
|
||||
type: MenuItemType.SUBITEMS,
|
||||
};
|
||||
}
|
||||
|
||||
export function DisposeUniverItemFactory(): IMenuButtonItem {
|
||||
return {
|
||||
id: DisposeUniverCommand.id,
|
||||
title: 'Dispose Univer',
|
||||
tooltip: 'Dispose the Univer instance',
|
||||
icon: 'DS',
|
||||
type: MenuItemType.BUTTON,
|
||||
};
|
||||
}
|
||||
|
||||
export function DisposeCurrentUnitMenuItemFactory(): IMenuButtonItem {
|
||||
return {
|
||||
id: DisposeCurrentUnitCommand.id,
|
||||
title: 'Dispose Current Unit',
|
||||
tooltip: 'Dispose Current Unit',
|
||||
icon: 'DS',
|
||||
type: MenuItemType.BUTTON,
|
||||
};
|
||||
}
|
||||
|
||||
export function CreateEmptySheetMenuItemFactory(): IMenuButtonItem {
|
||||
return {
|
||||
id: CreateEmptySheetCommand.id,
|
||||
title: 'Create Another Sheet',
|
||||
tooltip: 'Create Another Sheet',
|
||||
icon: 'CR',
|
||||
type: MenuItemType.BUTTON,
|
||||
};
|
||||
}
|
||||
|
||||
export function LoadSheetSnapshotMenuItemFactory(): IMenuButtonItem {
|
||||
return {
|
||||
id: LoadSheetSnapshotCommand.id,
|
||||
title: 'Load Snapshot',
|
||||
tooltip: 'Load Snapshot',
|
||||
icon: 'CR',
|
||||
type: MenuItemType.BUTTON,
|
||||
};
|
||||
}
|
||||
|
||||
export const FLOAT_DOM_ITEM_MENU_ID = 'debugger.float-dom-menu-item';
|
||||
|
||||
export function FloatDomMenuItemFactory(): IMenuSelectorItem {
|
||||
return {
|
||||
id: FLOAT_DOM_ITEM_MENU_ID,
|
||||
title: 'FloatDom',
|
||||
tooltip: 'Float Dom Commands',
|
||||
type: MenuItemType.SUBITEMS,
|
||||
};
|
||||
}
|
||||
|
||||
export function CreateFloatDOMMenuItemFactory(): IMenuButtonItem {
|
||||
return {
|
||||
id: CreateFloatDomCommand.id,
|
||||
title: 'Create Float Dom',
|
||||
tooltip: 'Create Float Dom',
|
||||
icon: 'DS',
|
||||
type: MenuItemType.BUTTON,
|
||||
};
|
||||
}
|
||||
|
||||
export function ShowCellContentMenuItemFactory(): IMenuButtonItem {
|
||||
return {
|
||||
id: ShowCellContentOperation.id,
|
||||
type: MenuItemType.BUTTON,
|
||||
title: 'Cell',
|
||||
icon: 'DS',
|
||||
};
|
||||
}
|
||||
|
||||
export function ChangeUserMenuItemFactory(): IMenuSelectorItem {
|
||||
return {
|
||||
id: ChangeUserCommand.id,
|
||||
type: MenuItemType.SELECTOR,
|
||||
title: 'Change User',
|
||||
selections: [
|
||||
{
|
||||
label: 'Owner',
|
||||
value: UnitRole.Owner,
|
||||
},
|
||||
{
|
||||
label: 'Editor',
|
||||
value: UnitRole.Editor,
|
||||
},
|
||||
{
|
||||
label: 'Reader',
|
||||
value: UnitRole.Reader,
|
||||
},
|
||||
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function WatermarkMenuItemFactory(): IMenuButtonItem {
|
||||
return {
|
||||
id: OpenWatermarkPanelOperation.id,
|
||||
title: 'univer-watermark.title',
|
||||
tooltip: 'univer-watermark.title',
|
||||
icon: UNIVER_WATERMARK_MENU,
|
||||
type: MenuItemType.BUTTON,
|
||||
};
|
||||
}
|
||||
@@ -21,9 +21,7 @@ import { IRenderManagerService } from '@univerjs/engine-render';
|
||||
import { distinctUntilChanged, filter, take, takeUntil } from 'rxjs';
|
||||
|
||||
export class PerformanceMonitorController extends RxDisposable {
|
||||
private _initListener = false;
|
||||
private _containerElement!: HTMLDivElement;
|
||||
private _styleElement!: HTMLStyleElement;
|
||||
private _containerElement: HTMLDivElement | null;
|
||||
|
||||
private _currentUnitSub: Nullable<Subscription>;
|
||||
|
||||
@@ -45,9 +43,6 @@ export class PerformanceMonitorController extends RxDisposable {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
document.body.removeChild(this._containerElement);
|
||||
document.head.removeChild(this._styleElement);
|
||||
|
||||
this._disposeCurrentObserver();
|
||||
}
|
||||
|
||||
@@ -66,46 +61,16 @@ export class PerformanceMonitorController extends RxDisposable {
|
||||
}
|
||||
|
||||
private _listenToRenderer(unitId: string) {
|
||||
this._tryInit();
|
||||
|
||||
const renderer = this._renderManagerService.getRenderById(unitId);
|
||||
if (renderer) {
|
||||
const { engine } = renderer;
|
||||
this._currentUnitSub = engine.endFrame$.subscribe(() => {
|
||||
this._containerElement.textContent = `FPS: ${Math.round(engine.getFps()).toString()}`;
|
||||
if (!this._containerElement) {
|
||||
this._containerElement = document.querySelector('[data-u-comp=debugger-fps]');
|
||||
} else {
|
||||
this._containerElement.textContent = `FPS: ${Math.round(engine.getFps()).toString()}`;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _tryInit(): void {
|
||||
if (this._initListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._initListener = true;
|
||||
|
||||
const container = (this._containerElement = document.createElement('div'));
|
||||
this._containerElement = container;
|
||||
container.classList.add('fps-monitor');
|
||||
document.body.appendChild(container);
|
||||
|
||||
const style = `
|
||||
.fps-monitor {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 10px;
|
||||
width: 100px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
color: rgba(32, 32, 32, .8);
|
||||
font-size: 14px;
|
||||
font-family: sans-serif;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
`;
|
||||
|
||||
this._styleElement = document.createElement('style');
|
||||
document.head.appendChild(this._styleElement).textContent = style;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,12 +15,10 @@
|
||||
*/
|
||||
|
||||
import { Disposable, Inject } from '@univerjs/core';
|
||||
import { WatermarkSingle } from '@univerjs/icons';
|
||||
import { ComponentManager, IMenuManagerService } from '@univerjs/ui';
|
||||
import { WatermarkPanel } from '../views/watermark/WatermarkPanel';
|
||||
import { WatermarkPanelFooter } from '../views/watermark/WatermarkPanelFooter';
|
||||
|
||||
export const UNIVER_WATERMARK_MENU = 'UNIVER_WATERMARK_MENU';
|
||||
export const WATERMARK_PANEL = 'WATERMARK_PANEL';
|
||||
|
||||
export const WATERMARK_PANEL_FOOTER = 'WATERMARK_PANEL_FOOTER';
|
||||
@@ -36,7 +34,6 @@ export class UniverWatermarkMenuController extends Disposable {
|
||||
|
||||
private _initComponents() {
|
||||
([
|
||||
[UNIVER_WATERMARK_MENU, WatermarkSingle],
|
||||
[WATERMARK_PANEL, WatermarkPanel],
|
||||
[WATERMARK_PANEL_FOOTER, WatermarkPanelFooter],
|
||||
] as const).forEach(([key, component]) => {
|
||||
|
||||
@@ -18,7 +18,6 @@ import type { Dependency } from '@univerjs/core';
|
||||
import type { IUniverDebuggerConfig } from './controllers/config.schema';
|
||||
import { IConfigService, Inject, Injector, merge, Plugin, registerDependencies, touchDependencies } from '@univerjs/core';
|
||||
import { DEBUGGER_PLUGIN_CONFIG_KEY, defaultPluginConfig } from './controllers/config.schema';
|
||||
import { DarkModeController } from './controllers/dark-mode.controller';
|
||||
import { DebuggerController } from './controllers/debugger.controller';
|
||||
import { E2EController } from './controllers/e2e/e2e.controller';
|
||||
import { MultiUnitsController } from './controllers/multi-units/multi-units.controller';
|
||||
@@ -51,7 +50,6 @@ export class UniverDebuggerPlugin extends Plugin {
|
||||
|
||||
override onStarting(): void {
|
||||
const dependencies: Dependency[] = [
|
||||
[DarkModeController],
|
||||
[DebuggerController],
|
||||
[MultiUnitsController],
|
||||
[E2EController],
|
||||
@@ -66,7 +64,6 @@ export class UniverDebuggerPlugin extends Plugin {
|
||||
|
||||
touchDependencies(this._injector, [
|
||||
[E2EController],
|
||||
[DarkModeController],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* 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 { IDropdownMenuProps } from '@univerjs/design';
|
||||
import type { IUniverDebuggerConfig } from '../controllers/config.schema';
|
||||
import { IConfigService, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { borderClassName, clsx, DropdownMenu } from '@univerjs/design';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import { DEBUGGER_PLUGIN_CONFIG_KEY } from '../controllers/config.schema';
|
||||
import { useCellContent } from './use-cell-content';
|
||||
import { useDarkMode } from './use-dark-mode';
|
||||
import { useDialog } from './use-dialog';
|
||||
import { useDispose } from './use-dispose';
|
||||
import { useEditable } from './use-editable';
|
||||
import { useFloatingDom } from './use-floating-dom';
|
||||
import { useLocale } from './use-locale';
|
||||
import { useMessage } from './use-message';
|
||||
import { useNotification } from './use-notification';
|
||||
import { useSidebar } from './use-sidebar';
|
||||
import { useSnapshot } from './use-snapshot';
|
||||
import { useTheme } from './use-theme';
|
||||
import { useUser } from './use-user';
|
||||
import { useWatermark } from './use-watermark';
|
||||
|
||||
export function Fab() {
|
||||
const configService = useDependency(IConfigService);
|
||||
const univerInstanceService = useDependency(IUniverInstanceService);
|
||||
const unitType = univerInstanceService.getFocusedUnit()?.type;
|
||||
|
||||
const items: IDropdownMenuProps['items'] = [
|
||||
useLocale(),
|
||||
useDarkMode(),
|
||||
useTheme(),
|
||||
useWatermark(),
|
||||
{ type: 'separator' },
|
||||
useNotification(),
|
||||
useMessage(),
|
||||
useDialog(),
|
||||
useSidebar(),
|
||||
{ type: 'separator' },
|
||||
unitType === UniverInstanceType.UNIVER_SHEET && useFloatingDom(),
|
||||
unitType === UniverInstanceType.UNIVER_SHEET && useCellContent(),
|
||||
useSnapshot(),
|
||||
useEditable(),
|
||||
useUser(),
|
||||
useDispose(),
|
||||
].filter((item) => item !== null) as IDropdownMenuProps['items'];
|
||||
|
||||
const configs = configService.getConfig<IUniverDebuggerConfig>(DEBUGGER_PLUGIN_CONFIG_KEY);
|
||||
const performanceMonitor = configs?.performanceMonitor;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
univer-fixed univer-bottom-12 univer-right-8 univer-z-[9999] univer-flex univer-select-none
|
||||
univer-flex-col univer-items-center univer-gap-1
|
||||
`}
|
||||
>
|
||||
<DropdownMenu align="end" items={items}>
|
||||
<button
|
||||
className={clsx(`
|
||||
univer-flex univer-size-9 univer-cursor-pointer univer-items-center univer-justify-center
|
||||
univer-rounded-full univer-bg-white univer-text-base univer-text-gray-900 univer-shadow
|
||||
univer-outline-none univer-transition-shadow
|
||||
dark:!univer-bg-gray-900 dark:!univer-text-gray-200
|
||||
hover:univer-ring-1 hover:univer-ring-primary-400
|
||||
`, borderClassName)}
|
||||
type="button"
|
||||
>
|
||||
🏗️
|
||||
</button>
|
||||
</DropdownMenu>
|
||||
|
||||
{performanceMonitor?.enabled && (
|
||||
<span data-u-comp="debugger-fps" className="univer-text-xs univer-text-gray-400" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+16
-11
@@ -14,17 +14,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommandType, type ICommand, ILogService, IUniverInstanceService, ObjectMatrix, Range } from '@univerjs/core';
|
||||
import { ILogService, IUniverInstanceService, ObjectMatrix, Range } from '@univerjs/core';
|
||||
import { getSheetCommandTarget, SheetsSelectionsService } from '@univerjs/sheets';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
|
||||
export const ShowCellContentOperation: ICommand = {
|
||||
id: 'debugger.operation.show-cell-content',
|
||||
type: CommandType.OPERATION,
|
||||
handler(accessor) {
|
||||
const logService = accessor.get(ILogService);
|
||||
const selectionManagerService = accessor.get(SheetsSelectionsService);
|
||||
export function useCellContent() {
|
||||
const logService = useDependency(ILogService);
|
||||
const selectionManagerService = useDependency(SheetsSelectionsService);
|
||||
const univerInstanceService = useDependency(IUniverInstanceService);
|
||||
|
||||
const onSelect = () => {
|
||||
const selections = selectionManagerService.getCurrentSelections();
|
||||
const univerInstanceService = accessor.get(IUniverInstanceService);
|
||||
const target = getSheetCommandTarget(univerInstanceService);
|
||||
const matrix = new ObjectMatrix();
|
||||
selections.forEach((selection) => {
|
||||
@@ -33,6 +33,11 @@ export const ShowCellContentOperation: ICommand = {
|
||||
});
|
||||
});
|
||||
logService.debug('cell-content', matrix);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'item' as const,
|
||||
children: '🗒️ Console cell content',
|
||||
onSelect,
|
||||
};
|
||||
}
|
||||
+21
-18
@@ -14,31 +14,34 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ILocalStorageService, Inject, RxDisposable, ThemeService } from '@univerjs/core';
|
||||
import { ThemeService } from '@univerjs/core';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export class DarkModeController extends RxDisposable {
|
||||
constructor(
|
||||
@ILocalStorageService private _localStorageService: ILocalStorageService,
|
||||
@Inject(ThemeService) themeService: ThemeService
|
||||
) {
|
||||
super();
|
||||
export function useDarkMode() {
|
||||
const themeService = useDependency(ThemeService);
|
||||
|
||||
useEffect(() => {
|
||||
const darkMode = localStorage.getItem('local.darkMode');
|
||||
|
||||
if (darkMode === 'dark') {
|
||||
document.documentElement.classList.add('univer-dark');
|
||||
themeService.setDarkMode(true);
|
||||
} else if (darkMode === 'system') {
|
||||
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
darkModeMediaQuery.addEventListener('change', (e) => {
|
||||
if (e.matches) {
|
||||
document.documentElement.classList.add('univer-dark');
|
||||
themeService.setDarkMode(true);
|
||||
} else {
|
||||
document.documentElement.classList.remove('univer-dark');
|
||||
themeService.setDarkMode(false);
|
||||
}
|
||||
});
|
||||
themeService.setDarkMode(false);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
const onSelect = () => {
|
||||
const darkMode = themeService.darkMode ? 'light' : 'dark';
|
||||
|
||||
themeService.setDarkMode(darkMode === 'dark');
|
||||
localStorage.setItem('local.darkMode', darkMode);
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'item' as const,
|
||||
children: '🌓 Toggle dark mode',
|
||||
onSelect,
|
||||
};
|
||||
}
|
||||
+52
-17
@@ -14,21 +14,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { IAccessor, ICommand } from '@univerjs/core';
|
||||
import { CommandType } from '@univerjs/core';
|
||||
import { IDialogService } from '@univerjs/ui';
|
||||
import { IConfirmService, IDialogService, useDependency } from '@univerjs/ui';
|
||||
|
||||
export interface IUIComponentCommandParams {
|
||||
value: string;
|
||||
}
|
||||
const menu = [
|
||||
{
|
||||
label: 'Open dialog',
|
||||
value: 'dialog',
|
||||
},
|
||||
{
|
||||
label: 'Draggable dialog',
|
||||
value: 'draggable',
|
||||
},
|
||||
{
|
||||
label: 'Open confirm',
|
||||
value: 'confirm',
|
||||
},
|
||||
];
|
||||
|
||||
export const DialogOperation: ICommand = {
|
||||
id: 'debugger.operation.dialog',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor: IAccessor, params: IUIComponentCommandParams) => {
|
||||
const dialogService = accessor.get(IDialogService);
|
||||
const { value } = params;
|
||||
export function useDialog() {
|
||||
const dialogService = useDependency(IDialogService);
|
||||
const confirmService = useDependency(IConfirmService);
|
||||
|
||||
const onSelect = (value: string) => {
|
||||
if (value === 'draggable') {
|
||||
dialogService.open({
|
||||
id: 'draggable',
|
||||
@@ -47,7 +54,7 @@ export const DialogOperation: ICommand = {
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
} else if (value === 'dialog') {
|
||||
dialogService.open({
|
||||
id: 'dialog1',
|
||||
children: { title: 'Dialog Content' },
|
||||
@@ -63,8 +70,36 @@ export const DialogOperation: ICommand = {
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
} else if (value === 'confirm') {
|
||||
confirmService.open({
|
||||
id: 'confirm1',
|
||||
children: { title: 'Confirm Content' },
|
||||
title: { title: 'Confirm Title' },
|
||||
confirmText: 'hello',
|
||||
cancelText: 'world',
|
||||
onClose() {
|
||||
confirmService.close('confirm1');
|
||||
},
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
confirmService.open({
|
||||
id: 'confirm2',
|
||||
children: { title: 'Confirm2 Content' },
|
||||
title: { title: 'Confirm2 Title' },
|
||||
onClose() {
|
||||
confirmService.close('confirm2');
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'subItem' as const,
|
||||
children: '💬 Dialog & Confirm',
|
||||
options: menu.map((item) => ({
|
||||
type: 'item' as const,
|
||||
children: item.label,
|
||||
onSelect: () => onSelect(item.value),
|
||||
})),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* 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 { IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
|
||||
const menu = [
|
||||
{
|
||||
label: 'Dispose Univer',
|
||||
value: 'univer',
|
||||
},
|
||||
{
|
||||
label: 'Dispose current unit',
|
||||
value: 'unit',
|
||||
},
|
||||
{
|
||||
label: 'Create another sheet',
|
||||
value: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
export function useDispose() {
|
||||
const univerInstanceService = useDependency(IUniverInstanceService);
|
||||
|
||||
const onSelect = (value: string) => {
|
||||
if (value === 'univer') {
|
||||
window.univer?.dispose();
|
||||
window.univer = undefined;
|
||||
window.univerAPI = undefined;
|
||||
} else if (value === 'unit') {
|
||||
const focused = univerInstanceService.getFocusedUnit();
|
||||
if (!focused) return false;
|
||||
|
||||
return univerInstanceService.disposeUnit(focused.getUnitId());
|
||||
} else if (value === 'create') {
|
||||
univerInstanceService.createUnit(UniverInstanceType.UNIVER_SHEET, {});
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'subItem' as const,
|
||||
children: '🗑️ Dispose',
|
||||
options: menu.map((item) => ({
|
||||
type: 'item' as const,
|
||||
children: item.label,
|
||||
onSelect: () => onSelect(item.value),
|
||||
})),
|
||||
};
|
||||
}
|
||||
+30
-15
@@ -14,29 +14,35 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommandType, IPermissionService, IUniverInstanceService } from '@univerjs/core';
|
||||
import { IPermissionService, IUniverInstanceService } from '@univerjs/core';
|
||||
import { getSheetCommandTarget, WorkbookEditablePermission, WorksheetEditPermission } from '@univerjs/sheets';
|
||||
import type { IAccessor, ICommand } from '@univerjs/core';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
|
||||
export interface ISetEditableCommandParams {
|
||||
value: 'sheet' | 'univer';
|
||||
}
|
||||
const menu = [
|
||||
{
|
||||
label: 'Change workbook editable',
|
||||
value: 'univer',
|
||||
},
|
||||
{
|
||||
label: 'Change worksheet editable',
|
||||
value: 'sheet',
|
||||
},
|
||||
];
|
||||
|
||||
export const SetEditable: ICommand = {
|
||||
id: 'debugger.operation.set.editable',
|
||||
type: CommandType.OPERATION,
|
||||
handler: (accessor: IAccessor, params: ISetEditableCommandParams) => {
|
||||
const univerInstanceService = accessor.get(IUniverInstanceService);
|
||||
export function useEditable() {
|
||||
const univerInstanceService = useDependency(IUniverInstanceService);
|
||||
const permissionService = useDependency(IPermissionService);
|
||||
|
||||
const onSelect = (value: string) => {
|
||||
const target = getSheetCommandTarget(univerInstanceService);
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
const { workbook, worksheet, unitId, subUnitId } = target;
|
||||
const permissionService = accessor.get(IPermissionService);
|
||||
if (!workbook || !worksheet) {
|
||||
return false;
|
||||
}
|
||||
if (params.value === 'sheet') {
|
||||
if (value === 'sheet') {
|
||||
const editable = permissionService.getPermissionPoint(new WorksheetEditPermission(unitId, subUnitId).id);
|
||||
permissionService.updatePermissionPoint(new WorksheetEditPermission(unitId, subUnitId).id, !editable);
|
||||
} else {
|
||||
@@ -44,6 +50,15 @@ export const SetEditable: ICommand = {
|
||||
const editable = permissionService.getPermissionPoint(new WorkbookEditablePermission(unitId).id);
|
||||
permissionService.updatePermissionPoint(new WorkbookEditablePermission(unitId).id, !editable);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'subItem' as const,
|
||||
children: '✍️ Editable',
|
||||
options: menu.map((item) => ({
|
||||
type: 'item' as const,
|
||||
children: item.label,
|
||||
onSelect: () => onSelect(item.value),
|
||||
})),
|
||||
};
|
||||
}
|
||||
+15
-12
@@ -14,19 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { ICommand } from '@univerjs/core';
|
||||
import { CommandType, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { DocFloatDomController } from '@univerjs/docs-drawing-ui';
|
||||
import { SheetCanvasFloatDomManagerService } from '@univerjs/sheets-drawing-ui';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
|
||||
export const CreateFloatDomCommand: ICommand = {
|
||||
id: 'debugger.command.create-float-dom',
|
||||
type: CommandType.COMMAND,
|
||||
handler: (accessor) => {
|
||||
const univerInstanceService = accessor.get(IUniverInstanceService);
|
||||
export function useFloatingDom() {
|
||||
const univerInstanceService = useDependency(IUniverInstanceService);
|
||||
const floatDomService = useDependency(SheetCanvasFloatDomManagerService);
|
||||
const floatDomController = useDependency(DocFloatDomController);
|
||||
|
||||
const onSelect = () => {
|
||||
const currentSheet = univerInstanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_SHEET);
|
||||
if (currentSheet) {
|
||||
const floatDomService = accessor.get(SheetCanvasFloatDomManagerService);
|
||||
floatDomService.addFloatDomToPosition({
|
||||
allowTransform: true,
|
||||
initPosition: {
|
||||
@@ -41,7 +41,6 @@ export const CreateFloatDomCommand: ICommand = {
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const floatDomController = accessor.get(DocFloatDomController);
|
||||
floatDomController.insertFloatDom({
|
||||
allowTransform: true,
|
||||
componentKey: 'ImageDemo',
|
||||
@@ -52,7 +51,11 @@ export const CreateFloatDomCommand: ICommand = {
|
||||
height: 300,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
return {
|
||||
type: 'item' as const,
|
||||
children: '☁️ Create floating DOM',
|
||||
onSelect,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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 { LocaleService, LocaleType } from '@univerjs/core';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
const locales = [
|
||||
{
|
||||
label: 'English',
|
||||
value: LocaleType.EN_US,
|
||||
},
|
||||
{
|
||||
label: 'Français',
|
||||
value: LocaleType.FR_FR,
|
||||
},
|
||||
{
|
||||
label: '简体中文',
|
||||
value: LocaleType.ZH_CN,
|
||||
},
|
||||
{
|
||||
label: 'Русский',
|
||||
value: LocaleType.RU_RU,
|
||||
},
|
||||
{
|
||||
label: '繁體中文',
|
||||
value: LocaleType.ZH_TW,
|
||||
},
|
||||
{
|
||||
label: 'Tiếng Việt',
|
||||
value: LocaleType.VI_VN,
|
||||
},
|
||||
];
|
||||
|
||||
export function useLocale() {
|
||||
const localeService = useDependency(LocaleService);
|
||||
|
||||
useEffect(() => {
|
||||
const locale = localStorage.getItem('local.locale');
|
||||
if (locale) {
|
||||
localeService.setLocale(locale as LocaleType);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const onSelect = (value: string) => {
|
||||
localeService.setLocale(value as LocaleType);
|
||||
localStorage.setItem('local.locale', value);
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'subItem' as const,
|
||||
children: '🌐 Languages',
|
||||
options: locales.map((lang) => ({
|
||||
type: 'radio' as const,
|
||||
value: localeService.getCurrentLocale(),
|
||||
options: [{
|
||||
label: lang.label,
|
||||
value: lang.value,
|
||||
}],
|
||||
onSelect,
|
||||
})),
|
||||
};
|
||||
}
|
||||
+33
-20
@@ -14,33 +14,46 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { IAccessor, ICommand } from '@univerjs/core';
|
||||
import { CommandType } from '@univerjs/core';
|
||||
import { MessageType } from '@univerjs/design';
|
||||
import { IMessageService } from '@univerjs/ui';
|
||||
import { IMessageService, useDependency } from '@univerjs/ui';
|
||||
|
||||
export const MessageOperation: ICommand = {
|
||||
id: 'debugger.operation.message',
|
||||
type: CommandType.OPERATION,
|
||||
handler: async (accessor: IAccessor, params: { value: string }) => {
|
||||
const messageService = accessor.get(IMessageService);
|
||||
const menu = [
|
||||
{
|
||||
label: 'Open message',
|
||||
value: '',
|
||||
},
|
||||
{
|
||||
label: 'Open loading message',
|
||||
value: 'loading',
|
||||
},
|
||||
];
|
||||
|
||||
if (params.value === 'loading') {
|
||||
export function useMessage() {
|
||||
const messageService = useDependency(IMessageService);
|
||||
|
||||
const onSelect = (value: string) => {
|
||||
if (value === 'loading') {
|
||||
messageService.show({
|
||||
type: MessageType.Loading,
|
||||
content: 'Loading message',
|
||||
duration: 3000,
|
||||
});
|
||||
|
||||
return true;
|
||||
} else {
|
||||
messageService.show({
|
||||
type: MessageType.Success,
|
||||
content: 'Demo message',
|
||||
duration: 1500,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
messageService.show({
|
||||
type: MessageType.Success,
|
||||
content: 'Demo message',
|
||||
duration: 1500,
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
return {
|
||||
type: 'subItem' as const,
|
||||
children: '✉️ Message',
|
||||
options: menu.map((item) => ({
|
||||
type: 'item' as const,
|
||||
children: item.label,
|
||||
onSelect: () => onSelect(item.value),
|
||||
})),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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 { INotificationOptions } from '@univerjs/ui';
|
||||
import { INotificationService, useDependency } from '@univerjs/ui';
|
||||
|
||||
const menu = [
|
||||
{
|
||||
label: 'Notification success',
|
||||
value: 'success',
|
||||
},
|
||||
{
|
||||
label: 'Notification info',
|
||||
value: 'info',
|
||||
},
|
||||
{
|
||||
label: 'Notification warning',
|
||||
value: 'warning',
|
||||
},
|
||||
{
|
||||
label: 'Notification error',
|
||||
value: 'error',
|
||||
},
|
||||
];
|
||||
|
||||
export function useNotification() {
|
||||
const notificationService = useDependency(INotificationService);
|
||||
|
||||
const onSelect = (value: string) => {
|
||||
notificationService.show({
|
||||
type: value as INotificationOptions['type'],
|
||||
content: 'Lorem Ipusm dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
|
||||
title: 'Notification Title',
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'subItem' as const,
|
||||
children: '🔔 Notification',
|
||||
options: menu.map((item) => ({
|
||||
type: 'item' as const,
|
||||
children: item.label,
|
||||
onSelect: () => onSelect(item.value),
|
||||
})),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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 { ISidebarService, useDependency } from '@univerjs/ui';
|
||||
import { TEST_EDITOR_CONTAINER_COMPONENT } from './test-editor/component-name';
|
||||
|
||||
const menu = [
|
||||
{
|
||||
label: 'Open sidebar',
|
||||
value: 'open',
|
||||
},
|
||||
{
|
||||
label: 'Close sidebar',
|
||||
value: 'close',
|
||||
},
|
||||
];
|
||||
|
||||
export function useSidebar() {
|
||||
const sidebarService = useDependency(ISidebarService);
|
||||
|
||||
const onSelect = (value: string) => {
|
||||
if (value === 'open') {
|
||||
sidebarService.open({
|
||||
header: { title: 'Sidebar title' },
|
||||
children: { label: TEST_EDITOR_CONTAINER_COMPONENT },
|
||||
footer: { title: 'Sidebar Footer' },
|
||||
onClose: () => {
|
||||
},
|
||||
});
|
||||
} else if (value === 'close') {
|
||||
sidebarService.close();
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'subItem' as const,
|
||||
children: '🧩 Sidebar',
|
||||
options: menu.map((item) => ({
|
||||
type: 'item' as const,
|
||||
children: item.label,
|
||||
onSelect: () => onSelect(item.value),
|
||||
})),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* eslint-disable node/prefer-global/process */
|
||||
import type { DocumentDataModel, IStyleData, IWorkbookData, Workbook } from '@univerjs/core';
|
||||
import { IResourceLoaderService, IUniverInstanceService, ObjectMatrix, UniverInstanceType } from '@univerjs/core';
|
||||
import { ILocalFileService, useDependency } from '@univerjs/ui';
|
||||
import { RecordController } from '../controllers/local-save/record.controller';
|
||||
|
||||
const menu = [
|
||||
{
|
||||
label: 'Save workbook',
|
||||
value: 'workbook',
|
||||
},
|
||||
{
|
||||
label: 'Save worksheet',
|
||||
value: 'sheet',
|
||||
},
|
||||
{
|
||||
label: 'Record',
|
||||
value: 'record',
|
||||
},
|
||||
{
|
||||
label: 'Load snapshot',
|
||||
value: 'load',
|
||||
},
|
||||
];
|
||||
|
||||
export interface ISaveSnapshotParams {
|
||||
value: 'sheet' | 'workbook' | 'record';
|
||||
}
|
||||
|
||||
const filterStyle = (workbookData: IWorkbookData) => {
|
||||
const sheets = workbookData.sheets;
|
||||
const cacheStyle: Record<string, IStyleData> = {};
|
||||
Object.keys(sheets).forEach((sheetId) => {
|
||||
const sheet = sheets[sheetId];
|
||||
new ObjectMatrix(sheet.cellData).forValue((_r, _c, value) => {
|
||||
const s = value?.s;
|
||||
if (s && typeof s === 'string') {
|
||||
const style = workbookData.styles[s];
|
||||
if (style) {
|
||||
cacheStyle[s] = style;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
workbookData.styles = cacheStyle;
|
||||
return workbookData;
|
||||
};
|
||||
|
||||
export function useSnapshot() {
|
||||
const univerInstanceService = useDependency(IUniverInstanceService);
|
||||
const resourceLoaderService = useDependency(IResourceLoaderService);
|
||||
const localFileService = useDependency(ILocalFileService);
|
||||
const recordController = useDependency(RecordController);
|
||||
|
||||
const onSelect = async (value: string) => {
|
||||
const preName = new Date().toLocaleString();
|
||||
const workbook = univerInstanceService.getCurrentUnitOfType<Workbook>(UniverInstanceType.UNIVER_SHEET)!;
|
||||
if (!workbook) {
|
||||
const doc = univerInstanceService.getCurrentUnitOfType<DocumentDataModel>(UniverInstanceType.UNIVER_DOC)!;
|
||||
const snapshot = resourceLoaderService.saveUnit(doc.getUnitId());
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
const gitHash = process.env.GIT_COMMIT_HASH;
|
||||
const gitBranch = process.env.GIT_REF_NAME;
|
||||
const buildTime = process.env.BUILD_TIME;
|
||||
(snapshot as any).__env__ = { gitHash, gitBranch, buildTime };
|
||||
}
|
||||
const text = JSON.stringify(snapshot, null, 2);
|
||||
localFileService.downloadFile(new Blob([text]), `${preName} snapshot.json`);
|
||||
return true;
|
||||
}
|
||||
|
||||
const worksheet = workbook.getActiveSheet();
|
||||
if (!worksheet) {
|
||||
return false;
|
||||
}
|
||||
const snapshot = resourceLoaderService.saveUnit<ReturnType<typeof workbook.getSnapshot>>(workbook.getUnitId())!;
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
const gitHash = process.env.GIT_COMMIT_HASH;
|
||||
const gitBranch = process.env.GIT_REF_NAME;
|
||||
const buildTime = process.env.BUILD_TIME;
|
||||
(snapshot as any).__env__ = { gitHash, gitBranch, buildTime };
|
||||
}
|
||||
|
||||
if (value === 'sheet') {
|
||||
const sheetId = worksheet.getSheetId();
|
||||
const sheet = snapshot.sheets[sheetId];
|
||||
snapshot.sheets = { [sheetId]: sheet };
|
||||
snapshot.sheetOrder = [sheetId];
|
||||
const text = JSON.stringify(filterStyle(snapshot), null, 2);
|
||||
localFileService.downloadFile(new Blob([text]), `${preName} snapshot.json`);
|
||||
} else if (value === 'workbook') {
|
||||
const text = JSON.stringify(filterStyle(snapshot), null, 2);
|
||||
localFileService.downloadFile(new Blob([text]), `${preName} snapshot.json`);
|
||||
} else if (value === 'record') {
|
||||
let endCommands = () => [];
|
||||
|
||||
recordController.record().subscribe((v) => {
|
||||
if (v.type === 'start') {
|
||||
endCommands = recordController.startSaveCommands() as any;
|
||||
}
|
||||
if (v.type === 'finish') {
|
||||
const commands = endCommands();
|
||||
localFileService.downloadFile(v.data, `${preName} video.webm`);
|
||||
localFileService.downloadFile(new Blob([JSON.stringify(commands, null, 2)]), `${preName} commands.json`);
|
||||
}
|
||||
});
|
||||
} else if (value === 'load') {
|
||||
const snapshotFile = await localFileService.openFile({ multiple: false, accept: '.json' });
|
||||
if (snapshotFile.length !== 1) return false;
|
||||
|
||||
const text = await snapshotFile[0].text();
|
||||
univerInstanceService.createUnit<IWorkbookData, Workbook>(UniverInstanceType.UNIVER_SHEET, JSON.parse(text));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'subItem' as const,
|
||||
children: '📷 Snapshot',
|
||||
options: menu.map((item) => ({
|
||||
type: 'item' as const,
|
||||
children: item.label,
|
||||
onSelect: () => onSelect(item.value),
|
||||
})),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* 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 { ThemeService } from '@univerjs/core';
|
||||
import { defaultTheme, greenTheme } from '@univerjs/themes';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
const themes = [
|
||||
{
|
||||
label: '🟢',
|
||||
value: greenTheme,
|
||||
},
|
||||
{
|
||||
label: '🔵',
|
||||
value: defaultTheme,
|
||||
},
|
||||
];
|
||||
|
||||
export function useTheme() {
|
||||
const themeService = useDependency(ThemeService);
|
||||
|
||||
useEffect(() => {
|
||||
const themeKey = localStorage.getItem('local.theme');
|
||||
|
||||
const theme = themes.find((theme) => theme.label === themeKey);
|
||||
|
||||
if (theme) {
|
||||
themeService.setTheme(theme.value);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const onSelect = (value: string) => {
|
||||
localStorage.setItem('local.theme', value);
|
||||
|
||||
const theme = themes.find((theme) => theme.label === value);
|
||||
|
||||
if (theme) {
|
||||
themeService.setTheme(theme.value);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'subItem' as const,
|
||||
children: '🎨 Themes',
|
||||
options: themes.map((theme) => ({
|
||||
type: 'item' as const,
|
||||
children: theme.label,
|
||||
onSelect: () => onSelect(theme.label),
|
||||
})),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 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 { Workbook } from '@univerjs/core';
|
||||
import { createDefaultUser, IPermissionService, IUniverInstanceService, UniverInstanceType, UserManagerService } from '@univerjs/core';
|
||||
import { WorkbookManageCollaboratorPermission } from '@univerjs/sheets';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
|
||||
enum UnitRole {
|
||||
Reader = 0,
|
||||
Editor = 1,
|
||||
Owner = 2,
|
||||
UNRECOGNIZED = -1,
|
||||
}
|
||||
|
||||
const menu = [
|
||||
{
|
||||
label: 'Owner',
|
||||
value: UnitRole.Owner,
|
||||
},
|
||||
{
|
||||
label: 'Editor',
|
||||
value: UnitRole.Editor,
|
||||
},
|
||||
{
|
||||
label: 'Reader',
|
||||
value: UnitRole.Reader,
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
export function useUser() {
|
||||
const univerInstanceService = useDependency(IUniverInstanceService);
|
||||
const userManagerService = useDependency(UserManagerService);
|
||||
const permissionService = useDependency(IPermissionService);
|
||||
|
||||
const onSelect = (value: UnitRole) => {
|
||||
userManagerService.setCurrentUser(createDefaultUser(value));
|
||||
const workbook = univerInstanceService.getCurrentUnitOfType<Workbook>(UniverInstanceType.UNIVER_SHEET)!;
|
||||
const unitId = workbook.getUnitId();
|
||||
if (value === UnitRole.Owner) {
|
||||
permissionService.updatePermissionPoint(new WorkbookManageCollaboratorPermission(unitId).id, true);
|
||||
} else {
|
||||
permissionService.updatePermissionPoint(new WorkbookManageCollaboratorPermission(unitId).id, false);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'subItem' as const,
|
||||
children: '👥 Change user\'s role',
|
||||
options: menu.map((item) => ({
|
||||
type: 'item' as const,
|
||||
children: item.label,
|
||||
onSelect: () => onSelect(item.value),
|
||||
})),
|
||||
};
|
||||
}
|
||||
+14
-13
@@ -14,18 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { ICommand } from '@univerjs/core';
|
||||
import { CommandType, LocaleService } from '@univerjs/core';
|
||||
import { ISidebarService } from '@univerjs/ui';
|
||||
import { WATERMARK_PANEL, WATERMARK_PANEL_FOOTER } from '../../controllers/watermark.menu.controller';
|
||||
import { LocaleService } from '@univerjs/core';
|
||||
import { ISidebarService, useDependency } from '@univerjs/ui';
|
||||
import { WATERMARK_PANEL, WATERMARK_PANEL_FOOTER } from '../controllers/watermark.menu.controller';
|
||||
|
||||
export const OpenWatermarkPanelOperation: ICommand = {
|
||||
type: CommandType.OPERATION,
|
||||
id: 'univer.operation.open-watermark-panel',
|
||||
handler(accessor) {
|
||||
const sidebarService = accessor.get(ISidebarService);
|
||||
const localeService = accessor.get(LocaleService);
|
||||
export function useWatermark() {
|
||||
const sidebarService = useDependency(ISidebarService);
|
||||
const localeService = useDependency(LocaleService);
|
||||
|
||||
const onSelect = () => {
|
||||
sidebarService.open({
|
||||
header: { title: localeService.t('univer-watermark.title') },
|
||||
children: { label: WATERMARK_PANEL },
|
||||
@@ -33,7 +30,11 @@ export const OpenWatermarkPanelOperation: ICommand = {
|
||||
onClose: () => { },
|
||||
width: 330,
|
||||
});
|
||||
};
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
return {
|
||||
type: 'item' as const,
|
||||
children: '🌊 Watermark Settings',
|
||||
onSelect,
|
||||
};
|
||||
}
|
||||
@@ -102,21 +102,32 @@ export function WatermarkTextSetting(props: IWatermarkTextSettingProps) {
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<a className="hover:univer-bg-gray-100">
|
||||
<a
|
||||
className={`
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`}
|
||||
>
|
||||
<FontColor extend={{ colorChannel1: config.color ?? '#2c53f1' }} />
|
||||
</a>
|
||||
</Dropdown>
|
||||
<a
|
||||
className={clsx('hover:univer-bg-gray-100', {
|
||||
'univer-bg-gray-200': config.bold,
|
||||
className={clsx(`
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`, {
|
||||
'univer-bg-gray-200 dark:!univer-bg-gray-600': config.bold,
|
||||
})}
|
||||
onClick={() => { onChange({ ...config, bold: !config.bold }); }}
|
||||
>
|
||||
<BoldSingle />
|
||||
</a>
|
||||
<a
|
||||
className={clsx('hover:univer-bg-gray-100', {
|
||||
'univer-bg-gray-200': config.italic,
|
||||
className={clsx(`
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`, {
|
||||
'univer-bg-gray-200 dark:!univer-bg-gray-600': config.italic,
|
||||
})}
|
||||
onClick={() => { onChange({ ...config, italic: !config.italic }); }}
|
||||
>
|
||||
|
||||
@@ -102,6 +102,7 @@ export function UniSheetBar() {
|
||||
className={clsx(`
|
||||
univer-flex univer-h-8 univer-cursor-pointer univer-items-center univer-rounded-lg
|
||||
univer-px-1 univer-py-0
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`, activeKey === item.sheetId ? 'univer-text-primary-500' : '')}
|
||||
onClick={() => handleSheetActiveChange(item.sheetId)}
|
||||
@@ -125,6 +126,7 @@ export function UniSheetBar() {
|
||||
univer-rounded-lg univer-border-0 univer-bg-transparent univer-text-primary-600
|
||||
before:absolute before:left-0 before:top-0 before:h-full before:w-full before:bg-gray-100
|
||||
before:content-['']
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-cursor-pointer hover:univer-bg-gray-100
|
||||
`}
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ export function UniSlideSideBar() {
|
||||
univer-justify-center univer-rounded-lg univer-border-0 univer-bg-transparent univer-px-1
|
||||
univer-text-primary-500
|
||||
before:absolute before:left-0 before:top-0 before:h-px before:content-[''] before:univer-bg-gray-200
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`}
|
||||
onClick={handleAppendSlide}
|
||||
|
||||
@@ -155,6 +155,7 @@ export const UniControls = ({ zoom, onItemClick }: { zoom: number; onItemClick?:
|
||||
`,
|
||||
`
|
||||
univer-rounded univer-no-underline univer-transition-colors univer-duration-200
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`,
|
||||
item === zoomPercent ? 'univer-bg-gray-100' : ''
|
||||
|
||||
@@ -20,10 +20,14 @@ import {
|
||||
DropdownMenuCheckboxItem,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuPortal,
|
||||
DropdownMenuPrimitive,
|
||||
DropdownMenuRadioGroup,
|
||||
DropdownMenuRadioItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuSub,
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuTrigger,
|
||||
} from './DropdownMenuPrimitive';
|
||||
|
||||
@@ -35,6 +39,15 @@ interface IDropdownMenuNormalItem {
|
||||
onSelect?: (item: DropdownMenuType) => void;
|
||||
}
|
||||
|
||||
interface IDropdownMenuNormalSubItem {
|
||||
type: 'subItem';
|
||||
className?: string;
|
||||
children: ReactNode;
|
||||
options?: DropdownMenuType[];
|
||||
disabled?: boolean;
|
||||
onSelect?: (item: DropdownMenuType) => void;
|
||||
}
|
||||
|
||||
interface IDropdownMenuSeparatorItem {
|
||||
type: 'separator';
|
||||
className?: string;
|
||||
@@ -65,7 +78,7 @@ interface IDropdownMenuCheckItem {
|
||||
onSelect?: (item: string) => void;
|
||||
}
|
||||
|
||||
type DropdownMenuType = IDropdownMenuNormalItem | IDropdownMenuSeparatorItem | IDropdownMenuRadioItem | IDropdownMenuCheckItem;
|
||||
type DropdownMenuType = IDropdownMenuNormalItem | IDropdownMenuNormalSubItem | IDropdownMenuSeparatorItem | IDropdownMenuRadioItem | IDropdownMenuCheckItem;
|
||||
|
||||
export interface IDropdownMenuProps extends ComponentProps<typeof DropdownMenuContent> {
|
||||
children: ReactNode;
|
||||
@@ -164,6 +177,19 @@ export function DropdownMenu(props: IDropdownMenuProps) {
|
||||
{item.children}
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
} else if (type === 'subItem') {
|
||||
return (
|
||||
<DropdownMenuSub key={index}>
|
||||
<DropdownMenuSubTrigger>{item.children}</DropdownMenuSubTrigger>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuSubContent sideOffset={12}>
|
||||
{item.options?.map((subItem, subIndex) => (
|
||||
renderMenuItem(subItem, subIndex)
|
||||
))}
|
||||
</DropdownMenuSubContent>
|
||||
</DropdownMenuPortal>
|
||||
</DropdownMenuSub>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ function DropdownMenuSubTrigger({
|
||||
univer-flex univer-cursor-default univer-select-none univer-items-center univer-justify-between
|
||||
univer-gap-2 univer-rounded univer-px-2 univer-py-1.5 univer-text-sm univer-outline-none
|
||||
[&_svg]:univer-pointer-events-none [&_svg]:univer-size-4 [&_svg]:univer-shrink-0
|
||||
dark:focus:!univer-bg-gray-600
|
||||
dark:focus:!univer-bg-gray-600 dark:data-[state=open]:!univer-bg-gray-600
|
||||
data-[state=open]:univer-bg-gray-100
|
||||
focus:univer-bg-gray-100
|
||||
`,
|
||||
@@ -330,7 +330,10 @@ function DropdownMenuSeparator({
|
||||
}: ComponentProps<typeof Separator>) {
|
||||
return (
|
||||
<Separator
|
||||
className={clsx('-univer-mx-1 univer-my-1 univer-h-px univer-bg-gray-200', className)}
|
||||
className={clsx(`
|
||||
-univer-mx-1 univer-my-1 univer-h-px univer-bg-gray-200
|
||||
dark:!univer-bg-gray-600
|
||||
`, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -57,6 +57,7 @@ export const Playground = {
|
||||
<a
|
||||
className={clsx(`
|
||||
univer-cursor-pointer univer-rounded-lg univer-px-4 univer-py-2 univer-transition-all
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`, borderClassName)}
|
||||
>
|
||||
|
||||
@@ -58,6 +58,7 @@ export const Playground = {
|
||||
<a
|
||||
className={clsx(`
|
||||
univer-cursor-pointer univer-rounded-lg univer-px-4 univer-py-2 univer-transition-all
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`, borderClassName)}
|
||||
>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import type { ComponentProps, ReactNode } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { HoverCardContent, HoverCardPrimitive, HoverCardTrigger } from './HoverCardPrimitive';
|
||||
import { HoverCardContent, HoverCardPortal, HoverCardPrimitive, HoverCardTrigger } from './HoverCardPrimitive';
|
||||
|
||||
export interface IHoverCardProps extends ComponentProps<typeof HoverCardContent> {
|
||||
children: ReactNode;
|
||||
@@ -60,9 +60,11 @@ export function HoverCard(props: IHoverCardProps) {
|
||||
return (
|
||||
<HoverCardPrimitive open={open} onOpenChange={handleChangeOpen} openDelay={openDelay}>
|
||||
<HoverCardTrigger asChild>{children}</HoverCardTrigger>
|
||||
<HoverCardContent {...restProps}>
|
||||
{overlay}
|
||||
</HoverCardContent>
|
||||
<HoverCardPortal>
|
||||
<HoverCardContent {...restProps}>
|
||||
{overlay}
|
||||
</HoverCardContent>
|
||||
</HoverCardPortal>
|
||||
</HoverCardPrimitive>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,13 +15,15 @@
|
||||
*/
|
||||
|
||||
import type { ComponentPropsWithoutRef, ElementRef } from 'react';
|
||||
import { Content, Root, Trigger } from '@radix-ui/react-hover-card';
|
||||
import { Content, Portal, Root, Trigger } from '@radix-ui/react-hover-card';
|
||||
import { forwardRef } from 'react';
|
||||
import { borderClassName } from '../../helper/class-utilities';
|
||||
import { clsx } from '../../helper/clsx';
|
||||
|
||||
const HoverCardPrimitive = Root;
|
||||
|
||||
const HoverCardPortal = Portal;
|
||||
|
||||
const HoverCardTrigger = Trigger;
|
||||
|
||||
const HoverCardContent = forwardRef<
|
||||
@@ -36,7 +38,7 @@ const HoverCardContent = forwardRef<
|
||||
`
|
||||
univer-z-[1080] univer-w-64 univer-origin-[--radix-hover-card-content-transform-origin] univer-rounded-md
|
||||
univer-bg-white univer-text-gray-900 univer-shadow-md univer-outline-none
|
||||
dark:univer-bg-gray-900 dark:univer-text-white
|
||||
dark:!univer-bg-gray-900 dark:!univer-text-white
|
||||
data-[side=bottom]:univer-slide-in-from-top-2
|
||||
data-[side=left]:univer-slide-in-from-right-2
|
||||
data-[side=right]:univer-slide-in-from-left-2
|
||||
@@ -54,4 +56,4 @@ const HoverCardContent = forwardRef<
|
||||
|
||||
HoverCardContent.displayName = Content.displayName;
|
||||
|
||||
export { HoverCardContent, HoverCardPrimitive, HoverCardTrigger };
|
||||
export { HoverCardContent, HoverCardPortal, HoverCardPrimitive, HoverCardTrigger };
|
||||
|
||||
@@ -79,10 +79,11 @@ export const QuickInsertButton = ({ className = '' }: IQuickInsertButtonProps) =
|
||||
className={clsx(`
|
||||
univer-mr-1 univer-flex univer-cursor-pointer univer-items-center univer-gap-2.5 univer-rounded-full
|
||||
univer-p-1.5 univer-shadow-sm
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`, borderClassName, {
|
||||
'univer-bg-gray-100': editPopup,
|
||||
'univer-bg-white': !editPopup,
|
||||
'univer-bg-gray-100 dark:!univer-bg-gray-700': editPopup,
|
||||
'univer-bg-white dark:univer-bg-gray-900': !editPopup,
|
||||
}, className)}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
|
||||
@@ -50,6 +50,7 @@ export const ColorPicker = (props: IColorPickerProps) => {
|
||||
<span
|
||||
className={clsx(`
|
||||
univer-flex univer-cursor-pointer univer-items-center univer-rounded univer-p-1
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`, className)}
|
||||
>
|
||||
|
||||
@@ -129,6 +129,7 @@ const IconGroupList = forwardRef<HTMLDivElement, IIconGroupListProps>((props, re
|
||||
<a
|
||||
className={`
|
||||
univer-cursor-pointer univer-rounded
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`}
|
||||
>
|
||||
@@ -192,6 +193,7 @@ const IconItemList = (props: { onClick: (iconType: IIconType, iconId: string) =>
|
||||
className={`
|
||||
univer-mb-2 univer-mr-2 univer-flex univer-cursor-pointer univer-items-center
|
||||
univer-justify-center univer-rounded
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`}
|
||||
>
|
||||
|
||||
@@ -381,9 +381,10 @@ export const RuleList = (props: IRuleListProps) => {
|
||||
className={clsx(`
|
||||
univer-group univer-relative univer-flex univer-items-center
|
||||
univer-justify-between univer-rounded univer-py-2 univer-pl-5 univer-pr-8
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`, {
|
||||
'univer-bg-gray-100': draggingId === index,
|
||||
'univer-bg-gray-100 dark:!univer-bg-gray-700': draggingId === index,
|
||||
})}
|
||||
onMouseMove={() => {
|
||||
rule.ranges !== currentRuleRanges && currentRuleRangesSet(rule.ranges);
|
||||
|
||||
+1
@@ -417,6 +417,7 @@ export function ListFormulaInput(props: IFormulaInputProps) {
|
||||
className={`
|
||||
univer-flex univer-w-fit univer-cursor-pointer univer-flex-row univer-items-center
|
||||
univer-rounded univer-p-1 univer-px-2 univer-text-sm univer-text-primary
|
||||
dark:hover:!univer-bg-gray-800
|
||||
hover:univer-bg-primary-50
|
||||
`}
|
||||
onClick={handleAdd}
|
||||
|
||||
@@ -130,6 +130,7 @@ export function HelpFunction(props: IHelpFunctionProps) {
|
||||
className={clsx(`
|
||||
univer-m-0 univer-box-border univer-w-[250px] univer-select-none univer-list-none
|
||||
univer-rounded-lg univer-bg-white univer-leading-5 univer-shadow-md univer-outline-none
|
||||
dark:univer-bg-gray-900
|
||||
`, borderClassName)}
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -256,6 +256,7 @@ export function SortOptionItem(props: ISortOptionItemProps) {
|
||||
univer-relative univer-box-border univer-flex univer-h-7 univer-cursor-pointer
|
||||
univer-list-none univer-items-center univer-justify-between univer-rounded
|
||||
univer-px-2 univer-text-sm univer-transition-all
|
||||
dark:hover:!univer-bg-gray-700
|
||||
hover:univer-bg-gray-100
|
||||
`}
|
||||
>
|
||||
|
||||
@@ -116,8 +116,8 @@ export function Sidebar() {
|
||||
<section
|
||||
data-u-comp="sidebar"
|
||||
className={clsx(`
|
||||
univer-relative univer-h-full univer-bg-white
|
||||
dark:!univer-bg-gray-900
|
||||
univer-relative univer-h-full univer-bg-white univer-text-gray-900
|
||||
dark:!univer-bg-gray-900 dark:!univer-text-white
|
||||
`, {
|
||||
'univer-w-96 univer-translate-x-0': options?.visible,
|
||||
'univer-w-0 univer-translate-x-full': !options?.visible,
|
||||
@@ -141,7 +141,13 @@ export function Sidebar() {
|
||||
>
|
||||
{options?.header}
|
||||
|
||||
<a className="univer-cursor-pointer univer-text-gray-500" onClick={handleClose}>
|
||||
<a
|
||||
className={`
|
||||
univer-cursor-pointer univer-text-gray-500
|
||||
dark:!univer-text-gray-300
|
||||
`}
|
||||
onClick={handleClose}
|
||||
>
|
||||
<CloseSingle />
|
||||
</a>
|
||||
</header>
|
||||
|
||||
Generated
-7
@@ -612,9 +612,6 @@ importers:
|
||||
'@univerjs/docs-drawing-ui':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/docs-drawing-ui
|
||||
'@univerjs/docs-ui':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/docs-ui
|
||||
'@univerjs/engine-render':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/engine-render
|
||||
@@ -664,10 +661,6 @@ importers:
|
||||
vitest:
|
||||
specifier: ^3.1.3
|
||||
version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.18)(happy-dom@17.4.7)(jiti@2.4.2)(jsdom@26.1.0)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.4)(yaml@2.7.1)
|
||||
optionalDependencies:
|
||||
vue:
|
||||
specifier: '>=3.0.0'
|
||||
version: 3.5.13(typescript@5.8.3)
|
||||
|
||||
packages-experimental/uni-docs-ui:
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user