Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New connections modal #5606

Merged
merged 17 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const LabeledTextInput = forwardRef<HTMLInputElement, LabeledTextInputPro
return (
<div className={positronClassNames('labeled-text-input', { 'disabled': props.disabled })}>
<label className='label'>
{props.label}
<span className='label-text'>{props.label}</span>
<input
className={positronClassNames('text-input', { 'error': props.error })}
ref={ref}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { IPositronConnectionInstance } from 'vs/workbench/services/positronConne
import { DisposableStore } from 'vs/base/common/lifecycle';
import { showResumeConnectionModalDialog } from 'vs/workbench/contrib/positronConnections/browser/components/resumeConnectionModalDialog';
import { localize } from 'vs/nls';
import { showNewConnectionModalDialog } from 'vs/workbench/contrib/positronConnections/browser/components/newConnectionModalDialog';

export interface ListConnnectionsProps extends ViewsProps { }

Expand Down Expand Up @@ -121,6 +122,9 @@ export const ListConnections = (props: React.PropsWithChildren<ListConnnectionsP
} :
undefined
}
onNewConnection={() => {
showNewConnectionModalDialog(context);
}}
>
</ActionBar>
<div className='connections-list-container'>
Expand Down Expand Up @@ -171,6 +175,7 @@ const ACTION_BAR_HEIGHT = 32;

interface ActionBarProps extends PositronConnectionsServices {
onDeleteConnection?: () => void;
onNewConnection: () => void;
}

