mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
CB-3497 error message (#1699)
* CB-3497 fix: error message * CB-3497 chore: update messages
This commit is contained in:
@@ -93,6 +93,21 @@ const style = css`
|
||||
}
|
||||
error[|icon] {
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-height: 24px;
|
||||
max-width: 24px;
|
||||
|
||||
& error-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
|
||||
& IconOrImage {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
error-action-close {
|
||||
cursor: pointer;
|
||||
@@ -103,8 +118,6 @@ const style = css`
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
name?: string;
|
||||
message?: string;
|
||||
exception?: Error;
|
||||
icon?: boolean;
|
||||
inline?: boolean;
|
||||
@@ -114,21 +127,9 @@ interface Props {
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
export const ExceptionMessage = observer<Props>(function ExceptionMessage({
|
||||
name,
|
||||
message,
|
||||
exception = null,
|
||||
icon,
|
||||
inline,
|
||||
className,
|
||||
styles,
|
||||
onRetry,
|
||||
onClose,
|
||||
}) {
|
||||
export const ExceptionMessage = observer<Props>(function ExceptionMessage({ exception = null, icon, inline, className, styles, onRetry, onClose }) {
|
||||
const translate = useTranslate();
|
||||
const error = useErrorDetails(exception);
|
||||
name = name || error.name;
|
||||
message = message || error.message;
|
||||
|
||||
if (error.refresh) {
|
||||
const retry = onRetry;
|
||||
@@ -141,22 +142,22 @@ export const ExceptionMessage = observer<Props>(function ExceptionMessage({
|
||||
|
||||
return styled(useStyles(style, styles))(
|
||||
<error {...use({ inline, icon })} className={className}>
|
||||
<error-icon title={message}>
|
||||
<IconOrImage icon={inline ? '/icons/error_icon_sm.svg' : '/icons/error_icon.svg'} />
|
||||
<error-icon title={error.message}>
|
||||
<IconOrImage icon={inline || icon ? '/icons/error_icon_sm.svg' : '/icons/error_icon.svg'} />
|
||||
</error-icon>
|
||||
{!icon && (
|
||||
<>
|
||||
<error-data>
|
||||
<error-name>
|
||||
<span>{name}</span>
|
||||
<span>{translate('core_blocks_exception_message_error_title')}</span>
|
||||
</error-name>
|
||||
<error-message>{message}</error-message>
|
||||
<error-message>
|
||||
{translate('core_blocks_exception_message_error_message')} {onRetry && translate('ui_please_retry')}
|
||||
</error-message>
|
||||
<error-actions>
|
||||
{error.hasDetails && (
|
||||
<Button type="button" mod={['outlined']} disabled={error.isOpen} onClick={error.open}>
|
||||
{translate('ui_errors_details')}
|
||||
</Button>
|
||||
)}
|
||||
<Button type="button" mod={['outlined']} disabled={error.isOpen} onClick={error.open}>
|
||||
{translate('ui_errors_details')}
|
||||
</Button>
|
||||
{onRetry && (
|
||||
<Button type="button" mod={['unelevated']} onClick={onRetry}>
|
||||
{translate('ui_processing_retry')}
|
||||
|
||||
@@ -156,7 +156,12 @@ export const Loader = observer<Props>(function Loader({
|
||||
}
|
||||
|
||||
if ('reload' in element) {
|
||||
reload = element.reload;
|
||||
const reloadLink = element.reload;
|
||||
const reloadCopy = reload;
|
||||
reload = () => {
|
||||
reloadCopy?.();
|
||||
reloadLink?.();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,6 @@ export default [
|
||||
['core_blocks_properties_table_item_reset', 'Reset to default'],
|
||||
['core_blocks_properties_table_item_remove', 'Remove property'],
|
||||
['combobox_no_results_placeholder', 'No results'],
|
||||
['core_blocks_exception_message_error_title', 'Unable to display content'],
|
||||
['core_blocks_exception_message_error_message', 'Something went wrong.'],
|
||||
];
|
||||
|
||||
@@ -11,7 +11,6 @@ import { Dependency, injectable } from '@cloudbeaver/core-di';
|
||||
import { ExecutorInterrupter, IAsyncContextLoader, IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import {
|
||||
INodeNavigationData,
|
||||
NavigationType,
|
||||
NavNodeInfoResource,
|
||||
NavNodeManagerService,
|
||||
NavTreeResource,
|
||||
@@ -232,11 +231,7 @@ export class ConnectionNavNodeService extends Dependency {
|
||||
this.navTreeResource.insertToNode(parentId, insertIndex, connection.nodePath);
|
||||
}
|
||||
|
||||
private async navigateHandler({ type, nodeId }: INodeNavigationData, contexts: IExecutionContextProvider<INodeNavigationData>): Promise<void> {
|
||||
if (type !== NavigationType.open) {
|
||||
return;
|
||||
}
|
||||
|
||||
private async navigateHandler({ nodeId }: INodeNavigationData, contexts: IExecutionContextProvider<INodeNavigationData>): Promise<void> {
|
||||
let connection: Connection | undefined | null = await contexts.getContext(this.navigationNavNodeConnectionContext);
|
||||
|
||||
if (NodeManagerUtils.isDatabaseObject(nodeId) && connection) {
|
||||
|
||||
@@ -162,10 +162,22 @@ export class NotificationService {
|
||||
const errorDetails = errorOf(exception, DetailsError);
|
||||
|
||||
if (!silent) {
|
||||
const hasDetails = errorDetails?.hasDetails() ?? false;
|
||||
|
||||
if (hasDetails) {
|
||||
if (!title) {
|
||||
title = exception?.name;
|
||||
}
|
||||
|
||||
if (!message) {
|
||||
message = exception?.message;
|
||||
}
|
||||
}
|
||||
|
||||
this.logError({
|
||||
title: title || exception?.name || 'Error',
|
||||
message: message || exception?.message,
|
||||
details: errorDetails?.hasDetails() ? exception : undefined,
|
||||
title: title || 'ui_unexpected_error',
|
||||
message: message || 'core_blocks_exception_message_error_message',
|
||||
details: exception,
|
||||
isSilent: silent,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,9 +23,11 @@ export default [
|
||||
['ui_minute_first_form', '{arg:interval} minute'],
|
||||
['ui_minute_second_form', '{arg:interval} minutes'],
|
||||
['ui_minute_third_form', '{arg:interval} minutes'],
|
||||
['ui_please_retry', 'Please retry'],
|
||||
['ui_custom', 'Custom'],
|
||||
['ui_configure', 'Configure'],
|
||||
['ui_apply', 'Apply'],
|
||||
['ui_unexpected_error', 'Unexpected error'],
|
||||
['ui_error', 'Error'],
|
||||
['ui_error_message', 'Error:'],
|
||||
['ui_error_close', 'Close'],
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { makeObservable, observable } from 'mobx';
|
||||
import { action } from 'mobx';
|
||||
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import { Executor, IExecutionContextProvider, IExecutor, ISyncContextLoader } from '@cloudbeaver/core-executor';
|
||||
import { resourceKeyList } from '@cloudbeaver/core-sdk';
|
||||
import { Executor, IExecutionContextProvider, IExecutor, ISyncContextLoader, ISyncExecutor, SyncExecutor } from '@cloudbeaver/core-executor';
|
||||
import { resourceKeyList, ResourceKeyUtils } from '@cloudbeaver/core-sdk';
|
||||
import { NavigationService } from '@cloudbeaver/core-ui';
|
||||
import { MetadataMap } from '@cloudbeaver/core-utils';
|
||||
import type { IDataContextProvider } from '@cloudbeaver/core-view';
|
||||
|
||||
import { ENodeFeature } from './ENodeFeature';
|
||||
@@ -22,11 +23,6 @@ import { NavTreeResource } from './NavTreeResource';
|
||||
import { NodeManagerUtils } from './NodeManagerUtils';
|
||||
import { ProjectsNavNodeService } from './ProjectsNavNodeService';
|
||||
|
||||
export enum NavigationType {
|
||||
open,
|
||||
canOpen,
|
||||
}
|
||||
|
||||
export interface NavNodeKey {
|
||||
nodeId: string;
|
||||
parentId?: string;
|
||||
@@ -66,7 +62,6 @@ export interface INavNodeId {
|
||||
}
|
||||
|
||||
export interface INodeNavigationContext {
|
||||
type: NavigationType;
|
||||
projectId: string | undefined;
|
||||
nodeId: string;
|
||||
parentId?: string;
|
||||
@@ -81,7 +76,6 @@ export interface INodeNavigationContext {
|
||||
}
|
||||
|
||||
export interface INodeNavigationData {
|
||||
type: NavigationType;
|
||||
projectId?: string;
|
||||
nodeId: string;
|
||||
parentId?: string;
|
||||
@@ -106,10 +100,10 @@ export interface INavNodeCache {
|
||||
|
||||
@injectable()
|
||||
export class NavNodeManagerService extends Bootstrap {
|
||||
readonly syncNodeInfoCache: Map<string, INavNodeCache>;
|
||||
|
||||
readonly onCanOpen: ISyncExecutor<INodeNavigationData>;
|
||||
readonly navigator: IExecutor<INodeNavigationData>;
|
||||
readonly onMove: IExecutor<INodeMoveData>;
|
||||
private readonly syncNodeInfoCache: MetadataMap<string, INavNodeCache>;
|
||||
|
||||
constructor(
|
||||
readonly navTree: NavTreeResource,
|
||||
@@ -118,22 +112,29 @@ export class NavNodeManagerService extends Bootstrap {
|
||||
navigationService: NavigationService,
|
||||
) {
|
||||
super();
|
||||
this.syncNodeInfoCache = new Map();
|
||||
this.syncNodeInfoCache = new MetadataMap(() => ({ canOpen: false, canMove: false }));
|
||||
this.onMove = new Executor<INodeMoveData>(null, (current, next) => current.type === next.type && current.targetNode === next.targetNode);
|
||||
this.onCanOpen = new SyncExecutor<INodeNavigationData>({
|
||||
nodeId: ROOT_NODE_PATH,
|
||||
parentId: ROOT_NODE_PATH,
|
||||
});
|
||||
this.navigator = new Executor<INodeNavigationData>(
|
||||
{
|
||||
type: NavigationType.open,
|
||||
nodeId: ROOT_NODE_PATH,
|
||||
parentId: ROOT_NODE_PATH,
|
||||
},
|
||||
(active, current) => active.projectId === current.projectId && active.nodeId === current.nodeId && active.type === current.type,
|
||||
(active, current) => active.projectId === current.projectId && active.nodeId === current.nodeId,
|
||||
)
|
||||
.before(navigationService.navigationTask, undefined, data => data.type === NavigationType.open)
|
||||
.before(navigationService.navigationTask)
|
||||
.addHandler(this.navigateHandler.bind(this));
|
||||
|
||||
makeObservable(this, {
|
||||
syncNodeInfoCache: observable,
|
||||
});
|
||||
this.navNodeInfoResource.onItemDelete.addHandler(
|
||||
action(key => {
|
||||
ResourceKeyUtils.forEach(key, key => {
|
||||
this.syncNodeInfoCache.delete(key);
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
register(): void {}
|
||||
@@ -141,7 +142,7 @@ export class NavNodeManagerService extends Bootstrap {
|
||||
load(): void {}
|
||||
|
||||
getNavNodeCache(nodeId: string): INavNodeCache {
|
||||
return this.syncNodeInfoCache.get(nodeId) || { canOpen: false, canMove: false };
|
||||
return this.syncNodeInfoCache.get(nodeId);
|
||||
}
|
||||
|
||||
async canMove(targetNode: NavNode, moveContexts: IDataContextProvider): Promise<boolean> {
|
||||
@@ -153,25 +154,18 @@ export class NavNodeManagerService extends Bootstrap {
|
||||
|
||||
const move = contexts.getContext(navNodeMoveContext);
|
||||
|
||||
let cache = this.syncNodeInfoCache.get(targetNode.id);
|
||||
|
||||
if (!cache) {
|
||||
cache = observable<INavNodeCache>({ canOpen: false, canMove: move.canMove });
|
||||
this.syncNodeInfoCache.set(targetNode.id, cache);
|
||||
}
|
||||
|
||||
const cache = this.syncNodeInfoCache.get(targetNode.id);
|
||||
cache.canMove = move.canMove;
|
||||
|
||||
return move.canMove;
|
||||
}
|
||||
|
||||
async canOpen(nodeId: string, parentId?: string, folderId?: string): Promise<boolean> {
|
||||
canOpen(nodeId: string, parentId?: string, folderId?: string): boolean {
|
||||
if (!this.navNodeInfoResource.has(nodeId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const contexts = await this.navigator.execute({
|
||||
type: NavigationType.canOpen,
|
||||
const contexts = this.onCanOpen.execute({
|
||||
nodeId,
|
||||
parentId,
|
||||
folderId,
|
||||
@@ -179,13 +173,7 @@ export class NavNodeManagerService extends Bootstrap {
|
||||
|
||||
const data = contexts.getContext(this.navigationNavNodeContext);
|
||||
|
||||
let cache = this.syncNodeInfoCache.get(nodeId);
|
||||
|
||||
if (!cache) {
|
||||
cache = observable<INavNodeCache>({ canOpen: data.canOpen, canMove: false });
|
||||
this.syncNodeInfoCache.set(nodeId, cache);
|
||||
}
|
||||
|
||||
const cache = this.syncNodeInfoCache.get(nodeId);
|
||||
cache.canOpen = data.canOpen;
|
||||
|
||||
return data.canOpen;
|
||||
@@ -193,7 +181,6 @@ export class NavNodeManagerService extends Bootstrap {
|
||||
|
||||
async navToNode(nodeId: string, parentId?: string, folderId?: string): Promise<void> {
|
||||
await this.navigator.execute({
|
||||
type: NavigationType.open,
|
||||
nodeId,
|
||||
parentId,
|
||||
folderId,
|
||||
@@ -385,7 +372,6 @@ export class NavNodeManagerService extends Bootstrap {
|
||||
return canOpen;
|
||||
},
|
||||
|
||||
type: data.type,
|
||||
projectId,
|
||||
nodeId,
|
||||
parentId,
|
||||
@@ -403,11 +389,7 @@ export class NavNodeManagerService extends Bootstrap {
|
||||
data: INodeNavigationData,
|
||||
contexts: IExecutionContextProvider<INodeNavigationData>,
|
||||
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
||||
): Promise<void> {
|
||||
if (data.type !== NavigationType.open) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
): Promise<void> {}
|
||||
}
|
||||
|
||||
export function parseNodeParentId(nodeId: string): string {
|
||||
|
||||
@@ -12,6 +12,7 @@ import styled, { css } from 'reshadow';
|
||||
import {
|
||||
BASE_CONTAINERS_STYLES,
|
||||
ErrorMessage,
|
||||
ExceptionMessage,
|
||||
IconOrImage,
|
||||
Loader,
|
||||
Placeholder,
|
||||
@@ -122,7 +123,6 @@ export const ConnectionForm = observer<Props>(function ConnectionForm({ state, o
|
||||
const style = [BASE_TAB_STYLES, tabsStyles, UNDERLINE_TAB_STYLES];
|
||||
const styles = useStyles(style, BASE_CONTAINERS_STYLES, topBarStyles, formStyles);
|
||||
const service = useService(ConnectionFormService);
|
||||
const error = useErrorDetails(state.initError);
|
||||
|
||||
useExecutor({
|
||||
executor: state.submittingTask,
|
||||
@@ -143,8 +143,8 @@ export const ConnectionForm = observer<Props>(function ConnectionForm({ state, o
|
||||
state.loadConnectionInfo();
|
||||
}, [state]);
|
||||
|
||||
if (error.name) {
|
||||
return styled(styles)(<ErrorMessage text={error.message || error.name} hasDetails={error.hasDetails} onShowDetails={error.open} />);
|
||||
if (state.initError) {
|
||||
return styled(styles)(<ExceptionMessage exception={state.initError} onRetry={() => state.loadConnectionInfo()} />);
|
||||
}
|
||||
|
||||
if (!state.configured) {
|
||||
|
||||
@@ -181,8 +181,8 @@ export class ConnectionFormState implements IConnectionFormState {
|
||||
|
||||
async loadConnectionInfo(): Promise<DatabaseConnection | undefined> {
|
||||
try {
|
||||
await this.loadConnectionTask.execute(this);
|
||||
this.initError = null;
|
||||
await this.loadConnectionTask.execute(this);
|
||||
|
||||
return this.info;
|
||||
} catch (exception: any) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ConnectionInfoResource, ConnectionsManagerService, IConnectionExecutorD
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { ExecutorInterrupter, IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { INodeNavigationData, NavigationType, NavNodeManagerService } from '@cloudbeaver/core-navigation-tree';
|
||||
import { INodeNavigationData, NavNodeManagerService } from '@cloudbeaver/core-navigation-tree';
|
||||
import { resourceKeyList } from '@cloudbeaver/core-sdk';
|
||||
import { ITab, NavigationTabsService } from '@cloudbeaver/plugin-navigation-tabs';
|
||||
import { DBObjectPageService, IObjectViewerTabState, isObjectViewerTab, ObjectPage, ObjectViewerTabService } from '@cloudbeaver/plugin-object-viewer';
|
||||
@@ -79,10 +79,6 @@ export class DataViewerTabService {
|
||||
}
|
||||
|
||||
private async navigationHandler(data: INodeNavigationData, contexts: IExecutionContextProvider<INodeNavigationData>) {
|
||||
if (data.type !== NavigationType.open) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { nodeInfo, tabInfo, initTab, trySwitchPage } = await contexts.getContext(this.objectViewerTabService.objectViewerTabContext);
|
||||
|
||||
|
||||
+1
-6
@@ -130,12 +130,7 @@ export class NavNodeContextMenuService extends Bootstrap {
|
||||
}
|
||||
|
||||
if (action === ACTION_OPEN) {
|
||||
// TODO: replace with loader, this call can lead to concurrent calls limit (Executor)
|
||||
untracked(() => {
|
||||
this.navNodeManagerService.canOpen(node.id, node.parentId); // trigger info
|
||||
});
|
||||
|
||||
return this.navNodeManagerService.getNavNodeCache(node.id).canOpen;
|
||||
return this.navNodeManagerService.canOpen(node.id, node.parentId);
|
||||
}
|
||||
|
||||
return [ACTION_OPEN, ACTION_REFRESH].includes(action);
|
||||
|
||||
+1
-5
@@ -8,7 +8,7 @@
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { type INodeNavigationData, NavigationType, NavNodeManagerService } from '@cloudbeaver/core-navigation-tree';
|
||||
import { type INodeNavigationData, NavNodeManagerService } from '@cloudbeaver/core-navigation-tree';
|
||||
|
||||
import { DBObjectPageService } from '../ObjectPage/DBObjectPageService';
|
||||
import type { ObjectPage } from '../ObjectPage/ObjectPage';
|
||||
@@ -39,10 +39,6 @@ export class ObjectPropertiesPageService {
|
||||
}
|
||||
|
||||
private async navigationHandler(data: INodeNavigationData, contexts: IExecutionContextProvider<INodeNavigationData>) {
|
||||
if (data.type !== NavigationType.open) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.page) {
|
||||
// TODO: it will be never true, because navHandler registers after page creation
|
||||
return;
|
||||
|
||||
@@ -21,13 +21,7 @@ import {
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import type { IAsyncContextLoader, IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import {
|
||||
type INodeNavigationData,
|
||||
NavigationType,
|
||||
NavNodeManagerService,
|
||||
NodeManagerUtils,
|
||||
objectNavNodeProvider,
|
||||
} from '@cloudbeaver/core-navigation-tree';
|
||||
import { type INodeNavigationData, NavNodeManagerService, NodeManagerUtils, objectNavNodeProvider } from '@cloudbeaver/core-navigation-tree';
|
||||
import { projectProvider } from '@cloudbeaver/core-projects';
|
||||
import { ResourceKey, resourceKeyList, ResourceKeySimple, ResourceKeyUtils } from '@cloudbeaver/core-sdk';
|
||||
import { ITab, NavigationTabsService, TabHandler } from '@cloudbeaver/plugin-navigation-tabs';
|
||||
@@ -77,6 +71,7 @@ export class ObjectViewerTabService {
|
||||
}
|
||||
|
||||
registerTabHandler(): void {
|
||||
this.navNodeManagerService.onCanOpen.addHandler(this.canOpenHandler.bind(this));
|
||||
this.navNodeManagerService.navigator.addHandler(this.navigationHandler.bind(this));
|
||||
this.navNodeManagerService.navigator.addPostHandler(this.navigationPostHandler.bind(this));
|
||||
this.connectionInfoResource.onConnectionClose.addHandler(this.closeConnectionInfoTabs.bind(this));
|
||||
@@ -366,17 +361,17 @@ export class ObjectViewerTabService {
|
||||
await this.dbObjectPageService.closePages(tab);
|
||||
}
|
||||
|
||||
private canOpenHandler(data: INodeNavigationData, contexts: IExecutionContextProvider<INodeNavigationData>) {
|
||||
const nodeInfo = contexts.getContext(this.navNodeManagerService.navigationNavNodeContext);
|
||||
|
||||
if (NodeManagerUtils.isDatabaseObject(data.nodeId)) {
|
||||
nodeInfo.markOpen();
|
||||
}
|
||||
}
|
||||
|
||||
private async navigationHandler(data: INodeNavigationData, contexts: IExecutionContextProvider<INodeNavigationData>) {
|
||||
try {
|
||||
const { isSupported, nodeInfo, initTab } = await contexts.getContext(this.objectViewerTabContext);
|
||||
|
||||
if (isSupported) {
|
||||
nodeInfo.markOpen();
|
||||
}
|
||||
|
||||
if (data.type !== NavigationType.open) {
|
||||
return;
|
||||
}
|
||||
const { nodeInfo, initTab } = await contexts.getContext(this.objectViewerTabContext);
|
||||
|
||||
const tab = initTab();
|
||||
|
||||
@@ -399,10 +394,6 @@ export class ObjectViewerTabService {
|
||||
}
|
||||
|
||||
private async navigationPostHandler(data: INodeNavigationData, contexts: IExecutionContextProvider<INodeNavigationData>) {
|
||||
if (data.type !== NavigationType.open) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!contexts.hasContext(this.objectViewerTabContext)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogService, DialogueStateResult } from '@cloudbeaver/core-dialogs';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { type INodeNavigationData, NavigationType, NavNodeInfoResource, NavNodeManagerService } from '@cloudbeaver/core-navigation-tree';
|
||||
import { type INodeNavigationData, NavNodeInfoResource, NavNodeManagerService } from '@cloudbeaver/core-navigation-tree';
|
||||
import { createResourceOfType, isResourceOfType, ProjectInfoResource, ProjectsService } from '@cloudbeaver/core-projects';
|
||||
import { NAV_NODE_TYPE_RM_RESOURCE, ResourceManagerResource, RESOURCES_NODE_PATH } from '@cloudbeaver/core-resource-manager';
|
||||
import { CachedMapAllKey } from '@cloudbeaver/core-sdk';
|
||||
@@ -59,6 +59,7 @@ export class PluginBootstrap extends Bootstrap {
|
||||
}
|
||||
|
||||
register(): void | Promise<void> {
|
||||
this.navNodeManagerService.onCanOpen.addHandler(this.canOpenHandler.bind(this));
|
||||
this.navNodeManagerService.navigator.addHandler(this.navigationHandler.bind(this));
|
||||
|
||||
this.actionService.addHandler({
|
||||
@@ -193,46 +194,26 @@ export class PluginBootstrap extends Bootstrap {
|
||||
|
||||
load(): void | Promise<void> {}
|
||||
|
||||
private canOpenHandler(data: INodeNavigationData, contexts: IExecutionContextProvider<INodeNavigationData>): void {
|
||||
const nodeInfo = contexts.getContext(this.navNodeManagerService.navigationNavNodeContext);
|
||||
|
||||
if (this.canOpen(data, contexts)) {
|
||||
nodeInfo.markOpen();
|
||||
}
|
||||
}
|
||||
|
||||
private async navigationHandler(data: INodeNavigationData, contexts: IExecutionContextProvider<INodeNavigationData>) {
|
||||
if (!this.resourceManagerService.enabled) {
|
||||
if (!this.canOpen(data, contexts)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const nodeInfo = contexts.getContext(this.navNodeManagerService.navigationNavNodeContext);
|
||||
|
||||
if (!nodeInfo.projectId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const node = this.navNodeInfoResource.get(data.nodeId);
|
||||
|
||||
const project = this.projectInfoResource.get(nodeInfo.projectId);
|
||||
if (!project) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resourceType = this.projectInfoResource.getResourceType(project, SCRIPTS_TYPE_ID);
|
||||
if (!resourceType) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!node || node.nodeType !== NAV_NODE_TYPE_RM_RESOURCE || !isResourceOfType(resourceType, node.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resourceKey = getResourceKeyFromNodeId(node.id);
|
||||
const resourceKey = getResourceKeyFromNodeId(data.nodeId);
|
||||
|
||||
if (!resourceKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
nodeInfo.markOpen();
|
||||
|
||||
if (data.type !== NavigationType.open) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resource = await this.resourceManagerResource.load(resourceKey);
|
||||
|
||||
const maxSize = this.sqlEditorSettingsService.settings.isValueDefault('maxFileSize')
|
||||
@@ -272,4 +253,40 @@ export class PluginBootstrap extends Bootstrap {
|
||||
this.notificationService.logException(exception as any, 'plugin_sql_editor_navigation_tab_resource_open_script_error');
|
||||
}
|
||||
}
|
||||
|
||||
private canOpen(data: INodeNavigationData, contexts: IExecutionContextProvider<INodeNavigationData>): boolean {
|
||||
if (!this.resourceManagerService.enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const nodeInfo = contexts.getContext(this.navNodeManagerService.navigationNavNodeContext);
|
||||
|
||||
if (!nodeInfo.projectId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const node = this.navNodeInfoResource.get(data.nodeId);
|
||||
|
||||
const project = this.projectInfoResource.get(nodeInfo.projectId);
|
||||
if (!project) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const resourceType = this.projectInfoResource.getResourceType(project, SCRIPTS_TYPE_ID);
|
||||
if (!resourceType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!node || node.nodeType !== NAV_NODE_TYPE_RM_RESOURCE || !isResourceOfType(resourceType, node.id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const resourceKey = getResourceKeyFromNodeId(node.id);
|
||||
|
||||
if (!resourceKey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user