Merge pull request #152 from dbeaver/feat-administration-redesign

feat(plugin-authentication): administration redesign
This commit is contained in:
Serge Rider
2020-09-01 08:36:57 +03:00
committed by GitHub
17 changed files with 442 additions and 326 deletions
@@ -26,13 +26,13 @@ export type AdministrationItemDrawerComponent = React.FunctionComponent<Administ
export type AdministrationItemContentProps = {
item: IAdministrationItem;
configurationWizard: boolean;
sub?: IAdministrationItemSubItem;
param?: string | null;
}
export type AdministrationItemContentComponent = React.FunctionComponent<AdministrationItemContentProps>
export type AdministrationItemSubContentProps = {
item: IAdministrationItem;
export type AdministrationItemSubContentProps = AdministrationItemContentProps & {
sub: IAdministrationItemSubItem;
configurationWizard: boolean;
param: string | null;
}
export type AdministrationItemSubContentComponent = React.FunctionComponent<AdministrationItemSubContentProps>
@@ -27,7 +27,7 @@ export class AdministrationScreenServiceBootstrap extends Bootstrap {
private serverConfigResource: ServerConfigResource
) {
super();
this.permissionsService.onUpdate.subscribe(this.handleActivate.bind(this));
this.permissionsService.onUpdate.subscribe(this.checkPermissions.bind(this));
}
register() {
@@ -110,8 +110,7 @@ export class AdministrationScreenServiceBootstrap extends Bootstrap {
}
private async handleActivate() {
if (!await this.isAccessProvided()) {
this.screenService.navigateToRoot();
if (!await this.checkPermissions()) {
return;
}
@@ -125,8 +124,16 @@ export class AdministrationScreenServiceBootstrap extends Bootstrap {
}
}
private async checkPermissions() {
if (!await this.isAccessProvided()) {
this.screenService.navigateToRoot();
return false;
}
return true;
}
private async isAccessProvided() {
if (await !this.permissionsService.hasAsync(EAdminPermission.admin)) {
if (!await this.permissionsService.hasAsync(EAdminPermission.admin)) {
return false;
}
@@ -0,0 +1,53 @@
/*
* 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 { Translate } from '@cloudbeaver/core-localization/src';
import { AdminUserInfo } from '@cloudbeaver/core-sdk';
import { useStyles, composes } from '@cloudbeaver/core-theming';
import { UserForm } from './UserForm/UserForm';
type Props = {
user: AdminUserInfo;
onCancel: () => void;
}
const styles = composes(
css`
title-bar {
composes: theme-border-color-background from global;
}
`,
css`
title-bar {
composes: theme-typography--headline6 from global;
padding: 0 16px;
border-top: solid 1px;
align-items: center;
height: 48px;
display: flex;
font-weight: 400;
flex: 1;
}
`
);
export function CreateUser({
user,
onCancel,
}: Props) {
return styled(useStyles(styles))(
<user-create as='div'>
<title-bar as='div'><Translate token='authentication_administration_user_connections_user_add'/></title-bar>
<UserForm userId={user.userId} onCancel={onCancel} />
</user-create>
);
}
@@ -0,0 +1,276 @@
/*
* 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 { useCallback } from 'react';
import styled, { css } from 'reshadow';
import {
TabsState, TabList, Tab,
TabTitle, Loader, SubmittingForm, TabPanel,
ErrorMessage, Button,
InputField,
Checkbox,
useFocus,
InputGroup
} from '@cloudbeaver/core-blocks';
import { useController } from '@cloudbeaver/core-di';
import { useTranslate } from '@cloudbeaver/core-localization';
import { useStyles, composes } from '@cloudbeaver/core-theming';
import { GrantedConnections } from './GrantedConnections';
import { UserFormController } from './UserFormController';
const styles = composes(
css`
Tab {
composes: theme-ripple theme-background-secondary theme-text-on-secondary from global;
}
TabList {
composes: theme-background-surface theme-text-on-surface from global;
}
ErrorMessage {
composes: theme-background-secondary from global;
}
box {
composes: theme-background-secondary theme-text-on-secondary from global;
}
content-box {
composes: theme-background-secondary theme-border-color-background from global;
}
GrantedConnections {
composes: theme-background-surface from global;
}
`,
css`
box {
padding: 24px;
}
SubmittingForm {
flex: 1;
display: flex;
flex-direction: column;
}
TabList {
align-items: center;
box-sizing: border-box;
display: inline-flex;
width: 100%;
padding-left: 24px;
outline: none;
}
TabPanel {
overflow: auto !important;
}
Tab {
composes: theme-typography--body2 from global;
text-transform: uppercase;
font-weight: normal;
&:global([aria-selected=true]) {
font-weight: normal !important;
}
& TabTitle {
padding: 0 24px !important;
}
}
ErrorMessage {
position: sticky;
bottom: 0;
padding: 8px 24px;
}
fill {
flex: 1;
}
SubmittingForm {
position: relative;
min-height: 320px;
max-height: 500px;
}
Button:not(:first-child) {
margin-right: 24px;
}
layout-grid {
flex: 1;
width: 100%;
}
flex-box {
flex: 1;
display: flex;
flex-wrap: wrap;
}
flex-box-element {
min-width: 450px;
}
`
);
type Props = {
userId: string;
onCancel: () => void;
}
export const UserForm = observer(function UserForm({
userId,
onCancel,
}: Props) {
const translate = useTranslate();
const controller = useController(UserFormController, userId, onCancel);
const [focusedRef] = useFocus({ focusFirstChild: true });
const handleLoginChange = useCallback(
(value: string) => controller.credentials.login = value,
[]
);
const handlePasswordChange = useCallback(
(value: string) => controller.credentials.password = value,
[]
);
const handlePasswordRepeatChange = useCallback(
(value: string) => controller.credentials.passwordRepeat = value,
[]
);
const handleRoleChange = useCallback(
(roleId: string, value: boolean) => controller.credentials.roles.set(roleId, value),
[]
);
return styled(useStyles(styles))(
<TabsState selectedId='info'>
<box as='div'>
<TabList>
<Tab tabId='info' >
<TabTitle>{translate('authentication_administration_user_info')}</TabTitle>
</Tab>
<Tab tabId='connections_access' onOpen={controller.loadConnectionsAccess} >
<TabTitle>{translate('authentication_administration_user_connections_access')}</TabTitle>
</Tab>
<fill as="div" />
<Button
type="button"
disabled={controller.isSaving}
mod={['outlined']}
onClick={onCancel}
>
{translate('ui_processing_cancel')}
</Button>
<Button
type="button"
disabled={controller.isSaving}
mod={['unelevated']}
onClick={controller.save}
>
{translate(controller.isNew ? 'ui_processing_create' : 'ui_processing_save')}
</Button>
</TabList>
<content-box as='div'>
<SubmittingForm onSubmit={controller.save} ref={focusedRef as React.RefObject<HTMLFormElement>}>
<TabPanel tabId='info'>
<flex-box as="div">
<flex-box-element as='div'>
<group as="div">
<InputGroup>{translate('authentication_user_credentials')}</InputGroup>
</group>
<group as="div">
<InputField
type='text'
name='login'
value={controller.credentials.login}
onChange={handleLoginChange}
disabled={!controller.isNew || controller.isSaving}
mod='surface'
required
>
{translate('authentication_user_name')}
</InputField>
</group>
<group as="div">
<InputField
type='password'
name='password'
value={controller.credentials.password}
onChange={handlePasswordChange}
disabled={controller.isSaving}
mod='surface'
>
{translate('authentication_user_password')}
</InputField>
</group>
<group as="div">
<InputField
type='password'
name='password_repeat'
value={controller.credentials.passwordRepeat}
onChange={handlePasswordRepeatChange}
disabled={controller.isSaving}
mod='surface'
>
{translate('authentication_user_password_repeat')}
</InputField>
</group>
</flex-box-element>
<flex-box-element as='div'>
<group as="div">
<InputGroup>{translate('authentication_user_role')}</InputGroup>
</group>
{controller.roles.map((role, i) => (
<group as="div" key={role.roleId}>
<Checkbox
value={role.roleId}
name='role'
checkboxLabel={role.roleName || role.roleId}
onChange={checked => handleRoleChange(role.roleId, checked)}
checked={controller.credentials.roles.get(role.roleId)}
disabled={controller.isSaving}
mod='surface'
/>
</group>
))}
</flex-box-element>
</flex-box>
</TabPanel>
{controller.isLoading && <Loader overlay/>}
<TabPanel tabId='connections_access'>
<GrantedConnections
grantedConnections={controller.grantedConnections}
connections={controller.connections}
selectedConnection={controller.selectedConnections}
disabled={controller.isLoading}
onChange={controller.handleConnectionsAccessChange}
/>
</TabPanel>
</SubmittingForm>
{controller.error.responseMessage && (
<ErrorMessage
text={controller.error.responseMessage}
hasDetails={controller.error.hasDetails}
onShowDetails={controller.showDetails}
/>
)}
</content-box>
</box>
</TabsState>
);
});
@@ -19,7 +19,7 @@ import {
} from '@cloudbeaver/core-sdk';
@injectable()
export class UserEditController implements IInitializableController, IDestructibleController {
export class UserFormController implements IInitializableController, IDestructibleController {
readonly selectedConnections = observable<string, boolean>(new Map())
@observable grantedConnections: AdminConnectionGrantInfo[] = [];
@observable isSaving = false;
@@ -9,11 +9,12 @@
import { observer } from 'mobx-react';
import styled, { css, use } from 'reshadow';
import { AdministrationTools } from '@cloudbeaver/core-administration';
import { AdministrationTools, AdministrationItemContentProps } from '@cloudbeaver/core-administration';
import { Loader, IconButton } from '@cloudbeaver/core-blocks';
import { useController } from '@cloudbeaver/core-di';
import { useStyles, composes } from '@cloudbeaver/core-theming';
import { CreateUser } from './CreateUser';
import { UsersAdministrationController } from './UsersAdministrationController';
import { UsersTable } from './UsersTable/UsersTable';
@@ -55,7 +56,9 @@ const styles = composes(
`
);
export const UsersAdministration = observer(function UsersAdministration() {
export const UsersAdministration = observer(function UsersAdministration({
sub,
}: AdministrationItemContentProps) {
const controller = useController(UsersAdministrationController);
return styled(useStyles(styles))(
@@ -67,6 +70,9 @@ export const UsersAdministration = observer(function UsersAdministration() {
<IconButton name="trash" viewBox="0 0 28 28" onClick={controller.delete} />
<IconButton name="reload" viewBox="0 0 28 28" onClick={controller.update} />
</AdministrationTools>
{sub && controller.creatingUser && (
<CreateUser user={controller.creatingUser} onCancel={controller.cancelCreate} />
)}
<UsersTable
users={controller.users}
selectedItems={controller.selectedItems}
@@ -6,7 +6,7 @@
* you may not use this file except in compliance with the License.
*/
import { observable } from 'mobx';
import { observable, computed } from 'mobx';
import { UsersResource } from '@cloudbeaver/core-authentication';
import { injectable } from '@cloudbeaver/core-di';
@@ -15,14 +15,18 @@ import { NotificationService } from '@cloudbeaver/core-events';
import { ErrorDetailsDialog } from '@cloudbeaver/core-notifications';
import { GQLErrorCatcher, resourceKeyList } from '@cloudbeaver/core-sdk';
import { UsersAdministrationNavigationService } from './UsersAdministrationNavigationService';
@injectable()
export class UsersAdministrationController {
@observable isDeleting = false;
readonly selectedItems = observable<string, boolean>(new Map())
readonly expandedItems = observable<string, boolean>(new Map())
readonly error = new GQLErrorCatcher();
get users() {
@computed get users() {
return Array.from(this.usersResource.data.values())
.filter(user => !this.usersResource.isNew(user.userId))
.sort((a, b) => {
if (this.usersResource.isNew(a.userId) === this.usersResource.isNew(b.userId)) {
return 0;
@@ -34,6 +38,11 @@ export class UsersAdministrationController {
});
}
@computed get creatingUser() {
return Array.from(this.usersResource.data.values())
.find(user => this.usersResource.isNew(user.userId));
}
get isLoading() {
return this.usersResource.isLoading() || this.isDeleting;
}
@@ -42,11 +51,21 @@ export class UsersAdministrationController {
private notificationService: NotificationService,
private usersResource: UsersResource,
private commonDialogService: CommonDialogService,
private usersAdministrationNavigationService: UsersAdministrationNavigationService,
) { }
create = () => {
const user = this.usersResource.addNew();
this.expandedItems.set(user.userId, true);
this.usersResource.addNew();
this.usersAdministrationNavigationService.navToAdd();
}
cancelCreate = () => {
if (!this.creatingUser) {
return;
}
this.usersResource.delete(this.creatingUser.userId);
this.usersAdministrationNavigationService.navToRoot();
}
update = async () => {
@@ -0,0 +1,31 @@
/*
* 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 { AdministrationScreenService } from '@cloudbeaver/core-administration';
import { injectable } from '@cloudbeaver/core-di';
@injectable()
export class UsersAdministrationNavigationService {
static ItemName = 'users'
static AddItemName = 'add'
constructor(
private administrationScreenService: AdministrationScreenService,
) {}
navToRoot() {
this.administrationScreenService.navigateToItem(UsersAdministrationNavigationService.ItemName);
}
navToAdd() {
this.administrationScreenService.navigateToItemSub(
UsersAdministrationNavigationService.ItemName,
UsersAdministrationNavigationService.AddItemName
);
}
}
@@ -6,19 +6,19 @@
* you may not use this file except in compliance with the License.
*/
import { AdministrationItemService, AdministrationScreenService } from '@cloudbeaver/core-administration';
import { AdministrationItemService } from '@cloudbeaver/core-administration';
import { UsersResource } from '@cloudbeaver/core-authentication';
import { injectable, Bootstrap } from '@cloudbeaver/core-di';
import { NotificationService } from '@cloudbeaver/core-events';
import { UsersAdministration } from './UsersAdministration';
import { UsersAdministrationNavigationService } from './UsersAdministrationNavigationService';
import { UsersDrawerItem } from './UsersDrawerItem';
@injectable()
export class UsersAdministrationService extends Bootstrap {
constructor(
private administrationItemService: AdministrationItemService,
private administrationScreenService: AdministrationScreenService,
private notificationService: NotificationService,
private usersResource: UsersResource,
) {
@@ -27,12 +27,13 @@ export class UsersAdministrationService extends Bootstrap {
register() {
this.administrationItemService.create({
name: 'users',
name: UsersAdministrationNavigationService.ItemName,
order: 1,
sub: [
{
name: 'edit',
name: UsersAdministrationNavigationService.AddItemName,
getComponent: () => UsersAdministration,
onActivate: this.onCreateActivate.bind(this),
},
],
getContentComponent: () => UsersAdministration,
@@ -43,12 +44,11 @@ export class UsersAdministrationService extends Bootstrap {
load(): void | Promise<void> { }
navToRoot() {
this.administrationScreenService.navigateToItem('users');
}
navToEdit(userId: string) {
this.administrationScreenService.navigateToItemSub('users', 'edit', userId);
private onCreateActivate() {
if (!Array.from(this.usersResource.data.values())
.some(user => this.usersResource.isNew(user.userId))) {
this.usersResource.addNew();
}
}
private async loadUsers() {
@@ -8,125 +8,12 @@
import { observer } from 'mobx-react';
import { useContext, useCallback } from 'react';
import styled, { css, use } from 'reshadow';
import { UsersResource } from '@cloudbeaver/core-authentication';
import {
TabsState, TabList, Tab,
TabTitle, Loader, SubmittingForm, TabPanel,
ErrorMessage, Button, TableItemContext,
TableContext,
InputField,
Checkbox,
useFocus,
InputGroup
} from '@cloudbeaver/core-blocks';
import { useService, useController } from '@cloudbeaver/core-di';
import { useTranslate } from '@cloudbeaver/core-localization';
import { useStyles, composes } from '@cloudbeaver/core-theming';
import { GrantedConnections } from './GrantedConnections';
import { UserEditController } from './UserEditController';
const styles = composes(
css`
Tab {
composes: theme-ripple theme-background-secondary theme-text-on-secondary from global;
}
TabList {
composes: theme-background-surface theme-text-on-surface from global;
}
ErrorMessage {
composes: theme-background-secondary from global;
}
box {
composes: theme-background-secondary theme-text-on-secondary from global;
}
content-box {
composes: theme-background-secondary theme-border-color-background from global;
}
GrantedConnections {
composes: theme-background-surface from global;
}
`,
css`
box {
padding: 24px;
}
SubmittingForm {
flex: 1;
display: flex;
flex-direction: column;
}
TabList {
align-items: center;
box-sizing: border-box;
display: inline-flex;
width: 100%;
padding-left: 24px;
outline: none;
}
TabPanel {
overflow: auto !important;
}
Tab {
composes: theme-typography--body2 from global;
text-transform: uppercase;
font-weight: normal;
&:global([aria-selected=true]) {
font-weight: normal !important;
}
& TabTitle {
padding: 0 24px !important;
}
}
ErrorMessage {
position: sticky;
bottom: 0;
padding: 8px 24px;
}
fill {
flex: 1;
}
SubmittingForm, Loader {
min-height: 320px;
max-height: 500px;
}
Button:not(:first-child) {
margin-right: 24px;
}
layout-grid {
flex: 1;
width: 100%;
}
flex-box {
flex: 1;
display: flex;
flex-wrap: wrap;
}
flex-box-element {
min-width: 450px;
}
`
);
import { UserForm } from '../UserForm/UserForm';
type Props = {
item: string;
@@ -136,155 +23,7 @@ export const UserEdit = observer(function UserEdit({
item,
}: Props) {
const tableContext = useContext(TableContext);
const context = useContext(TableItemContext);
const collapse = useCallback(() => tableContext?.setItemExpand(item, false), [tableContext]);
const translate = useTranslate();
const controller = useController(UserEditController, item, collapse);
const usersResource = useService(UsersResource);
const [focusedRef] = useFocus({ focusFirstChild: true });
const handleCancel = useCallback(() => {
collapse();
if (controller.isNew) {
usersResource.delete(item);
}
}, [collapse]);
const handleLoginChange = useCallback(
(value: string) => controller.credentials.login = value,
[]
);
const handlePasswordChange = useCallback(
(value: string) => controller.credentials.password = value,
[]
);
const handlePasswordRepeatChange = useCallback(
(value: string) => controller.credentials.passwordRepeat = value,
[]
);
const handleRoleChange = useCallback(
(roleId: string, value: boolean) => controller.credentials.roles.set(roleId, value),
[]
);
return styled(useStyles(styles))(
<TabsState selectedId='info'>
<box as='div'>
<TabList>
<Tab tabId='info' >
<TabTitle>{translate('authentication_administration_user_info')}</TabTitle>
</Tab>
<Tab tabId='connections_access' onOpen={controller.loadConnectionsAccess} >
<TabTitle>{translate('authentication_administration_user_connections_access')}</TabTitle>
</Tab>
<fill as="div" />
<Button
type="button"
disabled={controller.isSaving}
mod={['outlined']}
onClick={handleCancel}
>
{translate('ui_processing_cancel')}
</Button>
<Button
type="button"
disabled={controller.isSaving}
mod={['unelevated']}
onClick={controller.save}
>
{translate(controller.isNew ? 'ui_processing_create' : 'ui_processing_save')}
</Button>
</TabList>
<content-box as='div'>
{controller.isLoading
? <Loader />
: (
<SubmittingForm onSubmit={controller.save} ref={focusedRef as React.RefObject<HTMLFormElement>}>
<TabPanel tabId='info'>
<flex-box as="div">
<flex-box-element as='div'>
<group as="div">
<InputGroup>{translate('authentication_user_credentials')}</InputGroup>
</group>
<group as="div">
<InputField
type='text'
name='login'
value={controller.credentials.login}
onChange={handleLoginChange}
disabled={!controller.isNew || controller.isSaving}
mod='surface'
>
{translate('authentication_user_name')}
</InputField>
</group>
<group as="div">
<InputField
type='password'
name='password'
value={controller.credentials.password}
onChange={handlePasswordChange}
disabled={controller.isSaving}
mod='surface'
>
{translate('authentication_user_password')}
</InputField>
</group>
<group as="div">
<InputField
type='password'
name='password_repeat'
value={controller.credentials.passwordRepeat}
onChange={handlePasswordRepeatChange}
disabled={controller.isSaving}
mod='surface'
>
{translate('authentication_user_password_repeat')}
</InputField>
</group>
</flex-box-element>
<flex-box-element as='div'>
<group as="div">
<InputGroup>{translate('authentication_user_role')}</InputGroup>
</group>
{controller.roles.map((role, i) => (
<group as="div" key={role.roleId}>
<Checkbox
value={role.roleId}
name='role'
checkboxLabel={role.roleName || role.roleId}
onChange={checked => handleRoleChange(role.roleId, checked)}
checked={controller.credentials.roles.get(role.roleId)}
disabled={controller.isSaving}
mod='surface'
/>
</group>
))}
</flex-box-element>
</flex-box>
</TabPanel>
<TabPanel tabId='connections_access'>
<GrantedConnections
grantedConnections={controller.grantedConnections}
connections={controller.connections}
selectedConnection={controller.selectedConnections}
disabled={controller.isLoading}
onChange={controller.handleConnectionsAccessChange}
/>
</TabPanel>
</SubmittingForm>
)}
{controller.error.responseMessage && (
<ErrorMessage
text={controller.error.responseMessage}
hasDetails={controller.error.hasDetails}
onShowDetails={controller.showDetails}
/>
)}
</content-box>
</box>
</TabsState>
);
return <UserForm userId={item} onCancel={collapse} />;
});
@@ -9,7 +9,7 @@
import { AdministrationTopAppBarService } from '@cloudbeaver/core-administration';
import { SettingsMenuService, TopNavService } from '@cloudbeaver/core-app';
import { AuthInfoService } from '@cloudbeaver/core-authentication';
import { injectable } from '@cloudbeaver/core-di';
import { injectable, Bootstrap } from '@cloudbeaver/core-di';
import { NotificationService } from '@cloudbeaver/core-events';
import { ServerService } from '@cloudbeaver/core-root';
@@ -18,7 +18,7 @@ import { AuthDialogService } from './Dialog/AuthDialogService';
import { UserInfo } from './UserInfo';
@injectable()
export class AuthMenuService {
export class AuthMenuService extends Bootstrap {
constructor(
private serverService: ServerService,
private authDialogService: AuthDialogService,
@@ -28,7 +28,9 @@ export class AuthMenuService {
private notificationService: NotificationService,
private topNavService: TopNavService,
private administrationTopAppBarService: AdministrationTopAppBarService,
) { }
) {
super();
}
register() {
this.settingsMenuService.addMenuItem(
@@ -57,6 +59,8 @@ export class AuthMenuService {
this.administrationTopAppBarService.placeholder.add(UserInfo, 4);
}
load(): void | Promise<void> { }
private async logout() {
try {
await this.authInfoService.logout();
@@ -7,18 +7,20 @@
*/
import { AuthInfoService } from '@cloudbeaver/core-authentication';
import { injectable } from '@cloudbeaver/core-di';
import { injectable, Bootstrap } from '@cloudbeaver/core-di';
import { ServerService } from '@cloudbeaver/core-root';
import { AuthDialogService } from './Dialog/AuthDialogService';
@injectable()
export class AuthenticationService {
export class AuthenticationService extends Bootstrap {
constructor(
private serverService: ServerService,
private authDialogService: AuthDialogService,
private authInfoService: AuthInfoService,
) { }
) {
super();
}
async auth() {
const config = await this.serverService.config.load(null);
@@ -39,4 +41,11 @@ export class AuthenticationService {
await this.authDialogService.showLoginForm(true);
}
}
register(): void | Promise<void> { }
load() {
// we do not await it because to unblock app loading
this.auth();
}
}
@@ -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 '@cloudbeaver/core-di';
import { AuthenticationService } from './AuthenticationService';
import { AuthMenuService } from './AuthMenuService';
@injectable()
export class Bootstrap {
constructor(
private authenticationService: AuthenticationService,
private authMenuService: AuthMenuService
) { }
async bootstrap() {
this.authMenuService.register();
await this.authenticationService.auth();
}
}
@@ -2,6 +2,7 @@ export default [
['authentication_login_dialog_title', 'Authentication'],
['authentication_login', 'Login'],
['authentication_logout', 'Logout'],
['authentication_administration_user_connections_user_add', 'User Creation'],
['authentication_administration_user_connections_user_new', 'New user'],
['authentication_administration_user_connections_access_load_fail', 'User\'s granted connections loading failed'],
['authentication_administration_user_connections_access_connections_load_fail', 'Connections loading failed'],
@@ -2,6 +2,7 @@ export default [
['authentication_login_dialog_title', 'Авторизация'],
['authentication_login', 'Войти'],
['authentication_logout', 'Выйти'],
['authentication_administration_user_connections_user_add', 'Создание пользователя'],
['authentication_administration_user_connections_user_new', 'Новый пользователь'],
['authentication_administration_user_connections_access_load_fail', 'Не удалось загрузить доступные пользователю коннекшены'],
['authentication_administration_user_connections_access_connections_load_fail', 'Ошибка при загрузке списка коннекшенов'],
@@ -6,13 +6,13 @@
* you may not use this file except in compliance with the License.
*/
import { IServiceInjector, PluginManifest } from '@cloudbeaver/core-di';
import { PluginManifest } from '@cloudbeaver/core-di';
import { UsersAdministrationNavigationService } from './Administration/Users/UsersAdministrationNavigationService';
import { UsersAdministrationService } from './Administration/Users/UsersAdministrationService';
import { AuthenticationLocaleService } from './AuthenticationLocaleService';
import { AuthenticationService } from './AuthenticationService';
import { AuthMenuService } from './AuthMenuService';
import { Bootstrap } from './Bootstrap';
import { AuthDialogService } from './Dialog/AuthDialogService';
export const manifest: PluginManifest = {
@@ -26,11 +26,6 @@ export const manifest: PluginManifest = {
AuthMenuService,
UsersAdministrationService,
AuthenticationLocaleService,
UsersAdministrationNavigationService,
],
async initialize(services: IServiceInjector) {
services
.resolveServiceByClass(Bootstrap)
.bootstrap();
},
};