Skip to content

Commit

Permalink
CB-5955 creates connection according to the selected in tree project …
Browse files Browse the repository at this point in the history
…+ tree selection refactor
  • Loading branch information
sergeyteleshev committed Dec 12, 2024
1 parent e1ef8fc commit 41d46ac
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
*/
import { importLazyComponent } from '@cloudbeaver/core-blocks';
import { ConnectionsManagerService, NAV_NODE_TYPE_CONNECTION } from '@cloudbeaver/core-connections';
import type { IDataContextProvider } from '@cloudbeaver/core-data-context';
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { CommonDialogService } from '@cloudbeaver/core-dialogs';
import { DATA_CONTEXT_NAV_NODE, NAV_NODE_TYPE_FOLDER } from '@cloudbeaver/core-navigation-tree';
import { NAV_NODE_TYPE_PROJECT, ProjectInfoResource } from '@cloudbeaver/core-projects';
import { CachedMapAllKey, getCachedMapResourceLoaderState } from '@cloudbeaver/core-resource';
import { ActionService, MenuService } from '@cloudbeaver/core-view';
import { ActionService, type IAction, MenuService } from '@cloudbeaver/core-view';
import { ACTION_CREATE_CONNECTION, MENU_CONNECTIONS } from '@cloudbeaver/plugin-connections';
import { MENU_NAVIGATION_TREE_CREATE } from '@cloudbeaver/plugin-navigation-tree';
import { DATA_CONTEXT_ELEMENTS_TREE, MENU_NAVIGATION_TREE_CREATE, TreeSelectionService } from '@cloudbeaver/plugin-navigation-tree';

import { ACTION_CONNECTION_CUSTOM } from './Actions/ACTION_CONNECTION_CUSTOM.js';
import { CustomConnectionSettingsService } from './CustomConnectionSettingsService.js';
Expand All @@ -30,6 +31,7 @@ export class CustomConnectionPluginBootstrap extends Bootstrap {
private readonly actionService: ActionService,
private readonly connectionsManagerService: ConnectionsManagerService,
private readonly customConnectionSettingsService: CustomConnectionSettingsService,
private readonly treeProjectsService: TreeSelectionService,
) {
super();
}
Expand Down Expand Up @@ -61,29 +63,33 @@ export class CustomConnectionPluginBootstrap extends Bootstrap {
id: 'nav-tree-create-create-connection-handler',
menus: [MENU_NAVIGATION_TREE_CREATE],
actions: [ACTION_CREATE_CONNECTION],
handler: async (context, action) => {
if (action === ACTION_CREATE_CONNECTION) {
await this.openConnectionsDialog();
}
},
handler: this.createConnectionHandler.bind(this),
});

this.actionService.addHandler({
id: 'connection-custom',
actions: [ACTION_CONNECTION_CUSTOM],
isHidden: (context, action) => this.isConnectionFeatureDisabled(action === ACTION_CONNECTION_CUSTOM),
getLoader: (context, action) => getCachedMapResourceLoaderState(this.projectInfoResource, () => CachedMapAllKey),
handler: async (context, action) => {
switch (action) {
case ACTION_CONNECTION_CUSTOM: {
await this.openConnectionsDialog();
break;
}
}
},
handler: this.createConnectionHandler.bind(this),
});
}

private createConnectionHandler = async (context: IDataContextProvider, action: IAction) => {
const tree = context.get(DATA_CONTEXT_ELEMENTS_TREE);

switch (action) {
case ACTION_CREATE_CONNECTION:
if (tree) {
await this.openConnectionsDialog(this.treeProjectsService.getSelectedProject(tree)?.id);
}
break;
case ACTION_CONNECTION_CUSTOM:
await this.openConnectionsDialog();
break;
}
};

