mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Feature/bdc create (#4012)
* initial checkin * rename * wizard pages * target cluster radio button group * resource strings * existing cluster picker * revert changes to unwanted file * revert unwanted changes-2 * update cluster icon * settings page * fix group container * hyperlink component * address review comments * comments part 2
This commit is contained in:
35
extensions/big-data-cluster/src/data/kubeConfigParser.ts
Normal file
35
extensions/big-data-cluster/src/data/kubeConfigParser.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { ClusterInfo } from '../interfaces';
|
||||
|
||||
export interface IKubeConfigParser {
|
||||
parse(configPath: string): ClusterInfo[];
|
||||
}
|
||||
|
||||
export class TestKubeConfigParser implements IKubeConfigParser {
|
||||
parse(configPath: string): ClusterInfo[] {
|
||||
let clusters = [];
|
||||
for (let i = 0; i < 18; i++) {
|
||||
let name;
|
||||
if (i % 2 === 0) {
|
||||
name = `kubernetes cluster ${i}`;
|
||||
}
|
||||
else {
|
||||
name = 'cluster dev ' + i;
|
||||
}
|
||||
clusters.push(
|
||||
{
|
||||
displayName: name,
|
||||
name: `kub-dev-xxxx-cluster-${i}`,
|
||||
user: 'root'
|
||||
}
|
||||
);
|
||||
}
|
||||
return clusters;
|
||||
}
|
||||
}
|
||||
|
||||
17
extensions/big-data-cluster/src/interfaces.ts
Normal file
17
extensions/big-data-cluster/src/interfaces.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
export interface ClusterInfo {
|
||||
name: string;
|
||||
displayName: string;
|
||||
user: string;
|
||||
}
|
||||
|
||||
export enum TargetClusterType {
|
||||
ExistingKubernetesCluster,
|
||||
NewLocalCluster,
|
||||
NewAksCluster
|
||||
}
|
||||
21
extensions/big-data-cluster/src/main.ts
Normal file
21
extensions/big-data-cluster/src/main.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import vscode = require('vscode');
|
||||
import { MainController } from './mainController';
|
||||
export let controller: MainController;
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
controller = new MainController(context);
|
||||
controller.activate();
|
||||
}
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
export function deactivate(): void {
|
||||
if (controller) {
|
||||
controller.deactivate();
|
||||
}
|
||||
}
|
||||
34
extensions/big-data-cluster/src/mainController.ts
Normal file
34
extensions/big-data-cluster/src/mainController.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { CreateClusterWizard } from './wizards/create-cluster/createClusterWizard';
|
||||
|
||||
/**
|
||||
* The main controller class that initializes the extension
|
||||
*/
|
||||
export class MainController {
|
||||
protected _context: vscode.ExtensionContext;
|
||||
|
||||
public constructor(context: vscode.ExtensionContext) {
|
||||
this._context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates the extension
|
||||
*/
|
||||
public activate(): void {
|
||||
vscode.commands.registerCommand('mssql.cluster.create', () => {
|
||||
let wizard = new CreateClusterWizard(this._context);
|
||||
wizard.open();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivates the extension
|
||||
*/
|
||||
public deactivate(): void { }
|
||||
}
|
||||
9
extensions/big-data-cluster/src/typings/ref.d.ts
vendored
Normal file
9
extensions/big-data-cluster/src/typings/ref.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/// <reference path='../../../../src/vs/vscode.d.ts'/>
|
||||
/// <reference path='../../../../src/sql/sqlops.d.ts'/>
|
||||
/// <reference path='../../../../src/sql/sqlops.proposed.d.ts'/>
|
||||
/// <reference types='@types/node'/>
|
||||
@@ -0,0 +1,26 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IKubeConfigParser } from '../../data/kubeConfigParser';
|
||||
import { ClusterInfo, TargetClusterType } from '../../interfaces';
|
||||
|
||||
export class CreateClusterModel {
|
||||
|
||||
constructor(private _kubeConfigParser: IKubeConfigParser) {
|
||||
}
|
||||
|
||||
public loadClusters(configPath: string): ClusterInfo[] {
|
||||
return this._kubeConfigParser.parse(configPath);
|
||||
}
|
||||
|
||||
public targetClusterType: TargetClusterType;
|
||||
|
||||
public selectedCluster: ClusterInfo;
|
||||
|
||||
public adminUserName: string;
|
||||
|
||||
public adminPassword: string;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { CreateClusterModel } from './createClusterModel';
|
||||
import { SelectTargetClusterPage } from './pages/targetClusterPage';
|
||||
import { SummaryPage } from './pages/summaryPage';
|
||||
import { SettingsPage } from './pages/settingsPage';
|
||||
import { ClusterProfilePage } from './pages/clusterProfilePage';
|
||||
import { TestKubeConfigParser } from '../../data/kubeConfigParser';
|
||||
import { ExtensionContext } from 'vscode';
|
||||
import { WizardBase } from '../wizardBase';
|
||||
import * as nls from 'vscode-nls';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export class CreateClusterWizard extends WizardBase<CreateClusterModel> {
|
||||
constructor(context: ExtensionContext) {
|
||||
let configParser = new TestKubeConfigParser();
|
||||
let model = new CreateClusterModel(configParser);
|
||||
super(model, context, localize('bdc-create.wizardTitle', 'Create a big data cluster'));
|
||||
}
|
||||
|
||||
protected initialize(): void {
|
||||
let settingsPage = new SettingsPage(this.model, this);
|
||||
let clusterProfilePage = new ClusterProfilePage(this.model, this);
|
||||
let selectTargetClusterPage = new SelectTargetClusterPage(this.model, this);
|
||||
let summaryPage = new SummaryPage(this.model, this);
|
||||
|
||||
this.wizard.pages = [
|
||||
settingsPage.page,
|
||||
clusterProfilePage.page,
|
||||
selectTargetClusterPage.page,
|
||||
summaryPage.page
|
||||
];
|
||||
|
||||
this.wizard.generateScriptButton.label = localize('bdc-create.generateScriptsButtonText', 'Generate Scripts');
|
||||
this.wizard.doneButton.label = localize('bdc-create.createClusterButtonText', 'Create');
|
||||
|
||||
this.wizard.generateScriptButton.onClick(() => { });
|
||||
this.wizard.doneButton.onClick(() => { });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import { WizardPageBase } from '../../wizardPageBase';
|
||||
import { CreateClusterModel } from '../createClusterModel';
|
||||
import { WizardBase } from '../../wizardBase';
|
||||
import * as nls from 'vscode-nls';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export class ClusterProfilePage extends WizardPageBase<CreateClusterModel> {
|
||||
constructor(model: CreateClusterModel, wizard: WizardBase<CreateClusterModel>) {
|
||||
super(localize('bdc-create.clusterProfilePageTitle', 'Select a cluster profile'),
|
||||
localize('bdc-create.clusterProfilePageDescription', 'Select your requirement and we will provide you a pre-defined default scaling. You can later go to cluster configuration and customize it.'),
|
||||
model, wizard);
|
||||
}
|
||||
|
||||
protected initialize(view: sqlops.ModelView): Thenable<void> {
|
||||
let formBuilder = view.modelBuilder.formContainer();
|
||||
let form = formBuilder.component();
|
||||
return view.initializeModel(form);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import { WizardPageBase } from '../../wizardPageBase';
|
||||
import { CreateClusterModel } from '../createClusterModel';
|
||||
import { WizardBase } from '../../wizardBase';
|
||||
import * as nls from 'vscode-nls';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export class SettingsPage extends WizardPageBase<CreateClusterModel> {
|
||||
constructor(model: CreateClusterModel, wizard: WizardBase<CreateClusterModel>) {
|
||||
super(localize('bdc-create.settingsPageTitle', 'Settings'),
|
||||
localize('bdc-create.settingsPageDescription', 'Configure the settings required for deploying SQL Server big data cluster'),
|
||||
model, wizard);
|
||||
}
|
||||
|
||||
protected initialize(view: sqlops.ModelView): Thenable<void> {
|
||||
let formBuilder = view.modelBuilder.formContainer();
|
||||
let adminUserNameInput = this.createInputWithLabel(view, localize('bdc-create.AdminUsernameText', 'Admin username'), true, (inputBox: sqlops.InputBoxComponent) => {
|
||||
this.model.adminUserName = inputBox.value;
|
||||
});
|
||||
let adminPasswordInput = this.createInputWithLabel(view, localize('bdc-create.AdminUserPasswordText', 'Password'), true, (inputBox: sqlops.InputBoxComponent) => {
|
||||
this.model.adminPassword = inputBox.value;
|
||||
}, 'password');
|
||||
|
||||
let basicSettingsGroup = view.modelBuilder.groupContainer().withItems([adminUserNameInput, adminPasswordInput]).withLayout({ header: localize('bdc-create.BasicSettingsText', 'Basic Settings'), collapsible: true }).component();
|
||||
let dockerSettingsGroup = view.modelBuilder.groupContainer().withItems([]).withLayout({ header: localize('bdc-create.DockerSettingsText', 'Docker Settings'), collapsible: true }).component();
|
||||
|
||||
let acceptEulaCheckbox = view.modelBuilder.checkBox().component();
|
||||
acceptEulaCheckbox.label = localize('bdc-create.AcceptEulaText', 'I accept the SQL Server EULA');
|
||||
acceptEulaCheckbox.checked = false;
|
||||
|
||||
let eulaHyperlink = view.modelBuilder.hyperlink().withProperties({
|
||||
label: localize('bdc-create.ViewEulaText', 'View Eula'),
|
||||
url: 'https://docs.microsoft.com/en-us/sql/getting-started/about-the-sql-server-license-terms?view=sql-server-2014'
|
||||
}).component();
|
||||
|
||||
let eulaContainer = this.createRow(view, [acceptEulaCheckbox, eulaHyperlink]);
|
||||
|
||||
let form = formBuilder.withFormItems([
|
||||
{
|
||||
title: '',
|
||||
component: basicSettingsGroup
|
||||
}, {
|
||||
title: '',
|
||||
component: dockerSettingsGroup
|
||||
}, {
|
||||
title: '',
|
||||
component: eulaContainer
|
||||
}]).component();
|
||||
return view.initializeModel(form);
|
||||
}
|
||||
|
||||
private createInputWithLabel(view: sqlops.ModelView, label: string, isRequiredField: boolean, textChangedHandler: (inputBox: sqlops.InputBoxComponent) => void, inputType: string = 'text'): sqlops.FlexContainer {
|
||||
let input = view.modelBuilder.inputBox().withProperties({
|
||||
required: isRequiredField,
|
||||
inputType: inputType
|
||||
}).component();
|
||||
let text = view.modelBuilder.text().withProperties({ value: label }).component();
|
||||
input.width = '300px';
|
||||
text.width = '150px';
|
||||
input.onTextChanged(() => {
|
||||
textChangedHandler(input);
|
||||
});
|
||||
return this.createRow(view, [text, input]);
|
||||
}
|
||||
|
||||
private createRow(view: sqlops.ModelView, items: sqlops.Component[]): sqlops.FlexContainer {
|
||||
return view.modelBuilder.flexContainer().withItems(items, { CSSStyles: { 'margin-right': '10px' } }).withLayout({ flexFlow: 'row', alignItems: 'baseline' }).component();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import { WizardPageBase } from '../../wizardPageBase';
|
||||
import { CreateClusterModel } from '../createClusterModel';
|
||||
import { WizardBase } from '../../wizardBase';
|
||||
import * as nls from 'vscode-nls';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export class SummaryPage extends WizardPageBase<CreateClusterModel> {
|
||||
constructor(model: CreateClusterModel, wizard: WizardBase<CreateClusterModel>) {
|
||||
super(localize('bdc-create.summaryPageTitle', 'Summary'), '', model, wizard);
|
||||
}
|
||||
|
||||
protected initialize(view: sqlops.ModelView): Thenable<void> {
|
||||
let formBuilder = view.modelBuilder.formContainer();
|
||||
let form = formBuilder.component();
|
||||
return view.initializeModel(form);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import * as vscode from 'vscode';
|
||||
import * as os from 'os';
|
||||
import { WizardPageBase } from '../../wizardPageBase';
|
||||
import { CreateClusterModel } from '../createClusterModel';
|
||||
import { WizardBase } from '../../wizardBase';
|
||||
import { TargetClusterType } from '../../../interfaces';
|
||||
import * as nls from 'vscode-nls';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
const ClusterTypeRadioButtonGroupName = 'SelectClusterType';
|
||||
|
||||
export class SelectTargetClusterPage extends WizardPageBase<CreateClusterModel> {
|
||||
constructor(model: CreateClusterModel, wizard: WizardBase<CreateClusterModel>) {
|
||||
super(localize('bdc-create.selectTargetClusterPageTitle', 'Where do you want to deploy this SQL Server big data cluster?'),
|
||||
localize('bdc-create.selectTargetClusterPageDescription', 'Select an existing Kubernetes cluster or choose a cluster type you want to deploy'),
|
||||
model, wizard);
|
||||
}
|
||||
|
||||
private existingClusterOption: sqlops.RadioButtonComponent;
|
||||
private createLocalClusterOption: sqlops.RadioButtonComponent;
|
||||
private createAksClusterOption: sqlops.RadioButtonComponent;
|
||||
private pageContainer: sqlops.DivContainer;
|
||||
private existingClusterControl: sqlops.FlexContainer;
|
||||
private createLocalClusterControl: sqlops.FlexContainer;
|
||||
private createAksClusterControl: sqlops.FlexContainer;
|
||||
private clusterContextsLabel: sqlops.TextComponent;
|
||||
private errorLoadingClustersLabel: sqlops.TextComponent;
|
||||
private clusterContextContainer: sqlops.DivContainer;
|
||||
|
||||
private cards: sqlops.CardComponent[];
|
||||
|
||||
protected initialize(view: sqlops.ModelView): Thenable<void> {
|
||||
let self = this;
|
||||
this.model.targetClusterType = TargetClusterType.ExistingKubernetesCluster;
|
||||
this.existingClusterOption = this.createTargetTypeRadioButton(view, localize('bdc-create.existingK8sCluster', 'Existing Kubernetes cluster'), true);
|
||||
this.createLocalClusterOption = this.createTargetTypeRadioButton(view, localize('bdc-create.createLocalCluster', 'Create new local cluster'));
|
||||
this.createAksClusterOption = this.createTargetTypeRadioButton(view, localize('bdc-create.createAksCluster', 'Create new Azure Kubernetes Service cluster'));
|
||||
|
||||
this.existingClusterOption.onDidClick(() => {
|
||||
self.pageContainer.clearItems();
|
||||
self.pageContainer.addItem(self.existingClusterControl);
|
||||
self.model.targetClusterType = TargetClusterType.ExistingKubernetesCluster;
|
||||
});
|
||||
|
||||
this.createLocalClusterOption.onDidClick(() => {
|
||||
self.pageContainer.clearItems();
|
||||
self.pageContainer.addItem(self.createLocalClusterControl);
|
||||
self.model.targetClusterType = TargetClusterType.NewLocalCluster;
|
||||
});
|
||||
|
||||
this.createAksClusterOption.onDidClick(() => {
|
||||
self.pageContainer.clearItems();
|
||||
self.pageContainer.addItem(self.createAksClusterControl);
|
||||
self.model.targetClusterType = TargetClusterType.NewAksCluster;
|
||||
});
|
||||
|
||||
let optionGroup = view.modelBuilder.divContainer().withItems([this.existingClusterOption, this.createLocalClusterOption, this.createAksClusterOption],
|
||||
{ CSSStyles: { 'margin-right': '30px' } }).withLayout({ width: 'auto' }).component();
|
||||
this.initExistingClusterControl(view);
|
||||
this.initLocalClusterControl(view);
|
||||
this.initAksClusterControl(view);
|
||||
this.pageContainer = view.modelBuilder.divContainer().withItems([this.existingClusterControl]).withLayout({ width: '100%' }).component();
|
||||
let container = view.modelBuilder.flexContainer().withItems([optionGroup, this.pageContainer], { flex: '0 0 auto' }).withLayout({ flexFlow: 'row', alignItems: 'left' }).component();
|
||||
|
||||
let formBuilder = view.modelBuilder.formContainer().withFormItems(
|
||||
[
|
||||
{
|
||||
component: container,
|
||||
title: ''
|
||||
}
|
||||
],
|
||||
{
|
||||
horizontal: true
|
||||
}
|
||||
).withLayout({ width: '100%', height: '100%' });
|
||||
|
||||
let form = formBuilder.component();
|
||||
return view.initializeModel(form);
|
||||
}
|
||||
|
||||
private createTargetTypeRadioButton(view: sqlops.ModelView, label: string, checked: boolean = false): sqlops.RadioButtonComponent {
|
||||
return view.modelBuilder.radioButton().withProperties({ label: label, name: ClusterTypeRadioButtonGroupName, checked: checked }).component();
|
||||
}
|
||||
|
||||
private initExistingClusterControl(view: sqlops.ModelView): void {
|
||||
let self = this;
|
||||
let sectionDescription = view.modelBuilder.text().withProperties({ value: localize('bdc-create.existingClusterSectionDescription', 'Select the cluster context you want to install the SQL Server big data cluster') }).component();
|
||||
let configFileLabel = view.modelBuilder.text().withProperties({ value: localize('bdc-create.kubeConfigFileLabelText', 'KubeConfig File') }).component();
|
||||
let configFileInput = view.modelBuilder.inputBox().withProperties({ width: '300px' }).component();
|
||||
let browseFileButton = view.modelBuilder.button().withProperties({ label: localize('bdc-browseText', 'Browse'), width: '100px' }).component();
|
||||
let configFileContainer = view.modelBuilder.flexContainer()
|
||||
.withLayout({ flexFlow: 'row', alignItems: 'baseline' })
|
||||
.withItems([configFileLabel, configFileInput, browseFileButton], { CSSStyles: { 'margin-right': '10px' } }).component();
|
||||
this.clusterContextsLabel = view.modelBuilder.text().withProperties({ value: localize('bdc-clusterContextsLabelText', 'Cluster Contexts') }).component();
|
||||
this.errorLoadingClustersLabel = view.modelBuilder.text().withProperties({ value: localize('bdc-errorLoadingClustersText', 'No cluster information is found in the config file or an error ocurred while loading the config file') }).component();
|
||||
this.clusterContextContainer = view.modelBuilder.divContainer().component();
|
||||
this.existingClusterControl = view.modelBuilder.divContainer().withItems([sectionDescription, configFileContainer, this.clusterContextContainer], { CSSStyles: { 'margin-top': '0px' } }).component();
|
||||
|
||||
browseFileButton.onDidClick(async () => {
|
||||
let fileUris = await vscode.window.showOpenDialog(
|
||||
{
|
||||
canSelectFiles: true,
|
||||
canSelectFolders: false,
|
||||
canSelectMany: false,
|
||||
defaultUri: vscode.Uri.file(os.homedir()),
|
||||
openLabel: localize('bdc-selectKubeConfigFileText', 'Select'),
|
||||
filters: {
|
||||
'KubeConfig Files': ['kubeconfig'],
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (!fileUris || fileUris.length === 0) {
|
||||
return;
|
||||
}
|
||||
self.clusterContextContainer.clearItems();
|
||||
|
||||
let fileUri = fileUris[0];
|
||||
|
||||
configFileInput.value = fileUri.fsPath;
|
||||
|
||||
let clusters = self.model.loadClusters(fileUri.fsPath);
|
||||
|
||||
self.cards = [];
|
||||
if (clusters.length !== 0) {
|
||||
self.model.selectedCluster = clusters[0];
|
||||
for (let i = 0; i < clusters.length; i++) {
|
||||
let cluster = clusters[i];
|
||||
let card = view.modelBuilder.card().withProperties({
|
||||
selected: i === 0,
|
||||
label: cluster.name,
|
||||
descriptions: [cluster.displayName, cluster.user],
|
||||
cardType: sqlops.CardType.ListItem,
|
||||
iconPath: {
|
||||
dark: self.wizard.context.asAbsolutePath('images/cluster_inverse.svg'),
|
||||
light: self.wizard.context.asAbsolutePath('images/cluster.svg')
|
||||
},
|
||||
}).component();
|
||||
card.onCardSelectedChanged(() => {
|
||||
if (card.selected) {
|
||||
self.cards.forEach(c => {
|
||||
if (c !== card) {
|
||||
c.selected = false;
|
||||
}
|
||||
});
|
||||
self.model.selectedCluster = cluster;
|
||||
}
|
||||
});
|
||||
self.cards.push(card);
|
||||
}
|
||||
|
||||
self.clusterContextContainer.addItem(self.clusterContextsLabel);
|
||||
self.clusterContextContainer.addItems(self.cards);
|
||||
} else {
|
||||
self.clusterContextContainer.addItem(this.errorLoadingClustersLabel);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private initLocalClusterControl(view: sqlops.ModelView): void {
|
||||
let placeholder = view.modelBuilder.text().withProperties({ value: 'create local cluster place holder' }).component();
|
||||
this.createLocalClusterControl = view.modelBuilder.divContainer().withItems([placeholder]).component();
|
||||
}
|
||||
|
||||
private initAksClusterControl(view: sqlops.ModelView): void {
|
||||
let placeholder = view.modelBuilder.text().withProperties({ value: 'AKS cluster place holder' }).component();
|
||||
this.createAksClusterControl = view.modelBuilder.divContainer().withItems([placeholder]).component();
|
||||
}
|
||||
}
|
||||
24
extensions/big-data-cluster/src/wizards/wizardBase.ts
Normal file
24
extensions/big-data-cluster/src/wizards/wizardBase.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import { ExtensionContext } from 'vscode';
|
||||
|
||||
export abstract class WizardBase<T> {
|
||||
|
||||
protected wizard: sqlops.window.modelviewdialog.Wizard;
|
||||
|
||||
constructor(public model: T, public context: ExtensionContext, private title: string) {
|
||||
}
|
||||
|
||||
public open(): Thenable<void> {
|
||||
this.wizard = sqlops.window.modelviewdialog.createWizard(this.title);
|
||||
this.initialize();
|
||||
return this.wizard.open();
|
||||
}
|
||||
|
||||
protected abstract initialize(): void;
|
||||
}
|
||||
30
extensions/big-data-cluster/src/wizards/wizardPageBase.ts
Normal file
30
extensions/big-data-cluster/src/wizards/wizardPageBase.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import { WizardBase } from './wizardBase';
|
||||
|
||||
export abstract class WizardPageBase<T> {
|
||||
private _page: sqlops.window.modelviewdialog.WizardPage;
|
||||
|
||||
public get page(): sqlops.window.modelviewdialog.WizardPage {
|
||||
return this._page;
|
||||
}
|
||||
|
||||
public get wizard(): WizardBase<T> {
|
||||
return this._wizard;
|
||||
}
|
||||
|
||||
constructor(title: string, description: string, protected model: T, private _wizard: WizardBase<T>) {
|
||||
this._page = sqlops.window.modelviewdialog.createWizardPage(title);
|
||||
this._page.description = description;
|
||||
this._page.registerContent((view: sqlops.ModelView) => {
|
||||
return this.initialize(view);
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract initialize(view: sqlops.ModelView): Thenable<void>;
|
||||
}
|
||||
Reference in New Issue
Block a user