From 4b4c800cf7d097d2a76273588c4427d801e3e0d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E7=86=B1?= Date: Wed, 21 May 2025 18:07:10 +0800 Subject: [PATCH] feat: add simple mode for Ribbon (#5243) --- .../operations/dropdown-list.operation.ts | 36 ------ .../operations/single-button.operation.ts | 27 ---- .../controllers/custom-menu.controller.ts | 118 ------------------ .../controllers/menu/dropdown-list.menu.ts | 51 -------- .../controllers/menu/single-button.menu.ts | 34 ----- examples/src/sheets/custom-menu/index.ts | 17 --- .../src/sheets/custom-menu/locale/en-US.ts | 26 ---- .../src/sheets/custom-menu/locale/zh-CN.ts | 26 ---- examples/src/sheets/custom-menu/plugin.ts | 53 -------- examples/src/sheets/main.ts | 3 +- .../src/controllers/debugger.controller.ts | 4 +- .../multi-units/multi-units.controller.ts | 43 ------- .../multi-units/multi-units.menu.ts | 62 --------- packages-experimental/debugger/src/plugin.ts | 3 - .../debugger/src/views/Fab.tsx | 4 + .../debugger/src/views/use-dispose.ts | 8 +- .../debugger/src/views/use-units.ts | 66 ++++++++++ .../ui/src/controllers/ui/ui.controller.ts | 4 + .../ui/src/views/components/ribbon/Ribbon.tsx | 46 +++++-- packages/ui/src/views/workbench/Workbench.tsx | 2 + 20 files changed, 114 insertions(+), 519 deletions(-) delete mode 100644 examples/src/sheets/custom-menu/commands/operations/dropdown-list.operation.ts delete mode 100644 examples/src/sheets/custom-menu/commands/operations/single-button.operation.ts delete mode 100644 examples/src/sheets/custom-menu/controllers/custom-menu.controller.ts delete mode 100644 examples/src/sheets/custom-menu/controllers/menu/dropdown-list.menu.ts delete mode 100644 examples/src/sheets/custom-menu/controllers/menu/single-button.menu.ts delete mode 100644 examples/src/sheets/custom-menu/index.ts delete mode 100644 examples/src/sheets/custom-menu/locale/en-US.ts delete mode 100644 examples/src/sheets/custom-menu/locale/zh-CN.ts delete mode 100644 examples/src/sheets/custom-menu/plugin.ts delete mode 100644 packages-experimental/debugger/src/controllers/multi-units/multi-units.controller.ts delete mode 100644 packages-experimental/debugger/src/controllers/multi-units/multi-units.menu.ts create mode 100644 packages-experimental/debugger/src/views/use-units.ts diff --git a/examples/src/sheets/custom-menu/commands/operations/dropdown-list.operation.ts b/examples/src/sheets/custom-menu/commands/operations/dropdown-list.operation.ts deleted file mode 100644 index a320add14c..0000000000 --- a/examples/src/sheets/custom-menu/commands/operations/dropdown-list.operation.ts +++ /dev/null @@ -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 type { IAccessor, ICommand } from '@univerjs/core'; -import { CommandType } from '@univerjs/core'; - -export const DropdownListFirstItemOperation: ICommand = { - id: 'custom-menu.operation.dropdown-list-first-item', - type: CommandType.OPERATION, - handler: async (_accessor: IAccessor) => { - // alert('Dropdown list first item operation') - return true; - }, -}; - -export const DropdownListSecondItemOperation: ICommand = { - id: 'custom-menu.operation.dropdown-list-second-item', - type: CommandType.OPERATION, - handler: async (_accessor: IAccessor) => { - // alert('Dropdown list second item operation') - return true; - }, -}; diff --git a/examples/src/sheets/custom-menu/commands/operations/single-button.operation.ts b/examples/src/sheets/custom-menu/commands/operations/single-button.operation.ts deleted file mode 100644 index 4cca94b136..0000000000 --- a/examples/src/sheets/custom-menu/commands/operations/single-button.operation.ts +++ /dev/null @@ -1,27 +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'; - -export const SingleButtonOperation: ICommand = { - id: 'custom-menu.operation.single-button', - type: CommandType.OPERATION, - handler: async (_accessor: IAccessor) => { - // alert('Single button operation') - return true; - }, -}; diff --git a/examples/src/sheets/custom-menu/controllers/custom-menu.controller.ts b/examples/src/sheets/custom-menu/controllers/custom-menu.controller.ts deleted file mode 100644 index 74b53a12e0..0000000000 --- a/examples/src/sheets/custom-menu/controllers/custom-menu.controller.ts +++ /dev/null @@ -1,118 +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 { Disposable, ICommandService, Inject, Injector } from '@univerjs/core'; -import { AiSingle, BarChartSingle, CommentSingle } from '@univerjs/icons'; -import { ComponentManager, ContextMenuGroup, ContextMenuPosition, IMenuManagerService, MenuItemType, RibbonOthersGroup } from '@univerjs/ui'; -import { DropdownListFirstItemOperation, DropdownListSecondItemOperation } from '../commands/operations/dropdown-list.operation'; -import { SingleButtonOperation } from '../commands/operations/single-button.operation'; -import { CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID, CustomMenuItemDropdownListFirstItemFactory, CustomMenuItemDropdownListMainButtonFactory, CustomMenuItemDropdownListSecondItemFactory } from './menu/dropdown-list.menu'; -import { CustomMenuItemSingleButtonFactory } from './menu/single-button.menu'; - -export class CustomMenuController extends Disposable { - constructor( - @Inject(Injector) private readonly _injector: Injector, - @ICommandService private readonly _commandService: ICommandService, - @IMenuManagerService private readonly _menuManagerService: IMenuManagerService, - @Inject(ComponentManager) private readonly _componentManager: ComponentManager - ) { - super(); - - this._initCommands(); - this._registerComponents(); - this._initMenus(); - } - - /** - * register commands - */ - private _initCommands(): void { - [ - SingleButtonOperation, - DropdownListFirstItemOperation, - DropdownListSecondItemOperation, - ].forEach((c) => { - this.disposeWithMe(this._commandService.registerCommand(c)); - }); - } - - /** - * register icon components - */ - private _registerComponents(): void { - this.disposeWithMe(this._componentManager.register('ButtonIcon', AiSingle)); - this.disposeWithMe(this._componentManager.register('ItemIcon', BarChartSingle)); - this.disposeWithMe(this._componentManager.register('MainButtonIcon', CommentSingle)); - } - - /** - * register menu items - */ - private _initMenus(): void { - const largeDropdownList = Array.from({ length: 15 }, (_, i) => ({ - order: 20 + i, - menuItemFactory: () => { - return { - id: `${DropdownListSecondItemOperation.id}-${i}`, - type: MenuItemType.BUTTON, - title: 'customMenu.itemTwo', - icon: 'ItemIcon', - }; - }, - })); - this._menuManagerService.mergeMenu({ - [RibbonOthersGroup.OTHERS]: { - [SingleButtonOperation.id]: { - order: 9999, - menuItemFactory: CustomMenuItemSingleButtonFactory, - }, - [CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID]: { - order: 9998.5, - menuItemFactory: CustomMenuItemDropdownListMainButtonFactory, - [DropdownListFirstItemOperation.id]: { - order: 0, - menuItemFactory: CustomMenuItemDropdownListFirstItemFactory, - }, - [DropdownListSecondItemOperation.id]: { - order: 1, - menuItemFactory: CustomMenuItemDropdownListSecondItemFactory, - }, - ...largeDropdownList, - }, - }, - [ContextMenuPosition.MAIN_AREA]: { - [ContextMenuGroup.OTHERS]: { - [SingleButtonOperation.id]: { - order: 9999, - menuItemFactory: CustomMenuItemSingleButtonFactory, - }, - [CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID]: { - order: 9998, - menuItemFactory: CustomMenuItemDropdownListMainButtonFactory, - [DropdownListFirstItemOperation.id]: { - order: 0, - menuItemFactory: CustomMenuItemDropdownListFirstItemFactory, - }, - [DropdownListSecondItemOperation.id]: { - order: 1, - menuItemFactory: CustomMenuItemDropdownListSecondItemFactory, - }, - }, - }, - }, - }); - } -} diff --git a/examples/src/sheets/custom-menu/controllers/menu/dropdown-list.menu.ts b/examples/src/sheets/custom-menu/controllers/menu/dropdown-list.menu.ts deleted file mode 100644 index 67ea793625..0000000000 --- a/examples/src/sheets/custom-menu/controllers/menu/dropdown-list.menu.ts +++ /dev/null @@ -1,51 +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 { IMenuButtonItem, IMenuSelectorItem } from '@univerjs/ui'; -import { MenuItemType } from '@univerjs/ui'; -import { DropdownListFirstItemOperation, DropdownListSecondItemOperation } from '../../commands/operations/dropdown-list.operation'; - -export const CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID = 'custom-menu.operation.dropdown-list'; - -export function CustomMenuItemDropdownListMainButtonFactory(): IMenuSelectorItem { - return { - // When type is MenuItemType.SUBITEMS, this factory serves as a container for the drop-down list, and you can set any unique id - id: CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID, - // The type of the menu item, in this case, it is a subitems - type: MenuItemType.SUBITEMS, - icon: 'MainButtonIcon', - tooltip: 'customMenu.dropdownList', - title: 'customMenu.dropdown', - }; -} - -export function CustomMenuItemDropdownListFirstItemFactory(): IMenuButtonItem { - return { - id: DropdownListFirstItemOperation.id, - type: MenuItemType.BUTTON, - title: 'customMenu.itemOne', - icon: 'ItemIcon', - }; -} - -export function CustomMenuItemDropdownListSecondItemFactory(): IMenuButtonItem { - return { - id: DropdownListSecondItemOperation.id, - type: MenuItemType.BUTTON, - title: 'customMenu.itemTwo', - icon: 'ItemIcon', - }; -} diff --git a/examples/src/sheets/custom-menu/controllers/menu/single-button.menu.ts b/examples/src/sheets/custom-menu/controllers/menu/single-button.menu.ts deleted file mode 100644 index 223946a650..0000000000 --- a/examples/src/sheets/custom-menu/controllers/menu/single-button.menu.ts +++ /dev/null @@ -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 { IMenuButtonItem } from '@univerjs/ui'; -import { MenuItemType } from '@univerjs/ui'; -import { SingleButtonOperation } from '../../commands/operations/single-button.operation'; - -export function CustomMenuItemSingleButtonFactory(): IMenuButtonItem { - return { - // Bind the command id, clicking the button will trigger this command - id: SingleButtonOperation.id, - // The type of the menu item, in this case, it is a button - type: MenuItemType.BUTTON, - // The icon of the button, which needs to be registered in ComponentManager - icon: 'ButtonIcon', - // The tooltip of the button. Prioritize matching internationalization. If no match is found, the original string will be displayed - tooltip: 'customMenu.singleButton', - // The title of the button. Prioritize matching internationalization. If no match is found, the original string will be displayed - title: 'customMenu.button', - }; -} diff --git a/examples/src/sheets/custom-menu/index.ts b/examples/src/sheets/custom-menu/index.ts deleted file mode 100644 index 4ab3888d25..0000000000 --- a/examples/src/sheets/custom-menu/index.ts +++ /dev/null @@ -1,17 +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. - */ - -export { UniverSheetsCustomMenuPlugin } from './plugin'; diff --git a/examples/src/sheets/custom-menu/locale/en-US.ts b/examples/src/sheets/custom-menu/locale/en-US.ts deleted file mode 100644 index 0bd86a2866..0000000000 --- a/examples/src/sheets/custom-menu/locale/en-US.ts +++ /dev/null @@ -1,26 +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. - */ - -export default { - customMenu: { - button: 'Button', - singleButton: 'Single button', - dropdown: 'Dropdown', - dropdownList: 'Dropdown list', - itemOne: 'Item 1', - itemTwo: 'Item 2', - }, -}; diff --git a/examples/src/sheets/custom-menu/locale/zh-CN.ts b/examples/src/sheets/custom-menu/locale/zh-CN.ts deleted file mode 100644 index a692066c06..0000000000 --- a/examples/src/sheets/custom-menu/locale/zh-CN.ts +++ /dev/null @@ -1,26 +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. - */ - -export default { - customMenu: { - button: '按钮', - singleButton: '单个按钮', - dropdown: '下拉', - dropdownList: '下拉列表', - itemOne: '项目一', - itemTwo: '项目二', - }, -}; diff --git a/examples/src/sheets/custom-menu/plugin.ts b/examples/src/sheets/custom-menu/plugin.ts deleted file mode 100644 index ba8e2ec68d..0000000000 --- a/examples/src/sheets/custom-menu/plugin.ts +++ /dev/null @@ -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 { Dependency } from '@univerjs/core'; -import { Inject, Injector, LocaleService, Plugin, touchDependencies, UniverInstanceType } from '@univerjs/core'; -import { CustomMenuController } from './controllers/custom-menu.controller'; -import enUS from './locale/en-US'; -import zhCN from './locale/zh-CN'; - -const SHEET_CUSTOM_MENU_PLUGIN = 'SHEET_CUSTOM_MENU_PLUGIN'; - -export class UniverSheetsCustomMenuPlugin extends Plugin { - static override type = UniverInstanceType.UNIVER_SHEET; - static override pluginName = SHEET_CUSTOM_MENU_PLUGIN; - - constructor( - _config = {}, - @Inject(Injector) protected readonly _injector: Injector, - @Inject(LocaleService) private readonly _localeService: LocaleService - ) { - super(); - - this._localeService.load({ - enUS, - zhCN, - }); - } - - override onStarting(): void { - ([ - [CustomMenuController], - ] as Dependency[]).forEach((d) => this._injector.add(d)); - } - - override onRendered(): void { - touchDependencies(this._injector, [ - [CustomMenuController], - ]); - } -} diff --git a/examples/src/sheets/main.ts b/examples/src/sheets/main.ts index 065e9f26d4..68989f4855 100644 --- a/examples/src/sheets/main.ts +++ b/examples/src/sheets/main.ts @@ -39,7 +39,6 @@ import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui'; import { UniverSheetsZenEditorPlugin } from '@univerjs/sheets-zen-editor'; import { UniverUIPlugin } from '@univerjs/ui'; import { enUS, faIR, frFR, ruRU, viVN, zhCN, zhTW } from '../locales'; -import { UniverSheetsCustomMenuPlugin } from './custom-menu'; import ImportCSVButtonPlugin from './custom-plugin/import-csv-button'; import '@univerjs/sheets/facade'; @@ -105,6 +104,7 @@ function createNewInstance() { univer.registerPlugin(UniverRenderEnginePlugin); univer.registerPlugin(UniverUIPlugin, { container: 'app', + // ribbonType: 'simple', }); univer.registerPlugin(UniverDocsUIPlugin); @@ -126,7 +126,6 @@ function createNewInstance() { univer.registerPlugin(UniverSheetsSortPlugin); univer.registerPlugin(UniverSheetsHyperLinkPlugin); univer.registerPlugin(UniverSheetsThreadCommentPlugin); - univer.registerPlugin(UniverSheetsCustomMenuPlugin); univer.registerPlugin(UniverSheetsTablePlugin); univer.registerPlugin(UniverNetworkPlugin); diff --git a/packages-experimental/debugger/src/controllers/debugger.controller.ts b/packages-experimental/debugger/src/controllers/debugger.controller.ts index 1d2b3ce6f9..fcbbbee63d 100644 --- a/packages-experimental/debugger/src/controllers/debugger.controller.ts +++ b/packages-experimental/debugger/src/controllers/debugger.controller.ts @@ -48,7 +48,9 @@ export class DebuggerController extends Disposable { const configs = this._configService.getConfig(DEBUGGER_PLUGIN_CONFIG_KEY); if (configs?.fab) { - this._uiPartsService.registerComponent(BuiltInUIPart.GLOBAL, () => connectInjector(Fab, this._injector)); + this.disposeWithMe( + this._uiPartsService.registerComponent(BuiltInUIPart.GLOBAL, () => connectInjector(Fab, this._injector)) + ); } } } diff --git a/packages-experimental/debugger/src/controllers/multi-units/multi-units.controller.ts b/packages-experimental/debugger/src/controllers/multi-units/multi-units.controller.ts deleted file mode 100644 index 7d8c11a94a..0000000000 --- a/packages-experimental/debugger/src/controllers/multi-units/multi-units.controller.ts +++ /dev/null @@ -1,43 +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 { Disposable, ICommandService } from '@univerjs/core'; -import { IMenuManagerService } from '@univerjs/ui'; -import { menuSchema, SwitchUnitOperation } from './multi-units.menu'; - -/** - * This controller helps to debug multi units inside a single Univer - * instance. - */ -export class MultiUnitsController extends Disposable { - constructor( - @ICommandService private readonly _commandService: ICommandService, - @IMenuManagerService private readonly _menuManagerService: IMenuManagerService - ) { - super(); - - this._initializeCommand(); - this._initializeMenu(); - } - - private _initializeCommand(): void { - this.disposeWithMe(this._commandService.registerCommand(SwitchUnitOperation)); - } - - private _initializeMenu(): void { - this._menuManagerService.mergeMenu(menuSchema); - } -} diff --git a/packages-experimental/debugger/src/controllers/multi-units/multi-units.menu.ts b/packages-experimental/debugger/src/controllers/multi-units/multi-units.menu.ts deleted file mode 100644 index 89b04f8dcf..0000000000 --- a/packages-experimental/debugger/src/controllers/multi-units/multi-units.menu.ts +++ /dev/null @@ -1,62 +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, IOperation, Workbook } from '@univerjs/core'; -import type { IMenuSelectorItem, IValueOption, MenuSchemaType } from '@univerjs/ui'; -import { CommandType, IUniverInstanceService, UniverInstanceType } from '@univerjs/core'; -import { MenuItemType, RibbonOthersGroup } from '@univerjs/ui'; -import { merge, Observable, shareReplay } from 'rxjs'; - -export const SwitchUnitOperation: IOperation<{ value: string }> = { - id: 'debugger.operation.switch-unit', - type: CommandType.OPERATION, - handler: (accessor, params) => { - const univerInstanceService = accessor.get(IUniverInstanceService); - if (!univerInstanceService.getUnit(params.value)) return false; - univerInstanceService.setCurrentUnitForType(params.value); - return true; - }, -}; - -function SwitchUnitMenuFactory(accessor: IAccessor): IMenuSelectorItem { - const instanceService = accessor.get(IUniverInstanceService); - const selections$ = new Observable>((observer) => { - function emit() { - const sheets = instanceService.getAllUnitsForType(UniverInstanceType.UNIVER_SHEET); - const options = sheets.map((sheet) => ({ label: sheet.getName() || sheet.getUnitId(), value: sheet.getUnitId() })); - observer.next(options); - } - - merge(instanceService.unitAdded$, instanceService.unitDisposed$).subscribe(() => emit()); - emit(); - }).pipe(shareReplay(1)); - - return { - id: SwitchUnitOperation.id, - title: 'Switch Unit', // TODO: i18n, - type: MenuItemType.SELECTOR, - selections: selections$, - }; -} - -export const menuSchema: MenuSchemaType = { - [RibbonOthersGroup.OTHERS]: { - [SwitchUnitOperation.id]: { - order: 999, - menuItemFactory: SwitchUnitMenuFactory, - }, - }, -}; diff --git a/packages-experimental/debugger/src/plugin.ts b/packages-experimental/debugger/src/plugin.ts index fd5209a8a6..3763956b24 100644 --- a/packages-experimental/debugger/src/plugin.ts +++ b/packages-experimental/debugger/src/plugin.ts @@ -20,7 +20,6 @@ import { IConfigService, Inject, Injector, merge, Plugin, registerDependencies, import { DEBUGGER_PLUGIN_CONFIG_KEY, defaultPluginConfig } from './controllers/config.schema'; import { DebuggerController } from './controllers/debugger.controller'; import { E2EController } from './controllers/e2e/e2e.controller'; -import { MultiUnitsController } from './controllers/multi-units/multi-units.controller'; import { PerformanceMonitorController } from './controllers/performance-monitor.controller'; import { UniverWatermarkMenuController } from './controllers/watermark.menu.controller'; @@ -51,7 +50,6 @@ export class UniverDebuggerPlugin extends Plugin { override onStarting(): void { const dependencies: Dependency[] = [ [DebuggerController], - [MultiUnitsController], [E2EController], [UniverWatermarkMenuController], ]; @@ -70,7 +68,6 @@ export class UniverDebuggerPlugin extends Plugin { override onReady(): void { touchDependencies(this._injector, [ [DebuggerController], - [MultiUnitsController], ]); } diff --git a/packages-experimental/debugger/src/views/Fab.tsx b/packages-experimental/debugger/src/views/Fab.tsx index 867150d405..cb86286167 100644 --- a/packages-experimental/debugger/src/views/Fab.tsx +++ b/packages-experimental/debugger/src/views/Fab.tsx @@ -32,6 +32,7 @@ import { useNotification } from './use-notification'; import { useSidebar } from './use-sidebar'; import { useSnapshot } from './use-snapshot'; import { useTheme } from './use-theme'; +import { useUnits } from './use-units'; import { useUser } from './use-user'; import { useWatermark } from './use-watermark'; @@ -40,6 +41,8 @@ export function Fab() { const univerInstanceService = useDependency(IUniverInstanceService); const unitType = univerInstanceService.getFocusedUnit()?.type; + if (!unitType) return null; + const items: IDropdownMenuProps['items'] = [ useLocale(), useDarkMode(), @@ -53,6 +56,7 @@ export function Fab() { { type: 'separator' }, unitType === UniverInstanceType.UNIVER_SHEET && useFloatingDom(), unitType === UniverInstanceType.UNIVER_SHEET && useCellContent(), + unitType === UniverInstanceType.UNIVER_SHEET && useUnits(), useSnapshot(), useEditable(), useUser(), diff --git a/packages-experimental/debugger/src/views/use-dispose.ts b/packages-experimental/debugger/src/views/use-dispose.ts index d83670e2a6..7076da5fa6 100644 --- a/packages-experimental/debugger/src/views/use-dispose.ts +++ b/packages-experimental/debugger/src/views/use-dispose.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { IUniverInstanceService, UniverInstanceType } from '@univerjs/core'; +import { IUniverInstanceService } from '@univerjs/core'; import { useDependency } from '@univerjs/ui'; const menu = [ @@ -26,10 +26,6 @@ const menu = [ label: 'Dispose current unit', value: 'unit', }, - { - label: 'Create another sheet', - value: 'create', - }, ]; export function useDispose() { @@ -45,8 +41,6 @@ export function useDispose() { if (!focused) return false; return univerInstanceService.disposeUnit(focused.getUnitId()); - } else if (value === 'create') { - univerInstanceService.createUnit(UniverInstanceType.UNIVER_SHEET, {}); } }; diff --git a/packages-experimental/debugger/src/views/use-units.ts b/packages-experimental/debugger/src/views/use-units.ts new file mode 100644 index 0000000000..2dafecc291 --- /dev/null +++ b/packages-experimental/debugger/src/views/use-units.ts @@ -0,0 +1,66 @@ +/** + * 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 { IUniverInstanceService, UniverInstanceType } from '@univerjs/core'; +import { useDependency, useObservable } from '@univerjs/ui'; +import { useEffect, useState } from 'react'; + +const defaultMenu = [ + { + label: 'Create another sheet', + value: 'create', + }, +]; + +export function useUnits() { + const univerInstanceService = useDependency(IUniverInstanceService); + const [menu, setMenu] = useState<{ label: string; value: string }[]>([...defaultMenu]); + const unitAdded = useObservable(univerInstanceService.unitAdded$); + const unitDisposed = useObservable(univerInstanceService.unitDisposed$); + + useEffect(() => { + const sheets = univerInstanceService.getAllUnitsForType(UniverInstanceType.UNIVER_SHEET); + const options = sheets.map((sheet) => ({ + label: sheet.getName() || sheet.getUnitId(), + value: sheet.getUnitId(), + })); + + setMenu([ + ...defaultMenu, + ...(options as any[]), + ]); + }, [unitAdded, unitDisposed]); + + const onSelect = (value: string) => { + if (value === 'create') { + univerInstanceService.createUnit(UniverInstanceType.UNIVER_SHEET, {}); + } else { + if (!univerInstanceService.getUnit(value)) return false; + univerInstanceService.setCurrentUnitForType(value); + } + }; + + return { + type: 'subItem' as const, + children: '🪸 Units', + options: menu.map((item) => ({ + type: 'item' as const, + children: item.label, + onSelect: () => onSelect(item.value), + })), + }; +} diff --git a/packages/ui/src/controllers/ui/ui.controller.ts b/packages/ui/src/controllers/ui/ui.controller.ts index 739b3da958..f942e87c2d 100644 --- a/packages/ui/src/controllers/ui/ui.controller.ts +++ b/packages/ui/src/controllers/ui/ui.controller.ts @@ -16,6 +16,8 @@ import { createIdentifier } from '@univerjs/core'; +export type RibbonType = 'default' | 'simple'; + export interface IWorkbenchOptions { container?: string | HTMLElement; @@ -29,6 +31,8 @@ export interface IWorkbenchOptions { */ toolbar?: boolean; + ribbonType?: RibbonType; + /** * If Univer should make the footer bar visible. */ diff --git a/packages/ui/src/views/components/ribbon/Ribbon.tsx b/packages/ui/src/views/components/ribbon/Ribbon.tsx index e0879500c7..777bd8d611 100644 --- a/packages/ui/src/views/components/ribbon/Ribbon.tsx +++ b/packages/ui/src/views/components/ribbon/Ribbon.tsx @@ -16,6 +16,7 @@ import type { ComponentType } from 'react'; import type { Observable } from 'rxjs'; +import type { RibbonType } from '../../../controllers/ui/ui.controller'; import type { IMenuSchema } from '../../../services/menu/menu-manager.service'; import { LocaleService, throttle } from '@univerjs/core'; import { borderBottomClassName, borderClassName, clsx, divideXClassName, Dropdown, HoverCard } from '@univerjs/design'; @@ -30,6 +31,7 @@ import { ToolbarButton } from './ToolbarButton'; import { ToolbarItem } from './ToolbarItem'; interface IRibbonProps { + ribbonType: RibbonType; headerMenuComponents?: Set; headerMenu?: boolean; } @@ -44,7 +46,7 @@ const iconMap = { }; export function Ribbon(props: IRibbonProps) { - const { headerMenuComponents, headerMenu = true } = props; + const { ribbonType, headerMenuComponents, headerMenu = true } = props; const menuManagerService = useDependency(IMenuManagerService); const localeService = useDependency(LocaleService); @@ -64,8 +66,9 @@ export function Ribbon(props: IRibbonProps) { const toolbarItemRefs = useRef>({}); const [ribbon, setRibbon] = useState([]); @@ -156,7 +159,18 @@ export function Ribbon(props: IRibbonProps) { } } - setRibbon(newRibbon); + if (ribbonType === 'simple') { + const simpleRibbon: IMenuSchema[] = [{ key: RibbonPosition.START, children: [], order: 0 }]; + newRibbon.forEach((group) => { + group.children?.forEach((item) => { + simpleRibbon[0].children?.push(item); + }); + }); + + setRibbon(simpleRibbon); + } else { + setRibbon(newRibbon); + } }) .unsubscribe(); }, [menuChangedTimes]); @@ -201,10 +215,7 @@ export function Ribbon(props: IRibbonProps) { const { width: avaliableWidth } = entry.contentRect; const toolbarItems = Object.values(toolbarItemRefs.current); const sortedToolbarItems = toolbarItems.sort((a, b) => { - if (a.groupOrder === b.groupOrder) { - return a.order - b.order; - } - return a.groupOrder - b.groupOrder; + return a.order - b.order || a.groupOrder - b.groupOrder || a.itemOrder - b.itemOrder; }); const newCollapsedIds: string[] = []; @@ -229,7 +240,7 @@ export function Ribbon(props: IRibbonProps) { setFakeToolbarVisible(false); }); } - }, 300)); + }, 100)); observer.observe(containerRef.current); @@ -249,7 +260,7 @@ export function Ribbon(props: IRibbonProps) { univer-flex univer-h-10 univer-min-w-min univer-items-center univer-px-3 univer-opacity-0 `, borderBottomClassName)} > - {activeGroup.allGroups.map((groupItem) => (groupItem.children?.length || groupItem.item) && ( + {activeGroup.allGroups.map((groupItem, index) => (groupItem.children?.length || groupItem.item) && (
{groupItem.children && groupItem.children?.map((child) => ( @@ -262,8 +273,9 @@ export function Ribbon(props: IRibbonProps) { toolbarItemRefs.current[child.key] = { el: ref.el, key: child.key, + order: index, groupOrder: groupItem.order, - order: child.order, + itemOrder: child.order, }; } }} @@ -298,7 +310,10 @@ export function Ribbon(props: IRibbonProps) {
1, + 'univer-grid-cols-none': ribbon.length === 1, + }, borderBottomClassName)} > {/* @@ -317,6 +332,7 @@ export function Ribbon(props: IRibbonProps) { return ( )} -
+
{activeGroup.visibleGroups.map((groupItem) => (groupItem.children?.length || groupItem.item) && (
@@ -390,7 +410,7 @@ export function Ribbon(props: IRibbonProps) { {/* More functions dropdown */} {collapsedIds.length > 0 && ( -
+