mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 11:01:37 -05:00
Compare commits
91 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03ea265bab | ||
|
|
917f9eead3 | ||
|
|
08f2e72af8 | ||
|
|
a2fb0ec029 | ||
|
|
084042ad13 | ||
|
|
8da3defe24 | ||
|
|
58f9cd32a5 | ||
|
|
f7abf5a2d5 | ||
|
|
c8c6d072f6 | ||
|
|
4d9cc604b9 | ||
|
|
1dc76fa171 | ||
|
|
1d37b9ae9c | ||
|
|
26828602a8 | ||
|
|
e253f3ac89 | ||
|
|
4d59fdea1b | ||
|
|
98a313eb5b | ||
|
|
77e1cd8b32 | ||
|
|
dede5c5ef5 | ||
|
|
d156c0be3d | ||
|
|
dc0bc6e606 | ||
|
|
05040425df | ||
|
|
36f7c283b8 | ||
|
|
9fe4237033 | ||
|
|
b03c0a3e2d | ||
|
|
87946996ed | ||
|
|
cc55023440 | ||
|
|
1f19dfc50d | ||
|
|
950a440350 | ||
|
|
c92b88bfaf | ||
|
|
10875f26dc | ||
|
|
d62e809c18 | ||
|
|
d85bf4f6dd | ||
|
|
801e201cc3 | ||
|
|
e18e0da0c1 | ||
|
|
d046b0a412 | ||
|
|
72084b8fc1 | ||
|
|
2639b2bd2c | ||
|
|
82aa493dfd | ||
|
|
6c3c7c40b5 | ||
|
|
5616751c04 | ||
|
|
7d898ca34d | ||
|
|
e26556b21a | ||
|
|
89e6d363e2 | ||
|
|
c559ac7be9 | ||
|
|
b3fbe47f0a | ||
|
|
c73af4c480 | ||
|
|
8887fe1eac | ||
|
|
ed861a6c96 | ||
|
|
e63bb6a8ec | ||
|
|
8ec09d25ce | ||
|
|
a9a01ae479 | ||
|
|
31a3864789 | ||
|
|
a5c537197c | ||
|
|
4ea13bdbc0 | ||
|
|
b06ddf2dc7 | ||
|
|
2c45ac9df3 | ||
|
|
7735f68502 | ||
|
|
ffb0f5a1c7 | ||
|
|
80c7f9e855 | ||
|
|
709ef4e39f | ||
|
|
4ceb869420 | ||
|
|
432a209184 | ||
|
|
8444271c58 | ||
|
|
2bc97c23d4 | ||
|
|
9ea02bf125 | ||
|
|
2b4de52af4 | ||
|
|
d3492ebf2f | ||
|
|
ff8698f619 | ||
|
|
16bc218ea7 | ||
|
|
72d2920dc3 | ||
|
|
fb8de0d753 | ||
|
|
352afc9827 | ||
|
|
ce699a1c84 | ||
|
|
cde20d338e | ||
|
|
8ab22e9cc8 | ||
|
|
0f2442a7a5 | ||
|
|
ba91140ea5 | ||
|
|
10f05e75ce | ||
|
|
287811f4ab | ||
|
|
a68462c7cb | ||
|
|
005c28dd3a | ||
|
|
197e1c651f | ||
|
|
c01da0f263 | ||
|
|
81ff542d0b | ||
|
|
efee27559b | ||
|
|
dc5408f874 | ||
|
|
7cf9217158 | ||
|
|
401fc8161a | ||
|
|
be2f9a6099 | ||
|
|
21989aa88e | ||
|
|
461d041a50 |
7
.github/ISSUE_TEMPLATE/bug_report.md
vendored
7
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -3,17 +3,12 @@ name: Bug report
|
||||
about: Create a report to help us improve
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates. -->
|
||||
<!-- Please search existing issues to avoid creating duplicates. -->
|
||||
<!-- Also please test using the latest insiders build to make sure your issue has not already been fixed. -->
|
||||
|
||||
<!-- Use Help > Report Issue to prefill these. -->
|
||||
- SQL Operations Studio Version:
|
||||
- OS Version:
|
||||
|
||||
Steps to Reproduce:
|
||||
|
||||
1.
|
||||
2.
|
||||
|
||||
<!-- Launch with `sqlops --disable-extensions` to check. -->
|
||||
Does this issue occur when all extensions are disabled?: Yes/No
|
||||
|
||||
9
.github/ISSUE_TEMPLATE/feature_request.md
vendored
9
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,9 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates. -->
|
||||
|
||||
<!-- Describe the feature you'd like. -->
|
||||
4
.github/ISSUE_TEMPLATE/question.md
vendored
4
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -1,4 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
---
|
||||
|
||||
2
.yarnrc
2
.yarnrc
@@ -1,3 +1,3 @@
|
||||
disturl "https://atom.io/download/electron"
|
||||
target "2.0.7"
|
||||
target "2.0.9"
|
||||
runtime "electron"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"azure-storage": "^2.1.0",
|
||||
"decompress": "^4.2.0",
|
||||
"documentdb": "1.13.0",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.2",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||
"fs-extra-promise": "^1.0.1",
|
||||
"mime": "^1.3.4",
|
||||
"minimist": "^1.2.0",
|
||||
|
||||
@@ -1002,7 +1002,7 @@ hoek@4.x.x:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb"
|
||||
|
||||
http-proxy-agent@^2.0.0:
|
||||
http-proxy-agent@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
|
||||
dependencies:
|
||||
@@ -1025,7 +1025,7 @@ http-signature@~1.2.0:
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
https-proxy-agent@^2.1.1:
|
||||
https-proxy-agent@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
|
||||
dependencies:
|
||||
@@ -1843,14 +1843,14 @@ semver@^5.4.1:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
||||
|
||||
"service-downloader@github:anthonydresser/service-downloader#0.1.2":
|
||||
version "0.1.2"
|
||||
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/2aa9b336b6442e17e24693ddc907030575539798"
|
||||
"service-downloader@github:anthonydresser/service-downloader#0.1.5":
|
||||
version "0.1.5"
|
||||
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/6ebb0465573cc140e461a22f334260f55ef45546"
|
||||
dependencies:
|
||||
decompress "^4.2.0"
|
||||
eventemitter2 "^5.0.1"
|
||||
http-proxy-agent "^2.0.0"
|
||||
https-proxy-agent "^2.1.1"
|
||||
http-proxy-agent "^2.1.0"
|
||||
https-proxy-agent "^2.2.1"
|
||||
mkdirp "^0.5.1"
|
||||
tmp "^0.0.33"
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
import { ExtensionContext, workspace, window, Disposable, commands, Uri, OutputChannel } from 'vscode';
|
||||
import { ExtensionContext, workspace, window, Disposable, commands, OutputChannel } from 'vscode';
|
||||
import { findGit, Git, IGit } from './git';
|
||||
import { Model } from './model';
|
||||
import { CommandCenter } from './commands';
|
||||
@@ -98,28 +98,29 @@ export async function activate(context: ExtensionContext): Promise<API> {
|
||||
throw err;
|
||||
}
|
||||
|
||||
const config = workspace.getConfiguration('git');
|
||||
const shouldIgnore = config.get<boolean>('ignoreMissingGitWarning') === true;
|
||||
// {{SQL CARBON EDIT}} turn-off Git missing prompt
|
||||
//const config = workspace.getConfiguration('git');
|
||||
//const shouldIgnore = config.get<boolean>('ignoreMissingGitWarning') === true;
|
||||
|
||||
if (!shouldIgnore) {
|
||||
console.warn(err.message);
|
||||
outputChannel.appendLine(err.message);
|
||||
outputChannel.show();
|
||||
// if (!shouldIgnore) {
|
||||
// console.warn(err.message);
|
||||
// outputChannel.appendLine(err.message);
|
||||
// outputChannel.show();
|
||||
|
||||
const download = localize('downloadgit', "Download Git");
|
||||
const neverShowAgain = localize('neverShowAgain', "Don't Show Again");
|
||||
const choice = await window.showWarningMessage(
|
||||
localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."),
|
||||
download,
|
||||
neverShowAgain
|
||||
);
|
||||
// const download = localize('downloadgit', "Download Git");
|
||||
// const neverShowAgain = localize('neverShowAgain', "Don't Show Again");
|
||||
// const choice = await window.showWarningMessage(
|
||||
// localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."),
|
||||
// download,
|
||||
// neverShowAgain
|
||||
// );
|
||||
|
||||
if (choice === download) {
|
||||
commands.executeCommand('vscode.open', Uri.parse('https://git-scm.com/'));
|
||||
} else if (choice === neverShowAgain) {
|
||||
await config.update('ignoreMissingGitWarning', true, true);
|
||||
}
|
||||
}
|
||||
// if (choice === download) {
|
||||
// commands.executeCommand('vscode.open', Uri.parse('https://git-scm.com/'));
|
||||
// } else if (choice === neverShowAgain) {
|
||||
// await config.update('ignoreMissingGitWarning', true, true);
|
||||
// }
|
||||
// }
|
||||
|
||||
return new NoopAPIImpl();
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
"dependencies": {
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.7",
|
||||
"opener": "^1.4.3",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.4",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||
"vscode-extension-telemetry": "^0.0.5",
|
||||
"vscode-nls": "^3.2.1"
|
||||
},
|
||||
|
||||
@@ -177,14 +177,14 @@ graceful-fs@^4.1.10:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
|
||||
|
||||
http-proxy-agent@^2.0.0:
|
||||
http-proxy-agent@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
|
||||
dependencies:
|
||||
agent-base "4"
|
||||
debug "3.1.0"
|
||||
|
||||
https-proxy-agent@^2.1.1:
|
||||
https-proxy-agent@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
|
||||
dependencies:
|
||||
@@ -297,14 +297,14 @@ seek-bzip@^1.0.5:
|
||||
dependencies:
|
||||
commander "~2.8.1"
|
||||
|
||||
"service-downloader@github:anthonydresser/service-downloader#0.1.4":
|
||||
version "0.1.4"
|
||||
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/3c0abdf8603aca85d2eacfac3c547173e41bf0c7"
|
||||
"service-downloader@github:anthonydresser/service-downloader#0.1.5":
|
||||
version "0.1.5"
|
||||
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/6ebb0465573cc140e461a22f334260f55ef45546"
|
||||
dependencies:
|
||||
decompress "^4.2.0"
|
||||
eventemitter2 "^5.0.1"
|
||||
http-proxy-agent "^2.0.0"
|
||||
https-proxy-agent "^2.1.1"
|
||||
http-proxy-agent "^2.1.0"
|
||||
https-proxy-agent "^2.2.1"
|
||||
mkdirp "^0.5.1"
|
||||
tmp "^0.0.33"
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"dependencies": {
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.8",
|
||||
"opener": "^1.4.3",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.4",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||
"vscode-extension-telemetry": "^0.0.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
||||
"version": "1.5.0-alpha.28",
|
||||
"version": "1.5.0-alpha.34",
|
||||
"downloadFileNames": {
|
||||
"Windows_86": "win-x86-netcoreapp2.1.zip",
|
||||
"Windows_64": "win-x64-netcoreapp2.1.zip",
|
||||
|
||||
@@ -191,14 +191,14 @@ graceful-fs@^4.1.10:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
|
||||
|
||||
http-proxy-agent@^2.0.0:
|
||||
http-proxy-agent@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
|
||||
dependencies:
|
||||
agent-base "4"
|
||||
debug "3.1.0"
|
||||
|
||||
https-proxy-agent@^2.1.1:
|
||||
https-proxy-agent@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
|
||||
dependencies:
|
||||
@@ -315,14 +315,14 @@ semver@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
||||
|
||||
"service-downloader@github:anthonydresser/service-downloader#0.1.4":
|
||||
version "0.1.4"
|
||||
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/3c0abdf8603aca85d2eacfac3c547173e41bf0c7"
|
||||
"service-downloader@github:anthonydresser/service-downloader#0.1.5":
|
||||
version "0.1.5"
|
||||
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/6ebb0465573cc140e461a22f334260f55ef45546"
|
||||
dependencies:
|
||||
decompress "^4.2.0"
|
||||
eventemitter2 "^5.0.1"
|
||||
http-proxy-agent "^2.0.0"
|
||||
https-proxy-agent "^2.1.1"
|
||||
http-proxy-agent "^2.1.0"
|
||||
https-proxy-agent "^2.2.1"
|
||||
mkdirp "^0.5.1"
|
||||
tmp "^0.0.33"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sqlops",
|
||||
"version": "0.33.1",
|
||||
"version": "0.33.7",
|
||||
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
@@ -64,7 +64,7 @@
|
||||
"reflect-metadata": "^0.1.8",
|
||||
"rxjs": "5.4.0",
|
||||
"semver": "^5.5.0",
|
||||
"slickgrid": "github:anthonydresser/SlickGrid#2.3.25",
|
||||
"slickgrid": "github:anthonydresser/SlickGrid#2.3.27",
|
||||
"spdlog": "0.7.1",
|
||||
"sudo-prompt": "8.2.0",
|
||||
"svg.js": "^2.2.5",
|
||||
@@ -167,5 +167,8 @@
|
||||
"windows-foreground-love": "0.1.0",
|
||||
"windows-mutex": "^0.2.0",
|
||||
"windows-process-tree": "0.2.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"rc": "1.2.8"
|
||||
}
|
||||
}
|
||||
|
||||
2791
samples/extensionSamples/package-lock.json
generated
2791
samples/extensionSamples/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
2642
samples/serverReports/package-lock.json
generated
2642
samples/serverReports/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
2794
samples/sp_whoIsActive/package-lock.json
generated
2794
samples/sp_whoIsActive/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
2738
samples/sqlservices/package-lock.json
generated
2738
samples/sqlservices/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
||||
"version": "0.0.1",
|
||||
"publisher": "demo",
|
||||
"engines": {
|
||||
"vscode": "^1.21.0",
|
||||
"vscode": "^1.26.0",
|
||||
"sqlops": "*"
|
||||
},
|
||||
"categories": [
|
||||
|
||||
@@ -128,9 +128,11 @@ export default class MainController implements vscode.Disposable {
|
||||
}
|
||||
});
|
||||
treeView.onDidChangeSelection(selectedNodes => {
|
||||
selectedNodes.forEach(node => {
|
||||
console.info('tree node selected: ' + node.label);
|
||||
});
|
||||
if (selectedNodes && selectedNodes.selection) {
|
||||
selectedNodes.selection.forEach(node => {
|
||||
console.info('tree node selected: ' + node.label);
|
||||
});
|
||||
}
|
||||
});
|
||||
let formModel = view.modelBuilder.formContainer()
|
||||
.withFormItems([{
|
||||
@@ -516,7 +518,8 @@ export default class MainController implements vscode.Disposable {
|
||||
let runButton = view.modelBuilder.button()
|
||||
.withProperties({
|
||||
label: 'Run',
|
||||
iconPath: runIcon
|
||||
iconPath: runIcon,
|
||||
title: 'Run title'
|
||||
}).component();
|
||||
|
||||
let monitorLightPath = vscode.Uri.file(path.join(__dirname, '..', 'media', 'monitor.svg'));
|
||||
@@ -528,7 +531,8 @@ export default class MainController implements vscode.Disposable {
|
||||
let monitorButton = view.modelBuilder.button()
|
||||
.withProperties({
|
||||
label: 'Monitor',
|
||||
iconPath: monitorIcon
|
||||
iconPath: monitorIcon,
|
||||
title: 'Monitor title'
|
||||
}).component();
|
||||
let toolbarModel = view.modelBuilder.toolbarContainer()
|
||||
.withToolbarItems([{
|
||||
|
||||
@@ -2865,6 +2865,10 @@ qs@~6.5.1:
|
||||
version "6.5.1"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
|
||||
|
||||
querystringify@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.0.0.tgz#fa3ed6e68eb15159457c89b37bc6472833195755"
|
||||
|
||||
querystringify@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb"
|
||||
@@ -3131,7 +3135,7 @@ require-main-filename@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
|
||||
|
||||
requires-port@~1.0.0:
|
||||
requires-port@^1.0.0, requires-port@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
|
||||
@@ -3755,6 +3759,13 @@ url-parse@^1.1.9:
|
||||
querystringify "~1.0.0"
|
||||
requires-port "~1.0.0"
|
||||
|
||||
url-parse@^1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.3.tgz#bfaee455c889023219d757e045fa6a684ec36c15"
|
||||
dependencies:
|
||||
querystringify "^2.0.0"
|
||||
requires-port "^1.0.0"
|
||||
|
||||
use@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544"
|
||||
@@ -3933,9 +3944,9 @@ vscode-nls@^3.2.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.2.tgz#3817eca5b985c2393de325197cf4e15eb2aa5350"
|
||||
|
||||
vscode@^1.1.14:
|
||||
version "1.1.18"
|
||||
resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.18.tgz#e9227265dc72fc826bd6cd7bd21193f4e48fa671"
|
||||
vscode@^1.1.18:
|
||||
version "1.1.21"
|
||||
resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.21.tgz#1c8253d6238aefb4112d6e58cf975ad25313dafc"
|
||||
dependencies:
|
||||
glob "^7.1.2"
|
||||
gulp-chmod "^2.0.0"
|
||||
@@ -3949,7 +3960,7 @@ vscode@^1.1.14:
|
||||
request "^2.83.0"
|
||||
semver "^5.4.1"
|
||||
source-map-support "^0.5.0"
|
||||
url-parse "^1.1.9"
|
||||
url-parse "^1.4.3"
|
||||
vinyl-source-stream "^1.1.0"
|
||||
|
||||
vso-node-api@^6.1.2-preview:
|
||||
|
||||
@@ -10,7 +10,7 @@ export const IBreadcrumbService = new InjectionToken<IBreadcrumbService>('breadc
|
||||
|
||||
export interface IBreadcrumbService {
|
||||
breadcrumbItem: Subject<MenuItem[]>;
|
||||
setBreadcrumbs(any): void;
|
||||
setBreadcrumbs(page: any): void;
|
||||
}
|
||||
|
||||
export interface MenuItem {
|
||||
|
||||
@@ -23,6 +23,18 @@ export class Button extends vsButton {
|
||||
this.$el.style('outline-color', this.buttonFocusOutline ? this.buttonFocusOutline.toString() : null);
|
||||
this.$el.style('outline-width', '1px');
|
||||
});
|
||||
|
||||
this.$el.on(DOM.EventType.MOUSE_DOWN, (e) => {
|
||||
const mouseEvent = e as MouseEvent;
|
||||
if (!this.$el.hasClass('disabled') && mouseEvent.button === 0) {
|
||||
this.$el.addClass('active');
|
||||
}
|
||||
});
|
||||
|
||||
this.$el.on([DOM.EventType.MOUSE_UP], (e) => {
|
||||
DOM.EventHelper.stop(e);
|
||||
this.$el.removeClass('active');
|
||||
});
|
||||
}
|
||||
|
||||
public style(styles: IButtonStyles): void {
|
||||
|
||||
@@ -217,7 +217,7 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
if (this._modalOptions.isAngular === false && this._modalOptions.hasErrors) {
|
||||
let builder = errorMessagesInFooter ? this._leftFooter : body;
|
||||
builder.div({ class: 'dialogErrorMessage', id: 'dialogErrorMessage' }, (errorMessageContainer) => {
|
||||
errorMessageContainer.div({ class: 'icon error' }, (iconContainer) => {
|
||||
errorMessageContainer.div({ class: 'sql icon error' }, (iconContainer) => {
|
||||
this._errorIconElement = iconContainer.getHTMLElement();
|
||||
this._errorIconElement.style.visibility = 'hidden';
|
||||
});
|
||||
@@ -518,5 +518,6 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
public dispose() {
|
||||
super.dispose();
|
||||
this._keydownListener.dispose();
|
||||
this._footerButtons = [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,8 @@ export class TabbedPanel extends Disposable implements IThemable {
|
||||
private _onTabChange = new Emitter<PanelTabIdentifier>();
|
||||
public onTabChange: Event<PanelTabIdentifier> = this._onTabChange.event;
|
||||
|
||||
private tabHistory: string[] = [];
|
||||
|
||||
constructor(private container: HTMLElement, private options: IPanelOptions = defaultOptions) {
|
||||
super();
|
||||
this.$parent = this._register($('.tabbedPanel'));
|
||||
@@ -152,6 +154,7 @@ export class TabbedPanel extends Disposable implements IThemable {
|
||||
}
|
||||
|
||||
this._shownTab = id;
|
||||
this.tabHistory.push(id);
|
||||
this.$body.clearChildren();
|
||||
let tab = this._tabMap.get(this._shownTab);
|
||||
this.$body.attr('aria-labelledby', tab.identifier);
|
||||
@@ -173,6 +176,26 @@ export class TabbedPanel extends Disposable implements IThemable {
|
||||
}
|
||||
this._tabMap.get(tab).header.destroy();
|
||||
this._tabMap.delete(tab);
|
||||
if (this._shownTab === tab) {
|
||||
this._shownTab = undefined;
|
||||
while (this._shownTab === undefined && this.tabHistory.length > 0) {
|
||||
let lastTab = this.tabHistory.shift();
|
||||
if (this._tabMap.get(lastTab)) {
|
||||
this.showTab(lastTab);
|
||||
}
|
||||
}
|
||||
|
||||
// this shouldn't happen but just in case
|
||||
if (this._shownTab === undefined && this._tabMap.size > 0) {
|
||||
this.showTab(this._tabMap.keys().next().value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.options.showHeaderWhenSingleView && this._tabMap.size === 1 && this._headerVisible) {
|
||||
this.$header.offDOM();
|
||||
this._headerVisible = false;
|
||||
this.layout(this._currentDimensions);
|
||||
}
|
||||
}
|
||||
|
||||
public style(styles: IPanelStyles): void {
|
||||
@@ -180,14 +203,16 @@ export class TabbedPanel extends Disposable implements IThemable {
|
||||
}
|
||||
|
||||
public layout(dimension: Dimension): void {
|
||||
this._currentDimensions = dimension;
|
||||
this.$parent.style('height', dimension.height + 'px');
|
||||
this.$parent.style('width', dimension.width + 'px');
|
||||
this.$header.style('width', dimension.width + 'px');
|
||||
this.$body.style('width', dimension.width + 'px');
|
||||
const bodyHeight = dimension.height - (this._headerVisible ? this.headersize : 0);
|
||||
this.$body.style('height', bodyHeight + 'px');
|
||||
this._layoutCurrentTab(new Dimension(dimension.width, bodyHeight));
|
||||
if (dimension) {
|
||||
this._currentDimensions = dimension;
|
||||
this.$parent.style('height', dimension.height + 'px');
|
||||
this.$parent.style('width', dimension.width + 'px');
|
||||
this.$header.style('width', dimension.width + 'px');
|
||||
this.$body.style('width', dimension.width + 'px');
|
||||
const bodyHeight = dimension.height - (this._headerVisible ? this.headersize : 0);
|
||||
this.$body.style('height', bodyHeight + 'px');
|
||||
this._layoutCurrentTab(new Dimension(dimension.width, bodyHeight));
|
||||
}
|
||||
}
|
||||
|
||||
private _layoutCurrentTab(dimension: Dimension): void {
|
||||
|
||||
@@ -34,6 +34,8 @@ export interface IView extends HeightIView {
|
||||
readonly onDidChange: Event<number | undefined>;
|
||||
render(container: HTMLElement, orientation: Orientation): void;
|
||||
layout(size: number, orientation: Orientation): void;
|
||||
onAdd?(): void;
|
||||
onRemove?(): void;
|
||||
}
|
||||
|
||||
interface ISashEvent {
|
||||
@@ -48,6 +50,8 @@ interface IViewItem extends HeightIViewItem {
|
||||
container: HTMLElement;
|
||||
disposable: IDisposable;
|
||||
layout(): void;
|
||||
onRemove: () => void;
|
||||
onAdd: () => void;
|
||||
}
|
||||
|
||||
interface ISashItem {
|
||||
@@ -109,6 +113,9 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
|
||||
private _onDidSashReset = new Emitter<void>();
|
||||
readonly onDidSashReset = this._onDidSashReset.event;
|
||||
|
||||
private _onScroll = new Emitter<number>();
|
||||
readonly onScroll = this._onScroll.event;
|
||||
|
||||
get length(): number {
|
||||
return this.viewItems.length;
|
||||
}
|
||||
@@ -124,6 +131,7 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
|
||||
debounceEvent(this.scrollable.onScroll, (l, e) => e, 25)(e => {
|
||||
this.render(e.scrollTop, e.height);
|
||||
this.relayout();
|
||||
this._onScroll.fire(e.scrollTop);
|
||||
});
|
||||
let domNode = this.scrollable.getDomNode();
|
||||
dom.addClass(this.el, 'monaco-scroll-split-view');
|
||||
@@ -155,6 +163,9 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
|
||||
});
|
||||
const disposable = combinedDisposable([onChangeDisposable, containerDisposable]);
|
||||
|
||||
const onAdd = view.onAdd ? () => view.onAdd() : () => { };
|
||||
const onRemove = view.onRemove ? () => view.onRemove() : () => { };
|
||||
|
||||
const layoutContainer = this.orientation === Orientation.VERTICAL
|
||||
? size => item.container.style.height = `${item.size}px`
|
||||
: size => item.container.style.width = `${item.size}px`;
|
||||
@@ -165,7 +176,7 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
|
||||
};
|
||||
|
||||
size = Math.round(size);
|
||||
const item: IViewItem = { view, container, size, layout, disposable, height: size, top: 0, width: 0 };
|
||||
const item: IViewItem = { onRemove, onAdd, view, container, size, layout, disposable, height: size, top: 0, width: 0 };
|
||||
this.viewItems.splice(viewIndex, 0, item);
|
||||
|
||||
this.onInsertItems(new ArrayIterator([item]), viewIndex > 0 ? this.viewItems[viewIndex - 1].view.id : undefined);
|
||||
@@ -220,6 +231,9 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
|
||||
});
|
||||
const disposable = combinedDisposable([onChangeDisposable, containerDisposable]);
|
||||
|
||||
const onAdd = view.onAdd ? () => view.onAdd() : () => { };
|
||||
const onRemove = view.onRemove ? () => view.onRemove() : () => { };
|
||||
|
||||
const layoutContainer = this.orientation === Orientation.VERTICAL
|
||||
? size => item.container.style.height = `${item.size}px`
|
||||
: size => item.container.style.width = `${item.size}px`;
|
||||
@@ -230,7 +244,7 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
|
||||
};
|
||||
|
||||
size = Math.round(size);
|
||||
const item: IViewItem = { view, container, size, layout, disposable, height: size, top: 0, width: 0 };
|
||||
const item: IViewItem = { onAdd, onRemove, view, container, size, layout, disposable, height: size, top: 0, width: 0 };
|
||||
this.viewItems.splice(index, 0, item);
|
||||
|
||||
this.onInsertItems(new ArrayIterator([item]), index > 0 ? this.viewItems[index - 1].view.id : undefined);
|
||||
@@ -330,9 +344,16 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
|
||||
this.resize(this.viewItems.length - 1, this.size - contentSize, undefined, lowPriorityIndex);
|
||||
}
|
||||
|
||||
public setScrollPosition(position: number) {
|
||||
this.scrollable.setScrollPosition({ scrollTop: position });
|
||||
}
|
||||
|
||||
layout(size: number): void {
|
||||
const previousSize = Math.max(this.size, this.contentSize);
|
||||
const previousSize = this.size;
|
||||
this.size = size;
|
||||
this.contentSize = 0;
|
||||
this.lastRenderHeight = undefined;
|
||||
this.lastRenderTop = undefined;
|
||||
this.resize(this.viewItems.length - 1, size - previousSize);
|
||||
}
|
||||
|
||||
@@ -484,6 +505,8 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
|
||||
}
|
||||
|
||||
item.layout();
|
||||
|
||||
item.onAdd();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -493,6 +516,8 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
|
||||
}
|
||||
|
||||
this.el.removeChild(item.container);
|
||||
|
||||
item.onRemove();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,9 @@ export class SelectBox extends vsSelectBox {
|
||||
if (container) {
|
||||
this.element = dom.append(container, $('.monaco-selectbox.idle'));
|
||||
}
|
||||
|
||||
// explicitly set the accessible role so that the screen readers can read the control type properly
|
||||
this.selectElement.setAttribute('role', 'combobox');
|
||||
}
|
||||
|
||||
public style(styles: ISelectBoxStyles): void {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { range } from 'vs/base/common/arrays';
|
||||
|
||||
/**
|
||||
* Implements the various additional navigation keybindings we want out of slickgrid
|
||||
@@ -50,6 +51,14 @@ export class AdditionalKeyBindings<T> implements Slick.Plugin<T> {
|
||||
}
|
||||
} else if (event.equals(KeyCode.End | KeyMod.CtrlCmd)) {
|
||||
this.grid.setActiveCell(this.grid.getDataLength() - 1, this.grid.getColumns().length - 1);
|
||||
} else if (event.equals(KeyCode.KEY_A | KeyMod.CtrlCmd)) {
|
||||
// check if we can set the rows directly on the selectionModel, its cleaner
|
||||
let selectionModel = this.grid.getSelectionModel();
|
||||
if (selectionModel) {
|
||||
selectionModel.setSelectedRanges([new Slick.Range(0, 0, this.grid.getDataLength() - 1, this.grid.getColumns().length - 1)]);
|
||||
} else {
|
||||
this.grid.setSelectedRows(range(this.grid.getDataLength()));
|
||||
}
|
||||
} else {
|
||||
handled = false;
|
||||
}
|
||||
|
||||
145
src/sql/base/browser/ui/table/plugins/cellRangeSelector.ts
Normal file
145
src/sql/base/browser/ui/table/plugins/cellRangeSelector.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
|
||||
const defaultOptions: ICellRangeSelectorOptions = {
|
||||
selectionCss: {
|
||||
'border': '2px dashed blue'
|
||||
},
|
||||
offset: {
|
||||
top: -1,
|
||||
left: -1,
|
||||
height: 2,
|
||||
width: 2
|
||||
},
|
||||
dragClass: 'drag'
|
||||
};
|
||||
|
||||
export interface ICellRangeSelectorOptions {
|
||||
selectionCss?: { [key: string]: string };
|
||||
cellDecorator?: ICellRangeDecorator;
|
||||
offset?: { top: number, left: number, height: number, width: number };
|
||||
dragClass?: string;
|
||||
}
|
||||
|
||||
export interface ICellRangeSelector<T> extends Slick.Plugin<T> {
|
||||
onCellRangeSelected: Slick.Event<{ range: Slick.Range }>;
|
||||
onBeforeCellRangeSelected: Slick.Event<Slick.Cell>;
|
||||
}
|
||||
|
||||
export interface ICellRangeDecorator {
|
||||
show(range: Slick.Range);
|
||||
hide();
|
||||
}
|
||||
|
||||
export class CellRangeSelector<T> implements ICellRangeSelector<T> {
|
||||
private grid: Slick.Grid<T>;
|
||||
private dragging: boolean;
|
||||
private handler = new Slick.EventHandler();
|
||||
private decorator: ICellRangeDecorator;
|
||||
private canvas: HTMLCanvasElement;
|
||||
private currentlySelectedRange: { start: Slick.Cell, end: Slick.Cell };
|
||||
|
||||
public onBeforeCellRangeSelected = new Slick.Event<Slick.Cell>();
|
||||
public onCellRangeSelected = new Slick.Event<{ range: Slick.Range }>();
|
||||
|
||||
constructor(private options: ICellRangeSelectorOptions) {
|
||||
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangedecorator');
|
||||
|
||||
this.options = mixin(this.options, defaultOptions, false);
|
||||
}
|
||||
|
||||
public init(grid: Slick.Grid<T>) {
|
||||
this.decorator = this.options.cellDecorator || new (<any>Slick).CellRangeDecorator(grid, this.options);
|
||||
this.grid = grid;
|
||||
this.canvas = this.grid.getCanvasNode();
|
||||
this.handler
|
||||
.subscribe(this.grid.onDragInit, e => this.handleDragInit(e))
|
||||
.subscribe(this.grid.onDragStart, (e, dd) => this.handleDragStart(e, dd))
|
||||
.subscribe(this.grid.onDrag, (e, dd) => this.handleDrag(e, dd))
|
||||
.subscribe(this.grid.onDragEnd, (e, dd) => this.handleDragEnd(e, dd));
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.handler.unsubscribeAll();
|
||||
}
|
||||
|
||||
public getCellDecorator() {
|
||||
return this.decorator;
|
||||
}
|
||||
|
||||
public getCurrentRange() {
|
||||
return this.currentlySelectedRange;
|
||||
}
|
||||
|
||||
private handleDragInit(e: DOMEvent) {
|
||||
// prevent the grid from cancelling drag'n'drop by default
|
||||
e.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
private handleDragStart(e: MouseEvent, dd: Slick.OnDragStartEventArgs<T>) {
|
||||
let cell = this.grid.getCellFromEvent(e);
|
||||
if (this.onBeforeCellRangeSelected.notify(cell) !== false) {
|
||||
if (this.grid.canCellBeSelected(cell.row, cell.cell)) {
|
||||
this.dragging = true;
|
||||
e.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
if (!this.dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.canvas.classList.add(this.options.dragClass);
|
||||
|
||||
this.grid.setActiveCell(cell.row, cell.cell);
|
||||
|
||||
let start = this.grid.getCellFromPoint(
|
||||
dd.startX - $(this.canvas).offset().left,
|
||||
dd.startY - $(this.canvas).offset().top);
|
||||
|
||||
dd.range = { start: start, end: undefined };
|
||||
this.currentlySelectedRange = dd.range;
|
||||
return this.decorator.show(new Slick.Range(start.row, start.cell));
|
||||
}
|
||||
|
||||
private handleDrag(e: MouseEvent, dd: Slick.OnDragEventArgs<T>) {
|
||||
if (!this.dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.stopImmediatePropagation();
|
||||
|
||||
let end = this.grid.getCellFromPoint(
|
||||
e.pageX - $(this.canvas).offset().left,
|
||||
e.pageY - $(this.canvas).offset().top);
|
||||
|
||||
if (!this.grid.canCellBeSelected(end.row, end.cell)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dd.range.end = end;
|
||||
this.currentlySelectedRange = dd.range;
|
||||
this.decorator.show(new Slick.Range(dd.range.start.row, dd.range.start.cell, end.row, end.cell));
|
||||
}
|
||||
|
||||
private handleDragEnd(e: MouseEvent, dd: Slick.OnDragEndEventArgs<T>) {
|
||||
if (!this.dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.canvas.classList.remove(this.options.dragClass);
|
||||
this.dragging = false;
|
||||
e.stopImmediatePropagation();
|
||||
this.decorator.hide();
|
||||
// if this happens to fast there is a chance we don't have the necessary information to actually do proper selection
|
||||
if (!dd || !dd.range || !dd.range.start || !dd.range.end) {
|
||||
return;
|
||||
}
|
||||
this.onCellRangeSelected.notify({
|
||||
range: new Slick.Range(
|
||||
dd.range.start.row,
|
||||
dd.range.start.cell,
|
||||
dd.range.end.row,
|
||||
dd.range.end.cell
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,8 @@
|
||||
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangedecorator');
|
||||
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangeselector');
|
||||
|
||||
export interface ICellRangeSelector<T> extends Slick.Plugin<T> {
|
||||
onCellRangeSelected: Slick.Event<{ range: Slick.Range }>;
|
||||
onBeforeCellRangeSelected: Slick.Event<Slick.Cell>;
|
||||
}
|
||||
import { CellRangeSelector, ICellRangeSelector } from 'sql/base/browser/ui/table/plugins/cellRangeSelector';
|
||||
|
||||
export interface ICellSelectionModelOptions {
|
||||
cellRangeSelector?: any;
|
||||
@@ -36,7 +29,7 @@ export class CellSelectionModel<T> implements Slick.SelectionModel<T, Array<Slic
|
||||
this.selector = this.options.cellRangeSelector;
|
||||
} else {
|
||||
// this is added by the noderequires above
|
||||
this.selector = new (<any>Slick).CellRangeSelector({ selectionCss: { 'border': '2px dashed grey' } });
|
||||
this.selector = new CellRangeSelector({ selectionCss: { 'border': '2px dashed grey' } });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
62
src/sql/base/browser/ui/table/plugins/copyKeybind.plugin.ts
Normal file
62
src/sql/base/browser/ui/table/plugins/copyKeybind.plugin.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
|
||||
/**
|
||||
* Implements the various additional navigation keybindings we want out of slickgrid
|
||||
*/
|
||||
export class CopyKeybind<T> implements Slick.Plugin<T> {
|
||||
private grid: Slick.Grid<T>;
|
||||
private handler = new Slick.EventHandler();
|
||||
|
||||
private _onCopy = new Emitter<Slick.Range[]>();
|
||||
public onCopy: Event<Slick.Range[]> = this._onCopy.event;
|
||||
|
||||
public init(grid: Slick.Grid<T>) {
|
||||
this.grid = grid;
|
||||
this.handler.subscribe(this.grid.onKeyDown, (e, args) => this.handleKeyDown(e, args));
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.handler.unsubscribeAll();
|
||||
}
|
||||
|
||||
private handleKeyDown(e: KeyboardEvent, args: Slick.OnKeyDownEventArgs<T>): void {
|
||||
let event = new StandardKeyboardEvent(e);
|
||||
let handled = false;
|
||||
|
||||
if (event.equals(KeyCode.KEY_C | KeyMod.CtrlCmd)) {
|
||||
handled = true;
|
||||
let selectionModel = this.grid.getSelectionModel();
|
||||
let ranges: Slick.Range[];
|
||||
// check to see if we can get the range from the model directly
|
||||
if (selectionModel) {
|
||||
ranges = selectionModel.getSelectedRanges();
|
||||
} else {
|
||||
let selectedRows = this.grid.getSelectedRows();
|
||||
let startColumn = 0;
|
||||
// check for number column
|
||||
if (!isUndefinedOrNull(this.grid.getColumns()[0].selectable) && !this.grid.getColumns()[0].selectable) {
|
||||
startColumn = 1;
|
||||
}
|
||||
ranges = [new Slick.Range(selectedRows[0], startColumn, selectedRows[selectedRows.length - 1], this.grid.getColumns().length)]
|
||||
}
|
||||
this._onCopy.fire(ranges);
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
e.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,23 +36,31 @@ export class RowNumberColumn<T> implements Slick.Plugin<T> {
|
||||
private handleClick(e: MouseEvent, args: Slick.OnClickEventArgs<T>): void {
|
||||
if (this.grid.getColumns()[args.cell].id === 'rowNumber') {
|
||||
this.grid.setActiveCell(args.row, 1);
|
||||
this.grid.setSelectedRows([args.row]);
|
||||
if (this.grid.getSelectionModel()) {
|
||||
this.grid.setSelectedRows([args.row]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private handleHeaderClick(e: MouseEvent, args: Slick.OnHeaderClickEventArgs<T>): void {
|
||||
if (args.column.id === 'rowNumber') {
|
||||
this.grid.setActiveCell(0, 1);
|
||||
this.grid.setSelectedRows(range(this.grid.getDataLength()));
|
||||
if (this.grid.getSelectionModel()) {
|
||||
this.grid.setSelectedRows(range(this.grid.getDataLength()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getColumnDefinition(): Slick.Column<T> {
|
||||
// that smallest we can make it is 22 due to padding and margins in the cells
|
||||
let columnWidth = Math.max(this.options.numberOfRows.toString().length * sizePerDigit, 22);
|
||||
return {
|
||||
id: 'rowNumber',
|
||||
name: '',
|
||||
field: 'rowNumber',
|
||||
width: this.options.numberOfRows.toString().length * sizePerDigit,
|
||||
width: columnWidth,
|
||||
minWidth: columnWidth,
|
||||
maxWidth: columnWidth,
|
||||
resizable: false,
|
||||
cssClass: this.options.cssClass,
|
||||
focusable: false,
|
||||
|
||||
@@ -166,6 +166,10 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
|
||||
this._grid.setData(this._data, true);
|
||||
}
|
||||
|
||||
getData(): Slick.DataProvider<T> {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
get columns(): Slick.Column<T>[] {
|
||||
return this._grid.getColumns();
|
||||
}
|
||||
@@ -244,7 +248,6 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
|
||||
}
|
||||
}
|
||||
this.resizeCanvas();
|
||||
this.autosizeColumns();
|
||||
}
|
||||
|
||||
autosizeColumns() {
|
||||
@@ -308,10 +311,15 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
|
||||
|
||||
if (styles.listHoverBackground) {
|
||||
content.push(`.monaco-table.${this.idPrefix} .slick-row:hover { background-color: ${styles.listHoverBackground}; }`);
|
||||
// handle no coloring during drag
|
||||
content.push(`.monaco-table.${this.idPrefix} .drag .slick-row:hover { background-color: inherit; }`);
|
||||
|
||||
}
|
||||
|
||||
if (styles.listHoverForeground) {
|
||||
content.push(`.monaco-table.${this.idPrefix} .slick-row:hover { color: ${styles.listHoverForeground}; }`);
|
||||
// handle no coloring during drag
|
||||
content.push(`.monaco-table.${this.idPrefix} .drag .slick-row:hover { color: inherit; }`);
|
||||
}
|
||||
|
||||
if (styles.listSelectionOutline) {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
'use strict';
|
||||
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
/**
|
||||
* Implementation of vs/base/common/event/echo that is clearable
|
||||
@@ -37,3 +38,52 @@ export function echo<T>(event: Event<T>, nextTick = false, buffer: T[] = []): {
|
||||
clear
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of vs/base/common/event/debounceEvent that is clearable
|
||||
*/
|
||||
export function debounceEvent<T>(event: Event<T>, merger: (last: T, event: T) => T, delay?: number, leading?: boolean): { clear: () => void; event: Event<T> };
|
||||
export function debounceEvent<I, O>(event: Event<I>, merger: (last: O, event: I) => O, delay?: number, leading?: boolean): { clear: () => void; event: Event<O> };
|
||||
export function debounceEvent<I, O>(event: Event<I>, merger: (last: O, event: I) => O, delay: number = 100, leading = false): { clear: () => void; event: Event<O> } {
|
||||
|
||||
let subscription: IDisposable;
|
||||
let output: O = undefined;
|
||||
let handle: any = undefined;
|
||||
let numDebouncedCalls = 0;
|
||||
|
||||
const clear = () => output = undefined;
|
||||
|
||||
const emitter = new Emitter<O>({
|
||||
onFirstListenerAdd() {
|
||||
subscription = event(cur => {
|
||||
numDebouncedCalls++;
|
||||
output = merger(output, cur);
|
||||
|
||||
if (leading && !handle) {
|
||||
emitter.fire(output);
|
||||
}
|
||||
|
||||
clearTimeout(handle);
|
||||
handle = setTimeout(() => {
|
||||
let _output = output;
|
||||
output = undefined;
|
||||
handle = undefined;
|
||||
if (!leading || numDebouncedCalls > 1) {
|
||||
emitter.fire(_output);
|
||||
}
|
||||
|
||||
numDebouncedCalls = 0;
|
||||
}, delay);
|
||||
});
|
||||
},
|
||||
onLastListenerRemove() {
|
||||
subscription.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
event: emitter.event,
|
||||
clear
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -63,21 +63,21 @@
|
||||
background: url("globalerror.svg") center center no-repeat;
|
||||
}
|
||||
|
||||
.vs .icon.error,
|
||||
.vs-dark .icon.error,
|
||||
.hc-black .icon.error {
|
||||
.vs .sql.icon.error,
|
||||
.vs-dark .sql.icon.error,
|
||||
.hc-black .sql.icon.error {
|
||||
content: url("status_error.svg");
|
||||
}
|
||||
|
||||
.vs .icon.warning,
|
||||
.vs-dark .icon.warning,
|
||||
.hc-black .icon.warning {
|
||||
.vs .sql.icon.warning,
|
||||
.vs-dark .sql.icon.warning,
|
||||
.hc-black .sql.icon.warning {
|
||||
content: url("status_warning.svg");
|
||||
}
|
||||
|
||||
.vs .icon.info,
|
||||
.vs-dark .icon.info,
|
||||
.hc-black .icon.info {
|
||||
.vs .sql.icon.info,
|
||||
.vs-dark .sql.icon.info,
|
||||
.hc-black .sql.icon.info {
|
||||
content: url("status_info.svg");
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ export class AccountPicker extends Disposable {
|
||||
|
||||
// Create refresh account action
|
||||
this._refreshContainer = DOM.append(this._rootElement, DOM.$('div.refresh-container'));
|
||||
DOM.append(this._refreshContainer, DOM.$('div.icon warning'));
|
||||
DOM.append(this._refreshContainer, DOM.$('div.sql icon warning'));
|
||||
let actionBar = new ActionBar(this._refreshContainer, { animated: false });
|
||||
this._refreshAccountAction = this._instantiationService.createInstance(RefreshAccountAction);
|
||||
actionBar.push(this._refreshAccountAction, { icon: false, label: true });
|
||||
|
||||
@@ -123,6 +123,7 @@ export class ConnectionStore {
|
||||
.then(savedCred => {
|
||||
if (savedCred) {
|
||||
credentialsItem.password = savedCred.password;
|
||||
credentialsItem.options['password'] = savedCred.password;
|
||||
}
|
||||
resolve({ profile: credentialsItem, savedCred: !!savedCred });
|
||||
},
|
||||
|
||||
@@ -100,10 +100,10 @@ export class ConnectionDialogWidget extends Modal {
|
||||
public refresh(): void {
|
||||
let filteredProviderTypes = this.providerTypeOptions;
|
||||
|
||||
if (this._newConnectionParams && this._newConnectionParams.providers) {
|
||||
if (this._newConnectionParams && this._newConnectionParams.providers) {
|
||||
let validProviderNames = Object.keys(this.providerNameToDisplayNameMap).filter(x => this.includeProvider(x, this._newConnectionParams));
|
||||
if (validProviderNames && validProviderNames.length > 0) {
|
||||
filteredProviderTypes = filteredProviderTypes.filter(x => validProviderNames.find( v => this.providerNameToDisplayNameMap[v] === x) !== undefined);
|
||||
filteredProviderTypes = filteredProviderTypes.filter(x => validProviderNames.find(v => this.providerNameToDisplayNameMap[v] === x) !== undefined);
|
||||
}
|
||||
}
|
||||
this._providerTypeSelectBox.setOptions(filteredProviderTypes);
|
||||
@@ -118,8 +118,8 @@ export class ConnectionDialogWidget extends Modal {
|
||||
container.appendChild(connectionContainer.getHTMLElement());
|
||||
|
||||
this._bodyBuilder = new Builder(connectionContainer.getHTMLElement());
|
||||
this._providerTypeSelectBox = new SelectBox(this.providerTypeOptions, this.selectedProviderType, this._contextViewService);
|
||||
|
||||
const connectTypeLabel = localize('connectType', 'Connection type');
|
||||
this._providerTypeSelectBox = new SelectBox(this.providerTypeOptions, this.selectedProviderType, this._contextViewService, undefined, { ariaLabel: connectTypeLabel });
|
||||
// Recent connection tab
|
||||
let recentConnectionTab = $('.connection-recent-tab');
|
||||
recentConnectionTab.div({ class: 'connection-recent', id: 'recentConnection' }, (builder) => {
|
||||
@@ -182,7 +182,6 @@ export class ConnectionDialogWidget extends Modal {
|
||||
});
|
||||
|
||||
this._bodyBuilder.div({ class: 'connection-type' }, (modelTableContent) => {
|
||||
let connectTypeLabel = localize('connectType', 'Connection type');
|
||||
modelTableContent.element('table', { class: 'connection-table-content' }, (tableContainer) => {
|
||||
DialogHelper.appendInputSelectBox(
|
||||
DialogHelper.appendRow(tableContainer, connectTypeLabel, 'connection-label', 'connection-input'), this._providerTypeSelectBox);
|
||||
@@ -450,4 +449,4 @@ export class ConnectionDialogWidget extends Modal {
|
||||
public get databaseDropdownExpanded(): boolean {
|
||||
return this._databaseDropdownExpanded;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,7 @@ export class ConnectionWidget {
|
||||
private _databaseDropdownExpanded: boolean = false;
|
||||
private _defaultDatabaseName: string = localize('defaultDatabaseOption', '<Default>');
|
||||
private _loadingDatabaseName: string = localize('loadingDatabaseOption', 'Loading...');
|
||||
private _serverGroupDisplayString: string = localize('serverGroup', 'Server group');
|
||||
public DefaultServerGroup: IConnectionProfileGroup = {
|
||||
id: '',
|
||||
name: localize('defaultServerGroup', '<Default>'),
|
||||
@@ -112,14 +113,14 @@ export class ConnectionWidget {
|
||||
} else {
|
||||
authTypeOption.defaultValue = this.getAuthTypeDisplayName(Constants.sqlLogin);
|
||||
}
|
||||
this._authTypeSelectBox = new SelectBox(authTypeOption.categoryValues.map(c => c.displayName), authTypeOption.defaultValue, this._contextViewService);
|
||||
this._authTypeSelectBox = new SelectBox(authTypeOption.categoryValues.map(c => c.displayName), authTypeOption.defaultValue, this._contextViewService, undefined, { ariaLabel: authTypeOption.displayName });
|
||||
}
|
||||
this._providerName = providerName;
|
||||
}
|
||||
|
||||
public createConnectionWidget(container: HTMLElement): void {
|
||||
this._serverGroupOptions = [this.DefaultServerGroup];
|
||||
this._serverGroupSelectBox = new SelectBox(this._serverGroupOptions.map(g => g.name), this.DefaultServerGroup.name, this._contextViewService);
|
||||
this._serverGroupSelectBox = new SelectBox(this._serverGroupOptions.map(g => g.name), this.DefaultServerGroup.name, this._contextViewService, undefined, { ariaLabel: this._serverGroupDisplayString });
|
||||
this._previousGroupOption = this._serverGroupSelectBox.value;
|
||||
this._builder = $().div({ class: 'connection-table' }, (modelTableContent) => {
|
||||
modelTableContent.element('table', { class: 'connection-table-content' }, (tableContainer) => {
|
||||
@@ -155,11 +156,6 @@ export class ConnectionWidget {
|
||||
}
|
||||
|
||||
private fillInConnectionForm(): void {
|
||||
// Connection name
|
||||
let connectionNameOption = this._optionsMaps[ConnectionOptionSpecialType.connectionName];
|
||||
let connectionNameBuilder = DialogHelper.appendRow(this._tableContainer, connectionNameOption.displayName, 'connection-label', 'connection-input');
|
||||
this._connectionNameInputBox = new InputBox(connectionNameBuilder.getHTMLElement(), this._contextViewService, { ariaLabel: connectionNameOption.displayName });
|
||||
|
||||
// Server name
|
||||
let serverNameOption = this._optionsMaps[ConnectionOptionSpecialType.serverName];
|
||||
let serverNameBuilder = DialogHelper.appendRow(this._tableContainer, serverNameOption.displayName, 'connection-label', 'connection-input');
|
||||
@@ -193,7 +189,6 @@ export class ConnectionWidget {
|
||||
},
|
||||
ariaLabel: userNameOption.displayName
|
||||
});
|
||||
|
||||
// Password
|
||||
let passwordOption = this._optionsMaps[ConnectionOptionSpecialType.password];
|
||||
let passwordBuilder = DialogHelper.appendRow(this._tableContainer, passwordOption.displayName, 'connection-label', 'connection-input');
|
||||
@@ -219,10 +214,14 @@ export class ConnectionWidget {
|
||||
});
|
||||
|
||||
// Server group
|
||||
let serverGroupLabel = localize('serverGroup', 'Server group');
|
||||
let serverGroupBuilder = DialogHelper.appendRow(this._tableContainer, serverGroupLabel, 'connection-label', 'connection-input');
|
||||
let serverGroupBuilder = DialogHelper.appendRow(this._tableContainer, this._serverGroupDisplayString, 'connection-label', 'connection-input');
|
||||
DialogHelper.appendInputSelectBox(serverGroupBuilder, this._serverGroupSelectBox);
|
||||
|
||||
// Connection name
|
||||
let connectionNameOption = this._optionsMaps[ConnectionOptionSpecialType.connectionName];
|
||||
let connectionNameBuilder = DialogHelper.appendRow(this._tableContainer, connectionNameOption.displayName, 'connection-label', 'connection-input');
|
||||
this._connectionNameInputBox = new InputBox(connectionNameBuilder.getHTMLElement(), this._contextViewService, { ariaLabel: connectionNameOption.displayName });
|
||||
|
||||
let AdvancedLabel = localize('advanced', 'Advanced...');
|
||||
this._advancedButton = this.createAdvancedButton(this._tableContainer, AdvancedLabel);
|
||||
}
|
||||
@@ -399,7 +398,7 @@ export class ConnectionWidget {
|
||||
|
||||
public focusOnOpen(): void {
|
||||
this._handleClipboard();
|
||||
this._connectionNameInputBox.focus();
|
||||
this._serverNameInputBox.focus();
|
||||
this.focusPasswordIfNeeded();
|
||||
this.clearValidationMessages();
|
||||
}
|
||||
@@ -493,6 +492,7 @@ export class ConnectionWidget {
|
||||
this._databaseNameInputBox.enabled = false;
|
||||
this._userNameInputBox.disable();
|
||||
this._passwordInputBox.disable();
|
||||
this._connectionNameInputBox.disable();
|
||||
this._rememberPasswordCheckBox.enabled = false;
|
||||
if (this._authTypeSelectBox) {
|
||||
this._authTypeSelectBox.disable();
|
||||
@@ -504,6 +504,7 @@ export class ConnectionWidget {
|
||||
|
||||
this._serverGroupSelectBox.enable();
|
||||
this._serverNameInputBox.enable();
|
||||
this._connectionNameInputBox.enable();
|
||||
this._databaseNameInputBox.enabled = true;
|
||||
let currentAuthType: AuthenticationType = undefined;
|
||||
if (this._authTypeSelectBox) {
|
||||
|
||||
@@ -31,7 +31,7 @@ import * as nls from 'vs/nls';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
@@ -96,7 +96,8 @@ export abstract class DashboardPage extends AngularDisposable implements IConfig
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef,
|
||||
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
|
||||
@Inject(INotificationService) private notificationService: INotificationService,
|
||||
@Inject(IAngularEventingService) private angularEventingService: IAngularEventingService
|
||||
@Inject(IAngularEventingService) private angularEventingService: IAngularEventingService,
|
||||
@Inject(IConfigurationService) private configurationService: IConfigurationService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -138,6 +139,12 @@ export abstract class DashboardPage extends AngularDisposable implements IConfig
|
||||
// Before separating tabs into pinned / shown, ensure that the home tab is always set up as expected
|
||||
allTabs = this.setAndRemoveHomeTab(allTabs, homeWidgets);
|
||||
|
||||
// If preview features are disabled only show the home tab
|
||||
let extensionTabsEnabled = this.configurationService.getValue('workbench')['enablePreviewFeatures'];
|
||||
if (!extensionTabsEnabled) {
|
||||
allTabs = [];
|
||||
}
|
||||
|
||||
// Load tab setting configs
|
||||
this._tabSettingConfigs = this.dashboardService.getSettings<Array<TabSettingConfig>>([this.context, 'tabs'].join('.'));
|
||||
|
||||
@@ -164,9 +171,13 @@ export abstract class DashboardPage extends AngularDisposable implements IConfig
|
||||
|
||||
// Set panel actions
|
||||
let openedTabs = [...pinnedDashboardTabs, ...alwaysShowTabs];
|
||||
let addNewTabAction = this.instantiationService.createInstance(AddFeatureTabAction, allTabs, openedTabs, this.dashboardService.getUnderlyingUri());
|
||||
this._tabsDispose.push(addNewTabAction);
|
||||
this.panelActions = [addNewTabAction];
|
||||
if (extensionTabsEnabled) {
|
||||
let addNewTabAction = this.instantiationService.createInstance(AddFeatureTabAction, allTabs, openedTabs, this.dashboardService.getUnderlyingUri());
|
||||
this._tabsDispose.push(addNewTabAction);
|
||||
this.panelActions = [addNewTabAction];
|
||||
} else {
|
||||
this.panelActions = [];
|
||||
}
|
||||
this._cd.detectChanges();
|
||||
|
||||
this._tabsDispose.push(this.dashboardService.onPinUnpinTab(e => {
|
||||
|
||||
@@ -18,6 +18,7 @@ import * as nls from 'vs/nls';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
export class DatabaseDashboardPage extends DashboardPage implements OnInit {
|
||||
protected propertiesWidget: WidgetConfig = {
|
||||
@@ -43,9 +44,10 @@ export class DatabaseDashboardPage extends DashboardPage implements OnInit {
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||
@Inject(IInstantiationService) instantiationService: IInstantiationService,
|
||||
@Inject(INotificationService) notificationService: INotificationService,
|
||||
@Inject(IAngularEventingService) angularEventingService: IAngularEventingService
|
||||
@Inject(IAngularEventingService) angularEventingService: IAngularEventingService,
|
||||
@Inject(IConfigurationService) configurationService: IConfigurationService
|
||||
) {
|
||||
super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService);
|
||||
super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService, configurationService);
|
||||
this._register(dashboardService.onUpdatePage(() => {
|
||||
this.refresh(true);
|
||||
this._cd.detectChanges();
|
||||
|
||||
@@ -18,6 +18,7 @@ import * as nls from 'vs/nls';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
export class ServerDashboardPage extends DashboardPage implements OnInit {
|
||||
protected propertiesWidget: WidgetConfig = {
|
||||
@@ -44,9 +45,10 @@ export class ServerDashboardPage extends DashboardPage implements OnInit {
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||
@Inject(IInstantiationService) instantiationService: IInstantiationService,
|
||||
@Inject(INotificationService) notificationService: INotificationService,
|
||||
@Inject(IAngularEventingService) angularEventingService: IAngularEventingService
|
||||
@Inject(IAngularEventingService) angularEventingService: IAngularEventingService,
|
||||
@Inject(IConfigurationService) configurationService: IConfigurationService
|
||||
) {
|
||||
super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService);
|
||||
super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService, configurationService);
|
||||
// revert back to default database
|
||||
this._letDashboardPromise = this.dashboardService.connectionManagementService.changeDatabase('master');
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import * as TelemetryUtils from 'sql/common/telemetryUtilities';
|
||||
import { IInsightsView, IInsightData } from 'sql/parts/dashboard/widgets/insights/interfaces';
|
||||
import { memoize, unmemoize } from 'sql/base/common/decorators';
|
||||
import { mixin } from 'sql/base/common/objects';
|
||||
import { LegendPosition, DataDirection, ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
|
||||
|
||||
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
@@ -21,29 +22,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
declare var Chart: any;
|
||||
|
||||
export enum ChartType {
|
||||
Bar = 'bar',
|
||||
Doughnut = 'doughnut',
|
||||
HorizontalBar = 'horizontalBar',
|
||||
Line = 'line',
|
||||
Pie = 'pie',
|
||||
TimeSeries = 'timeSeries',
|
||||
Scatter = 'scatter'
|
||||
}
|
||||
|
||||
export enum DataDirection {
|
||||
Vertical = 'vertical',
|
||||
Horizontal = 'horizontal'
|
||||
}
|
||||
|
||||
export enum LegendPosition {
|
||||
Top = 'top',
|
||||
Bottom = 'bottom',
|
||||
Left = 'left',
|
||||
Right = 'right',
|
||||
None = 'none'
|
||||
}
|
||||
|
||||
export function customMixin(destination: any, source: any, overwrite?: boolean): any {
|
||||
if (types.isObject(source)) {
|
||||
mixin(destination, source, overwrite, customMixin);
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export enum ChartType {
|
||||
Bar = 'bar',
|
||||
Doughnut = 'doughnut',
|
||||
HorizontalBar = 'horizontalBar',
|
||||
Line = 'line',
|
||||
Pie = 'pie',
|
||||
TimeSeries = 'timeSeries',
|
||||
Scatter = 'scatter'
|
||||
}
|
||||
|
||||
export enum DataDirection {
|
||||
Vertical = 'vertical',
|
||||
Horizontal = 'horizontal'
|
||||
}
|
||||
|
||||
export enum LegendPosition {
|
||||
Top = 'top',
|
||||
Bottom = 'bottom',
|
||||
Left = 'left',
|
||||
Right = 'right',
|
||||
None = 'none'
|
||||
}
|
||||
|
||||
export enum DataType {
|
||||
Number = 'number',
|
||||
Point = 'point'
|
||||
}
|
||||
@@ -3,8 +3,9 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ChartInsight, ChartType, customMixin, IChartConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import { ChartInsight, customMixin, IChartConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import { mixin } from 'sql/base/common/objects';
|
||||
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
|
||||
|
||||
import { IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import PieChart from './pieChart.component';
|
||||
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
|
||||
|
||||
export default class DoughnutChart extends PieChart {
|
||||
protected readonly chartType: ChartType = ChartType.Doughnut;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import BarChart from './barChart.component';
|
||||
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
|
||||
|
||||
export default class HorizontalBarChart extends BarChart {
|
||||
protected readonly chartType: ChartType = ChartType.HorizontalBar;
|
||||
|
||||
@@ -3,16 +3,13 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ChartType, customMixin, defaultChartConfig, IDataSet, IPointDataSet } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
|
||||
import { defaultChartConfig, IDataSet, IPointDataSet } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import BarChart, { IBarChartConfig } from './barChart.component';
|
||||
import { memoize, unmemoize } from 'sql/base/common/decorators';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { clone } from 'sql/base/common/objects';
|
||||
|
||||
export enum DataType {
|
||||
Number = 'number',
|
||||
Point = 'point'
|
||||
}
|
||||
import { ChartType, DataType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
|
||||
|
||||
export interface ILineConfig extends IBarChartConfig {
|
||||
dataType?: DataType;
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ChartInsight, ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import { ChartInsight } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
|
||||
|
||||
export default class PieChart extends ChartInsight {
|
||||
protected readonly chartType: ChartType = ChartType.Pie;
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ChartType, defaultChartConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import { defaultChartConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import LineChart, { ILineConfig } from './lineChart.component';
|
||||
import { clone } from 'sql/base/common/objects';
|
||||
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
|
||||
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { clone } from 'sql/base/common/objects';
|
||||
|
||||
const defaultScatterConfig = mixin(clone(defaultChartConfig), { dataType: 'point', dataDirection: 'horizontal' }) as ILineConfig;
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { defaultChartConfig, IPointDataSet, ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import { defaultChartConfig, IPointDataSet } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import LineChart, { ILineConfig } from './lineChart.component';
|
||||
import { clone } from 'sql/base/common/objects';
|
||||
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
|
||||
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
|
||||
@@ -86,7 +86,7 @@ export class TasksWidget extends DashboardWidget implements IDashboardWidget, On
|
||||
}).filter(i => !!i);
|
||||
}
|
||||
|
||||
this._tasks = tasks.map(i => TaskRegistry.getCommandActionById(i)).filter(v => !!v);
|
||||
this._tasks = tasks.map(i => MenuRegistry.getCommand(i)).filter(v => !!v);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<div class="option check" #encryptCheckContainer>
|
||||
</div>
|
||||
<div class="option" #encryptWarningContainer>
|
||||
<div class="icon warning">
|
||||
<div class="sql icon warning">
|
||||
</div>
|
||||
<div class="warning-message">
|
||||
{{localizedStrings.NO_ENCRYPTOR_WARNING}}
|
||||
|
||||
@@ -221,7 +221,7 @@ export class BackupComponent {
|
||||
ariaLabel: LocalizedStrings.RECOVERY_MODEL
|
||||
});
|
||||
// Set backup type
|
||||
this.backupTypeSelectBox = new SelectBox([], '', this.contextViewService);
|
||||
this.backupTypeSelectBox = new SelectBox([], '', this.contextViewService, undefined, { ariaLabel: this.localizedStrings.BACKUP_TYPE });
|
||||
this.backupTypeSelectBox.render(this.backupTypeElement.nativeElement);
|
||||
|
||||
// Set copy-only check box
|
||||
@@ -283,13 +283,13 @@ export class BackupComponent {
|
||||
this.removePathButton.title = localize('removeFile', 'Remove files');
|
||||
|
||||
// Set compression
|
||||
this.compressionSelectBox = new SelectBox(this.compressionOptions, this.compressionOptions[0], this.contextViewService);
|
||||
this.compressionSelectBox = new SelectBox(this.compressionOptions, this.compressionOptions[0], this.contextViewService, undefined, { ariaLabel: this.localizedStrings.SET_BACKUP_COMPRESSION });
|
||||
this.compressionSelectBox.render(this.compressionElement.nativeElement);
|
||||
|
||||
// Set encryption
|
||||
this.algorithmSelectBox = new SelectBox(this.encryptionAlgorithms, this.encryptionAlgorithms[0], this.contextViewService);
|
||||
this.algorithmSelectBox = new SelectBox(this.encryptionAlgorithms, this.encryptionAlgorithms[0], this.contextViewService, undefined, { ariaLabel: this.localizedStrings.ALGORITHM });
|
||||
this.algorithmSelectBox.render(this.encryptionAlgorithmElement.nativeElement);
|
||||
this.encryptorSelectBox = new SelectBox([], '', this.contextViewService);
|
||||
this.encryptorSelectBox = new SelectBox([], '', this.contextViewService, undefined, { ariaLabel: this.localizedStrings.CERTIFICATE_OR_ASYMMETRIC_KEY });
|
||||
this.encryptorSelectBox.render(this.encryptorElement.nativeElement);
|
||||
|
||||
// Set media
|
||||
@@ -911,4 +911,4 @@ export class BackupComponent {
|
||||
|
||||
return backupInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -273,7 +273,7 @@ export class RestoreDialog extends Modal {
|
||||
labelContainer.hide();
|
||||
this._restorePlanData = new TableDataView<Slick.SlickData>();
|
||||
this._restorePlanTable = new Table<Slick.SlickData>(labelContainer.getHTMLElement(),
|
||||
{ dataProvider: this._restorePlanData, columns: this._restorePlanColumn }, { enableColumnReorder: false });
|
||||
{ dataProvider: this._restorePlanData, columns: this._restorePlanColumn }, { enableColumnReorder: false });
|
||||
this._restorePlanTable.setSelectionModel(new RowSelectionModel({ selectActiveRow: false }));
|
||||
this._restorePlanTable.onSelectedRowsChanged((e, data) => this.backupFileCheckboxChanged(e, data));
|
||||
});
|
||||
@@ -330,7 +330,7 @@ export class RestoreDialog extends Modal {
|
||||
}];
|
||||
this._fileListData = new TableDataView<FileListElement>();
|
||||
this._fileListTable = new Table<FileListElement>(fileNameContainer.getHTMLElement(),
|
||||
{ dataProvider : this._fileListData, columns } , { enableColumnReorder: false });
|
||||
{ dataProvider: this._fileListData, columns }, { enableColumnReorder: false });
|
||||
this._fileListTable.setSelectionModel(new RowSelectionModel());
|
||||
});
|
||||
});
|
||||
@@ -541,7 +541,7 @@ export class RestoreDialog extends Modal {
|
||||
});
|
||||
|
||||
inputContainer.div({ class: 'dialog-input' }, (inputCellContainer) => {
|
||||
selectBox = new SelectBox(options, selectedOption, this._contextViewService, inputCellContainer.getHTMLElement());
|
||||
selectBox = new SelectBox(options, selectedOption, this._contextViewService, inputCellContainer.getHTMLElement(), { ariaLabel: label });
|
||||
selectBox.render(inputCellContainer.getHTMLElement());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ classes should alter those!
|
||||
overflow: hidden;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
height: 16px;
|
||||
height: 28px;
|
||||
line-height: 16px;
|
||||
margin: 0;
|
||||
padding: 4px;
|
||||
@@ -35,7 +35,7 @@ classes should alter those!
|
||||
border-bottom: 2px solid #bbb;
|
||||
float: left;
|
||||
background-color: #eee;
|
||||
box-sizing: content-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.slick-headerrow-column.ui-state-default, .slick-footerrow-column.ui-state-default {
|
||||
@@ -104,6 +104,11 @@ classes should alter those!
|
||||
white-space: nowrap;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.slick-cell .grid-cell-value-container.missing-value {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.slick-cell, .slick-headerrow-column{
|
||||
border-bottom-color: silver;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) cd: ChangeDetectorRef,
|
||||
@Inject(IBootstrapParams) params: IEditDataComponentParams,
|
||||
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
|
||||
@Inject(INotificationService) private notificationService: INotificationService,
|
||||
@Inject(INotificationService) notificationService: INotificationService,
|
||||
@Inject(IContextMenuService) contextMenuService: IContextMenuService,
|
||||
@Inject(IKeybindingService) keybindingService: IKeybindingService,
|
||||
@Inject(IContextKeyService) contextKeyService: IContextKeyService,
|
||||
@@ -96,7 +96,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
|
||||
@Inject(IClipboardService) clipboardService: IClipboardService,
|
||||
@Inject(IQueryEditorService) queryEditorService: IQueryEditorService
|
||||
) {
|
||||
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService);
|
||||
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService, notificationService);
|
||||
this._el.nativeElement.className = 'slickgridContainer';
|
||||
this.dataService = params.dataService;
|
||||
this.actionProvider = this.instantiationService.createInstance(EditDataGridActionProvider, this.dataService, this.onGridSelectAll(), this.onDeleteRow(), this.onRevertRow());
|
||||
@@ -166,7 +166,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
|
||||
|
||||
this.onCellEditEnd = (event: Slick.OnCellChangeEventArgs<any>): void => {
|
||||
// Store the value that was set
|
||||
self.currentEditCellValue = event.item[event.cell - 1];
|
||||
self.currentEditCellValue = event.item[event.cell];
|
||||
};
|
||||
|
||||
this.overrideCellFn = (rowNumber, columnId, value?, data?): string => {
|
||||
@@ -270,18 +270,18 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
|
||||
|
||||
return self.dataService.updateCell(sessionRowId, self.currentCell.column - 1, self.currentEditCellValue)
|
||||
.then(
|
||||
result => {
|
||||
// Cell update was successful, update the flags
|
||||
self.currentEditCellValue = null;
|
||||
self.setCellDirtyState(row, self.currentCell.column, result.cell.isDirty);
|
||||
self.setRowDirtyState(row, result.isRowDirty);
|
||||
return Promise.resolve();
|
||||
},
|
||||
error => {
|
||||
// Cell update failed, jump back to the last cell we were on
|
||||
self.focusCell(self.currentCell.row, self.currentCell.column, true);
|
||||
return Promise.reject(null);
|
||||
}
|
||||
result => {
|
||||
// Cell update was successful, update the flags
|
||||
self.currentEditCellValue = null;
|
||||
self.setCellDirtyState(row, self.currentCell.column, result.cell.isDirty);
|
||||
self.setRowDirtyState(row, result.isRowDirty);
|
||||
return Promise.resolve();
|
||||
},
|
||||
error => {
|
||||
// Cell update failed, jump back to the last cell we were on
|
||||
self.focusCell(self.currentCell.row, self.currentCell.column, true);
|
||||
return Promise.reject(null);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -377,10 +377,11 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
|
||||
index => { return {}; }
|
||||
),
|
||||
columnDefinitions: [rowNumberColumn.getColumnDefinition()].concat(resultSet.columnInfo.map((c, i) => {
|
||||
let columnIndex = (i + 1).toString();
|
||||
return {
|
||||
id: i.toString(),
|
||||
id: columnIndex,
|
||||
name: escape(c.columnName),
|
||||
field: i.toString(),
|
||||
field: columnIndex,
|
||||
formatter: Services.textFormatter,
|
||||
isEditable: c.isUpdatable
|
||||
};
|
||||
@@ -464,7 +465,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
|
||||
} else {
|
||||
try {
|
||||
// Perform a revert row operation
|
||||
if (this.currentCell) {
|
||||
if (this.currentCell && this.currentCell.row !== undefined && this.currentCell.row !== null) {
|
||||
await this.dataService.revertRow(this.currentCell.row);
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -37,6 +37,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
export abstract class GridParentComponent {
|
||||
// CONSTANTS
|
||||
@@ -100,7 +101,8 @@ export abstract class GridParentComponent {
|
||||
protected contextKeyService: IContextKeyService,
|
||||
protected configurationService: IConfigurationService,
|
||||
protected clipboardService: IClipboardService,
|
||||
protected queryEditorService: IQueryEditorService
|
||||
protected queryEditorService: IQueryEditorService,
|
||||
protected notificationService: INotificationService
|
||||
) {
|
||||
this.toDispose = [];
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import { IGridDataSet } from 'sql/parts/grid/common/interfaces';
|
||||
import { IInsightData, IInsightsView, IInsightsConfig } from 'sql/parts/dashboard/widgets/insights/interfaces';
|
||||
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
||||
import { QueryEditor } from 'sql/parts/query/editor/queryEditor';
|
||||
import { DataType, ILineConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/types/lineChart.component';
|
||||
import { ILineConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/types/lineChart.component';
|
||||
import * as PathUtilities from 'sql/common/pathUtilities';
|
||||
import { IChartViewActionContext, CopyAction, CreateInsightAction, SaveImageAction } from 'sql/parts/grid/views/query/chartViewerActions';
|
||||
import * as WorkbenchUtils from 'sql/workbench/common/sqlWorkbenchUtils';
|
||||
@@ -24,10 +24,11 @@ import * as Constants from 'sql/parts/query/common/constants';
|
||||
import { SelectBox as AngularSelectBox } from 'sql/base/browser/ui/selectBox/selectBox.component';
|
||||
import { IQueryModelService } from 'sql/parts/query/execution/queryModel';
|
||||
import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService';
|
||||
import { LegendPosition, DataDirection, DataType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
|
||||
|
||||
/* Insights */
|
||||
import {
|
||||
ChartInsight, DataDirection, LegendPosition
|
||||
ChartInsight
|
||||
} from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
@@ -42,6 +42,8 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
export const QUERY_SELECTOR: string = 'query-component';
|
||||
|
||||
@@ -126,7 +128,9 @@ export class QueryComponent extends GridParentComponent implements OnInit, OnDes
|
||||
}
|
||||
},
|
||||
{
|
||||
showCondition: () => { return true; },
|
||||
showCondition: () => {
|
||||
return this.configurationService.getValue('workbench')['enablePreviewFeatures'];
|
||||
},
|
||||
icon: () => { return 'viewChart'; },
|
||||
hoverText: () => { return LocalizedConstants.viewChartLabel; },
|
||||
functionality: (batchId, resultId, index) => {
|
||||
@@ -187,9 +191,10 @@ export class QueryComponent extends GridParentComponent implements OnInit, OnDes
|
||||
@Inject(IContextKeyService) contextKeyService: IContextKeyService,
|
||||
@Inject(IConfigurationService) configurationService: IConfigurationService,
|
||||
@Inject(IClipboardService) clipboardService: IClipboardService,
|
||||
@Inject(IQueryEditorService) queryEditorService: IQueryEditorService
|
||||
@Inject(IQueryEditorService) queryEditorService: IQueryEditorService,
|
||||
@Inject(INotificationService) notificationService: INotificationService,
|
||||
) {
|
||||
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService);
|
||||
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService, notificationService);
|
||||
this._el.nativeElement.className = 'slickgridContainer';
|
||||
this.rowHeight = configurationService.getValue<any>('resultsGrid').rowHeight;
|
||||
configurationService.onDidChangeConfiguration(e => {
|
||||
|
||||
@@ -188,8 +188,16 @@ export class InsightsDialogView extends Modal {
|
||||
for (let i = 0; i < this._model.columns.length; i++) {
|
||||
resourceArray.push({ label: this._model.columns[i], value: element.data[i], data: element.data });
|
||||
}
|
||||
|
||||
this._bottomTableData.clear();
|
||||
this._bottomTableData.push(resourceArray);
|
||||
// this table view has to be collapsed and expanded
|
||||
// because the initial expand doesn't have the
|
||||
// loaded data
|
||||
if (bottomTableView.isExpanded()) {
|
||||
bottomTableView.collapse();
|
||||
bottomTableView.expand();
|
||||
}
|
||||
this._enableTaskButtons(true);
|
||||
} else {
|
||||
this._enableTaskButtons(false);
|
||||
@@ -334,6 +342,7 @@ export class InsightsDialogView extends Modal {
|
||||
this.hide();
|
||||
dispose(this._taskButtonDisposables);
|
||||
this._taskButtonDisposables = [];
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
protected onClose(e: StandardKeyboardEvent) {
|
||||
|
||||
@@ -13,11 +13,11 @@ import * as sqlops from 'sqlops';
|
||||
import { ComponentWithIconBase } from 'sql/parts/modelComponents/componentWithIconBase';
|
||||
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
|
||||
import { attachButtonStyler } from 'sql/common/theme/styler';
|
||||
import { Button } from 'sql/base/browser/ui/button/button';
|
||||
|
||||
import { SIDE_BAR_BACKGROUND, SIDE_BAR_TITLE_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { focusBorder, foreground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { Button } from 'sql/base/browser/ui/button/button';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
|
||||
|
||||
@@ -42,9 +42,10 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
|
||||
@ViewChild('fileInput', { read: ElementRef }) private _fileInputContainer: ElementRef;
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||
) {
|
||||
super(changeRef);
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -63,7 +64,7 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
|
||||
if (this._fileInputContainer) {
|
||||
const self = this;
|
||||
this._fileInputContainer.nativeElement.onchange = () => {
|
||||
let file = self._fileInputContainer.nativeElement.files[0];
|
||||
let file = self._fileInputContainer.nativeElement.files[0];
|
||||
let reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
let text = (<FileReader>e.target).result;
|
||||
@@ -100,6 +101,7 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
|
||||
super.setProperties(properties);
|
||||
this._button.enabled = this.enabled;
|
||||
this._button.label = this.label;
|
||||
this._button.title = this.title;
|
||||
if (this.width) {
|
||||
this._button.setWidth(this.convertSize(this.width.toString()));
|
||||
}
|
||||
@@ -153,7 +155,7 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
|
||||
this.setPropertyFromUI<sqlops.ButtonProperties, string>(this.setFileContentProperties, newValue);
|
||||
}
|
||||
|
||||
private setFileContentProperties(properties: sqlops.ButtonProperties, fileContent: string) : void {
|
||||
private setFileContentProperties(properties: sqlops.ButtonProperties, fileContent: string): void {
|
||||
properties.fileContent = fileContent;
|
||||
}
|
||||
|
||||
@@ -164,4 +166,13 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
|
||||
private setFileProperties(properties: sqlops.ButtonProperties, isFile: boolean): void {
|
||||
properties.isFile = isFile;
|
||||
}
|
||||
|
||||
private get title(): string {
|
||||
return this.getPropertyOrDefault<sqlops.ButtonProperties, string>((props) => props.title, '');
|
||||
}
|
||||
|
||||
private set title(newValue: string) {
|
||||
this.setPropertyFromUI<sqlops.ButtonProperties, string>((properties, title) => { properties.title = title; }, newValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'vs/css!./card';
|
||||
|
||||
import { Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver,
|
||||
import {
|
||||
Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver,
|
||||
ViewChild, ViewChildren, ElementRef, Injector, OnDestroy, QueryList,
|
||||
} from '@angular/core';
|
||||
|
||||
@@ -28,11 +29,11 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
|
||||
|
||||
private backgroundColor: string;
|
||||
|
||||
constructor(@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||
constructor( @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService
|
||||
) {
|
||||
super(changeRef);
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -70,7 +71,7 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
|
||||
|
||||
public getClass(): string {
|
||||
return (this.selectable && this.selected || this._hasFocus) ? 'model-card selected' :
|
||||
'model-card unselected';
|
||||
'model-card unselected';
|
||||
}
|
||||
|
||||
public onCardHoverChanged(event: any) {
|
||||
@@ -81,7 +82,7 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
|
||||
}
|
||||
/// IComponent implementation
|
||||
|
||||
public setLayout (layout: any): void {
|
||||
public setLayout(layout: any): void {
|
||||
// TODO allow configuring the look and feel
|
||||
this.layout();
|
||||
}
|
||||
@@ -141,7 +142,7 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
|
||||
|
||||
public get statusColor(): string {
|
||||
let status = this.getPropertyOrDefault<CardProperties, StatusIndicator>((props) => props.status, StatusIndicator.None);
|
||||
switch(status) {
|
||||
switch (status) {
|
||||
case StatusIndicator.Ok:
|
||||
return 'green';
|
||||
case StatusIndicator.Warning:
|
||||
|
||||
@@ -29,8 +29,9 @@ export default class CheckBoxComponent extends ComponentBase implements ICompone
|
||||
@ViewChild('input', { read: ElementRef }) private _inputContainer: ElementRef;
|
||||
constructor(
|
||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
||||
super(changeRef);
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
@@ -19,6 +19,7 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ModelComponentWrapper } from 'sql/parts/modelComponents/modelComponentWrapper.component';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { Builder } from 'vs/base/browser/builder';
|
||||
import { IdGenerator } from 'vs/base/common/idGenerator';
|
||||
import { createCSSRule, removeCSSRulesContainingSelector } from 'vs/base/browser/dom';
|
||||
import * as nls from 'vs/nls';
|
||||
@@ -35,8 +36,11 @@ export abstract class ComponentBase extends Disposable implements IComponent, On
|
||||
private _valid: boolean = true;
|
||||
protected _validations: (() => boolean | Thenable<boolean>)[] = [];
|
||||
private _eventQueue: IComponentEventArgs[] = [];
|
||||
private _CSSStyles: { [key: string]: string } = {};
|
||||
|
||||
constructor(
|
||||
protected _changeRef: ChangeDetectorRef) {
|
||||
protected _changeRef: ChangeDetectorRef,
|
||||
protected _el: ElementRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -80,11 +84,20 @@ export abstract class ComponentBase extends Disposable implements IComponent, On
|
||||
public refreshDataProvider(item: any): void {
|
||||
}
|
||||
|
||||
public updateStyles() {
|
||||
let element = new Builder(this._el.nativeElement);
|
||||
this._CSSStyles = this.CSSStyles;
|
||||
element.style(this._CSSStyles);
|
||||
}
|
||||
|
||||
public setProperties(properties: { [key: string]: any; }): void {
|
||||
if (!properties) {
|
||||
this.properties = {};
|
||||
}
|
||||
this.properties = properties;
|
||||
if (this.CSSStyles !== this._CSSStyles) {
|
||||
this.updateStyles();
|
||||
}
|
||||
this.layout();
|
||||
this.validate();
|
||||
}
|
||||
@@ -140,11 +153,19 @@ export abstract class ComponentBase extends Disposable implements IComponent, On
|
||||
}
|
||||
|
||||
public get position(): string {
|
||||
return this.getPropertyOrDefault<sqlops.EditorProperties, string>((props) => props.position, '');
|
||||
return this.getPropertyOrDefault<sqlops.ComponentProperties, string>((props) => props.position, '');
|
||||
}
|
||||
|
||||
public set position(newValue: string) {
|
||||
this.setPropertyFromUI<sqlops.EditorProperties, string>((properties, position) => { properties.position = position; }, newValue);
|
||||
this.setPropertyFromUI<sqlops.ComponentProperties, string>((properties, position) => { properties.position = position; }, newValue);
|
||||
}
|
||||
|
||||
public get CSSStyles(): { [key: string]: string } {
|
||||
return this.getPropertyOrDefault<sqlops.ComponentProperties, { [key: string]: string }>((props) => props.CSSStyles, {});
|
||||
}
|
||||
|
||||
public set CSSStyles(newValue: { [key: string]: string }) {
|
||||
this.setPropertyFromUI<sqlops.ComponentProperties, { [key: string]: string }>((properties, CSSStyles) => { properties.CSSStyles = CSSStyles; }, newValue);
|
||||
}
|
||||
|
||||
public convertSizeToNumber(size: number | string): number {
|
||||
@@ -223,9 +244,10 @@ export abstract class ContainerBase<T> extends ComponentBase {
|
||||
|
||||
@ViewChildren(ModelComponentWrapper) protected _componentWrappers: QueryList<ModelComponentWrapper>;
|
||||
constructor(
|
||||
_changeRef: ChangeDetectorRef
|
||||
_changeRef: ChangeDetectorRef,
|
||||
_el: ElementRef
|
||||
) {
|
||||
super(_changeRef);
|
||||
super(_changeRef, _el);
|
||||
this.items = [];
|
||||
this._validations.push(() => this.items.every(item => {
|
||||
return this.modelStore.getComponent(item.descriptor.id).valid;
|
||||
@@ -239,7 +261,7 @@ export abstract class ContainerBase<T> extends ComponentBase {
|
||||
}
|
||||
if (index !== undefined && index !== null && index >= 0 && index < this.items.length) {
|
||||
this.items.splice(index, 0, new ItemDescriptor(componentDescriptor, config));
|
||||
} else if(!index) {
|
||||
} else if (!index) {
|
||||
this.items.push(new ItemDescriptor(componentDescriptor, config));
|
||||
} else {
|
||||
throw new Error(nls.localize('invalidIndex', 'The index is invalid.'));
|
||||
|
||||
@@ -22,13 +22,16 @@ export class ItemDescriptor<T> {
|
||||
constructor(public descriptor: IComponentDescriptor, public config: T) { }
|
||||
}
|
||||
|
||||
const ids = new IdGenerator('model-view-component-icon-');
|
||||
|
||||
export abstract class ComponentWithIconBase extends ComponentBase {
|
||||
|
||||
protected _iconClass: string;
|
||||
protected _iconPath: IUserFriendlyIcon;
|
||||
constructor(
|
||||
changeRef: ChangeDetectorRef) {
|
||||
super(changeRef);
|
||||
changeRef: ChangeDetectorRef,
|
||||
el: ElementRef, ) {
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
/// IComponent implementation
|
||||
@@ -41,7 +44,6 @@ export abstract class ComponentWithIconBase extends ComponentBase {
|
||||
if (this.iconPath && this.iconPath !== this._iconPath) {
|
||||
this._iconPath = this.iconPath;
|
||||
if (!this._iconClass) {
|
||||
const ids = new IdGenerator('model-view-component-icon-' + Math.round(Math.random() * 1000));
|
||||
this._iconClass = ids.nextId();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import DivContainer from './divContainer.component';
|
||||
import FlexContainer from './flexContainer.component';
|
||||
import FormContainer from './formContainer.component';
|
||||
import ToolbarContainer from './toolbarContainer.component';
|
||||
@@ -22,9 +22,13 @@ import TextComponent from './text.component';
|
||||
import LoadingComponent from './loadingComponent.component';
|
||||
import FileBrowserTreeComponent from './fileBrowserTree.component';
|
||||
import EditorComponent from './editor.component';
|
||||
import DomComponent from './dom.component';
|
||||
import { registerComponentType } from 'sql/platform/dashboard/common/modelComponentRegistry';
|
||||
import { ModelComponentTypes } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
|
||||
export const DIV_CONTAINER = 'div-container';
|
||||
registerComponentType(DIV_CONTAINER, ModelComponentTypes.DivContainer, DivContainer);
|
||||
|
||||
export const FLEX_CONTAINER = 'flex-container';
|
||||
registerComponentType(FLEX_CONTAINER, ModelComponentTypes.FlexContainer, FlexContainer);
|
||||
|
||||
@@ -82,3 +86,6 @@ registerComponentType(FILEBROWSERTREE_COMPONENT, ModelComponentTypes.FileBrowser
|
||||
|
||||
export const EDITOR_COMPONENT = 'editor-component';
|
||||
registerComponentType(EDITOR_COMPONENT, ModelComponentTypes.Editor, EditorComponent);
|
||||
|
||||
export const DOM_COMPONENT = 'dom-component';
|
||||
registerComponentType(DOM_COMPONENT, ModelComponentTypes.Dom, DomComponent);
|
||||
|
||||
@@ -64,9 +64,10 @@ export default class DeclarativeTableComponent extends ComponentBase implements
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||
@Inject(IContextViewService) private contextViewService: IContextViewService
|
||||
@Inject(IContextViewService) private contextViewService: IContextViewService,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||
) {
|
||||
super(changeRef);
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -134,7 +135,7 @@ export default class DeclarativeTableComponent extends ComponentBase implements
|
||||
private onCellDataChanged(newValue: any, row: number, cell: number): void {
|
||||
this.data[row][cell] = newValue;
|
||||
this.data = this.data;
|
||||
let newCellData : sqlops.TableCell = {
|
||||
let newCellData: sqlops.TableCell = {
|
||||
row: row,
|
||||
column: cell,
|
||||
value: newValue
|
||||
|
||||
120
src/sql/parts/modelComponents/divContainer.component.ts
Normal file
120
src/sql/parts/modelComponents/divContainer.component.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'vs/css!./divContainer';
|
||||
|
||||
import {
|
||||
Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver,
|
||||
ViewChild, ViewChildren, ElementRef, Injector, OnDestroy, QueryList,
|
||||
} from '@angular/core';
|
||||
|
||||
import { IComponent, IComponentDescriptor, IModelStore } from 'sql/parts/modelComponents/interfaces';
|
||||
import * as sqlops from 'sqlops';
|
||||
|
||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||
import { ContainerBase } from 'sql/parts/modelComponents/componentBase';
|
||||
import { ModelComponentWrapper } from 'sql/parts/modelComponents/modelComponentWrapper.component';
|
||||
|
||||
import types = require('vs/base/common/types');
|
||||
|
||||
class DivItem {
|
||||
constructor(public descriptor: IComponentDescriptor, public config: sqlops.DivItemLayout) { }
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<div #divContainer *ngIf="items" class="divContainer" [style.height]="height" [style.width]="width">
|
||||
<div *ngFor="let item of items" [style.order]="getItemOrder(item)" [ngStyle]="getItemStyles(item)">
|
||||
<model-component-wrapper [descriptor]="item.descriptor" [modelStore]="modelStore">
|
||||
</model-component-wrapper>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export default class DivContainer extends ContainerBase<sqlops.DivItemLayout> implements IComponent, OnDestroy {
|
||||
@Input() descriptor: IComponentDescriptor;
|
||||
@Input() modelStore: IModelStore;
|
||||
@ViewChild('divContainer', { read: ElementRef }) divContainer;
|
||||
private _height: string;
|
||||
private _width: string;
|
||||
private _overflowY: string;
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||
) {
|
||||
super(changeRef, el);
|
||||
this._overflowY = ''; // default
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.baseInit();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.baseDestroy();
|
||||
}
|
||||
|
||||
|
||||
/// IComponent implementation
|
||||
|
||||
public setLayout(layout: sqlops.DivLayout): void {
|
||||
this._height = this.convertSize(layout.height);
|
||||
this._width = this.convertSize(layout.width);
|
||||
this.layout();
|
||||
}
|
||||
|
||||
public setProperties(properties: { [key: string]: any; }): void {
|
||||
super.setProperties(properties);
|
||||
if (this.overflowY !== this._overflowY) {
|
||||
this.updateOverflowY();
|
||||
}
|
||||
this.updateScroll();
|
||||
}
|
||||
|
||||
private updateOverflowY() {
|
||||
this._overflowY = this.overflowY;
|
||||
if (this._overflowY) {
|
||||
let element = <HTMLElement> this.divContainer.nativeElement;
|
||||
element.style.overflowY = this._overflowY;
|
||||
}
|
||||
}
|
||||
|
||||
private updateScroll() {
|
||||
let element = <HTMLElement> this.divContainer.nativeElement;
|
||||
element.scrollTop = element.scrollTop - this.yOffsetChange;
|
||||
element.dispatchEvent(new Event('scroll'));
|
||||
}
|
||||
|
||||
// CSS-bound properties
|
||||
public get height(): string {
|
||||
return this._height;
|
||||
}
|
||||
|
||||
public get width(): string {
|
||||
return this._width;
|
||||
}
|
||||
|
||||
// CSS-bound properties
|
||||
public get overflowY(): string {
|
||||
return this.getPropertyOrDefault<sqlops.DivContainerProperties, any>((props) => props.overflowY, '');
|
||||
}
|
||||
public set overflowY(newValue: string) {
|
||||
this.setPropertyFromUI<sqlops.DivContainerProperties, any>((properties, newValue) => { properties.overflowY = newValue; }, newValue);
|
||||
}
|
||||
|
||||
public get yOffsetChange(): number {
|
||||
return this.getPropertyOrDefault<sqlops.DivContainerProperties, any>((props) => props.yOffsetChange, 0);
|
||||
}
|
||||
public set yOffsetChange(newValue: number) {
|
||||
this.setPropertyFromUI<sqlops.DivContainerProperties, any>((properties, newValue) => { properties.yOffsetChange = newValue; }, newValue);
|
||||
}
|
||||
|
||||
private getItemOrder(item: DivItem): number {
|
||||
return item.config ? item.config.order : 0;
|
||||
}
|
||||
private getItemStyles(item: DivItem): { [key: string]: string } {
|
||||
return item.config && item.config.CSSStyles ? item.config.CSSStyles : {};
|
||||
}
|
||||
}
|
||||
5
src/sql/parts/modelComponents/divContainer.css
Normal file
5
src/sql/parts/modelComponents/divContainer.css
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
.divContainer {
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
92
src/sql/parts/modelComponents/dom.component.ts
Normal file
92
src/sql/parts/modelComponents/dom.component.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'vs/css!./dom';
|
||||
import 'vs/css!./highlight';
|
||||
import 'vs/css!./markdown';
|
||||
import {
|
||||
Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver,
|
||||
ViewChild, ViewChildren, ElementRef, Injector, OnDestroy, QueryList
|
||||
} from '@angular/core';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { $, Builder } from 'vs/base/browser/builder';
|
||||
|
||||
import { ComponentBase } from 'sql/parts/modelComponents/componentBase';
|
||||
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
|
||||
|
||||
@Component({
|
||||
template: '',
|
||||
selector: 'modelview-dom-component'
|
||||
})
|
||||
export default class DomComponent extends ComponentBase implements IComponent, OnDestroy {
|
||||
@Input() descriptor: IComponentDescriptor;
|
||||
@Input() modelStore: IModelStore;
|
||||
private _renderedHtml: string;
|
||||
private _rootElement: Builder;
|
||||
private _bodyElement: Builder;
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||
) {
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.baseInit();
|
||||
this.createDomElement();
|
||||
this._register(DOM.addDisposableListener(window, DOM.EventType.RESIZE, e => {
|
||||
this.layout();
|
||||
}));
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.baseDestroy();
|
||||
}
|
||||
|
||||
private createDomElement() {
|
||||
this._rootElement = new Builder(this._el.nativeElement);
|
||||
this._bodyElement = $('.dom-body');
|
||||
this._rootElement.append(this._bodyElement);
|
||||
}
|
||||
|
||||
/// Dom Functions
|
||||
private setHtml(): void {
|
||||
if (this.html) {
|
||||
this._renderedHtml = this.html;
|
||||
this._bodyElement.innerHtml(this._renderedHtml);
|
||||
}
|
||||
}
|
||||
|
||||
/// IComponent implementation
|
||||
public layout(): void {
|
||||
super.layout();
|
||||
let element = <HTMLElement>this._el.nativeElement;
|
||||
element.style.width = this.getWidth();
|
||||
element.style.height = this.getHeight();
|
||||
}
|
||||
|
||||
public setLayout(layout: any): void {
|
||||
// TODO allow configuring the look and feel
|
||||
this.layout();
|
||||
}
|
||||
|
||||
public setProperties(properties: { [key: string]: any; }): void {
|
||||
super.setProperties(properties);
|
||||
if (this.html !== this._renderedHtml) {
|
||||
this.setHtml();
|
||||
}
|
||||
}
|
||||
|
||||
// CSS-bound properties
|
||||
public get html(): string {
|
||||
return this.getPropertyOrDefault<sqlops.DomProperties, string>((props) => props.html, '');
|
||||
}
|
||||
|
||||
public set html(newValue: string) {
|
||||
this.setPropertyFromUI<sqlops.DomProperties, string>((properties, html) => { properties.html = html; }, newValue);
|
||||
}
|
||||
}
|
||||
9
src/sql/parts/modelComponents/dom.css
Normal file
9
src/sql/parts/modelComponents/dom.css
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.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
modelview-dom-component {
|
||||
display: block;
|
||||
-webkit-user-select: text;
|
||||
}
|
||||
@@ -41,9 +41,10 @@ export default class DropDownComponent extends ComponentBase implements ICompone
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||
@Inject(IContextViewService) private contextViewService: IContextViewService
|
||||
@Inject(IContextViewService) private contextViewService: IContextViewService,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||
) {
|
||||
super(changeRef);
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
@@ -41,12 +41,12 @@ export default class EditorComponent extends ComponentBase implements IComponent
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
|
||||
@Inject(IModelService) private _modelService: IModelService,
|
||||
@Inject(IModeService) private _modeService: IModeService
|
||||
) {
|
||||
super(changeRef);
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -63,7 +63,7 @@ export default class EditorComponent extends ComponentBase implements IComponent
|
||||
this._editor.create(this._el.nativeElement);
|
||||
this._editor.setVisible(true);
|
||||
let uri = this.createUri();
|
||||
this._editorInput = instantiationService.createInstance(UntitledEditorInput, uri, false, 'sql', '', '');
|
||||
this._editorInput = instantiationService.createInstance(UntitledEditorInput, uri, false, 'plaintext', '', '');
|
||||
this._editor.setInput(this._editorInput, undefined);
|
||||
this._editorInput.resolve().then(model => {
|
||||
this._editorModel = model.textEditorModel;
|
||||
@@ -107,7 +107,7 @@ export default class EditorComponent extends ComponentBase implements IComponent
|
||||
this._editor.layout(new DOM.Dimension(
|
||||
width && width > 0 ? width : DOM.getContentWidth(this._el.nativeElement),
|
||||
height && height > 0 ? height : DOM.getContentHeight(this._el.nativeElement)));
|
||||
let element = <HTMLElement> this._el.nativeElement;
|
||||
let element = <HTMLElement>this._el.nativeElement;
|
||||
element.style.position = this.position;
|
||||
}
|
||||
|
||||
@@ -129,7 +129,6 @@ export default class EditorComponent extends ComponentBase implements IComponent
|
||||
}
|
||||
|
||||
/// IComponent implementation
|
||||
|
||||
public setLayout(layout: any): void {
|
||||
// TODO allow configuring the look and feel
|
||||
this.layout();
|
||||
|
||||
@@ -27,15 +27,16 @@ export default class FileBrowserTreeComponent extends ComponentBase implements I
|
||||
@Input() modelStore: IModelStore;
|
||||
private _treeView: FileBrowserTreeView;
|
||||
private _viewModel: FileBrowserViewModel;
|
||||
private _fileFilters: [{label: string, filters: string[]}] = [
|
||||
private _fileFilters: [{ label: string, filters: string[] }] = [
|
||||
{ label: 'All Files', filters: ['*'] }
|
||||
];
|
||||
|
||||
@ViewChild('fileBrowserTree', { read: ElementRef }) private _treeContainer: ElementRef;
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(IInstantiationService) private _instantiationService: IInstantiationService) {
|
||||
super(changeRef);
|
||||
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
@@ -45,8 +45,11 @@ export default class FlexContainer extends ContainerBase<FlexItemLayout> impleme
|
||||
private _width: string;
|
||||
private _position: string;
|
||||
|
||||
constructor(@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
||||
super(changeRef);
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||
) {
|
||||
super(changeRef, el);
|
||||
this._flexFlow = ''; // default
|
||||
this._justifyContent = ''; // default
|
||||
}
|
||||
|
||||
@@ -106,8 +106,9 @@ export default class FormContainer extends ContainerBase<FormItemLayout> impleme
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
||||
super(changeRef);
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
@@ -45,8 +45,9 @@ export default class GroupContainer extends ContainerBase<GroupLayout> implement
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
||||
super(changeRef);
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
183
src/sql/parts/modelComponents/highlight.css
Normal file
183
src/sql/parts/modelComponents/highlight.css
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
https://raw.githubusercontent.com/isagalaev/highlight.js/master/src/styles/vs2015.css
|
||||
*/
|
||||
/*
|
||||
* Visual Studio 2015 dark style
|
||||
* Author: Nicolas LLOBERA <nllobera@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
modelview-dom-component .hljs-keyword,
|
||||
modelview-dom-component .hljs-literal,
|
||||
modelview-dom-component .hljs-symbol,
|
||||
modelview-dom-component .hljs-name {
|
||||
color: #569CD6;
|
||||
}
|
||||
modelview-dom-component .hljs-link {
|
||||
color: #569CD6;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-built_in,
|
||||
modelview-dom-component .hljs-type {
|
||||
color: #4EC9B0;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-number,
|
||||
modelview-dom-component .hljs-class {
|
||||
color: #B8D7A3;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-string,
|
||||
modelview-dom-component .hljs-meta-string {
|
||||
color: #D69D85;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-regexp,
|
||||
modelview-dom-component .hljs-template-tag {
|
||||
color: #9A5334;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-subst,
|
||||
modelview-dom-component .hljs-function,
|
||||
modelview-dom-component .hljs-title,
|
||||
modelview-dom-component .hljs-params,
|
||||
modelview-dom-component .hljs-formula {
|
||||
color: #DCDCDC;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-comment,
|
||||
modelview-dom-component .hljs-quote {
|
||||
color: #57A64A;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-doctag {
|
||||
color: #608B4E;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-meta,
|
||||
modelview-dom-component .hljs-meta-keyword,
|
||||
modelview-dom-component .hljs-tag {
|
||||
color: #9B9B9B;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-variable,
|
||||
modelview-dom-component .hljs-template-variable {
|
||||
color: #BD63C5;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-attr,
|
||||
modelview-dom-component .hljs-attribute,
|
||||
modelview-dom-component .hljs-builtin-name {
|
||||
color: #9CDCFE;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-section {
|
||||
color: gold;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*.hljs-code {
|
||||
font-family:'Monospace';
|
||||
}*/
|
||||
|
||||
modelview-dom-component .hljs-bullet,
|
||||
modelview-dom-component .hljs-selector-tag,
|
||||
modelview-dom-component .hljs-selector-id,
|
||||
modelview-dom-component .hljs-selector-class,
|
||||
modelview-dom-component .hljs-selector-attr,
|
||||
modelview-dom-component .hljs-selector-pseudo {
|
||||
color: #D7BA7D;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-addition {
|
||||
background-color: #144212;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
modelview-dom-component .hljs-deletion {
|
||||
background-color: #600;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
From https://raw.githubusercontent.com/isagalaev/highlight.js/master/src/styles/vs.css
|
||||
*/
|
||||
/*
|
||||
|
||||
Visual Studio-like style based on original C# coloring by Jason Diamond <jason@diamond.name>
|
||||
|
||||
*/
|
||||
/*
|
||||
.vscode-light .hljs-function,
|
||||
.vscode-light .hljs-params {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.vscode-light .hljs-comment,
|
||||
.vscode-light .hljs-quote,
|
||||
.vscode-light .hljs-variable {
|
||||
color: #008000;
|
||||
}
|
||||
|
||||
.vscode-light .hljs-keyword,
|
||||
.vscode-light .hljs-selector-tag,
|
||||
.vscode-light .hljs-built_in,
|
||||
.vscode-light .hljs-name,
|
||||
.vscode-light .hljs-tag {
|
||||
color: #00f;
|
||||
}
|
||||
|
||||
.vscode-light .hljs-string,
|
||||
.vscode-light .hljs-title,
|
||||
.vscode-light .hljs-section,
|
||||
.vscode-light .hljs-attribute,
|
||||
.vscode-light .hljs-literal,
|
||||
.vscode-light .hljs-template-tag,
|
||||
.vscode-light .hljs-template-variable,
|
||||
.vscode-light .hljs-type,
|
||||
.vscode-light .hljs-addition {
|
||||
color: #a31515;
|
||||
}
|
||||
|
||||
.vscode-light .hljs-deletion,
|
||||
.vscode-light .hljs-selector-attr,
|
||||
.vscode-light .hljs-selector-pseudo,
|
||||
.vscode-light .hljs-meta {
|
||||
color: #2b91af;
|
||||
}
|
||||
|
||||
.vscode-light .hljs-doctag {
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
.vscode-light .hljs-attr {
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
.vscode-light .hljs-symbol,
|
||||
.vscode-light .hljs-bullet,
|
||||
.vscode-light .hljs-link {
|
||||
color: #00b0e8;
|
||||
}
|
||||
|
||||
|
||||
.vscode-light .hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.vscode-light .hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
*/
|
||||
@@ -42,9 +42,10 @@ export default class InputBoxComponent extends ComponentBase implements ICompone
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||
@Inject(IContextViewService) private contextViewService: IContextViewService
|
||||
@Inject(IContextViewService) private contextViewService: IContextViewService,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||
) {
|
||||
super(changeRef);
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
@@ -37,9 +37,10 @@ export default class ListBoxComponent extends ComponentBase implements IComponen
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||
@Inject(IContextViewService) private contextViewService: IContextViewService,
|
||||
@Inject(IClipboardService) private clipboardService: IClipboardService
|
||||
@Inject(IClipboardService) private clipboardService: IClipboardService,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||
) {
|
||||
super(changeRef);
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
@@ -35,8 +35,9 @@ export default class LoadingComponent extends ComponentBase implements IComponen
|
||||
@ViewChild('childElement', { read: ElementRef }) private _childElement: ElementRef;
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
||||
super(changeRef);
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||
super(changeRef, el);
|
||||
this._validations.push(() => {
|
||||
if (!this._component) {
|
||||
return true;
|
||||
|
||||
239
src/sql/parts/modelComponents/markdown.css
Normal file
239
src/sql/parts/modelComponents/markdown.css
Normal file
@@ -0,0 +1,239 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
modelview-dom-component {
|
||||
font-family: "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
|
||||
font-size: 14px;
|
||||
padding: 0 26px;
|
||||
line-height: 22px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
modelview-dom-component #code-csp-warning {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
color: white;
|
||||
margin: 16px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-family: sans-serif;
|
||||
background-color:#444444;
|
||||
cursor: pointer;
|
||||
padding: 6px;
|
||||
box-shadow: 1px 1px 1px rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
modelview-dom-component #code-csp-warning:hover {
|
||||
text-decoration: none;
|
||||
background-color:#007acc;
|
||||
box-shadow: 2px 2px 2px rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
|
||||
modelview-dom-component .scrollBeyondLastLine {
|
||||
margin-bottom: calc(100vh - 22px);
|
||||
}
|
||||
|
||||
modelview-dom-component .showEditorSelection .code-line {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
modelview-dom-component .showEditorSelection .code-active-line:before,
|
||||
modelview-dom-component .showEditorSelection .code-line:hover:before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -12px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
modelview-dom-component .showEditorSelection li.code-active-line:before,
|
||||
modelview-dom-component .showEditorSelection li.code-line:hover:before {
|
||||
left: -30px;
|
||||
}
|
||||
|
||||
modelview-dom-component .showEditorSelection .code-active-line:before {
|
||||
border-left: 3px solid rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
modelview-dom-component .showEditorSelection .code-line:hover:before {
|
||||
border-left: 3px solid rgba(0, 0, 0, 0.40);
|
||||
}
|
||||
|
||||
modelview-dom-component .showEditorSelection .code-line .code-line:hover:before {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench modelview-dom-component .showEditorSelection .code-active-line:before
|
||||
.hc-black .monaco-workbench modelview-dom-component .showEditorSelection .code-active-line:before {
|
||||
border-left: 3px solid rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench modelview-dom-component .showEditorSelection .code-line:hover:before
|
||||
.hc-black .monaco-workbench modelview-dom-component .showEditorSelection .code-line:hover:before {
|
||||
border-left: 3px solid rgba(255, 255, 255, 0.60);
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench modelview-dom-component .showEditorSelection .code-line .code-line:hover:before
|
||||
.hc-black .monaco-workbench modelview-dom-component .showEditorSelection .code-line .code-line:hover:before {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.hc-black modelview-dom-component .showEditorSelection .code-active-line:before {
|
||||
border-left: 3px solid rgba(255, 160, 0, 0.7);
|
||||
}
|
||||
|
||||
.hc-black modelview-dom-component .showEditorSelection .code-line:hover:before {
|
||||
border-left: 3px solid rgba(255, 160, 0, 1);
|
||||
}
|
||||
|
||||
modelview-dom-component .showEditorSelection .code-line .code-line:hover:before {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
modelview-dom-component img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
modelview-dom-component a, a:link{
|
||||
text-decoration: none;
|
||||
color: rgb(0, 0, 238) !important;
|
||||
}
|
||||
|
||||
modelview-dom-component a:hover, a:link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
modelview-dom-component a:focus,
|
||||
modelview-dom-component input:focus,
|
||||
modelview-dom-component select:focus,
|
||||
modelview-dom-component textarea:focus {
|
||||
outline: 1px solid -webkit-focus-ring-color;
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
modelview-dom-component hr {
|
||||
border: 0;
|
||||
height: 2px;
|
||||
border-bottom: 2px solid;
|
||||
}
|
||||
|
||||
modelview-dom-component h1 {
|
||||
padding-bottom: 0.3em;
|
||||
line-height: 1.2;
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
modelview-dom-component h1,
|
||||
modelview-dom-component h2,
|
||||
modelview-dom-component h3 {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
modelview-dom-component h1 code,
|
||||
modelview-dom-component h2 code,
|
||||
modelview-dom-component h3 code,
|
||||
modelview-dom-component h4 code,
|
||||
modelview-dom-component h5 code,
|
||||
modelview-dom-component h6 code {
|
||||
font-size: inherit;
|
||||
line-height: auto;
|
||||
}
|
||||
|
||||
modelview-dom-component table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
modelview-dom-component table > thead > tr > th {
|
||||
text-align: left;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
modelview-dom-component table > thead > tr > th,
|
||||
modelview-dom-component table > thead > tr > td,
|
||||
modelview-dom-component table > tbody > tr > th,
|
||||
modelview-dom-component table > tbody > tr > td {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
modelview-dom-component table > tbody > tr + tr > td {
|
||||
border-top: 1px solid;
|
||||
}
|
||||
|
||||
modelview-dom-component blockquote {
|
||||
margin: 0 7px 0 5px;
|
||||
padding: 0 16px 0 10px;
|
||||
border-left-width: 5px;
|
||||
border-left-style: solid;
|
||||
}
|
||||
|
||||
modelview-dom-component code {
|
||||
font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
|
||||
font-size: 14px;
|
||||
line-height: 19px;
|
||||
}
|
||||
|
||||
modelview-dom-component .wordWrap pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
modelview-dom-component .mac code {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
modelview-dom-component pre:not(.hljs),
|
||||
modelview-dom-component pre.hljs code > div {
|
||||
padding: 16px;
|
||||
border-radius: 3px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/** Theming */
|
||||
|
||||
modelview-dom-component pre code {
|
||||
color: var(--vscode-editor-foreground);
|
||||
}
|
||||
|
||||
|
||||
modelview-dom-component pre {
|
||||
background-color: rgba(220, 220, 220, 0.4);
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench modelview-dom-component pre {
|
||||
background-color: rgba(10, 10, 10, 0.4);
|
||||
}
|
||||
|
||||
.hc-black .monaco-workbench modelview-dom-component pre {
|
||||
background-color: rgb(0, 0, 0);
|
||||
}
|
||||
|
||||
.hc-black .monaco-workbench modelview-dom-component h1 {
|
||||
border-color: rgb(0, 0, 0);
|
||||
}
|
||||
|
||||
modelview-dom-component table > thead > tr > th {
|
||||
border-color: rgba(0, 0, 0, 0.69);
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench modelview-dom-component table > thead > tr > th {
|
||||
border-color: rgba(255, 255, 255, 0.69);
|
||||
}
|
||||
|
||||
modelview-dom-component h1,
|
||||
modelview-dom-component hr,
|
||||
modelview-dom-component table > tbody > tr + tr > td {
|
||||
border-color: rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench modelview-dom-component h1,
|
||||
.vs-dark .monaco-workbench modelview-dom-component hr,
|
||||
.vs-dark .monaco-workbench modelview-dom-component table > tbody > tr + tr > td {
|
||||
border-color: rgba(255, 255, 255, 0.18);
|
||||
}
|
||||
@@ -3,16 +3,50 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IEditorModel } from 'vs/platform/editor/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor';
|
||||
import { EditorInput, EditorModel, ConfirmResult } from 'vs/workbench/common/editor';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
|
||||
|
||||
import { DialogPane } from 'sql/platform/dialog/dialogPane';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
export type ModeViewSaveHandler = (handle: number) => Thenable<boolean>;
|
||||
|
||||
export class ModelViewInputModel extends EditorModel {
|
||||
private dirty: boolean;
|
||||
private readonly _onDidChangeDirty: Emitter<void> = this._register(new Emitter<void>());
|
||||
get onDidChangeDirty(): Event<void> { return this._onDidChangeDirty.event; }
|
||||
|
||||
constructor(public readonly modelViewId, private readonly handle: number, private saveHandler?: ModeViewSaveHandler) {
|
||||
super();
|
||||
this.dirty = false;
|
||||
}
|
||||
|
||||
get isDirty(): boolean {
|
||||
return this.dirty;
|
||||
}
|
||||
|
||||
public setDirty(dirty: boolean): void {
|
||||
if (this.dirty === dirty) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dirty = dirty;
|
||||
this._onDidChangeDirty.fire();
|
||||
}
|
||||
|
||||
save(): TPromise<boolean> {
|
||||
if (this.saveHandler) {
|
||||
return TPromise.wrap(this.saveHandler(this.handle));
|
||||
}
|
||||
return TPromise.wrap(true);
|
||||
}
|
||||
}
|
||||
export class ModelViewInput extends EditorInput {
|
||||
|
||||
public static ID: string = 'workbench.editorinputs.ModelViewEditorInput';
|
||||
@@ -20,14 +54,15 @@ export class ModelViewInput extends EditorInput {
|
||||
private _dialogPaneContainer: HTMLElement;
|
||||
private _dialogPane: DialogPane;
|
||||
|
||||
constructor(private _title: string, private _modelViewId: string,
|
||||
constructor(private _title: string, private _model: ModelViewInputModel,
|
||||
private _options: sqlops.ModelViewEditorOptions,
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
@IPartService private readonly _partService: IPartService
|
||||
) {
|
||||
super();
|
||||
this._model.onDidChangeDirty(() => this._onDidChangeDirty.fire());
|
||||
this._container = document.createElement('div');
|
||||
this._container.id = `modelView-${_modelViewId}`;
|
||||
this._container.id = `modelView-${_model.modelViewId}`;
|
||||
this._partService.getContainer(Parts.EDITOR_PART).appendChild(this._container);
|
||||
|
||||
}
|
||||
@@ -37,7 +72,7 @@ export class ModelViewInput extends EditorInput {
|
||||
}
|
||||
|
||||
public get modelViewId(): string {
|
||||
return this._modelViewId;
|
||||
return this._model.modelViewId;
|
||||
}
|
||||
|
||||
public getTypeId(): string {
|
||||
@@ -85,6 +120,31 @@ export class ModelViewInput extends EditorInput {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
/**
|
||||
* An editor that is dirty will be asked to be saved once it closes.
|
||||
*/
|
||||
isDirty(): boolean {
|
||||
return this._model.isDirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should bring up a proper dialog for the user if the editor is dirty and return the result.
|
||||
*/
|
||||
confirmSave(): TPromise<ConfirmResult> {
|
||||
// TODO #2530 support save on close / confirm save. This is significantly more work
|
||||
// as we need to either integrate with textFileService (seems like this isn't viable)
|
||||
// or register our own complimentary service that handles the lifecycle operations such
|
||||
// as close all, auto save etc.
|
||||
return TPromise.wrap(ConfirmResult.DONT_SAVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the editor if it is dirty. Subclasses return a promise with a boolean indicating the success of the operation.
|
||||
*/
|
||||
save(): TPromise<boolean> {
|
||||
return this._model.save();
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (this._dialogPane) {
|
||||
this._dialogPane.dispose();
|
||||
@@ -93,6 +153,9 @@ export class ModelViewInput extends EditorInput {
|
||||
this._container.remove();
|
||||
this._container = undefined;
|
||||
}
|
||||
if (this._model) {
|
||||
this._model.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,9 @@ export default class RadioButtonComponent extends ComponentBase implements IComp
|
||||
@ViewChild('input', { read: ElementRef }) private _inputContainer: ElementRef;
|
||||
constructor(
|
||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
||||
super(changeRef);
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
@@ -35,8 +35,9 @@ export default class TableComponent extends ComponentBase implements IComponent,
|
||||
@ViewChild('table', { read: ElementRef }) private _inputContainer: ElementRef;
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService) {
|
||||
super(changeRef);
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import 'vs/css!./radioButton';
|
||||
import {
|
||||
Component, Input, Inject, ChangeDetectorRef, forwardRef,
|
||||
OnDestroy, AfterViewInit
|
||||
OnDestroy, AfterViewInit, ElementRef
|
||||
} from '@angular/core';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
@@ -26,8 +26,9 @@ export default class TextComponent extends ComponentBase implements IComponent,
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
||||
super(changeRef);
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
@@ -29,7 +29,7 @@ export class ToolbarItem {
|
||||
template: `
|
||||
<div #container *ngIf="items" [class]="toolbarClass" >
|
||||
<ng-container *ngFor="let item of items">
|
||||
<div class="modelview-toolbar-item" [title]="getItemTitle(item)" [style.paddingTop]="paddingTop" tabindex="0">
|
||||
<div class="modelview-toolbar-item" [style.paddingTop]="paddingTop">
|
||||
<div *ngIf="shouldShowTitle(item)" class="modelview-toolbar-title" >
|
||||
{{getItemTitle(item)}}
|
||||
</div>
|
||||
@@ -52,8 +52,9 @@ export default class ToolbarContainer extends ContainerBase<ToolbarItemConfig> i
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
||||
super(changeRef);
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||
super(changeRef, el);
|
||||
this._orientation = Orientation.Horizontal;
|
||||
}
|
||||
|
||||
@@ -89,7 +90,7 @@ export default class ToolbarContainer extends ContainerBase<ToolbarItemConfig> i
|
||||
}
|
||||
|
||||
public get paddingTop(): string {
|
||||
return this.isHorizontal() ? '' : '10px';
|
||||
return this.isHorizontal() ? '' : '';
|
||||
}
|
||||
|
||||
public get toolbarClass(): string {
|
||||
|
||||
@@ -30,6 +30,13 @@
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.modelview-toolbar-container.toolbar-vertical .modelview-toolbar-item {
|
||||
flex: 0 0;
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.modelview-toolbar-container .modelview-toolbar-title {
|
||||
padding: 4px;
|
||||
font-size: 14px;
|
||||
@@ -46,4 +53,21 @@
|
||||
padding-left: 15px;
|
||||
background-size: 11px;
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
}
|
||||
|
||||
/* Vertical button handling */
|
||||
.modelview-toolbar-container.toolbar-vertical .modelview-toolbar-component modelview-button .monaco-text-button.icon {
|
||||
padding: 22px 16px 22px 16px;
|
||||
background-size: 22px;
|
||||
margin-right: 0.3em;
|
||||
background-position: 50% 50%;
|
||||
|
||||
}
|
||||
|
||||
.modelview-toolbar-container .modelview-toolbar-component modelview-button .monaco-text-button.active {
|
||||
-ms-transform: scale(1.272019649, 1.272019649); /* 1.272019649 = √φ */
|
||||
-webkit-transform: scale(1.272019649, 1.272019649);
|
||||
-moz-transform: scale(1.272019649, 1.272019649);
|
||||
-o-transform: scale(1.272019649, 1.272019649);
|
||||
transform: scale(1.272019649, 1.272019649);
|
||||
}
|
||||
|
||||
@@ -55,8 +55,10 @@ export default class TreeComponent extends ComponentBase implements IComponent,
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||
@Inject(IContextViewService) private contextViewService: IContextViewService,
|
||||
@Inject(IInstantiationService) private _instantiationService: IInstantiationService) {
|
||||
super(changeRef);
|
||||
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||
) {
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -112,7 +114,7 @@ export default class TreeComponent extends ComponentBase implements IComponent,
|
||||
this._tree.domFocus();
|
||||
this._register(this._tree);
|
||||
this._register(attachListStyler(this._tree, this.themeService));
|
||||
this._register(this._tree.onDidChangeSelection( e => {
|
||||
this._register(this._tree.onDidChangeSelection(e => {
|
||||
this._dataProvider.onNodeSelected(e.selection);
|
||||
}));
|
||||
this._tree.refresh();
|
||||
|
||||
@@ -29,11 +29,6 @@ export class TreeViewDataProvider extends vsTreeView.TreeViewDataProvider implem
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
refresh(itemsToRefreshByHandle: { [treeItemHandle: string]: ITreeComponentItem }) {
|
||||
}
|
||||
|
||||
getChildren(element?: ITreeComponentItem): TPromise<ITreeComponentItem[]> {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,13 @@ import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } fro
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
function reviveWebviewOptions(options: vscode.WebviewOptions): vscode.WebviewOptions {
|
||||
return {
|
||||
...options,
|
||||
localResourceRoots: Array.isArray(options.localResourceRoots) ? options.localResourceRoots.map(URI.revive) : undefined
|
||||
};
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: '',
|
||||
selector: 'modelview-webview-component'
|
||||
@@ -46,7 +53,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
|
||||
constructor(
|
||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||
@Inject(IPartService) private partService: IPartService,
|
||||
@Inject(IThemeService) private themeService: IThemeService,
|
||||
@Inject(IEnvironmentService) private environmentService: IEnvironmentService,
|
||||
@@ -56,7 +63,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
|
||||
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
|
||||
@Inject(IContextKeyService) contextKeyService: IContextKeyService
|
||||
) {
|
||||
super(changeRef);
|
||||
super(changeRef, el);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -132,7 +139,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
|
||||
/// IComponent implementation
|
||||
|
||||
public layout(): void {
|
||||
let element = <HTMLElement> this._el.nativeElement;
|
||||
let element = <HTMLElement>this._el.nativeElement;
|
||||
element.style.position = this.position;
|
||||
this._webview.layout();
|
||||
}
|
||||
@@ -192,6 +199,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
|
||||
|
||||
private getExtendedOptions(): WebviewOptions {
|
||||
let options = this.options || { enableScripts: true };
|
||||
options = reviveWebviewOptions(options);
|
||||
return {
|
||||
allowScripts: options.enableScripts,
|
||||
allowSvgs: true,
|
||||
@@ -208,4 +216,5 @@ export default class WebViewComponent extends ComponentBase implements IComponen
|
||||
}
|
||||
return rootPaths;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -72,6 +72,8 @@ export interface IObjectExplorerService {
|
||||
getActiveConnectionNodes(): TreeNode[];
|
||||
|
||||
getTreeNode(connectionId: string, nodePath: string): Thenable<TreeNode>;
|
||||
|
||||
refreshNodeInView(connectionId: string, nodePath: string): Thenable<TreeNode>;
|
||||
}
|
||||
|
||||
interface SessionStatus {
|
||||
@@ -476,6 +478,20 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
return Object.values(this._activeObjectExplorerNodes);
|
||||
}
|
||||
|
||||
public async refreshNodeInView(connectionId: string, nodePath: string): Promise<TreeNode> {
|
||||
// Get the tree node and call refresh from the provider
|
||||
let treeNode = await this.getTreeNode(connectionId, nodePath);
|
||||
await this.refreshTreeNode(treeNode.getSession(), treeNode);
|
||||
|
||||
// Get the new tree node, refresh it in the view, and expand it if needed
|
||||
treeNode = await this.getTreeNode(connectionId, nodePath);
|
||||
await this._serverTreeView.refreshElement(treeNode);
|
||||
if (treeNode.children.length > 0) {
|
||||
await treeNode.setExpandedState(TreeItemCollapsibleState.Expanded);
|
||||
}
|
||||
return treeNode;
|
||||
}
|
||||
|
||||
private async setNodeExpandedState(treeNode: TreeNode, expandedState: TreeItemCollapsibleState): Promise<void> {
|
||||
treeNode = await this.getUpdatedTreeNode(treeNode);
|
||||
let expandNode = this.getTreeItem(treeNode);
|
||||
|
||||
@@ -39,7 +39,7 @@ const viewletDescriptor = new ViewletDescriptor(
|
||||
VIEWLET_ID,
|
||||
'Servers',
|
||||
'connectionViewlet',
|
||||
-100
|
||||
0
|
||||
);
|
||||
|
||||
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(viewletDescriptor);
|
||||
|
||||
@@ -167,12 +167,12 @@ export class ServerTreeActionProvider extends ContributableActionProvider {
|
||||
if (TreeUpdateUtils.isDatabaseNode(treeNode)) {
|
||||
if (TreeUpdateUtils.isAvailableDatabaseNode(treeNode)) {
|
||||
actions.push(this._instantiationService.createInstance(ManageConnectionAction, ManageConnectionAction.ID, ManageConnectionAction.LABEL, context.tree));
|
||||
this.addNewQueryAction(context, actions);
|
||||
} else {
|
||||
return actions;
|
||||
}
|
||||
}
|
||||
|
||||
this.addNewQueryAction(context, actions);
|
||||
this.addScriptingActions(context, actions);
|
||||
actions.push(this._instantiationService.createInstance(RefreshAction, RefreshAction.ID, RefreshAction.LABEL, context.tree, treeNode));
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import { ConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
|
||||
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
||||
import { ITree, IDataSource } from 'vs/base/parts/tree/browser/tree';
|
||||
import { TreeNode } from 'sql/parts/objectExplorer/common/treeNode';
|
||||
import { TreeNode, TreeItemCollapsibleState } from 'sql/parts/objectExplorer/common/treeNode';
|
||||
import { IObjectExplorerService } from 'sql/parts/objectExplorer/common/objectExplorerService';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { TreeUpdateUtils } from 'sql/parts/objectExplorer/viewlet/treeUpdateUtils';
|
||||
@@ -72,9 +72,13 @@ export class ServerTreeDataSource implements IDataSource {
|
||||
if (node.children) {
|
||||
resolve(node.children);
|
||||
} else {
|
||||
// These similar changes are probably needed for a ConnectionProfile group element as well. However, we do not have a repro of a failiure in that scenario so they will be tackled in a future checkin.
|
||||
// It has been tested for connecting to the server in profile itself and things work fine there.
|
||||
this._objectExplorerService.resolveTreeNodeChildren(node.getSession(), node).then(() => {
|
||||
resolve(node.children);
|
||||
}, expandError => {
|
||||
node.setExpandedState(TreeItemCollapsibleState.Collapsed);
|
||||
node.errorStateMessage = expandError;
|
||||
this.showError(expandError);
|
||||
resolve([]);
|
||||
});
|
||||
|
||||
@@ -138,7 +138,7 @@ export class ServerTreeView {
|
||||
|
||||
let expandGroups: boolean = self._configurationService.getValue(SERVER_GROUP_CONFIG)[SERVER_GROUP_AUTOEXPAND_CONFIG];
|
||||
if (expandGroups) {
|
||||
self._tree.expandAll(ConnectionProfileGroup.getSubgroups(root));
|
||||
self._tree.expandAll(ConnectionProfileGroup.getSubgroups(root));
|
||||
}
|
||||
|
||||
if (root && !root.hasValidConnections) {
|
||||
@@ -244,6 +244,10 @@ export class ServerTreeView {
|
||||
TreeUpdateUtils.registeredServerUpdate(this._tree, this._connectionManagementService);
|
||||
}
|
||||
|
||||
public refreshElement(element: any): Thenable<void> {
|
||||
return this._tree.refresh(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter connections based on view (recent/active)
|
||||
*/
|
||||
|
||||
@@ -10,6 +10,27 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { EditorInput } from 'vs/workbench/common/editor';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
|
||||
import { GridPanelState } from 'sql/parts/query/editor/gridPanel';
|
||||
import { MessagePanelState } from 'sql/parts/query/editor/messagePanel';
|
||||
import { QueryPlanState } from 'sql/parts/queryPlan/queryPlan';
|
||||
import { ChartState } from 'sql/parts/query/editor/charting/chartView';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
export class ResultsViewState {
|
||||
public gridPanelState: GridPanelState = new GridPanelState();
|
||||
public messagePanelState: MessagePanelState = new MessagePanelState(this.configurationService);
|
||||
public chartState: ChartState = new ChartState();
|
||||
public queryPlanState: QueryPlanState = new QueryPlanState();
|
||||
public gridPanelSize: number;
|
||||
public messagePanelSize: number;
|
||||
public activeTab: string;
|
||||
public visibleTabs: Set<string> = new Set<string>();
|
||||
|
||||
constructor(@IConfigurationService private configurationService: IConfigurationService) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Input for the QueryResultsEditor. This input helps with logic for the viewing and editing of
|
||||
* data in the results grid.
|
||||
@@ -29,7 +50,11 @@ export class QueryResultsInput extends EditorInput {
|
||||
public readonly onRestoreViewStateEmitter = new Emitter<void>();
|
||||
public readonly onSaveViewStateEmitter = new Emitter<void>();
|
||||
|
||||
constructor(private _uri: string) {
|
||||
public readonly state = new ResultsViewState(this.configurationService);
|
||||
|
||||
constructor(private _uri: string,
|
||||
@IConfigurationService private configurationService: IConfigurationService
|
||||
) {
|
||||
super();
|
||||
this._visible = false;
|
||||
this._hasBootstrapped = false;
|
||||
|
||||
@@ -82,12 +82,12 @@ export class RowCountStatusBarItem implements IStatusbarItem {
|
||||
}
|
||||
|
||||
private _displayValue(runner: QueryRunner) {
|
||||
let number = runner.batchSets.reduce((p, c) => {
|
||||
let rowCount = runner.batchSets.reduce((p, c) => {
|
||||
return p + c.resultSetSummaries.reduce((rp, rc) => {
|
||||
return rp + rc.rowCount;
|
||||
}, 0);
|
||||
}, 0);
|
||||
this._flavorElement.innerText = nls.localize('rowCount', "{0} rows", number);
|
||||
this._flavorElement.innerText = nls.localize('rowCount', "{0} rows", rowCount);
|
||||
show(this._flavorElement);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,14 @@ import { localize } from 'vs/nls';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
||||
import QueryRunner from 'sql/parts/query/execution/queryRunner';
|
||||
import { SaveFormat } from 'sql/parts/grid/common/interfaces';
|
||||
import { Table } from 'sql/base/browser/ui/table/table';
|
||||
import { GridTableState } from 'sql/parts/query/editor/gridPanel';
|
||||
import { QueryEditor } from './queryEditor';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { CellSelectionModel } from 'sql/base/browser/ui/table/plugins/cellSelectionModel.plugin';
|
||||
|
||||
export interface IGridActionContext {
|
||||
cell: { row: number; cell: number; };
|
||||
@@ -26,6 +27,7 @@ export interface IGridActionContext {
|
||||
batchId: number;
|
||||
resultId: number;
|
||||
table: Table<any>;
|
||||
selectionModel: CellSelectionModel<any>;
|
||||
tableState: GridTableState;
|
||||
}
|
||||
|
||||
@@ -34,6 +36,14 @@ export interface IMessagesActionContext {
|
||||
tree: ITree;
|
||||
}
|
||||
|
||||
function mapForNumberColumn(ranges: Slick.Range[]): Slick.Range[] {
|
||||
if (ranges) {
|
||||
return ranges.map(e => new Slick.Range(e.fromRow, e.fromCell - 1, e.toRow, e.toCell ? e.toCell - 1 : undefined));
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export class SaveResultAction extends Action {
|
||||
public static SAVECSV_ID = 'grid.saveAsCsv';
|
||||
public static SAVECSV_LABEL = localize('saveAsCsv', 'Save As CSV');
|
||||
@@ -51,13 +61,19 @@ export class SaveResultAction extends Action {
|
||||
id: string,
|
||||
label: string,
|
||||
icon: string,
|
||||
private format: SaveFormat
|
||||
private format: SaveFormat,
|
||||
private accountForNumberColumn = true
|
||||
) {
|
||||
super(id, label, icon);
|
||||
}
|
||||
|
||||
public run(context: IGridActionContext): TPromise<boolean> {
|
||||
context.runner.serializeResults(context.batchId, context.resultId, this.format, context.selection);
|
||||
if (this.accountForNumberColumn) {
|
||||
context.runner.serializeResults(context.batchId, context.resultId, this.format,
|
||||
mapForNumberColumn(context.selection));
|
||||
} else {
|
||||
context.runner.serializeResults(context.batchId, context.resultId, this.format, context.selection);
|
||||
}
|
||||
return TPromise.as(true);
|
||||
}
|
||||
}
|
||||
@@ -73,12 +89,19 @@ export class CopyResultAction extends Action {
|
||||
id: string,
|
||||
label: string,
|
||||
private copyHeader: boolean,
|
||||
private accountForNumberColumn = true
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
public run(context: IGridActionContext): TPromise<boolean> {
|
||||
context.runner.copyResults(context.selection, context.batchId, context.resultId, this.copyHeader);
|
||||
if (this.accountForNumberColumn) {
|
||||
context.runner.copyResults(
|
||||
mapForNumberColumn(context.selection),
|
||||
context.batchId, context.resultId, this.copyHeader);
|
||||
} else {
|
||||
context.runner.copyResults(context.selection, context.batchId, context.resultId, this.copyHeader);
|
||||
}
|
||||
return TPromise.as(true);
|
||||
}
|
||||
}
|
||||
@@ -92,7 +115,7 @@ export class SelectAllGridAction extends Action {
|
||||
}
|
||||
|
||||
public run(context: IGridActionContext): TPromise<boolean> {
|
||||
context.table.setSelectedRows(true);
|
||||
context.selectionModel.setSelectedRanges([new Slick.Range(0, 0, context.table.getData().getLength() - 1, context.table.columns.length - 1)]);
|
||||
return TPromise.as(true);
|
||||
}
|
||||
}
|
||||
@@ -146,13 +169,13 @@ export class MaximizeTableAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class MinimizeTableAction extends Action {
|
||||
public static ID = 'grid.minimize';
|
||||
public static LABEL = localize('minimize', 'Minimize');
|
||||
export class RestoreTableAction extends Action {
|
||||
public static ID = 'grid.restore';
|
||||
public static LABEL = localize('restore', 'Restore');
|
||||
public static ICON = 'exitFullScreen';
|
||||
|
||||
constructor() {
|
||||
super(MinimizeTableAction.ID, MinimizeTableAction.LABEL, MinimizeTableAction.ICON);
|
||||
super(RestoreTableAction.ID, RestoreTableAction.LABEL, RestoreTableAction.ICON);
|
||||
}
|
||||
|
||||
public run(context: IGridActionContext): TPromise<boolean> {
|
||||
@@ -200,5 +223,4 @@ export class ShowQueryPlanAction extends Action {
|
||||
return TPromise.as(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
import { localize } from 'vs/nls';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
|
||||
import { ChartType, DataDirection, LegendPosition } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
|
||||
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
||||
import { DataType } from 'sql/parts/dashboard/widgets/insights/views/charts/types/lineChart.component';
|
||||
import { InsightType, IInsightOptions } from './insights/interfaces';
|
||||
import { DataDirection, ChartType, LegendPosition, DataType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
|
||||
|
||||
const insightRegistry = Registry.as<IInsightRegistry>(Extensions.InsightContribution);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user