mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-17 17:22:42 -05:00
297 lines
9.2 KiB
TypeScript
297 lines
9.2 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import * as azdata from 'azdata';
|
|
import * as loc from '../common/localizedConstants';
|
|
import { RemoteBookController, IAsset } from '../book/remoteBookController';
|
|
import * as utils from '../common/utils';
|
|
import * as vscode from 'vscode';
|
|
|
|
const defaultRepos = ['repos/microsoft/tigertoolbox', 'repos/azure-samples/synapse'];
|
|
const urlGithubRE = /^(?:https:\/\/(?:github\.com|api\.github\.com\/repos)|(?:\/)?(?:\/)?repos)([\w-.?!=&%*+:@\/]*)/g;
|
|
|
|
function apiGitHub(url: string): string {
|
|
return `https://api.github.com/${url}/releases`;
|
|
}
|
|
|
|
function getRemoteLocationCategory(name: string): azdata.CategoryValue {
|
|
if (name === loc.onGitHub) {
|
|
return { name: name, displayName: loc.onGitHub };
|
|
}
|
|
return { name: name, displayName: loc.onSharedFile };
|
|
}
|
|
|
|
export class RemoteBookDialog {
|
|
|
|
private dialog: azdata.window.Dialog;
|
|
public view: azdata.ModelView;
|
|
private formModel: azdata.FormContainer;
|
|
private githubRepoDropdown: azdata.DropDownComponent;
|
|
private remoteLocationDropdown: azdata.DropDownComponent;
|
|
public releaseDropdown: azdata.DropDownComponent;
|
|
private searchButton: azdata.ButtonComponent;
|
|
public bookDropdown: azdata.DropDownComponent;
|
|
public versionDropdown: azdata.DropDownComponent;
|
|
public languageDropdown: azdata.DropDownComponent;
|
|
private _remoteTypes: azdata.CategoryValue[];
|
|
|
|
constructor(public controller: RemoteBookController) {
|
|
}
|
|
|
|
public async createDialog(): Promise<void> {
|
|
this.dialog = azdata.window.createModelViewDialog(loc.addRemoteBook);
|
|
this.dialog.registerContent(async view => {
|
|
this.view = view;
|
|
|
|
this.remoteLocationDropdown = this.view.modelBuilder.dropDown().withProps({
|
|
values: this.remoteLocationCategories,
|
|
value: '',
|
|
editable: false,
|
|
}).component();
|
|
|
|
this.remoteLocationDropdown.onValueChanged(e => this.onRemoteLocationChanged());
|
|
|
|
this.githubRepoDropdown = this.view.modelBuilder.dropDown().withProps({
|
|
values: defaultRepos,
|
|
value: '',
|
|
editable: true,
|
|
fireOnTextChange: true,
|
|
}).component();
|
|
|
|
this.searchButton = this.view.modelBuilder.button().withProps({
|
|
label: loc.search,
|
|
title: loc.search,
|
|
width: '200px',
|
|
secondary: true
|
|
}).component();
|
|
this.searchButton.onDidClick(async () => await this.validate());
|
|
|
|
this.releaseDropdown = this.view.modelBuilder.dropDown()
|
|
.withProps({
|
|
values: [],
|
|
value: '',
|
|
enabled: false
|
|
}).component();
|
|
|
|
this.releaseDropdown.onValueChanged(async () => await this.getAssets());
|
|
|
|
this.bookDropdown = this.view.modelBuilder.dropDown().withProps({
|
|
values: [],
|
|
value: '',
|
|
editable: false,
|
|
}).component();
|
|
|
|
this.bookDropdown.onValueChanged(async () => await this.fillVersionDropdown());
|
|
|
|
this.versionDropdown = this.view.modelBuilder.dropDown().withProps({
|
|
values: [],
|
|
value: '',
|
|
editable: false,
|
|
}).component();
|
|
|
|
this.versionDropdown.onValueChanged(async () => await this.fillLanguageDropdown());
|
|
|
|
this.languageDropdown = this.view.modelBuilder.dropDown().withProps({
|
|
values: [],
|
|
value: '',
|
|
editable: false,
|
|
}).component();
|
|
|
|
this.languageDropdown.onValueChanged(async () => this.checkValues());
|
|
await this.setFieldsToEmpty();
|
|
|
|
this.formModel = this.view.modelBuilder.formContainer()
|
|
.withFormItems([{
|
|
components: [
|
|
{
|
|
component: this.remoteLocationDropdown,
|
|
title: loc.location,
|
|
required: true
|
|
},
|
|
{
|
|
component: this.githubRepoDropdown,
|
|
title: loc.repoUrl,
|
|
required: true
|
|
},
|
|
{
|
|
component: this.searchButton,
|
|
title: ''
|
|
},
|
|
{
|
|
component: this.releaseDropdown,
|
|
title: loc.releases,
|
|
},
|
|
{
|
|
component: this.bookDropdown,
|
|
title: loc.book,
|
|
required: true
|
|
},
|
|
{
|
|
component: this.versionDropdown,
|
|
title: loc.version,
|
|
required: true
|
|
},
|
|
{
|
|
component: this.languageDropdown,
|
|
title: loc.language,
|
|
required: true
|
|
},
|
|
],
|
|
title: ''
|
|
}]).withLayout({ width: '100%' }).component();
|
|
await this.view.initializeModel(this.formModel);
|
|
});
|
|
this.dialog.okButton.enabled = false;
|
|
this.dialog.okButton.label = loc.add;
|
|
this.dialog.cancelButton.label = loc.close;
|
|
this.dialog.registerCloseValidator(async () => await this.download());
|
|
azdata.window.openDialog(this.dialog);
|
|
}
|
|
|
|
private async setFieldsToEmpty(): Promise<void> {
|
|
await this.bookDropdown.updateProperties({
|
|
values: [loc.invalidTextPlaceholder],
|
|
value: loc.invalidTextPlaceholder
|
|
});
|
|
await this.versionDropdown.updateProperties({
|
|
values: [loc.invalidTextPlaceholder],
|
|
value: loc.invalidTextPlaceholder
|
|
});
|
|
await this.languageDropdown.updateProperties({
|
|
values: [loc.invalidTextPlaceholder],
|
|
value: loc.invalidTextPlaceholder
|
|
});
|
|
this.dialog.okButton.enabled = false;
|
|
}
|
|
|
|
private get remoteLocationValue(): string {
|
|
return (<azdata.CategoryValue>this.remoteLocationDropdown.value).name;
|
|
}
|
|
|
|
public onRemoteLocationChanged(): void {
|
|
if (this.controller.getReleases() !== undefined && this.remoteLocationValue === loc.onGitHub) {
|
|
this.releaseDropdown.enabled = true;
|
|
} else {
|
|
this.releaseDropdown.enabled = false;
|
|
}
|
|
}
|
|
|
|
public async validate(): Promise<void> {
|
|
try {
|
|
let url = utils.getDropdownValue(this.githubRepoDropdown);
|
|
url = url.trim().toLowerCase();
|
|
if (this.remoteLocationValue === loc.onGitHub && url.length > 0) {
|
|
//get the first group to extract /owner/repo/releases format
|
|
let groupsRe = url.match(urlGithubRE);
|
|
if (groupsRe?.length > 0) {
|
|
url = apiGitHub(groupsRe[0]);
|
|
let releases = await this.controller.getReleases(vscode.Uri.parse(url));
|
|
if (releases) {
|
|
this.releaseDropdown.enabled = true;
|
|
await this.fillReleasesDropdown();
|
|
await this.setFieldsToEmpty();
|
|
}
|
|
} else {
|
|
throw new Error(loc.urlGithubError);
|
|
}
|
|
}
|
|
}
|
|
catch (error) {
|
|
await this.fillReleasesDropdown();
|
|
await this.setFieldsToEmpty();
|
|
this.showErrorMessage(error.message);
|
|
}
|
|
}
|
|
|
|
public async getAssets(): Promise<void> {
|
|
try {
|
|
if (this.remoteLocationValue === loc.onGitHub) {
|
|
let releases = await this.controller.getReleases();
|
|
let selected_release = releases.filter(release =>
|
|
release.name === this.releaseDropdown.value);
|
|
let assets = await this.controller.getAssets(selected_release[0]);
|
|
if (assets?.length > 0) {
|
|
this.bookDropdown.values = ['-'].concat([...new Set(assets.map(asset => asset.book))]);
|
|
}
|
|
this.checkValues();
|
|
}
|
|
}
|
|
catch (error) {
|
|
await this.setFieldsToEmpty();
|
|
this.showErrorMessage(error.message);
|
|
}
|
|
}
|
|
|
|
public async download(): Promise<boolean> {
|
|
try {
|
|
if (this.remoteLocationValue === loc.onGitHub) {
|
|
let selected_asset = await this.getSelectedAsset();
|
|
if (!selected_asset) {
|
|
throw new Error(loc.msgUndefinedAssetError);
|
|
}
|
|
await this.controller.setRemoteBook(selected_asset.url, this.remoteLocationValue, selected_asset);
|
|
} else {
|
|
let url = utils.getDropdownValue(this.githubRepoDropdown);
|
|
let newUrl = vscode.Uri.parse(url);
|
|
await this.controller.setRemoteBook(newUrl, this.remoteLocationValue);
|
|
}
|
|
return true;
|
|
}
|
|
catch (error) {
|
|
this.showErrorMessage(error.message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async fillReleasesDropdown(): Promise<void> {
|
|
this.releaseDropdown.values = ['-'].concat((await this.controller.getReleases()).map(release => release.name));
|
|
}
|
|
|
|
public async fillVersionDropdown(): Promise<void> {
|
|
const assets = await this.controller.getAssets();
|
|
let filtered_assets = assets.filter(asset => asset.book === this.bookDropdown.value);
|
|
this.versionDropdown.values = ['-'].concat(filtered_assets.map(asset => asset.version));
|
|
this.checkValues();
|
|
}
|
|
|
|
public async fillLanguageDropdown(): Promise<void> {
|
|
const assets = await this.controller.getAssets();
|
|
let filtered_assets = assets.filter(asset => asset.book === this.bookDropdown.value &&
|
|
asset.version === this.versionDropdown.value);
|
|
this.languageDropdown.values = ['-'].concat(filtered_assets.map(asset => asset.language));
|
|
this.checkValues();
|
|
}
|
|
|
|
public async getSelectedAsset(): Promise<IAsset> {
|
|
let lang = this.languageDropdown.value;
|
|
let book = this.bookDropdown.value;
|
|
let version = this.versionDropdown.value;
|
|
return (await this.controller.getAssets()).filter(asset => asset.book === book && asset.version === version && asset.language === lang)[0];
|
|
}
|
|
|
|
public checkValues(): void {
|
|
if (this.languageDropdown.value !== loc.invalidTextPlaceholder && this.versionDropdown.value !== loc.invalidTextPlaceholder &&
|
|
this.bookDropdown.value !== loc.invalidTextPlaceholder) {
|
|
this.dialog.okButton.enabled = true;
|
|
} else {
|
|
this.dialog.okButton.enabled = false;
|
|
}
|
|
}
|
|
|
|
public get remoteLocationCategories(): azdata.CategoryValue[] {
|
|
if (!this._remoteTypes) {
|
|
this._remoteTypes = [getRemoteLocationCategory(loc.onGitHub)];
|
|
}
|
|
return this._remoteTypes;
|
|
}
|
|
|
|
public showErrorMessage(message: string): void {
|
|
this.dialog.message = {
|
|
text: message,
|
|
level: azdata.window.MessageLevel.Error
|
|
};
|
|
}
|
|
}
|