diff --git a/webapp/packages/administration/src/AdministrationMenuService.ts b/webapp/packages/administration/src/AdministrationMenuService.ts
index 650b843273..629be48fb4 100644
--- a/webapp/packages/administration/src/AdministrationMenuService.ts
+++ b/webapp/packages/administration/src/AdministrationMenuService.ts
@@ -6,33 +6,46 @@
* you may not use this file except in compliance with the License.
*/
-import { SettingsMenuService } from '@dbeaver/core/app';
-import { injectable } from '@dbeaver/core/di';
+import { SettingsMenuService, ScreenService, AppScreenService } from '@dbeaver/core/app';
+import { injectable, Bootstrap } from '@dbeaver/core/di';
import { PermissionsService } from '@dbeaver/core/root';
import { AdministrationScreenService } from './AdministrationScreen/AdministrationScreenService';
-
-export const ADMINISTRATION_PERMISSION = 'admin';
+import { EAdminPermission } from './EAdminPermission';
@injectable()
-export class AdministrationMenuService {
- static administrationMenuToken = 'administrationMenu';
+export class AdministrationMenuService extends Bootstrap {
constructor(
private settingsMenuService: SettingsMenuService,
private permissionsService: PermissionsService,
+ private screenService: ScreenService,
private administrationScreenService: AdministrationScreenService,
- ) { }
+ private appScreenService: AppScreenService
+ ) {
+ super();
+ }
- register() {
+ bootstrap() {
this.settingsMenuService.addMenuItem(
SettingsMenuService.settingsMenuToken,
{
- id: AdministrationMenuService.administrationMenuToken,
+ id: 'administrationMenuEnter',
order: 0,
- isHidden: () => !this.permissionsService.has(ADMINISTRATION_PERMISSION),
+ isHidden: () => !this.permissionsService.has(EAdminPermission.admin)
+ || this.screenService.isActive(AdministrationScreenService.screenName),
title: 'administration_menu_enter',
onClick: () => this.administrationScreenService.navigateToRoot(),
}
);
+ this.settingsMenuService.addMenuItem(
+ SettingsMenuService.settingsMenuToken,
+ {
+ id: 'administrationMenuBack',
+ order: 0,
+ isHidden: () => !this.screenService.isActive(AdministrationScreenService.screenName),
+ title: 'administration_menu_back',
+ onClick: () => this.appScreenService.navigateToRoot(),
+ }
+ );
}
}
diff --git a/webapp/packages/administration/src/AdministrationScreen/AdministrationScreen.tsx b/webapp/packages/administration/src/AdministrationScreen/AdministrationScreen.tsx
index e8eb7f588f..6cf20e05bc 100644
--- a/webapp/packages/administration/src/AdministrationScreen/AdministrationScreen.tsx
+++ b/webapp/packages/administration/src/AdministrationScreen/AdministrationScreen.tsx
@@ -6,6 +6,21 @@
* you may not use this file except in compliance with the License.
*/
-export function AdministrationScreen() {
- return <>Hello>;
-}
+import { observer } from 'mobx-react';
+
+import { usePermission } from '@dbeaver/core/root';
+
+import { EAdminPermission } from '../EAdminPermission';
+import { AdministrationTopAppBar } from './AdministrationTopAppBar/AdministrationTopAppBar';
+
+export const AdministrationScreen = observer(function AdministrationScreen() {
+ if (!usePermission(EAdminPermission.admin)) {
+ return <>You has no permission>;
+ }
+
+ return (
+ <>
+
+ >
+ );
+});
diff --git a/webapp/packages/administration/src/AdministrationScreen/AdministrationScreenService.ts b/webapp/packages/administration/src/AdministrationScreen/AdministrationScreenService.ts
index c5081f1f7c..de9a5997ac 100644
--- a/webapp/packages/administration/src/AdministrationScreen/AdministrationScreenService.ts
+++ b/webapp/packages/administration/src/AdministrationScreen/AdministrationScreenService.ts
@@ -6,26 +6,44 @@
* you may not use this file except in compliance with the License.
*/
-import { ScreenService, RouterService } from '@dbeaver/core/app';
-import { injectable } from '@dbeaver/core/di';
+import { ScreenService, RouterService, AppScreenService } from '@dbeaver/core/app';
+import { injectable, Bootstrap } from '@dbeaver/core/di';
+import { PermissionsService } from '@dbeaver/core/root';
+import { EAdminPermission } from '../EAdminPermission';
import { AdministrationScreen } from './AdministrationScreen';
@injectable()
-export class AdministrationScreenService {
+export class AdministrationScreenService extends Bootstrap {
static screenName = 'administration'
constructor(
private screenService: ScreenService,
private routerService: RouterService,
- ) {}
+ private permissionsService: PermissionsService,
+ private appScreenService: AppScreenService
+ ) {
+ super();
+ this.permissionsService.onUpdate.subscribe(this.handleActivate.bind(this));
+ }
navigateToRoot() {
- return this.routerService.router.navigate(AdministrationScreenService.screenName);
+ this.routerService.router.navigate(AdministrationScreenService.screenName);
}
- register() {
- this.screenService.add({ name: AdministrationScreenService.screenName, path: '/admin', component: AdministrationScreen });
+ bootstrap() {
+ this.screenService.create({
+ name: AdministrationScreenService.screenName,
+ path: '/admin',
+ component: AdministrationScreen,
+ onActivate: this.handleActivate.bind(this),
+ });
+ }
+
+ private handleActivate() {
+ if (!this.permissionsService.has(EAdminPermission.admin)) {
+ this.appScreenService.navigateToRoot();
+ }
}
}
diff --git a/webapp/packages/administration/src/AdministrationScreen/AdministrationTopAppBar/AdministrationTopAppBar.tsx b/webapp/packages/administration/src/AdministrationScreen/AdministrationTopAppBar/AdministrationTopAppBar.tsx
new file mode 100644
index 0000000000..67f8db9820
--- /dev/null
+++ b/webapp/packages/administration/src/AdministrationScreen/AdministrationTopAppBar/AdministrationTopAppBar.tsx
@@ -0,0 +1,22 @@
+/*
+ * 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 { Placeholder, TopAppBar } from '@dbeaver/core/blocks';
+import { useService } from '@dbeaver/core/di';
+
+import { AdministrationTopAppBarService } from './AdministrationTopAppBarService';
+
+export function AdministrationTopAppBar() {
+ const administrationTopAppBarService = useService(AdministrationTopAppBarService);
+
+ return (
+
+
+
+ );
+}
diff --git a/webapp/packages/administration/src/AdministrationScreen/AdministrationTopAppBar/AdministrationTopAppBarService.ts b/webapp/packages/administration/src/AdministrationScreen/AdministrationTopAppBar/AdministrationTopAppBarService.ts
new file mode 100644
index 0000000000..bcd0ae00a8
--- /dev/null
+++ b/webapp/packages/administration/src/AdministrationScreen/AdministrationTopAppBar/AdministrationTopAppBarService.ts
@@ -0,0 +1,24 @@
+/*
+ * 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 { SettingsMenu, Logo } from '@dbeaver/core/app';
+import { PlaceholderContainer } from '@dbeaver/core/blocks';
+import { injectable } from '@dbeaver/core/di';
+
+import { Fill } from './Fill';
+
+@injectable()
+export class AdministrationTopAppBarService {
+ readonly placeholder = new PlaceholderContainer();
+
+ constructor() {
+ this.placeholder.add(Logo, 0);
+ this.placeholder.add(Fill, 3);
+ this.placeholder.add(SettingsMenu, 4);
+ }
+}
diff --git a/webapp/packages/administration/src/AdministrationScreen/AdministrationTopAppBar/Fill.tsx b/webapp/packages/administration/src/AdministrationScreen/AdministrationTopAppBar/Fill.tsx
new file mode 100644
index 0000000000..54bdf739be
--- /dev/null
+++ b/webapp/packages/administration/src/AdministrationScreen/AdministrationTopAppBar/Fill.tsx
@@ -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)();
+}
diff --git a/webapp/packages/administration/src/Bootstrap.ts b/webapp/packages/administration/src/Bootstrap.ts
deleted file mode 100644
index d5f2a72de9..0000000000
--- a/webapp/packages/administration/src/Bootstrap.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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 { AdministrationMenuService } from './AdministrationMenuService';
-import { AdministrationScreenService } from './AdministrationScreen/AdministrationScreenService';
-
-@injectable()
-export class Bootstrap {
- constructor(
- private administrationMenuService: AdministrationMenuService,
- private administrationScreenService: AdministrationScreenService,
- ) { }
-
- bootstrap() {
- this.administrationScreenService.register();
- this.administrationMenuService.register();
- }
-}
diff --git a/webapp/packages/administration/src/EAdminPermission.ts b/webapp/packages/administration/src/EAdminPermission.ts
new file mode 100644
index 0000000000..c1c7cddd49
--- /dev/null
+++ b/webapp/packages/administration/src/EAdminPermission.ts
@@ -0,0 +1,11 @@
+/*
+ * 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.
+ */
+
+export enum EAdminPermission {
+ admin = 'admin'
+}
diff --git a/webapp/packages/administration/src/index.ts b/webapp/packages/administration/src/index.ts
index 72c5cfecc9..41181aba8c 100644
--- a/webapp/packages/administration/src/index.ts
+++ b/webapp/packages/administration/src/index.ts
@@ -3,3 +3,5 @@ import { manifest } from './manifest';
export default manifest;
export * from './AdministrationMenuService';
+export * from './AdministrationScreen/AdministrationScreenService';
+export * from './AdministrationScreen/AdministrationTopAppBar/AdministrationTopAppBarService';
diff --git a/webapp/packages/administration/src/manifest.ts b/webapp/packages/administration/src/manifest.ts
index 4acf5d475d..955e91126d 100644
--- a/webapp/packages/administration/src/manifest.ts
+++ b/webapp/packages/administration/src/manifest.ts
@@ -10,7 +10,7 @@ import { IServiceInjector, PluginManifest } from '@dbeaver/core/di';
import { AdministrationMenuService } from './AdministrationMenuService';
import { AdministrationScreenService } from './AdministrationScreen/AdministrationScreenService';
-import { Bootstrap } from './Bootstrap';
+import { AdministrationTopAppBarService } from './AdministrationScreen/AdministrationTopAppBar/AdministrationTopAppBarService';
export const manifest: PluginManifest = {
info: {
@@ -20,11 +20,9 @@ export const manifest: PluginManifest = {
providers: [
AdministrationMenuService,
AdministrationScreenService,
+ AdministrationTopAppBarService,
],
async initialize(services: IServiceInjector) {
- services
- .resolveServiceByClass(Bootstrap)
- .bootstrap();
},
};
diff --git a/webapp/packages/authentication/package.json b/webapp/packages/authentication/package.json
index dde951a9e1..bbb32ddcb6 100644
--- a/webapp/packages/authentication/package.json
+++ b/webapp/packages/authentication/package.json
@@ -12,10 +12,12 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
- "@dbeaver/core": "^0.1.0",
- "@dbeaver/builder": "^0.1.0"
+ "@dbeaver/administration": "^0.1.0",
+ "@dbeaver/builder": "^0.1.0",
+ "@dbeaver/core": "^0.1.0"
},
"peerDependencies": {
+ "@dbeaver/administration": "^0.1.0",
"@dbeaver/core": "^0.1.0"
}
}
diff --git a/webapp/packages/authentication/src/AuthMenuService.ts b/webapp/packages/authentication/src/AuthMenuService.ts
index 0ed1ee92a4..16c998f1ce 100644
--- a/webapp/packages/authentication/src/AuthMenuService.ts
+++ b/webapp/packages/authentication/src/AuthMenuService.ts
@@ -6,6 +6,7 @@
* you may not use this file except in compliance with the License.
*/
+import { AdministrationTopAppBarService } from '@dbeaver/administration';
import { SettingsMenuService, TopNavService } from '@dbeaver/core/app';
import { injectable } from '@dbeaver/core/di';
import { ServerService } from '@dbeaver/core/root';
@@ -24,6 +25,7 @@ export class AuthMenuService {
private settingsMenuService: SettingsMenuService,
private authenticationService: AuthenticationService,
private topNavService: TopNavService,
+ private administrationTopAppBarService: AdministrationTopAppBarService,
) { }
register() {
@@ -50,6 +52,7 @@ export class AuthMenuService {
);
this.topNavService.placeholder.add(UserInfo, 4);
+ this.administrationTopAppBarService.placeholder.add(UserInfo, 4);
}
private async logout() {
diff --git a/webapp/packages/core/assets/locales/en.js b/webapp/packages/core/assets/locales/en.js
index 740bb9c556..e47957ffb9 100644
--- a/webapp/packages/core/assets/locales/en.js
+++ b/webapp/packages/core/assets/locales/en.js
@@ -42,6 +42,7 @@ module.exports = {
data_transfer_exporting_sql: 'SQL:',
administration_menu_enter: 'Administration',
+ administration_menu_back: 'Back to app',
authentication_login_dialog_title: 'Authentication',
authentication_login: 'Login',
diff --git a/webapp/packages/core/assets/locales/ru.js b/webapp/packages/core/assets/locales/ru.js
index 4f5a6ed5db..b652c1dae6 100644
--- a/webapp/packages/core/assets/locales/ru.js
+++ b/webapp/packages/core/assets/locales/ru.js
@@ -41,6 +41,7 @@ module.exports = {
data_transfer_exporting_sql: 'SQL:',
administration_menu_enter: 'Администрирование',
+ administration_menu_back: 'Вернуться в приложение',
authentication_login_dialog_title: 'Авторизация',
authentication_login: 'Войти',
diff --git a/webapp/packages/core/src/app/AppScreen/AppScreen.tsx b/webapp/packages/core/src/app/AppScreen/AppScreen.tsx
index 702c3734c0..c8c2aac465 100644
--- a/webapp/packages/core/src/app/AppScreen/AppScreen.tsx
+++ b/webapp/packages/core/src/app/AppScreen/AppScreen.tsx
@@ -6,9 +6,6 @@
* you may not use this file except in compliance with the License.
*/
-import { DialogsPortal } from '@dbeaver/core/dialogs';
-
-import { Notifications } from '../Notifications/Notifications';
import { TopNavBar } from '../TopNavBar/TopNavBar';
import { Main } from './Main';
@@ -18,8 +15,6 @@ export function AppScreen() {
<>
-
-
>
);
}
diff --git a/webapp/packages/core/src/app/AppScreen/AppScreenService.ts b/webapp/packages/core/src/app/AppScreen/AppScreenService.ts
index c51fe18354..2169015209 100644
--- a/webapp/packages/core/src/app/AppScreen/AppScreenService.ts
+++ b/webapp/packages/core/src/app/AppScreen/AppScreenService.ts
@@ -8,17 +8,25 @@
import { injectable } from '@dbeaver/core/di';
+import { RouterService } from '../RouterService';
import { ScreenService } from '../Screen/ScreenService';
import { AppScreen } from './AppScreen';
@injectable()
export class AppScreenService {
+ static screenName = 'app'
+
constructor(
- private screenService: ScreenService
+ private screenService: ScreenService,
+ private routerService: RouterService,
) {}
+ navigateToRoot() {
+ this.routerService.router.navigate(AppScreenService.screenName);
+ }
+
register() {
- this.screenService.add({ name: 'app', path: '/', component: AppScreen });
+ this.screenService.create({ name: AppScreenService.screenName, path: '/', component: AppScreen });
}
}
diff --git a/webapp/packages/core/src/app/Body.tsx b/webapp/packages/core/src/app/Body.tsx
index 19a5167704..e016f6b8e5 100644
--- a/webapp/packages/core/src/app/Body.tsx
+++ b/webapp/packages/core/src/app/Body.tsx
@@ -10,8 +10,10 @@ import { observer } from 'mobx-react';
import styled, { css } from 'reshadow';
import { useService } from '@dbeaver/core/di';
+import { DialogsPortal } from '@dbeaver/core/dialogs';
import { useStyles, useTheme } from '@dbeaver/core/theming';
+import { Notifications } from './Notifications/Notifications';
import { ScreenService } from './Screen/ScreenService';
const bodyStyles = css`
@@ -31,6 +33,8 @@ export const Body = observer(function Body() {
return styled(useStyles(bodyStyles))(
{Screen && }
+
+
);
});
diff --git a/webapp/packages/core/src/app/Screen/ScreenService.ts b/webapp/packages/core/src/app/Screen/ScreenService.ts
index 998b0797ef..4b4b15827f 100644
--- a/webapp/packages/core/src/app/Screen/ScreenService.ts
+++ b/webapp/packages/core/src/app/Screen/ScreenService.ts
@@ -28,7 +28,7 @@ export class ScreenService {
this.routerService.subscribe(this.onRouteChange.bind(this));
}
- add(screen: IScreen) {
+ create(screen: IScreen) {
if (this.screens.has(screen.name)) {
return;
}
@@ -37,6 +37,14 @@ export class ScreenService {
this.routerService.router.add({ name: screen.name, path: screen.path });
}
+ isActive(name: string, strict = false): boolean {
+ if (strict) {
+ return this.screen?.name === name;
+ }
+
+ return this.screen?.name.startsWith(name) || false;
+ }
+
buildUrl(screen: string) {
return this.routerService.router.buildUrl(screen);
}
diff --git a/webapp/packages/core/src/app/TopNavBar/Logo.tsx b/webapp/packages/core/src/app/TopNavBar/Logo.tsx
index 4439d512e3..5f5fe8208e 100644
--- a/webapp/packages/core/src/app/TopNavBar/Logo.tsx
+++ b/webapp/packages/core/src/app/TopNavBar/Logo.tsx
@@ -7,37 +7,20 @@
*/
import { observer } from 'mobx-react';
-import styled, { css } from 'reshadow';
-import { Icon } from '@dbeaver/core/blocks';
+import { AppLogo } from '@dbeaver/core/blocks';
import { useService } from '@dbeaver/core/di';
import { ServerService } from '@dbeaver/core/root';
+import { AppScreenService } from '../AppScreen/AppScreenService';
+
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 appScreenService = useService(AppScreenService);
+
const title = `Frontend: ${version}\nBackend: ${serverService.config.data?.version}`;
- return styled(styles)(
-
-
-
- );
+ return appScreenService.navigateToRoot()}/>;
});
diff --git a/webapp/packages/core/src/app/TopNavBar/TopNavBar.tsx b/webapp/packages/core/src/app/TopNavBar/TopNavBar.tsx
index f1ac6baa5f..207f59faca 100644
--- a/webapp/packages/core/src/app/TopNavBar/TopNavBar.tsx
+++ b/webapp/packages/core/src/app/TopNavBar/TopNavBar.tsx
@@ -6,21 +6,17 @@
* you may not use this file except in compliance with the License.
*/
-import styled from 'reshadow';
-
-import { Placeholder } from '@dbeaver/core/blocks';
+import { Placeholder, TopAppBar } from '@dbeaver/core/blocks';
import { useService } from '@dbeaver/core/di';
-import { useStyles } from '@dbeaver/core/theming';
import { TopNavService } from './TopNavBarService';
-import { topNavBarStyles } from './topNavBarStyles';
export function TopNavBar() {
const topNavBarService = useService(TopNavService);
- return styled(useStyles(topNavBarStyles))(
-
+
);
}
diff --git a/webapp/packages/core/src/app/index.ts b/webapp/packages/core/src/app/index.ts
index 5296588631..2c2c7e761f 100644
--- a/webapp/packages/core/src/app/index.ts
+++ b/webapp/packages/core/src/app/index.ts
@@ -44,6 +44,8 @@ export * from './shared/InlineEditor/InlineEditor';
// components
export * from './Body';
export * from './Notifications/NotificationsItem/ErrorDetailsDialog/ErrorDetailsDialog';
+export * from './TopNavBar/SettingsMenu/SettingsMenu';
+export * from './TopNavBar/Logo';
// Interfaces
export * from './shared/Navigation/INavigator';
diff --git a/webapp/packages/core/src/blocks/Placeholder/PlaceholderContainer.ts b/webapp/packages/core/src/blocks/Placeholder/PlaceholderContainer.ts
index 52c589a657..cb3d48ebea 100644
--- a/webapp/packages/core/src/blocks/Placeholder/PlaceholderContainer.ts
+++ b/webapp/packages/core/src/blocks/Placeholder/PlaceholderContainer.ts
@@ -22,7 +22,7 @@ export type PlaceholderElement = {
order?: number;
}
-export class PlaceholderContainer {
+export class PlaceholderContainer {
private placeholders = observable>([], { deep: false });
get() {
diff --git a/webapp/packages/core/src/blocks/index.ts b/webapp/packages/core/src/blocks/index.ts
index a688b5421a..dba7030142 100644
--- a/webapp/packages/core/src/blocks/index.ts
+++ b/webapp/packages/core/src/blocks/index.ts
@@ -1,22 +1,23 @@
-export * from './Icons';
-export * from './Split';
-export * from './StaticImage';
export * from './ComplexLoader';
-export * from './Loader/Loader';
-export * from './StaticImage';
-export * from './Tabs';
-export * from './Button';
-export * from './Radio';
-export * from './InputField';
-export * from './ShadowInput';
-export * from './ErrorMessage';
-export * from './IconOrImage';
-export * from './TextPlaceholder';
-export * from './useClipboard';
-export * from './SubmittingForm';
-export * from './SanitizedHTML/SanitizedHTML';
+export * from './Icons';
export * from './ItemList';
-export * from './PropertiesTable';
-export * from './IconButton';
+export * from './layout/AppLogo';
+export * from './layout/TopAppBar';
+export * from './Loader/Loader';
export * from './Placeholder/Placeholder';
export * from './Placeholder/PlaceholderContainer';
+export * from './PropertiesTable';
+export * from './SanitizedHTML/SanitizedHTML';
+export * from './Split';
+export * from './Tabs';
+export * from './Button';
+export * from './ErrorMessage';
+export * from './IconButton';
+export * from './IconOrImage';
+export * from './InputField';
+export * from './Radio';
+export * from './ShadowInput';
+export * from './StaticImage';
+export * from './SubmittingForm';
+export * from './TextPlaceholder';
+export * from './useClipboard';
diff --git a/webapp/packages/core/src/blocks/layout/AppLogo.tsx b/webapp/packages/core/src/blocks/layout/AppLogo.tsx
new file mode 100644
index 0000000000..4b074003e5
--- /dev/null
+++ b/webapp/packages/core/src/blocks/layout/AppLogo.tsx
@@ -0,0 +1,41 @@
+/*
+ * 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';
+
+import { Icon } from '../Icons/Icon';
+
+const styles = css`
+ logo {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ margin-right: 16px;
+ width: 250px;
+ cursor: pointer;
+ }
+
+ Icon {
+ height: 24px;
+ width: auto;
+ margin-bottom: 2px;
+ }
+`;
+
+type Props = {
+ title: string;
+ onClick?: () => void;
+}
+
+export function AppLogo({ title, onClick }: Props) {
+ return styled(styles)(
+
+
+
+ );
+}
diff --git a/webapp/packages/core/src/app/TopNavBar/topNavBarStyles.ts b/webapp/packages/core/src/blocks/layout/TopAppBar.tsx
similarity index 62%
rename from webapp/packages/core/src/app/TopNavBar/topNavBarStyles.ts
rename to webapp/packages/core/src/blocks/layout/TopAppBar.tsx
index 18aa0f60e8..1d28fa0bb0 100644
--- a/webapp/packages/core/src/app/TopNavBar/topNavBarStyles.ts
+++ b/webapp/packages/core/src/blocks/layout/TopAppBar.tsx
@@ -6,11 +6,11 @@
* you may not use this file except in compliance with the License.
*/
-import { css } from 'reshadow';
+import styled, { css } from 'reshadow';
-import { composes } from '@dbeaver/core/theming';
+import { useStyles, composes } from '@dbeaver/core/theming';
-export const topNavBarStyles = composes(
+export const topAppBarStyles = composes(
css`
header {
composes: theme-background-primary theme-text-on-primary from global;
@@ -27,3 +27,11 @@ export const topNavBarStyles = composes(
}
`
);
+
+export function TopAppBar({ children }: React.PropsWithChildren<{}>) {
+ return styled(useStyles(topAppBarStyles))(
+
+ );
+}
diff --git a/webapp/packages/core/src/bootstrap.ts b/webapp/packages/core/src/bootstrap.ts
index 87e2a02fe6..1c824d7ad9 100644
--- a/webapp/packages/core/src/bootstrap.ts
+++ b/webapp/packages/core/src/bootstrap.ts
@@ -13,6 +13,7 @@ export async function bootstrap(plugins: PluginManifest[]) {
try {
await appBootstrap.init();
+ await app.initializeServices();
await app.initializePlugins();
await appBootstrap.doAfterPluginsInit();
await app.load();
diff --git a/webapp/packages/core/src/di/App.ts b/webapp/packages/core/src/di/App.ts
index 3e2deee34a..95ced75684 100644
--- a/webapp/packages/core/src/di/App.ts
+++ b/webapp/packages/core/src/di/App.ts
@@ -6,6 +6,7 @@
* you may not use this file except in compliance with the License.
*/
+import { Bootstrap } from './Bootstrap';
import { DIContainer } from './DIContainer';
import { RootContainerService } from './entities/RootContainerService';
import { IServiceCollection, IServiceInjector } from './IApp';
@@ -55,6 +56,18 @@ export class App {
}
}
+ async initializeServices() {
+ for (const plugin of this.plugins) {
+ for (const service of plugin.providers) {
+ if (service.prototype instanceof Bootstrap) {
+ const serviceInstance = this.diWrapper.injector.getServiceByClass(service);
+
+ await serviceInstance.bootstrap();
+ }
+ }
+ }
+ }
+
// second phase - run init scripts todo run it based on dependency tree
async initializePlugins() {
for (const plugin of this.plugins) {
diff --git a/webapp/packages/core/src/di/Bootstrap.ts b/webapp/packages/core/src/di/Bootstrap.ts
new file mode 100644
index 0000000000..6f7a37b6c2
--- /dev/null
+++ b/webapp/packages/core/src/di/Bootstrap.ts
@@ -0,0 +1,14 @@
+/*
+ * 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 './injectable';
+
+@injectable()
+export abstract class Bootstrap {
+ abstract bootstrap(): void | Promise;
+}
diff --git a/webapp/packages/core/src/di/index.ts b/webapp/packages/core/src/di/index.ts
index e46b7ac9a6..af0b07fbd7 100644
--- a/webapp/packages/core/src/di/index.ts
+++ b/webapp/packages/core/src/di/index.ts
@@ -1,6 +1,7 @@
export * from './IApp';
export * from './App';
export * from './AppContext';
+export * from './Bootstrap';
export * from './injectable';
export * from './PluginManifest';
export * from './useService';
diff --git a/webapp/packages/core/src/theming/ThemeService.ts b/webapp/packages/core/src/theming/ThemeService.ts
index 130a01e0a7..b927dffba1 100644
--- a/webapp/packages/core/src/theming/ThemeService.ts
+++ b/webapp/packages/core/src/theming/ThemeService.ts
@@ -60,11 +60,11 @@ export class ThemeService {
constructor(private notificationService: NotificationService,
private settingsService: SettingsService) {
+ this.loadAllThemes();
}
async init() {
this.settingsService.registerSettings(this.settings, THEME_SETTINGS_KEY);
- await this.loadAllThemesAsync();
await this.changeThemeAsync(this.currentThemeId);
}
@@ -95,7 +95,7 @@ export class ThemeService {
this.settings.currentThemeId = themeId;
}
- private async loadAllThemesAsync(): Promise {
+ private loadAllThemes(): void {
for (const theme of themes) {
this.themeMap.set(theme.id, theme);
}