mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
feat(core): add placeholder
CB-63
This commit is contained in:
@@ -6,13 +6,14 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { SettingsMenuService, MainRightMenuService } from '@dbeaver/core/app';
|
||||
import { SettingsMenuService, TopNavService } from '@dbeaver/core/app';
|
||||
import { injectable } from '@dbeaver/core/di';
|
||||
import { ServerService } from '@dbeaver/core/root';
|
||||
|
||||
import { AuthenticationService } from './AuthenticationService';
|
||||
import { AuthInfoService } from './AuthInfoService';
|
||||
import { AuthDialogService } from './Dialog/AuthDialogService';
|
||||
import { UserInfo } from './UserInfo';
|
||||
|
||||
@injectable()
|
||||
export class AuthMenuService {
|
||||
@@ -22,7 +23,7 @@ export class AuthMenuService {
|
||||
private authInfoService: AuthInfoService,
|
||||
private settingsMenuService: SettingsMenuService,
|
||||
private authenticationService: AuthenticationService,
|
||||
private mainRightMenuService: MainRightMenuService,
|
||||
private topNavService: TopNavService,
|
||||
) { }
|
||||
|
||||
register() {
|
||||
@@ -48,13 +49,7 @@ export class AuthMenuService {
|
||||
}
|
||||
);
|
||||
|
||||
this.mainRightMenuService.registerRootItem({
|
||||
id: 'user',
|
||||
order: 0,
|
||||
isHidden: () => !this.authInfoService.userInfo,
|
||||
icon: 'user',
|
||||
title: 'User',
|
||||
});
|
||||
this.topNavService.placeholder.add(UserInfo, 4);
|
||||
}
|
||||
|
||||
private async logout() {
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { IconOrImage } from '@dbeaver/core/blocks';
|
||||
import { useService } from '@dbeaver/core/di';
|
||||
import { composes, useStyles } from '@dbeaver/core/theming';
|
||||
|
||||
import { AuthInfoService } from './AuthInfoService';
|
||||
|
||||
const styles = composes(
|
||||
css`
|
||||
user {
|
||||
composes: theme-ripple from global;
|
||||
}
|
||||
`,
|
||||
css`
|
||||
user {
|
||||
height: 100%;
|
||||
padding: 0 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
IconOrImage {
|
||||
display: block;
|
||||
width: 24px;
|
||||
}
|
||||
user-name {
|
||||
display: block;
|
||||
line-height: initial;
|
||||
margin-left: 8px;
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
export const UserInfo = observer(function UserInfo() {
|
||||
const authInfoService = useService(AuthInfoService);
|
||||
|
||||
if (!authInfoService.userInfo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return styled(useStyles(styles))(
|
||||
<user as='div'>
|
||||
<user-icon as="div">
|
||||
<IconOrImage icon='user' viewBox='0 0 28 28' />
|
||||
</user-icon>
|
||||
<user-name as='div'>{authInfoService.userInfo.userId}</user-name>
|
||||
</user>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "@dbeaver/core/placeholder",
|
||||
"private": true,
|
||||
"sideEffects": false,
|
||||
"main": "../dist/placeholder",
|
||||
"module": "../dist/placeholder",
|
||||
"types": "../dist/types/placeholder"
|
||||
}
|
||||
@@ -26,16 +26,17 @@ import { LocalizationService } from './localization';
|
||||
@injectable()
|
||||
export class AppBootstrap {
|
||||
|
||||
constructor(private exceptionsCatcherService: ExceptionsCatcherService,
|
||||
private localizationService: LocalizationService,
|
||||
private themeService: ThemeService,
|
||||
private connectionDialogService: ConnectionDialogsService,
|
||||
private logViewerMenuService: LogViewerMenuService,
|
||||
private sessionExpireService: SessionExpireService,
|
||||
private navigationTreeContextMenuService: NavigationTreeContextMenuService,
|
||||
private navigationTabsService: NavigationTabsService,
|
||||
private connectionSchemaManagerService: ConnectionSchemaManagerService) {
|
||||
}
|
||||
constructor(
|
||||
private exceptionsCatcherService: ExceptionsCatcherService,
|
||||
private localizationService: LocalizationService,
|
||||
private themeService: ThemeService,
|
||||
private connectionDialogService: ConnectionDialogsService,
|
||||
private logViewerMenuService: LogViewerMenuService,
|
||||
private sessionExpireService: SessionExpireService,
|
||||
private navigationTreeContextMenuService: NavigationTreeContextMenuService,
|
||||
private navigationTabsService: NavigationTabsService,
|
||||
private connectionSchemaManagerService: ConnectionSchemaManagerService,
|
||||
) { }
|
||||
|
||||
async init() {
|
||||
this.exceptionsCatcherService.subscribe();
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
const styles = css`
|
||||
fill {
|
||||
flex: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
export function Fill() {
|
||||
return styled(styles)(<fill as='div' />);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { Icon } from '@dbeaver/core/blocks';
|
||||
import { useService } from '@dbeaver/core/di';
|
||||
import { ServerService } from '@dbeaver/core/root';
|
||||
|
||||
declare const version: string; // declared in webpack DefinePlugin // todo move to enviroment?
|
||||
|
||||
const styles = css`
|
||||
logo {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 16px;
|
||||
width: 250px;
|
||||
|
||||
& Icon {
|
||||
height: 24px;
|
||||
width: auto;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const Logo = observer(function Logo() {
|
||||
const serverService = useService(ServerService);
|
||||
const title = `Frontend: ${version}\nBackend: ${serverService.config.data?.version}`;
|
||||
|
||||
return styled(styles)(
|
||||
<logo as="div" title={title}>
|
||||
<Icon name="logo" viewBox="0 0 361 73" />
|
||||
</logo>
|
||||
);
|
||||
});
|
||||
@@ -6,37 +6,21 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import styled from 'reshadow';
|
||||
|
||||
import { Icon } from '@dbeaver/core/blocks';
|
||||
import { useService } from '@dbeaver/core/di';
|
||||
import { ServerService } from '@dbeaver/core/root';
|
||||
import { Placeholder } from '@dbeaver/core/placeholder';
|
||||
import { useStyles } from '@dbeaver/core/theming';
|
||||
|
||||
import { ConnectionSelector } from './ConnectionSchemaManager/ConnectionSelector/ConnectionSelector';
|
||||
import { MainMenu } from './MainMenu/MainMenu';
|
||||
import { MainRightMenu } from './MainRightMenu/MainRightMenu';
|
||||
import { SettingsMenu } from './SettingsMenu/SettingsMenu';
|
||||
import { TopNavService } from './TopNavBarService';
|
||||
import { topNavBarStyles } from './topNavBarStyles';
|
||||
|
||||
|
||||
declare const version: string; // declared in webpack DefinePlugin // todo move to enviroment?
|
||||
|
||||
export const TopNavBar = observer(function TopNavBar() {
|
||||
const serverService = useService(ServerService);
|
||||
const title = `Frontend: ${version}\nBackend: ${serverService.config.data?.version}`;
|
||||
export function TopNavBar() {
|
||||
const topNavBarService = useService(TopNavService);
|
||||
|
||||
return styled(useStyles(topNavBarStyles))(
|
||||
<header>
|
||||
<logo as="div" title={title}>
|
||||
<Icon name="logo" viewBox="0 0 361 73" />
|
||||
</logo>
|
||||
<MainMenu />
|
||||
<ConnectionSelector/>
|
||||
<fill as='div'/>
|
||||
<MainRightMenu />
|
||||
<SettingsMenu />
|
||||
<Placeholder container={topNavBarService.placeholder} />
|
||||
</header>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { injectable } from '@dbeaver/core/di';
|
||||
import { PlaceholderContainer } from '@dbeaver/core/placeholder';
|
||||
|
||||
import { ConnectionSelector } from './ConnectionSchemaManager/ConnectionSelector/ConnectionSelector';
|
||||
import { Fill } from './Fill';
|
||||
import { Logo } from './Logo';
|
||||
import { MainMenu } from './MainMenu/MainMenu';
|
||||
import { MainRightMenu } from './MainRightMenu/MainRightMenu';
|
||||
|
||||
@injectable()
|
||||
export class TopNavService {
|
||||
readonly placeholder = new PlaceholderContainer();
|
||||
|
||||
constructor() {
|
||||
this.placeholder.add(Logo, 0);
|
||||
this.placeholder.add(MainMenu, 1);
|
||||
this.placeholder.add(ConnectionSelector, 2);
|
||||
this.placeholder.add(Fill, 3);
|
||||
this.placeholder.add(MainRightMenu, 4);
|
||||
}
|
||||
}
|
||||
@@ -25,21 +25,5 @@ export const topNavBarStyles = composes(
|
||||
padding: 0 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
logo {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 16px;
|
||||
width: 250px;
|
||||
|
||||
& Icon {
|
||||
height: 24px;
|
||||
width: auto;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
fill {
|
||||
flex: 1;
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ export * from './TopNavBar/MainMenu/MainMenuService';
|
||||
export * from './TopNavBar/MainRightMenu/MainRightMenuService';
|
||||
export * from './TopNavBar/ConnectionSchemaManager/ConnectionSchemaManagerService';
|
||||
export * from './TopNavBar/SettingsMenu/SettingsMenuService';
|
||||
export * from './TopNavBar/TopNavBarService';
|
||||
export * from './shared/ConnectionsManager/ConnectionsManagerService';
|
||||
export * from './shared/ConnectionsManager/ConnectionDialogsService';
|
||||
export * from './shared/ConnectionsManager/extensions/IConnectionProvider';
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
MainMenuService, NavigationService, NavigationTreeService, NodesManagerService,
|
||||
ConnectionSchemaManagerService, NavigationTabsService,
|
||||
NavigationTreeContextMenuService,
|
||||
SettingsMenuService, LogViewerService, LogViewerMenuService, MainRightMenuService,
|
||||
SettingsMenuService, LogViewerService, LogViewerMenuService, MainRightMenuService, TopNavService,
|
||||
} from '@dbeaver/core/app';
|
||||
import { PluginManifest } from '@dbeaver/core/di';
|
||||
import { CommonDialogService, ContextMenuService, SessionExpireService } from '@dbeaver/core/dialogs';
|
||||
@@ -56,6 +56,7 @@ export const coreManifest: PluginManifest = {
|
||||
LogViewerMenuService,
|
||||
LogViewerService,
|
||||
MainMenuService,
|
||||
TopNavService,
|
||||
NavigationService,
|
||||
NavigationTabsService,
|
||||
NavigationTreeContextMenuService,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
import { PlaceholderContainer } from './PlaceholderContainer';
|
||||
|
||||
type Props<T = unknown> = T extends unknown ? {
|
||||
container: PlaceholderContainer<T>;
|
||||
context?: T;
|
||||
} :{
|
||||
container: PlaceholderContainer<T>;
|
||||
context: T;
|
||||
}
|
||||
|
||||
export const Placeholder = observer(function Placeholder<T = unknown>({ container, context }: Props<T>) {
|
||||
return (
|
||||
<>
|
||||
{container.get().map(({ id, component: Component }) => <Component key={id} context={context!} />)}
|
||||
</>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observable } from 'mobx';
|
||||
|
||||
import { uuid } from '@dbeaver/core/utils';
|
||||
|
||||
export type PlaceholderProps<T = unknown> = {
|
||||
context: T;
|
||||
}
|
||||
|
||||
export type PlaceholderComponent<T = unknown> = React.FunctionComponent<PlaceholderProps<T>>
|
||||
|
||||
export type PlaceholderElement<T = unknown> = {
|
||||
id: string;
|
||||
component: PlaceholderComponent<T>;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
export class PlaceholderContainer<T = unknown> {
|
||||
private placeholders = observable<PlaceholderElement<T>>([], { deep: false });
|
||||
|
||||
get() {
|
||||
return this.placeholders;
|
||||
}
|
||||
|
||||
add(component: PlaceholderComponent<T>, order?: number) {
|
||||
const placeholder: PlaceholderElement<T> = {
|
||||
id: uuid(),
|
||||
component,
|
||||
order,
|
||||
};
|
||||
|
||||
if (!order) {
|
||||
this.placeholders.push(placeholder);
|
||||
} else {
|
||||
const position = this.findPosition(order);
|
||||
console.log(position);
|
||||
this.placeholders.splice(position, 0, placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
private findPosition(order: number) {
|
||||
for (let i = 0; i < this.placeholders.length; i++) {
|
||||
const placeholder = this.placeholders[i];
|
||||
if (placeholder.order === undefined || order <= placeholder.order) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return this.placeholders.length;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './Placeholder';
|
||||
export * from './PlaceholderContainer';
|
||||
@@ -49,6 +49,7 @@ module.exports = (env, argv) => merge(commonConfig(env, argv), {
|
||||
"@dbeaver/core/extensions": path.resolve(__dirname, "../../../core/src/extensions"),
|
||||
"@dbeaver/core/product": path.resolve(__dirname, "../../../core/src/product"),
|
||||
"@dbeaver/core/plugin": path.resolve(__dirname, "../../../core/src/plugin"),
|
||||
"@dbeaver/core/placeholder": path.resolve(__dirname, "../../../core/src/placeholder"),
|
||||
|
||||
// rewrite imports for unnecessary work in `web/src/libs/sdk.ts`
|
||||
'graphql-tag': path.join(__dirname, '../../fix-gql.js'),
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
"@dbeaver/core/utils": ["packages/core/src/utils"],
|
||||
"@dbeaver/core/extensions": ["packages/core/src/extensions"],
|
||||
"@dbeaver/core/plugin": ["packages/core/src/plugin"],
|
||||
"@dbeaver/core/product": ["packages/core/src/product"]
|
||||
"@dbeaver/core/product": ["packages/core/src/product"],
|
||||
"@dbeaver/core/placeholder": ["packages/core/src/placeholder"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3216
-2808
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user