const ActionBar = (props: React.PropsWithChildren<ActionBarProps>) => {
Expand All @@ -190,7 +195,9 @@ const ActionBar = (props: React.PropsWithChildren<ActionBarProps>) => {
align='left'
iconId='positron-new-connection'
text={localize('positron.listConnections.newConnection', 'New Connection')}
disabled={true}
onPressed={() => {
props.onNewConnection();
}}
/>
</ActionBarRegion>
<ActionBarRegion location='right'>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------------------------
* Copyright (C) 2024 Posit Software, PBC. All rights reserved.
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information.
*--------------------------------------------------------------------------------------------*/


import React, { PropsWithChildren, useState } from 'react';
import { localize } from 'vs/nls';
import { PositronModalDialog } from 'vs/workbench/browser/positronComponents/positronModalDialog/positronModalDialog';
import { PositronModalReactRenderer } from 'vs/workbench/browser/positronModalReactRenderer/positronModalReactRenderer';
import { PositronConnectionsServices } from 'vs/workbench/contrib/positronConnections/browser/positronConnectionsContext';
import 'vs/css!./newConnectionModelDialog';
import { ContentArea } from 'vs/workbench/browser/positronComponents/positronModalDialog/components/contentArea';
import { CreateConnection } from 'vs/workbench/contrib/positronConnections/browser/components/newConnectionModalDialog/createConnectionState';
import { ListDrivers } from 'vs/workbench/contrib/positronConnections/browser/components/newConnectionModalDialog/listDriversState';
import { IDriver } from 'vs/workbench/services/positronConnections/browser/interfaces/positronConnectionsDriver';

const NEW_CONNECTION_MODAL_DIALOG_WIDTH = 700;
const NEW_CONNECTION_MODAL_DIALOG_HEIGHT = 630;

export const showNewConnectionModalDialog = (services: PositronConnectionsServices) => {

// Create the renderer.
const renderer = new PositronModalReactRenderer({
keybindingService: services.keybindingService,
layoutService: services.layoutService,
container: services.layoutService.activeContainer,
});

renderer.render(
<NewConnectionModalDialog
renderer={renderer}
services={services}
/>
);
};

interface NewConnectionModalDialogProps {
readonly renderer: PositronModalReactRenderer;
readonly services: PositronConnectionsServices;
}

const NewConnectionModalDialog = (props: PropsWithChildren<NewConnectionModalDialogProps>) => {

const [selectedDriver, setSelectedDriver] = useState<IDriver | undefined>();
const [languageId, setLanguageId] = useState<string | undefined>(getPreferedLanguageId(props.services));

const cancelHandler = () => {
props.renderer.dispose();
};

const backHandler = () => {
// When hitting back, reset the language ID to the previously selected language id
setLanguageId(selectedDriver?.languageId);
setSelectedDriver(undefined);
};

return <PositronModalDialog
renderer={props.renderer}
title={(() => localize('positron.newConnectionModalDialog.title', "Create New Connection"))()}
width={NEW_CONNECTION_MODAL_DIALOG_WIDTH}
height={NEW_CONNECTION_MODAL_DIALOG_HEIGHT}
onCancel={cancelHandler}
>
<div className='connections-new-connection-modal'>
<ContentArea>
{
selectedDriver ?
<CreateConnection
services={props.services}
renderer={props.renderer}
onCancel={cancelHandler}
onBack={backHandler}
selectedDriver={selectedDriver} /> :
<ListDrivers
services={props.services}
onCancel={cancelHandler}
onSelection={(driver) => setSelectedDriver(driver)}
languageId={languageId}
setLanguageId={setLanguageId}
/>}
</ContentArea>
</div>
</PositronModalDialog>;
};

const getPreferedLanguageId = (services: PositronConnectionsServices): string | undefined => {
// If threre is a foreground session, use its language ID as the preferred language id
return services.runtimeSessionService.foregroundSession?.runtimeMetadata.languageId;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------------------------
* Copyright (C) 2024 Posit Software, PBC. All rights reserved.
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information.
*--------------------------------------------------------------------------------------------*/

.connections-new-connection-create-connection {
display: grid;
gap: 10px;
grid-template-rows: 36px 2fr 15px 2fr 28px;
grid-template-columns: 1fr 90px;
grid-template-areas:
"title-1 title-1"
"inputs inputs"
"title-2 title-2"
"editor buttons"
"footer buttons";
height: 100%;
}

.connections-new-connection-create-connection .action-bar-button {
padding: 0 15px;
}

.connections-new-connection-create-connection > .create-connection-title {
grid-area: title-1;
display: flex;
align-items: center;
}

.connections-new-connection-create-connection > .create-connection-inputs {
grid-area: inputs;
padding: 2px;
border: solid 1px var(--vscode-positronVariables-border);
border-radius: 4px;
overflow: auto;
}

.connections-new-connection-create-connection > .create-connection-code-editor {
grid-area: editor;
border: solid 1px var(--vscode-positronVariables-border);
border-radius: 4px;
padding: 10px;
}

.connections-new-connection-create-connection > .create-connection-code-editor .scroll-decoration {
box-shadow: none;
}

.connections-new-connection-create-connection > .create-connection-buttons {
grid-area: buttons;
display: flex;
flex-direction: column;
justify-content: space-between;
}

.connections-new-connection-create-connection > .create-connection-footer {
grid-area: footer;
display: flex;
flex-direction: row;
align-items: center;
}

.create-connection-footer > .default {
margin-left: auto;
}

.create-connection-inputs {
display: flex;
flex-direction: column;
overflow: auto;
padding: 2px;
}

.create-connection-inputs > .labeled-input label {
display: flex;
flex-direction: row;
align-items: center;
gap: 5px;
height: 40px;
text-wrap: nowrap;
padding: 0px 8px;
}

.create-connection-inputs > .labeled-input:not(:last-child) label {
border-bottom: 1px solid var(--vscode-positronVariables-border);
}

.create-connection-inputs > .labeled-input label > .label-text {
flex-basis: 150px;
flex-shrink: 0;
overflow-x: hidden;
text-overflow: ellipsis;
}

.create-connection-inputs > .labeled-input label > .text-input {
flex: 1;
min-width: 0;
margin-top: 0px;
background: transparent;
border: none;
}

.create-connection-inputs > .labeled-input > label > .radio-group {
display: flex;
flex-direction: row;
align-items: center;
gap: 6px;
}
Loading
Loading