feat(administration): item sub implementation

This commit is contained in:
Wroud
2020-05-28 15:45:04 +03:00
parent e39f981745
commit 3148bf2dc1
6 changed files with 101 additions and 8 deletions
@@ -64,10 +64,14 @@ const administrationStyles = composes(
type Props = {
activeItem: string | null;
activeItemSub: string | null;
activeItemSubParam: string | null;
onItemSelect(name: string): void;
}
export const Administration = observer(function Administration({ activeItem, onItemSelect }: Props) {
export const Administration = observer(function Administration({
activeItem, activeItemSub, activeItemSubParam, onItemSelect,
}: Props) {
const controller = useController(AdministrationController);
return styled(useStyles(verticalTabStyles, administrationStyles, tabsStyles))(
@@ -81,7 +85,11 @@ export const Administration = observer(function Administration({ activeItem, onI
</TabList>
</drawer>
<content as='div'>
<ItemContent activeItemName={activeItem}/>
<ItemContent
activeItemName={activeItem}
activeItemSub={activeItemSub}
activeItemSubParam={activeItemSubParam}
/>
</content>
</TabsState>
</container>
@@ -14,9 +14,11 @@ import { AdministrationItemService } from '../AdministrationItem/AdministrationI
type Props = {
activeItemName: string | null;
activeItemSub: string | null;
activeItemSubParam: string | null;
}
export const ItemContent = observer(function ItemContent({ activeItemName }: Props) {
export const ItemContent = observer(function ItemContent({ activeItemName, activeItemSub, activeItemSubParam }: Props) {
const administrationItemService = useService(AdministrationItemService);
if (!activeItemName) {
@@ -29,6 +31,15 @@ export const ItemContent = observer(function ItemContent({ activeItemName }: Pro
return null;
}
if (activeItemSub) {
const sub = administrationItemService.getItemSub(item, activeItemSub);
if (sub) {
const Component = sub.getComponent();
return <Component item={item} sub={sub} param={activeItemSubParam} />;
}
}
const Component = item.getContentComponent();
return <Component item={item} />;
@@ -10,7 +10,7 @@ import { observable } from 'mobx';
import { injectable } from '@dbeaver/core/di';
import { IAdministrationItem, IAdministrationItemOptions } from './IAdministrationItem';
import { IAdministrationItem, IAdministrationItemOptions, IAdministrationItemSubItem } from './IAdministrationItem';
@injectable()
export class AdministrationItemService {
@@ -33,6 +33,15 @@ export class AdministrationItemService {
return item;
}
getItemSub(item: IAdministrationItem, subItem: string): IAdministrationItemSubItem | null {
const sub = item.sub.find(sub => sub.name === subItem);
if (!sub) {
return null;
}
return sub;
}
create(options: IAdministrationItemOptions) {
if (this.items.some(item => item.name === options.name)) {
throw new Error(`Administration item "${options.name}" already exists`);
@@ -40,15 +49,27 @@ export class AdministrationItemService {
const item: IAdministrationItem = {
...options,
sub: options.sub || [],
order: options.order || Number.MAX_SAFE_INTEGER,
};
this.items.push(item);
}
async activate(name: string) {
async activate(name: string, itemSub: string | null, param: string | null) {
const item = this.getItem(name);
if (item && item.onActivate) {
if (!item) {
return;
}
if (item.onActivate) {
await item.onActivate();
}
if (itemSub) {
const sub = this.getItemSub(item, itemSub);
if (sub && sub.onActivate) {
await sub.onActivate(param);
}
}
}
}
@@ -20,11 +20,26 @@ export type AdministrationItemContentProps = {
}
export type AdministrationItemContentComponent = React.FunctionComponent<AdministrationItemContentProps>
export type AdministrationItemSubContentProps = {
item: IAdministrationItem;
sub: IAdministrationItemSubItem;
param: string | null;
}
export type AdministrationItemSubContentComponent = React.FunctionComponent<AdministrationItemSubContentProps>
export type AdministrationItemEvent = () => Promise<void> | void
export type AdministrationItemSubEvent = (param: string | null) => Promise<void> | void
export interface IAdministrationItemSubItem {
name: string;
getComponent(): AdministrationItemSubContentComponent;
onActivate?: AdministrationItemSubEvent;
}
export interface IAdministrationItemOptions {
name: string;
order?: number;
sub?: IAdministrationItemSubItem[];
getDrawerComponent(): AdministrationItemDrawerComponent;
getContentComponent(): AdministrationItemContentComponent;
onActivate?: AdministrationItemEvent;
@@ -32,4 +47,5 @@ export interface IAdministrationItemOptions {
export interface IAdministrationItem extends IAdministrationItemOptions {
order: number;
sub: IAdministrationItemSubItem[];
}
@@ -32,7 +32,12 @@ export const AdministrationScreen = observer(function AdministrationScreen() {
return (
<>
<AdministrationTopAppBar />
<Administration activeItem={administrationScreenService.activeItem} onItemSelect={handleSelect} />
<Administration
activeItem={administrationScreenService.activeItem}
activeItemSub={administrationScreenService.activeItemSub}
activeItemSubParam={administrationScreenService.activeItemSubParam}
onItemSelect={handleSelect}
/>
</>
);
});
@@ -21,6 +21,8 @@ export class AdministrationScreenService extends Bootstrap {
static screenName = 'administration'
static itemRouteName = 'administration.item'
static itemSubRouteName = 'administration.item.sub'
static itemSubParamRouteName = 'administration.item.sub.param'
@computed get activeItem(): string | null {
if (!this.screenService.isActive(AdministrationScreenService.screenName)) {
@@ -29,6 +31,20 @@ export class AdministrationScreenService extends Bootstrap {
return this.routerService.params.item || this.administrationItemService.getDefaultItem();
}
@computed get activeItemSub(): string | null {
if (!this.screenService.isActive(AdministrationScreenService.screenName)) {
return null;
}
return this.routerService.params.sub || null;
}
@computed get activeItemSubParam(): string | null {
if (!this.screenService.isActive(AdministrationScreenService.screenName)) {
return null;
}
return this.routerService.params.param || null;
}
constructor(
private screenService: ScreenService,
private routerService: RouterService,
@@ -48,6 +64,14 @@ export class AdministrationScreenService extends Bootstrap {
this.routerService.router.navigate(AdministrationScreenService.itemRouteName, { item });
}
navigateToItemSub(item: string, sub: string, param?: string) {
if (!param) {
this.routerService.router.navigate(AdministrationScreenService.itemSubRouteName, { item, sub });
return;
}
this.routerService.router.navigate(AdministrationScreenService.itemSubParamRouteName, { item, sub, param });
}
bootstrap() {
this.screenService.create({
name: AdministrationScreenService.screenName,
@@ -60,6 +84,14 @@ export class AdministrationScreenService extends Bootstrap {
name: AdministrationScreenService.itemRouteName,
path: '/:item',
},
{
name: AdministrationScreenService.itemSubRouteName,
path: '/:sub',
},
{
name: AdministrationScreenService.itemSubParamRouteName,
path: '/:param',
},
],
component: AdministrationScreen,
onActivate: this.handleActivate.bind(this),
@@ -73,7 +105,7 @@ export class AdministrationScreenService extends Bootstrap {
}
if (this.activeItem) {
await this.administrationItemService.activate(this.activeItem);
await this.administrationItemService.activate(this.activeItem, this.activeItemSub, this.activeItemSubParam);
}
}
}