Skip to content

Commit

Permalink
CB-5955 pr fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeyteleshev committed Dec 16, 2024
1 parent c42b1a1 commit d663881
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
import type { NavNode } from './EntityTypes.js';
import { NAV_NODE_TYPE_FOLDER } from './NAV_NODE_TYPE_FOLDER.js';

export function isFolderNode(node: NavNode | undefined): boolean {
export function isConnectionFolder(node: NavNode | undefined): boolean {
return node?.nodeType === NAV_NODE_TYPE_FOLDER;
}
2 changes: 1 addition & 1 deletion webapp/packages/core-navigation-tree/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export * from './NodesManager/navNodeMoveContext.js';
export * from './NodesManager/getNodesFromContext.js';
export * from './NodesManager/NAV_NODE_TYPE_FOLDER.js';
export * from './NodesManager/NAV_NODE_TYPE_ROOT.js';
export * from './NodesManager/isFolderNode.js';
export * from './NodesManager/isConnectionFolder.js';
export * from './NodesManager/isProjectNode.js';

export * from './NodesManager/ENodeFeature.js';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ConnectionsManagerService, getFolderPath, isConnectionNode } from '@clo
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, isFolderNode, isProjectNode } from '@cloudbeaver/core-navigation-tree';
import { DATA_CONTEXT_NAV_NODE, isConnectionFolder, isProjectNode } from '@cloudbeaver/core-navigation-tree';
import { getProjectNodeId, ProjectInfoResource } from '@cloudbeaver/core-projects';
import { CachedMapAllKey, getCachedMapResourceLoaderState } from '@cloudbeaver/core-resource';
import { ActionService, type IAction, MenuService } from '@cloudbeaver/core-view';
Expand Down Expand Up @@ -47,7 +47,7 @@ export class CustomConnectionPluginBootstrap extends Bootstrap {
isApplicable: context => {
const node = context.get(DATA_CONTEXT_NAV_NODE);

if (![isConnectionNode, isFolderNode, isProjectNode].some(check => check(node)) || this.isConnectionFeatureDisabled(true)) {
if (![isConnectionNode, isConnectionFolder, isProjectNode].some(check => check(node)) || this.isConnectionFeatureDisabled(true)) {
return false;
}

Expand All @@ -61,6 +61,7 @@ export class CustomConnectionPluginBootstrap extends Bootstrap {
menus: [MENU_NAVIGATION_TREE_CREATE],
actions: [ACTION_TREE_CREATE_CONNECTION],
contexts: [DATA_CONTEXT_ELEMENTS_TREE],
getLoader: (context, action) => getCachedMapResourceLoaderState(this.projectInfoResource, () => CachedMapAllKey),
handler: this.createConnectionHandler.bind(this),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import { observer } from 'mobx-react-lite';

import { CommonDialogBody, CommonDialogHeader, CommonDialogWrapper, s, useResource, useS, useTranslate } from '@cloudbeaver/core-blocks';
import { DBDriverResource } from '@cloudbeaver/core-connections';
import type { DialogComponent } from '@cloudbeaver/core-dialogs';
import { ProjectInfoResource } from '@cloudbeaver/core-projects';
import { CachedMapAllKey } from '@cloudbeaver/core-resource';
Expand All @@ -26,11 +25,7 @@ export const DriverSelectorDialog: DialogComponent<Payload> = observer(function
const translate = useTranslate();
const style = useS(styles);
useResource(DriverSelectorDialog, ProjectInfoResource, CachedMapAllKey, { forceSuspense: true });
const dbDriverResource = useResource(DriverSelectorDialog, DBDriverResource, CachedMapAllKey);

const enabledDrivers = dbDriverResource.resource.enabledDrivers;
const dialog = useDriverSelectorDialog({
drivers: enabledDrivers.map(driver => driver.id),
projectId: payload.projectId,
folderPath: payload.folderPath,
onSelect: rejectDialog,
Expand All @@ -40,7 +35,7 @@ export const DriverSelectorDialog: DialogComponent<Payload> = observer(function
<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={dialog.enabledDrivers} onSelect={dialog.select} />
</CommonDialogBody>
</CommonDialogWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,56 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { action } from 'mobx';
import { action, observable } from 'mobx';

import { useObservableRef } from '@cloudbeaver/core-blocks';
import { ConnectionsManagerService } from '@cloudbeaver/core-connections';
import { useObservableRef, useResource } from '@cloudbeaver/core-blocks';
import { ConnectionsManagerService, DBDriverResource } from '@cloudbeaver/core-connections';
import { useService } from '@cloudbeaver/core-di';
import { NotificationService } from '@cloudbeaver/core-events';
import { CachedMapAllKey } from '@cloudbeaver/core-resource';
import { PublicConnectionFormService } from '@cloudbeaver/plugin-connections';

import type { IDriver } from './Driver.js';

interface State {
select(driverId: string): Promise<void>;
enabledDrivers: IDriver[];
}

type Args = {
drivers: string[];
interface DriverSelectorDialogArgs {
onSelect?: () => void;
projectId: string | undefined;
folderPath: string | undefined;
};
}

export function useDriverSelectorDialog({ drivers, onSelect, projectId, folderPath }: Args) {
export function useDriverSelectorDialog({ onSelect, projectId, folderPath }: DriverSelectorDialogArgs) {
const notificationService = useService(NotificationService);
const connectionsManagerService = useService(ConnectionsManagerService);
const publicConnectionFormService = useService(PublicConnectionFormService);
const dbDriverResource = useResource(useDriverSelectorDialog, DBDriverResource, CachedMapAllKey);
const enabledDrivers = dbDriverResource.resource.enabledDrivers;

const state: State = useObservableRef(
() => ({
async select(driverId: string) {
const projects = this.connectionsManagerService.createConnectionProjects;
const drivers = this.enabledDrivers.map(driver => driver.id);

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

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

if (state) {
onSelect?.();
}
},
}),
{ select: action.bound },
{ drivers, notificationService, connectionsManagerService, publicConnectionFormService },
{ select: action.bound, enabledDrivers: observable.ref },
{ notificationService, connectionsManagerService, publicConnectionFormService, enabledDrivers },
);

return state;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
ENodeMoveType,
getNodesFromContext,
type INodeMoveData,
isFolderNode,
isConnectionFolder,
isProjectNode,
type NavNode,
NavNodeInfoResource,
Expand All @@ -43,7 +43,13 @@ import {
ROOT_NODE_PATH,
} from '@cloudbeaver/core-navigation-tree';
import { getProjectNodeId, ProjectInfoResource } from '@cloudbeaver/core-projects';
import { CachedMapAllKey, resourceKeyList, type ResourceKeySimple, ResourceKeyUtils } from '@cloudbeaver/core-resource';
import {
CachedMapAllKey,
getCachedMapResourceLoaderState,
resourceKeyList,
type ResourceKeySimple,
ResourceKeyUtils,
} from '@cloudbeaver/core-resource';
import { createPath } from '@cloudbeaver/core-utils';
import { ACTION_NEW_FOLDER, ActionService, type IAction, MenuService } from '@cloudbeaver/core-view';
import {
Expand Down Expand Up @@ -131,6 +137,7 @@ export class ConnectionFoldersBootstrap extends Bootstrap {

return targetNode !== undefined;
},
getLoader: (context, action) => getCachedMapResourceLoaderState(this.projectInfoResource, () => CachedMapAllKey),

Check warning on line 140 in webapp/packages/plugin-connections/src/NavNodes/ConnectionFoldersBootstrap.ts

View check run for this annotation

Jenkins-CI-integration / CheckStyle TypeScript Report

webapp/packages/plugin-connections/src/NavNodes/ConnectionFoldersBootstrap.ts#L140

context is defined but never used. (@typescript-eslint/no-unused-vars)

Check warning on line 140 in webapp/packages/plugin-connections/src/NavNodes/ConnectionFoldersBootstrap.ts

View check run for this annotation

Jenkins-CI-integration / CheckStyle TypeScript Report

webapp/packages/plugin-connections/src/NavNodes/ConnectionFoldersBootstrap.ts#L140

action is defined but never used. (@typescript-eslint/no-unused-vars)
handler: this.elementsTreeActionHandler.bind(this),
});

Expand All @@ -147,13 +154,23 @@ export class ConnectionFoldersBootstrap extends Bootstrap {

this.menuService.addCreator({
menus: [MENU_NAVIGATION_TREE_CREATE],
isApplicable: context => {
const node = context.get(DATA_CONTEXT_NAV_NODE);
contexts: [DATA_CONTEXT_NAV_NODE, DATA_CONTEXT_ELEMENTS_TREE],
getItems: (context, items) => [...items, ACTION_TREE_CREATE_FOLDER],
});

this.actionService.addHandler({
id: 'nav-tree-create-create-folders-handler',
menus: [MENU_NAVIGATION_TREE_CREATE],
contexts: [DATA_CONTEXT_NAV_NODE, DATA_CONTEXT_ELEMENTS_TREE],
actions: [ACTION_TREE_CREATE_FOLDER],
isActionApplicable: (context, action) => {
const node = context.get(DATA_CONTEXT_NAV_NODE)!;
const tree = context.get(DATA_CONTEXT_ELEMENTS_TREE)!;
const targetNode = this.treeSelectionService.getFirstSelectedNode(tree, getProjectNodeId);

if (
![isConnectionNode, isFolderNode, isProjectNode].some(check => check(node)) ||
action !== ACTION_TREE_CREATE_FOLDER ||
![isConnectionNode, isConnectionFolder, isProjectNode].some(check => check(node)) ||
!this.userInfoResource.isAuthenticated() ||
tree.baseRoot !== ROOT_NODE_PATH ||
targetNode === undefined
Expand All @@ -163,19 +180,13 @@ export class ConnectionFoldersBootstrap extends Bootstrap {

return true;
},
getItems: (context, items) => [...items, ACTION_TREE_CREATE_FOLDER],
});

this.actionService.addHandler({
id: 'nav-tree-create-create-folders-handler',
menus: [MENU_NAVIGATION_TREE_CREATE],
actions: [ACTION_TREE_CREATE_FOLDER],
getLoader: (context, action) => getCachedMapResourceLoaderState(this.projectInfoResource, () => CachedMapAllKey),

Check warning on line 183 in webapp/packages/plugin-connections/src/NavNodes/ConnectionFoldersBootstrap.ts

View check run for this annotation

Jenkins-CI-integration / CheckStyle TypeScript Report

webapp/packages/plugin-connections/src/NavNodes/ConnectionFoldersBootstrap.ts#L183

context is defined but never used. (@typescript-eslint/no-unused-vars)

Check warning on line 183 in webapp/packages/plugin-connections/src/NavNodes/ConnectionFoldersBootstrap.ts

View check run for this annotation

Jenkins-CI-integration / CheckStyle TypeScript Report

webapp/packages/plugin-connections/src/NavNodes/ConnectionFoldersBootstrap.ts#L183

action is defined but never used. (@typescript-eslint/no-unused-vars)
handler: this.elementsTreeActionHandler.bind(this),
});
}

private async moveConnectionToFolder({ type, targetNode, moveContexts }: INodeMoveData, contexts: IExecutionContextProvider<INodeMoveData>) {
if (![isProjectNode, isFolderNode].some(check => check(targetNode))) {
if (![isProjectNode, isConnectionFolder].some(check => check(targetNode))) {
return;
}

Expand All @@ -189,7 +200,7 @@ export class ConnectionFoldersBootstrap extends Bootstrap {

const supported = nodes.every(node => {
if (
![isConnectionNode, isFolderNode, isProjectNode].some(check => check(node)) ||
![isConnectionNode, isConnectionFolder, isProjectNode].some(check => check(node)) ||
targetProject !== this.projectsNavNodeService.getProject(node.id) ||
children.includes(node.id) ||
targetNode.id === node.id
Expand All @@ -212,9 +223,9 @@ export class ConnectionFoldersBootstrap extends Bootstrap {
const childrenNode = this.navNodeInfoResource.get(resourceKeyList(children));
const folderDuplicates = nodes.filter(
node =>
isFolderNode(node) &&
(childrenNode.some(child => child && isFolderNode(child) && child.name === node.name) ||
nodes.some(child => isFolderNode(child) && child.name === node.name && child.id !== node.id)),
isConnectionFolder(node) &&
(childrenNode.some(child => child && isConnectionFolder(child) && child.name === node.name) ||
nodes.some(child => isConnectionFolder(child) && child.name === node.name && child.id !== node.id)),
);

if (folderDuplicates.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import { ConnectionsManagerService } from '@cloudbeaver/core-connections';
import { injectable } from '@cloudbeaver/core-di';
import { isFolderNode, isProjectNode, type NavNode, NavNodeInfoResource, ProjectsNavNodeService } from '@cloudbeaver/core-navigation-tree';
import { isConnectionFolder, isProjectNode, type NavNode, NavNodeInfoResource, ProjectsNavNodeService } from '@cloudbeaver/core-navigation-tree';
import { type ProjectInfo } from '@cloudbeaver/core-projects';
import { resourceKeyList } from '@cloudbeaver/core-resource';
import { isNotNullDefined } from '@cloudbeaver/core-utils';
Expand All @@ -34,6 +34,7 @@ export class TreeSelectionService {
this.getFirstSelectedNode = this.getFirstSelectedNode.bind(this);
}

// Should preload ProjectInfoResource. Cause the resource used indirectly (TODO make it directly used)
getFirstSelectedNode(tree: IElementsTree, nodeIdGetter: NodeIdGetter): ISelectedNode | undefined {
const selected = tree.getSelected();

Expand All @@ -53,28 +54,23 @@ export class TreeSelectionService {
return;
}

const projectNode = this.getParents(tree).find(isProjectNode);

if (!projectNode) {
return;
}

const project = this.getSelectedProject(tree);

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

const selectedFolderNode = this.getParents(tree).slice().reverse().find(isFolderNode);
const selectedFolderNode = this.getParents(tree).slice().reverse().find(isConnectionFolder);

return {
projectId: project.id,
folderId: selectedFolderNode?.id,
projectNodeId: projectNode.id,
projectNodeId: nodeIdGetter(project.id),
selectProject: false,
};
}

// Should preload ProjectInfoResource. Cause the resource used indirectly (TODO make it directly used)
getSelectedProject(tree: IElementsTree): ProjectInfo | undefined {
const projectNode = this.getParents(tree).find(isProjectNode);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
ENodeFeature,
getNodePlainName,
type INodeActions,
isFolderNode,
isConnectionFolder,
type NavNode,
NavNodeInfoResource,
NavNodeManagerService,
Expand Down Expand Up @@ -101,7 +101,7 @@ export class NavNodeContextMenuService extends Bootstrap {
isActionApplicable: (context, action): boolean => {
const node = context.get(DATA_CONTEXT_NAV_NODE)!;

if (NodeManagerUtils.isDatabaseObject(node.id) || isFolderNode(node)) {
if (NodeManagerUtils.isDatabaseObject(node.id) || isConnectionFolder(node)) {
if (action === ACTION_RENAME) {
return node.features?.includes(ENodeFeature.canRename) ?? false;
}
Expand Down

0 comments on commit d663881

Please sign in to comment.