Skip to content

Commit d98030e

Browse files
authored
Refactoring form to decouple from underlying form target type (#18018)
* Refactoring forms to decouple from IConnectionDialogProfile and make generic * string changes * removing redundant property * adding connectionProfile shorthand for formState
1 parent 8816afc commit d98030e

File tree

7 files changed

+234
-221
lines changed

7 files changed

+234
-221
lines changed

src/connectionconfig/connectionDialogWebViewController.ts

+30-29
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import * as vscode from 'vscode';
77
import { ReactWebViewPanelController } from "../controllers/reactWebviewController";
8-
import { AuthenticationType, ConnectionDialogReducers, ConnectionDialogWebviewState, FormComponent, FormComponentActionButton, FormComponentOptions, FormComponentType, FormTabType, IConnectionDialogProfile } from '../sharedInterfaces/connectionDialog';
8+
import { AuthenticationType, ConnectionDialogReducers, ConnectionDialogWebviewState, FormTabType, IConnectionDialogProfile } from '../sharedInterfaces/connectionDialog';
99
import { IConnectionInfo } from 'vscode-mssql';
1010
import MainController from '../controllers/mainController';
1111
import { getConnectionDisplayName } from '../models/connectionInfo';
@@ -17,6 +17,7 @@ import { ConnectionOption } from 'azdata';
1717
import { Logger } from '../models/logger';
1818
import VscodeWrapper from '../controllers/vscodeWrapper';
1919
import * as LocalizedConstants from '../constants/localizedConstants';
20+
import { FormItemSpec, FormItemActionButton, FormItemOptions, FormItemType } from '../reactviews/common/forms/form';
2021
import { ApiStatus } from '../sharedInterfaces/webview';
2122

2223
export class ConnectionDialogWebViewController extends ReactWebViewPanelController<ConnectionDialogWebviewState, ConnectionDialogReducers> {
@@ -34,7 +35,7 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
3435
context,
3536
LocalizedConstants.connectionDialog,
3637
WebviewRoute.connectionDialog,
37-
{
38+
new ConnectionDialogWebviewState({
3839
connectionProfile: {} as IConnectionDialogProfile,
3940
recentConnections: [],
4041
selectedFormTab: FormTabType.Parameters,
@@ -45,7 +46,7 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
4546
connectionStringComponents: [],
4647
connectionStatus: ApiStatus.NotStarted,
4748
formError: ''
48-
},
49+
}),
4950
vscode.ViewColumn.Active,
5051
{
5152
dark: vscode.Uri.joinPath(context.extensionUri, 'media', 'connectionDialogEditor_inverse.svg'),
@@ -154,19 +155,19 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
154155
}
155156
}
156157

157-
private getActiveFormComponents(): FormComponent[] {
158+
private getActiveFormComponents(): FormItemSpec<IConnectionDialogProfile>[] {
158159
if (this.state.selectedFormTab === FormTabType.Parameters) {
159160
return this.state.connectionFormComponents.mainComponents;
160161
}
161162
return this.state.connectionStringComponents;
162163
}
163164

164-
private getFormComponent(propertyName: keyof IConnectionDialogProfile): FormComponent | undefined {
165+
private getFormComponent(propertyName: keyof IConnectionDialogProfile): FormItemSpec<IConnectionDialogProfile> | undefined {
165166

166167
return this.getActiveFormComponents().find(c => c.propertyName === propertyName);
167168
}
168169

169-
private async getAccounts(): Promise<FormComponentOptions[]> {
170+
private async getAccounts(): Promise<FormItemOptions[]> {
170171
const accounts = await this._mainController.azureAccountService.getAccounts();
171172
return accounts.map(account => {
172173
return {
@@ -177,7 +178,7 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
177178

178179
}
179180

180-
private async getTenants(accountId: string): Promise<FormComponentOptions[]> {
181+
private async getTenants(accountId: string): Promise<FormItemOptions[]> {
181182
const account = (await this._mainController.azureAccountService.getAccounts()).find(account => account.displayInfo.userId === accountId);
182183
if (!account) {
183184
return [];
@@ -194,30 +195,30 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
194195
});
195196
}
196197

197-
private convertToFormComponent(connOption: ConnectionOption): FormComponent {
198+
private convertToFormComponent(connOption: ConnectionOption): FormItemSpec<IConnectionDialogProfile> {
198199
switch (connOption.valueType) {
199200
case 'boolean':
200201
return {
201202
propertyName: connOption.name as keyof IConnectionDialogProfile,
202203
label: connOption.displayName,
203204
required: connOption.isRequired,
204-
type: FormComponentType.Checkbox,
205+
type: FormItemType.Checkbox,
205206
tooltip: connOption.description,
206207
};
207208
case 'string':
208209
return {
209210
propertyName: connOption.name as keyof IConnectionDialogProfile,
210211
label: connOption.displayName,
211212
required: connOption.isRequired,
212-
type: FormComponentType.Input,
213+
type: FormItemType.Input,
213214
tooltip: connOption.description,
214215
};
215216
case 'password':
216217
return {
217218
propertyName: connOption.name as keyof IConnectionDialogProfile,
218219
label: connOption.displayName,
219220
required: connOption.isRequired,
220-
type: FormComponentType.Password,
221+
type: FormItemType.Password,
221222
tooltip: connOption.description,
222223
};
223224

@@ -226,15 +227,15 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
226227
propertyName: connOption.name as keyof IConnectionDialogProfile,
227228
label: connOption.displayName,
228229
required: connOption.isRequired,
229-
type: FormComponentType.Input,
230+
type: FormItemType.Input,
230231
tooltip: connOption.description,
231232
};
232233
case 'category':
233234
return {
234235
propertyName: connOption.name as keyof IConnectionDialogProfile,
235236
label: connOption.displayName,
236237
required: connOption.isRequired,
237-
type: FormComponentType.Dropdown,
238+
type: FormItemType.Dropdown,
238239
tooltip: connOption.description,
239240
options: connOption.categoryValues.map(v => {
240241
return {
@@ -248,15 +249,15 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
248249
}
249250
}
250251

251-
private async completeFormComponents(components: Map<string, {option: ConnectionOption, component: FormComponent}>) {
252+
private async completeFormComponents(components: Map<string, {option: ConnectionOption, component: FormItemSpec<IConnectionDialogProfile>}>) {
252253
// Add additional components that are not part of the connection options
253254
components.set('savePassword', {
254255
option: undefined,
255256
component: {
256257
propertyName: 'savePassword',
257258
label: LocalizedConstants.savePassword,
258259
required: false,
259-
type: FormComponentType.Checkbox,
260+
type: FormItemType.Checkbox,
260261
}
261262
});
262263

@@ -266,7 +267,7 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
266267
propertyName: 'accountId',
267268
label: LocalizedConstants.azureAccount,
268269
required: true,
269-
type: FormComponentType.Dropdown,
270+
type: FormItemType.Dropdown,
270271
options: await this.getAccounts(),
271272
placeholder: LocalizedConstants.selectAnAccount,
272273
actionButtons: await this.getAzureActionButtons(),
@@ -291,7 +292,7 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
291292
propertyName: 'tenantId',
292293
label: LocalizedConstants.tenantId,
293294
required: true,
294-
type: FormComponentType.Dropdown,
295+
type: FormItemType.Dropdown,
295296
options: [],
296297
hidden: true,
297298
placeholder: LocalizedConstants.selectATenant,
@@ -316,7 +317,7 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
316317
propertyName: 'profileName',
317318
label: LocalizedConstants.profileName,
318319
required: false,
319-
type: FormComponentType.Input,
320+
type: FormItemType.Input,
320321
}
321322
});
322323

@@ -363,15 +364,15 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
363364
]);
364365

365366
private async generateConnectionFormComponents(): Promise<{
366-
mainComponents: FormComponent[],
367-
advancedComponents: {[category: string]: FormComponent[]}
367+
mainComponents: FormItemSpec<IConnectionDialogProfile>[],
368+
advancedComponents: {[category: string]: FormItemSpec<IConnectionDialogProfile>[]}
368369
}> {
369370
// get list of connection options from Tools Service
370371
const result: CapabilitiesResult = await this._mainController.connectionManager.client.sendRequest(GetCapabilitiesRequest.type, {});
371372
const connectionOptions: ConnectionOption[] = result.capabilities.connectionProvider.options;
372373

373374
// convert connection options to form components
374-
const allConnectionFormComponents = new Map<string, {option: ConnectionOption, component: FormComponent}>();
375+
const allConnectionFormComponents = new Map<string, {option: ConnectionOption, component: FormItemSpec<IConnectionDialogProfile>}>();
375376

376377
for (const option of connectionOptions) {
377378
allConnectionFormComponents.set(option.name, {option, component: this.convertToFormComponent(option)});
@@ -381,8 +382,8 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
381382

382383
// organize the main components and advanced components
383384
// main components are few-enough that there's no grouping, but advanced components get grouped by category
384-
const mainComponents: FormComponent[] = [];
385-
const advancedComponents: {[category: string]: FormComponent[]} = {};
385+
const mainComponents: FormItemSpec<IConnectionDialogProfile>[] = [];
386+
const advancedComponents: {[category: string]: FormItemSpec<IConnectionDialogProfile>[]} = {};
386387

387388
for (const [optionName, {option, component}] of allConnectionFormComponents) {
388389
if (this._mainOptionNames.has(optionName)) {
@@ -399,10 +400,10 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
399400
return {mainComponents, advancedComponents};
400401
}
401402

402-
private async generateConnectionStringComponents(): Promise<FormComponent[]> {
403+
private async generateConnectionStringComponents(): Promise<FormItemSpec<IConnectionDialogProfile>[]> {
403404
return [
404405
{
405-
type: FormComponentType.TextArea,
406+
type: FormItemType.TextArea,
406407
propertyName: 'connectionString',
407408
label: LocalizedConstants.connectionString,
408409
required: true,
@@ -423,7 +424,7 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
423424
propertyName: 'profileName',
424425
label: LocalizedConstants.profileName,
425426
required: false,
426-
type: FormComponentType.Input,
427+
type: FormItemType.Input,
427428
}
428429
];
429430
}
@@ -460,8 +461,8 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
460461
return errorCount;
461462
}
462463

463-
private async getAzureActionButtons(): Promise<FormComponentActionButton[]> {
464-
const actionButtons: FormComponentActionButton[] = [];
464+
private async getAzureActionButtons(): Promise<FormItemActionButton[]> {
465+
const actionButtons: FormItemActionButton[] = [];
465466
actionButtons.push({
466467
label: LocalizedConstants.signIn,
467468
id: 'azureSignIn',
@@ -507,7 +508,7 @@ export class ConnectionDialogWebViewController extends ReactWebViewPanelControll
507508
}
508509
const accountComponent = this.getFormComponent('accountId');
509510
const tenantComponent = this.getFormComponent('tenantId');
510-
let tenants: FormComponentOptions[] = [];
511+
let tenants: FormItemOptions[] = [];
511512
switch (propertyName) {
512513
case 'accountId':
513514
tenants = await this.getTenants(this.state.connectionProfile.accountId);

0 commit comments

Comments
 (0)