Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui): ui parts service support more generic situations #2286

Merged
merged 1 commit into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/docs-ui/src/controllers/doc-ui.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import type { DocumentDataModel } from '@univerjs/core';
import { Disposable, IUniverInstanceService, LifecycleStages, OnLifecycle, UniverInstanceType } from '@univerjs/core';
import type { IMenuItemFactory } from '@univerjs/ui';
import { ComponentManager, DesktopUIPart, IEditorService, ILayoutService, IMenuService, IUIPartsService } from '@univerjs/ui';
import { BuiltInUIPart, ComponentManager, IEditorService, ILayoutService, IMenuService, IUIPartsService } from '@univerjs/ui';
import { Inject, Injector } from '@wendellhu/redi';

import { connectInjector } from '@wendellhu/redi/react-bindings';
Expand Down Expand Up @@ -129,7 +129,7 @@ export class DocUIController extends Disposable {
const embedded = this._editorService.isEditor(firstDocUnitId);
if (!embedded) {
this.disposeWithMe(
this._uiPartsService.registerComponent(DesktopUIPart.CONTENT, () => connectInjector(DocBackground, this._injector))
this._uiPartsService.registerComponent(BuiltInUIPart.CONTENT, () => connectInjector(DocBackground, this._injector))
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import { Disposable, ICommandService, LifecycleStages, OnLifecycle, UniverInstanceType } from '@univerjs/core';
import type { MenuConfig } from '@univerjs/ui';
import { ComponentManager, DesktopUIPart, IMenuService, IShortcutService, IUIPartsService } from '@univerjs/ui';
import { BuiltInUIPart, ComponentManager, IMenuService, IShortcutService, IUIPartsService } from '@univerjs/ui';
import type { Ctor } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { connectInjector } from '@wendellhu/redi/react-bindings';
Expand Down Expand Up @@ -124,7 +124,7 @@ export class FormulaUIController extends Disposable {

private _registerComponents(): void {
this.disposeWithMe(
this._uiPartsService.registerComponent(DesktopUIPart.CONTENT, () => connectInjector(RenderFormulaPromptContent, this._injector))
this._uiPartsService.registerComponent(BuiltInUIPart.CONTENT, () => connectInjector(RenderFormulaPromptContent, this._injector))
);

this._componentManager.register(MORE_FUNCTIONS_COMPONENT, MoreFunctions);
Expand Down
8 changes: 4 additions & 4 deletions packages/sheets-ui/src/controllers/sheet-ui.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
SetUnderlineCommand,
} from '@univerjs/sheets';
import type { IMenuItemFactory, MenuConfig } from '@univerjs/ui';
import { ComponentManager, DesktopUIPart, ILayoutService, IMenuService, IShortcutService, IUIPartsService } from '@univerjs/ui';
import { BuiltInUIPart, ComponentManager, ILayoutService, IMenuService, IShortcutService, IUIPartsService } from '@univerjs/ui';
import { Inject, Injector } from '@wendellhu/redi';
import { connectInjector } from '@wendellhu/redi/react-bindings';

Expand Down Expand Up @@ -485,9 +485,9 @@ export class SheetUIController extends Disposable {
const uiController = this._uiPartsService;
const injector = this._injector;

this.disposeWithMe(uiController.registerComponent(DesktopUIPart.HEADER, () => connectInjector(RenderSheetHeader, injector)));
this.disposeWithMe(uiController.registerComponent(DesktopUIPart.FOOTER, () => connectInjector(RenderSheetFooter, injector)));
this.disposeWithMe(uiController.registerComponent(DesktopUIPart.CONTENT, () => connectInjector(RenderSheetContent, injector)));
this.disposeWithMe(uiController.registerComponent(BuiltInUIPart.HEADER, () => connectInjector(RenderSheetHeader, injector)));
this.disposeWithMe(uiController.registerComponent(BuiltInUIPart.FOOTER, () => connectInjector(RenderSheetFooter, injector)));
this.disposeWithMe(uiController.registerComponent(BuiltInUIPart.CONTENT, () => connectInjector(RenderSheetContent, injector)));
}

private _initFocusHandler(): void {
Expand Down
4 changes: 2 additions & 2 deletions packages/slides-ui/src/controllers/slide-ui.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import { Disposable, ICommandService, LifecycleStages, OnLifecycle } from '@univerjs/core';
import { DesktopUIPart, IUIPartsService } from '@univerjs/ui';
import { BuiltInUIPart, IUIPartsService } from '@univerjs/ui';
import { Inject, Injector } from '@wendellhu/redi';
import { connectInjector } from '@wendellhu/redi/react-bindings';
import { SlideSideBar } from '../views/slide-bar/SlideBar';
Expand Down Expand Up @@ -47,7 +47,7 @@ export class SlideUIController extends Disposable {

private _initUIComponents(): void {
this.disposeWithMe(
this._uiPartsService.registerComponent(DesktopUIPart.LEFT_SIDEBAR, () => connectInjector(SlideSideBar, this._injector))
this._uiPartsService.registerComponent(BuiltInUIPart.LEFT_SIDEBAR, () => connectInjector(SlideSideBar, this._injector))
);
}
}
2 changes: 1 addition & 1 deletion packages/ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export {
} from './controllers/shared-shortcut.controller';
export { IUIController, type IWorkbenchOptions } from './controllers/ui/ui.controller';
export { DesktopUIController } from './controllers/ui/ui-desktop.controller';
export { IUIPartsService, DesktopUIPart, DesktopUIPartsService } from './services/parts/parts.service';
export { IUIPartsService, BuiltInUIPart, UIPartsService as BuiltInUIPartsService } from './services/parts/parts.service';
export { enUS, zhCN, ruRU } from './locale';
export { DesktopBeforeCloseService, IBeforeCloseService } from './services/before-close/before-close.service';
export { CopyCommand, CutCommand, PasteCommand } from './services/clipboard/clipboard.command';
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/services/confirm/desktop-confirm.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Subject } from 'rxjs';

import { connectInjector } from '@wendellhu/redi/react-bindings';
import type { IConfirmPartMethodOptions } from '../../views/components/confirm-part/interface';
import { DesktopUIPart, IUIPartsService } from '../parts/parts.service';
import { BuiltInUIPart, IUIPartsService } from '../parts/parts.service';
import { ConfirmPart } from '../../views/components/confirm-part/ConfirmPart';
import type { IConfirmService } from './confirm.service';

Expand Down Expand Up @@ -83,7 +83,7 @@ export class DesktopConfirmService extends Disposable implements IConfirmService

protected _initUIPart(): void {
this.disposeWithMe(
this._uiPartsService.registerComponent(DesktopUIPart.GLOBAL, () => connectInjector(ConfirmPart, this._injector))
this._uiPartsService.registerComponent(BuiltInUIPart.GLOBAL, () => connectInjector(ConfirmPart, this._injector))
);
}
}
4 changes: 2 additions & 2 deletions packages/ui/src/services/dialog/desktop-dialog.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Subject } from 'rxjs';

import { connectInjector } from '@wendellhu/redi/react-bindings';
import type { IDialogPartMethodOptions } from '../../views/components/dialog-part/interface';
import { DesktopUIPart, IUIPartsService } from '../parts/parts.service';
import { BuiltInUIPart, IUIPartsService } from '../parts/parts.service';
import { DialogPart } from '../../views/components/dialog-part/DialogPart';
import type { IDialogService } from './dialog.service';

Expand Down Expand Up @@ -79,7 +79,7 @@ export class DesktopDialogService extends Disposable implements IDialogService {

protected _initUIPart(): void {
this.disposeWithMe(
this._uiPartsService.registerComponent(DesktopUIPart.GLOBAL, () => connectInjector(DialogPart, this._injector))
this._uiPartsService.registerComponent(BuiltInUIPart.GLOBAL, () => connectInjector(DialogPart, this._injector))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { type IDisposable, Inject, Injector } from '@wendellhu/redi';
import { connectInjector } from '@wendellhu/redi/react-bindings';
import type { INotificationOptions } from '../../components/notification/Notification';
import { notification, Notification } from '../../components/notification/Notification';
import { DesktopUIPart, IUIPartsService } from '../parts/parts.service';
import { BuiltInUIPart, IUIPartsService } from '../parts/parts.service';
import type { INotificationService } from './notification.service';

export class DesktopNotificationService extends Disposable implements INotificationService {
Expand All @@ -40,6 +40,6 @@ export class DesktopNotificationService extends Disposable implements INotificat
}

protected _initUIPart(): void {
this.disposeWithMe(this._uiPartsService.registerComponent(DesktopUIPart.GLOBAL, () => connectInjector(Notification, this._injector)));
this.disposeWithMe(this._uiPartsService.registerComponent(BuiltInUIPart.GLOBAL, () => connectInjector(Notification, this._injector)));
}
}
34 changes: 21 additions & 13 deletions packages/ui/src/services/parts/parts.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@
import type { IDisposable } from '@wendellhu/redi';
import { createIdentifier } from '@wendellhu/redi';
import { type Observable, Subject } from 'rxjs';
import { toDisposable } from '@univerjs/core';
import { Disposable, toDisposable } from '@univerjs/core';

import type { ComponentType } from '../../common/component-manager';

export enum DesktopUIPart {
type ComponentRenderer = () => ComponentType;
type ComponentPartKey = BuiltInUIPart | string;

export enum BuiltInUIPart {
GLOBAL = 'global',
HEADER = 'header',
HEADER_MENU = 'header-menu',
Expand All @@ -30,39 +34,43 @@ export enum DesktopUIPart {
}

export interface IUIPartsService {
componentRegistered$: Observable<void>;
componentRegistered$: Observable<ComponentPartKey>;

registerComponent(part: DesktopUIPart, component: () => ComponentType): IDisposable;
getComponents(part: DesktopUIPart): Set<() => ComponentType>;
registerComponent(part: ComponentPartKey, component: () => ComponentType): IDisposable;
getComponents(part: ComponentPartKey): Set<ComponentRenderer>;
}

export const IUIPartsService = createIdentifier<IUIPartsService>('ui.parts.service');

export class DesktopUIPartsService implements IUIPartsService {
private _componentsByPart: Map<DesktopUIPart, Set<() => ComponentType>> = new Map();
export class UIPartsService extends Disposable implements IUIPartsService {
private _componentsByPart: Map<ComponentPartKey, Set<ComponentRenderer>> = new Map();

private readonly _componentRegistered$ = new Subject<void>();
private readonly _componentRegistered$ = new Subject<ComponentPartKey>();
readonly componentRegistered$ = this._componentRegistered$.asObservable();

registerComponent(part: DesktopUIPart, component: () => React.ComponentType): IDisposable {
override dispose(): void {
super.dispose();

this._componentRegistered$.complete();
}

registerComponent(part: ComponentPartKey, component: () => React.ComponentType): IDisposable {
const components = (
this._componentsByPart.get(part)
|| this._componentsByPart.set(part, new Set()).get(part)!
).add(component);

this._componentRegistered$.next();
this._componentRegistered$.next(part);

return toDisposable(() => {
components.delete(component);
if (components.size === 0) {
this._componentsByPart.delete(part);
}

this._componentRegistered$.complete();
});
}

getComponents(part: DesktopUIPart): Set<() => ComponentType> {
getComponents(part: ComponentPartKey): Set<ComponentRenderer> {
return new Set([...(this._componentsByPart.get(part) || new Set())]);
}
}
4 changes: 2 additions & 2 deletions packages/ui/src/ui-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import { IZenZoneService } from './services/zen-zone/zen-zone.service';
import { EditorService, IEditorService } from './services/editor/editor.service';
import { IRangeSelectorService, RangeSelectorService } from './services/range-selector/range-selector.service';
import { IProgressService, ProgressService } from './services/progress/progress.service';
import { DesktopUIPartsService, IUIPartsService } from './services/parts/parts.service';
import { IUIPartsService, UIPartsService } from './services/parts/parts.service';

const PLUGIN_NAME = 'ui';

Expand Down Expand Up @@ -100,7 +100,7 @@ export class UniverUIPlugin extends Plugin {

// services
[ShortcutPanelService],
[IUIPartsService, { useClass: DesktopUIPartsService }],
[IUIPartsService, { useClass: UIPartsService }],
[ILayoutService, { useClass: DesktopLayoutService }],
[IShortcutService, { useClass: DesktopShortcutService }],
[IPlatformService, { useClass: DesktopPlatformService }],
Expand Down
14 changes: 7 additions & 7 deletions packages/ui/src/views/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { useDependency } from '@wendellhu/redi/react-bindings';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import type { IWorkbenchOptions } from '../controllers/ui/ui.controller';
import { IMessageService } from '../services/message/message.service';
import { DesktopUIPart, IUIPartsService } from '../services/parts/parts.service';
import { BuiltInUIPart, IUIPartsService } from '../services/parts/parts.service';
import styles from './app.module.less';
import { ComponentContainer } from './components/ComponentContainer';
import { Toolbar } from './components/doc-bars/Toolbar';
Expand Down Expand Up @@ -67,12 +67,12 @@ export function App(props: IUniverAppProps) {
}, []);

const { headerComponents, contentComponents, footerComponents, headerMenuComponents, leftSidebarComponents, globalComponents } = useMemo(() => ({
headerComponents: uiPartsService.getComponents(DesktopUIPart.HEADER),
contentComponents: uiPartsService.getComponents(DesktopUIPart.CONTENT),
footerComponents: uiPartsService.getComponents(DesktopUIPart.FOOTER),
headerMenuComponents: uiPartsService.getComponents(DesktopUIPart.HEADER_MENU),
leftSidebarComponents: uiPartsService.getComponents(DesktopUIPart.LEFT_SIDEBAR),
globalComponents: uiPartsService.getComponents(DesktopUIPart.GLOBAL),
headerComponents: uiPartsService.getComponents(BuiltInUIPart.HEADER),
contentComponents: uiPartsService.getComponents(BuiltInUIPart.CONTENT),
footerComponents: uiPartsService.getComponents(BuiltInUIPart.FOOTER),
headerMenuComponents: uiPartsService.getComponents(BuiltInUIPart.HEADER_MENU),
leftSidebarComponents: uiPartsService.getComponents(BuiltInUIPart.LEFT_SIDEBAR),
globalComponents: uiPartsService.getComponents(BuiltInUIPart.GLOBAL),
// eslint-disable-next-line react-hooks/exhaustive-deps
}), [updateTrigger]);

Expand Down
Loading