mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-25 18:47:14 -05:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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
|
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. -->
|
<!-- 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. -->
|
<!-- Use Help > Report Issue to prefill these. -->
|
||||||
- SQL Operations Studio Version:
|
- SQL Operations Studio Version:
|
||||||
- OS Version:
|
|
||||||
|
|
||||||
Steps to Reproduce:
|
Steps to Reproduce:
|
||||||
|
|
||||||
1.
|
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"
|
disturl "https://atom.io/download/electron"
|
||||||
target "2.0.7"
|
target "2.0.8"
|
||||||
runtime "electron"
|
runtime "electron"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
const localize = nls.loadMessageBundle();
|
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 { findGit, Git, IGit } from './git';
|
||||||
import { Model } from './model';
|
import { Model } from './model';
|
||||||
import { CommandCenter } from './commands';
|
import { CommandCenter } from './commands';
|
||||||
@@ -98,28 +98,29 @@ export async function activate(context: ExtensionContext): Promise<API> {
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = workspace.getConfiguration('git');
|
// {{SQL CARBON EDIT}} turn-off Git missing prompt
|
||||||
const shouldIgnore = config.get<boolean>('ignoreMissingGitWarning') === true;
|
//const config = workspace.getConfiguration('git');
|
||||||
|
//const shouldIgnore = config.get<boolean>('ignoreMissingGitWarning') === true;
|
||||||
|
|
||||||
if (!shouldIgnore) {
|
// if (!shouldIgnore) {
|
||||||
console.warn(err.message);
|
// console.warn(err.message);
|
||||||
outputChannel.appendLine(err.message);
|
// outputChannel.appendLine(err.message);
|
||||||
outputChannel.show();
|
// outputChannel.show();
|
||||||
|
|
||||||
const download = localize('downloadgit', "Download Git");
|
// const download = localize('downloadgit', "Download Git");
|
||||||
const neverShowAgain = localize('neverShowAgain', "Don't Show Again");
|
// const neverShowAgain = localize('neverShowAgain', "Don't Show Again");
|
||||||
const choice = await window.showWarningMessage(
|
// const choice = await window.showWarningMessage(
|
||||||
localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."),
|
// localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."),
|
||||||
download,
|
// download,
|
||||||
neverShowAgain
|
// neverShowAgain
|
||||||
);
|
// );
|
||||||
|
|
||||||
if (choice === download) {
|
// if (choice === download) {
|
||||||
commands.executeCommand('vscode.open', Uri.parse('https://git-scm.com/'));
|
// commands.executeCommand('vscode.open', Uri.parse('https://git-scm.com/'));
|
||||||
} else if (choice === neverShowAgain) {
|
// } else if (choice === neverShowAgain) {
|
||||||
await config.update('ignoreMissingGitWarning', true, true);
|
// await config.update('ignoreMissingGitWarning', true, true);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return new NoopAPIImpl();
|
return new NoopAPIImpl();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sqlops",
|
"name": "sqlops",
|
||||||
"version": "0.33.1",
|
"version": "0.33.4",
|
||||||
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
|
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Microsoft Corporation"
|
"name": "Microsoft Corporation"
|
||||||
|
|||||||
85
samples/sqlservices/package-lock.json
generated
85
samples/sqlservices/package-lock.json
generated
@@ -3121,6 +3121,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"gulp-remote-src-vscode": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/gulp-remote-src-vscode/-/gulp-remote-src-vscode-0.5.0.tgz",
|
||||||
|
"integrity": "sha512-/9vtSk9eI9DEWCqzGieglPqmx0WUQ9pwPHyHFpKmfxqdgqGJC2l0vFMdYs54hLdDsMDEZFLDL2J4ikjc4hQ5HQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"event-stream": "3.3.4",
|
||||||
|
"node.extend": "1.1.6",
|
||||||
|
"request": "2.85.0",
|
||||||
|
"through2": "2.0.3",
|
||||||
|
"vinyl": "2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"gulp-sourcemaps": {
|
"gulp-sourcemaps": {
|
||||||
"version": "2.6.4",
|
"version": "2.6.4",
|
||||||
"resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.4.tgz",
|
"resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.4.tgz",
|
||||||
@@ -7423,25 +7436,85 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"version": "1.1.14",
|
"version": "1.1.21",
|
||||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.14.tgz",
|
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.21.tgz",
|
||||||
"integrity": "sha512-acfn3fzGtTm7UjChAN7/YjsC0qIyJeuSrJwvm6qb7tLN6Geq1FmCz1JnBOc3kaY+HCLjQBAfwG/CsgnasOdXMw==",
|
"integrity": "sha512-tJl9eL15ZMm6vzCYYeQ26sSYRuXGMGPsaeIAmG2rOOYRn01jdaDg6I4b9G5Ed6FISdmn6egpKThk4o4om8Ax/A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"glob": "7.1.2",
|
"glob": "7.1.2",
|
||||||
"gulp-chmod": "2.0.0",
|
"gulp-chmod": "2.0.0",
|
||||||
"gulp-filter": "5.1.0",
|
"gulp-filter": "5.1.0",
|
||||||
"gulp-gunzip": "1.0.0",
|
"gulp-gunzip": "1.0.0",
|
||||||
"gulp-remote-src": "0.4.3",
|
"gulp-remote-src-vscode": "0.5.0",
|
||||||
"gulp-symdest": "1.1.0",
|
"gulp-symdest": "1.1.0",
|
||||||
"gulp-untar": "0.0.6",
|
"gulp-untar": "0.0.7",
|
||||||
"gulp-vinyl-zip": "2.1.0",
|
"gulp-vinyl-zip": "2.1.0",
|
||||||
"mocha": "4.1.0",
|
"mocha": "4.1.0",
|
||||||
"request": "2.85.0",
|
"request": "2.85.0",
|
||||||
"semver": "5.5.0",
|
"semver": "5.5.0",
|
||||||
"source-map-support": "0.5.4",
|
"source-map-support": "0.5.4",
|
||||||
"url-parse": "1.3.0",
|
"url-parse": "1.4.3",
|
||||||
"vinyl-source-stream": "1.1.2"
|
"vinyl-source-stream": "1.1.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"clone": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
|
||||||
|
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"clone-stats": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"gulp-untar": {
|
||||||
|
"version": "0.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/gulp-untar/-/gulp-untar-0.0.7.tgz",
|
||||||
|
"integrity": "sha512-0QfbCH2a1k2qkTLWPqTX+QO4qNsHn3kC546YhAP3/n0h+nvtyGITDuDrYBMDZeW4WnFijmkOvBWa5HshTic1tw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"event-stream": "3.3.4",
|
||||||
|
"streamifier": "0.1.1",
|
||||||
|
"tar": "2.2.1",
|
||||||
|
"through2": "2.0.3",
|
||||||
|
"vinyl": "1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"querystringify": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"replace-ext": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"url-parse": {
|
||||||
|
"version": "1.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz",
|
||||||
|
"integrity": "sha512-rh+KuAW36YKo0vClhQzLLveoj8FwPJNu65xLb7Mrt+eZht0IPT0IXgSv8gcMegZ6NvjJUALf6Mf25POlMwD1Fw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"querystringify": "2.0.0",
|
||||||
|
"requires-port": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"vinyl": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"clone": "1.0.4",
|
||||||
|
"clone-stats": "0.0.1",
|
||||||
|
"replace-ext": "0.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vscode-nls": {
|
"vscode-nls": {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"publisher": "demo",
|
"publisher": "demo",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.21.0",
|
"vscode": "^1.26.0",
|
||||||
"sqlops": "*"
|
"sqlops": "*"
|
||||||
},
|
},
|
||||||
"categories": [
|
"categories": [
|
||||||
|
|||||||
@@ -128,9 +128,11 @@ export default class MainController implements vscode.Disposable {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
treeView.onDidChangeSelection(selectedNodes => {
|
treeView.onDidChangeSelection(selectedNodes => {
|
||||||
selectedNodes.forEach(node => {
|
if (selectedNodes && selectedNodes.selection) {
|
||||||
console.info('tree node selected: ' + node.label);
|
selectedNodes.selection.forEach(node => {
|
||||||
});
|
console.info('tree node selected: ' + node.label);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
let formModel = view.modelBuilder.formContainer()
|
let formModel = view.modelBuilder.formContainer()
|
||||||
.withFormItems([{
|
.withFormItems([{
|
||||||
@@ -516,7 +518,8 @@ export default class MainController implements vscode.Disposable {
|
|||||||
let runButton = view.modelBuilder.button()
|
let runButton = view.modelBuilder.button()
|
||||||
.withProperties({
|
.withProperties({
|
||||||
label: 'Run',
|
label: 'Run',
|
||||||
iconPath: runIcon
|
iconPath: runIcon,
|
||||||
|
title: 'Run title'
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
let monitorLightPath = vscode.Uri.file(path.join(__dirname, '..', 'media', 'monitor.svg'));
|
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()
|
let monitorButton = view.modelBuilder.button()
|
||||||
.withProperties({
|
.withProperties({
|
||||||
label: 'Monitor',
|
label: 'Monitor',
|
||||||
iconPath: monitorIcon
|
iconPath: monitorIcon,
|
||||||
|
title: 'Monitor title'
|
||||||
}).component();
|
}).component();
|
||||||
let toolbarModel = view.modelBuilder.toolbarContainer()
|
let toolbarModel = view.modelBuilder.toolbarContainer()
|
||||||
.withToolbarItems([{
|
.withToolbarItems([{
|
||||||
|
|||||||
@@ -2865,6 +2865,10 @@ qs@~6.5.1:
|
|||||||
version "6.5.1"
|
version "6.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
|
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:
|
querystringify@~1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb"
|
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"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
|
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"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
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"
|
querystringify "~1.0.0"
|
||||||
requires-port "~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:
|
use@^3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544"
|
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"
|
version "3.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.2.tgz#3817eca5b985c2393de325197cf4e15eb2aa5350"
|
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.2.tgz#3817eca5b985c2393de325197cf4e15eb2aa5350"
|
||||||
|
|
||||||
vscode@^1.1.14:
|
vscode@^1.1.18:
|
||||||
version "1.1.18"
|
version "1.1.21"
|
||||||
resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.18.tgz#e9227265dc72fc826bd6cd7bd21193f4e48fa671"
|
resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.21.tgz#1c8253d6238aefb4112d6e58cf975ad25313dafc"
|
||||||
dependencies:
|
dependencies:
|
||||||
glob "^7.1.2"
|
glob "^7.1.2"
|
||||||
gulp-chmod "^2.0.0"
|
gulp-chmod "^2.0.0"
|
||||||
@@ -3949,7 +3960,7 @@ vscode@^1.1.14:
|
|||||||
request "^2.83.0"
|
request "^2.83.0"
|
||||||
semver "^5.4.1"
|
semver "^5.4.1"
|
||||||
source-map-support "^0.5.0"
|
source-map-support "^0.5.0"
|
||||||
url-parse "^1.1.9"
|
url-parse "^1.4.3"
|
||||||
vinyl-source-stream "^1.1.0"
|
vinyl-source-stream "^1.1.0"
|
||||||
|
|
||||||
vso-node-api@^6.1.2-preview:
|
vso-node-api@^6.1.2-preview:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const IBreadcrumbService = new InjectionToken<IBreadcrumbService>('breadc
|
|||||||
|
|
||||||
export interface IBreadcrumbService {
|
export interface IBreadcrumbService {
|
||||||
breadcrumbItem: Subject<MenuItem[]>;
|
breadcrumbItem: Subject<MenuItem[]>;
|
||||||
setBreadcrumbs(any): void;
|
setBreadcrumbs(page: any): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MenuItem {
|
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-color', this.buttonFocusOutline ? this.buttonFocusOutline.toString() : null);
|
||||||
this.$el.style('outline-width', '1px');
|
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 {
|
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) {
|
if (this._modalOptions.isAngular === false && this._modalOptions.hasErrors) {
|
||||||
let builder = errorMessagesInFooter ? this._leftFooter : body;
|
let builder = errorMessagesInFooter ? this._leftFooter : body;
|
||||||
builder.div({ class: 'dialogErrorMessage', id: 'dialogErrorMessage' }, (errorMessageContainer) => {
|
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 = iconContainer.getHTMLElement();
|
||||||
this._errorIconElement.style.visibility = 'hidden';
|
this._errorIconElement.style.visibility = 'hidden';
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -331,8 +331,11 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
layout(size: number): void {
|
layout(size: number): void {
|
||||||
const previousSize = Math.max(this.size, this.contentSize);
|
const previousSize = this.size;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
|
this.contentSize = 0;
|
||||||
|
this.lastRenderHeight = undefined;
|
||||||
|
this.lastRenderTop = undefined;
|
||||||
this.resize(this.viewItems.length - 1, size - previousSize);
|
this.resize(this.viewItems.length - 1, size - previousSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,9 @@ export class SelectBox extends vsSelectBox {
|
|||||||
if (container) {
|
if (container) {
|
||||||
this.element = dom.append(container, $('.monaco-selectbox.idle'));
|
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 {
|
public style(styles: ISelectBoxStyles): void {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
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
|
* 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)) {
|
} else if (event.equals(KeyCode.End | KeyMod.CtrlCmd)) {
|
||||||
this.grid.setActiveCell(this.grid.getDataLength() - 1, this.grid.getColumns().length - 1);
|
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 {
|
} else {
|
||||||
handled = false;
|
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';
|
||||||
|
|
||||||
|
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangedecorator');
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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,10 @@
|
|||||||
|
|
||||||
import { mixin } from 'vs/base/common/objects';
|
import { mixin } from 'vs/base/common/objects';
|
||||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
|
||||||
|
import { CellRangeSelector, ICellRangeSelector } from 'sql/base/browser/ui/table/plugins/cellRangeSelector';
|
||||||
|
|
||||||
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangedecorator');
|
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>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ICellSelectionModelOptions {
|
export interface ICellSelectionModelOptions {
|
||||||
cellRangeSelector?: any;
|
cellRangeSelector?: any;
|
||||||
@@ -36,7 +31,7 @@ export class CellSelectionModel<T> implements Slick.SelectionModel<T, Array<Slic
|
|||||||
this.selector = this.options.cellRangeSelector;
|
this.selector = this.options.cellRangeSelector;
|
||||||
} else {
|
} else {
|
||||||
// this is added by the noderequires above
|
// 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 {
|
private handleClick(e: MouseEvent, args: Slick.OnClickEventArgs<T>): void {
|
||||||
if (this.grid.getColumns()[args.cell].id === 'rowNumber') {
|
if (this.grid.getColumns()[args.cell].id === 'rowNumber') {
|
||||||
this.grid.setActiveCell(args.row, 1);
|
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 {
|
private handleHeaderClick(e: MouseEvent, args: Slick.OnHeaderClickEventArgs<T>): void {
|
||||||
if (args.column.id === 'rowNumber') {
|
if (args.column.id === 'rowNumber') {
|
||||||
this.grid.setActiveCell(0, 1);
|
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> {
|
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 {
|
return {
|
||||||
id: 'rowNumber',
|
id: 'rowNumber',
|
||||||
name: '',
|
name: '',
|
||||||
field: 'rowNumber',
|
field: 'rowNumber',
|
||||||
width: this.options.numberOfRows.toString().length * sizePerDigit,
|
width: columnWidth,
|
||||||
|
minWidth: columnWidth,
|
||||||
|
maxWidth: columnWidth,
|
||||||
resizable: false,
|
resizable: false,
|
||||||
cssClass: this.options.cssClass,
|
cssClass: this.options.cssClass,
|
||||||
focusable: false,
|
focusable: false,
|
||||||
|
|||||||
@@ -166,6 +166,10 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
|
|||||||
this._grid.setData(this._data, true);
|
this._grid.setData(this._data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getData(): Slick.DataProvider<T> {
|
||||||
|
return this._data;
|
||||||
|
}
|
||||||
|
|
||||||
get columns(): Slick.Column<T>[] {
|
get columns(): Slick.Column<T>[] {
|
||||||
return this._grid.getColumns();
|
return this._grid.getColumns();
|
||||||
}
|
}
|
||||||
@@ -244,7 +248,6 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.resizeCanvas();
|
this.resizeCanvas();
|
||||||
this.autosizeColumns();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
autosizeColumns() {
|
autosizeColumns() {
|
||||||
@@ -308,10 +311,15 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
|
|||||||
|
|
||||||
if (styles.listHoverBackground) {
|
if (styles.listHoverBackground) {
|
||||||
content.push(`.monaco-table.${this.idPrefix} .slick-row:hover { background-color: ${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) {
|
if (styles.listHoverForeground) {
|
||||||
content.push(`.monaco-table.${this.idPrefix} .slick-row:hover { color: ${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) {
|
if (styles.listSelectionOutline) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { Emitter, Event } from 'vs/base/common/event';
|
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
|
* 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
|
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;
|
background: url("globalerror.svg") center center no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vs .icon.error,
|
.vs .sql.icon.error,
|
||||||
.vs-dark .icon.error,
|
.vs-dark .sql.icon.error,
|
||||||
.hc-black .icon.error {
|
.hc-black .sql.icon.error {
|
||||||
content: url("status_error.svg");
|
content: url("status_error.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
.vs .icon.warning,
|
.vs .sql.icon.warning,
|
||||||
.vs-dark .icon.warning,
|
.vs-dark .sql.icon.warning,
|
||||||
.hc-black .icon.warning {
|
.hc-black .sql.icon.warning {
|
||||||
content: url("status_warning.svg");
|
content: url("status_warning.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
.vs .icon.info,
|
.vs .sql.icon.info,
|
||||||
.vs-dark .icon.info,
|
.vs-dark .sql.icon.info,
|
||||||
.hc-black .icon.info {
|
.hc-black .sql.icon.info {
|
||||||
content: url("status_info.svg");
|
content: url("status_info.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ export class AccountPicker extends Disposable {
|
|||||||
|
|
||||||
// Create refresh account action
|
// Create refresh account action
|
||||||
this._refreshContainer = DOM.append(this._rootElement, DOM.$('div.refresh-container'));
|
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 });
|
let actionBar = new ActionBar(this._refreshContainer, { animated: false });
|
||||||
this._refreshAccountAction = this._instantiationService.createInstance(RefreshAccountAction);
|
this._refreshAccountAction = this._instantiationService.createInstance(RefreshAccountAction);
|
||||||
actionBar.push(this._refreshAccountAction, { icon: false, label: true });
|
actionBar.push(this._refreshAccountAction, { icon: false, label: true });
|
||||||
|
|||||||
@@ -100,10 +100,10 @@ export class ConnectionDialogWidget extends Modal {
|
|||||||
public refresh(): void {
|
public refresh(): void {
|
||||||
let filteredProviderTypes = this.providerTypeOptions;
|
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));
|
let validProviderNames = Object.keys(this.providerNameToDisplayNameMap).filter(x => this.includeProvider(x, this._newConnectionParams));
|
||||||
if (validProviderNames && validProviderNames.length > 0) {
|
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);
|
this._providerTypeSelectBox.setOptions(filteredProviderTypes);
|
||||||
@@ -118,8 +118,8 @@ export class ConnectionDialogWidget extends Modal {
|
|||||||
container.appendChild(connectionContainer.getHTMLElement());
|
container.appendChild(connectionContainer.getHTMLElement());
|
||||||
|
|
||||||
this._bodyBuilder = new Builder(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
|
// Recent connection tab
|
||||||
let recentConnectionTab = $('.connection-recent-tab');
|
let recentConnectionTab = $('.connection-recent-tab');
|
||||||
recentConnectionTab.div({ class: 'connection-recent', id: 'recentConnection' }, (builder) => {
|
recentConnectionTab.div({ class: 'connection-recent', id: 'recentConnection' }, (builder) => {
|
||||||
@@ -182,7 +182,6 @@ export class ConnectionDialogWidget extends Modal {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this._bodyBuilder.div({ class: 'connection-type' }, (modelTableContent) => {
|
this._bodyBuilder.div({ class: 'connection-type' }, (modelTableContent) => {
|
||||||
let connectTypeLabel = localize('connectType', 'Connection type');
|
|
||||||
modelTableContent.element('table', { class: 'connection-table-content' }, (tableContainer) => {
|
modelTableContent.element('table', { class: 'connection-table-content' }, (tableContainer) => {
|
||||||
DialogHelper.appendInputSelectBox(
|
DialogHelper.appendInputSelectBox(
|
||||||
DialogHelper.appendRow(tableContainer, connectTypeLabel, 'connection-label', 'connection-input'), this._providerTypeSelectBox);
|
DialogHelper.appendRow(tableContainer, connectTypeLabel, 'connection-label', 'connection-input'), this._providerTypeSelectBox);
|
||||||
@@ -450,4 +449,4 @@ export class ConnectionDialogWidget extends Modal {
|
|||||||
public get databaseDropdownExpanded(): boolean {
|
public get databaseDropdownExpanded(): boolean {
|
||||||
return this._databaseDropdownExpanded;
|
return this._databaseDropdownExpanded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,6 +65,7 @@ export class ConnectionWidget {
|
|||||||
private _databaseDropdownExpanded: boolean = false;
|
private _databaseDropdownExpanded: boolean = false;
|
||||||
private _defaultDatabaseName: string = localize('defaultDatabaseOption', '<Default>');
|
private _defaultDatabaseName: string = localize('defaultDatabaseOption', '<Default>');
|
||||||
private _loadingDatabaseName: string = localize('loadingDatabaseOption', 'Loading...');
|
private _loadingDatabaseName: string = localize('loadingDatabaseOption', 'Loading...');
|
||||||
|
private _serverGroupDisplayString: string = localize('serverGroup', 'Server group');
|
||||||
public DefaultServerGroup: IConnectionProfileGroup = {
|
public DefaultServerGroup: IConnectionProfileGroup = {
|
||||||
id: '',
|
id: '',
|
||||||
name: localize('defaultServerGroup', '<Default>'),
|
name: localize('defaultServerGroup', '<Default>'),
|
||||||
@@ -112,14 +113,14 @@ export class ConnectionWidget {
|
|||||||
} else {
|
} else {
|
||||||
authTypeOption.defaultValue = this.getAuthTypeDisplayName(Constants.sqlLogin);
|
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;
|
this._providerName = providerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createConnectionWidget(container: HTMLElement): void {
|
public createConnectionWidget(container: HTMLElement): void {
|
||||||
this._serverGroupOptions = [this.DefaultServerGroup];
|
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._previousGroupOption = this._serverGroupSelectBox.value;
|
||||||
this._builder = $().div({ class: 'connection-table' }, (modelTableContent) => {
|
this._builder = $().div({ class: 'connection-table' }, (modelTableContent) => {
|
||||||
modelTableContent.element('table', { class: 'connection-table-content' }, (tableContainer) => {
|
modelTableContent.element('table', { class: 'connection-table-content' }, (tableContainer) => {
|
||||||
@@ -155,11 +156,6 @@ export class ConnectionWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fillInConnectionForm(): void {
|
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
|
// Server name
|
||||||
let serverNameOption = this._optionsMaps[ConnectionOptionSpecialType.serverName];
|
let serverNameOption = this._optionsMaps[ConnectionOptionSpecialType.serverName];
|
||||||
let serverNameBuilder = DialogHelper.appendRow(this._tableContainer, serverNameOption.displayName, 'connection-label', 'connection-input');
|
let serverNameBuilder = DialogHelper.appendRow(this._tableContainer, serverNameOption.displayName, 'connection-label', 'connection-input');
|
||||||
@@ -193,7 +189,6 @@ export class ConnectionWidget {
|
|||||||
},
|
},
|
||||||
ariaLabel: userNameOption.displayName
|
ariaLabel: userNameOption.displayName
|
||||||
});
|
});
|
||||||
|
|
||||||
// Password
|
// Password
|
||||||
let passwordOption = this._optionsMaps[ConnectionOptionSpecialType.password];
|
let passwordOption = this._optionsMaps[ConnectionOptionSpecialType.password];
|
||||||
let passwordBuilder = DialogHelper.appendRow(this._tableContainer, passwordOption.displayName, 'connection-label', 'connection-input');
|
let passwordBuilder = DialogHelper.appendRow(this._tableContainer, passwordOption.displayName, 'connection-label', 'connection-input');
|
||||||
@@ -219,10 +214,14 @@ export class ConnectionWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Server group
|
// Server group
|
||||||
let serverGroupLabel = localize('serverGroup', 'Server group');
|
let serverGroupBuilder = DialogHelper.appendRow(this._tableContainer, this._serverGroupDisplayString, 'connection-label', 'connection-input');
|
||||||
let serverGroupBuilder = DialogHelper.appendRow(this._tableContainer, serverGroupLabel, 'connection-label', 'connection-input');
|
|
||||||
DialogHelper.appendInputSelectBox(serverGroupBuilder, this._serverGroupSelectBox);
|
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...');
|
let AdvancedLabel = localize('advanced', 'Advanced...');
|
||||||
this._advancedButton = this.createAdvancedButton(this._tableContainer, AdvancedLabel);
|
this._advancedButton = this.createAdvancedButton(this._tableContainer, AdvancedLabel);
|
||||||
}
|
}
|
||||||
@@ -399,7 +398,7 @@ export class ConnectionWidget {
|
|||||||
|
|
||||||
public focusOnOpen(): void {
|
public focusOnOpen(): void {
|
||||||
this._handleClipboard();
|
this._handleClipboard();
|
||||||
this._connectionNameInputBox.focus();
|
this._serverNameInputBox.focus();
|
||||||
this.focusPasswordIfNeeded();
|
this.focusPasswordIfNeeded();
|
||||||
this.clearValidationMessages();
|
this.clearValidationMessages();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import * as nls from 'vs/nls';
|
|||||||
import * as objects from 'vs/base/common/objects';
|
import * as objects from 'vs/base/common/objects';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
import { Action } from 'vs/base/common/actions';
|
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 Severity from 'vs/base/common/severity';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
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(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef,
|
||||||
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
|
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
|
||||||
@Inject(INotificationService) private notificationService: INotificationService,
|
@Inject(INotificationService) private notificationService: INotificationService,
|
||||||
@Inject(IAngularEventingService) private angularEventingService: IAngularEventingService
|
@Inject(IAngularEventingService) private angularEventingService: IAngularEventingService,
|
||||||
|
@Inject(IConfigurationService) private configurationService: IConfigurationService
|
||||||
) {
|
) {
|
||||||
super();
|
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
|
// Before separating tabs into pinned / shown, ensure that the home tab is always set up as expected
|
||||||
allTabs = this.setAndRemoveHomeTab(allTabs, homeWidgets);
|
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
|
// Load tab setting configs
|
||||||
this._tabSettingConfigs = this.dashboardService.getSettings<Array<TabSettingConfig>>([this.context, 'tabs'].join('.'));
|
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
|
// Set panel actions
|
||||||
let openedTabs = [...pinnedDashboardTabs, ...alwaysShowTabs];
|
let openedTabs = [...pinnedDashboardTabs, ...alwaysShowTabs];
|
||||||
let addNewTabAction = this.instantiationService.createInstance(AddFeatureTabAction, allTabs, openedTabs, this.dashboardService.getUnderlyingUri());
|
if (extensionTabsEnabled) {
|
||||||
this._tabsDispose.push(addNewTabAction);
|
let addNewTabAction = this.instantiationService.createInstance(AddFeatureTabAction, allTabs, openedTabs, this.dashboardService.getUnderlyingUri());
|
||||||
this.panelActions = [addNewTabAction];
|
this._tabsDispose.push(addNewTabAction);
|
||||||
|
this.panelActions = [addNewTabAction];
|
||||||
|
} else {
|
||||||
|
this.panelActions = [];
|
||||||
|
}
|
||||||
this._cd.detectChanges();
|
this._cd.detectChanges();
|
||||||
|
|
||||||
this._tabsDispose.push(this.dashboardService.onPinUnpinTab(e => {
|
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 { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
|
|
||||||
export class DatabaseDashboardPage extends DashboardPage implements OnInit {
|
export class DatabaseDashboardPage extends DashboardPage implements OnInit {
|
||||||
protected propertiesWidget: WidgetConfig = {
|
protected propertiesWidget: WidgetConfig = {
|
||||||
@@ -43,9 +44,10 @@ export class DatabaseDashboardPage extends DashboardPage implements OnInit {
|
|||||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||||
@Inject(IInstantiationService) instantiationService: IInstantiationService,
|
@Inject(IInstantiationService) instantiationService: IInstantiationService,
|
||||||
@Inject(INotificationService) notificationService: INotificationService,
|
@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._register(dashboardService.onUpdatePage(() => {
|
||||||
this.refresh(true);
|
this.refresh(true);
|
||||||
this._cd.detectChanges();
|
this._cd.detectChanges();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import * as nls from 'vs/nls';
|
|||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
|
|
||||||
export class ServerDashboardPage extends DashboardPage implements OnInit {
|
export class ServerDashboardPage extends DashboardPage implements OnInit {
|
||||||
protected propertiesWidget: WidgetConfig = {
|
protected propertiesWidget: WidgetConfig = {
|
||||||
@@ -44,9 +45,10 @@ export class ServerDashboardPage extends DashboardPage implements OnInit {
|
|||||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||||
@Inject(IInstantiationService) instantiationService: IInstantiationService,
|
@Inject(IInstantiationService) instantiationService: IInstantiationService,
|
||||||
@Inject(INotificationService) notificationService: INotificationService,
|
@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
|
// revert back to default database
|
||||||
this._letDashboardPromise = this.dashboardService.connectionManagementService.changeDatabase('master');
|
this._letDashboardPromise = this.dashboardService.connectionManagementService.changeDatabase('master');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export class TasksWidget extends DashboardWidget implements IDashboardWidget, On
|
|||||||
}).filter(i => !!i);
|
}).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() {
|
ngOnInit() {
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
<div class="option check" #encryptCheckContainer>
|
<div class="option check" #encryptCheckContainer>
|
||||||
</div>
|
</div>
|
||||||
<div class="option" #encryptWarningContainer>
|
<div class="option" #encryptWarningContainer>
|
||||||
<div class="icon warning">
|
<div class="sql icon warning">
|
||||||
</div>
|
</div>
|
||||||
<div class="warning-message">
|
<div class="warning-message">
|
||||||
{{localizedStrings.NO_ENCRYPTOR_WARNING}}
|
{{localizedStrings.NO_ENCRYPTOR_WARNING}}
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ export class BackupComponent {
|
|||||||
ariaLabel: LocalizedStrings.RECOVERY_MODEL
|
ariaLabel: LocalizedStrings.RECOVERY_MODEL
|
||||||
});
|
});
|
||||||
// Set backup type
|
// 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);
|
this.backupTypeSelectBox.render(this.backupTypeElement.nativeElement);
|
||||||
|
|
||||||
// Set copy-only check box
|
// Set copy-only check box
|
||||||
@@ -283,13 +283,13 @@ export class BackupComponent {
|
|||||||
this.removePathButton.title = localize('removeFile', 'Remove files');
|
this.removePathButton.title = localize('removeFile', 'Remove files');
|
||||||
|
|
||||||
// Set compression
|
// 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);
|
this.compressionSelectBox.render(this.compressionElement.nativeElement);
|
||||||
|
|
||||||
// Set encryption
|
// 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.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);
|
this.encryptorSelectBox.render(this.encryptorElement.nativeElement);
|
||||||
|
|
||||||
// Set media
|
// Set media
|
||||||
@@ -911,4 +911,4 @@ export class BackupComponent {
|
|||||||
|
|
||||||
return backupInfo;
|
return backupInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -273,7 +273,7 @@ export class RestoreDialog extends Modal {
|
|||||||
labelContainer.hide();
|
labelContainer.hide();
|
||||||
this._restorePlanData = new TableDataView<Slick.SlickData>();
|
this._restorePlanData = new TableDataView<Slick.SlickData>();
|
||||||
this._restorePlanTable = new Table<Slick.SlickData>(labelContainer.getHTMLElement(),
|
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.setSelectionModel(new RowSelectionModel({ selectActiveRow: false }));
|
||||||
this._restorePlanTable.onSelectedRowsChanged((e, data) => this.backupFileCheckboxChanged(e, data));
|
this._restorePlanTable.onSelectedRowsChanged((e, data) => this.backupFileCheckboxChanged(e, data));
|
||||||
});
|
});
|
||||||
@@ -330,7 +330,7 @@ export class RestoreDialog extends Modal {
|
|||||||
}];
|
}];
|
||||||
this._fileListData = new TableDataView<FileListElement>();
|
this._fileListData = new TableDataView<FileListElement>();
|
||||||
this._fileListTable = new Table<FileListElement>(fileNameContainer.getHTMLElement(),
|
this._fileListTable = new Table<FileListElement>(fileNameContainer.getHTMLElement(),
|
||||||
{ dataProvider : this._fileListData, columns } , { enableColumnReorder: false });
|
{ dataProvider: this._fileListData, columns }, { enableColumnReorder: false });
|
||||||
this._fileListTable.setSelectionModel(new RowSelectionModel());
|
this._fileListTable.setSelectionModel(new RowSelectionModel());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -541,7 +541,7 @@ export class RestoreDialog extends Modal {
|
|||||||
});
|
});
|
||||||
|
|
||||||
inputContainer.div({ class: 'dialog-input' }, (inputCellContainer) => {
|
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());
|
selectBox.render(inputCellContainer.getHTMLElement());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ classes should alter those!
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
-o-text-overflow: ellipsis;
|
-o-text-overflow: ellipsis;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
height: 16px;
|
height: 28px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
@@ -35,7 +35,7 @@ classes should alter those!
|
|||||||
border-bottom: 2px solid #bbb;
|
border-bottom: 2px solid #bbb;
|
||||||
float: left;
|
float: left;
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
box-sizing: content-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slick-headerrow-column.ui-state-default, .slick-footerrow-column.ui-state-default {
|
.slick-headerrow-column.ui-state-default, .slick-footerrow-column.ui-state-default {
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
|
|||||||
@Inject(forwardRef(() => ChangeDetectorRef)) cd: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) cd: ChangeDetectorRef,
|
||||||
@Inject(IBootstrapParams) params: IEditDataComponentParams,
|
@Inject(IBootstrapParams) params: IEditDataComponentParams,
|
||||||
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
|
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
|
||||||
@Inject(INotificationService) private notificationService: INotificationService,
|
@Inject(INotificationService) notificationService: INotificationService,
|
||||||
@Inject(IContextMenuService) contextMenuService: IContextMenuService,
|
@Inject(IContextMenuService) contextMenuService: IContextMenuService,
|
||||||
@Inject(IKeybindingService) keybindingService: IKeybindingService,
|
@Inject(IKeybindingService) keybindingService: IKeybindingService,
|
||||||
@Inject(IContextKeyService) contextKeyService: IContextKeyService,
|
@Inject(IContextKeyService) contextKeyService: IContextKeyService,
|
||||||
@@ -96,7 +96,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
|
|||||||
@Inject(IClipboardService) clipboardService: IClipboardService,
|
@Inject(IClipboardService) clipboardService: IClipboardService,
|
||||||
@Inject(IQueryEditorService) queryEditorService: IQueryEditorService
|
@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._el.nativeElement.className = 'slickgridContainer';
|
||||||
this.dataService = params.dataService;
|
this.dataService = params.dataService;
|
||||||
this.actionProvider = this.instantiationService.createInstance(EditDataGridActionProvider, this.dataService, this.onGridSelectAll(), this.onDeleteRow(), this.onRevertRow());
|
this.actionProvider = this.instantiationService.createInstance(EditDataGridActionProvider, this.dataService, this.onGridSelectAll(), this.onDeleteRow(), this.onRevertRow());
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
|||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||||
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
|
|
||||||
export abstract class GridParentComponent {
|
export abstract class GridParentComponent {
|
||||||
// CONSTANTS
|
// CONSTANTS
|
||||||
@@ -100,7 +101,8 @@ export abstract class GridParentComponent {
|
|||||||
protected contextKeyService: IContextKeyService,
|
protected contextKeyService: IContextKeyService,
|
||||||
protected configurationService: IConfigurationService,
|
protected configurationService: IConfigurationService,
|
||||||
protected clipboardService: IClipboardService,
|
protected clipboardService: IClipboardService,
|
||||||
protected queryEditorService: IQueryEditorService
|
protected queryEditorService: IQueryEditorService,
|
||||||
|
protected notificationService: INotificationService
|
||||||
) {
|
) {
|
||||||
this.toDispose = [];
|
this.toDispose = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
|||||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
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';
|
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'; },
|
icon: () => { return 'viewChart'; },
|
||||||
hoverText: () => { return LocalizedConstants.viewChartLabel; },
|
hoverText: () => { return LocalizedConstants.viewChartLabel; },
|
||||||
functionality: (batchId, resultId, index) => {
|
functionality: (batchId, resultId, index) => {
|
||||||
@@ -187,9 +191,10 @@ export class QueryComponent extends GridParentComponent implements OnInit, OnDes
|
|||||||
@Inject(IContextKeyService) contextKeyService: IContextKeyService,
|
@Inject(IContextKeyService) contextKeyService: IContextKeyService,
|
||||||
@Inject(IConfigurationService) configurationService: IConfigurationService,
|
@Inject(IConfigurationService) configurationService: IConfigurationService,
|
||||||
@Inject(IClipboardService) clipboardService: IClipboardService,
|
@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._el.nativeElement.className = 'slickgridContainer';
|
||||||
this.rowHeight = configurationService.getValue<any>('resultsGrid').rowHeight;
|
this.rowHeight = configurationService.getValue<any>('resultsGrid').rowHeight;
|
||||||
configurationService.onDidChangeConfiguration(e => {
|
configurationService.onDidChangeConfiguration(e => {
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ import * as sqlops from 'sqlops';
|
|||||||
import { ComponentWithIconBase } from 'sql/parts/modelComponents/componentWithIconBase';
|
import { ComponentWithIconBase } from 'sql/parts/modelComponents/componentWithIconBase';
|
||||||
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
|
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
|
||||||
import { attachButtonStyler } from 'sql/common/theme/styler';
|
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 { SIDE_BAR_BACKGROUND, SIDE_BAR_TITLE_FOREGROUND } from 'vs/workbench/common/theme';
|
||||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||||
import { focusBorder, foreground } from 'vs/platform/theme/common/colorRegistry';
|
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';
|
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;
|
@ViewChild('fileInput', { read: ElementRef }) private _fileInputContainer: ElementRef;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
@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 {
|
ngOnInit(): void {
|
||||||
@@ -63,7 +64,7 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
|
|||||||
if (this._fileInputContainer) {
|
if (this._fileInputContainer) {
|
||||||
const self = this;
|
const self = this;
|
||||||
this._fileInputContainer.nativeElement.onchange = () => {
|
this._fileInputContainer.nativeElement.onchange = () => {
|
||||||
let file = self._fileInputContainer.nativeElement.files[0];
|
let file = self._fileInputContainer.nativeElement.files[0];
|
||||||
let reader = new FileReader();
|
let reader = new FileReader();
|
||||||
reader.onload = (e) => {
|
reader.onload = (e) => {
|
||||||
let text = (<FileReader>e.target).result;
|
let text = (<FileReader>e.target).result;
|
||||||
@@ -100,6 +101,7 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
|
|||||||
super.setProperties(properties);
|
super.setProperties(properties);
|
||||||
this._button.enabled = this.enabled;
|
this._button.enabled = this.enabled;
|
||||||
this._button.label = this.label;
|
this._button.label = this.label;
|
||||||
|
this._button.title = this.title;
|
||||||
if (this.width) {
|
if (this.width) {
|
||||||
this._button.setWidth(this.convertSize(this.width.toString()));
|
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);
|
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;
|
properties.fileContent = fileContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,4 +166,13 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
|
|||||||
private setFileProperties(properties: sqlops.ButtonProperties, isFile: boolean): void {
|
private setFileProperties(properties: sqlops.ButtonProperties, isFile: boolean): void {
|
||||||
properties.isFile = isFile;
|
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 'vs/css!./card';
|
||||||
|
|
||||||
import { Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver,
|
import {
|
||||||
|
Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver,
|
||||||
ViewChild, ViewChildren, ElementRef, Injector, OnDestroy, QueryList,
|
ViewChild, ViewChildren, ElementRef, Injector, OnDestroy, QueryList,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
@@ -28,11 +29,11 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
|
|||||||
|
|
||||||
private backgroundColor: string;
|
private backgroundColor: string;
|
||||||
|
|
||||||
constructor(@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
constructor( @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService
|
||||||
) {
|
) {
|
||||||
super(changeRef);
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@@ -70,7 +71,7 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
|
|||||||
|
|
||||||
public getClass(): string {
|
public getClass(): string {
|
||||||
return (this.selectable && this.selected || this._hasFocus) ? 'model-card selected' :
|
return (this.selectable && this.selected || this._hasFocus) ? 'model-card selected' :
|
||||||
'model-card unselected';
|
'model-card unselected';
|
||||||
}
|
}
|
||||||
|
|
||||||
public onCardHoverChanged(event: any) {
|
public onCardHoverChanged(event: any) {
|
||||||
@@ -81,7 +82,7 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
|
|||||||
}
|
}
|
||||||
/// IComponent implementation
|
/// IComponent implementation
|
||||||
|
|
||||||
public setLayout (layout: any): void {
|
public setLayout(layout: any): void {
|
||||||
// TODO allow configuring the look and feel
|
// TODO allow configuring the look and feel
|
||||||
this.layout();
|
this.layout();
|
||||||
}
|
}
|
||||||
@@ -141,7 +142,7 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
|
|||||||
|
|
||||||
public get statusColor(): string {
|
public get statusColor(): string {
|
||||||
let status = this.getPropertyOrDefault<CardProperties, StatusIndicator>((props) => props.status, StatusIndicator.None);
|
let status = this.getPropertyOrDefault<CardProperties, StatusIndicator>((props) => props.status, StatusIndicator.None);
|
||||||
switch(status) {
|
switch (status) {
|
||||||
case StatusIndicator.Ok:
|
case StatusIndicator.Ok:
|
||||||
return 'green';
|
return 'green';
|
||||||
case StatusIndicator.Warning:
|
case StatusIndicator.Warning:
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ export default class CheckBoxComponent extends ComponentBase implements ICompone
|
|||||||
@ViewChild('input', { read: ElementRef }) private _inputContainer: ElementRef;
|
@ViewChild('input', { read: ElementRef }) private _inputContainer: ElementRef;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
super(changeRef);
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||||
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { Event, Emitter } from 'vs/base/common/event';
|
|||||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { ModelComponentWrapper } from 'sql/parts/modelComponents/modelComponentWrapper.component';
|
import { ModelComponentWrapper } from 'sql/parts/modelComponents/modelComponentWrapper.component';
|
||||||
import URI from 'vs/base/common/uri';
|
import URI from 'vs/base/common/uri';
|
||||||
|
import { Builder } from 'vs/base/browser/builder';
|
||||||
import { IdGenerator } from 'vs/base/common/idGenerator';
|
import { IdGenerator } from 'vs/base/common/idGenerator';
|
||||||
import { createCSSRule, removeCSSRulesContainingSelector } from 'vs/base/browser/dom';
|
import { createCSSRule, removeCSSRulesContainingSelector } from 'vs/base/browser/dom';
|
||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
@@ -35,8 +36,11 @@ export abstract class ComponentBase extends Disposable implements IComponent, On
|
|||||||
private _valid: boolean = true;
|
private _valid: boolean = true;
|
||||||
protected _validations: (() => boolean | Thenable<boolean>)[] = [];
|
protected _validations: (() => boolean | Thenable<boolean>)[] = [];
|
||||||
private _eventQueue: IComponentEventArgs[] = [];
|
private _eventQueue: IComponentEventArgs[] = [];
|
||||||
|
private _CSSStyles: { [key: string]: string } = {};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected _changeRef: ChangeDetectorRef) {
|
protected _changeRef: ChangeDetectorRef,
|
||||||
|
protected _el: ElementRef) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,11 +84,20 @@ export abstract class ComponentBase extends Disposable implements IComponent, On
|
|||||||
public refreshDataProvider(item: any): void {
|
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 {
|
public setProperties(properties: { [key: string]: any; }): void {
|
||||||
if (!properties) {
|
if (!properties) {
|
||||||
this.properties = {};
|
this.properties = {};
|
||||||
}
|
}
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
|
if (this.CSSStyles !== this._CSSStyles) {
|
||||||
|
this.updateStyles();
|
||||||
|
}
|
||||||
this.layout();
|
this.layout();
|
||||||
this.validate();
|
this.validate();
|
||||||
}
|
}
|
||||||
@@ -140,11 +153,19 @@ export abstract class ComponentBase extends Disposable implements IComponent, On
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get position(): string {
|
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) {
|
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 {
|
public convertSizeToNumber(size: number | string): number {
|
||||||
@@ -223,9 +244,10 @@ export abstract class ContainerBase<T> extends ComponentBase {
|
|||||||
|
|
||||||
@ViewChildren(ModelComponentWrapper) protected _componentWrappers: QueryList<ModelComponentWrapper>;
|
@ViewChildren(ModelComponentWrapper) protected _componentWrappers: QueryList<ModelComponentWrapper>;
|
||||||
constructor(
|
constructor(
|
||||||
_changeRef: ChangeDetectorRef
|
_changeRef: ChangeDetectorRef,
|
||||||
|
_el: ElementRef
|
||||||
) {
|
) {
|
||||||
super(_changeRef);
|
super(_changeRef, _el);
|
||||||
this.items = [];
|
this.items = [];
|
||||||
this._validations.push(() => this.items.every(item => {
|
this._validations.push(() => this.items.every(item => {
|
||||||
return this.modelStore.getComponent(item.descriptor.id).valid;
|
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) {
|
if (index !== undefined && index !== null && index >= 0 && index < this.items.length) {
|
||||||
this.items.splice(index, 0, new ItemDescriptor(componentDescriptor, config));
|
this.items.splice(index, 0, new ItemDescriptor(componentDescriptor, config));
|
||||||
} else if(!index) {
|
} else if (!index) {
|
||||||
this.items.push(new ItemDescriptor(componentDescriptor, config));
|
this.items.push(new ItemDescriptor(componentDescriptor, config));
|
||||||
} else {
|
} else {
|
||||||
throw new Error(nls.localize('invalidIndex', 'The index is invalid.'));
|
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) { }
|
constructor(public descriptor: IComponentDescriptor, public config: T) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ids = new IdGenerator('model-view-component-icon-');
|
||||||
|
|
||||||
export abstract class ComponentWithIconBase extends ComponentBase {
|
export abstract class ComponentWithIconBase extends ComponentBase {
|
||||||
|
|
||||||
protected _iconClass: string;
|
protected _iconClass: string;
|
||||||
protected _iconPath: IUserFriendlyIcon;
|
protected _iconPath: IUserFriendlyIcon;
|
||||||
constructor(
|
constructor(
|
||||||
changeRef: ChangeDetectorRef) {
|
changeRef: ChangeDetectorRef,
|
||||||
super(changeRef);
|
el: ElementRef, ) {
|
||||||
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// IComponent implementation
|
/// IComponent implementation
|
||||||
@@ -41,7 +44,6 @@ export abstract class ComponentWithIconBase extends ComponentBase {
|
|||||||
if (this.iconPath && this.iconPath !== this._iconPath) {
|
if (this.iconPath && this.iconPath !== this._iconPath) {
|
||||||
this._iconPath = this.iconPath;
|
this._iconPath = this.iconPath;
|
||||||
if (!this._iconClass) {
|
if (!this._iconClass) {
|
||||||
const ids = new IdGenerator('model-view-component-icon-' + Math.round(Math.random() * 1000));
|
|
||||||
this._iconClass = ids.nextId();
|
this._iconClass = ids.nextId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* 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 FlexContainer from './flexContainer.component';
|
||||||
import FormContainer from './formContainer.component';
|
import FormContainer from './formContainer.component';
|
||||||
import ToolbarContainer from './toolbarContainer.component';
|
import ToolbarContainer from './toolbarContainer.component';
|
||||||
@@ -25,6 +25,9 @@ import EditorComponent from './editor.component';
|
|||||||
import { registerComponentType } from 'sql/platform/dashboard/common/modelComponentRegistry';
|
import { registerComponentType } from 'sql/platform/dashboard/common/modelComponentRegistry';
|
||||||
import { ModelComponentTypes } from 'sql/workbench/api/common/sqlExtHostTypes';
|
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';
|
export const FLEX_CONTAINER = 'flex-container';
|
||||||
registerComponentType(FLEX_CONTAINER, ModelComponentTypes.FlexContainer, FlexContainer);
|
registerComponentType(FLEX_CONTAINER, ModelComponentTypes.FlexContainer, FlexContainer);
|
||||||
|
|
||||||
|
|||||||
@@ -64,9 +64,10 @@ export default class DeclarativeTableComponent extends ComponentBase implements
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
@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 {
|
ngOnInit(): void {
|
||||||
@@ -134,7 +135,7 @@ export default class DeclarativeTableComponent extends ComponentBase implements
|
|||||||
private onCellDataChanged(newValue: any, row: number, cell: number): void {
|
private onCellDataChanged(newValue: any, row: number, cell: number): void {
|
||||||
this.data[row][cell] = newValue;
|
this.data[row][cell] = newValue;
|
||||||
this.data = this.data;
|
this.data = this.data;
|
||||||
let newCellData : sqlops.TableCell = {
|
let newCellData: sqlops.TableCell = {
|
||||||
row: row,
|
row: row,
|
||||||
column: cell,
|
column: cell,
|
||||||
value: newValue
|
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%;
|
||||||
|
}
|
||||||
@@ -41,9 +41,10 @@ export default class DropDownComponent extends ComponentBase implements ICompone
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
@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 {
|
ngOnInit(): void {
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ export default class EditorComponent extends ComponentBase implements IComponent
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||||
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
|
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
|
||||||
@Inject(IModelService) private _modelService: IModelService,
|
@Inject(IModelService) private _modelService: IModelService,
|
||||||
@Inject(IModeService) private _modeService: IModeService
|
@Inject(IModeService) private _modeService: IModeService
|
||||||
) {
|
) {
|
||||||
super(changeRef);
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@@ -63,7 +63,7 @@ export default class EditorComponent extends ComponentBase implements IComponent
|
|||||||
this._editor.create(this._el.nativeElement);
|
this._editor.create(this._el.nativeElement);
|
||||||
this._editor.setVisible(true);
|
this._editor.setVisible(true);
|
||||||
let uri = this.createUri();
|
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._editor.setInput(this._editorInput, undefined);
|
||||||
this._editorInput.resolve().then(model => {
|
this._editorInput.resolve().then(model => {
|
||||||
this._editorModel = model.textEditorModel;
|
this._editorModel = model.textEditorModel;
|
||||||
@@ -107,7 +107,7 @@ export default class EditorComponent extends ComponentBase implements IComponent
|
|||||||
this._editor.layout(new DOM.Dimension(
|
this._editor.layout(new DOM.Dimension(
|
||||||
width && width > 0 ? width : DOM.getContentWidth(this._el.nativeElement),
|
width && width > 0 ? width : DOM.getContentWidth(this._el.nativeElement),
|
||||||
height && height > 0 ? height : DOM.getContentHeight(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;
|
element.style.position = this.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +129,6 @@ export default class EditorComponent extends ComponentBase implements IComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// IComponent implementation
|
/// IComponent implementation
|
||||||
|
|
||||||
public setLayout(layout: any): void {
|
public setLayout(layout: any): void {
|
||||||
// TODO allow configuring the look and feel
|
// TODO allow configuring the look and feel
|
||||||
this.layout();
|
this.layout();
|
||||||
|
|||||||
@@ -27,15 +27,16 @@ export default class FileBrowserTreeComponent extends ComponentBase implements I
|
|||||||
@Input() modelStore: IModelStore;
|
@Input() modelStore: IModelStore;
|
||||||
private _treeView: FileBrowserTreeView;
|
private _treeView: FileBrowserTreeView;
|
||||||
private _viewModel: FileBrowserViewModel;
|
private _viewModel: FileBrowserViewModel;
|
||||||
private _fileFilters: [{label: string, filters: string[]}] = [
|
private _fileFilters: [{ label: string, filters: string[] }] = [
|
||||||
{ label: 'All Files', filters: ['*'] }
|
{ label: 'All Files', filters: ['*'] }
|
||||||
];
|
];
|
||||||
|
|
||||||
@ViewChild('fileBrowserTree', { read: ElementRef }) private _treeContainer: ElementRef;
|
@ViewChild('fileBrowserTree', { read: ElementRef }) private _treeContainer: ElementRef;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
@Inject(IInstantiationService) private _instantiationService: IInstantiationService) {
|
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
|
||||||
super(changeRef);
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||||
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|||||||
@@ -45,8 +45,11 @@ export default class FlexContainer extends ContainerBase<FlexItemLayout> impleme
|
|||||||
private _width: string;
|
private _width: string;
|
||||||
private _position: string;
|
private _position: string;
|
||||||
|
|
||||||
constructor(@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
constructor(
|
||||||
super(changeRef);
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||||
|
) {
|
||||||
|
super(changeRef, el);
|
||||||
this._flexFlow = ''; // default
|
this._flexFlow = ''; // default
|
||||||
this._justifyContent = ''; // default
|
this._justifyContent = ''; // default
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,8 +106,9 @@ export default class FormContainer extends ContainerBase<FormItemLayout> impleme
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
super(changeRef);
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||||
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|||||||
@@ -45,8 +45,9 @@ export default class GroupContainer extends ContainerBase<GroupLayout> implement
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
super(changeRef);
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||||
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|||||||
@@ -42,9 +42,10 @@ export default class InputBoxComponent extends ComponentBase implements ICompone
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
@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 {
|
ngOnInit(): void {
|
||||||
|
|||||||
@@ -37,9 +37,10 @@ export default class ListBoxComponent extends ComponentBase implements IComponen
|
|||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||||
@Inject(IContextViewService) private contextViewService: IContextViewService,
|
@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 {
|
ngOnInit(): void {
|
||||||
|
|||||||
@@ -35,8 +35,9 @@ export default class LoadingComponent extends ComponentBase implements IComponen
|
|||||||
@ViewChild('childElement', { read: ElementRef }) private _childElement: ElementRef;
|
@ViewChild('childElement', { read: ElementRef }) private _childElement: ElementRef;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
super(changeRef);
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||||
|
super(changeRef, el);
|
||||||
this._validations.push(() => {
|
this._validations.push(() => {
|
||||||
if (!this._component) {
|
if (!this._component) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -3,16 +3,50 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* 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 { TPromise } from 'vs/base/common/winjs.base';
|
||||||
import { IEditorModel } from 'vs/platform/editor/common/editor';
|
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 * as DOM from 'vs/base/browser/dom';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
|
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
|
||||||
|
|
||||||
import { DialogPane } from 'sql/platform/dialog/dialogPane';
|
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 {
|
export class ModelViewInput extends EditorInput {
|
||||||
|
|
||||||
public static ID: string = 'workbench.editorinputs.ModelViewEditorInput';
|
public static ID: string = 'workbench.editorinputs.ModelViewEditorInput';
|
||||||
@@ -20,14 +54,15 @@ export class ModelViewInput extends EditorInput {
|
|||||||
private _dialogPaneContainer: HTMLElement;
|
private _dialogPaneContainer: HTMLElement;
|
||||||
private _dialogPane: DialogPane;
|
private _dialogPane: DialogPane;
|
||||||
|
|
||||||
constructor(private _title: string, private _modelViewId: string,
|
constructor(private _title: string, private _model: ModelViewInputModel,
|
||||||
private _options: sqlops.ModelViewEditorOptions,
|
private _options: sqlops.ModelViewEditorOptions,
|
||||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||||
@IPartService private readonly _partService: IPartService
|
@IPartService private readonly _partService: IPartService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
this._model.onDidChangeDirty(() => this._onDidChangeDirty.fire());
|
||||||
this._container = document.createElement('div');
|
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);
|
this._partService.getContainer(Parts.EDITOR_PART).appendChild(this._container);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -37,7 +72,7 @@ export class ModelViewInput extends EditorInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get modelViewId(): string {
|
public get modelViewId(): string {
|
||||||
return this._modelViewId;
|
return this._model.modelViewId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTypeId(): string {
|
public getTypeId(): string {
|
||||||
@@ -85,6 +120,31 @@ export class ModelViewInput extends EditorInput {
|
|||||||
return this._options;
|
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 {
|
public dispose(): void {
|
||||||
if (this._dialogPane) {
|
if (this._dialogPane) {
|
||||||
this._dialogPane.dispose();
|
this._dialogPane.dispose();
|
||||||
@@ -93,6 +153,9 @@ export class ModelViewInput extends EditorInput {
|
|||||||
this._container.remove();
|
this._container.remove();
|
||||||
this._container = undefined;
|
this._container = undefined;
|
||||||
}
|
}
|
||||||
|
if (this._model) {
|
||||||
|
this._model.dispose();
|
||||||
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,9 @@ export default class RadioButtonComponent extends ComponentBase implements IComp
|
|||||||
@ViewChild('input', { read: ElementRef }) private _inputContainer: ElementRef;
|
@ViewChild('input', { read: ElementRef }) private _inputContainer: ElementRef;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
super(changeRef);
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||||
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|||||||
@@ -35,8 +35,9 @@ export default class TableComponent extends ComponentBase implements IComponent,
|
|||||||
@ViewChild('table', { read: ElementRef }) private _inputContainer: ElementRef;
|
@ViewChild('table', { read: ElementRef }) private _inputContainer: ElementRef;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService) {
|
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||||
super(changeRef);
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||||
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import 'vs/css!./radioButton';
|
import 'vs/css!./radioButton';
|
||||||
import {
|
import {
|
||||||
Component, Input, Inject, ChangeDetectorRef, forwardRef,
|
Component, Input, Inject, ChangeDetectorRef, forwardRef,
|
||||||
OnDestroy, AfterViewInit
|
OnDestroy, AfterViewInit, ElementRef
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
import * as sqlops from 'sqlops';
|
import * as sqlops from 'sqlops';
|
||||||
@@ -26,8 +26,9 @@ export default class TextComponent extends ComponentBase implements IComponent,
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
super(changeRef);
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||||
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export class ToolbarItem {
|
|||||||
template: `
|
template: `
|
||||||
<div #container *ngIf="items" [class]="toolbarClass" >
|
<div #container *ngIf="items" [class]="toolbarClass" >
|
||||||
<ng-container *ngFor="let item of items">
|
<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" >
|
<div *ngIf="shouldShowTitle(item)" class="modelview-toolbar-title" >
|
||||||
{{getItemTitle(item)}}
|
{{getItemTitle(item)}}
|
||||||
</div>
|
</div>
|
||||||
@@ -52,8 +52,9 @@ export default class ToolbarContainer extends ContainerBase<ToolbarItemConfig> i
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
super(changeRef);
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||||
|
super(changeRef, el);
|
||||||
this._orientation = Orientation.Horizontal;
|
this._orientation = Orientation.Horizontal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +90,7 @@ export default class ToolbarContainer extends ContainerBase<ToolbarItemConfig> i
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get paddingTop(): string {
|
public get paddingTop(): string {
|
||||||
return this.isHorizontal() ? '' : '10px';
|
return this.isHorizontal() ? '' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public get toolbarClass(): string {
|
public get toolbarClass(): string {
|
||||||
|
|||||||
@@ -30,6 +30,13 @@
|
|||||||
padding-left: 10px;
|
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 {
|
.modelview-toolbar-container .modelview-toolbar-title {
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -46,4 +53,21 @@
|
|||||||
padding-left: 15px;
|
padding-left: 15px;
|
||||||
background-size: 11px;
|
background-size: 11px;
|
||||||
margin-right: 0.3em;
|
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(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||||
@Inject(IContextViewService) private contextViewService: IContextViewService,
|
@Inject(IContextViewService) private contextViewService: IContextViewService,
|
||||||
@Inject(IInstantiationService) private _instantiationService: IInstantiationService) {
|
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
|
||||||
super(changeRef);
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||||
|
) {
|
||||||
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@@ -112,7 +114,7 @@ export default class TreeComponent extends ComponentBase implements IComponent,
|
|||||||
this._tree.domFocus();
|
this._tree.domFocus();
|
||||||
this._register(this._tree);
|
this._register(this._tree);
|
||||||
this._register(attachListStyler(this._tree, this.themeService));
|
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._dataProvider.onNodeSelected(e.selection);
|
||||||
}));
|
}));
|
||||||
this._tree.refresh();
|
this._tree.refresh();
|
||||||
|
|||||||
@@ -29,11 +29,6 @@ export class TreeViewDataProvider extends vsTreeView.TreeViewDataProvider implem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
refresh(itemsToRefreshByHandle: { [treeItemHandle: string]: ITreeComponentItem }) {
|
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 { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
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({
|
@Component({
|
||||||
template: '',
|
template: '',
|
||||||
selector: 'modelview-webview-component'
|
selector: 'modelview-webview-component'
|
||||||
@@ -46,7 +53,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||||
@Inject(IPartService) private partService: IPartService,
|
@Inject(IPartService) private partService: IPartService,
|
||||||
@Inject(IThemeService) private themeService: IThemeService,
|
@Inject(IThemeService) private themeService: IThemeService,
|
||||||
@Inject(IEnvironmentService) private environmentService: IEnvironmentService,
|
@Inject(IEnvironmentService) private environmentService: IEnvironmentService,
|
||||||
@@ -56,7 +63,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
|
|||||||
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
|
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
|
||||||
@Inject(IContextKeyService) contextKeyService: IContextKeyService
|
@Inject(IContextKeyService) contextKeyService: IContextKeyService
|
||||||
) {
|
) {
|
||||||
super(changeRef);
|
super(changeRef, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@@ -132,7 +139,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
|
|||||||
/// IComponent implementation
|
/// IComponent implementation
|
||||||
|
|
||||||
public layout(): void {
|
public layout(): void {
|
||||||
let element = <HTMLElement> this._el.nativeElement;
|
let element = <HTMLElement>this._el.nativeElement;
|
||||||
element.style.position = this.position;
|
element.style.position = this.position;
|
||||||
this._webview.layout();
|
this._webview.layout();
|
||||||
}
|
}
|
||||||
@@ -192,6 +199,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
|
|||||||
|
|
||||||
private getExtendedOptions(): WebviewOptions {
|
private getExtendedOptions(): WebviewOptions {
|
||||||
let options = this.options || { enableScripts: true };
|
let options = this.options || { enableScripts: true };
|
||||||
|
options = reviveWebviewOptions(options);
|
||||||
return {
|
return {
|
||||||
allowScripts: options.enableScripts,
|
allowScripts: options.enableScripts,
|
||||||
allowSvgs: true,
|
allowSvgs: true,
|
||||||
@@ -208,4 +216,5 @@ export default class WebViewComponent extends ComponentBase implements IComponen
|
|||||||
}
|
}
|
||||||
return rootPaths;
|
return rootPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ const viewletDescriptor = new ViewletDescriptor(
|
|||||||
VIEWLET_ID,
|
VIEWLET_ID,
|
||||||
'Servers',
|
'Servers',
|
||||||
'connectionViewlet',
|
'connectionViewlet',
|
||||||
-100
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(viewletDescriptor);
|
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(viewletDescriptor);
|
||||||
|
|||||||
@@ -82,12 +82,12 @@ export class RowCountStatusBarItem implements IStatusbarItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _displayValue(runner: QueryRunner) {
|
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 p + c.resultSetSummaries.reduce((rp, rc) => {
|
||||||
return rp + rc.rowCount;
|
return rp + rc.rowCount;
|
||||||
}, 0);
|
}, 0);
|
||||||
}, 0);
|
}, 0);
|
||||||
this._flavorElement.innerText = nls.localize('rowCount', "{0} rows", number);
|
this._flavorElement.innerText = nls.localize('rowCount', "{0} rows", rowCount);
|
||||||
show(this._flavorElement);
|
show(this._flavorElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,13 +11,14 @@ import { localize } from 'vs/nls';
|
|||||||
import { TPromise } from 'vs/base/common/winjs.base';
|
import { TPromise } from 'vs/base/common/winjs.base';
|
||||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||||
import { ITree } from 'vs/base/parts/tree/browser/tree';
|
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 QueryRunner from 'sql/parts/query/execution/queryRunner';
|
||||||
import { SaveFormat } from 'sql/parts/grid/common/interfaces';
|
import { SaveFormat } from 'sql/parts/grid/common/interfaces';
|
||||||
import { Table } from 'sql/base/browser/ui/table/table';
|
import { Table } from 'sql/base/browser/ui/table/table';
|
||||||
import { GridTableState } from 'sql/parts/query/editor/gridPanel';
|
import { GridTableState } from 'sql/parts/query/editor/gridPanel';
|
||||||
import { QueryEditor } from './queryEditor';
|
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 {
|
export interface IGridActionContext {
|
||||||
cell: { row: number; cell: number; };
|
cell: { row: number; cell: number; };
|
||||||
@@ -26,6 +27,7 @@ export interface IGridActionContext {
|
|||||||
batchId: number;
|
batchId: number;
|
||||||
resultId: number;
|
resultId: number;
|
||||||
table: Table<any>;
|
table: Table<any>;
|
||||||
|
selectionModel: CellSelectionModel<any>;
|
||||||
tableState: GridTableState;
|
tableState: GridTableState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +36,14 @@ export interface IMessagesActionContext {
|
|||||||
tree: ITree;
|
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 {
|
export class SaveResultAction extends Action {
|
||||||
public static SAVECSV_ID = 'grid.saveAsCsv';
|
public static SAVECSV_ID = 'grid.saveAsCsv';
|
||||||
public static SAVECSV_LABEL = localize('saveAsCsv', 'Save As CSV');
|
public static SAVECSV_LABEL = localize('saveAsCsv', 'Save As CSV');
|
||||||
@@ -51,13 +61,19 @@ export class SaveResultAction extends Action {
|
|||||||
id: string,
|
id: string,
|
||||||
label: string,
|
label: string,
|
||||||
icon: string,
|
icon: string,
|
||||||
private format: SaveFormat
|
private format: SaveFormat,
|
||||||
|
private accountForNumberColumn = true
|
||||||
) {
|
) {
|
||||||
super(id, label, icon);
|
super(id, label, icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
public run(context: IGridActionContext): TPromise<boolean> {
|
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);
|
return TPromise.as(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,12 +89,19 @@ export class CopyResultAction extends Action {
|
|||||||
id: string,
|
id: string,
|
||||||
label: string,
|
label: string,
|
||||||
private copyHeader: boolean,
|
private copyHeader: boolean,
|
||||||
|
private accountForNumberColumn = true
|
||||||
) {
|
) {
|
||||||
super(id, label);
|
super(id, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
public run(context: IGridActionContext): TPromise<boolean> {
|
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);
|
return TPromise.as(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,7 +115,7 @@ export class SelectAllGridAction extends Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public run(context: IGridActionContext): TPromise<boolean> {
|
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);
|
return TPromise.as(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,13 +169,13 @@ export class MaximizeTableAction extends Action {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MinimizeTableAction extends Action {
|
export class RestoreTableAction extends Action {
|
||||||
public static ID = 'grid.minimize';
|
public static ID = 'grid.restore';
|
||||||
public static LABEL = localize('minimize', 'Minimize');
|
public static LABEL = localize('restore', 'Restore');
|
||||||
public static ICON = 'exitFullScreen';
|
public static ICON = 'exitFullScreen';
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(MinimizeTableAction.ID, MinimizeTableAction.LABEL, MinimizeTableAction.ICON);
|
super(RestoreTableAction.ID, RestoreTableAction.LABEL, RestoreTableAction.ICON);
|
||||||
}
|
}
|
||||||
|
|
||||||
public run(context: IGridActionContext): TPromise<boolean> {
|
public run(context: IGridActionContext): TPromise<boolean> {
|
||||||
|
|||||||
@@ -12,11 +12,13 @@ import { ScrollableSplitView } from 'sql/base/browser/ui/scrollableSplitview/scr
|
|||||||
import { MouseWheelSupport } from 'sql/base/browser/ui/table/plugins/mousewheelTableScroll.plugin';
|
import { MouseWheelSupport } from 'sql/base/browser/ui/table/plugins/mousewheelTableScroll.plugin';
|
||||||
import { AutoColumnSize } from 'sql/base/browser/ui/table/plugins/autoSizeColumns.plugin';
|
import { AutoColumnSize } from 'sql/base/browser/ui/table/plugins/autoSizeColumns.plugin';
|
||||||
import { SaveFormat } from 'sql/parts/grid/common/interfaces';
|
import { SaveFormat } from 'sql/parts/grid/common/interfaces';
|
||||||
import { IGridActionContext, SaveResultAction, CopyResultAction, SelectAllGridAction, MaximizeTableAction, MinimizeTableAction, ChartDataAction, ShowQueryPlanAction } from 'sql/parts/query/editor/actions';
|
import { IGridActionContext, SaveResultAction, CopyResultAction, SelectAllGridAction, MaximizeTableAction, RestoreTableAction, ChartDataAction, ShowQueryPlanAction } from 'sql/parts/query/editor/actions';
|
||||||
import { CellSelectionModel } from 'sql/base/browser/ui/table/plugins/cellSelectionModel.plugin';
|
import { CellSelectionModel } from 'sql/base/browser/ui/table/plugins/cellSelectionModel.plugin';
|
||||||
import { RowNumberColumn } from 'sql/base/browser/ui/table/plugins/rowNumberColumn.plugin';
|
import { RowNumberColumn } from 'sql/base/browser/ui/table/plugins/rowNumberColumn.plugin';
|
||||||
import { escape } from 'sql/base/common/strings';
|
import { escape } from 'sql/base/common/strings';
|
||||||
import { hyperLinkFormatter, textFormatter } from 'sql/parts/grid/services/sharedServices';
|
import { hyperLinkFormatter, textFormatter } from 'sql/parts/grid/services/sharedServices';
|
||||||
|
import { CopyKeybind } from 'sql/base/browser/ui/table/plugins/copyKeybind.plugin';
|
||||||
|
import { AdditionalKeyBindings } from 'sql/base/browser/ui/table/plugins/additionalKeyBindings.plugin';
|
||||||
|
|
||||||
import * as sqlops from 'sqlops';
|
import * as sqlops from 'sqlops';
|
||||||
|
|
||||||
@@ -38,19 +40,20 @@ import { Dimension, getContentWidth } from 'vs/base/browser/dom';
|
|||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
|
import { IAction } from 'vs/base/common/actions';
|
||||||
|
|
||||||
const ROW_HEIGHT = 29;
|
const ROW_HEIGHT = 29;
|
||||||
const HEADER_HEIGHT = 26;
|
const HEADER_HEIGHT = 26;
|
||||||
const MIN_GRID_HEIGHT_ROWS = 8;
|
const MIN_GRID_HEIGHT_ROWS = 8;
|
||||||
const ESTIMATED_SCROLL_BAR_HEIGHT = 10;
|
const ESTIMATED_SCROLL_BAR_HEIGHT = 10;
|
||||||
const BOTTOM_PADDING = 5;
|
const BOTTOM_PADDING = 15;
|
||||||
const ACTIONBAR_WIDTH = 26;
|
const ACTIONBAR_WIDTH = 26;
|
||||||
|
|
||||||
// minimum height needed to show the full actionbar
|
// minimum height needed to show the full actionbar
|
||||||
const ACTIONBAR_HEIGHT = 100;
|
const ACTIONBAR_HEIGHT = 100;
|
||||||
|
|
||||||
// this handles min size if rows is greater than the min grid visible rows
|
// this handles min size if rows is greater than the min grid visible rows
|
||||||
const MIN_GRID_HEIGHT = (MIN_GRID_HEIGHT_ROWS * ROW_HEIGHT) + HEADER_HEIGHT + ESTIMATED_SCROLL_BAR_HEIGHT + BOTTOM_PADDING;
|
const MIN_GRID_HEIGHT = (MIN_GRID_HEIGHT_ROWS * ROW_HEIGHT) + HEADER_HEIGHT + ESTIMATED_SCROLL_BAR_HEIGHT;
|
||||||
|
|
||||||
|
|
||||||
export interface IGridTableState {
|
export interface IGridTableState {
|
||||||
@@ -65,15 +68,30 @@ export class GridTableState {
|
|||||||
private _onMaximizedChange = new Emitter<boolean>();
|
private _onMaximizedChange = new Emitter<boolean>();
|
||||||
public onMaximizedChange: Event<boolean> = this._onMaximizedChange.event;
|
public onMaximizedChange: Event<boolean> = this._onMaximizedChange.event;
|
||||||
|
|
||||||
public canBeMaximized: boolean;
|
private _onCanBeMaximizedChange = new Emitter<boolean>();
|
||||||
|
public onCanBeMaximizedChange: Event<boolean> = this._onCanBeMaximizedChange.event;
|
||||||
|
|
||||||
|
private _canBeMaximized: boolean;
|
||||||
|
|
||||||
constructor(state?: IGridTableState) {
|
constructor(state?: IGridTableState) {
|
||||||
if (state) {
|
if (state) {
|
||||||
this._maximized = state.maximized;
|
this._maximized = state.maximized;
|
||||||
this.canBeMaximized = state.canBeMaximized;
|
this._canBeMaximized = state.canBeMaximized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get canBeMaximized(): boolean {
|
||||||
|
return this._canBeMaximized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set canBeMaximized(val: boolean) {
|
||||||
|
if (val === this._canBeMaximized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._canBeMaximized = val;
|
||||||
|
this._onCanBeMaximizedChange.fire(val);
|
||||||
|
}
|
||||||
|
|
||||||
public get maximized(): boolean {
|
public get maximized(): boolean {
|
||||||
return this._maximized;
|
return this._maximized;
|
||||||
}
|
}
|
||||||
@@ -215,10 +233,6 @@ export class GridPanel extends ViewletPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public layout(size: number) {
|
|
||||||
this.splitView.layout(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
private minimizeTables(): void {
|
private minimizeTables(): void {
|
||||||
if (this.maximizedGrid) {
|
if (this.maximizedGrid) {
|
||||||
this.maximizedGrid.state.maximized = false;
|
this.maximizedGrid.state.maximized = false;
|
||||||
@@ -246,7 +260,7 @@ class GridTable<T> extends Disposable implements IView {
|
|||||||
readonly element: HTMLElement = this.container;
|
readonly element: HTMLElement = this.container;
|
||||||
|
|
||||||
// this handles if the row count is small, like 4-5 rows
|
// this handles if the row count is small, like 4-5 rows
|
||||||
private readonly maxSize = ((this.resultSet.rowCount) * ROW_HEIGHT) + HEADER_HEIGHT + ESTIMATED_SCROLL_BAR_HEIGHT + BOTTOM_PADDING;
|
private readonly maxSize = ((this.resultSet.rowCount) * ROW_HEIGHT) + HEADER_HEIGHT + ESTIMATED_SCROLL_BAR_HEIGHT;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private runner: QueryRunner,
|
private runner: QueryRunner,
|
||||||
@@ -260,7 +274,7 @@ class GridTable<T> extends Disposable implements IView {
|
|||||||
super();
|
super();
|
||||||
this.container.style.width = '100%';
|
this.container.style.width = '100%';
|
||||||
this.container.style.height = '100%';
|
this.container.style.height = '100%';
|
||||||
this.container.style.marginBottom = BOTTOM_PADDING + 'px';
|
// this.container.style.marginBottom = BOTTOM_PADDING + 'px';
|
||||||
this.container.className = 'grid-panel';
|
this.container.className = 'grid-panel';
|
||||||
|
|
||||||
this.columns = this.resultSet.columnInfo.map((c, i) => {
|
this.columns = this.resultSet.columnInfo.map((c, i) => {
|
||||||
@@ -295,12 +309,24 @@ class GridTable<T> extends Disposable implements IView {
|
|||||||
this.renderGridDataRowsRange(startIndex, count);
|
this.renderGridDataRowsRange(startIndex, count);
|
||||||
});
|
});
|
||||||
let numberColumn = new RowNumberColumn({ numberOfRows: this.resultSet.rowCount });
|
let numberColumn = new RowNumberColumn({ numberOfRows: this.resultSet.rowCount });
|
||||||
|
let copyHandler = new CopyKeybind();
|
||||||
|
copyHandler.onCopy(e => {
|
||||||
|
new CopyResultAction(CopyResultAction.COPY_ID, CopyResultAction.COPY_LABEL, false).run(this.generateContext());
|
||||||
|
});
|
||||||
this.columns.unshift(numberColumn.getColumnDefinition());
|
this.columns.unshift(numberColumn.getColumnDefinition());
|
||||||
this.table = this._register(new Table(tableContainer, { dataProvider: new AsyncDataProvider(collection), columns: this.columns }, { rowHeight: ROW_HEIGHT, showRowNumber: true }));
|
let tableOptions: Slick.GridOptions<T> = {
|
||||||
|
rowHeight: ROW_HEIGHT,
|
||||||
|
showRowNumber: true,
|
||||||
|
forceFitColumns: false,
|
||||||
|
defaultColumnWidth: 120
|
||||||
|
};
|
||||||
|
this.table = this._register(new Table(tableContainer, { dataProvider: new AsyncDataProvider(collection), columns: this.columns }, tableOptions));
|
||||||
this.table.setSelectionModel(this.selectionModel);
|
this.table.setSelectionModel(this.selectionModel);
|
||||||
this.table.registerPlugin(new MouseWheelSupport());
|
this.table.registerPlugin(new MouseWheelSupport());
|
||||||
this.table.registerPlugin(new AutoColumnSize());
|
this.table.registerPlugin(new AutoColumnSize());
|
||||||
|
this.table.registerPlugin(copyHandler);
|
||||||
this.table.registerPlugin(numberColumn);
|
this.table.registerPlugin(numberColumn);
|
||||||
|
this.table.registerPlugin(new AdditionalKeyBindings());
|
||||||
this._register(this.table.onContextMenu(this.contextMenu, this));
|
this._register(this.table.onContextMenu(this.contextMenu, this));
|
||||||
this._register(this.table.onClick(this.onTableClick, this));
|
this._register(this.table.onClick(this.onTableClick, this));
|
||||||
|
|
||||||
@@ -308,22 +334,7 @@ class GridTable<T> extends Disposable implements IView {
|
|||||||
this.table.style(this.styles);
|
this.table.style(this.styles);
|
||||||
}
|
}
|
||||||
|
|
||||||
let actions = [];
|
let actions = this.getCurrentActions();
|
||||||
|
|
||||||
if (this.state.canBeMaximized) {
|
|
||||||
if (this.state.maximized) {
|
|
||||||
actions.splice(1, 0, new MinimizeTableAction());
|
|
||||||
} else {
|
|
||||||
actions.splice(1, 0, new MaximizeTableAction());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actions.push(
|
|
||||||
new SaveResultAction(SaveResultAction.SAVECSV_ID, SaveResultAction.SAVECSV_LABEL, SaveResultAction.SAVECSV_ICON, SaveFormat.CSV),
|
|
||||||
new SaveResultAction(SaveResultAction.SAVEEXCEL_ID, SaveResultAction.SAVEEXCEL_LABEL, SaveResultAction.SAVEEXCEL_ICON, SaveFormat.EXCEL),
|
|
||||||
new SaveResultAction(SaveResultAction.SAVEJSON_ID, SaveResultAction.SAVEJSON_LABEL, SaveResultAction.SAVEJSON_ICON, SaveFormat.JSON),
|
|
||||||
this.instantiationService.createInstance(ChartDataAction)
|
|
||||||
);
|
|
||||||
|
|
||||||
let actionBarContainer = document.createElement('div');
|
let actionBarContainer = document.createElement('div');
|
||||||
actionBarContainer.style.width = ACTIONBAR_WIDTH + 'px';
|
actionBarContainer.style.width = ACTIONBAR_WIDTH + 'px';
|
||||||
@@ -340,7 +351,16 @@ class GridTable<T> extends Disposable implements IView {
|
|||||||
tableState: this.state
|
tableState: this.state
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// update context before we run an action
|
||||||
|
this.selectionModel.onSelectedRangesChanged.subscribe(e => {
|
||||||
|
this.actionBar.context = this.generateContext();
|
||||||
|
});
|
||||||
this.actionBar.push(actions, { icon: true, label: false });
|
this.actionBar.push(actions, { icon: true, label: false });
|
||||||
|
|
||||||
|
// change actionbar on maximize change
|
||||||
|
this.state.onMaximizedChange(this.rebuildActionBar, this);
|
||||||
|
|
||||||
|
this.state.onCanBeMaximizedChange(this.rebuildActionBar, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onTableClick(event: ITableMouseEvent) {
|
private onTableClick(event: ITableMouseEvent) {
|
||||||
@@ -356,6 +376,48 @@ class GridTable<T> extends Disposable implements IView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private generateContext(cell?: Slick.Cell): IGridActionContext {
|
||||||
|
const selection = this.selectionModel.getSelectedRanges();
|
||||||
|
return <IGridActionContext>{
|
||||||
|
cell,
|
||||||
|
selection,
|
||||||
|
runner: this.runner,
|
||||||
|
batchId: this.resultSet.batchId,
|
||||||
|
resultId: this.resultSet.id,
|
||||||
|
table: this.table,
|
||||||
|
tableState: this.state,
|
||||||
|
selectionModel: this.selectionModel
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private rebuildActionBar() {
|
||||||
|
let actions = this.getCurrentActions();
|
||||||
|
this.actionBar.clear();
|
||||||
|
this.actionBar.push(actions, { icon: true, label: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCurrentActions(): IAction[] {
|
||||||
|
|
||||||
|
let actions = [];
|
||||||
|
|
||||||
|
if (this.state.canBeMaximized) {
|
||||||
|
if (this.state.maximized) {
|
||||||
|
actions.splice(1, 0, new RestoreTableAction());
|
||||||
|
} else {
|
||||||
|
actions.splice(1, 0, new MaximizeTableAction());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.push(
|
||||||
|
new SaveResultAction(SaveResultAction.SAVECSV_ID, SaveResultAction.SAVECSV_LABEL, SaveResultAction.SAVECSV_ICON, SaveFormat.CSV),
|
||||||
|
new SaveResultAction(SaveResultAction.SAVEEXCEL_ID, SaveResultAction.SAVEEXCEL_LABEL, SaveResultAction.SAVEEXCEL_ICON, SaveFormat.EXCEL),
|
||||||
|
new SaveResultAction(SaveResultAction.SAVEJSON_ID, SaveResultAction.SAVEJSON_LABEL, SaveResultAction.SAVEJSON_ICON, SaveFormat.JSON),
|
||||||
|
this.instantiationService.createInstance(ChartDataAction)
|
||||||
|
);
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
public layout(size?: number): void {
|
public layout(size?: number): void {
|
||||||
if (!this.table) {
|
if (!this.table) {
|
||||||
this.build();
|
this.build();
|
||||||
@@ -368,18 +430,18 @@ class GridTable<T> extends Disposable implements IView {
|
|||||||
this.table.layout(
|
this.table.layout(
|
||||||
new Dimension(
|
new Dimension(
|
||||||
getContentWidth(this.container) - ACTIONBAR_WIDTH,
|
getContentWidth(this.container) - ACTIONBAR_WIDTH,
|
||||||
size - BOTTOM_PADDING
|
size
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get minimumSize(): number {
|
public get minimumSize(): number {
|
||||||
// clamp between ensuring we can show the actionbar, while also making sure we don't take too much space
|
// clamp between ensuring we can show the actionbar, while also making sure we don't take too much space
|
||||||
return Math.max(Math.min(this.maxSize, MIN_GRID_HEIGHT), ACTIONBAR_HEIGHT);
|
return Math.max(Math.min(this.maxSize, MIN_GRID_HEIGHT), ACTIONBAR_HEIGHT + BOTTOM_PADDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get maximumSize(): number {
|
public get maximumSize(): number {
|
||||||
return Math.max(this.maxSize, ACTIONBAR_HEIGHT);
|
return Math.max(this.maxSize, ACTIONBAR_HEIGHT + BOTTOM_PADDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadData(offset: number, count: number): Thenable<T[]> {
|
private loadData(offset: number, count: number): Thenable<T[]> {
|
||||||
@@ -403,7 +465,6 @@ class GridTable<T> extends Disposable implements IView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private contextMenu(e: ITableMouseEvent): void {
|
private contextMenu(e: ITableMouseEvent): void {
|
||||||
const selection = this.selectionModel.getSelectedRanges();
|
|
||||||
const { cell } = e;
|
const { cell } = e;
|
||||||
this.contextMenuService.showContextMenu({
|
this.contextMenuService.showContextMenu({
|
||||||
getAnchor: () => e.anchor,
|
getAnchor: () => e.anchor,
|
||||||
@@ -421,7 +482,7 @@ class GridTable<T> extends Disposable implements IView {
|
|||||||
|
|
||||||
if (this.state.canBeMaximized) {
|
if (this.state.canBeMaximized) {
|
||||||
if (this.state.maximized) {
|
if (this.state.maximized) {
|
||||||
actions.splice(1, 0, new MinimizeTableAction());
|
actions.splice(1, 0, new RestoreTableAction());
|
||||||
} else {
|
} else {
|
||||||
actions.splice(1, 0, new MaximizeTableAction());
|
actions.splice(1, 0, new MaximizeTableAction());
|
||||||
}
|
}
|
||||||
@@ -430,15 +491,7 @@ class GridTable<T> extends Disposable implements IView {
|
|||||||
return TPromise.as(actions);
|
return TPromise.as(actions);
|
||||||
},
|
},
|
||||||
getActionsContext: () => {
|
getActionsContext: () => {
|
||||||
return <IGridActionContext>{
|
return this.generateContext(cell);
|
||||||
cell,
|
|
||||||
selection,
|
|
||||||
runner: this.runner,
|
|
||||||
batchId: this.resultSet.batchId,
|
|
||||||
resultId: this.resultSet.id,
|
|
||||||
table: this.table,
|
|
||||||
tableState: this.state
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,18 +13,28 @@
|
|||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.monaco-workbench .message-tree .monaco-tree .monaco-tree-rows>.monaco-tree-row {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
.message-tree .time-stamp {
|
.message-tree .time-stamp {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-tree .message,
|
.message-tree .message,
|
||||||
.message-tree .batch-start {
|
.message-tree .batch-start,
|
||||||
|
.message-tree .error-message {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-tree .batch-start {
|
.message-tree .batch-start {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-tree .error-message {
|
||||||
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-tree .batch-start:hover {
|
.message-tree .batch-start:hover {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import 'vs/css!./media/messagePanel';
|
|||||||
import { IMessagesActionContext, SelectAllMessagesAction, CopyMessagesAction } from './actions';
|
import { IMessagesActionContext, SelectAllMessagesAction, CopyMessagesAction } from './actions';
|
||||||
import QueryRunner from 'sql/parts/query/execution/queryRunner';
|
import QueryRunner from 'sql/parts/query/execution/queryRunner';
|
||||||
|
|
||||||
import { IResultMessage, BatchSummary, ISelectionData } from 'sqlops';
|
import { IResultMessage, ISelectionData } from 'sqlops';
|
||||||
|
|
||||||
import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet';
|
import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet';
|
||||||
import { IDataSource, ITree, IRenderer, ContextMenuEvent } from 'vs/base/parts/tree/browser/tree';
|
import { IDataSource, ITree, IRenderer, ContextMenuEvent } from 'vs/base/parts/tree/browser/tree';
|
||||||
@@ -27,7 +27,6 @@ import { IMouseEvent } from 'vs/base/browser/mouseEvent';
|
|||||||
import { $ } from 'vs/base/browser/builder';
|
import { $ } from 'vs/base/browser/builder';
|
||||||
import { isArray } from 'vs/base/common/types';
|
import { isArray } from 'vs/base/common/types';
|
||||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||||
import { localize } from 'vs/nls';
|
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { IEditor } from 'vs/editor/common/editorCommon';
|
import { IEditor } from 'vs/editor/common/editorCommon';
|
||||||
|
|
||||||
@@ -56,7 +55,8 @@ interface IBatchTemplate extends IMessageTemplate {
|
|||||||
const TemplateIds = {
|
const TemplateIds = {
|
||||||
MESSAGE: 'message',
|
MESSAGE: 'message',
|
||||||
BATCH: 'batch',
|
BATCH: 'batch',
|
||||||
MODEL: 'model'
|
MODEL: 'model',
|
||||||
|
ERROR: 'error'
|
||||||
};
|
};
|
||||||
|
|
||||||
export class MessagePanel extends ViewletPanel {
|
export class MessagePanel extends ViewletPanel {
|
||||||
@@ -113,11 +113,17 @@ export class MessagePanel extends ViewletPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onMessage(message: IResultMessage | IResultMessage[]) {
|
private onMessage(message: IResultMessage | IResultMessage[]) {
|
||||||
|
let hasError = false;
|
||||||
if (isArray(message)) {
|
if (isArray(message)) {
|
||||||
|
hasError = message.find(e => e.isError) ? true : false;
|
||||||
this.model.messages.push(...message);
|
this.model.messages.push(...message);
|
||||||
} else {
|
} else {
|
||||||
|
hasError = message.isError;
|
||||||
this.model.messages.push(message);
|
this.model.messages.push(message);
|
||||||
}
|
}
|
||||||
|
if (hasError) {
|
||||||
|
this.setExpanded(true);
|
||||||
|
}
|
||||||
const previousScrollPosition = this.tree.getScrollPosition();
|
const previousScrollPosition = this.tree.getScrollPosition();
|
||||||
this.tree.refresh(this.model).then(() => {
|
this.tree.refresh(this.model).then(() => {
|
||||||
if (previousScrollPosition === 1) {
|
if (previousScrollPosition === 1) {
|
||||||
@@ -176,6 +182,8 @@ class MessageRenderer implements IRenderer {
|
|||||||
return TemplateIds.MODEL;
|
return TemplateIds.MODEL;
|
||||||
} else if (element.selection) {
|
} else if (element.selection) {
|
||||||
return TemplateIds.BATCH;
|
return TemplateIds.BATCH;
|
||||||
|
} else if (element.isError) {
|
||||||
|
return TemplateIds.ERROR;
|
||||||
} else {
|
} else {
|
||||||
return TemplateIds.MESSAGE;
|
return TemplateIds.MESSAGE;
|
||||||
}
|
}
|
||||||
@@ -191,15 +199,19 @@ class MessageRenderer implements IRenderer {
|
|||||||
const timeStamp = $('div.time-stamp').appendTo(container).getHTMLElement();
|
const timeStamp = $('div.time-stamp').appendTo(container).getHTMLElement();
|
||||||
const message = $('div.batch-start').appendTo(container).getHTMLElement();
|
const message = $('div.batch-start').appendTo(container).getHTMLElement();
|
||||||
return { message, timeStamp };
|
return { message, timeStamp };
|
||||||
|
} else if (templateId === TemplateIds.ERROR) {
|
||||||
|
$('div.time-stamp').appendTo(container);
|
||||||
|
const message = $('div.error-message').appendTo(container).getHTMLElement();
|
||||||
|
return { message };
|
||||||
} else {
|
} else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderElement(tree: ITree, element: IResultMessage, templateId: string, templateData: IMessageTemplate | IBatchTemplate): void {
|
renderElement(tree: ITree, element: IResultMessage, templateId: string, templateData: IMessageTemplate | IBatchTemplate): void {
|
||||||
if (templateId === TemplateIds.MESSAGE) {
|
if (templateId === TemplateIds.MESSAGE || templateId === TemplateIds.ERROR) {
|
||||||
let data: IMessageTemplate = templateData;
|
let data: IMessageTemplate = templateData;
|
||||||
data.message.innerText = element.message;
|
data.message.innerText = element.message.replace(/(\r\n|\n|\r)/g, ' ');
|
||||||
} else if (templateId === TemplateIds.BATCH) {
|
} else if (templateId === TemplateIds.BATCH) {
|
||||||
let data = templateData as IBatchTemplate;
|
let data = templateData as IBatchTemplate;
|
||||||
data.timeStamp.innerText = element.time;
|
data.timeStamp.innerText = element.time;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import { IQueryModelService } from 'sql/parts/query/execution/queryModel';
|
|||||||
import { IEditorDescriptorService } from 'sql/parts/query/editor/editorDescriptorService';
|
import { IEditorDescriptorService } from 'sql/parts/query/editor/editorDescriptorService';
|
||||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||||
import { attachEditableDropdownStyler } from 'sql/common/theme/styler';
|
import { attachEditableDropdownStyler } from 'sql/common/theme/styler';
|
||||||
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||||
|
|
||||||
@@ -96,7 +97,8 @@ export class QueryEditor extends BaseEditor {
|
|||||||
@IQueryModelService private _queryModelService: IQueryModelService,
|
@IQueryModelService private _queryModelService: IQueryModelService,
|
||||||
@IEditorDescriptorService private _editorDescriptorService: IEditorDescriptorService,
|
@IEditorDescriptorService private _editorDescriptorService: IEditorDescriptorService,
|
||||||
@IContextKeyService contextKeyService: IContextKeyService,
|
@IContextKeyService contextKeyService: IContextKeyService,
|
||||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService
|
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||||
|
@IConfigurationService private _configurationService: IConfigurationService
|
||||||
) {
|
) {
|
||||||
super(QueryEditor.ID, _telemetryService, themeService);
|
super(QueryEditor.ID, _telemetryService, themeService);
|
||||||
|
|
||||||
@@ -293,7 +295,7 @@ export class QueryEditor extends BaseEditor {
|
|||||||
let input = <QueryInput>this.input;
|
let input = <QueryInput>this.input;
|
||||||
this._createResultsEditorContainer();
|
this._createResultsEditorContainer();
|
||||||
|
|
||||||
this._createEditor(<QueryResultsInput>input.results, this._resultsEditorContainer)
|
this._createEditor(<QueryResultsInput>input.results, this._resultsEditorContainer, this.group)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
this._onResultsEditorCreated(<any>result, input.results, this.options);
|
this._onResultsEditorCreated(<any>result, input.results, this.options);
|
||||||
this.resultsEditorVisibility = true;
|
this.resultsEditorVisibility = true;
|
||||||
@@ -446,6 +448,16 @@ export class QueryEditor extends BaseEditor {
|
|||||||
this._estimatedQueryPlanAction = this._instantiationService.createInstance(EstimatedQueryPlanAction, this);
|
this._estimatedQueryPlanAction = this._instantiationService.createInstance(EstimatedQueryPlanAction, this);
|
||||||
this._actualQueryPlanAction = this._instantiationService.createInstance(ActualQueryPlanAction, this);
|
this._actualQueryPlanAction = this._instantiationService.createInstance(ActualQueryPlanAction, this);
|
||||||
|
|
||||||
|
this.setTaskbarContent();
|
||||||
|
|
||||||
|
this._configurationService.onDidChangeConfiguration(e => {
|
||||||
|
if (e.affectedKeys.includes('workbench.enablePreviewFeatures')) {
|
||||||
|
this.setTaskbarContent();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private setTaskbarContent(): void {
|
||||||
// Create HTML Elements for the taskbar
|
// Create HTML Elements for the taskbar
|
||||||
let separator = Taskbar.createTaskbarSeparator();
|
let separator = Taskbar.createTaskbarSeparator();
|
||||||
|
|
||||||
@@ -460,6 +472,13 @@ export class QueryEditor extends BaseEditor {
|
|||||||
{ element: separator },
|
{ element: separator },
|
||||||
{ action: this._estimatedQueryPlanAction }
|
{ action: this._estimatedQueryPlanAction }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Remove the estimated query plan action if preview features are not enabled
|
||||||
|
let previewFeaturesEnabled = this._configurationService.getValue('workbench')['enablePreviewFeatures'];
|
||||||
|
if (!previewFeaturesEnabled) {
|
||||||
|
content = content.slice(0, -2);
|
||||||
|
}
|
||||||
|
|
||||||
this._taskbar.setContent(content);
|
this._taskbar.setContent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -537,8 +556,8 @@ export class QueryEditor extends BaseEditor {
|
|||||||
if (this._isResultsEditorVisible()) {
|
if (this._isResultsEditorVisible()) {
|
||||||
createEditors = () => {
|
createEditors = () => {
|
||||||
return TPromise.join([
|
return TPromise.join([
|
||||||
this._createEditor(<QueryResultsInput>newInput.results, this._resultsEditorContainer),
|
this._createEditor(<QueryResultsInput>newInput.results, this._resultsEditorContainer, this.group),
|
||||||
this._createEditor(<UntitledEditorInput>newInput.sql, this._sqlEditorContainer)
|
this._createEditor(<UntitledEditorInput>newInput.sql, this._sqlEditorContainer, this.group)
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
onEditorsCreated = (result: IEditor[]) => {
|
onEditorsCreated = (result: IEditor[]) => {
|
||||||
@@ -551,7 +570,7 @@ export class QueryEditor extends BaseEditor {
|
|||||||
// If only the sql editor exists, create a promise and wait for the sql editor to be created
|
// If only the sql editor exists, create a promise and wait for the sql editor to be created
|
||||||
} else {
|
} else {
|
||||||
createEditors = () => {
|
createEditors = () => {
|
||||||
return this._createEditor(<UntitledEditorInput>newInput.sql, this._sqlEditorContainer);
|
return this._createEditor(<UntitledEditorInput>newInput.sql, this._sqlEditorContainer, this.group);
|
||||||
};
|
};
|
||||||
onEditorsCreated = (result: TextResourceEditor) => {
|
onEditorsCreated = (result: TextResourceEditor) => {
|
||||||
return TPromise.join([
|
return TPromise.join([
|
||||||
@@ -583,7 +602,7 @@ export class QueryEditor extends BaseEditor {
|
|||||||
/**
|
/**
|
||||||
* Create a single editor based on the type of the given EditorInput.
|
* Create a single editor based on the type of the given EditorInput.
|
||||||
*/
|
*/
|
||||||
private _createEditor(editorInput: EditorInput, container: HTMLElement): TPromise<BaseEditor> {
|
private _createEditor(editorInput: EditorInput, container: HTMLElement, group: IEditorGroup): TPromise<BaseEditor> {
|
||||||
const descriptor = this._editorDescriptorService.getEditor(editorInput);
|
const descriptor = this._editorDescriptorService.getEditor(editorInput);
|
||||||
if (!descriptor) {
|
if (!descriptor) {
|
||||||
return TPromise.wrapError(new Error(strings.format('Can not find a registered editor for the input {0}', editorInput)));
|
return TPromise.wrapError(new Error(strings.format('Can not find a registered editor for the input {0}', editorInput)));
|
||||||
@@ -591,7 +610,7 @@ export class QueryEditor extends BaseEditor {
|
|||||||
|
|
||||||
let editor = descriptor.instantiate(this._instantiationService);
|
let editor = descriptor.instantiate(this._instantiationService);
|
||||||
editor.create(container);
|
editor.create(container);
|
||||||
editor.setVisible(this.isVisible(), editor.group);
|
editor.setVisible(this.isVisible(), group);
|
||||||
return TPromise.as(editor);
|
return TPromise.as(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ export class QueryResultsEditor extends BaseEditor {
|
|||||||
protected _input: QueryResultsInput;
|
protected _input: QueryResultsInput;
|
||||||
|
|
||||||
private resultsView: QueryResultsView;
|
private resultsView: QueryResultsView;
|
||||||
|
private styleSheet = DOM.createStyleSheet();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ITelemetryService telemetryService: ITelemetryService,
|
@ITelemetryService telemetryService: ITelemetryService,
|
||||||
@@ -103,12 +104,13 @@ export class QueryResultsEditor extends BaseEditor {
|
|||||||
) {
|
) {
|
||||||
super(QueryResultsEditor.ID, telemetryService, themeService);
|
super(QueryResultsEditor.ID, telemetryService, themeService);
|
||||||
this._rawOptions = BareResultsGridInfo.createFromRawSettings(this._configurationService.getValue('resultsGrid'), getZoomLevel());
|
this._rawOptions = BareResultsGridInfo.createFromRawSettings(this._configurationService.getValue('resultsGrid'), getZoomLevel());
|
||||||
// this._configurationService.onDidChangeConfiguration(e => {
|
this._configurationService.onDidChangeConfiguration(e => {
|
||||||
// if (e.affectsConfiguration('resultsGrid')) {
|
if (e.affectsConfiguration('resultsGrid')) {
|
||||||
// this._rawOptions = BareResultsGridInfo.createFromRawSettings(this._configurationService.getValue('resultsGrid'), getZoomLevel());
|
this._rawOptions = BareResultsGridInfo.createFromRawSettings(this._configurationService.getValue('resultsGrid'), getZoomLevel());
|
||||||
// this.applySettings();
|
this.applySettings();
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
|
this.applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get input(): QueryResultsInput {
|
public get input(): QueryResultsInput {
|
||||||
@@ -116,23 +118,20 @@ export class QueryResultsEditor extends BaseEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private applySettings() {
|
private applySettings() {
|
||||||
if (this.input && this.input.container) {
|
let cssRuleText = '';
|
||||||
if (!this.input.css) {
|
if (types.isNumber(this._rawOptions.cellPadding)) {
|
||||||
this.input.css = DOM.createStyleSheet(this.input.container);
|
cssRuleText = this._rawOptions.cellPadding + 'px';
|
||||||
}
|
} else {
|
||||||
let cssRuleText = '';
|
cssRuleText = this._rawOptions.cellPadding.join('px ') + 'px;';
|
||||||
if (types.isNumber(this._rawOptions.cellPadding)) {
|
|
||||||
cssRuleText = this._rawOptions.cellPadding + 'px';
|
|
||||||
} else {
|
|
||||||
cssRuleText = this._rawOptions.cellPadding.join('px ') + 'px;';
|
|
||||||
}
|
|
||||||
let content = `.grid .slick-cell { padding: ${cssRuleText}; }`;
|
|
||||||
content += `.grid { ${getBareResultsGridInfoStyles(this._rawOptions)} }`;
|
|
||||||
this.input.css.innerHTML = content;
|
|
||||||
}
|
}
|
||||||
|
let content = `.grid-panel .monaco-table .slick-cell { padding: ${cssRuleText} }`;
|
||||||
|
content += `.grid-panel .monaco-table { ${getBareResultsGridInfoStyles(this._rawOptions)} }`;
|
||||||
|
this.styleSheet.innerHTML = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
createEditor(parent: HTMLElement): void {
|
createEditor(parent: HTMLElement): void {
|
||||||
|
this.styleSheet.remove();
|
||||||
|
parent.appendChild(this.styleSheet);
|
||||||
if (!this.resultsView) {
|
if (!this.resultsView) {
|
||||||
this.resultsView = new QueryResultsView(parent, this._instantiationService, this._queryModelService);
|
this.resultsView = new QueryResultsView(parent, this._instantiationService, this._queryModelService);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import * as UUID from 'vs/base/common/uuid';
|
|||||||
import { PanelViewlet } from 'vs/workbench/browser/parts/views/panelViewlet';
|
import { PanelViewlet } from 'vs/workbench/browser/parts/views/panelViewlet';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import * as DOM from 'vs/base/browser/dom';
|
import * as DOM from 'vs/base/browser/dom';
|
||||||
|
import { once } from 'vs/base/common/event';
|
||||||
|
|
||||||
class ResultsView implements IPanelView {
|
class ResultsView implements IPanelView {
|
||||||
private panelViewlet: PanelViewlet;
|
private panelViewlet: PanelViewlet;
|
||||||
@@ -25,19 +26,62 @@ class ResultsView implements IPanelView {
|
|||||||
private messagePanel: MessagePanel;
|
private messagePanel: MessagePanel;
|
||||||
private container = document.createElement('div');
|
private container = document.createElement('div');
|
||||||
private currentDimension: DOM.Dimension;
|
private currentDimension: DOM.Dimension;
|
||||||
|
private isGridRendered = false;
|
||||||
|
private needsGridResize = false;
|
||||||
|
private lastGridHeight: number;
|
||||||
|
|
||||||
constructor(instantiationService: IInstantiationService) {
|
constructor(instantiationService: IInstantiationService) {
|
||||||
this.panelViewlet = instantiationService.createInstance(PanelViewlet, 'resultsView', { showHeaderInTitleWhenSingleView: false });
|
this.panelViewlet = instantiationService.createInstance(PanelViewlet, 'resultsView', { showHeaderInTitleWhenSingleView: false });
|
||||||
this.gridPanel = instantiationService.createInstance(GridPanel, { title: nls.localize('gridPanel', 'Results') });
|
this.gridPanel = instantiationService.createInstance(GridPanel, { title: nls.localize('gridPanel', 'Results'), id: 'gridPanel' });
|
||||||
this.messagePanel = instantiationService.createInstance(MessagePanel, { title: nls.localize('messagePanel', 'Messages') });
|
this.messagePanel = instantiationService.createInstance(MessagePanel, { title: nls.localize('messagePanel', 'Messages'), minimumBodySize: 0, id: 'messagePanel' });
|
||||||
this.gridPanel.render();
|
this.gridPanel.render();
|
||||||
this.messagePanel.render();
|
this.messagePanel.render();
|
||||||
this.panelViewlet.create(this.container).then(() => {
|
this.panelViewlet.create(this.container).then(() => {
|
||||||
this.panelViewlet.addPanels([
|
this.panelViewlet.addPanels([
|
||||||
{ panel: this.gridPanel, size: 1000, index: 0 },
|
|
||||||
{ panel: this.messagePanel, size: this.messagePanel.minimumSize, index: 1 }
|
{ panel: this.messagePanel, size: this.messagePanel.minimumSize, index: 1 }
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
this.gridPanel.onDidChange(e => {
|
||||||
|
let size = this.gridPanel.maximumBodySize;
|
||||||
|
if (this.isGridRendered) {
|
||||||
|
if (size < 1) {
|
||||||
|
this.lastGridHeight = this.panelViewlet.getPanelSize(this.gridPanel);
|
||||||
|
this.panelViewlet.removePanels([this.gridPanel]);
|
||||||
|
// tell the panel is has been removed.
|
||||||
|
this.gridPanel.layout(0);
|
||||||
|
this.isGridRendered = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.currentDimension) {
|
||||||
|
this.needsGridResize = false;
|
||||||
|
if (size > 0) {
|
||||||
|
this.panelViewlet.addPanels([
|
||||||
|
{ panel: this.gridPanel, index: 0, size: this.lastGridHeight || Math.round(this.currentDimension.height * .7) }
|
||||||
|
]);
|
||||||
|
this.isGridRendered = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.panelViewlet.addPanels([
|
||||||
|
{ panel: this.gridPanel, index: 0, size: this.lastGridHeight || 200 }
|
||||||
|
]);
|
||||||
|
this.isGridRendered = true;
|
||||||
|
this.needsGridResize = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let gridResizeList = this.gridPanel.onDidChange(e => {
|
||||||
|
if (this.currentDimension) {
|
||||||
|
this.needsGridResize = false;
|
||||||
|
this.panelViewlet.resizePanel(this.gridPanel, Math.round(this.currentDimension.height * .7));
|
||||||
|
} else {
|
||||||
|
this.needsGridResize = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// once the user changes the sash we should stop trying to resize the grid
|
||||||
|
once(this.panelViewlet.onDidSashChange)(e => {
|
||||||
|
this.needsGridResize = false;
|
||||||
|
gridResizeList.dispose();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render(container: HTMLElement): void {
|
render(container: HTMLElement): void {
|
||||||
@@ -51,6 +95,9 @@ class ResultsView implements IPanelView {
|
|||||||
this.gridPanel.layout(dimension.height);
|
this.gridPanel.layout(dimension.height);
|
||||||
}
|
}
|
||||||
this.currentDimension = dimension;
|
this.currentDimension = dimension;
|
||||||
|
if (this.needsGridResize) {
|
||||||
|
this.panelViewlet.resizePanel(this.gridPanel, Math.round(this.currentDimension.height * .7));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(): void {
|
remove(): void {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import * as WorkbenchUtils from 'sql/workbench/common/sqlWorkbenchUtils';
|
|||||||
import { IQueryManagementService } from 'sql/parts/query/common/queryManagement';
|
import { IQueryManagementService } from 'sql/parts/query/common/queryManagement';
|
||||||
import * as Utils from 'sql/parts/connection/common/utils';
|
import * as Utils from 'sql/parts/connection/common/utils';
|
||||||
import { SaveFormat } from 'sql/parts/grid/common/interfaces';
|
import { SaveFormat } from 'sql/parts/grid/common/interfaces';
|
||||||
import { echo } from 'sql/base/common/event';
|
import { echo, debounceEvent } from 'sql/base/common/event';
|
||||||
|
|
||||||
import Severity from 'vs/base/common/severity';
|
import Severity from 'vs/base/common/severity';
|
||||||
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
|
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
|
||||||
@@ -22,9 +22,10 @@ import * as types from 'vs/base/common/types';
|
|||||||
import { EventEmitter } from 'sql/base/common/eventEmitter';
|
import { EventEmitter } from 'sql/base/common/eventEmitter';
|
||||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { Emitter, debounceEvent, Event } from 'vs/base/common/event';
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { ResultSerializer } from 'sql/parts/query/common/resultSerializer';
|
import { ResultSerializer } from 'sql/parts/query/common/resultSerializer';
|
||||||
|
import { TPromise } from 'vs/base/common/winjs.base';
|
||||||
|
|
||||||
export interface IEditSessionReadyEvent {
|
export interface IEditSessionReadyEvent {
|
||||||
ownerUri: string;
|
ownerUri: string;
|
||||||
@@ -73,25 +74,27 @@ export default class QueryRunner {
|
|||||||
public get isQueryPlan(): boolean { return this._isQueryPlan; }
|
public get isQueryPlan(): boolean { return this._isQueryPlan; }
|
||||||
|
|
||||||
private _onMessage = new Emitter<sqlops.IResultMessage>();
|
private _onMessage = new Emitter<sqlops.IResultMessage>();
|
||||||
private _echoedMessages = echo(debounceEvent<sqlops.IResultMessage, sqlops.IResultMessage[]>(this._onMessage.event, (l, e) => {
|
private _debouncedMessage = debounceEvent<sqlops.IResultMessage, sqlops.IResultMessage[]>(this._onMessage.event, (l, e) => {
|
||||||
// on first run
|
// on first run
|
||||||
if (types.isUndefinedOrNull(l)) {
|
if (types.isUndefinedOrNull(l)) {
|
||||||
return [e];
|
return [e];
|
||||||
} else {
|
} else {
|
||||||
return l.concat(e);
|
return l.concat(e);
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
|
private _echoedMessages = echo(this._debouncedMessage.event);
|
||||||
public readonly onMessage = this._echoedMessages.event;
|
public readonly onMessage = this._echoedMessages.event;
|
||||||
|
|
||||||
private _onResultSet = new Emitter<sqlops.ResultSetSummary>();
|
private _onResultSet = new Emitter<sqlops.ResultSetSummary>();
|
||||||
private _echoedResultSet = echo(debounceEvent<sqlops.ResultSetSummary, sqlops.ResultSetSummary[]>(this._onResultSet.event, (l, e) => {
|
private _debouncedResultSet = debounceEvent<sqlops.ResultSetSummary, sqlops.ResultSetSummary[]>(this._onResultSet.event, (l, e) => {
|
||||||
// on first run
|
// on first run
|
||||||
if (types.isUndefinedOrNull(l)) {
|
if (types.isUndefinedOrNull(l)) {
|
||||||
return [e];
|
return [e];
|
||||||
} else {
|
} else {
|
||||||
return l.concat(e);
|
return l.concat(e);
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
|
private _echoedResultSet = echo(this._debouncedResultSet.event);
|
||||||
public readonly onResultSet = this._echoedResultSet.event;
|
public readonly onResultSet = this._echoedResultSet.event;
|
||||||
|
|
||||||
private _onQueryStart = new Emitter<void>();
|
private _onQueryStart = new Emitter<void>();
|
||||||
@@ -171,8 +174,13 @@ export default class QueryRunner {
|
|||||||
private doRunQuery(input: string, runCurrentStatement: boolean, runOptions?: sqlops.ExecutionPlanOptions): Thenable<void>;
|
private doRunQuery(input: string, runCurrentStatement: boolean, runOptions?: sqlops.ExecutionPlanOptions): Thenable<void>;
|
||||||
private doRunQuery(input: sqlops.ISelectionData, runCurrentStatement: boolean, runOptions?: sqlops.ExecutionPlanOptions): Thenable<void>;
|
private doRunQuery(input: sqlops.ISelectionData, runCurrentStatement: boolean, runOptions?: sqlops.ExecutionPlanOptions): Thenable<void>;
|
||||||
private doRunQuery(input, runCurrentStatement: boolean, runOptions?: sqlops.ExecutionPlanOptions): Thenable<void> {
|
private doRunQuery(input, runCurrentStatement: boolean, runOptions?: sqlops.ExecutionPlanOptions): Thenable<void> {
|
||||||
|
if (this.isExecuting) {
|
||||||
|
return TPromise.as(undefined);
|
||||||
|
}
|
||||||
this._echoedMessages.clear();
|
this._echoedMessages.clear();
|
||||||
this._echoedResultSet.clear();
|
this._echoedResultSet.clear();
|
||||||
|
this._debouncedMessage.clear();
|
||||||
|
this._debouncedResultSet.clear();
|
||||||
let ownerUri = this.uri;
|
let ownerUri = this.uri;
|
||||||
this._batchSets = [];
|
this._batchSets = [];
|
||||||
this._hasCompleted = false;
|
this._hasCompleted = false;
|
||||||
@@ -242,16 +250,18 @@ export default class QueryRunner {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this._eventEmitter.emit(EventType.COMPLETE, Utils.parseNumAsTimeString(this._totalElapsedMilliseconds));
|
let timeStamp = Utils.parseNumAsTimeString(this._totalElapsedMilliseconds);
|
||||||
|
|
||||||
|
this._eventEmitter.emit(EventType.COMPLETE, timeStamp);
|
||||||
// We're done with this query so shut down any waiting mechanisms
|
// We're done with this query so shut down any waiting mechanisms
|
||||||
|
|
||||||
let message = {
|
let message = {
|
||||||
message: nls.localize('query.message.executionTime', 'Total execution time: {0}', this._totalElapsedMilliseconds),
|
message: nls.localize('query.message.executionTime', 'Total execution time: {0}', timeStamp),
|
||||||
isError: false,
|
isError: false,
|
||||||
time: undefined
|
time: undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
this._onQueryEnd.fire(Utils.parseNumAsTimeString(this._totalElapsedMilliseconds));
|
this._onQueryEnd.fire(timeStamp);
|
||||||
this._onMessage.fire(message);
|
this._onMessage.fire(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +284,8 @@ export default class QueryRunner {
|
|||||||
this.batchSets[batch.id] = batch;
|
this.batchSets[batch.id] = batch;
|
||||||
|
|
||||||
let message = {
|
let message = {
|
||||||
message: nls.localize('query.message.startQuery', 'Started executing query at Line {0}', batch.selection.startLine),
|
// account for index by 1
|
||||||
|
message: nls.localize('query.message.startQuery', 'Started executing query at Line {0}', batch.selection.startLine + 1),
|
||||||
time: new Date(batch.executionStart).toLocaleTimeString(),
|
time: new Date(batch.executionStart).toLocaleTimeString(),
|
||||||
selection: batch.selection,
|
selection: batch.selection,
|
||||||
isError: false
|
isError: false
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import { PanelComponent, IPanelOptions } from 'sql/base/browser/ui/panel/panel.c
|
|||||||
|
|
||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||||
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
|
|
||||||
export const QUERY_OUTPUT_SELECTOR: string = 'query-output-component';
|
export const QUERY_OUTPUT_SELECTOR: string = 'query-output-component';
|
||||||
|
|
||||||
@@ -66,7 +67,8 @@ export class QueryOutputComponent implements OnDestroy {
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef,
|
||||||
@Inject(IBootstrapParams) public queryParameters: IQueryComponentParams
|
@Inject(IBootstrapParams) public queryParameters: IQueryComponentParams,
|
||||||
|
@Inject(IConfigurationService) private _configurationService: IConfigurationService
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,12 +77,14 @@ export class QueryOutputComponent implements OnDestroy {
|
|||||||
*/
|
*/
|
||||||
public ngAfterViewInit(): void {
|
public ngAfterViewInit(): void {
|
||||||
this._disposables.push(toDisposableSubscription(this.queryComponent.queryPlanAvailable.subscribe((xml) => {
|
this._disposables.push(toDisposableSubscription(this.queryComponent.queryPlanAvailable.subscribe((xml) => {
|
||||||
this.hasQueryPlan = true;
|
if (this._configurationService.getValue('workbench')['enablePreviewFeatures']) {
|
||||||
this._cd.detectChanges();
|
this.hasQueryPlan = true;
|
||||||
this._panel.selectTab(this.topOperationsTabIdentifier);
|
this._cd.detectChanges();
|
||||||
this.topOperationsComponent.planXml = xml;
|
this._panel.selectTab(this.topOperationsTabIdentifier);
|
||||||
this._panel.selectTab(this.queryPlanTabIdentifier);
|
this.topOperationsComponent.planXml = xml;
|
||||||
this.queryPlanComponent.planXml = xml;
|
this._panel.selectTab(this.queryPlanTabIdentifier);
|
||||||
|
this.queryPlanComponent.planXml = xml;
|
||||||
|
}
|
||||||
})));
|
})));
|
||||||
|
|
||||||
this._disposables.push(toDisposableSubscription(this.queryComponent.showChartRequested.subscribe((dataSet) => {
|
this._disposables.push(toDisposableSubscription(this.queryComponent.showChartRequested.subscribe((dataSet) => {
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ const viewletDescriptor = new ViewletDescriptor(
|
|||||||
VIEWLET_ID,
|
VIEWLET_ID,
|
||||||
'Task History',
|
'Task History',
|
||||||
'taskHistoryViewlet',
|
'taskHistoryViewlet',
|
||||||
-90
|
1
|
||||||
);
|
);
|
||||||
|
|
||||||
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(viewletDescriptor);
|
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(viewletDescriptor);
|
||||||
|
|||||||
@@ -48,9 +48,7 @@ export abstract class Task {
|
|||||||
id: this.id,
|
id: this.id,
|
||||||
handler: (accessor, profile, args) => this.runTask(accessor, profile, args),
|
handler: (accessor, profile, args) => this.runTask(accessor, profile, args),
|
||||||
description: this._description,
|
description: this._description,
|
||||||
iconClass: this._iconClass,
|
iconClass: this._iconClass
|
||||||
iconPath: this.opts.iconPath,
|
|
||||||
title: this.title
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,10 +60,8 @@ export abstract class Task {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerTask(showInCommandPalette: boolean = true): IDisposable {
|
public registerTask(): IDisposable {
|
||||||
if (showInCommandPalette) {
|
MenuRegistry.addCommand(this.toCommandAction());
|
||||||
MenuRegistry.addCommand(this.toCommandAction());
|
|
||||||
}
|
|
||||||
return TaskRegistry.registerTask(this.toITask());
|
return TaskRegistry.registerTask(this.toITask());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,8 +96,6 @@ export interface ITask {
|
|||||||
precondition?: ContextKeyExpr;
|
precondition?: ContextKeyExpr;
|
||||||
description?: ITaskHandlerDescription;
|
description?: ITaskHandlerDescription;
|
||||||
iconClass?: string;
|
iconClass?: string;
|
||||||
iconPath?: { dark: string; light?: string; };
|
|
||||||
title?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITaskRegistry {
|
export interface ITaskRegistry {
|
||||||
@@ -110,7 +104,6 @@ export interface ITaskRegistry {
|
|||||||
getTasks(): string[];
|
getTasks(): string[];
|
||||||
getOrCreateTaskIconClassName(item: ICommandAction): string;
|
getOrCreateTaskIconClassName(item: ICommandAction): string;
|
||||||
onTaskRegistered: Event<string>;
|
onTaskRegistered: Event<string>;
|
||||||
getCommandActionById(id: string): ICommandAction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ids = new IdGenerator('task-icon-');
|
const ids = new IdGenerator('task-icon-');
|
||||||
@@ -121,7 +114,6 @@ export const TaskRegistry: ITaskRegistry = new class implements ITaskRegistry {
|
|||||||
private _onTaskRegistered = new Emitter<string>();
|
private _onTaskRegistered = new Emitter<string>();
|
||||||
public readonly onTaskRegistered: Event<string> = this._onTaskRegistered.event;
|
public readonly onTaskRegistered: Event<string> = this._onTaskRegistered.event;
|
||||||
private taskIdToIconClassNameMap: Map<string /* task id */, string /* CSS rule */> = new Map<string, string>();
|
private taskIdToIconClassNameMap: Map<string /* task id */, string /* CSS rule */> = new Map<string, string>();
|
||||||
private taskIdToCommandActionMap: Map<string, ICommandAction> = new Map<string, ICommandAction>();
|
|
||||||
|
|
||||||
registerTask(idOrTask: string | ITask, handler?: ITaskHandler): IDisposable {
|
registerTask(idOrTask: string | ITask, handler?: ITaskHandler): IDisposable {
|
||||||
let disposable: IDisposable;
|
let disposable: IDisposable;
|
||||||
@@ -133,16 +125,6 @@ export const TaskRegistry: ITaskRegistry = new class implements ITaskRegistry {
|
|||||||
if (idOrTask.iconClass) {
|
if (idOrTask.iconClass) {
|
||||||
this.taskIdToIconClassNameMap.set(idOrTask.id, idOrTask.iconClass);
|
this.taskIdToIconClassNameMap.set(idOrTask.id, idOrTask.iconClass);
|
||||||
}
|
}
|
||||||
if (idOrTask.iconPath && idOrTask.title) {
|
|
||||||
this.taskIdToCommandActionMap.set(idOrTask.id, {
|
|
||||||
iconLocation: {
|
|
||||||
dark: URI.parse(idOrTask.iconPath.dark),
|
|
||||||
light: URI.parse(idOrTask.iconPath.light),
|
|
||||||
},
|
|
||||||
id: idOrTask.id,
|
|
||||||
title: idOrTask.title
|
|
||||||
});
|
|
||||||
}
|
|
||||||
disposable = CommandsRegistry.registerCommand(idOrTask);
|
disposable = CommandsRegistry.registerCommand(idOrTask);
|
||||||
id = idOrTask.id;
|
id = idOrTask.id;
|
||||||
}
|
}
|
||||||
@@ -177,8 +159,4 @@ export const TaskRegistry: ITaskRegistry = new class implements ITaskRegistry {
|
|||||||
getTasks(): string[] {
|
getTasks(): string[] {
|
||||||
return this._tasks.slice(0);
|
return this._tasks.slice(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCommandActionById(taskId: string): ICommandAction {
|
|
||||||
return this.taskIdToCommandActionMap.get(taskId);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
57
src/sql/sqlops.d.ts
vendored
57
src/sql/sqlops.d.ts
vendored
@@ -209,6 +209,38 @@ declare module 'sqlops' {
|
|||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for the actions that could happen after connecting is complete
|
||||||
|
*/
|
||||||
|
export interface IConnectionCompletionOptions {
|
||||||
|
/**
|
||||||
|
* Save the connection to MRU and settings (only save to setting if profile.saveProfile is set to true)
|
||||||
|
* Default is true.
|
||||||
|
*/
|
||||||
|
saveConnection: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, open the dashboard after connection is complete.
|
||||||
|
* If undefined / false, dashboard won't be opened after connection completes.
|
||||||
|
* Default is false.
|
||||||
|
*/
|
||||||
|
showDashboard?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If undefined / true, open the connection dialog if connection fails.
|
||||||
|
* If false, connection dialog won't be opened even if connection fails.
|
||||||
|
* Default is true.
|
||||||
|
*/
|
||||||
|
showConnectionDialogOnError?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If undefined / true, open the connection firewall rule dialog if connection fails.
|
||||||
|
* If false, connection firewall rule dialog won't be opened even if connection fails.
|
||||||
|
* Default is true.
|
||||||
|
*/
|
||||||
|
showFirewallRuleOnError?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ConnectionInfoSummary {
|
export interface ConnectionInfoSummary {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1855,14 +1887,19 @@ declare module 'sqlops' {
|
|||||||
* Gets all added accounts.
|
* Gets all added accounts.
|
||||||
* @returns {Thenable<Account>} Promise to return the accounts
|
* @returns {Thenable<Account>} Promise to return the accounts
|
||||||
*/
|
*/
|
||||||
export function getAllAccounts(): Thenable<AccountWithProviderHandle[]>;
|
export function getAllAccounts(): Thenable<Account[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a security token by asking the account's provider
|
* Generates a security token by asking the account's provider
|
||||||
* @param {Account} account Account to generate security token for
|
* @param {Account} account Account to generate security token for
|
||||||
* @return {Thenable<{}>} Promise to return the security token
|
* @return {Thenable<{}>} Promise to return the security token
|
||||||
*/
|
*/
|
||||||
export function getSecurityToken(account: AccountWithProviderHandle): Thenable<{}>;
|
export function getSecurityToken(account: Account): Thenable<{}>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An [event](#Event) which fires when the accounts have changed.
|
||||||
|
*/
|
||||||
|
export const onDidChangeAccounts: vscode.Event<DidChangeAccountsParams>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1930,19 +1967,9 @@ declare module 'sqlops' {
|
|||||||
isStale: boolean;
|
isStale: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export interface DidChangeAccountsParams {
|
||||||
* Represents an account with account provider's handle
|
// Updated accounts
|
||||||
*/
|
accounts: Account[];
|
||||||
export interface AccountWithProviderHandle {
|
|
||||||
/**
|
|
||||||
* Account
|
|
||||||
*/
|
|
||||||
account: Account;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Account's provider handle
|
|
||||||
*/
|
|
||||||
providerHandle: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - ACCOUNT PROVIDER //////////////////////////////////////////////////
|
// - ACCOUNT PROVIDER //////////////////////////////////////////////////
|
||||||
|
|||||||
93
src/sql/sqlops.proposed.d.ts
vendored
93
src/sql/sqlops.proposed.d.ts
vendored
@@ -17,6 +17,7 @@ declare module 'sqlops' {
|
|||||||
*/
|
*/
|
||||||
export interface ModelBuilder {
|
export interface ModelBuilder {
|
||||||
navContainer(): ContainerBuilder<NavContainer, any, any>;
|
navContainer(): ContainerBuilder<NavContainer, any, any>;
|
||||||
|
divContainer(): DivBuilder;
|
||||||
flexContainer(): FlexBuilder;
|
flexContainer(): FlexBuilder;
|
||||||
card(): ComponentBuilder<CardComponent>;
|
card(): ComponentBuilder<CardComponent>;
|
||||||
inputBox(): ComponentBuilder<InputBoxComponent>;
|
inputBox(): ComponentBuilder<InputBoxComponent>;
|
||||||
@@ -72,6 +73,10 @@ declare module 'sqlops' {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DivBuilder extends ContainerBuilder<DivContainer, DivLayout, DivItemLayout> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export interface GroupBuilder extends ContainerBuilder<GroupContainer, GroupLayout, GroupItemLayout> {
|
export interface GroupBuilder extends ContainerBuilder<GroupContainer, GroupLayout, GroupItemLayout> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +152,15 @@ declare module 'sqlops' {
|
|||||||
*/
|
*/
|
||||||
updateProperties(properties: { [key: string]: any }): Thenable<void>;
|
updateProperties(properties: { [key: string]: any }): Thenable<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an updated property of the component to the UI
|
||||||
|
*
|
||||||
|
* @returns {Thenable<void>} Thenable that completes once the update
|
||||||
|
* has been applied in the UI
|
||||||
|
* @memberof Component
|
||||||
|
*/
|
||||||
|
updateProperty(key: string, value: any): Thenable<void>;
|
||||||
|
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
/**
|
/**
|
||||||
* Event fired to notify that the component's validity has changed
|
* Event fired to notify that the component's validity has changed
|
||||||
@@ -312,7 +326,7 @@ declare module 'sqlops' {
|
|||||||
/**
|
/**
|
||||||
* Matches the CSS style key and its available values.
|
* Matches the CSS style key and its available values.
|
||||||
*/
|
*/
|
||||||
CSSStyles?: { [key: string]: string }
|
CSSStyles?: { [key: string]: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormItemLayout {
|
export interface FormItemLayout {
|
||||||
@@ -337,6 +351,33 @@ declare module 'sqlops' {
|
|||||||
export interface GroupItemLayout {
|
export interface GroupItemLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DivLayout {
|
||||||
|
/**
|
||||||
|
* Container Height
|
||||||
|
*/
|
||||||
|
height?: number | string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container Width
|
||||||
|
*/
|
||||||
|
width?: number | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DivItemLayout {
|
||||||
|
/**
|
||||||
|
* Matches the order CSS property and its available values.
|
||||||
|
*/
|
||||||
|
order?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches the CSS style key and its available values.
|
||||||
|
*/
|
||||||
|
CSSStyles?: { [key: string]: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DivContainer extends Container<DivLayout, DivItemLayout>, DivContainerProperties {
|
||||||
|
}
|
||||||
|
|
||||||
export interface FlexContainer extends Container<FlexLayout, FlexItemLayout> {
|
export interface FlexContainer extends Container<FlexLayout, FlexItemLayout> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,6 +468,10 @@ declare module 'sqlops' {
|
|||||||
* Without this the component will fail to correctly size itself
|
* Without this the component will fail to correctly size itself
|
||||||
*/
|
*/
|
||||||
position?: string;
|
position?: string;
|
||||||
|
/**
|
||||||
|
* Matches the CSS style key and its available values.
|
||||||
|
*/
|
||||||
|
CSSStyles?: { [key: string]: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComponentWithIcon {
|
export interface ComponentWithIcon {
|
||||||
@@ -548,12 +593,26 @@ declare module 'sqlops' {
|
|||||||
label?: string;
|
label?: string;
|
||||||
isFile?: boolean;
|
isFile?: boolean;
|
||||||
fileContent?: string;
|
fileContent?: string;
|
||||||
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LoadingComponentProperties {
|
export interface LoadingComponentProperties {
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DivContainerProperties extends ComponentProperties {
|
||||||
|
/**
|
||||||
|
* Matches the overflow-y CSS property and its available values.
|
||||||
|
*/
|
||||||
|
overflowY?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setting the scroll based on the y offset
|
||||||
|
* This is used when its child component is webview
|
||||||
|
*/
|
||||||
|
yOffsetChange?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CardComponent extends Component, CardProperties {
|
export interface CardComponent extends Component, CardProperties {
|
||||||
onDidActionClick: vscode.Event<ActionDescriptor>;
|
onDidActionClick: vscode.Event<ActionDescriptor>;
|
||||||
onCardSelectedChanged: vscode.Event<any>;
|
onCardSelectedChanged: vscode.Event<any>;
|
||||||
@@ -649,8 +708,22 @@ declare module 'sqlops' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ButtonComponent extends Component, ButtonProperties {
|
export interface ButtonComponent extends Component, ButtonProperties {
|
||||||
|
/**
|
||||||
|
* The label for the button
|
||||||
|
*/
|
||||||
label: string;
|
label: string;
|
||||||
|
/**
|
||||||
|
* The title for the button. This title will show when it hovers
|
||||||
|
*/
|
||||||
|
title: string;
|
||||||
|
/**
|
||||||
|
* Icon Path for the button.
|
||||||
|
*/
|
||||||
iconPath: string | vscode.Uri | { light: string | vscode.Uri; dark: string | vscode.Uri };
|
iconPath: string | vscode.Uri | { light: string | vscode.Uri; dark: string | vscode.Uri };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event called when the button is clicked
|
||||||
|
*/
|
||||||
onDidClick: vscode.Event<any>;
|
onDidClick: vscode.Event<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1087,11 +1160,22 @@ declare module 'sqlops' {
|
|||||||
export function createModelViewEditor(title: string, options?: ModelViewEditorOptions): ModelViewEditor;
|
export function createModelViewEditor(title: string, options?: ModelViewEditorOptions): ModelViewEditor;
|
||||||
|
|
||||||
export interface ModelViewEditor extends window.modelviewdialog.ModelViewPanel {
|
export interface ModelViewEditor extends window.modelviewdialog.ModelViewPanel {
|
||||||
|
/**
|
||||||
|
* `true` if there are unpersisted changes.
|
||||||
|
* This is editable to support extensions updating the dirty status.
|
||||||
|
*/
|
||||||
|
isDirty: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the editor
|
* Opens the editor
|
||||||
*/
|
*/
|
||||||
openEditor(position?: vscode.ViewColumn): Thenable<void>;
|
openEditor(position?: vscode.ViewColumn): Thenable<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a save handler for this editor. This will be called if [supportsSave](#ModelViewEditorOptions.supportsSave)
|
||||||
|
* is set to true and the editor is marked as dirty
|
||||||
|
*/
|
||||||
|
registerSaveHandler(handler: () => Thenable<boolean>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1100,6 +1184,11 @@ declare module 'sqlops' {
|
|||||||
* Should the model view editor's context be kept around even when the editor is no longer visible? It is false by default
|
* Should the model view editor's context be kept around even when the editor is no longer visible? It is false by default
|
||||||
*/
|
*/
|
||||||
readonly retainContextWhenHidden?: boolean;
|
readonly retainContextWhenHidden?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this model view editor support save?
|
||||||
|
*/
|
||||||
|
readonly supportsSave?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum DataProviderType {
|
export enum DataProviderType {
|
||||||
@@ -1246,6 +1335,6 @@ declare module 'sqlops' {
|
|||||||
* returns the connection otherwise returns undefined
|
* returns the connection otherwise returns undefined
|
||||||
* @param callback
|
* @param callback
|
||||||
*/
|
*/
|
||||||
export function openConnectionDialog(provider?: string[], initialConnectionProfile?: IConnectionProfile): Thenable<connection.Connection>;
|
export function openConnectionDialog(providers?: string[], initialConnectionProfile?: IConnectionProfile, connectionCompletionOptions?: IConnectionCompletionOptions): Thenable<connection.Connection>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ export enum FrequencyRelativeIntervals {
|
|||||||
|
|
||||||
export enum ModelComponentTypes {
|
export enum ModelComponentTypes {
|
||||||
NavContainer,
|
NavContainer,
|
||||||
|
DivContainer,
|
||||||
FlexContainer,
|
FlexContainer,
|
||||||
Card,
|
Card,
|
||||||
InputBox,
|
InputBox,
|
||||||
|
|||||||
@@ -14,11 +14,14 @@ import {
|
|||||||
SqlMainContext,
|
SqlMainContext,
|
||||||
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||||
import { IMainContext } from 'vs/workbench/api/node/extHost.protocol';
|
import { IMainContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||||
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
|
|
||||||
export class ExtHostAccountManagement extends ExtHostAccountManagementShape {
|
export class ExtHostAccountManagement extends ExtHostAccountManagementShape {
|
||||||
private _handlePool: number = 0;
|
private _handlePool: number = 0;
|
||||||
private _proxy: MainThreadAccountManagementShape;
|
private _proxy: MainThreadAccountManagementShape;
|
||||||
private _providers: { [handle: number]: AccountProviderWithMetadata } = {};
|
private _providers: { [handle: number]: AccountProviderWithMetadata } = {};
|
||||||
|
private _accounts: { [handle: number]: sqlops.Account[] } = {};
|
||||||
|
private readonly _onDidChangeAccounts = new Emitter<sqlops.DidChangeAccountsParams>();
|
||||||
|
|
||||||
constructor(mainContext: IMainContext) {
|
constructor(mainContext: IMainContext) {
|
||||||
super();
|
super();
|
||||||
@@ -31,10 +34,6 @@ export class ExtHostAccountManagement extends ExtHostAccountManagementShape {
|
|||||||
return this._withProvider(handle, (provider: sqlops.AccountProvider) => provider.clear(accountKey));
|
return this._withProvider(handle, (provider: sqlops.AccountProvider) => provider.clear(accountKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
public $getSecurityToken(handle: number, account: sqlops.Account): Thenable<{}> {
|
|
||||||
return this._withProvider(handle, (provider: sqlops.AccountProvider) => provider.getSecurityToken(account));
|
|
||||||
}
|
|
||||||
|
|
||||||
public $initialize(handle: number, restoredAccounts: sqlops.Account[]): Thenable<sqlops.Account[]> {
|
public $initialize(handle: number, restoredAccounts: sqlops.Account[]): Thenable<sqlops.Account[]> {
|
||||||
return this._withProvider(handle, (provider: sqlops.AccountProvider) => provider.initialize(restoredAccounts));
|
return this._withProvider(handle, (provider: sqlops.AccountProvider) => provider.initialize(restoredAccounts));
|
||||||
}
|
}
|
||||||
@@ -64,31 +63,51 @@ export class ExtHostAccountManagement extends ExtHostAccountManagementShape {
|
|||||||
this._proxy.$accountUpdated(updatedAccount);
|
this._proxy.$accountUpdated(updatedAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public $getAllAccounts(): Thenable<sqlops.AccountWithProviderHandle[]> {
|
public $getAllAccounts(): Thenable<sqlops.Account[]> {
|
||||||
if (Object.keys(this._providers).length === 0) {
|
if (Object.keys(this._providers).length === 0) {
|
||||||
throw new Error('No account providers registered.');
|
throw new Error('No account providers registered.');
|
||||||
}
|
}
|
||||||
|
|
||||||
let accountWithProviderHandles: sqlops.AccountWithProviderHandle[] = [];
|
this._accounts = {};
|
||||||
let promises: Thenable<void>[] = [];
|
|
||||||
|
|
||||||
for (let providerKey in this._providers) {
|
const resultAccounts: sqlops.Account[] = [];
|
||||||
let providerHandle = parseInt(providerKey);
|
|
||||||
let provider = this._providers[providerHandle];
|
|
||||||
|
|
||||||
|
const promises: Thenable<void>[] = [];
|
||||||
|
|
||||||
|
for (const providerKey in this._providers) {
|
||||||
|
const providerHandle = parseInt(providerKey);
|
||||||
|
|
||||||
|
const provider = this._providers[providerHandle];
|
||||||
promises.push(this._proxy.$getAccountsForProvider(provider.metadata.id).then(
|
promises.push(this._proxy.$getAccountsForProvider(provider.metadata.id).then(
|
||||||
(accounts) => {
|
(accounts) => {
|
||||||
accounts.forEach((account) => {
|
this._accounts[providerHandle] = accounts;
|
||||||
accountWithProviderHandles.push({
|
resultAccounts.push(...accounts);
|
||||||
account: account,
|
|
||||||
providerHandle: providerHandle
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(promises).then(() => accountWithProviderHandles);
|
return Promise.all(promises).then(() => resultAccounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public $getSecurityToken(account: sqlops.Account): Thenable<{}> {
|
||||||
|
return this.$getAllAccounts().then(() => {
|
||||||
|
for (const handle in this._accounts) {
|
||||||
|
const providerHandle = parseInt(handle);
|
||||||
|
if (this._accounts[handle].findIndex((acct) => acct.key.accountId === account.key.accountId) !== -1) {
|
||||||
|
return this._withProvider(providerHandle, (provider: sqlops.AccountProvider) => provider.getSecurityToken(account));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Account ${account.key.accountId} not found.`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get onDidChangeAccounts(): Event<sqlops.DidChangeAccountsParams> {
|
||||||
|
return this._onDidChangeAccounts.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public $accountsChanged(handle: number, accounts: sqlops.Account[]): Thenable<void> {
|
||||||
|
return this._onDidChangeAccounts.fire({ accounts: accounts });
|
||||||
}
|
}
|
||||||
|
|
||||||
public $registerAccountProvider(providerMetadata: sqlops.AccountProviderMetadata, provider: sqlops.AccountProvider): Disposable {
|
public $registerAccountProvider(providerMetadata: sqlops.AccountProviderMetadata, provider: sqlops.AccountProvider): Disposable {
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ export class ExtHostConnectionManagement extends ExtHostConnectionManagementShap
|
|||||||
return this._proxy.$getCredentials(connectionId);
|
return this._proxy.$getCredentials(connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public $openConnectionDialog(providers?: string[], initialConnectionProfile?: sqlops.IConnectionProfile): Thenable<sqlops.connection.Connection> {
|
public $openConnectionDialog(providers?: string[], initialConnectionProfile?: sqlops.IConnectionProfile, connectionCompletionOptions?: sqlops.IConnectionCompletionOptions): Thenable<sqlops.connection.Connection> {
|
||||||
return this._proxy.$openConnectionDialog(providers, initialConnectionProfile);
|
return this._proxy.$openConnectionDialog(providers, initialConnectionProfile, connectionCompletionOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public $listDatabases(connectionId: string): Thenable<string[]> {
|
public $listDatabases(connectionId: string): Thenable<string[]> {
|
||||||
|
|||||||
@@ -32,14 +32,21 @@ class ModelBuilderImpl implements sqlops.ModelBuilder {
|
|||||||
|
|
||||||
navContainer(): sqlops.ContainerBuilder<sqlops.NavContainer, any, any> {
|
navContainer(): sqlops.ContainerBuilder<sqlops.NavContainer, any, any> {
|
||||||
let id = this.getNextComponentId();
|
let id = this.getNextComponentId();
|
||||||
let container: ContainerBuilderImpl<sqlops.NavContainer, any, any> = new ContainerBuilderImpl(this._proxy, this._handle, ModelComponentTypes.NavContainer, id);
|
let container: GenericContainerBuilder<sqlops.NavContainer, any, any> = new GenericContainerBuilder(this._proxy, this._handle, ModelComponentTypes.NavContainer, id);
|
||||||
|
this._componentBuilders.set(id, container);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
divContainer(): sqlops.DivBuilder {
|
||||||
|
let id = this.getNextComponentId();
|
||||||
|
let container = new DivContainerBuilder(this._proxy, this._handle, ModelComponentTypes.DivContainer, id);
|
||||||
this._componentBuilders.set(id, container);
|
this._componentBuilders.set(id, container);
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
flexContainer(): sqlops.FlexBuilder {
|
flexContainer(): sqlops.FlexBuilder {
|
||||||
let id = this.getNextComponentId();
|
let id = this.getNextComponentId();
|
||||||
let container: ContainerBuilderImpl<sqlops.FlexContainer, any, any> = new ContainerBuilderImpl<sqlops.FlexContainer, sqlops.FlexLayout, sqlops.FlexItemLayout>(this._proxy, this._handle, ModelComponentTypes.FlexContainer, id);
|
let container: GenericContainerBuilder<sqlops.FlexContainer, any, any> = new GenericContainerBuilder<sqlops.FlexContainer, sqlops.FlexLayout, sqlops.FlexItemLayout>(this._proxy, this._handle, ModelComponentTypes.FlexContainer, id);
|
||||||
this._componentBuilders.set(id, container);
|
this._componentBuilders.set(id, container);
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
@@ -60,7 +67,7 @@ class ModelBuilderImpl implements sqlops.ModelBuilder {
|
|||||||
|
|
||||||
groupContainer(): sqlops.GroupBuilder {
|
groupContainer(): sqlops.GroupBuilder {
|
||||||
let id = this.getNextComponentId();
|
let id = this.getNextComponentId();
|
||||||
let container: ContainerBuilderImpl<sqlops.GroupContainer, any, any> = new ContainerBuilderImpl<sqlops.GroupContainer, sqlops.GroupLayout, sqlops.GroupItemLayout>(this._proxy, this._handle, ModelComponentTypes.Group, id);
|
let container: GenericContainerBuilder<sqlops.GroupContainer, any, any> = new GenericContainerBuilder<sqlops.GroupContainer, sqlops.GroupLayout, sqlops.GroupItemLayout>(this._proxy, this._handle, ModelComponentTypes.Group, id);
|
||||||
this._componentBuilders.set(id, container);
|
this._componentBuilders.set(id, container);
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
@@ -241,17 +248,9 @@ class ComponentBuilderImpl<T extends sqlops.Component> implements sqlops.Compone
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GenericComponentBuilder<T extends sqlops.Component> extends ComponentBuilderImpl<T> {
|
|
||||||
constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string) {
|
|
||||||
super(new ComponentWrapper(proxy, handle, type, id));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ContainerBuilderImpl<T extends sqlops.Component, TLayout, TItemLayout> extends ComponentBuilderImpl<T> implements sqlops.ContainerBuilder<T, TLayout, TItemLayout> {
|
class ContainerBuilderImpl<T extends sqlops.Component, TLayout, TItemLayout> extends ComponentBuilderImpl<T> implements sqlops.ContainerBuilder<T, TLayout, TItemLayout> {
|
||||||
constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string) {
|
constructor(componentWrapper: ComponentWrapper) {
|
||||||
super(new ComponentWrapper(proxy, handle, type, id));
|
super(componentWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
withLayout(layout: TLayout): sqlops.ContainerBuilder<T, TLayout, TItemLayout> {
|
withLayout(layout: TLayout): sqlops.ContainerBuilder<T, TLayout, TItemLayout> {
|
||||||
@@ -268,7 +267,19 @@ class ContainerBuilderImpl<T extends sqlops.Component, TLayout, TItemLayout> ext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FormContainerBuilder extends ContainerBuilderImpl<sqlops.FormContainer, sqlops.FormLayout, sqlops.FormItemLayout> implements sqlops.FormBuilder {
|
class GenericContainerBuilder<T extends sqlops.Component, TLayout, TItemLayout> extends ContainerBuilderImpl<T, TLayout, TItemLayout> {
|
||||||
|
constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string) {
|
||||||
|
super(new ComponentWrapper(proxy, handle, type, id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DivContainerBuilder extends ContainerBuilderImpl<sqlops.DivContainer, sqlops.DivLayout, sqlops.DivItemLayout> {
|
||||||
|
constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string) {
|
||||||
|
super(new DivContainerWrapper(proxy, handle, type, id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FormContainerBuilder extends GenericContainerBuilder<sqlops.FormContainer, sqlops.FormLayout, sqlops.FormItemLayout> implements sqlops.FormBuilder {
|
||||||
constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string, private _builder: ModelBuilderImpl) {
|
constructor(proxy: MainThreadModelViewShape, handle: number, type: ModelComponentTypes, id: string, private _builder: ModelBuilderImpl) {
|
||||||
super(proxy, handle, type, id);
|
super(proxy, handle, type, id);
|
||||||
}
|
}
|
||||||
@@ -340,7 +351,7 @@ class FormContainerBuilder extends ContainerBuilderImpl<sqlops.FormContainer, sq
|
|||||||
itemConfig.config.isInGroup = true;
|
itemConfig.config.isInGroup = true;
|
||||||
this._component.insertItem(component.component as ComponentWrapper, componentIndex, itemConfig.config);
|
this._component.insertItem(component.component as ComponentWrapper, componentIndex, itemConfig.config);
|
||||||
if (componentIndex) {
|
if (componentIndex) {
|
||||||
componentIndex ++;
|
componentIndex++;
|
||||||
}
|
}
|
||||||
this.addComponentActions(component, layout);
|
this.addComponentActions(component, layout);
|
||||||
});
|
});
|
||||||
@@ -376,7 +387,7 @@ class FormContainerBuilder extends ContainerBuilderImpl<sqlops.FormContainer, sq
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ToolbarContainerBuilder extends ContainerBuilderImpl<sqlops.ToolbarContainer, sqlops.ToolbarLayout, any> implements sqlops.ToolbarBuilder {
|
class ToolbarContainerBuilder extends GenericContainerBuilder<sqlops.ToolbarContainer, sqlops.ToolbarLayout, any> implements sqlops.ToolbarBuilder {
|
||||||
withToolbarItems(components: sqlops.ToolbarComponent[]): sqlops.ContainerBuilder<sqlops.ToolbarContainer, any, any> {
|
withToolbarItems(components: sqlops.ToolbarComponent[]): sqlops.ContainerBuilder<sqlops.ToolbarContainer, any, any> {
|
||||||
this._component.itemConfigs = components.map(item => {
|
this._component.itemConfigs = components.map(item => {
|
||||||
return this.convertToItemConfig(item);
|
return this.convertToItemConfig(item);
|
||||||
@@ -548,7 +559,7 @@ class ComponentWrapper implements sqlops.Component {
|
|||||||
} else {
|
} else {
|
||||||
throw new Error(nls.localize('invalidIndex', 'The index is invalid.'));
|
throw new Error(nls.localize('invalidIndex', 'The index is invalid.'));
|
||||||
}
|
}
|
||||||
this._proxy.$addToContainer(this._handle, this.id, config.toIItemConfig(), index).then(undefined, this.handleError);
|
this._proxy.$addToContainer(this._handle, this.id, config.toIItemConfig(), index).then(undefined, (err) => this.handleError(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
public setLayout(layout: any): Thenable<void> {
|
public setLayout(layout: any): Thenable<void> {
|
||||||
@@ -560,6 +571,10 @@ class ComponentWrapper implements sqlops.Component {
|
|||||||
return this.notifyPropertyChanged();
|
return this.notifyPropertyChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public updateProperty(key: string, value: any): Thenable<void> {
|
||||||
|
return this.setProperty(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
protected notifyPropertyChanged(): Thenable<void> {
|
protected notifyPropertyChanged(): Thenable<void> {
|
||||||
return this._proxy.$setProperties(this._handle, this._id, this.properties);
|
return this._proxy.$setProperties(this._handle, this._id, this.properties);
|
||||||
}
|
}
|
||||||
@@ -840,9 +855,6 @@ class WebViewWrapper extends ComponentWrapper implements sqlops.WebViewComponent
|
|||||||
public set options(o: vscode.WebviewOptions) {
|
public set options(o: vscode.WebviewOptions) {
|
||||||
this.setProperty('options', o);
|
this.setProperty('options', o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class EditorWrapper extends ComponentWrapper implements sqlops.EditorComponent {
|
class EditorWrapper extends ComponentWrapper implements sqlops.EditorComponent {
|
||||||
@@ -1099,6 +1111,13 @@ class ButtonWrapper extends ComponentWrapper implements sqlops.ButtonComponent {
|
|||||||
this.setProperty('iconPath', v);
|
this.setProperty('iconPath', v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get title(): string {
|
||||||
|
return this.properties['title'];
|
||||||
|
}
|
||||||
|
public set title(v: string) {
|
||||||
|
this.setProperty('title', v);
|
||||||
|
}
|
||||||
|
|
||||||
public get onDidClick(): vscode.Event<any> {
|
public get onDidClick(): vscode.Event<any> {
|
||||||
let emitter = this._emitterMap.get(ComponentEventType.onDidClick);
|
let emitter = this._emitterMap.get(ComponentEventType.onDidClick);
|
||||||
return emitter && emitter.event;
|
return emitter && emitter.event;
|
||||||
@@ -1151,6 +1170,24 @@ class FileBrowserTreeComponentWrapper extends ComponentWrapper implements sqlops
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DivContainerWrapper extends ComponentWrapper implements sqlops.DivContainer {
|
||||||
|
public get overflowY(): string {
|
||||||
|
return this.properties['overflowY'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public set overflowY(value: string) {
|
||||||
|
this.setProperty('overflowY', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get yOffsetChange(): number {
|
||||||
|
return this.properties['yOffsetChange'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public set yOffsetChange(value: number) {
|
||||||
|
this.setProperty('yOffsetChange', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TreeComponentWrapper<T> extends ComponentWrapper implements sqlops.TreeComponent<T> {
|
class TreeComponentWrapper<T> extends ComponentWrapper implements sqlops.TreeComponent<T> {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ class ModelViewPanelImpl implements sqlops.window.modelviewdialog.ModelViewPanel
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ModelViewEditorImpl extends ModelViewPanelImpl implements sqlops.workspace.ModelViewEditor {
|
class ModelViewEditorImpl extends ModelViewPanelImpl implements sqlops.workspace.ModelViewEditor {
|
||||||
|
private _isDirty: boolean;
|
||||||
|
private _saveHandler: () => Thenable<boolean>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
extHostModelViewDialog: ExtHostModelViewDialog,
|
extHostModelViewDialog: ExtHostModelViewDialog,
|
||||||
extHostModelView: ExtHostModelViewShape,
|
extHostModelView: ExtHostModelViewShape,
|
||||||
@@ -84,10 +87,32 @@ class ModelViewEditorImpl extends ModelViewPanelImpl implements sqlops.workspace
|
|||||||
private _options: sqlops.ModelViewEditorOptions
|
private _options: sqlops.ModelViewEditorOptions
|
||||||
) {
|
) {
|
||||||
super('modelViewEditor', extHostModelViewDialog, extHostModelView, extensionLocation);
|
super('modelViewEditor', extHostModelViewDialog, extHostModelView, extensionLocation);
|
||||||
|
this._isDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public openEditor(position?: vscode.ViewColumn): Thenable<void> {
|
public openEditor(position?: vscode.ViewColumn): Thenable<void> {
|
||||||
return this._proxy.$openEditor(this._modelViewId, this._title, this._options, position);
|
return this._proxy.$openEditor(this.handle, this._modelViewId, this._title, this._options, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isDirty(): boolean {
|
||||||
|
return this._isDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set isDirty(value: boolean) {
|
||||||
|
this._isDirty = value;
|
||||||
|
this._proxy.$setDirty(this.handle, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
registerSaveHandler(handler: () => Thenable<boolean>) {
|
||||||
|
this._saveHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public handleSave(): Thenable<boolean> {
|
||||||
|
if (this._saveHandler) {
|
||||||
|
return Promise.resolve(this._saveHandler());
|
||||||
|
} else {
|
||||||
|
return Promise.resolve(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,6 +495,11 @@ export class ExtHostModelViewDialog implements ExtHostModelViewDialogShape {
|
|||||||
return dialog.validateClose();
|
return dialog.validateClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public $handleSave(handle: number): Thenable<boolean> {
|
||||||
|
let editor = this._objectsByHandle.get(handle) as ModelViewEditorImpl;
|
||||||
|
return editor.handleSave();
|
||||||
|
}
|
||||||
|
|
||||||
public openDialog(dialog: sqlops.window.modelviewdialog.Dialog): void {
|
public openDialog(dialog: sqlops.window.modelviewdialog.Dialog): void {
|
||||||
let handle = this.getHandle(dialog);
|
let handle = this.getHandle(dialog);
|
||||||
this.updateDialogContent(dialog);
|
this.updateDialogContent(dialog);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||||
import { IExtHostContext } from 'vs/workbench/api/node/extHost.protocol';
|
import { IExtHostContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||||
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||||
|
import { UpdateAccountListEventParams } from 'sql/services/accountManagement/eventTypes';
|
||||||
|
|
||||||
@extHostNamedCustomer(SqlMainContext.MainThreadAccountManagement)
|
@extHostNamedCustomer(SqlMainContext.MainThreadAccountManagement)
|
||||||
export class MainThreadAccountManagement implements MainThreadAccountManagementShape {
|
export class MainThreadAccountManagement implements MainThreadAccountManagementShape {
|
||||||
@@ -32,6 +33,20 @@ export class MainThreadAccountManagement implements MainThreadAccountManagementS
|
|||||||
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostAccountManagement);
|
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostAccountManagement);
|
||||||
}
|
}
|
||||||
this._toDispose = [];
|
this._toDispose = [];
|
||||||
|
|
||||||
|
this._accountManagementService.updateAccountListEvent((e: UpdateAccountListEventParams) => {
|
||||||
|
if (!e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const providerMetadataIndex = Object.values(this._providerMetadata).findIndex((providerMetadata: sqlops.AccountProviderMetadata) => providerMetadata.id === e.providerId);
|
||||||
|
if (providerMetadataIndex === -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const providerHandle = parseInt(Object.keys(this._providerMetadata)[providerMetadataIndex]);
|
||||||
|
this._proxy.$accountsChanged(providerHandle, e.accountList);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public $beginAutoOAuthDeviceCode(providerId: string, title: string, message: string, userCode: string, uri: string): Thenable<void> {
|
public $beginAutoOAuthDeviceCode(providerId: string, title: string, message: string, userCode: string, uri: string): Thenable<void> {
|
||||||
@@ -62,7 +77,7 @@ export class MainThreadAccountManagement implements MainThreadAccountManagementS
|
|||||||
return self._proxy.$clear(handle, accountKey);
|
return self._proxy.$clear(handle, accountKey);
|
||||||
},
|
},
|
||||||
getSecurityToken(account: sqlops.Account): Thenable<{}> {
|
getSecurityToken(account: sqlops.Account): Thenable<{}> {
|
||||||
return self._proxy.$getSecurityToken(handle, account);
|
return self._proxy.$getSecurityToken(account);
|
||||||
},
|
},
|
||||||
initialize(restoredAccounts: sqlops.Account[]): Thenable<sqlops.Account[]> {
|
initialize(restoredAccounts: sqlops.Account[]): Thenable<sqlops.Account[]> {
|
||||||
return self._proxy.$initialize(handle, restoredAccounts);
|
return self._proxy.$initialize(handle, restoredAccounts);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
|||||||
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
|
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
|
||||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
|
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||||
|
|
||||||
@extHostNamedCustomer(SqlMainContext.MainThreadConnectionManagement)
|
@extHostNamedCustomer(SqlMainContext.MainThreadConnectionManagement)
|
||||||
export class MainThreadConnectionManagement implements MainThreadConnectionManagementShape {
|
export class MainThreadConnectionManagement implements MainThreadConnectionManagementShape {
|
||||||
@@ -51,13 +52,27 @@ export class MainThreadConnectionManagement implements MainThreadConnectionManag
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async $openConnectionDialog(providers: string[], initialConnectionProfile?: IConnectionProfile): Promise<sqlops.connection.Connection> {
|
public async $openConnectionDialog(providers: string[], initialConnectionProfile?: IConnectionProfile, connectionCompletionOptions?: sqlops.IConnectionCompletionOptions): Promise<sqlops.connection.Connection> {
|
||||||
let connectionProfile = await this._connectionDialogService.openDialogAndWait(this._connectionManagementService, { connectionType: 1, providers: providers }, initialConnectionProfile);
|
let connectionProfile = await this._connectionDialogService.openDialogAndWait(this._connectionManagementService, { connectionType: 1, providers: providers }, initialConnectionProfile);
|
||||||
return connectionProfile ? {
|
const connection = connectionProfile ? {
|
||||||
connectionId: connectionProfile.id,
|
connectionId: connectionProfile.id,
|
||||||
options: connectionProfile.options,
|
options: connectionProfile.options,
|
||||||
providerName: connectionProfile.providerName
|
providerName: connectionProfile.providerName
|
||||||
} : undefined;
|
} : undefined;
|
||||||
|
|
||||||
|
if (connectionCompletionOptions) {
|
||||||
|
// Somehow, connectionProfile.saveProfile is false even if initialConnectionProfile.saveProfile is true, reset the flag here.
|
||||||
|
connectionProfile.saveProfile = initialConnectionProfile.saveProfile;
|
||||||
|
await this._connectionManagementService.connectAndSaveProfile(connectionProfile, undefined, {
|
||||||
|
saveTheConnection: isUndefinedOrNull(connectionCompletionOptions.saveConnection) ? true : connectionCompletionOptions.saveConnection,
|
||||||
|
showDashboard: isUndefinedOrNull(connectionCompletionOptions.showDashboard) ? false : connectionCompletionOptions.showDashboard,
|
||||||
|
params: undefined,
|
||||||
|
showConnectionDialogOnError: isUndefinedOrNull(connectionCompletionOptions.showConnectionDialogOnError) ? true : connectionCompletionOptions.showConnectionDialogOnError,
|
||||||
|
showFirewallRuleOnError: isUndefinedOrNull(connectionCompletionOptions.showFirewallRuleOnError) ? true : connectionCompletionOptions.showFirewallRuleOnError
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $listDatabases(connectionId: string): Promise<string[]> {
|
public async $listDatabases(connectionId: string): Promise<string[]> {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { IEditorOptions } from 'vs/platform/editor/common/editor';
|
import { IEditorOptions } from 'vs/platform/editor/common/editor';
|
||||||
|
import { IEditor } from 'vs/workbench/common/editor';
|
||||||
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||||
import { IExtHostContext } from 'vs/workbench/api/node/extHost.protocol';
|
import { IExtHostContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
@@ -14,7 +15,7 @@ import { MainThreadModelViewDialogShape, SqlMainContext, ExtHostModelViewDialogS
|
|||||||
import { Dialog, DialogTab, DialogButton, WizardPage, Wizard } from 'sql/platform/dialog/dialogTypes';
|
import { Dialog, DialogTab, DialogButton, WizardPage, Wizard } from 'sql/platform/dialog/dialogTypes';
|
||||||
import { CustomDialogService } from 'sql/platform/dialog/customDialogService';
|
import { CustomDialogService } from 'sql/platform/dialog/customDialogService';
|
||||||
import { IModelViewDialogDetails, IModelViewTabDetails, IModelViewButtonDetails, IModelViewWizardPageDetails, IModelViewWizardDetails } from 'sql/workbench/api/common/sqlExtHostTypes';
|
import { IModelViewDialogDetails, IModelViewTabDetails, IModelViewButtonDetails, IModelViewWizardPageDetails, IModelViewWizardDetails } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||||
import { ModelViewInput } from 'sql/parts/modelComponents/modelEditor/modelViewInput';
|
import { ModelViewInput, ModelViewInputModel, ModeViewSaveHandler } from 'sql/parts/modelComponents/modelEditor/modelViewInput';
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as sqlops from 'sqlops';
|
import * as sqlops from 'sqlops';
|
||||||
@@ -28,6 +29,7 @@ export class MainThreadModelViewDialog implements MainThreadModelViewDialogShape
|
|||||||
private readonly _wizardPages = new Map<number, WizardPage>();
|
private readonly _wizardPages = new Map<number, WizardPage>();
|
||||||
private readonly _wizardPageHandles = new Map<WizardPage, number>();
|
private readonly _wizardPageHandles = new Map<WizardPage, number>();
|
||||||
private readonly _wizards = new Map<number, Wizard>();
|
private readonly _wizards = new Map<number, Wizard>();
|
||||||
|
private readonly _editorInputModels = new Map<number, ModelViewInputModel>();
|
||||||
private _dialogService: CustomDialogService;
|
private _dialogService: CustomDialogService;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -43,15 +45,18 @@ export class MainThreadModelViewDialog implements MainThreadModelViewDialogShape
|
|||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public $openEditor(modelViewId: string, title: string, options?: sqlops.ModelViewEditorOptions, position?: vscode.ViewColumn): Thenable<void> {
|
public $openEditor(handle: number, modelViewId: string, title: string, options?: sqlops.ModelViewEditorOptions, position?: vscode.ViewColumn): Thenable<void> {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
let input = this._instatiationService.createInstance(ModelViewInput, title, modelViewId, options);
|
let saveHandler: ModeViewSaveHandler = options && options.supportsSave ? (h) => this.handleSave(h) : undefined;
|
||||||
|
let model = new ModelViewInputModel(modelViewId, handle, saveHandler);
|
||||||
|
let input = this._instatiationService.createInstance(ModelViewInput, title, model, options);
|
||||||
let editorOptions = {
|
let editorOptions = {
|
||||||
preserveFocus: true,
|
preserveFocus: true,
|
||||||
pinned: true
|
pinned: true
|
||||||
};
|
};
|
||||||
|
|
||||||
this._editorService.openEditor(input, editorOptions, position as any).then(() => {
|
this._editorService.openEditor(input, editorOptions, position as any).then((editor) => {
|
||||||
|
this._editorInputModels.set(handle, model);
|
||||||
resolve();
|
resolve();
|
||||||
}, error => {
|
}, error => {
|
||||||
reject(error);
|
reject(error);
|
||||||
@@ -59,6 +64,10 @@ export class MainThreadModelViewDialog implements MainThreadModelViewDialogShape
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleSave(handle: number): Thenable<boolean> {
|
||||||
|
return this._proxy.$handleSave(handle);
|
||||||
|
}
|
||||||
|
|
||||||
public $openDialog(handle: number): Thenable<void> {
|
public $openDialog(handle: number): Thenable<void> {
|
||||||
let dialog = this.getDialog(handle);
|
let dialog = this.getDialog(handle);
|
||||||
this._dialogService.showDialog(dialog);
|
this._dialogService.showDialog(dialog);
|
||||||
@@ -213,6 +222,21 @@ export class MainThreadModelViewDialog implements MainThreadModelViewDialogShape
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$setDirty(handle: number, isDirty: boolean): void {
|
||||||
|
let model = this.getEditor(handle);
|
||||||
|
if (model) {
|
||||||
|
model.setDirty(isDirty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getEditor(handle: number): ModelViewInputModel {
|
||||||
|
let model = this._editorInputModels.get(handle);
|
||||||
|
if (!model) {
|
||||||
|
throw new Error('No editor matching the given handle');
|
||||||
|
}
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
private getDialog(handle: number): Dialog {
|
private getDialog(handle: number): Dialog {
|
||||||
let dialog = this._dialogs.get(handle);
|
let dialog = this._dialogs.get(handle);
|
||||||
if (!dialog) {
|
if (!dialog) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionS
|
|||||||
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
import { realpath } from 'fs';
|
import { realpath } from 'fs';
|
||||||
import * as extHostTypes from 'vs/workbench/api/node/extHostTypes';
|
import * as extHostTypes from 'vs/workbench/api/node/extHostTypes';
|
||||||
|
import URI from 'vs/base/common/uri';
|
||||||
|
|
||||||
import * as sqlops from 'sqlops';
|
import * as sqlops from 'sqlops';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
@@ -91,11 +92,14 @@ export function createApiFactory(
|
|||||||
accountUpdated(updatedAccount: sqlops.Account): void {
|
accountUpdated(updatedAccount: sqlops.Account): void {
|
||||||
return extHostAccountManagement.$accountUpdated(updatedAccount);
|
return extHostAccountManagement.$accountUpdated(updatedAccount);
|
||||||
},
|
},
|
||||||
getAllAccounts(): Thenable<sqlops.AccountWithProviderHandle[]> {
|
getAllAccounts(): Thenable<sqlops.Account[]> {
|
||||||
return extHostAccountManagement.$getAllAccounts();
|
return extHostAccountManagement.$getAllAccounts();
|
||||||
},
|
},
|
||||||
getSecurityToken(account: sqlops.AccountWithProviderHandle): Thenable<{}> {
|
getSecurityToken(account: sqlops.Account): Thenable<{}> {
|
||||||
return extHostAccountManagement.$getSecurityToken(account.providerHandle, account.account);
|
return extHostAccountManagement.$getSecurityToken(account);
|
||||||
|
},
|
||||||
|
onDidChangeAccounts(listener: (e: sqlops.DidChangeAccountsParams) => void, thisArgs?: any, disposables?: extHostTypes.Disposable[]) {
|
||||||
|
return extHostAccountManagement.onDidChangeAccounts(listener, thisArgs, disposables);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -110,8 +114,8 @@ export function createApiFactory(
|
|||||||
getCredentials(connectionId: string): Thenable<{ [name: string]: string }> {
|
getCredentials(connectionId: string): Thenable<{ [name: string]: string }> {
|
||||||
return extHostConnectionManagement.$getCredentials(connectionId);
|
return extHostConnectionManagement.$getCredentials(connectionId);
|
||||||
},
|
},
|
||||||
openConnectionDialog(providers?: string[], initialConnectionProfile?: sqlops.IConnectionProfile): Thenable<sqlops.connection.Connection> {
|
openConnectionDialog(providers?: string[], initialConnectionProfile?: sqlops.IConnectionProfile, connectionCompletionOptions?: sqlops.IConnectionCompletionOptions): Thenable<sqlops.connection.Connection> {
|
||||||
return extHostConnectionManagement.$openConnectionDialog(providers, initialConnectionProfile);
|
return extHostConnectionManagement.$openConnectionDialog(providers, initialConnectionProfile, connectionCompletionOptions);
|
||||||
},
|
},
|
||||||
listDatabases(connectionId: string): Thenable<string[]> {
|
listDatabases(connectionId: string): Thenable<string[]> {
|
||||||
return extHostConnectionManagement.$listDatabases(connectionId);
|
return extHostConnectionManagement.$listDatabases(connectionId);
|
||||||
@@ -482,7 +486,7 @@ function defineAPI(factory: ISqlExtensionApiFactory, extensionPaths: TrieMap<IEx
|
|||||||
setDefaultApiImpl: (defaultImpl: ApiImpl) => void,
|
setDefaultApiImpl: (defaultImpl: ApiImpl) => void,
|
||||||
parent: any): ApiImpl {
|
parent: any): ApiImpl {
|
||||||
// get extension id from filename and api for extension
|
// get extension id from filename and api for extension
|
||||||
const ext = extensionPaths.findSubstr(parent.filename);
|
const ext = extensionPaths.findSubstr(URI.file(parent.filename).fsPath);
|
||||||
if (ext) {
|
if (ext) {
|
||||||
let apiImpl = apiMap.get(ext.id);
|
let apiImpl = apiMap.get(ext.id);
|
||||||
if (!apiImpl) {
|
if (!apiImpl) {
|
||||||
@@ -494,6 +498,7 @@ function defineAPI(factory: ISqlExtensionApiFactory, extensionPaths: TrieMap<IEx
|
|||||||
|
|
||||||
// fall back to a default implementation
|
// fall back to a default implementation
|
||||||
if (!defaultImpl) {
|
if (!defaultImpl) {
|
||||||
|
console.warn(`Could not identify extension for 'vscode' require call from ${parent.filename}`);
|
||||||
defaultImpl = createApi(nullExtensionDescription);
|
defaultImpl = createApi(nullExtensionDescription);
|
||||||
setDefaultApiImpl(defaultImpl);
|
setDefaultApiImpl(defaultImpl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,11 @@ import {
|
|||||||
export abstract class ExtHostAccountManagementShape {
|
export abstract class ExtHostAccountManagementShape {
|
||||||
$autoOAuthCancelled(handle: number): Thenable<void> { throw ni(); }
|
$autoOAuthCancelled(handle: number): Thenable<void> { throw ni(); }
|
||||||
$clear(handle: number, accountKey: sqlops.AccountKey): Thenable<void> { throw ni(); }
|
$clear(handle: number, accountKey: sqlops.AccountKey): Thenable<void> { throw ni(); }
|
||||||
$getSecurityToken(handle: number, account: sqlops.Account): Thenable<{}> { throw ni(); }
|
$getSecurityToken(account: sqlops.Account): Thenable<{}> { throw ni(); }
|
||||||
$initialize(handle: number, restoredAccounts: sqlops.Account[]): Thenable<sqlops.Account[]> { throw ni(); }
|
$initialize(handle: number, restoredAccounts: sqlops.Account[]): Thenable<sqlops.Account[]> { throw ni(); }
|
||||||
$prompt(handle: number): Thenable<sqlops.Account> { throw ni(); }
|
$prompt(handle: number): Thenable<sqlops.Account> { throw ni(); }
|
||||||
$refresh(handle: number, account: sqlops.Account): Thenable<sqlops.Account> { throw ni(); }
|
$refresh(handle: number, account: sqlops.Account): Thenable<sqlops.Account> { throw ni(); }
|
||||||
|
$accountsChanged(handle: number, accounts: sqlops.Account[]): Thenable<void> { throw ni(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class ExtHostConnectionManagementShape {
|
export abstract class ExtHostConnectionManagementShape {
|
||||||
@@ -502,7 +503,7 @@ export interface MainThreadConnectionManagementShape extends IDisposable {
|
|||||||
$getActiveConnections(): Thenable<sqlops.connection.Connection[]>;
|
$getActiveConnections(): Thenable<sqlops.connection.Connection[]>;
|
||||||
$getCurrentConnection(): Thenable<sqlops.connection.Connection>;
|
$getCurrentConnection(): Thenable<sqlops.connection.Connection>;
|
||||||
$getCredentials(connectionId: string): Thenable<{ [name: string]: string }>;
|
$getCredentials(connectionId: string): Thenable<{ [name: string]: string }>;
|
||||||
$openConnectionDialog(providers: string[], initialConnectionProfile?: sqlops.IConnectionProfile): Thenable<sqlops.connection.Connection>;
|
$openConnectionDialog(providers: string[], initialConnectionProfile?: sqlops.IConnectionProfile, connectionCompletionOptions?: sqlops.IConnectionCompletionOptions): Thenable<sqlops.connection.Connection>;
|
||||||
$listDatabases(connectionId: string): Thenable<string[]>;
|
$listDatabases(connectionId: string): Thenable<string[]>;
|
||||||
$getConnectionString(connectionId: string, includePassword: boolean): Thenable<string>;
|
$getConnectionString(connectionId: string, includePassword: boolean): Thenable<string>;
|
||||||
$getUriForConnection(connectionId: string): Thenable<string>;
|
$getUriForConnection(connectionId: string): Thenable<string>;
|
||||||
@@ -671,10 +672,11 @@ export interface ExtHostModelViewDialogShape {
|
|||||||
$updateWizardPageInfo(handle: number, pageHandles: number[], currentPageIndex: number): void;
|
$updateWizardPageInfo(handle: number, pageHandles: number[], currentPageIndex: number): void;
|
||||||
$validateNavigation(handle: number, info: sqlops.window.modelviewdialog.WizardPageChangeInfo): Thenable<boolean>;
|
$validateNavigation(handle: number, info: sqlops.window.modelviewdialog.WizardPageChangeInfo): Thenable<boolean>;
|
||||||
$validateDialogClose(handle: number): Thenable<boolean>;
|
$validateDialogClose(handle: number): Thenable<boolean>;
|
||||||
|
$handleSave(handle: number): Thenable<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MainThreadModelViewDialogShape extends IDisposable {
|
export interface MainThreadModelViewDialogShape extends IDisposable {
|
||||||
$openEditor(modelViewId: string, title: string, options?: sqlops.ModelViewEditorOptions, position?: vscode.ViewColumn): Thenable<void>;
|
$openEditor(handle: number, modelViewId: string, title: string, options?: sqlops.ModelViewEditorOptions, position?: vscode.ViewColumn): Thenable<void>;
|
||||||
$openDialog(handle: number): Thenable<void>;
|
$openDialog(handle: number): Thenable<void>;
|
||||||
$closeDialog(handle: number): Thenable<void>;
|
$closeDialog(handle: number): Thenable<void>;
|
||||||
$setDialogDetails(handle: number, details: IModelViewDialogDetails): Thenable<void>;
|
$setDialogDetails(handle: number, details: IModelViewDialogDetails): Thenable<void>;
|
||||||
@@ -687,6 +689,7 @@ export interface MainThreadModelViewDialogShape extends IDisposable {
|
|||||||
$addWizardPage(wizardHandle: number, pageHandle: number, pageIndex: number): Thenable<void>;
|
$addWizardPage(wizardHandle: number, pageHandle: number, pageIndex: number): Thenable<void>;
|
||||||
$removeWizardPage(wizardHandle: number, pageIndex: number): Thenable<void>;
|
$removeWizardPage(wizardHandle: number, pageIndex: number): Thenable<void>;
|
||||||
$setWizardPage(wizardHandle: number, pageIndex: number): Thenable<void>;
|
$setWizardPage(wizardHandle: number, pageIndex: number): Thenable<void>;
|
||||||
|
$setDirty(handle: number, isDirty: boolean): void;
|
||||||
}
|
}
|
||||||
export interface ExtHostQueryEditorShape {
|
export interface ExtHostQueryEditorShape {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,26 @@ import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/wor
|
|||||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||||
import { ShowCurrentReleaseNotesAction } from 'sql/workbench/update/releaseNotes';
|
import { ShowCurrentReleaseNotesAction } from 'sql/workbench/update/releaseNotes';
|
||||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||||
|
import { IConfigurationRegistry, Extensions as ConfigExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||||
|
|
||||||
new Actions.BackupAction().registerTask(false);
|
new Actions.BackupAction().registerTask();
|
||||||
new Actions.RestoreAction().registerTask(false);
|
new Actions.RestoreAction().registerTask();
|
||||||
new Actions.NewQueryAction().registerTask();
|
new Actions.NewQueryAction().registerTask();
|
||||||
new Actions.ConfigureDashboardAction().registerTask();
|
new Actions.ConfigureDashboardAction().registerTask();
|
||||||
|
|
||||||
// add product update and release notes contributions
|
// add product update and release notes contributions
|
||||||
Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions)
|
Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions)
|
||||||
.registerWorkbenchAction(new SyncActionDescriptor(ShowCurrentReleaseNotesAction, ShowCurrentReleaseNotesAction.ID, ShowCurrentReleaseNotesAction.LABEL), 'Show Getting Started');
|
.registerWorkbenchAction(new SyncActionDescriptor(ShowCurrentReleaseNotesAction, ShowCurrentReleaseNotesAction.ID, ShowCurrentReleaseNotesAction.LABEL), 'Show Getting Started');
|
||||||
|
|
||||||
|
Registry.as<IConfigurationRegistry>(ConfigExtensions.Configuration).registerConfiguration({
|
||||||
|
'id': 'previewFeatures',
|
||||||
|
'title': nls.localize('previewFeatures.configTitle', 'Preview Features'),
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'workbench.enablePreviewFeatures': {
|
||||||
|
'type': 'boolean',
|
||||||
|
'default': undefined,
|
||||||
|
'description': nls.localize('previewFeatures.configEnable', 'Enable unreleased preview features')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import { IWindowsService } from 'vs/platform/windows/common/windows';
|
|||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
|
||||||
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
|
|
||||||
export interface BaseActionContext {
|
export interface BaseActionContext {
|
||||||
object?: ObjectMetadata;
|
object?: ObjectMetadata;
|
||||||
@@ -300,6 +302,20 @@ export class BackupAction extends Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runTask(accessor: ServicesAccessor, profile: IConnectionProfile): TPromise<void> {
|
runTask(accessor: ServicesAccessor, profile: IConnectionProfile): TPromise<void> {
|
||||||
|
if (!profile) {
|
||||||
|
let objectExplorerService = accessor.get<IObjectExplorerService>(IObjectExplorerService);
|
||||||
|
let connectionManagementService = accessor.get<IConnectionManagementService>(IConnectionManagementService);
|
||||||
|
let workbenchEditorService = accessor.get<IEditorService>(IEditorService);
|
||||||
|
profile = TaskUtilities.getCurrentGlobalConnection(objectExplorerService, connectionManagementService, workbenchEditorService);
|
||||||
|
}
|
||||||
|
let configurationService = accessor.get<IWorkspaceConfigurationService>(IWorkspaceConfigurationService);
|
||||||
|
let previewFeaturesEnabled: boolean = configurationService.getValue('workbench')['enablePreviewFeatures'];
|
||||||
|
if (!previewFeaturesEnabled) {
|
||||||
|
return new TPromise<void>((resolve, reject) => {
|
||||||
|
accessor.get<INotificationService>(INotificationService).info(nls.localize('backup.isPreviewFeature', 'You must enable preview features in order to use backup'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return new TPromise<void>((resolve, reject) => {
|
return new TPromise<void>((resolve, reject) => {
|
||||||
TaskUtilities.showBackup(
|
TaskUtilities.showBackup(
|
||||||
profile,
|
profile,
|
||||||
@@ -331,6 +347,14 @@ export class RestoreAction extends Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runTask(accessor: ServicesAccessor, profile: IConnectionProfile): TPromise<void> {
|
runTask(accessor: ServicesAccessor, profile: IConnectionProfile): TPromise<void> {
|
||||||
|
let configurationService = accessor.get<IWorkspaceConfigurationService>(IWorkspaceConfigurationService);
|
||||||
|
let previewFeaturesEnabled: boolean = configurationService.getValue('workbench')['enablePreviewFeatures'];
|
||||||
|
if (!previewFeaturesEnabled) {
|
||||||
|
return new TPromise<void>((resolve, reject) => {
|
||||||
|
accessor.get<INotificationService>(INotificationService).info(nls.localize('restore.isPreviewFeature', 'You must enable preview features in order to use restore'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return new TPromise<void>((resolve, reject) => {
|
return new TPromise<void>((resolve, reject) => {
|
||||||
TaskUtilities.showRestore(
|
TaskUtilities.showRestore(
|
||||||
profile,
|
profile,
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { TPromise } from 'vs/base/common/winjs.base';
|
|
||||||
import { Event } from 'vs/base/common/event';
|
|
||||||
import { ITreeViewDataProvider, ITreeItem } from 'vs/workbench/common/views';
|
import { ITreeViewDataProvider, ITreeItem } from 'vs/workbench/common/views';
|
||||||
|
|
||||||
export interface ITreeComponentItem extends ITreeItem {
|
export interface ITreeComponentItem extends ITreeItem {
|
||||||
@@ -16,7 +14,3 @@ export interface ITreeComponentItem extends ITreeItem {
|
|||||||
export interface IModelViewTreeViewDataProvider extends ITreeViewDataProvider {
|
export interface IModelViewTreeViewDataProvider extends ITreeViewDataProvider {
|
||||||
refresh(itemsToRefreshByHandle: { [treeItemHandle: string]: ITreeComponentItem });
|
refresh(itemsToRefreshByHandle: { [treeItemHandle: string]: ITreeComponentItem });
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IModelViewTreeViewDataProvider {
|
|
||||||
getChildren(element?: ITreeComponentItem): TPromise<ITreeComponentItem[]>;
|
|
||||||
}
|
|
||||||
70
src/sql/workbench/electron-browser/enablePreviewFeatures.ts
Normal file
70
src/sql/workbench/electron-browser/enablePreviewFeatures.ts
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||||
|
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||||
|
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
|
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||||
|
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||||
|
import { localize } from 'vs/nls';
|
||||||
|
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||||
|
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
|
||||||
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
|
|
||||||
|
export class EnablePreviewFeatures implements IWorkbenchContribution {
|
||||||
|
|
||||||
|
private static ENABLE_PREVIEW_FEATURES_SHOWN = 'workbench.enablePreviewFeaturesShown';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@IStorageService storageService: IStorageService,
|
||||||
|
@IOpenerService openerService: IOpenerService,
|
||||||
|
@INotificationService notificationService: INotificationService,
|
||||||
|
@IWindowService windowService: IWindowService,
|
||||||
|
@IWindowsService windowsService: IWindowsService,
|
||||||
|
@ITelemetryService telemetryService: ITelemetryService,
|
||||||
|
@IConfigurationService configurationService: IConfigurationService
|
||||||
|
) {
|
||||||
|
let previewFeaturesEnabled = configurationService.getValue('workbench')['enablePreviewFeatures'];
|
||||||
|
if (previewFeaturesEnabled || storageService.get(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Promise.all([
|
||||||
|
windowService.isFocused(),
|
||||||
|
windowsService.getWindowCount()
|
||||||
|
]).then(([focused, count]) => {
|
||||||
|
if (!focused && count > 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
configurationService.updateValue('workbench.enablePreviewFeatures', false);
|
||||||
|
|
||||||
|
const enablePreviewFeaturesNotice = localize('enablePreviewFeatures.notice', "Would you like to enable preview features?");
|
||||||
|
notificationService.prompt(
|
||||||
|
Severity.Info,
|
||||||
|
enablePreviewFeaturesNotice,
|
||||||
|
[{
|
||||||
|
label: localize('enablePreviewFeatures.yes', "Yes"),
|
||||||
|
run: () => {
|
||||||
|
configurationService.updateValue('workbench.enablePreviewFeatures', true);
|
||||||
|
storageService.store(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
label: localize('enablePreviewFeatures.no', "No"),
|
||||||
|
run: () => {
|
||||||
|
configurationService.updateValue('workbench.enablePreviewFeatures', false);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
label: localize('enablePreviewFeatures.never', "No, don't show again"),
|
||||||
|
run: () => {
|
||||||
|
configurationService.updateValue('workbench.enablePreviewFeatures', false);
|
||||||
|
storageService.store(EnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true);
|
||||||
|
},
|
||||||
|
isSecondary: true
|
||||||
|
}]
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.then(null, onUnexpectedError);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -108,13 +108,13 @@ export class ErrorMessageDialog extends Modal {
|
|||||||
private updateIconTitle(): void {
|
private updateIconTitle(): void {
|
||||||
switch (this._severity) {
|
switch (this._severity) {
|
||||||
case Severity.Error:
|
case Severity.Error:
|
||||||
this.titleIconClassName = 'icon error';
|
this.titleIconClassName = 'sql icon error';
|
||||||
break;
|
break;
|
||||||
case Severity.Warning:
|
case Severity.Warning:
|
||||||
this.titleIconClassName = 'icon warning';
|
this.titleIconClassName = 'sql icon warning';
|
||||||
break;
|
break;
|
||||||
case Severity.Info:
|
case Severity.Info:
|
||||||
this.titleIconClassName = 'icon info';
|
this.titleIconClassName = 'sql icon info';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class TestComponent extends ComponentBase {
|
|||||||
public descriptor: IComponentDescriptor;
|
public descriptor: IComponentDescriptor;
|
||||||
|
|
||||||
constructor(public modelStore: IModelStore, id: string) {
|
constructor(public modelStore: IModelStore, id: string) {
|
||||||
super(undefined);
|
super(undefined, undefined);
|
||||||
this.descriptor = modelStore.createComponentDescriptor('TestComponent', id);
|
this.descriptor = modelStore.createComponentDescriptor('TestComponent', id);
|
||||||
this.baseInit();
|
this.baseInit();
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ class TestContainer extends ContainerBase<TestComponent> {
|
|||||||
public descriptor: IComponentDescriptor;
|
public descriptor: IComponentDescriptor;
|
||||||
|
|
||||||
constructor(public modelStore: IModelStore, id: string) {
|
constructor(public modelStore: IModelStore, id: string) {
|
||||||
super(undefined);
|
super(undefined, undefined);
|
||||||
this.descriptor = modelStore.createComponentDescriptor('TestContainer', id);
|
this.descriptor = modelStore.createComponentDescriptor('TestContainer', id);
|
||||||
this._changeRef = {
|
this._changeRef = {
|
||||||
detectChanges: () => undefined
|
detectChanges: () => undefined
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||||
import { EditorInput } from 'vs/workbench/common/editor';
|
|
||||||
import { IEditorDescriptor } from 'vs/workbench/browser/editor';
|
import { IEditorDescriptor } from 'vs/workbench/browser/editor';
|
||||||
import { TPromise } from 'vs/base/common/winjs.base';
|
import { TPromise } from 'vs/base/common/winjs.base';
|
||||||
import URI from 'vs/base/common/uri';
|
import URI from 'vs/base/common/uri';
|
||||||
@@ -30,8 +29,9 @@ import * as TypeMoq from 'typemoq';
|
|||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||||
import { INotification, INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
|
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
|
||||||
|
import { ConfigurationService } from 'vs/platform/configuration/node/configurationService';
|
||||||
|
|
||||||
suite('SQL QueryEditor Tests', () => {
|
suite('SQL QueryEditor Tests', () => {
|
||||||
let queryModelService: QueryModelService;
|
let queryModelService: QueryModelService;
|
||||||
@@ -40,6 +40,7 @@ suite('SQL QueryEditor Tests', () => {
|
|||||||
let notificationService: TypeMoq.Mock<INotificationService>;
|
let notificationService: TypeMoq.Mock<INotificationService>;
|
||||||
let editorDescriptorService: TypeMoq.Mock<EditorDescriptorService>;
|
let editorDescriptorService: TypeMoq.Mock<EditorDescriptorService>;
|
||||||
let connectionManagementService: TypeMoq.Mock<ConnectionManagementService>;
|
let connectionManagementService: TypeMoq.Mock<ConnectionManagementService>;
|
||||||
|
let configurationService: TypeMoq.Mock<ConfigurationService>;
|
||||||
let memento: TypeMoq.Mock<Memento>;
|
let memento: TypeMoq.Mock<Memento>;
|
||||||
|
|
||||||
let queryInput: QueryInput;
|
let queryInput: QueryInput;
|
||||||
@@ -57,7 +58,8 @@ suite('SQL QueryEditor Tests', () => {
|
|||||||
undefined,
|
undefined,
|
||||||
editorDescriptorService.object,
|
editorDescriptorService.object,
|
||||||
undefined,
|
undefined,
|
||||||
undefined);
|
undefined,
|
||||||
|
configurationService.object);
|
||||||
};
|
};
|
||||||
|
|
||||||
setup(() => {
|
setup(() => {
|
||||||
@@ -134,6 +136,14 @@ suite('SQL QueryEditor Tests', () => {
|
|||||||
|
|
||||||
// Create a QueryModelService
|
// Create a QueryModelService
|
||||||
queryModelService = new QueryModelService(instantiationService.object, notificationService.object);
|
queryModelService = new QueryModelService(instantiationService.object, notificationService.object);
|
||||||
|
|
||||||
|
configurationService = TypeMoq.Mock.ofInstance({
|
||||||
|
getValue: () => undefined,
|
||||||
|
onDidChangeConfiguration: () => undefined
|
||||||
|
} as any);
|
||||||
|
configurationService.setup(x => x.getValue(TypeMoq.It.isAny())).returns(() => {
|
||||||
|
return { enablePreviewFeatures: true };
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('createEditor creates only the taskbar', (done) => {
|
test('createEditor creates only the taskbar', (done) => {
|
||||||
|
|||||||
@@ -292,16 +292,7 @@ suite('ExtHostAccountManagement', () => {
|
|||||||
};
|
};
|
||||||
let mockAccounts = [mockAccount1, mockAccount2];
|
let mockAccounts = [mockAccount1, mockAccount2];
|
||||||
|
|
||||||
let expectedAccounts = [
|
let expectedAccounts = [mockAccount1, mockAccount2];
|
||||||
{
|
|
||||||
account: mockAccount1,
|
|
||||||
providerHandle: 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
account: mockAccount2,
|
|
||||||
providerHandle: 0
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
let mockAccountManagementService = getMockAccountManagementService(mockAccounts);
|
let mockAccountManagementService = getMockAccountManagementService(mockAccounts);
|
||||||
instantiationService.stub(IAccountManagementService, mockAccountManagementService.object);
|
instantiationService.stub(IAccountManagementService, mockAccountManagementService.object);
|
||||||
@@ -341,6 +332,110 @@ suite('ExtHostAccountManagement', () => {
|
|||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('GetSecurityToken - Success', (done) => {
|
||||||
|
let mockAccountProviderMetadata = {
|
||||||
|
id: 'azure',
|
||||||
|
displayName: 'Azure'
|
||||||
|
};
|
||||||
|
|
||||||
|
let mockAccount1 = {
|
||||||
|
key: {
|
||||||
|
providerId: mockAccountProviderMetadata.id,
|
||||||
|
accountId: 'azure_account_1'
|
||||||
|
},
|
||||||
|
displayInfo: {
|
||||||
|
contextualDisplayName: 'Microsoft Account',
|
||||||
|
accountType: 'microsoft',
|
||||||
|
displayName: 'Azure Account 1'
|
||||||
|
},
|
||||||
|
properties: [],
|
||||||
|
isStale: false
|
||||||
|
};
|
||||||
|
let mockAccounts = [mockAccount1];
|
||||||
|
|
||||||
|
let mockAccountManagementService = getMockAccountManagementService(mockAccounts);
|
||||||
|
instantiationService.stub(IAccountManagementService, mockAccountManagementService.object);
|
||||||
|
let accountManagementService = instantiationService.createInstance(MainThreadAccountManagement);
|
||||||
|
threadService.set(SqlMainContext.MainThreadAccountManagement, accountManagementService);
|
||||||
|
|
||||||
|
// Setup: Create ext host account management with registered account provider
|
||||||
|
let extHost = new ExtHostAccountManagement(threadService);
|
||||||
|
extHost.$registerAccountProvider(mockAccountProviderMetadata, new AccountProviderStub());
|
||||||
|
|
||||||
|
extHost.$getAllAccounts()
|
||||||
|
.then((accounts) => {
|
||||||
|
// If: I get security token
|
||||||
|
extHost.$getSecurityToken(mockAccount1)
|
||||||
|
.then((securityToken) => {
|
||||||
|
// Then: The call should have been passed to the account management service
|
||||||
|
mockAccountManagementService.verify(
|
||||||
|
(obj) => obj.getSecurityToken(TypeMoq.It.isAny()),
|
||||||
|
TypeMoq.Times.once()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
).then(() => done(), (err) => done(err));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('GetSecurityToken - Account not found', (done) => {
|
||||||
|
let mockAccountProviderMetadata = {
|
||||||
|
id: 'azure',
|
||||||
|
displayName: 'Azure'
|
||||||
|
};
|
||||||
|
|
||||||
|
let mockAccount1 = {
|
||||||
|
key: {
|
||||||
|
providerId: mockAccountProviderMetadata.id,
|
||||||
|
accountId: 'azure_account_1'
|
||||||
|
},
|
||||||
|
displayInfo: {
|
||||||
|
contextualDisplayName: 'Microsoft Account',
|
||||||
|
accountType: 'microsoft',
|
||||||
|
displayName: 'Azure Account 1'
|
||||||
|
},
|
||||||
|
properties: [],
|
||||||
|
isStale: false
|
||||||
|
};
|
||||||
|
let mockAccounts = [mockAccount1];
|
||||||
|
|
||||||
|
let mockAccountManagementService = getMockAccountManagementService(mockAccounts);
|
||||||
|
instantiationService.stub(IAccountManagementService, mockAccountManagementService.object);
|
||||||
|
let accountManagementService = instantiationService.createInstance(MainThreadAccountManagement);
|
||||||
|
threadService.set(SqlMainContext.MainThreadAccountManagement, accountManagementService);
|
||||||
|
|
||||||
|
// Setup: Create ext host account management with registered account provider
|
||||||
|
let extHost = new ExtHostAccountManagement(threadService);
|
||||||
|
extHost.$registerAccountProvider(mockAccountProviderMetadata, new AccountProviderStub());
|
||||||
|
|
||||||
|
let mockAccount2 = {
|
||||||
|
key: {
|
||||||
|
providerId: mockAccountProviderMetadata.id,
|
||||||
|
accountId: 'azure_account_2'
|
||||||
|
},
|
||||||
|
displayInfo: {
|
||||||
|
contextualDisplayName: 'Work/School Account',
|
||||||
|
accountType: 'microsoft',
|
||||||
|
displayName: 'Azure Account 2'
|
||||||
|
},
|
||||||
|
properties: [],
|
||||||
|
isStale: false
|
||||||
|
};
|
||||||
|
|
||||||
|
extHost.$getAllAccounts().then((accounts) => {
|
||||||
|
// If: I get security token for mockAccount2
|
||||||
|
// Then: It should throw
|
||||||
|
assert.throws(
|
||||||
|
() => extHost.$getSecurityToken(mockAccount2),
|
||||||
|
(error) => {
|
||||||
|
return error.message === `Account ${mockAccount2.key.accountId} not found.`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function getMockAccountProvider(): TypeMoq.Mock<sqlops.AccountProvider> {
|
function getMockAccountProvider(): TypeMoq.Mock<sqlops.AccountProvider> {
|
||||||
@@ -362,6 +457,10 @@ function getMockAccountManagementService(accounts: sqlops.Account[]): TypeMoq.Mo
|
|||||||
|
|
||||||
mockAccountManagementService.setup(x => x.getAccountsForProvider(TypeMoq.It.isAny()))
|
mockAccountManagementService.setup(x => x.getAccountsForProvider(TypeMoq.It.isAny()))
|
||||||
.returns(() => Promise.resolve(accounts));
|
.returns(() => Promise.resolve(accounts));
|
||||||
|
mockAccountManagementService.setup(x => x.getSecurityToken(TypeMoq.It.isValue(accounts[0])))
|
||||||
|
.returns(() => Promise.resolve({}));
|
||||||
|
mockAccountManagementService.setup(x => x.updateAccountListEvent)
|
||||||
|
.returns(() => () => { return undefined; } );
|
||||||
|
|
||||||
return mockAccountManagementService;
|
return mockAccountManagementService;
|
||||||
}
|
}
|
||||||
15
src/typings/globals/slickgrid/index.d.ts
vendored
15
src/typings/globals/slickgrid/index.d.ts
vendored
@@ -764,6 +764,16 @@ declare namespace Slick {
|
|||||||
**/
|
**/
|
||||||
destroy(): void;
|
destroy(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets selected ranges for the grid
|
||||||
|
*/
|
||||||
|
setSelectedRanges(ranges: Slick.Range[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets selected ranges for the grid
|
||||||
|
*/
|
||||||
|
getSelectedRanges(): Slick.Range[];
|
||||||
|
|
||||||
onSelectedRangesChanged: Slick.Event<E>;
|
onSelectedRangesChanged: Slick.Event<E>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1252,16 +1262,21 @@ declare namespace Slick {
|
|||||||
export interface OnDragEndEventArgs<T extends SlickData> extends GridEventArgs<T> {
|
export interface OnDragEndEventArgs<T extends SlickData> extends GridEventArgs<T> {
|
||||||
// todo: need to understand $canvas drag event parameter's 'dd' object
|
// todo: need to understand $canvas drag event parameter's 'dd' object
|
||||||
// the documentation is not enlightening
|
// the documentation is not enlightening
|
||||||
|
range: { start: Slick.Cell, end: Slick.Cell };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OnDragEventArgs<T extends SlickData> extends GridEventArgs<T> {
|
export interface OnDragEventArgs<T extends SlickData> extends GridEventArgs<T> {
|
||||||
// todo: need to understand $canvas drag event parameter's 'dd' object
|
// todo: need to understand $canvas drag event parameter's 'dd' object
|
||||||
// the documentation is not enlightening
|
// the documentation is not enlightening
|
||||||
|
range: { start: Slick.Cell, end: Slick.Cell };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OnDragStartEventArgs<T extends SlickData> extends GridEventArgs<T> {
|
export interface OnDragStartEventArgs<T extends SlickData> extends GridEventArgs<T> {
|
||||||
// todo: need to understand $canvas drag event parameter's 'dd' object
|
// todo: need to understand $canvas drag event parameter's 'dd' object
|
||||||
// the documentation is not enlightening
|
// the documentation is not enlightening
|
||||||
|
startX: number;
|
||||||
|
startY: number;
|
||||||
|
range: { start: Slick.Cell, end: Slick.Cell };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OnDragInitEventArgs<T extends SlickData> extends GridEventArgs<T> {
|
export interface OnDragInitEventArgs<T extends SlickData> extends GridEventArgs<T> {
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ import { readFile } from 'vs/base/node/pfs';
|
|||||||
import { writeFileAndFlushSync } from 'vs/base/node/extfs';
|
import { writeFileAndFlushSync } from 'vs/base/node/extfs';
|
||||||
import { generateUuid, isUUID } from 'vs/base/common/uuid';
|
import { generateUuid, isUUID } from 'vs/base/common/uuid';
|
||||||
import { values } from 'vs/base/common/map';
|
import { values } from 'vs/base/common/map';
|
||||||
|
// {{SQL CARBON EDIT}}
|
||||||
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
|
import { ExtensionsPolicy, ExtensionsPolicyKey } from 'vs/workbench/parts/extensions/common/extensions';
|
||||||
|
|
||||||
interface IRawGalleryExtensionFile {
|
interface IRawGalleryExtensionFile {
|
||||||
assetType: string;
|
assetType: string;
|
||||||
@@ -367,7 +370,9 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
|||||||
constructor(
|
constructor(
|
||||||
@IRequestService private requestService: IRequestService,
|
@IRequestService private requestService: IRequestService,
|
||||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||||
@ITelemetryService private telemetryService: ITelemetryService
|
@ITelemetryService private telemetryService: ITelemetryService,
|
||||||
|
// {{SQL CARBON EDIT}}
|
||||||
|
@IConfigurationService private configurationService: IConfigurationService
|
||||||
) {
|
) {
|
||||||
const config = product.extensionsGallery;
|
const config = product.extensionsGallery;
|
||||||
this.extensionsGalleryUrl = config && config.serviceUrl;
|
this.extensionsGalleryUrl = config && config.serviceUrl;
|
||||||
@@ -508,6 +513,12 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let actualTotal = filteredExtensions.length;
|
let actualTotal = filteredExtensions.length;
|
||||||
|
|
||||||
|
// {{SQL CARBON EDIT}}
|
||||||
|
let extensionPolicy = this.configurationService.getValue<string>(ExtensionsPolicyKey);
|
||||||
|
if (extensionPolicy === ExtensionsPolicy.allowMicrosoft) {
|
||||||
|
filteredExtensions = filteredExtensions.filter(ext => ext.publisher && ext.publisher.displayName === 'Microsoft');
|
||||||
|
}
|
||||||
return { galleryExtensions: filteredExtensions, total: actualTotal };
|
return { galleryExtensions: filteredExtensions, total: actualTotal };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,7 +562,9 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
|||||||
headers
|
headers
|
||||||
}).then(context => {
|
}).then(context => {
|
||||||
|
|
||||||
if (context.res.statusCode >= 400 && context.res.statusCode < 500) {
|
// {{SQL CARBON EDIT}}
|
||||||
|
let extensionPolicy: string = this.configurationService.getValue<string>(ExtensionsPolicyKey);
|
||||||
|
if (context.res.statusCode >= 400 && context.res.statusCode < 500 || extensionPolicy === ExtensionsPolicy.allowNone) {
|
||||||
return { galleryExtensions: [], total: 0 };
|
return { galleryExtensions: [], total: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,7 +618,9 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
|||||||
*/
|
*/
|
||||||
const log = (duration: number) => this.telemetryService.publicLog('galleryService:downloadVSIX', assign(data, { duration }));
|
const log = (duration: number) => this.telemetryService.publicLog('galleryService:downloadVSIX', assign(data, { duration }));
|
||||||
|
|
||||||
const operationParam = operation === InstallOperation.Install ? 'install' : operation === InstallOperation.Update ? 'update' : '';
|
// {{SQL Carbon Edit}} - Don't append install or update on to the URL
|
||||||
|
// const operationParam = operation === InstallOperation.Install ? 'install' : operation === InstallOperation.Update ? 'update' : '';
|
||||||
|
const operationParam = undefined;
|
||||||
const downloadAsset = operationParam ? {
|
const downloadAsset = operationParam ? {
|
||||||
uri: `${extension.assets.download.uri}&${operationParam}=true`,
|
uri: `${extension.assets.download.uri}&${operationParam}=true`,
|
||||||
fallbackUri: `${extension.assets.download.fallbackUri}?${operationParam}=true`
|
fallbackUri: `${extension.assets.download.fallbackUri}?${operationParam}=true`
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(new Vie
|
|||||||
VIEWLET_ID,
|
VIEWLET_ID,
|
||||||
nls.localize('debug', "Debug"),
|
nls.localize('debug', "Debug"),
|
||||||
'debug',
|
'debug',
|
||||||
3
|
// {{SQL CARBON EDIT}}
|
||||||
|
13
|
||||||
));
|
));
|
||||||
|
|
||||||
const openViewletKb: IKeybindings = {
|
const openViewletKb: IKeybindings = {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user