mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
feat: CB-639 public connection edit form
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
"@cloudbeaver/core-sdk": "^0.1.0",
|
||||
"@cloudbeaver/core-settings": "^0.1.0",
|
||||
"@cloudbeaver/core-theming": "^0.1.0",
|
||||
"@cloudbeaver/core-ui": "^0.1.0",
|
||||
"@cloudbeaver/core-utils": "^0.1.0",
|
||||
"@cloudbeaver/core-view": "^0.1.0",
|
||||
"@cloudbeaver/core-executor": "^0.1.0",
|
||||
|
||||
@@ -42,7 +42,7 @@ const mainStyles = composes(
|
||||
`
|
||||
);
|
||||
|
||||
export function Main() {
|
||||
export const Main: React.FC = function Main() {
|
||||
return styled(useStyles(mainStyles, splitStyles))(
|
||||
<space as="main">
|
||||
<Split sticky={30}>
|
||||
@@ -56,4 +56,4 @@ export function Main() {
|
||||
</Split>
|
||||
</space>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,10 +10,11 @@ import { observer } from 'mobx-react-lite';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import {
|
||||
Pane, ResizerControls, Split, splitHorizontalStyles, splitStyles
|
||||
Pane, ResizerControls, SlideBox, SlideElement, slideBoxStyles, Split, splitHorizontalStyles, splitStyles
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import { useController } from '@cloudbeaver/core-di';
|
||||
import { useController, useService } from '@cloudbeaver/core-di';
|
||||
import { useStyles, composes } from '@cloudbeaver/core-theming';
|
||||
import { OptionsPanelService } from '@cloudbeaver/core-ui';
|
||||
|
||||
import { NavigationTabsBar } from '../shared/NavigationTabs/NavigationTabsBar';
|
||||
import { LogViewTab } from '../shared/ToolsPanel/LogViewTab/LogViewTab';
|
||||
@@ -34,21 +35,36 @@ const styles = composes(
|
||||
Pane:last-child {
|
||||
flex: 0 0 30%;
|
||||
}
|
||||
SlideBox {
|
||||
flex: 1;
|
||||
}
|
||||
SlideElement {
|
||||
display: flex;
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
export const RightArea = observer(function RightArea() {
|
||||
const controller = useController(LogViewTabController);
|
||||
const optionsPanelService = useService(OptionsPanelService);
|
||||
const OptionsPanel = optionsPanelService.getPanelComponent();
|
||||
|
||||
return styled(useStyles(styles, splitStyles, splitHorizontalStyles))(
|
||||
<Split sticky={30} split="horizontal" mode={controller.isActive ? undefined : 'minimize'} keepRatio>
|
||||
<Pane>
|
||||
<NavigationTabsBar />
|
||||
</Pane>
|
||||
{controller.isActive && <ResizerControls />}
|
||||
<Pane main>
|
||||
<LogViewTab />
|
||||
</Pane>
|
||||
</Split>
|
||||
return styled(useStyles(styles, splitStyles, splitHorizontalStyles, slideBoxStyles))(
|
||||
<SlideBox open={optionsPanelService.active}>
|
||||
<SlideElement>
|
||||
<OptionsPanel />
|
||||
</SlideElement>
|
||||
<SlideElement>
|
||||
<Split sticky={30} split="horizontal" mode={controller.isActive ? undefined : 'minimize'} keepRatio>
|
||||
<Pane>
|
||||
<NavigationTabsBar />
|
||||
</Pane>
|
||||
{controller.isActive && <ResizerControls />}
|
||||
<Pane main>
|
||||
<LogViewTab />
|
||||
</Pane>
|
||||
</Split>
|
||||
</SlideElement>
|
||||
</SlideBox>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -70,7 +70,12 @@ export const Loader: React.FC<Props> = observer(function Loader({
|
||||
if ('loading' in element) {
|
||||
loading = element.loading;
|
||||
} else if ('isLoading' in element) {
|
||||
loading = element.isLoading() && (overlay || !element.isLoaded());
|
||||
const loaded = element.isLoaded();
|
||||
loading = element.isLoading() || !loaded;
|
||||
|
||||
if (!loaded) {
|
||||
overlay = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
interface Props {
|
||||
open?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const SlideBox: React.FC<Props> = function SlideBox({ children, className }) {
|
||||
return (
|
||||
<div className={className}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { css } from 'reshadow';
|
||||
|
||||
export const slideBoxStyles = css`
|
||||
SlideBox {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
& SlideElement {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
vertical-align:top;
|
||||
transition: transform cubic-bezier(0.4, 0.0, 0.2, 1) 0.6s;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
&[open] SlideElement {
|
||||
transform: translateX(0%);
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const SlideElement: React.FC<Props> = function SlideElement({ children, className }) {
|
||||
return (
|
||||
<div className={className}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -13,7 +13,7 @@ import { Translate } from '@cloudbeaver/core-localization';
|
||||
import { DynamicStyle, useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { TabContext } from '../TabContext';
|
||||
import type { ITabData } from '../TabsContext';
|
||||
import type { ITabData } from '../TabsContainer/ITabsContainer';
|
||||
import { Tab } from './Tab';
|
||||
import { TabIcon } from './TabIcon';
|
||||
import type { TabProps } from './TabProps';
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { PropsWithChildren } from 'react';
|
||||
|
||||
import type { DynamicStyle } from '@cloudbeaver/core-theming';
|
||||
|
||||
import type { ITabData } from '../TabsContext';
|
||||
import type { ITabData } from '../TabsContainer/ITabsContainer';
|
||||
|
||||
export type TabProps = PropsWithChildren<{
|
||||
tabId: string;
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { useContext, useEffect, useRef } from 'react';
|
||||
import { useContext, useEffect } from 'react';
|
||||
|
||||
import type { IExecutorHandler } from '@cloudbeaver/core-executor';
|
||||
|
||||
import { useObjectRef } from '../../useObjectRef';
|
||||
import { ITabData, TabsContext } from '../TabsContext';
|
||||
import type { ITabData } from '../TabsContainer/ITabsContainer';
|
||||
import { TabsContext } from '../TabsContext';
|
||||
|
||||
export function useTab(
|
||||
tabId: string,
|
||||
|
||||
@@ -12,7 +12,7 @@ import styled from 'reshadow';
|
||||
import { DynamicStyle, useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { TabPanel } from './TabPanel';
|
||||
import type { ITabInfo } from './TabsContainer';
|
||||
import type { ITabInfo } from './TabsContainer/ITabsContainer';
|
||||
import { TabsContext } from './TabsContext';
|
||||
|
||||
interface Props {
|
||||
|
||||
@@ -29,7 +29,7 @@ export const TabsBox = forwardRef<HTMLDivElement, TabsBoxProps>(function TabsBox
|
||||
className,
|
||||
style = [],
|
||||
}: TabsBoxProps, ref) {
|
||||
return styled(useStyles(...style))(
|
||||
return styled(useStyles(style))(
|
||||
<TabsState currentTabId={currentTabId}>
|
||||
<tabs-box ref={ref} as="div" className={className} tabIndex={tabIndex}>
|
||||
{tabs && (
|
||||
|
||||
@@ -13,7 +13,7 @@ import { useStyles, Style } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { Tab } from '../Tab';
|
||||
import { TabPanel } from '../TabPanel';
|
||||
import type { ITabData } from '../TabsContext';
|
||||
import type { ITabData } from '../TabsContainer/ITabsContainer';
|
||||
import { TabsBox } from './TabsBox';
|
||||
|
||||
export interface TabElementProps {
|
||||
|
||||
+10
-35
@@ -6,12 +6,14 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { computed, observable, makeObservable } from 'mobx';
|
||||
|
||||
import type { MetadataValueGetter } from '@cloudbeaver/core-utils';
|
||||
|
||||
import type { TabProps } from './Tab/TabProps';
|
||||
import type { ITabData } from './TabsContext';
|
||||
import type { TabProps } from '../Tab/TabProps';
|
||||
|
||||
export interface ITabData<T = Record<string, any>> {
|
||||
tabId: string;
|
||||
props: T;
|
||||
}
|
||||
|
||||
export type TabContainerTabComponent<TProps = Record<string, any>> = React.FC<TabProps & TProps>;
|
||||
export type TabContainerPanelComponent<TProps = Record<string, any>> = React.FC<{ tabId: string } & TProps>;
|
||||
@@ -42,35 +44,8 @@ export interface ITabInfo<
|
||||
order: number;
|
||||
}
|
||||
|
||||
export class TabsContainer<TProps = Record<string, any>, TOptions extends Record<string, any> = never> {
|
||||
readonly tabInfoMap: Map<string, ITabInfo<TProps, TOptions>>;
|
||||
|
||||
get tabInfoList(): Array<ITabInfo<TProps, TOptions>> {
|
||||
return Array.from(this.tabInfoMap.values())
|
||||
.sort((a, b) => a.order - b.order);
|
||||
}
|
||||
|
||||
constructor() {
|
||||
makeObservable(this, {
|
||||
tabInfoMap: observable.shallow,
|
||||
tabInfoList: computed,
|
||||
});
|
||||
|
||||
this.tabInfoMap = new Map();
|
||||
}
|
||||
|
||||
getDisplayed(props?: TProps): Array<ITabInfo<TProps, TOptions>> {
|
||||
return this.tabInfoList.filter(tabInfo => !tabInfo.isHidden?.(tabInfo.key, props));
|
||||
}
|
||||
|
||||
add(tabInfo: ITabInfoOptions<TProps, TOptions>): void {
|
||||
if (this.tabInfoMap.has(tabInfo.key)) {
|
||||
throw new Error('Tab with same key already exists');
|
||||
}
|
||||
|
||||
this.tabInfoMap.set(tabInfo.key, {
|
||||
...tabInfo,
|
||||
order: tabInfo.order ?? Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
}
|
||||
export interface ITabsContainer<TProps = Record<string, any>, TOptions extends Record<string, any> = never> {
|
||||
tabInfoList: Array<ITabInfo<TProps, TOptions>>;
|
||||
getTabInfo: (tabId: string) => ITabInfo<TProps, TOptions> | undefined;
|
||||
getDisplayed: (props?: TProps) => Array<ITabInfo<TProps, TOptions>>;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { computed, observable, makeObservable } from 'mobx';
|
||||
|
||||
import type { ITabInfo, ITabInfoOptions, ITabsContainer } from './ITabsContainer';
|
||||
|
||||
export class TabsContainer<TProps = Record<string, any>, TOptions extends Record<string, any> = never>
|
||||
implements ITabsContainer<TProps, TOptions> {
|
||||
readonly tabInfoMap: Map<string, ITabInfo<TProps, TOptions>>;
|
||||
|
||||
get tabInfoList(): Array<ITabInfo<TProps, TOptions>> {
|
||||
return Array.from(this.tabInfoMap.values())
|
||||
.sort((a, b) => a.order - b.order);
|
||||
}
|
||||
|
||||
constructor() {
|
||||
makeObservable(this, {
|
||||
tabInfoMap: observable.shallow,
|
||||
tabInfoList: computed,
|
||||
});
|
||||
|
||||
this.tabInfoMap = new Map();
|
||||
}
|
||||
|
||||
getTabInfo(tabId: string): ITabInfo<TProps, TOptions> | undefined {
|
||||
return this.tabInfoMap.get(tabId);
|
||||
}
|
||||
|
||||
getDisplayed(props?: TProps): Array<ITabInfo<TProps, TOptions>> {
|
||||
return this.tabInfoList.filter(tabInfo => !tabInfo.isHidden?.(tabInfo.key, props));
|
||||
}
|
||||
|
||||
add(tabInfo: ITabInfoOptions<TProps, TOptions>): void {
|
||||
if (this.tabInfoMap.has(tabInfo.key)) {
|
||||
throw new Error('Tab with same key already exists');
|
||||
}
|
||||
|
||||
this.tabInfoMap.set(tabInfo.key, {
|
||||
...tabInfo,
|
||||
order: tabInfo.order ?? Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -12,18 +12,13 @@ import type { TabStateReturn } from 'reakit/Tab';
|
||||
import type { IExecutor } from '@cloudbeaver/core-executor';
|
||||
import type { MetadataMap } from '@cloudbeaver/core-utils';
|
||||
|
||||
import type { ITabInfo, TabsContainer } from './TabsContainer';
|
||||
|
||||
export interface ITabData<T = Record<string, any>> {
|
||||
tabId: string;
|
||||
props: T;
|
||||
}
|
||||
import type { ITabData, ITabInfo, ITabsContainer } from './TabsContainer/ITabsContainer';
|
||||
|
||||
export interface ITabsContext<T = Record<string, any>> {
|
||||
state: TabStateReturn;
|
||||
tabsState: MetadataMap<string, any>;
|
||||
props: T;
|
||||
container?: TabsContainer<T>;
|
||||
container?: ITabsContainer<T>;
|
||||
openExecutor: IExecutor<ITabData<T>>;
|
||||
closeExecutor: IExecutor<ITabData<T>>;
|
||||
lazy: boolean;
|
||||
|
||||
@@ -13,14 +13,14 @@ import { Executor, ExecutorInterrupter, IExecutorHandler } from '@cloudbeaver/co
|
||||
import { MetadataMap } from '@cloudbeaver/core-utils';
|
||||
|
||||
import { useObjectRef } from '../useObjectRef';
|
||||
import type { TabsContainer } from './TabsContainer';
|
||||
import { TabsContext, ITabsContext, ITabData } from './TabsContext';
|
||||
import type { ITabData, ITabsContainer } from './TabsContainer/ITabsContainer';
|
||||
import { TabsContext, ITabsContext } from './TabsContext';
|
||||
|
||||
type Props<T = Record<string, any>> = T & React.PropsWithChildren<{
|
||||
selectedId?: string;
|
||||
orientation?: 'horizontal' | 'vertical';
|
||||
currentTabId?: string | null;
|
||||
container?: TabsContainer<T, any>;
|
||||
container?: ITabsContainer<T, any>;
|
||||
localState?: MetadataMap<string, any>;
|
||||
lazy?: boolean;
|
||||
manual?: boolean;
|
||||
@@ -120,7 +120,7 @@ export function TabsState<T = Record<string, any>>({
|
||||
props: dynamic.props,
|
||||
}), []);
|
||||
|
||||
const getTabInfo = useCallback((tabId: string) => dynamic.container?.tabInfoMap.get(tabId), []);
|
||||
const getTabInfo = useCallback((tabId: string) => dynamic.container?.getTabInfo(tabId), []);
|
||||
|
||||
const value = useMemo<ITabsContext<T>>(() => ({
|
||||
state,
|
||||
|
||||
@@ -4,7 +4,8 @@ export * from './TabList';
|
||||
export * from './TabPanel';
|
||||
export * from './TabPanelList';
|
||||
export * from './TabPanelProps';
|
||||
export * from './TabsContainer';
|
||||
export * from './TabsContainer/ITabsContainer';
|
||||
export * from './TabsContainer/TabsContainer';
|
||||
export * from './TabsContext';
|
||||
export * from './TabsState';
|
||||
export * from './useTabState';
|
||||
|
||||
@@ -11,6 +11,9 @@ export * from './Placeholder/Placeholder';
|
||||
export * from './Placeholder/PlaceholderContainer';
|
||||
export * from './PropertiesTable';
|
||||
export * from './SanitizedHTML/SanitizedHTML';
|
||||
export * from './Slide/SlideBox';
|
||||
export * from './Slide/SlideBoxStyles';
|
||||
export * from './Slide/SlideElement';
|
||||
export * from './Split';
|
||||
export * from './Table';
|
||||
export * from './Tabs';
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
"@cloudbeaver/core-sdk": "^0.1.0",
|
||||
"@cloudbeaver/core-settings": "^0.1.0",
|
||||
"@cloudbeaver/core-theming": "^0.1.0",
|
||||
"@cloudbeaver/core-ui": "^0.1.0",
|
||||
"@cloudbeaver/core-utils": "^0.1.0",
|
||||
"@cloudbeaver/core-view": "^0.1.0",
|
||||
"react": "^16.x.x",
|
||||
|
||||
@@ -92,6 +92,7 @@ import { RouterService, ScreenService } from '@cloudbeaver/core-routing';
|
||||
import { EnvironmentService, GraphQLService } from '@cloudbeaver/core-sdk';
|
||||
import { LocalStorageSaveService, SettingsService } from '@cloudbeaver/core-settings';
|
||||
import { ThemeService } from '@cloudbeaver/core-theming';
|
||||
import { OptionsPanelService } from '@cloudbeaver/core-ui';
|
||||
import { ActiveViewService } from '@cloudbeaver/core-view';
|
||||
|
||||
export const coreManifest: PluginManifest = {
|
||||
@@ -154,6 +155,7 @@ export const coreManifest: PluginManifest = {
|
||||
EnvironmentService,
|
||||
ExceptionsCatcherService,
|
||||
EventsSettingsService,
|
||||
OptionsPanelService,
|
||||
GraphQLService,
|
||||
LocalStorageSaveService,
|
||||
LocalizationService,
|
||||
|
||||
@@ -235,6 +235,9 @@ export class ConnectionsResource extends CachedMapResource<string, DatabaseConne
|
||||
}
|
||||
|
||||
export function isLocalConnection(connection: DatabaseConnection): boolean {
|
||||
if (!connection.origin) {
|
||||
return true;
|
||||
}
|
||||
return connection.origin.type === 'local';
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -83,7 +83,10 @@ export class ConnectionOptionsTabService extends Bootstrap {
|
||||
}
|
||||
} else {
|
||||
if (submitType === 'submit') {
|
||||
if (options.mode === 'create') {
|
||||
if (options.mode === 'edit') {
|
||||
const connection = await this.connectionInfoResource.update(config);
|
||||
status.info(`Connection ${connection.name} updated`);
|
||||
} else {
|
||||
const connection = await this.connectionInfoResource.createConnection(config);
|
||||
config.connectionId = connection.id;
|
||||
status.info(`Connection ${connection.name} created`);
|
||||
|
||||
@@ -180,6 +180,19 @@ export class ConnectionInfoResource extends CachedMapResource<string, Connection
|
||||
return this.get(id)!;
|
||||
}
|
||||
|
||||
async update(config: ConnectionConfig): Promise<DatabaseConnection> {
|
||||
await this.performUpdate(config.connectionId!, [], async () => {
|
||||
const { connection } = await this.graphQLService.sdk.updateConnection({
|
||||
config,
|
||||
...this.getDefaultIncludes(),
|
||||
...this.getIncludesMap(config.connectionId!),
|
||||
});
|
||||
|
||||
this.updateConnection(connection);
|
||||
});
|
||||
return this.get(config.connectionId!)!;
|
||||
}
|
||||
|
||||
async close(id: string): Promise<Connection> {
|
||||
await this.performUpdate(id, [], async () => {
|
||||
const { connection } = await this.graphQLService.sdk.closeConnection({
|
||||
|
||||
@@ -5,6 +5,7 @@ export * from './ConnectionForm/OriginInfo/ConnectionOriginInfoTabService';
|
||||
export * from './ConnectionForm/ConnectionAccess/ConnectionAccessTabService';
|
||||
export * from './ConnectionForm/ConnectionFormService';
|
||||
export * from './ConnectionForm/useConnectionFormState';
|
||||
export * from './ConnectionForm/ConnectionForm';
|
||||
export * from './Administration/Connections/ConnectionsAdministration';
|
||||
export * from './Administration/Connections/ConnectionsAdministrationNavService';
|
||||
export * from './Administration/Connections/ConnectionsAdministrationService';
|
||||
|
||||
@@ -14,7 +14,7 @@ import type { IExecutorHandler } from './IExecutorHandler';
|
||||
import type { IExecutorHandlersCollection } from './IExecutorHandlersCollection';
|
||||
import { BlockedExecution, TaskScheduler } from './TaskScheduler/TaskScheduler';
|
||||
|
||||
export class Executor<T = unknown> implements IExecutor<T> {
|
||||
export class Executor<T = void> implements IExecutor<T> {
|
||||
private collection: ExecutorHandlersCollection<T>;
|
||||
private scheduler: TaskScheduler<T>;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { IExecutionContext, IExecutionContextProvider } from './IExecutionC
|
||||
import type { IExecutorHandler } from './IExecutorHandler';
|
||||
import type { IExecutorHandlersCollection } from './IExecutorHandlersCollection';
|
||||
|
||||
export interface IExecutor<T = unknown> {
|
||||
export interface IExecutor<T = void> {
|
||||
before: <TNext extends T>(executor: IExecutor<TNext>, map?: (data: T) => TNext) => this;
|
||||
next: <TNext extends T>(executor: IExecutor<TNext>, map?: (data: T) => TNext) => this;
|
||||
execute: (
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
mutation updateConnection(
|
||||
$config: ConnectionConfig!
|
||||
|
||||
$includeOrigin: Boolean!,
|
||||
$customIncludeOriginDetails: Boolean!,
|
||||
$includeAuthProperties: Boolean!,
|
||||
$customIncludeNetworkHandlerCredentials: Boolean!
|
||||
) {
|
||||
connection: updateConnection(config: $config) {
|
||||
...DatabaseConnection
|
||||
}
|
||||
}
|
||||
@@ -279,6 +279,7 @@ export interface Mutation {
|
||||
testConnection: ConnectionInfo;
|
||||
testNetworkHandler: NetworkEndpointInfo;
|
||||
touchSession?: Maybe<Scalars['Boolean']>;
|
||||
updateConnection: ConnectionInfo;
|
||||
updateResultsData?: Maybe<SqlExecuteInfo>;
|
||||
updateResultsDataBatch?: Maybe<SqlExecuteInfo>;
|
||||
}
|
||||
@@ -389,6 +390,10 @@ export interface MutationTestNetworkHandlerArgs {
|
||||
config: NetworkHandlerConfigInput;
|
||||
}
|
||||
|
||||
export interface MutationUpdateConnectionArgs {
|
||||
config: ConnectionConfig;
|
||||
}
|
||||
|
||||
export interface MutationUpdateResultsDataArgs {
|
||||
connectionId: Scalars['ID'];
|
||||
contextId: Scalars['ID'];
|
||||
@@ -1217,6 +1222,16 @@ export type TestNetworkHandlerMutationVariables = Exact<{
|
||||
|
||||
export interface TestNetworkHandlerMutation { testNetworkHandler: Pick<NetworkEndpointInfo, 'message' | 'clientVersion' | 'serverVersion'> }
|
||||
|
||||
export type UpdateConnectionMutationVariables = Exact<{
|
||||
config: ConnectionConfig;
|
||||
includeOrigin: Scalars['Boolean'];
|
||||
customIncludeOriginDetails: Scalars['Boolean'];
|
||||
includeAuthProperties: Scalars['Boolean'];
|
||||
customIncludeNetworkHandlerCredentials: Scalars['Boolean'];
|
||||
}>;
|
||||
|
||||
export interface UpdateConnectionMutation { connection: DatabaseConnectionFragment }
|
||||
|
||||
export type ExportDataFromContainerQueryVariables = Exact<{
|
||||
connectionId: Scalars['ID'];
|
||||
containerNodePath: Scalars['ID'];
|
||||
@@ -2045,6 +2060,13 @@ export const TestNetworkHandlerDocument = `
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const UpdateConnectionDocument = `
|
||||
mutation updateConnection($config: ConnectionConfig!, $includeOrigin: Boolean!, $customIncludeOriginDetails: Boolean!, $includeAuthProperties: Boolean!, $customIncludeNetworkHandlerCredentials: Boolean!) {
|
||||
connection: updateConnection(config: $config) {
|
||||
...DatabaseConnection
|
||||
}
|
||||
}
|
||||
${DatabaseConnectionFragmentDoc}`;
|
||||
export const ExportDataFromContainerDocument = `
|
||||
query exportDataFromContainer($connectionId: ID!, $containerNodePath: ID!, $parameters: DataTransferParameters!) {
|
||||
taskInfo: dataTransferExportDataFromContainer(
|
||||
@@ -2603,6 +2625,9 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
|
||||
testNetworkHandler(variables: TestNetworkHandlerMutationVariables): Promise<TestNetworkHandlerMutation> {
|
||||
return withWrapper(() => client.request<TestNetworkHandlerMutation>(TestNetworkHandlerDocument, variables));
|
||||
},
|
||||
updateConnection(variables: UpdateConnectionMutationVariables): Promise<UpdateConnectionMutation> {
|
||||
return withWrapper(() => client.request<UpdateConnectionMutation>(UpdateConnectionDocument, variables));
|
||||
},
|
||||
exportDataFromContainer(variables: ExportDataFromContainerQueryVariables): Promise<ExportDataFromContainerQuery> {
|
||||
return withWrapper(() => client.request<ExportDataFromContainerQuery>(ExportDataFromContainerDocument, variables));
|
||||
},
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/lib
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env*
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@cloudbeaver/core-ui",
|
||||
"sideEffects": false,
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"license": "Apache-2.0",
|
||||
"main": "lib/index.js",
|
||||
"module": "lib/index.js",
|
||||
"types": "src/index.ts",
|
||||
"scripts": {
|
||||
"prebuild": "rimraf lib/*",
|
||||
"build": "webpack --config ../../configs/webpack.plugin.config.js",
|
||||
"postbuild": "tsc",
|
||||
"lint": "eslint ./src/ --ext .ts,.tsx",
|
||||
"lint-fix": "eslint ./src/ --ext .ts,.tsx --fix"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@cloudbeaver/core-di": "^0.1.0",
|
||||
"@cloudbeaver/core-executor": "^0.1.0",
|
||||
"mobx": "^5.x.x"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* 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 { injectable } from '@cloudbeaver/core-di';
|
||||
import { Executor, ExecutorInterrupter, IExecutor } from '@cloudbeaver/core-executor';
|
||||
|
||||
@injectable()
|
||||
export class OptionsPanelService {
|
||||
active: boolean;
|
||||
closeTask: IExecutor;
|
||||
|
||||
panelComponent: (() => React.FC) | null;
|
||||
|
||||
constructor() {
|
||||
makeObservable(this, {
|
||||
active: observable,
|
||||
panelComponent: observable,
|
||||
});
|
||||
this.active = false;
|
||||
this.panelComponent = null;
|
||||
this.closeTask = new Executor();
|
||||
}
|
||||
|
||||
getPanelComponent(): React.FC {
|
||||
if (this.panelComponent === null) {
|
||||
return () => null;
|
||||
}
|
||||
return this.panelComponent();
|
||||
}
|
||||
|
||||
async open(component: () => React.FC): Promise<void> {
|
||||
if (!(await this.close(component))) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.panelComponent = component;
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
async close(component: () => React.FC): Promise<boolean> {
|
||||
if (component !== this.panelComponent || this.panelComponent === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const contexts = await this.closeTask.execute();
|
||||
|
||||
const interrupted = contexts.getContext(ExecutorInterrupter.interruptContext);
|
||||
|
||||
if (interrupted.interrupted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.panelComponent = null;
|
||||
this.active = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './Screens/AppScreen/OptionsPanelService';
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["**/node_modules", "**/.*/"],
|
||||
}
|
||||
-115
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { useAdministrationSettings } from '@cloudbeaver/core-administration';
|
||||
import {
|
||||
InputField,
|
||||
useFocus,
|
||||
ObjectPropertyInfoForm,
|
||||
InputGroup,
|
||||
FieldCheckbox,
|
||||
SubmittingForm,
|
||||
FormBox,
|
||||
FormBoxElement,
|
||||
FormGroup,
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import type { DBDriver } from '@cloudbeaver/core-connections';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import type { IFormController } from './IFormController';
|
||||
import { ParametersForm } from './ParametersForm';
|
||||
|
||||
interface ConnectionFormProps {
|
||||
driver: DBDriver | null;
|
||||
controller: IFormController;
|
||||
}
|
||||
|
||||
const connectionFormStyles = css`
|
||||
SubmittingForm {
|
||||
flex: 1;
|
||||
}
|
||||
FormBoxElement {
|
||||
flex: 1;
|
||||
}
|
||||
FormBox {
|
||||
padding: 24px 4px 24px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const ConnectionForm = observer(function ConnectionForm({
|
||||
driver,
|
||||
controller,
|
||||
}: ConnectionFormProps) {
|
||||
const translate = useTranslate();
|
||||
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
|
||||
const { credentialsSavingEnabled } = useAdministrationSettings();
|
||||
|
||||
return styled(useStyles(connectionFormStyles))(
|
||||
<SubmittingForm ref={focusedRef} onChange={controller.onChange}>
|
||||
<FormBox>
|
||||
<FormBoxElement>
|
||||
<FormGroup>
|
||||
<InputField
|
||||
type="text"
|
||||
name="name"
|
||||
disabled={controller.isConnecting}
|
||||
mod='surface'
|
||||
state={controller.config}
|
||||
>
|
||||
{translate('customConnection_custom_name')}
|
||||
</InputField>
|
||||
</FormGroup>
|
||||
{controller.isUrlConnection ? (
|
||||
<FormGroup>
|
||||
<InputField
|
||||
type="text"
|
||||
name="url"
|
||||
state={controller.config}
|
||||
disabled={controller.isConnecting}
|
||||
mod='surface'
|
||||
>
|
||||
{translate('customConnection_url_JDBC')}
|
||||
</InputField>
|
||||
</FormGroup>
|
||||
) : (
|
||||
<ParametersForm controller={controller} embedded={driver?.embedded} />
|
||||
)}
|
||||
{controller.authModel && (
|
||||
<>
|
||||
<FormGroup>
|
||||
<InputGroup>{translate('connections_connection_edit_authentication')}</InputGroup>
|
||||
</FormGroup>
|
||||
<ObjectPropertyInfoForm
|
||||
autofillToken='new-password'
|
||||
properties={controller.authModel.properties}
|
||||
state={controller.config.credentials}
|
||||
disabled={controller.isConnecting}
|
||||
/>
|
||||
{credentialsSavingEnabled && (
|
||||
<FormGroup>
|
||||
<FieldCheckbox
|
||||
name="saveCredentials"
|
||||
value={controller.authModel.id}
|
||||
state={controller.config}
|
||||
checkboxLabel={translate('connections_connection_edit_save_credentials')}
|
||||
disabled={controller.isConnecting}
|
||||
mod='surface'
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</FormBoxElement>
|
||||
</FormBox>
|
||||
</SubmittingForm>
|
||||
);
|
||||
});
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { ConnectionConfig, DatabaseAuthModel } from '@cloudbeaver/core-sdk';
|
||||
|
||||
export interface IFormController {
|
||||
authModel?: DatabaseAuthModel;
|
||||
config: ConnectionConfig;
|
||||
isUrlConnection: boolean;
|
||||
isConnecting: boolean;
|
||||
onChange: (value?: unknown, name?: string) => void;
|
||||
}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import styled, { css, use } from 'reshadow';
|
||||
|
||||
import { InputField } from '@cloudbeaver/core-blocks';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import type { IFormController } from './IFormController';
|
||||
|
||||
interface ParametersFormProps {
|
||||
controller: IFormController;
|
||||
embedded?: boolean;
|
||||
}
|
||||
|
||||
const parametersFormStyles = css`
|
||||
sub-label {
|
||||
composes: theme-typography--caption from global;
|
||||
line-height: 14px;
|
||||
}`;
|
||||
|
||||
export const ParametersForm = observer(function ParametersForm({
|
||||
controller,
|
||||
embedded,
|
||||
}: ParametersFormProps) {
|
||||
const translate = useTranslate();
|
||||
|
||||
return styled(useStyles(parametersFormStyles))(
|
||||
<>
|
||||
{!embedded && (
|
||||
<layout-grid-inner as="div">
|
||||
<layout-grid-cell as='div' {...use({ 'span-tablet': 12, 'span-desktop': 8 })}>
|
||||
<InputField
|
||||
type="text"
|
||||
name="host"
|
||||
disabled={controller.isConnecting}
|
||||
mod='surface'
|
||||
state={controller.config}
|
||||
>
|
||||
{translate('customConnection_custom_host')}
|
||||
<sub-label as="div">{translate('customConnection_custom_obligatory')}</sub-label>
|
||||
</InputField>
|
||||
</layout-grid-cell>
|
||||
<layout-grid-cell as='div' {...use({ 'span-tablet': 12, 'span-desktop': 4 })}>
|
||||
<InputField
|
||||
type="number"
|
||||
name="port"
|
||||
disabled={controller.isConnecting}
|
||||
mod='surface'
|
||||
state={controller.config}
|
||||
short
|
||||
>
|
||||
{translate('customConnection_custom_port')}
|
||||
</InputField>
|
||||
</layout-grid-cell>
|
||||
</layout-grid-inner>
|
||||
)}
|
||||
<group as="div">
|
||||
<InputField
|
||||
type="text"
|
||||
name="databaseName"
|
||||
disabled={controller.isConnecting}
|
||||
mod='surface'
|
||||
state={controller.config}
|
||||
>
|
||||
{translate('customConnection_custom_database')}
|
||||
</InputField>
|
||||
</group>
|
||||
</>
|
||||
);
|
||||
});
|
||||
@@ -14,7 +14,7 @@ import { TemplateConnectionsResource } from './TemplateConnectionsResource';
|
||||
|
||||
export const connectionTemplate: PluginManifest = {
|
||||
info: {
|
||||
name: 'Connection template plugin',
|
||||
name: 'Connections plugin',
|
||||
},
|
||||
|
||||
providers: [
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/lib
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env*
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "@cloudbeaver/plugin-connections",
|
||||
"sideEffects": false,
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"license": "Apache-2.0",
|
||||
"main": "lib/index.js",
|
||||
"module": "lib/index.js",
|
||||
"types": "src/index.ts",
|
||||
"scripts": {
|
||||
"prebuild": "rimraf lib/*",
|
||||
"build": "webpack --config ../../configs/webpack.plugin.config.js",
|
||||
"postbuild": "tsc",
|
||||
"lint": "eslint ./src/ --ext .ts,.tsx",
|
||||
"lint-fix": "eslint ./src/ --ext .ts,.tsx --fix"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@cloudbeaver/core-app": "^0.1.0",
|
||||
"@cloudbeaver/core-blocks": "^0.1.0",
|
||||
"@cloudbeaver/core-connections": "^0.1.0",
|
||||
"@cloudbeaver/core-di": "^0.1.0",
|
||||
"@cloudbeaver/core-dialogs": "^0.1.0",
|
||||
"@cloudbeaver/core-events": "^0.1.0",
|
||||
"@cloudbeaver/core-extensions": "^0.1.0",
|
||||
"@cloudbeaver/core-localization": "^0.1.0",
|
||||
"@cloudbeaver/core-plugin": "^0.1.0",
|
||||
"@cloudbeaver/core-product": "^0.1.0",
|
||||
"@cloudbeaver/core-root": "^0.1.0",
|
||||
"@cloudbeaver/core-sdk": "^0.1.0",
|
||||
"@cloudbeaver/core-settings": "^0.1.0",
|
||||
"@cloudbeaver/core-theming": "^0.1.0",
|
||||
"@cloudbeaver/core-ui": "^0.1.0",
|
||||
"@cloudbeaver/core-utils": "^0.1.0",
|
||||
"react": "^16.x.x",
|
||||
"rxjs": "^6.x.x",
|
||||
"mobx": "^5.x.x",
|
||||
"mobx-react-lite": "^3.x.x",
|
||||
"reshadow": "^0.x.x"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observable } from 'mobx';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useCallback, useState } from 'react';
|
||||
import styled from 'reshadow';
|
||||
import { css } from 'reshadow';
|
||||
|
||||
import { Loader, useMapResource } from '@cloudbeaver/core-blocks';
|
||||
import { ConnectionInfoResource, IConnectionFormData, IConnectionFormOptions, ConnectionForm } from '@cloudbeaver/core-connections';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { MetadataMap } from '@cloudbeaver/core-utils';
|
||||
|
||||
import { PublicConnectionFormService } from './PublicConnectionFormService';
|
||||
|
||||
const styles = css`
|
||||
Loader {
|
||||
height: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
export const PublicConnectionForm: React.FC = observer(function PublicConnectionForm() {
|
||||
const service = useService(PublicConnectionFormService);
|
||||
const connection = useMapResource(ConnectionInfoResource, {
|
||||
key: service.connectionId,
|
||||
includes: ['includeOrigin', 'customIncludeNetworkHandlerCredentials', 'includeAuthProperties', 'customIncludeNetworkHandlerCredentials'],
|
||||
});
|
||||
|
||||
const [data] = useState<IConnectionFormData>(() => ({
|
||||
config: observable({}),
|
||||
get info() {
|
||||
return connection.data;
|
||||
},
|
||||
resource: connection.resource,
|
||||
partsState: new MetadataMap<string, any>(),
|
||||
}));
|
||||
|
||||
const [options] = useState<IConnectionFormOptions>(() => ({
|
||||
mode: 'edit',
|
||||
type: 'public',
|
||||
}));
|
||||
|
||||
const close = useCallback(() => service.close(), []);
|
||||
|
||||
return styled(styles)(
|
||||
<Loader state={connection}>
|
||||
{() => (
|
||||
<ConnectionForm
|
||||
data={data}
|
||||
options={options}
|
||||
onCancel={close}
|
||||
onSave={close}
|
||||
/>
|
||||
)}
|
||||
</Loader>
|
||||
);
|
||||
});
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
NavigationTreeContextMenuService,
|
||||
EObjectFeature,
|
||||
NodeManagerUtils,
|
||||
NavNode
|
||||
} from '@cloudbeaver/core-app';
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import { ContextMenuService } from '@cloudbeaver/core-dialogs';
|
||||
|
||||
import { PublicConnectionFormService } from './PublicConnectionFormService';
|
||||
|
||||
@injectable()
|
||||
export class PublicConnectionFormBootstrap extends Bootstrap {
|
||||
constructor(
|
||||
private readonly contextMenuService: ContextMenuService,
|
||||
private readonly publicConnectionFormService: PublicConnectionFormService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
register(): void | Promise<void> {
|
||||
this.contextMenuService.addMenuItem<NavNode>(this.contextMenuService.getRootMenuToken(), {
|
||||
id: 'connection-edit',
|
||||
isPresent(context) {
|
||||
return context.contextType === NavigationTreeContextMenuService.nodeContextType
|
||||
&& context.data.objectFeatures.includes(EObjectFeature.dataSource);
|
||||
},
|
||||
title: 'Edit',
|
||||
order: 2,
|
||||
onClick: context => {
|
||||
const node = context.data;
|
||||
const connectionId = NodeManagerUtils.connectionNodeIdToConnectionId(node.id);
|
||||
this.publicConnectionFormService.open(connectionId);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
load(): void | Promise<void> {
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { OptionsPanelService } from '@cloudbeaver/core-ui';
|
||||
|
||||
import { PublicConnectionForm } from './PublicConnectionForm';
|
||||
|
||||
const formGetter = () => PublicConnectionForm;
|
||||
|
||||
@injectable()
|
||||
export class PublicConnectionFormService {
|
||||
connectionId: string | null;
|
||||
|
||||
constructor(
|
||||
private readonly optionsPanelService: OptionsPanelService
|
||||
) {
|
||||
this.connectionId = null;
|
||||
}
|
||||
|
||||
async open(connectionId: string): Promise<void> {
|
||||
this.connectionId = connectionId;
|
||||
await this.optionsPanelService.open(formGetter);
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
this.connectionId = null;
|
||||
await this.optionsPanelService.close(formGetter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { connectionPlugin } from './manifest';
|
||||
|
||||
export default connectionPlugin;
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import type { PluginManifest } from '@cloudbeaver/core-di';
|
||||
|
||||
import { PublicConnectionFormBootstrap } from './PublicConnectionForm/PublicConnectionFormBootstrap';
|
||||
import { PublicConnectionFormService } from './PublicConnectionForm/PublicConnectionFormService';
|
||||
|
||||
export const connectionPlugin: PluginManifest = {
|
||||
info: {
|
||||
name: 'Connection template plugin',
|
||||
},
|
||||
|
||||
providers: [
|
||||
PublicConnectionFormBootstrap,
|
||||
PublicConnectionFormService,
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["**/node_modules", "**/.*/"],
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import administration from '@cloudbeaver/plugin-administration';
|
||||
import authentication from '@cloudbeaver/plugin-authentication';
|
||||
import connectionCustom from '@cloudbeaver/plugin-connection-custom';
|
||||
import connectionTemplate from '@cloudbeaver/plugin-connection-template';
|
||||
import connectionPlugin from '@cloudbeaver/plugin-connections';
|
||||
import dataExport from '@cloudbeaver/plugin-data-export';
|
||||
import spreadsheetNew from '@cloudbeaver/plugin-data-spreadsheet-new';
|
||||
import dataViewer from '@cloudbeaver/plugin-data-viewer';
|
||||
@@ -27,6 +28,7 @@ const PLUGINS = [
|
||||
objectViewer,
|
||||
sqlEditor,
|
||||
defaultProductManifest,
|
||||
connectionPlugin,
|
||||
];
|
||||
|
||||
bootstrap(PLUGINS);
|
||||
|
||||
Reference in New Issue
Block a user