feat: CB-794 administration item replacement

This commit is contained in:
Wroud
2021-03-24 11:46:56 +03:00
parent 7f50642490
commit d30ac1ca58
6 changed files with 83 additions and 48 deletions
@@ -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
@@ -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;
@@ -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;