mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
feat: CB-794 administration item replacement
This commit is contained in:
@@ -79,7 +79,7 @@ export const Administration: React.FC<Props> = observer(function Administration(
|
||||
const contentRef = useRef<HTMLDivElement>(null);
|
||||
const administrationItemService = useService(AdministrationItemService);
|
||||
const items = administrationItemService.getActiveItems(configurationWizard);
|
||||
const hasOnlyActive = items.some(filterOnlyActive);
|
||||
const hasOnlyActive = items.some(filterOnlyActive(configurationWizard));
|
||||
|
||||
useLayoutEffect(() => {
|
||||
contentRef.current?.scrollTo({ top: 0, left: 0 });
|
||||
|
||||
@@ -24,7 +24,7 @@ export const DrawerItem = observer(function DrawerItem({
|
||||
disabled = !configurationWizardService.isStepAvailable(item.name);
|
||||
}
|
||||
|
||||
const onlyActive = filterOnlyActive(item) ? false : disabled;
|
||||
const onlyActive = filterOnlyActive(configurationWizard)(item) ? false : disabled;
|
||||
|
||||
return (
|
||||
<Component
|
||||
|
||||
+53
-37
@@ -28,9 +28,33 @@ export class AdministrationItemService {
|
||||
});
|
||||
}
|
||||
|
||||
getUniqueItems(configurationWizard: boolean): IAdministrationItem[] {
|
||||
const items: IAdministrationItem[] = [];
|
||||
|
||||
const orderedByPriority = this.items.slice()
|
||||
.sort((a, b) => {
|
||||
if (a.replace && b.replace) {
|
||||
return (b.replace.priority ?? Number.MIN_SAFE_INTEGER) - (a.replace.priority ?? Number.MIN_SAFE_INTEGER);
|
||||
}
|
||||
return 0;
|
||||
})
|
||||
.filter(item => !item.replace?.condition || item.replace.condition(configurationWizard));
|
||||
|
||||
let lastItem: IAdministrationItem | null = null;
|
||||
for (const item of orderedByPriority) {
|
||||
if (lastItem?.name === item.name) {
|
||||
continue;
|
||||
}
|
||||
items.push(item);
|
||||
lastItem = item;
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
getActiveItems(configurationWizard: boolean): IAdministrationItem[] {
|
||||
return this.items.filter(item =>
|
||||
filterHiddenAdministrationItem(item)
|
||||
return this.getUniqueItems(configurationWizard).filter(item =>
|
||||
filterHiddenAdministrationItem(configurationWizard)(item)
|
||||
&& filterConfigurationWizard(configurationWizard)(item)
|
||||
).sort(orderAdministrationItems(configurationWizard));
|
||||
}
|
||||
@@ -42,7 +66,7 @@ export class AdministrationItemService {
|
||||
return null;
|
||||
}
|
||||
|
||||
const onlyActive = items.find(filterOnlyActive);
|
||||
const onlyActive = items.find(filterOnlyActive(configurationWizard));
|
||||
|
||||
if (onlyActive) {
|
||||
return onlyActive.name;
|
||||
@@ -60,11 +84,7 @@ export class AdministrationItemService {
|
||||
}
|
||||
|
||||
getItem(name: string, configurationWizard: boolean): IAdministrationItem | null {
|
||||
const item = this.items.find(item => (
|
||||
filterHiddenAdministrationItem(item)
|
||||
&& filterConfigurationWizard(configurationWizard)(item)
|
||||
&& item.name === name
|
||||
));
|
||||
const item = this.getActiveItems(configurationWizard).find(item => item.name === name);
|
||||
|
||||
if (!item) {
|
||||
return null;
|
||||
@@ -82,7 +102,7 @@ export class AdministrationItemService {
|
||||
return sub;
|
||||
}
|
||||
|
||||
create(options: IAdministrationItemOptions, replace?: boolean): void {
|
||||
create(options: IAdministrationItemOptions): void {
|
||||
const type = options.type ?? AdministrationItemType.Administration;
|
||||
|
||||
const existedIndex = this.items.findIndex(item => item.name === options.name && (
|
||||
@@ -91,7 +111,7 @@ export class AdministrationItemService {
|
||||
|| type === AdministrationItemType.Default
|
||||
));
|
||||
|
||||
if (!replace && existedIndex !== -1) {
|
||||
if (!options.replace && existedIndex !== -1) {
|
||||
throw new Error(`Administration item "${options.name}" already exists in the same visibility scope`);
|
||||
}
|
||||
|
||||
@@ -101,11 +121,7 @@ export class AdministrationItemService {
|
||||
sub: options.sub ?? [],
|
||||
order: options.order ?? Number.MAX_SAFE_INTEGER,
|
||||
};
|
||||
if (replace && existedIndex !== -1) {
|
||||
this.items.splice(existedIndex, 1, item);
|
||||
} else {
|
||||
this.items.push(item);
|
||||
}
|
||||
this.items.push(item);
|
||||
}
|
||||
|
||||
async activate(
|
||||
@@ -113,12 +129,16 @@ export class AdministrationItemService {
|
||||
configurationWizard: boolean,
|
||||
outside: boolean
|
||||
): Promise<void> {
|
||||
const item = this.getItem(screen.item, configurationWizard);
|
||||
if (!item) {
|
||||
return;
|
||||
if (configurationWizard) {
|
||||
const items = this.getActiveItems(configurationWizard);
|
||||
|
||||
for (const item of items) {
|
||||
await item.configurationWizardOptions?.onLoad?.();
|
||||
}
|
||||
}
|
||||
|
||||
if (!filterHiddenAdministrationItem(item)) {
|
||||
const item = this.getItem(screen.item, configurationWizard);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -139,10 +159,6 @@ export class AdministrationItemService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!filterHiddenAdministrationItem(item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await item.onDeActivate?.(configurationWizard, outside);
|
||||
|
||||
if (screen.sub) {
|
||||
@@ -160,10 +176,6 @@ export class AdministrationItemService {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!filterHiddenAdministrationItem(item)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item.canActivate && !(await item.canActivate(configurationWizard, outside))) {
|
||||
return false;
|
||||
}
|
||||
@@ -179,18 +191,22 @@ export class AdministrationItemService {
|
||||
}
|
||||
}
|
||||
|
||||
export function filterHiddenAdministrationItem(item: IAdministrationItem): boolean {
|
||||
if (typeof item.isHidden === 'function') {
|
||||
return !item.isHidden();
|
||||
}
|
||||
export function filterHiddenAdministrationItem(configurationWizard: boolean): (item: IAdministrationItem) => boolean {
|
||||
return function filterHiddenAdministrationItem(item: IAdministrationItem) {
|
||||
if (typeof item.isHidden === 'function') {
|
||||
return !item.isHidden(configurationWizard);
|
||||
}
|
||||
|
||||
return !item.isHidden;
|
||||
return !item.isHidden;
|
||||
};
|
||||
}
|
||||
|
||||
export function filterOnlyActive(item: IAdministrationItem): boolean {
|
||||
if (typeof item.isOnlyActive === 'function') {
|
||||
return item.isOnlyActive();
|
||||
}
|
||||
export function filterOnlyActive(configurationWizard: boolean): (item: IAdministrationItem) => boolean {
|
||||
return function filterOnlyActive(item: IAdministrationItem) {
|
||||
if (typeof item.isOnlyActive === 'function') {
|
||||
return item.isOnlyActive(configurationWizard);
|
||||
}
|
||||
|
||||
return item.isOnlyActive === true;
|
||||
return item.isOnlyActive === true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -16,6 +16,11 @@ export enum AdministrationItemType {
|
||||
ConfigurationWizard
|
||||
}
|
||||
|
||||
export interface IAdministrationItemReplaceOptions {
|
||||
priority: number;
|
||||
condition?: (configurationWizard: boolean) => boolean;
|
||||
}
|
||||
|
||||
export interface AdministrationItemDrawerProps {
|
||||
item: IAdministrationItem;
|
||||
configurationWizard: boolean;
|
||||
@@ -69,8 +74,9 @@ export interface IConfigurationWizardItemOptions {
|
||||
isDisabled?: () => boolean;
|
||||
isHidden?: () => boolean;
|
||||
isDone?: () => boolean;
|
||||
onLoad?: () => Promise<void> | void;
|
||||
onFinish?: () => Promise<boolean> | boolean;
|
||||
onConfigurationFinish?: () => Promise<void> | void;
|
||||
onConfigurationFinish?: () => Promise<any> | any;
|
||||
}
|
||||
|
||||
export interface IAdministrationItemOptions {
|
||||
@@ -80,8 +86,9 @@ export interface IAdministrationItemOptions {
|
||||
configurationWizardOptions?: IConfigurationWizardItemOptions;
|
||||
order?: number;
|
||||
sub?: IAdministrationItemSubItem[];
|
||||
isHidden?: (() => boolean) | boolean;
|
||||
isOnlyActive?: (() => boolean) | boolean;
|
||||
isHidden?: ((configurationWizard: boolean) => boolean) | boolean;
|
||||
isOnlyActive?: ((configurationWizard: boolean) => boolean) | boolean;
|
||||
replace?: IAdministrationItemReplaceOptions;
|
||||
getDrawerComponent: () => AdministrationItemDrawerComponent;
|
||||
getContentComponent: () => AdministrationItemContentComponent;
|
||||
onActivate?: AdministrationItemEvent;
|
||||
|
||||
+7
-4
@@ -11,7 +11,7 @@ import { computed, makeObservable } from 'mobx';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { ScreenService } from '@cloudbeaver/core-routing';
|
||||
|
||||
import { AdministrationItemService } from '../../AdministrationItem/AdministrationItemService';
|
||||
import { AdministrationItemService, filterHiddenAdministrationItem } from '../../AdministrationItem/AdministrationItemService';
|
||||
import { filterConfigurationWizard } from '../../AdministrationItem/filterConfigurationWizard';
|
||||
import type { IAdministrationItem } from '../../AdministrationItem/IAdministrationItem';
|
||||
import { orderAdministrationItems } from '../../AdministrationItem/orderAdministrationItems';
|
||||
@@ -20,8 +20,11 @@ import { AdministrationScreenService } from '../AdministrationScreenService';
|
||||
@injectable()
|
||||
export class ConfigurationWizardService {
|
||||
get steps(): IAdministrationItem[] {
|
||||
return this.administrationItemService.items
|
||||
.filter(filterConfigurationWizard(true))
|
||||
return this.administrationItemService.getUniqueItems(true)
|
||||
.filter(item =>
|
||||
filterConfigurationWizard(true)(item)
|
||||
&& filterHiddenAdministrationItem(true)(item)
|
||||
)
|
||||
.sort(orderAdministrationItems(true));
|
||||
}
|
||||
|
||||
@@ -163,7 +166,7 @@ export class ConfigurationWizardService {
|
||||
}
|
||||
|
||||
private getStep(name: string) {
|
||||
return this.administrationItemService.items
|
||||
return this.administrationItemService.getUniqueItems(true)
|
||||
.find(step => filterConfigurationWizard(true)(step) && step.name === name);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { PermissionsResource } from '@cloudbeaver/core-root';
|
||||
import { PermissionsResource, ServerConfigResource } from '@cloudbeaver/core-root';
|
||||
import {
|
||||
GraphQLService,
|
||||
CachedDataResource,
|
||||
@@ -20,13 +20,22 @@ export type AuthProvider = Omit<AuthProviderInfo, 'configurationParameters'>;
|
||||
export class AuthProvidersResource extends CachedDataResource<AuthProvider[], void> {
|
||||
constructor(
|
||||
private graphQLService: GraphQLService,
|
||||
private permissionsResource: PermissionsResource
|
||||
private permissionsResource: PermissionsResource,
|
||||
private serverConfigResource: ServerConfigResource
|
||||
) {
|
||||
super([]);
|
||||
|
||||
this.permissionsResource.onDataUpdate.addHandler(() => this.markOutdated());
|
||||
}
|
||||
|
||||
getEnabledProviders(): string[] {
|
||||
return this.serverConfigResource.data?.enabledAuthProviders ?? [];
|
||||
}
|
||||
|
||||
isEnabled(id: string): boolean {
|
||||
return this.serverConfigResource.data?.enabledAuthProviders.includes(id) ?? false;
|
||||
}
|
||||
|
||||
protected async loader(): Promise<AuthProvider[]> {
|
||||
const { providers } = await this.graphQLService.sdk.getAuthProviders();
|
||||
return providers;
|
||||
|
||||
Reference in New Issue
Block a user