private isConnectionFeatureDisabled(hasSettings: boolean) {
if (this.connectionsManagerService.createConnectionProjects.length === 0) {
return true;
Expand All @@ -96,7 +102,9 @@ export class CustomConnectionPluginBootstrap extends Bootstrap {
return false;
}

private async openConnectionsDialog() {
await this.commonDialogService.open(DriverSelectorDialog, null);
private async openConnectionsDialog(projectId?: string) {
await this.commonDialogService.open(DriverSelectorDialog, {
projectId,
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import { DriverSelector } from './DriverSelector.js';
import styles from './DriverSelectorDialog.module.css';
import { useDriverSelectorDialog } from './useDriverSelectorDialog.js';

export const DriverSelectorDialog: DialogComponent<null> = observer(function DriverSelectorDialog({ rejectDialog }) {
type Payload = {
projectId?: string;
};

export const DriverSelectorDialog: DialogComponent<Payload> = observer(function DriverSelectorDialog({ rejectDialog, payload }) {
const translate = useTranslate();
const style = useS(styles);
useResource(DriverSelectorDialog, ProjectInfoResource, CachedMapAllKey, { forceSuspense: true });
Expand All @@ -33,7 +37,11 @@ export const DriverSelectorDialog: DialogComponent<null> = observer(function Dri
<CommonDialogWrapper size="large" autofocus={false} fixedSize>
<CommonDialogHeader title={translate('plugin_connections_new_connection_dialog_title')} />
<CommonDialogBody noBodyPadding noOverflow>
<DriverSelector className={s(style, { driverSelector: true })} drivers={enabledDrivers} onSelect={dialog.select} />
<DriverSelector
className={s(style, { driverSelector: true })}
drivers={enabledDrivers}
onSelect={driverId => dialog.select(driverId, payload.projectId)}
/>
</CommonDialogBody>
</CommonDialogWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { NotificationService } from '@cloudbeaver/core-events';
import { PublicConnectionFormService } from '@cloudbeaver/plugin-connections';

interface State {
select(driverId: string): Promise<void>;
select(driverId: string, projectId?: string): Promise<void>;
}

export function useDriverSelectorDialog(drivers: string[], onSelect?: () => void) {
Expand All @@ -24,15 +24,16 @@ export function useDriverSelectorDialog(drivers: string[], onSelect?: () => void

const state: State = useObservableRef(
() => ({
async select(driverId: string) {
async select(driverId: string, projectId?: string) {
const projects = this.connectionsManagerService.createConnectionProjects;

if (projects.length === 0) {
this.notificationService.logError({ title: 'core_projects_no_default_project' });
return;
}

const state = await this.publicConnectionFormService.open(projects[0]!.id, { driverId }, this.drivers);
const selectedProjectId = projects.find(project => project.id === projectId)?.id || projects[0]!.id;
const state = await this.publicConnectionFormService.open(selectedProjectId, { driverId }, this.drivers);

if (state) {
onSelect?.();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { untracked } from 'mobx';

import { UserInfoResource } from '@cloudbeaver/core-authentication';
import { ConfirmationDialogDelete } from '@cloudbeaver/core-blocks';
import {
CONNECTION_FOLDER_NAME_VALIDATION,
ConnectionFolderProjectKey,
ConnectionFolderResource,
ConnectionInfoResource,
ConnectionsManagerService,
createConnectionFolderParam,
createConnectionParam,
getConnectionFolderId,
Expand Down Expand Up @@ -49,23 +46,15 @@ import { createPath } from '@cloudbeaver/core-utils';
import { ACTION_NEW_FOLDER, ActionService, type IAction, MenuService } from '@cloudbeaver/core-view';
import {
DATA_CONTEXT_ELEMENTS_TREE,
type IElementsTree,
MENU_ELEMENTS_TREE_TOOLS,
MENU_NAVIGATION_TREE_CREATE,
TreeSelectionService,
} from '@cloudbeaver/plugin-navigation-tree';
import { FolderDialog } from '@cloudbeaver/plugin-projects';

import { ACTION_CREATE_FOLDER } from '../Actions/ACTION_CREATE_FOLDER.js';
import { NAV_NODE_TYPE_CONNECTION } from './NAV_NODE_TYPE_CONNECTION.js';

interface ITargetNode {
projectId: string;
folderId?: string;

projectNodeId: string;
selectProject: boolean;
}

@injectable()
export class ConnectionFoldersBootstrap extends Bootstrap {
constructor(
Expand All @@ -77,12 +66,12 @@ export class ConnectionFoldersBootstrap extends Bootstrap {
private readonly connectionInfoResource: ConnectionInfoResource,
private readonly navNodeManagerService: NavNodeManagerService,
private readonly connectionFolderResource: ConnectionFolderResource,
private readonly connectionsManagerService: ConnectionsManagerService,
private readonly commonDialogService: CommonDialogService,
private readonly notificationService: NotificationService,
private readonly navNodeInfoResource: NavNodeInfoResource,
private readonly projectInfoResource: ProjectInfoResource,
private readonly projectsNavNodeService: ProjectsNavNodeService,
private readonly treeProjectsService: TreeSelectionService,
) {
super();
}
Expand Down Expand Up @@ -137,7 +126,7 @@ export class ConnectionFoldersBootstrap extends Bootstrap {
return false;
}

const targetNode = this.getTargetNode(tree);
const targetNode = this.treeProjectsService.getSelectedNode(tree, getProjectNodeId);

return targetNode !== undefined;
},
Expand All @@ -160,7 +149,7 @@ export class ConnectionFoldersBootstrap extends Bootstrap {
isApplicable: context => {
const node = context.get(DATA_CONTEXT_NAV_NODE);
const tree = context.get(DATA_CONTEXT_ELEMENTS_TREE)!;
const targetNode = this.getTargetNode(tree);
const targetNode = this.treeProjectsService.getSelectedNode(tree, getProjectNodeId);

if (
![NAV_NODE_TYPE_CONNECTION, NAV_NODE_TYPE_FOLDER, NAV_NODE_TYPE_PROJECT].includes(node?.nodeType ?? '') ||
Expand Down Expand Up @@ -268,7 +257,7 @@ export class ConnectionFoldersBootstrap extends Bootstrap {
switch (action) {
case ACTION_CREATE_FOLDER:
case ACTION_NEW_FOLDER: {
const targetNode = this.getTargetNode(tree);
const targetNode = this.treeProjectsService.getSelectedNode(tree, getProjectNodeId);

if (!targetNode) {
this.notificationService.logError({ title: "Can't create folder", message: 'core_projects_no_default_project' });
Expand Down Expand Up @@ -333,51 +322,4 @@ export class ConnectionFoldersBootstrap extends Bootstrap {
this.connectionFolderResource.markOutdated();
}
}

private getTargetNode(tree: IElementsTree): ITargetNode | undefined {
untracked(() => this.projectInfoResource.load(CachedMapAllKey));
const selected = tree.getSelected();

if (selected.length === 0) {
const editableProjects = this.connectionsManagerService.createConnectionProjects;

if (editableProjects.length > 0) {
const project = editableProjects[0]!;

return {
projectId: project.id,
projectNodeId: getProjectNodeId(project.id),
selectProject: editableProjects.length > 1,
};
}
return;
}

const targetFolder = selected[0]!;
const parentIds = [...this.navNodeInfoResource.getParents(targetFolder), targetFolder];
const parents = this.navNodeInfoResource.get(resourceKeyList(parentIds));
const projectNode = parents.find(parent => parent?.nodeType === NAV_NODE_TYPE_PROJECT);

if (!projectNode) {
return;
}

const project = this.projectsNavNodeService.getByNodeId(projectNode.id);

if (!project?.canEditDataSources) {
return;
}

const targetFolderNode = parents
.slice()
.reverse()
.find(parent => parent?.nodeType === NAV_NODE_TYPE_FOLDER);

return {
projectId: project.id,
folderId: targetFolderNode?.id,
projectNodeId: projectNode.id,
selectProject: false,
};
}
}
Loading

0 comments on commit 41d46ac

Please sign in to comment.