Compare commits

...

91 Commits

Author SHA1 Message Date
Anthony Dresser
03ea265bab Hide tabs on reexecute (#2624)
* add logic to hide tabs when a query rerun is executed

* remove double entry in the map
2018-09-18 17:56:37 -07:00
Abbie Petchtes
917f9eead3 Feat/add dom component (#2622)
* add dom component for model view

* formatting

* make css style hardcoded in dom.component

* comment out the unused CSS

* address comments

* address comment
2018-09-18 17:23:26 -07:00
Karl Burtram
08f2e72af8 Bump SQL Tools Service to 1.5.0-alpha.34 (#2621) 2018-09-18 14:57:59 -07:00
Aditya Bist
a2fb0ec029 fixed actual show plan command (#2620) 2018-09-18 13:42:14 -07:00
ranasaria
084042ad13 Bug/oetimeout Fix - When timeout happens while fetching node children, the node becomes unusable (#2616)
This commit fixes issue when multiple OE nodes are expanded simultaneously. While the error was getting displayed the node was left in incorrect state which was leading to the node being unusable in future. This commit repairs this defect.
2018-09-18 13:41:14 -07:00
AlexFsmn
8da3defe24 Added text underline CSS for DB NULL values when editing / showing data (#2597)
* Added text underline CSS for DB NULL values when editing / showing data
#217

* Changed db nulls styling to italic
2018-09-18 12:30:32 -07:00
Karl Burtram
58f9cd32a5 Update SQL Ops to 0.33.7 2018-09-18 12:12:23 -07:00
Anthony Dresser
f7abf5a2d5 Fix stating for scrolls (#2615)
* nearly working

* add accounting for the downsides to slickgrid
2018-09-17 17:55:52 -07:00
Anthony Dresser
c8c6d072f6 Respect message settings (#2614)
* add results view stating

* working through the bugs

* handle various resizing bugs

* gnale resizing better

* add configuration to state

* address comments
2018-09-17 17:55:38 -07:00
Anthony Dresser
4d9cc604b9 add view area options to pick up chart background fix (#2613) 2018-09-17 16:37:18 -07:00
Aditya Bist
1dc76fa171 Dashboard: Fixed all insight bugs (#2612)
* fixed all insight bugs

* removed unused imports

* added comment
2018-09-17 14:47:46 -07:00
Aditya Bist
1d37b9ae9c fixes scrolling in query plan (#2609) 2018-09-17 13:02:38 -07:00
Matt Irvine
26828602a8 Use version 2.0.9 of electron (#2606) 2018-09-17 12:08:50 -07:00
Matt Irvine
e253f3ac89 Fix/bump dependency versions (#2608) 2018-09-17 11:21:41 -07:00
AlexFsmn
4d59fdea1b The "New Query" context menu is now only available from the server & db (#2598)
#1890
2018-09-15 13:44:58 -07:00
AlexFsmn
98a313eb5b Changed the "Configure" link to "Learn How To Configure The Dashboard". (#2599)
* Changed the "Configure" link to "Learn How To Configure the Dashboard".
This inlcudes the command as well as the tile label
#1227

* Capitalizing first character in each word
2018-09-15 11:45:21 -07:00
Aditya Bist
77e1cd8b32 fixed insights crash (#2596) 2018-09-14 21:20:37 -07:00
Alan Ren
dede5c5ef5 edit data issue with column index handling (#2595) 2018-09-14 21:19:56 -07:00
Matt Irvine
d156c0be3d Fix crash when reverting in edit data with no changes (#2594) 2018-09-14 21:18:54 -07:00
Karl Burtram
dc0bc6e606 Update SQL Ops to 0.33.6 2018-09-13 23:48:40 -07:00
Matt Irvine
05040425df Add OE node refresh API method (#2578)
* Initial working commit for refreshing OE node via API

* Add test and fix up code

* Run tsfmt

* Fix test
2018-09-13 18:43:47 -07:00
Alan Ren
36f7c283b8 use latest slickgrid library (#2584) 2018-09-13 18:43:06 -07:00
Anthony Dresser
9fe4237033 Maintain Query State (#2571)
* add results view stating

* working through the bugs

* handle various resizing bugs

* gnale resizing better

* fix tests by adding missing node module

* formatting

* refactor interfaces out to get around testing restrictions

* more refactoring of importants to avoid loading errors
2018-09-13 18:42:29 -07:00
Alan Ren
b03c0a3e2d accessibility setting based select database dropdown (#2579) 2018-09-13 15:07:08 -07:00
Aditya Bist
87946996ed added context to chart buttons so they work (#2575) 2018-09-13 14:22:57 -07:00
AlexFsmn
cc55023440 Disabled connection name input when connecting to a server. (#2566)
* Disabled connection name input when connecting to a server.
#2557

* Fixed reset state of connection inputs
2018-09-13 12:36:28 -07:00
Karl Burtram
1f19dfc50d Update SQL Ops to 0.33.5 2018-09-13 08:06:27 -07:00
Alan Ren
950a440350 fix the connection issue when opening new query after connection (#2561) 2018-09-13 08:05:46 -07:00
Aditya Bist
c92b88bfaf Bug/extension contribution (#2560)
* revert 4ab5d84b94

* fixed extensions
2018-09-12 23:04:59 -07:00
Abbie Petchtes
10875f26dc add divcontainer in modelview (#2559)
* add divcontainer in modelview

* address comment
2018-09-12 20:18:40 -07:00
Kevin Cunnane
d62e809c18 Support isDirty flag for model view editors and begin plumb through of save support (#2547)
* Add dirty and save support to model view

* Add issue # for a TODO
2018-09-12 14:35:19 -07:00
Alan Ren
d85bf4f6dd fix the account not found error when creating firewall rules (#2543) 2018-09-12 13:32:40 -07:00
Anthony Dresser
801e201cc3 change active cell during change to fix focus shift (#2545) 2018-09-12 13:22:01 -07:00
Anthony Dresser
e18e0da0c1 Fix sizing error when switching windows (#2544)
* add work around for when we need to resize while we don't have a dimension to resize off of

* formatting
2018-09-12 13:21:51 -07:00
Karl Burtram
d046b0a412 Update SQL Ops to 0.33.4 2018-09-12 13:09:41 -07:00
Karl Burtram
72084b8fc1 Fix build break in Git extension (#2538) 2018-09-11 21:48:44 -07:00
Anthony Dresser
2639b2bd2c Fix bug around debounced event not being flushed in time (#2536)
* fix bug around debounced event not being flushed in time

* add comment
2018-09-11 21:22:25 -07:00
Anthony Dresser
82aa493dfd Reduce message panel min size to 0 (#2534)
* reduce message panel minimum size to 0; attempt to restore panel sizing on requery sizes; default grid panel size to 80%

* formatting
2018-09-11 21:22:06 -07:00
Karl Burtram
6c3c7c40b5 Turn-off Git missing prompt (#2533) 2018-09-11 21:21:44 -07:00
Anthony Dresser
5616751c04 fix grid action bar not updating (#2532) 2018-09-11 21:21:30 -07:00
Anthony Dresser
7d898ca34d Fix grid gaps (#2531)
* modifying grid gaps

* reduce gaps and increase gap for action bar
2018-09-11 21:21:06 -07:00
Kevin Cunnane
e26556b21a Fixes #2523 (#2528)
The IdGenerator was recreated each time and had a high likelihood of conflicts. Invitably after adding dozens or hundreds of icons you'll start seeing the CSS class replaced and overridden.

The solution is to do like elsewhere: have 1 const that is loaded on first import of the file and keeps a global track.

Side note is that it'd be a good idea to cache CSS rules with the same iconPath so we don't create lots of additional rules unnecessarily. If we reuse the same icon a bunch we should cache them - #2524 is tracking this.
2018-09-11 21:20:38 -07:00
Anthony Dresser
89e6d363e2 Selection in grid context (#2527)
* update action context on selection change

* correctly add ranges rather than a new range for every row

* add required functions to typings
2018-09-11 17:10:53 -07:00
Anthony Dresser
c559ac7be9 expand messages panel on error (#2519) 2018-09-11 17:09:40 -07:00
Anthony Dresser
b3fbe47f0a add min size for row num column (#2518) 2018-09-11 17:09:17 -07:00
Anthony Dresser
c73af4c480 add check for selection model in edit data (#2517) 2018-09-11 17:08:41 -07:00
Alan Ren
8887fe1eac fix the save and save all for untitled file (#2526) 2018-09-11 17:06:28 -07:00
Kevin Cunnane
ed861a6c96 Revert "Fixes #2523" (#2525)
This reverts commit e63bb6a8ec.
2018-09-11 16:42:27 -07:00
Kevin Cunnane
e63bb6a8ec Fixes #2523
The IdGenerator was recreated each time and had a high likelihood of conflicts. Invitably after adding dozens or hundreds of icons you'll start seeing the CSS class replaced and overridden.

The solution is to do like elsewhere: have 1 const that is loaded on first import of the file and keeps a global track.

Side note is that it'd be a good idea to cache CSS rules with the same iconPath so we don't create lots of additional rules unnecessarily. If we reuse the same icon a bunch we should cache them - #2524 is tracking this.
2018-09-11 16:36:17 -07:00
Anthony Dresser
8ec09d25ce add listener to change action bar on maximize change (#2505) 2018-09-11 12:42:06 -07:00
Anthony Dresser
a9a01ae479 fixes a rendering problem in splitview (#2512) 2018-09-11 12:18:03 -07:00
Karl Burtram
31a3864789 Disable the User Setup prompt (#2501) 2018-09-11 11:52:04 -07:00
Abbie Petchtes
a5c537197c add animation when button is clicked and fix title in button (#2488)
* add animation similar to toolbar in vscode and fix title in button

* remove bur method in button
2018-09-11 10:37:02 -07:00
Anthony Dresser
4ea13bdbc0 add select all handler to grid (#2496) 2018-09-10 21:18:39 -07:00
Anthony Dresser
b06ddf2dc7 change cursor in message panel to default (#2494) 2018-09-10 21:18:18 -07:00
Karl Burtram
2c45ac9df3 Reorder Connection Name field in Connection Dialog (#2498) 2018-09-10 21:17:57 -07:00
Anthony Dresser
7735f68502 Add check for potential failure in handling drag (#2499)
* add check for potential failure in handling drag

* move check to avoid ui glitches
2018-09-10 21:17:42 -07:00
Anthony Dresser
ffb0f5a1c7 add grid styles (#2483) 2018-09-10 21:17:26 -07:00
Anthony Dresser
80c7f9e855 add logic to hide and add grid panel based on size (#2481) 2018-09-10 21:16:54 -07:00
Alan Ren
709ef4e39f Alanren/icon overwrite issue (#2484)
* fix the error icon too large issue

* formatting
2018-09-10 15:55:40 -07:00
Anthony Dresser
4ceb869420 remove autosize and change column header css to properly respect column sizes (#2480) 2018-09-10 14:59:32 -07:00
Anthony Dresser
432a209184 fix error message formatting (#2477) 2018-09-10 14:58:51 -07:00
Karl Burtram
8444271c58 Fix Action Bar viewlet ordering (#2472) 2018-09-09 19:58:27 -07:00
Karl Burtram
2bc97c23d4 Bump Electron to 2.0.8 and SQL Ops to 0.33.3 (#2466) 2018-09-07 22:08:36 -07:00
Aditya Bist
9ea02bf125 Security: Added user setting for extension policies (#2426)
* added user setting for extension policy

* fix extension action tests
2018-09-07 16:58:37 -07:00
Cory Rivera
2b4de52af4 Remove redundant getChildren method in IModelViewTreeViewDataProvider. (#2463) 2018-09-07 16:37:44 -07:00
Matt Irvine
d3492ebf2f Change some variable names that used reserved keywords (#2457) 2018-09-07 16:25:55 -07:00
Aditya Bist
ff8698f619 Security: Added warning for all vsix extensions (#2406)
* added warning for all vsix extensions

* added sql carbon tag

* added dont show warning for extensions
2018-09-07 16:25:19 -07:00
Anthony Dresser
16bc218ea7 fix formatting on time stamps (#2456) 2018-09-07 16:24:06 -07:00
Anthony Dresser
72d2920dc3 add table options to fix column widths (#2458) 2018-09-07 16:22:40 -07:00
Alan Ren
fb8de0d753 fix select box's screen reader issues (#2462) 2018-09-07 16:17:56 -07:00
Kevin Cunnane
352afc9827 Pixel perfect support for buttons showing correctly in vertical mode (#2460) 2018-09-07 13:40:50 -07:00
Abbie Petchtes
ce699a1c84 change the default lang in editor component to plaintext and fix sample (#2459)
* change the default lang in editor component to plaintext and fix sample

* minor fix
2018-09-07 13:29:34 -07:00
Matt Irvine
cde20d338e Fix extension installation that broke in merge (#2448) 2018-09-07 13:17:32 -07:00
Anthony Dresser
8ab22e9cc8 change layout for gridpanel to correctly handle header size (#2452) 2018-09-07 11:08:27 -07:00
Anthony Dresser
0f2442a7a5 Add fix for flashing during dragging and resize drag box (#2451)
* add fix for flashing during dragging and resize drag box

* remove unnecessary code
2018-09-07 11:08:14 -07:00
Vincent Feng
ba91140ea5 Enable the support for post-connection behaviors for openConnectionDialog (#2455)
* Enable the support for post-connection behaviors for openConnectionDialog.

* Fixed bugs.

* Make everything in IConnectionCompletionOptions optional except saveConnection.

* showConnectionDialogOnError & showFirewallRuleOnError default to true.

* Use types.isUndefinedOrNull to do value checking.

* Minor changes.
2018-09-08 01:08:18 +08:00
Abbie Petchtes
10f05e75ce Add css styles options to all components (#2454)
* add css styling in all components

* formatting

* formatting

* small typo

* small typo

* use builder to add style instead
2018-09-07 09:08:29 -07:00
Kevin Cunnane
287811f4ab Fix bug where webview options weren't revived, causing URI lookup to fail (#2453) 2018-09-06 18:00:23 -07:00
Karl Burtram
a68462c7cb Fix Extension Manager marketplace sorting (#2450) 2018-09-06 17:46:26 -07:00
Vincent Feng
005c28dd3a Accounts: Enable notification for accounts change (#2432)
* Enable notification for accounts change

* Fixed bugs in extHostAccountManagement.test.ts

* Fixed as commented:
1. Removed AccountWithProviderHandle
2. Use a private dictionary _accounts in ExtHostAccountManagement to cache all accounts and corresponding provider handles.
3. getSecurityToken gets provider handle from _accounts for specified account.
4. Added / changed unit tests for getAllAccounts & getSecurityToken
2018-09-07 08:23:28 +08:00
Anthony Dresser
197e1c651f add listeners to make grid the largest (#2447) 2018-09-06 17:00:54 -07:00
Anthony Dresser
c01da0f263 fix off by one in query messages (#2446) 2018-09-06 17:00:41 -07:00
Anthony Dresser
81ff542d0b add copy keybind (#2445) 2018-09-06 17:00:30 -07:00
Karl Burtram
efee27559b Update SQL Ops to 0.33.2 2018-09-06 16:25:59 -07:00
Karl Burtram
dc5408f874 Fix break opening SQL files (#2449) 2018-09-06 15:46:50 -07:00
Chris LaFreniere
7cf9217158 fix for findSubstr not doing URI.file(<filename>).fspath (#2441) 2018-09-06 15:04:16 -07:00
Anthony Dresser
401fc8161a fix dragging (#2438) 2018-09-06 14:43:52 -07:00
Matt Irvine
be2f9a6099 Add "preview features" config switch (#2334)
* Initial working commit for preview features config

* Clean up code

* Update tests

* Remove unused imports

* Update message and options

* Update don't show again message
2018-09-06 14:16:47 -07:00
Karl Burtram
21989aa88e Simplify GitHub templates (#2440) 2018-09-06 14:10:03 -07:00
Karl Burtram
461d041a50 Fix SQLPLAN custom editor support (#2439) 2018-09-06 14:09:34 -07:00
161 changed files with 8677 additions and 6265 deletions

View File

@@ -3,17 +3,12 @@ name: Bug report
about: Create a report to help us improve
---
<!-- Please search existing issues to avoid creating duplicates. -->
<!-- Please search existing issues to avoid creating duplicates. -->
<!-- Also please test using the latest insiders build to make sure your issue has not already been fixed. -->
<!-- Use Help > Report Issue to prefill these. -->
- SQL Operations Studio Version:
- OS Version:
Steps to Reproduce:
1.
2.
<!-- Launch with `sqlops --disable-extensions` to check. -->
Does this issue occur when all extensions are disabled?: Yes/No

View File

@@ -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. -->

View File

@@ -1,4 +0,0 @@
---
name: Question
---

View File

@@ -1,3 +1,3 @@
disturl "https://atom.io/download/electron"
target "2.0.7"
target "2.0.9"
runtime "electron"

View File

@@ -13,7 +13,7 @@
"azure-storage": "^2.1.0",
"decompress": "^4.2.0",
"documentdb": "1.13.0",
"service-downloader": "github:anthonydresser/service-downloader#0.1.2",
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
"fs-extra-promise": "^1.0.1",
"mime": "^1.3.4",
"minimist": "^1.2.0",

View File

@@ -1002,7 +1002,7 @@ hoek@4.x.x:
version "4.2.1"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb"
http-proxy-agent@^2.0.0:
http-proxy-agent@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
dependencies:
@@ -1025,7 +1025,7 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
https-proxy-agent@^2.1.1:
https-proxy-agent@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
dependencies:
@@ -1843,14 +1843,14 @@ semver@^5.4.1:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
"service-downloader@github:anthonydresser/service-downloader#0.1.2":
version "0.1.2"
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/2aa9b336b6442e17e24693ddc907030575539798"
"service-downloader@github:anthonydresser/service-downloader#0.1.5":
version "0.1.5"
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/6ebb0465573cc140e461a22f334260f55ef45546"
dependencies:
decompress "^4.2.0"
eventemitter2 "^5.0.1"
http-proxy-agent "^2.0.0"
https-proxy-agent "^2.1.1"
http-proxy-agent "^2.1.0"
https-proxy-agent "^2.2.1"
mkdirp "^0.5.1"
tmp "^0.0.33"

View File

@@ -7,7 +7,7 @@
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { ExtensionContext, workspace, window, Disposable, commands, Uri, OutputChannel } from 'vscode';
import { ExtensionContext, workspace, window, Disposable, commands, OutputChannel } from 'vscode';
import { findGit, Git, IGit } from './git';
import { Model } from './model';
import { CommandCenter } from './commands';
@@ -98,28 +98,29 @@ export async function activate(context: ExtensionContext): Promise<API> {
throw err;
}
const config = workspace.getConfiguration('git');
const shouldIgnore = config.get<boolean>('ignoreMissingGitWarning') === true;
// {{SQL CARBON EDIT}} turn-off Git missing prompt
//const config = workspace.getConfiguration('git');
//const shouldIgnore = config.get<boolean>('ignoreMissingGitWarning') === true;
if (!shouldIgnore) {
console.warn(err.message);
outputChannel.appendLine(err.message);
outputChannel.show();
// if (!shouldIgnore) {
// console.warn(err.message);
// outputChannel.appendLine(err.message);
// outputChannel.show();
const download = localize('downloadgit', "Download Git");
const neverShowAgain = localize('neverShowAgain', "Don't Show Again");
const choice = await window.showWarningMessage(
localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."),
download,
neverShowAgain
);
// const download = localize('downloadgit', "Download Git");
// const neverShowAgain = localize('neverShowAgain', "Don't Show Again");
// const choice = await window.showWarningMessage(
// localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."),
// download,
// neverShowAgain
// );
if (choice === download) {
commands.executeCommand('vscode.open', Uri.parse('https://git-scm.com/'));
} else if (choice === neverShowAgain) {
await config.update('ignoreMissingGitWarning', true, true);
}
}
// if (choice === download) {
// commands.executeCommand('vscode.open', Uri.parse('https://git-scm.com/'));
// } else if (choice === neverShowAgain) {
// await config.update('ignoreMissingGitWarning', true, true);
// }
// }
return new NoopAPIImpl();
}

View File

@@ -82,7 +82,7 @@
"dependencies": {
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.7",
"opener": "^1.4.3",
"service-downloader": "github:anthonydresser/service-downloader#0.1.4",
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
"vscode-extension-telemetry": "^0.0.5",
"vscode-nls": "^3.2.1"
},

View File

@@ -177,14 +177,14 @@ graceful-fs@^4.1.10:
version "1.0.1"
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
http-proxy-agent@^2.0.0:
http-proxy-agent@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
dependencies:
agent-base "4"
debug "3.1.0"
https-proxy-agent@^2.1.1:
https-proxy-agent@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
dependencies:
@@ -297,14 +297,14 @@ seek-bzip@^1.0.5:
dependencies:
commander "~2.8.1"
"service-downloader@github:anthonydresser/service-downloader#0.1.4":
version "0.1.4"
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/3c0abdf8603aca85d2eacfac3c547173e41bf0c7"
"service-downloader@github:anthonydresser/service-downloader#0.1.5":
version "0.1.5"
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/6ebb0465573cc140e461a22f334260f55ef45546"
dependencies:
decompress "^4.2.0"
eventemitter2 "^5.0.1"
http-proxy-agent "^2.0.0"
https-proxy-agent "^2.1.1"
http-proxy-agent "^2.1.0"
https-proxy-agent "^2.2.1"
mkdirp "^0.5.1"
tmp "^0.0.33"

View File

@@ -20,7 +20,7 @@
"dependencies": {
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.8",
"opener": "^1.4.3",
"service-downloader": "github:anthonydresser/service-downloader#0.1.4",
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
"vscode-extension-telemetry": "^0.0.15"
},
"devDependencies": {

View File

@@ -1,6 +1,6 @@
{
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
"version": "1.5.0-alpha.28",
"version": "1.5.0-alpha.34",
"downloadFileNames": {
"Windows_86": "win-x86-netcoreapp2.1.zip",
"Windows_64": "win-x64-netcoreapp2.1.zip",

View File

@@ -191,14 +191,14 @@ graceful-fs@^4.1.10:
version "1.0.1"
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
http-proxy-agent@^2.0.0:
http-proxy-agent@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
dependencies:
agent-base "4"
debug "3.1.0"
https-proxy-agent@^2.1.1:
https-proxy-agent@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
dependencies:
@@ -315,14 +315,14 @@ semver@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
"service-downloader@github:anthonydresser/service-downloader#0.1.4":
version "0.1.4"
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/3c0abdf8603aca85d2eacfac3c547173e41bf0c7"
"service-downloader@github:anthonydresser/service-downloader#0.1.5":
version "0.1.5"
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/6ebb0465573cc140e461a22f334260f55ef45546"
dependencies:
decompress "^4.2.0"
eventemitter2 "^5.0.1"
http-proxy-agent "^2.0.0"
https-proxy-agent "^2.1.1"
http-proxy-agent "^2.1.0"
https-proxy-agent "^2.2.1"
mkdirp "^0.5.1"
tmp "^0.0.33"

View File

@@ -1,6 +1,6 @@
{
"name": "sqlops",
"version": "0.33.1",
"version": "0.33.7",
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
"author": {
"name": "Microsoft Corporation"
@@ -64,7 +64,7 @@
"reflect-metadata": "^0.1.8",
"rxjs": "5.4.0",
"semver": "^5.5.0",
"slickgrid": "github:anthonydresser/SlickGrid#2.3.25",
"slickgrid": "github:anthonydresser/SlickGrid#2.3.27",
"spdlog": "0.7.1",
"sudo-prompt": "8.2.0",
"svg.js": "^2.2.5",
@@ -167,5 +167,8 @@
"windows-foreground-love": "0.1.0",
"windows-mutex": "^0.2.0",
"windows-process-tree": "0.2.2"
},
"resolutions": {
"rc": "1.2.8"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
"version": "0.0.1",
"publisher": "demo",
"engines": {
"vscode": "^1.21.0",
"vscode": "^1.26.0",
"sqlops": "*"
},
"categories": [

View File

@@ -128,9 +128,11 @@ export default class MainController implements vscode.Disposable {
}
});
treeView.onDidChangeSelection(selectedNodes => {
selectedNodes.forEach(node => {
console.info('tree node selected: ' + node.label);
});
if (selectedNodes && selectedNodes.selection) {
selectedNodes.selection.forEach(node => {
console.info('tree node selected: ' + node.label);
});
}
});
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
@@ -516,7 +518,8 @@ export default class MainController implements vscode.Disposable {
let runButton = view.modelBuilder.button()
.withProperties({
label: 'Run',
iconPath: runIcon
iconPath: runIcon,
title: 'Run title'
}).component();
let monitorLightPath = vscode.Uri.file(path.join(__dirname, '..', 'media', 'monitor.svg'));
@@ -528,7 +531,8 @@ export default class MainController implements vscode.Disposable {
let monitorButton = view.modelBuilder.button()
.withProperties({
label: 'Monitor',
iconPath: monitorIcon
iconPath: monitorIcon,
title: 'Monitor title'
}).component();
let toolbarModel = view.modelBuilder.toolbarContainer()
.withToolbarItems([{

View File

@@ -2865,6 +2865,10 @@ qs@~6.5.1:
version "6.5.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
querystringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.0.0.tgz#fa3ed6e68eb15159457c89b37bc6472833195755"
querystringify@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb"
@@ -3131,7 +3135,7 @@ require-main-filename@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
requires-port@~1.0.0:
requires-port@^1.0.0, requires-port@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
@@ -3755,6 +3759,13 @@ url-parse@^1.1.9:
querystringify "~1.0.0"
requires-port "~1.0.0"
url-parse@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.3.tgz#bfaee455c889023219d757e045fa6a684ec36c15"
dependencies:
querystringify "^2.0.0"
requires-port "^1.0.0"
use@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544"
@@ -3933,9 +3944,9 @@ vscode-nls@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.2.tgz#3817eca5b985c2393de325197cf4e15eb2aa5350"
vscode@^1.1.14:
version "1.1.18"
resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.18.tgz#e9227265dc72fc826bd6cd7bd21193f4e48fa671"
vscode@^1.1.18:
version "1.1.21"
resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.21.tgz#1c8253d6238aefb4112d6e58cf975ad25313dafc"
dependencies:
glob "^7.1.2"
gulp-chmod "^2.0.0"
@@ -3949,7 +3960,7 @@ vscode@^1.1.14:
request "^2.83.0"
semver "^5.4.1"
source-map-support "^0.5.0"
url-parse "^1.1.9"
url-parse "^1.4.3"
vinyl-source-stream "^1.1.0"
vso-node-api@^6.1.2-preview:

View File

@@ -10,7 +10,7 @@ export const IBreadcrumbService = new InjectionToken<IBreadcrumbService>('breadc
export interface IBreadcrumbService {
breadcrumbItem: Subject<MenuItem[]>;
setBreadcrumbs(any): void;
setBreadcrumbs(page: any): void;
}
export interface MenuItem {

View File

@@ -23,6 +23,18 @@ export class Button extends vsButton {
this.$el.style('outline-color', this.buttonFocusOutline ? this.buttonFocusOutline.toString() : null);
this.$el.style('outline-width', '1px');
});
this.$el.on(DOM.EventType.MOUSE_DOWN, (e) => {
const mouseEvent = e as MouseEvent;
if (!this.$el.hasClass('disabled') && mouseEvent.button === 0) {
this.$el.addClass('active');
}
});
this.$el.on([DOM.EventType.MOUSE_UP], (e) => {
DOM.EventHelper.stop(e);
this.$el.removeClass('active');
});
}
public style(styles: IButtonStyles): void {

View File

@@ -217,7 +217,7 @@ export abstract class Modal extends Disposable implements IThemable {
if (this._modalOptions.isAngular === false && this._modalOptions.hasErrors) {
let builder = errorMessagesInFooter ? this._leftFooter : body;
builder.div({ class: 'dialogErrorMessage', id: 'dialogErrorMessage' }, (errorMessageContainer) => {
errorMessageContainer.div({ class: 'icon error' }, (iconContainer) => {
errorMessageContainer.div({ class: 'sql icon error' }, (iconContainer) => {
this._errorIconElement = iconContainer.getHTMLElement();
this._errorIconElement.style.visibility = 'hidden';
});
@@ -518,5 +518,6 @@ export abstract class Modal extends Disposable implements IThemable {
public dispose() {
super.dispose();
this._keydownListener.dispose();
this._footerButtons = [];
}
}

View File

@@ -61,6 +61,8 @@ export class TabbedPanel extends Disposable implements IThemable {
private _onTabChange = new Emitter<PanelTabIdentifier>();
public onTabChange: Event<PanelTabIdentifier> = this._onTabChange.event;
private tabHistory: string[] = [];
constructor(private container: HTMLElement, private options: IPanelOptions = defaultOptions) {
super();
this.$parent = this._register($('.tabbedPanel'));
@@ -152,6 +154,7 @@ export class TabbedPanel extends Disposable implements IThemable {
}
this._shownTab = id;
this.tabHistory.push(id);
this.$body.clearChildren();
let tab = this._tabMap.get(this._shownTab);
this.$body.attr('aria-labelledby', tab.identifier);
@@ -173,6 +176,26 @@ export class TabbedPanel extends Disposable implements IThemable {
}
this._tabMap.get(tab).header.destroy();
this._tabMap.delete(tab);
if (this._shownTab === tab) {
this._shownTab = undefined;
while (this._shownTab === undefined && this.tabHistory.length > 0) {
let lastTab = this.tabHistory.shift();
if (this._tabMap.get(lastTab)) {
this.showTab(lastTab);
}
}
// this shouldn't happen but just in case
if (this._shownTab === undefined && this._tabMap.size > 0) {
this.showTab(this._tabMap.keys().next().value);
}
}
if (!this.options.showHeaderWhenSingleView && this._tabMap.size === 1 && this._headerVisible) {
this.$header.offDOM();
this._headerVisible = false;
this.layout(this._currentDimensions);
}
}
public style(styles: IPanelStyles): void {
@@ -180,14 +203,16 @@ export class TabbedPanel extends Disposable implements IThemable {
}
public layout(dimension: Dimension): void {
this._currentDimensions = dimension;
this.$parent.style('height', dimension.height + 'px');
this.$parent.style('width', dimension.width + 'px');
this.$header.style('width', dimension.width + 'px');
this.$body.style('width', dimension.width + 'px');
const bodyHeight = dimension.height - (this._headerVisible ? this.headersize : 0);
this.$body.style('height', bodyHeight + 'px');
this._layoutCurrentTab(new Dimension(dimension.width, bodyHeight));
if (dimension) {
this._currentDimensions = dimension;
this.$parent.style('height', dimension.height + 'px');
this.$parent.style('width', dimension.width + 'px');
this.$header.style('width', dimension.width + 'px');
this.$body.style('width', dimension.width + 'px');
const bodyHeight = dimension.height - (this._headerVisible ? this.headersize : 0);
this.$body.style('height', bodyHeight + 'px');
this._layoutCurrentTab(new Dimension(dimension.width, bodyHeight));
}
}
private _layoutCurrentTab(dimension: Dimension): void {

View File

@@ -34,6 +34,8 @@ export interface IView extends HeightIView {
readonly onDidChange: Event<number | undefined>;
render(container: HTMLElement, orientation: Orientation): void;
layout(size: number, orientation: Orientation): void;
onAdd?(): void;
onRemove?(): void;
}
interface ISashEvent {
@@ -48,6 +50,8 @@ interface IViewItem extends HeightIViewItem {
container: HTMLElement;
disposable: IDisposable;
layout(): void;
onRemove: () => void;
onAdd: () => void;
}
interface ISashItem {
@@ -109,6 +113,9 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
private _onDidSashReset = new Emitter<void>();
readonly onDidSashReset = this._onDidSashReset.event;
private _onScroll = new Emitter<number>();
readonly onScroll = this._onScroll.event;
get length(): number {
return this.viewItems.length;
}
@@ -124,6 +131,7 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
debounceEvent(this.scrollable.onScroll, (l, e) => e, 25)(e => {
this.render(e.scrollTop, e.height);
this.relayout();
this._onScroll.fire(e.scrollTop);
});
let domNode = this.scrollable.getDomNode();
dom.addClass(this.el, 'monaco-scroll-split-view');
@@ -155,6 +163,9 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
});
const disposable = combinedDisposable([onChangeDisposable, containerDisposable]);
const onAdd = view.onAdd ? () => view.onAdd() : () => { };
const onRemove = view.onRemove ? () => view.onRemove() : () => { };
const layoutContainer = this.orientation === Orientation.VERTICAL
? size => item.container.style.height = `${item.size}px`
: size => item.container.style.width = `${item.size}px`;
@@ -165,7 +176,7 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
};
size = Math.round(size);
const item: IViewItem = { view, container, size, layout, disposable, height: size, top: 0, width: 0 };
const item: IViewItem = { onRemove, onAdd, view, container, size, layout, disposable, height: size, top: 0, width: 0 };
this.viewItems.splice(viewIndex, 0, item);
this.onInsertItems(new ArrayIterator([item]), viewIndex > 0 ? this.viewItems[viewIndex - 1].view.id : undefined);
@@ -220,6 +231,9 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
});
const disposable = combinedDisposable([onChangeDisposable, containerDisposable]);
const onAdd = view.onAdd ? () => view.onAdd() : () => { };
const onRemove = view.onRemove ? () => view.onRemove() : () => { };
const layoutContainer = this.orientation === Orientation.VERTICAL
? size => item.container.style.height = `${item.size}px`
: size => item.container.style.width = `${item.size}px`;
@@ -230,7 +244,7 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
};
size = Math.round(size);
const item: IViewItem = { view, container, size, layout, disposable, height: size, top: 0, width: 0 };
const item: IViewItem = { onAdd, onRemove, view, container, size, layout, disposable, height: size, top: 0, width: 0 };
this.viewItems.splice(index, 0, item);
this.onInsertItems(new ArrayIterator([item]), index > 0 ? this.viewItems[index - 1].view.id : undefined);
@@ -330,9 +344,16 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
this.resize(this.viewItems.length - 1, this.size - contentSize, undefined, lowPriorityIndex);
}
public setScrollPosition(position: number) {
this.scrollable.setScrollPosition({ scrollTop: position });
}
layout(size: number): void {
const previousSize = Math.max(this.size, this.contentSize);
const previousSize = this.size;
this.size = size;
this.contentSize = 0;
this.lastRenderHeight = undefined;
this.lastRenderTop = undefined;
this.resize(this.viewItems.length - 1, size - previousSize);
}
@@ -484,6 +505,8 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
}
item.layout();
item.onAdd();
return true;
}
@@ -493,6 +516,8 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
}
this.el.removeChild(item.container);
item.onRemove();
return true;
}

View File

@@ -69,6 +69,9 @@ export class SelectBox extends vsSelectBox {
if (container) {
this.element = dom.append(container, $('.monaco-selectbox.idle'));
}
// explicitly set the accessible role so that the screen readers can read the control type properly
this.selectElement.setAttribute('role', 'combobox');
}
public style(styles: ISelectBoxStyles): void {

View File

@@ -7,6 +7,7 @@
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { range } from 'vs/base/common/arrays';
/**
* Implements the various additional navigation keybindings we want out of slickgrid
@@ -50,6 +51,14 @@ export class AdditionalKeyBindings<T> implements Slick.Plugin<T> {
}
} else if (event.equals(KeyCode.End | KeyMod.CtrlCmd)) {
this.grid.setActiveCell(this.grid.getDataLength() - 1, this.grid.getColumns().length - 1);
} else if (event.equals(KeyCode.KEY_A | KeyMod.CtrlCmd)) {
// check if we can set the rows directly on the selectionModel, its cleaner
let selectionModel = this.grid.getSelectionModel();
if (selectionModel) {
selectionModel.setSelectedRanges([new Slick.Range(0, 0, this.grid.getDataLength() - 1, this.grid.getColumns().length - 1)]);
} else {
this.grid.setSelectedRows(range(this.grid.getDataLength()));
}
} else {
handled = false;
}

View File

@@ -0,0 +1,145 @@
import { mixin } from 'vs/base/common/objects';
const defaultOptions: ICellRangeSelectorOptions = {
selectionCss: {
'border': '2px dashed blue'
},
offset: {
top: -1,
left: -1,
height: 2,
width: 2
},
dragClass: 'drag'
};
export interface ICellRangeSelectorOptions {
selectionCss?: { [key: string]: string };
cellDecorator?: ICellRangeDecorator;
offset?: { top: number, left: number, height: number, width: number };
dragClass?: string;
}
export interface ICellRangeSelector<T> extends Slick.Plugin<T> {
onCellRangeSelected: Slick.Event<{ range: Slick.Range }>;
onBeforeCellRangeSelected: Slick.Event<Slick.Cell>;
}
export interface ICellRangeDecorator {
show(range: Slick.Range);
hide();
}
export class CellRangeSelector<T> implements ICellRangeSelector<T> {
private grid: Slick.Grid<T>;
private dragging: boolean;
private handler = new Slick.EventHandler();
private decorator: ICellRangeDecorator;
private canvas: HTMLCanvasElement;
private currentlySelectedRange: { start: Slick.Cell, end: Slick.Cell };
public onBeforeCellRangeSelected = new Slick.Event<Slick.Cell>();
public onCellRangeSelected = new Slick.Event<{ range: Slick.Range }>();
constructor(private options: ICellRangeSelectorOptions) {
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangedecorator');
this.options = mixin(this.options, defaultOptions, false);
}
public init(grid: Slick.Grid<T>) {
this.decorator = this.options.cellDecorator || new (<any>Slick).CellRangeDecorator(grid, this.options);
this.grid = grid;
this.canvas = this.grid.getCanvasNode();
this.handler
.subscribe(this.grid.onDragInit, e => this.handleDragInit(e))
.subscribe(this.grid.onDragStart, (e, dd) => this.handleDragStart(e, dd))
.subscribe(this.grid.onDrag, (e, dd) => this.handleDrag(e, dd))
.subscribe(this.grid.onDragEnd, (e, dd) => this.handleDragEnd(e, dd));
}
public destroy() {
this.handler.unsubscribeAll();
}
public getCellDecorator() {
return this.decorator;
}
public getCurrentRange() {
return this.currentlySelectedRange;
}
private handleDragInit(e: DOMEvent) {
// prevent the grid from cancelling drag'n'drop by default
e.stopImmediatePropagation();
}
private handleDragStart(e: MouseEvent, dd: Slick.OnDragStartEventArgs<T>) {
let cell = this.grid.getCellFromEvent(e);
if (this.onBeforeCellRangeSelected.notify(cell) !== false) {
if (this.grid.canCellBeSelected(cell.row, cell.cell)) {
this.dragging = true;
e.stopImmediatePropagation();
}
}
if (!this.dragging) {
return;
}
this.canvas.classList.add(this.options.dragClass);
this.grid.setActiveCell(cell.row, cell.cell);
let start = this.grid.getCellFromPoint(
dd.startX - $(this.canvas).offset().left,
dd.startY - $(this.canvas).offset().top);
dd.range = { start: start, end: undefined };
this.currentlySelectedRange = dd.range;
return this.decorator.show(new Slick.Range(start.row, start.cell));
}
private handleDrag(e: MouseEvent, dd: Slick.OnDragEventArgs<T>) {
if (!this.dragging) {
return;
}
e.stopImmediatePropagation();
let end = this.grid.getCellFromPoint(
e.pageX - $(this.canvas).offset().left,
e.pageY - $(this.canvas).offset().top);
if (!this.grid.canCellBeSelected(end.row, end.cell)) {
return;
}
dd.range.end = end;
this.currentlySelectedRange = dd.range;
this.decorator.show(new Slick.Range(dd.range.start.row, dd.range.start.cell, end.row, end.cell));
}
private handleDragEnd(e: MouseEvent, dd: Slick.OnDragEndEventArgs<T>) {
if (!this.dragging) {
return;
}
this.canvas.classList.remove(this.options.dragClass);
this.dragging = false;
e.stopImmediatePropagation();
this.decorator.hide();
// if this happens to fast there is a chance we don't have the necessary information to actually do proper selection
if (!dd || !dd.range || !dd.range.start || !dd.range.end) {
return;
}
this.onCellRangeSelected.notify({
range: new Slick.Range(
dd.range.start.row,
dd.range.start.cell,
dd.range.end.row,
dd.range.end.cell
)
});
}
}

View File

@@ -3,15 +3,8 @@
import { mixin } from 'vs/base/common/objects';
import { isUndefinedOrNull } from 'vs/base/common/types';
import { IThemeService } from 'vs/platform/theme/common/themeService';
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangedecorator');
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangeselector');
export interface ICellRangeSelector<T> extends Slick.Plugin<T> {
onCellRangeSelected: Slick.Event<{ range: Slick.Range }>;
onBeforeCellRangeSelected: Slick.Event<Slick.Cell>;
}
import { CellRangeSelector, ICellRangeSelector } from 'sql/base/browser/ui/table/plugins/cellRangeSelector';
export interface ICellSelectionModelOptions {
cellRangeSelector?: any;
@@ -36,7 +29,7 @@ export class CellSelectionModel<T> implements Slick.SelectionModel<T, Array<Slic
this.selector = this.options.cellRangeSelector;
} else {
// this is added by the noderequires above
this.selector = new (<any>Slick).CellRangeSelector({ selectionCss: { 'border': '2px dashed grey' } });
this.selector = new CellRangeSelector({ selectionCss: { 'border': '2px dashed grey' } });
}
}

View 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();
}
}
}

View File

@@ -36,23 +36,31 @@ export class RowNumberColumn<T> implements Slick.Plugin<T> {
private handleClick(e: MouseEvent, args: Slick.OnClickEventArgs<T>): void {
if (this.grid.getColumns()[args.cell].id === 'rowNumber') {
this.grid.setActiveCell(args.row, 1);
this.grid.setSelectedRows([args.row]);
if (this.grid.getSelectionModel()) {
this.grid.setSelectedRows([args.row]);
}
}
}
private handleHeaderClick(e: MouseEvent, args: Slick.OnHeaderClickEventArgs<T>): void {
if (args.column.id === 'rowNumber') {
this.grid.setActiveCell(0, 1);
this.grid.setSelectedRows(range(this.grid.getDataLength()));
if (this.grid.getSelectionModel()) {
this.grid.setSelectedRows(range(this.grid.getDataLength()));
}
}
}
public getColumnDefinition(): Slick.Column<T> {
// that smallest we can make it is 22 due to padding and margins in the cells
let columnWidth = Math.max(this.options.numberOfRows.toString().length * sizePerDigit, 22);
return {
id: 'rowNumber',
name: '',
field: 'rowNumber',
width: this.options.numberOfRows.toString().length * sizePerDigit,
width: columnWidth,
minWidth: columnWidth,
maxWidth: columnWidth,
resizable: false,
cssClass: this.options.cssClass,
focusable: false,

View File

@@ -166,6 +166,10 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
this._grid.setData(this._data, true);
}
getData(): Slick.DataProvider<T> {
return this._data;
}
get columns(): Slick.Column<T>[] {
return this._grid.getColumns();
}
@@ -244,7 +248,6 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
}
}
this.resizeCanvas();
this.autosizeColumns();
}
autosizeColumns() {
@@ -308,10 +311,15 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
if (styles.listHoverBackground) {
content.push(`.monaco-table.${this.idPrefix} .slick-row:hover { background-color: ${styles.listHoverBackground}; }`);
// handle no coloring during drag
content.push(`.monaco-table.${this.idPrefix} .drag .slick-row:hover { background-color: inherit; }`);
}
if (styles.listHoverForeground) {
content.push(`.monaco-table.${this.idPrefix} .slick-row:hover { color: ${styles.listHoverForeground}; }`);
// handle no coloring during drag
content.push(`.monaco-table.${this.idPrefix} .drag .slick-row:hover { color: inherit; }`);
}
if (styles.listSelectionOutline) {

View File

@@ -5,6 +5,7 @@
'use strict';
import { Emitter, Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
/**
* Implementation of vs/base/common/event/echo that is clearable
@@ -37,3 +38,52 @@ export function echo<T>(event: Event<T>, nextTick = false, buffer: T[] = []): {
clear
};
}
/**
* Implementation of vs/base/common/event/debounceEvent that is clearable
*/
export function debounceEvent<T>(event: Event<T>, merger: (last: T, event: T) => T, delay?: number, leading?: boolean): { clear: () => void; event: Event<T> };
export function debounceEvent<I, O>(event: Event<I>, merger: (last: O, event: I) => O, delay?: number, leading?: boolean): { clear: () => void; event: Event<O> };
export function debounceEvent<I, O>(event: Event<I>, merger: (last: O, event: I) => O, delay: number = 100, leading = false): { clear: () => void; event: Event<O> } {
let subscription: IDisposable;
let output: O = undefined;
let handle: any = undefined;
let numDebouncedCalls = 0;
const clear = () => output = undefined;
const emitter = new Emitter<O>({
onFirstListenerAdd() {
subscription = event(cur => {
numDebouncedCalls++;
output = merger(output, cur);
if (leading && !handle) {
emitter.fire(output);
}
clearTimeout(handle);
handle = setTimeout(() => {
let _output = output;
output = undefined;
handle = undefined;
if (!leading || numDebouncedCalls > 1) {
emitter.fire(_output);
}
numDebouncedCalls = 0;
}, delay);
});
},
onLastListenerRemove() {
subscription.dispose();
}
});
return {
event: emitter.event,
clear
};
}

View File

@@ -63,21 +63,21 @@
background: url("globalerror.svg") center center no-repeat;
}
.vs .icon.error,
.vs-dark .icon.error,
.hc-black .icon.error {
.vs .sql.icon.error,
.vs-dark .sql.icon.error,
.hc-black .sql.icon.error {
content: url("status_error.svg");
}
.vs .icon.warning,
.vs-dark .icon.warning,
.hc-black .icon.warning {
.vs .sql.icon.warning,
.vs-dark .sql.icon.warning,
.hc-black .sql.icon.warning {
content: url("status_warning.svg");
}
.vs .icon.info,
.vs-dark .icon.info,
.hc-black .icon.info {
.vs .sql.icon.info,
.vs-dark .sql.icon.info,
.hc-black .sql.icon.info {
content: url("status_info.svg");
}

View File

@@ -117,7 +117,7 @@ export class AccountPicker extends Disposable {
// Create refresh account action
this._refreshContainer = DOM.append(this._rootElement, DOM.$('div.refresh-container'));
DOM.append(this._refreshContainer, DOM.$('div.icon warning'));
DOM.append(this._refreshContainer, DOM.$('div.sql icon warning'));
let actionBar = new ActionBar(this._refreshContainer, { animated: false });
this._refreshAccountAction = this._instantiationService.createInstance(RefreshAccountAction);
actionBar.push(this._refreshAccountAction, { icon: false, label: true });

View File

@@ -123,6 +123,7 @@ export class ConnectionStore {
.then(savedCred => {
if (savedCred) {
credentialsItem.password = savedCred.password;
credentialsItem.options['password'] = savedCred.password;
}
resolve({ profile: credentialsItem, savedCred: !!savedCred });
},

View File

@@ -100,10 +100,10 @@ export class ConnectionDialogWidget extends Modal {
public refresh(): void {
let filteredProviderTypes = this.providerTypeOptions;
if (this._newConnectionParams && this._newConnectionParams.providers) {
if (this._newConnectionParams && this._newConnectionParams.providers) {
let validProviderNames = Object.keys(this.providerNameToDisplayNameMap).filter(x => this.includeProvider(x, this._newConnectionParams));
if (validProviderNames && validProviderNames.length > 0) {
filteredProviderTypes = filteredProviderTypes.filter(x => validProviderNames.find( v => this.providerNameToDisplayNameMap[v] === x) !== undefined);
filteredProviderTypes = filteredProviderTypes.filter(x => validProviderNames.find(v => this.providerNameToDisplayNameMap[v] === x) !== undefined);
}
}
this._providerTypeSelectBox.setOptions(filteredProviderTypes);
@@ -118,8 +118,8 @@ export class ConnectionDialogWidget extends Modal {
container.appendChild(connectionContainer.getHTMLElement());
this._bodyBuilder = new Builder(connectionContainer.getHTMLElement());
this._providerTypeSelectBox = new SelectBox(this.providerTypeOptions, this.selectedProviderType, this._contextViewService);
const connectTypeLabel = localize('connectType', 'Connection type');
this._providerTypeSelectBox = new SelectBox(this.providerTypeOptions, this.selectedProviderType, this._contextViewService, undefined, { ariaLabel: connectTypeLabel });
// Recent connection tab
let recentConnectionTab = $('.connection-recent-tab');
recentConnectionTab.div({ class: 'connection-recent', id: 'recentConnection' }, (builder) => {
@@ -182,7 +182,6 @@ export class ConnectionDialogWidget extends Modal {
});
this._bodyBuilder.div({ class: 'connection-type' }, (modelTableContent) => {
let connectTypeLabel = localize('connectType', 'Connection type');
modelTableContent.element('table', { class: 'connection-table-content' }, (tableContainer) => {
DialogHelper.appendInputSelectBox(
DialogHelper.appendRow(tableContainer, connectTypeLabel, 'connection-label', 'connection-input'), this._providerTypeSelectBox);
@@ -450,4 +449,4 @@ export class ConnectionDialogWidget extends Modal {
public get databaseDropdownExpanded(): boolean {
return this._databaseDropdownExpanded;
}
}
}

View File

@@ -65,6 +65,7 @@ export class ConnectionWidget {
private _databaseDropdownExpanded: boolean = false;
private _defaultDatabaseName: string = localize('defaultDatabaseOption', '<Default>');
private _loadingDatabaseName: string = localize('loadingDatabaseOption', 'Loading...');
private _serverGroupDisplayString: string = localize('serverGroup', 'Server group');
public DefaultServerGroup: IConnectionProfileGroup = {
id: '',
name: localize('defaultServerGroup', '<Default>'),
@@ -112,14 +113,14 @@ export class ConnectionWidget {
} else {
authTypeOption.defaultValue = this.getAuthTypeDisplayName(Constants.sqlLogin);
}
this._authTypeSelectBox = new SelectBox(authTypeOption.categoryValues.map(c => c.displayName), authTypeOption.defaultValue, this._contextViewService);
this._authTypeSelectBox = new SelectBox(authTypeOption.categoryValues.map(c => c.displayName), authTypeOption.defaultValue, this._contextViewService, undefined, { ariaLabel: authTypeOption.displayName });
}
this._providerName = providerName;
}
public createConnectionWidget(container: HTMLElement): void {
this._serverGroupOptions = [this.DefaultServerGroup];
this._serverGroupSelectBox = new SelectBox(this._serverGroupOptions.map(g => g.name), this.DefaultServerGroup.name, this._contextViewService);
this._serverGroupSelectBox = new SelectBox(this._serverGroupOptions.map(g => g.name), this.DefaultServerGroup.name, this._contextViewService, undefined, { ariaLabel: this._serverGroupDisplayString });
this._previousGroupOption = this._serverGroupSelectBox.value;
this._builder = $().div({ class: 'connection-table' }, (modelTableContent) => {
modelTableContent.element('table', { class: 'connection-table-content' }, (tableContainer) => {
@@ -155,11 +156,6 @@ export class ConnectionWidget {
}
private fillInConnectionForm(): void {
// Connection name
let connectionNameOption = this._optionsMaps[ConnectionOptionSpecialType.connectionName];
let connectionNameBuilder = DialogHelper.appendRow(this._tableContainer, connectionNameOption.displayName, 'connection-label', 'connection-input');
this._connectionNameInputBox = new InputBox(connectionNameBuilder.getHTMLElement(), this._contextViewService, { ariaLabel: connectionNameOption.displayName });
// Server name
let serverNameOption = this._optionsMaps[ConnectionOptionSpecialType.serverName];
let serverNameBuilder = DialogHelper.appendRow(this._tableContainer, serverNameOption.displayName, 'connection-label', 'connection-input');
@@ -193,7 +189,6 @@ export class ConnectionWidget {
},
ariaLabel: userNameOption.displayName
});
// Password
let passwordOption = this._optionsMaps[ConnectionOptionSpecialType.password];
let passwordBuilder = DialogHelper.appendRow(this._tableContainer, passwordOption.displayName, 'connection-label', 'connection-input');
@@ -219,10 +214,14 @@ export class ConnectionWidget {
});
// Server group
let serverGroupLabel = localize('serverGroup', 'Server group');
let serverGroupBuilder = DialogHelper.appendRow(this._tableContainer, serverGroupLabel, 'connection-label', 'connection-input');
let serverGroupBuilder = DialogHelper.appendRow(this._tableContainer, this._serverGroupDisplayString, 'connection-label', 'connection-input');
DialogHelper.appendInputSelectBox(serverGroupBuilder, this._serverGroupSelectBox);
// Connection name
let connectionNameOption = this._optionsMaps[ConnectionOptionSpecialType.connectionName];
let connectionNameBuilder = DialogHelper.appendRow(this._tableContainer, connectionNameOption.displayName, 'connection-label', 'connection-input');
this._connectionNameInputBox = new InputBox(connectionNameBuilder.getHTMLElement(), this._contextViewService, { ariaLabel: connectionNameOption.displayName });
let AdvancedLabel = localize('advanced', 'Advanced...');
this._advancedButton = this.createAdvancedButton(this._tableContainer, AdvancedLabel);
}
@@ -399,7 +398,7 @@ export class ConnectionWidget {
public focusOnOpen(): void {
this._handleClipboard();
this._connectionNameInputBox.focus();
this._serverNameInputBox.focus();
this.focusPasswordIfNeeded();
this.clearValidationMessages();
}
@@ -493,6 +492,7 @@ export class ConnectionWidget {
this._databaseNameInputBox.enabled = false;
this._userNameInputBox.disable();
this._passwordInputBox.disable();
this._connectionNameInputBox.disable();
this._rememberPasswordCheckBox.enabled = false;
if (this._authTypeSelectBox) {
this._authTypeSelectBox.disable();
@@ -504,6 +504,7 @@ export class ConnectionWidget {
this._serverGroupSelectBox.enable();
this._serverNameInputBox.enable();
this._connectionNameInputBox.enable();
this._databaseNameInputBox.enabled = true;
let currentAuthType: AuthenticationType = undefined;
if (this._authTypeSelectBox) {

View File

@@ -31,7 +31,7 @@ import * as nls from 'vs/nls';
import * as objects from 'vs/base/common/objects';
import { Event, Emitter } from 'vs/base/common/event';
import { Action } from 'vs/base/common/actions';
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import Severity from 'vs/base/common/severity';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { INotificationService } from 'vs/platform/notification/common/notification';
@@ -96,7 +96,8 @@ export abstract class DashboardPage extends AngularDisposable implements IConfig
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef,
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
@Inject(INotificationService) private notificationService: INotificationService,
@Inject(IAngularEventingService) private angularEventingService: IAngularEventingService
@Inject(IAngularEventingService) private angularEventingService: IAngularEventingService,
@Inject(IConfigurationService) private configurationService: IConfigurationService
) {
super();
}
@@ -138,6 +139,12 @@ export abstract class DashboardPage extends AngularDisposable implements IConfig
// Before separating tabs into pinned / shown, ensure that the home tab is always set up as expected
allTabs = this.setAndRemoveHomeTab(allTabs, homeWidgets);
// If preview features are disabled only show the home tab
let extensionTabsEnabled = this.configurationService.getValue('workbench')['enablePreviewFeatures'];
if (!extensionTabsEnabled) {
allTabs = [];
}
// Load tab setting configs
this._tabSettingConfigs = this.dashboardService.getSettings<Array<TabSettingConfig>>([this.context, 'tabs'].join('.'));
@@ -164,9 +171,13 @@ export abstract class DashboardPage extends AngularDisposable implements IConfig
// Set panel actions
let openedTabs = [...pinnedDashboardTabs, ...alwaysShowTabs];
let addNewTabAction = this.instantiationService.createInstance(AddFeatureTabAction, allTabs, openedTabs, this.dashboardService.getUnderlyingUri());
this._tabsDispose.push(addNewTabAction);
this.panelActions = [addNewTabAction];
if (extensionTabsEnabled) {
let addNewTabAction = this.instantiationService.createInstance(AddFeatureTabAction, allTabs, openedTabs, this.dashboardService.getUnderlyingUri());
this._tabsDispose.push(addNewTabAction);
this.panelActions = [addNewTabAction];
} else {
this.panelActions = [];
}
this._cd.detectChanges();
this._tabsDispose.push(this.dashboardService.onPinUnpinTab(e => {

View File

@@ -18,6 +18,7 @@ import * as nls from 'vs/nls';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
export class DatabaseDashboardPage extends DashboardPage implements OnInit {
protected propertiesWidget: WidgetConfig = {
@@ -43,9 +44,10 @@ export class DatabaseDashboardPage extends DashboardPage implements OnInit {
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
@Inject(IInstantiationService) instantiationService: IInstantiationService,
@Inject(INotificationService) notificationService: INotificationService,
@Inject(IAngularEventingService) angularEventingService: IAngularEventingService
@Inject(IAngularEventingService) angularEventingService: IAngularEventingService,
@Inject(IConfigurationService) configurationService: IConfigurationService
) {
super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService);
super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService, configurationService);
this._register(dashboardService.onUpdatePage(() => {
this.refresh(true);
this._cd.detectChanges();

View File

@@ -18,6 +18,7 @@ import * as nls from 'vs/nls';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
export class ServerDashboardPage extends DashboardPage implements OnInit {
protected propertiesWidget: WidgetConfig = {
@@ -44,9 +45,10 @@ export class ServerDashboardPage extends DashboardPage implements OnInit {
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
@Inject(IInstantiationService) instantiationService: IInstantiationService,
@Inject(INotificationService) notificationService: INotificationService,
@Inject(IAngularEventingService) angularEventingService: IAngularEventingService
@Inject(IAngularEventingService) angularEventingService: IAngularEventingService,
@Inject(IConfigurationService) configurationService: IConfigurationService
) {
super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService);
super(dashboardService, el, _cd, instantiationService, notificationService, angularEventingService, configurationService);
// revert back to default database
this._letDashboardPromise = this.dashboardService.connectionManagementService.changeDatabase('master');
}

View File

@@ -10,6 +10,7 @@ import * as TelemetryUtils from 'sql/common/telemetryUtilities';
import { IInsightsView, IInsightData } from 'sql/parts/dashboard/widgets/insights/interfaces';
import { memoize, unmemoize } from 'sql/base/common/decorators';
import { mixin } from 'sql/base/common/objects';
import { LegendPosition, DataDirection, ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
import * as colors from 'vs/platform/theme/common/colorRegistry';
import { Color } from 'vs/base/common/color';
@@ -21,29 +22,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
declare var Chart: any;
export enum ChartType {
Bar = 'bar',
Doughnut = 'doughnut',
HorizontalBar = 'horizontalBar',
Line = 'line',
Pie = 'pie',
TimeSeries = 'timeSeries',
Scatter = 'scatter'
}
export enum DataDirection {
Vertical = 'vertical',
Horizontal = 'horizontal'
}
export enum LegendPosition {
Top = 'top',
Bottom = 'bottom',
Left = 'left',
Right = 'right',
None = 'none'
}
export function customMixin(destination: any, source: any, overwrite?: boolean): any {
if (types.isObject(source)) {
mixin(destination, source, overwrite, customMixin);

View File

@@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export enum ChartType {
Bar = 'bar',
Doughnut = 'doughnut',
HorizontalBar = 'horizontalBar',
Line = 'line',
Pie = 'pie',
TimeSeries = 'timeSeries',
Scatter = 'scatter'
}
export enum DataDirection {
Vertical = 'vertical',
Horizontal = 'horizontal'
}
export enum LegendPosition {
Top = 'top',
Bottom = 'bottom',
Left = 'left',
Right = 'right',
None = 'none'
}
export enum DataType {
Number = 'number',
Point = 'point'
}

View File

@@ -3,8 +3,9 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ChartInsight, ChartType, customMixin, IChartConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import { ChartInsight, customMixin, IChartConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import { mixin } from 'sql/base/common/objects';
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
import { IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
import * as colors from 'vs/platform/theme/common/colorRegistry';

View File

@@ -3,8 +3,8 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import PieChart from './pieChart.component';
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
export default class DoughnutChart extends PieChart {
protected readonly chartType: ChartType = ChartType.Doughnut;

View File

@@ -3,8 +3,8 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import BarChart from './barChart.component';
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
export default class HorizontalBarChart extends BarChart {
protected readonly chartType: ChartType = ChartType.HorizontalBar;

View File

@@ -3,16 +3,13 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ChartType, customMixin, defaultChartConfig, IDataSet, IPointDataSet } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import { mixin } from 'vs/base/common/objects';
import { defaultChartConfig, IDataSet, IPointDataSet } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import BarChart, { IBarChartConfig } from './barChart.component';
import { memoize, unmemoize } from 'sql/base/common/decorators';
import { mixin } from 'vs/base/common/objects';
import { clone } from 'sql/base/common/objects';
export enum DataType {
Number = 'number',
Point = 'point'
}
import { ChartType, DataType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
export interface ILineConfig extends IBarChartConfig {
dataType?: DataType;

View File

@@ -3,7 +3,8 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ChartInsight, ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import { ChartInsight } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
export default class PieChart extends ChartInsight {
protected readonly chartType: ChartType = ChartType.Pie;

View File

@@ -3,11 +3,12 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ChartType, defaultChartConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import { defaultChartConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import LineChart, { ILineConfig } from './lineChart.component';
import { clone } from 'sql/base/common/objects';
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
import { mixin } from 'vs/base/common/objects';
import { clone } from 'sql/base/common/objects';
const defaultScatterConfig = mixin(clone(defaultChartConfig), { dataType: 'point', dataDirection: 'horizontal' }) as ILineConfig;

View File

@@ -3,9 +3,10 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { defaultChartConfig, IPointDataSet, ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import { defaultChartConfig, IPointDataSet } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import LineChart, { ILineConfig } from './lineChart.component';
import { clone } from 'sql/base/common/objects';
import { ChartType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
import { mixin } from 'vs/base/common/objects';
import { Color } from 'vs/base/common/color';

View File

@@ -86,7 +86,7 @@ export class TasksWidget extends DashboardWidget implements IDashboardWidget, On
}).filter(i => !!i);
}
this._tasks = tasks.map(i => TaskRegistry.getCommandActionById(i)).filter(v => !!v);
this._tasks = tasks.map(i => MenuRegistry.getCommand(i)).filter(v => !!v);
}
ngOnInit() {

View File

@@ -65,7 +65,7 @@
<div class="option check" #encryptCheckContainer>
</div>
<div class="option" #encryptWarningContainer>
<div class="icon warning">
<div class="sql icon warning">
</div>
<div class="warning-message">
{{localizedStrings.NO_ENCRYPTOR_WARNING}}

View File

@@ -221,7 +221,7 @@ export class BackupComponent {
ariaLabel: LocalizedStrings.RECOVERY_MODEL
});
// Set backup type
this.backupTypeSelectBox = new SelectBox([], '', this.contextViewService);
this.backupTypeSelectBox = new SelectBox([], '', this.contextViewService, undefined, { ariaLabel: this.localizedStrings.BACKUP_TYPE });
this.backupTypeSelectBox.render(this.backupTypeElement.nativeElement);
// Set copy-only check box
@@ -283,13 +283,13 @@ export class BackupComponent {
this.removePathButton.title = localize('removeFile', 'Remove files');
// Set compression
this.compressionSelectBox = new SelectBox(this.compressionOptions, this.compressionOptions[0], this.contextViewService);
this.compressionSelectBox = new SelectBox(this.compressionOptions, this.compressionOptions[0], this.contextViewService, undefined, { ariaLabel: this.localizedStrings.SET_BACKUP_COMPRESSION });
this.compressionSelectBox.render(this.compressionElement.nativeElement);
// Set encryption
this.algorithmSelectBox = new SelectBox(this.encryptionAlgorithms, this.encryptionAlgorithms[0], this.contextViewService);
this.algorithmSelectBox = new SelectBox(this.encryptionAlgorithms, this.encryptionAlgorithms[0], this.contextViewService, undefined, { ariaLabel: this.localizedStrings.ALGORITHM });
this.algorithmSelectBox.render(this.encryptionAlgorithmElement.nativeElement);
this.encryptorSelectBox = new SelectBox([], '', this.contextViewService);
this.encryptorSelectBox = new SelectBox([], '', this.contextViewService, undefined, { ariaLabel: this.localizedStrings.CERTIFICATE_OR_ASYMMETRIC_KEY });
this.encryptorSelectBox.render(this.encryptorElement.nativeElement);
// Set media
@@ -911,4 +911,4 @@ export class BackupComponent {
return backupInfo;
}
}
}

View File

@@ -273,7 +273,7 @@ export class RestoreDialog extends Modal {
labelContainer.hide();
this._restorePlanData = new TableDataView<Slick.SlickData>();
this._restorePlanTable = new Table<Slick.SlickData>(labelContainer.getHTMLElement(),
{ dataProvider: this._restorePlanData, columns: this._restorePlanColumn }, { enableColumnReorder: false });
{ dataProvider: this._restorePlanData, columns: this._restorePlanColumn }, { enableColumnReorder: false });
this._restorePlanTable.setSelectionModel(new RowSelectionModel({ selectActiveRow: false }));
this._restorePlanTable.onSelectedRowsChanged((e, data) => this.backupFileCheckboxChanged(e, data));
});
@@ -330,7 +330,7 @@ export class RestoreDialog extends Modal {
}];
this._fileListData = new TableDataView<FileListElement>();
this._fileListTable = new Table<FileListElement>(fileNameContainer.getHTMLElement(),
{ dataProvider : this._fileListData, columns } , { enableColumnReorder: false });
{ dataProvider: this._fileListData, columns }, { enableColumnReorder: false });
this._fileListTable.setSelectionModel(new RowSelectionModel());
});
});
@@ -541,7 +541,7 @@ export class RestoreDialog extends Modal {
});
inputContainer.div({ class: 'dialog-input' }, (inputCellContainer) => {
selectBox = new SelectBox(options, selectedOption, this._contextViewService, inputCellContainer.getHTMLElement());
selectBox = new SelectBox(options, selectedOption, this._contextViewService, inputCellContainer.getHTMLElement(), { ariaLabel: label });
selectBox.render(inputCellContainer.getHTMLElement());
});
});

View File

@@ -25,7 +25,7 @@ classes should alter those!
overflow: hidden;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
height: 16px;
height: 28px;
line-height: 16px;
margin: 0;
padding: 4px;
@@ -35,7 +35,7 @@ classes should alter those!
border-bottom: 2px solid #bbb;
float: left;
background-color: #eee;
box-sizing: content-box;
box-sizing: border-box;
}
.slick-headerrow-column.ui-state-default, .slick-footerrow-column.ui-state-default {
@@ -104,6 +104,11 @@ classes should alter those!
white-space: nowrap;
cursor: default;
}
.slick-cell .grid-cell-value-container.missing-value {
font-style: italic;
}
.slick-cell, .slick-headerrow-column{
border-bottom-color: silver;
}

View File

@@ -88,7 +88,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
@Inject(forwardRef(() => ChangeDetectorRef)) cd: ChangeDetectorRef,
@Inject(IBootstrapParams) params: IEditDataComponentParams,
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
@Inject(INotificationService) private notificationService: INotificationService,
@Inject(INotificationService) notificationService: INotificationService,
@Inject(IContextMenuService) contextMenuService: IContextMenuService,
@Inject(IKeybindingService) keybindingService: IKeybindingService,
@Inject(IContextKeyService) contextKeyService: IContextKeyService,
@@ -96,7 +96,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
@Inject(IClipboardService) clipboardService: IClipboardService,
@Inject(IQueryEditorService) queryEditorService: IQueryEditorService
) {
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService);
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService, notificationService);
this._el.nativeElement.className = 'slickgridContainer';
this.dataService = params.dataService;
this.actionProvider = this.instantiationService.createInstance(EditDataGridActionProvider, this.dataService, this.onGridSelectAll(), this.onDeleteRow(), this.onRevertRow());
@@ -166,7 +166,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
this.onCellEditEnd = (event: Slick.OnCellChangeEventArgs<any>): void => {
// Store the value that was set
self.currentEditCellValue = event.item[event.cell - 1];
self.currentEditCellValue = event.item[event.cell];
};
this.overrideCellFn = (rowNumber, columnId, value?, data?): string => {
@@ -270,18 +270,18 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
return self.dataService.updateCell(sessionRowId, self.currentCell.column - 1, self.currentEditCellValue)
.then(
result => {
// Cell update was successful, update the flags
self.currentEditCellValue = null;
self.setCellDirtyState(row, self.currentCell.column, result.cell.isDirty);
self.setRowDirtyState(row, result.isRowDirty);
return Promise.resolve();
},
error => {
// Cell update failed, jump back to the last cell we were on
self.focusCell(self.currentCell.row, self.currentCell.column, true);
return Promise.reject(null);
}
result => {
// Cell update was successful, update the flags
self.currentEditCellValue = null;
self.setCellDirtyState(row, self.currentCell.column, result.cell.isDirty);
self.setRowDirtyState(row, result.isRowDirty);
return Promise.resolve();
},
error => {
// Cell update failed, jump back to the last cell we were on
self.focusCell(self.currentCell.row, self.currentCell.column, true);
return Promise.reject(null);
}
);
});
}
@@ -377,10 +377,11 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
index => { return {}; }
),
columnDefinitions: [rowNumberColumn.getColumnDefinition()].concat(resultSet.columnInfo.map((c, i) => {
let columnIndex = (i + 1).toString();
return {
id: i.toString(),
id: columnIndex,
name: escape(c.columnName),
field: i.toString(),
field: columnIndex,
formatter: Services.textFormatter,
isEditable: c.isUpdatable
};
@@ -464,7 +465,7 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
} else {
try {
// Perform a revert row operation
if (this.currentCell) {
if (this.currentCell && this.currentCell.row !== undefined && this.currentCell.row !== null) {
await this.dataService.revertRow(this.currentCell.row);
}
} finally {

View File

@@ -37,6 +37,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { INotificationService } from 'vs/platform/notification/common/notification';
export abstract class GridParentComponent {
// CONSTANTS
@@ -100,7 +101,8 @@ export abstract class GridParentComponent {
protected contextKeyService: IContextKeyService,
protected configurationService: IConfigurationService,
protected clipboardService: IClipboardService,
protected queryEditorService: IQueryEditorService
protected queryEditorService: IQueryEditorService,
protected notificationService: INotificationService
) {
this.toDispose = [];
}

View File

@@ -16,7 +16,7 @@ import { IGridDataSet } from 'sql/parts/grid/common/interfaces';
import { IInsightData, IInsightsView, IInsightsConfig } from 'sql/parts/dashboard/widgets/insights/interfaces';
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
import { QueryEditor } from 'sql/parts/query/editor/queryEditor';
import { DataType, ILineConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/types/lineChart.component';
import { ILineConfig } from 'sql/parts/dashboard/widgets/insights/views/charts/types/lineChart.component';
import * as PathUtilities from 'sql/common/pathUtilities';
import { IChartViewActionContext, CopyAction, CreateInsightAction, SaveImageAction } from 'sql/parts/grid/views/query/chartViewerActions';
import * as WorkbenchUtils from 'sql/workbench/common/sqlWorkbenchUtils';
@@ -24,10 +24,11 @@ import * as Constants from 'sql/parts/query/common/constants';
import { SelectBox as AngularSelectBox } from 'sql/base/browser/ui/selectBox/selectBox.component';
import { IQueryModelService } from 'sql/parts/query/execution/queryModel';
import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService';
import { LegendPosition, DataDirection, DataType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
/* Insights */
import {
ChartInsight, DataDirection, LegendPosition
ChartInsight
} from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import { IDisposable } from 'vs/base/common/lifecycle';

View File

@@ -42,6 +42,8 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { localize } from 'vs/nls';
export const QUERY_SELECTOR: string = 'query-component';
@@ -126,7 +128,9 @@ export class QueryComponent extends GridParentComponent implements OnInit, OnDes
}
},
{
showCondition: () => { return true; },
showCondition: () => {
return this.configurationService.getValue('workbench')['enablePreviewFeatures'];
},
icon: () => { return 'viewChart'; },
hoverText: () => { return LocalizedConstants.viewChartLabel; },
functionality: (batchId, resultId, index) => {
@@ -187,9 +191,10 @@ export class QueryComponent extends GridParentComponent implements OnInit, OnDes
@Inject(IContextKeyService) contextKeyService: IContextKeyService,
@Inject(IConfigurationService) configurationService: IConfigurationService,
@Inject(IClipboardService) clipboardService: IClipboardService,
@Inject(IQueryEditorService) queryEditorService: IQueryEditorService
@Inject(IQueryEditorService) queryEditorService: IQueryEditorService,
@Inject(INotificationService) notificationService: INotificationService,
) {
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService);
super(el, cd, contextMenuService, keybindingService, contextKeyService, configurationService, clipboardService, queryEditorService, notificationService);
this._el.nativeElement.className = 'slickgridContainer';
this.rowHeight = configurationService.getValue<any>('resultsGrid').rowHeight;
configurationService.onDidChangeConfiguration(e => {

View File

@@ -188,8 +188,16 @@ export class InsightsDialogView extends Modal {
for (let i = 0; i < this._model.columns.length; i++) {
resourceArray.push({ label: this._model.columns[i], value: element.data[i], data: element.data });
}
this._bottomTableData.clear();
this._bottomTableData.push(resourceArray);
// this table view has to be collapsed and expanded
// because the initial expand doesn't have the
// loaded data
if (bottomTableView.isExpanded()) {
bottomTableView.collapse();
bottomTableView.expand();
}
this._enableTaskButtons(true);
} else {
this._enableTaskButtons(false);
@@ -334,6 +342,7 @@ export class InsightsDialogView extends Modal {
this.hide();
dispose(this._taskButtonDisposables);
this._taskButtonDisposables = [];
this.dispose();
}
protected onClose(e: StandardKeyboardEvent) {

View File

@@ -13,11 +13,11 @@ import * as sqlops from 'sqlops';
import { ComponentWithIconBase } from 'sql/parts/modelComponents/componentWithIconBase';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
import { attachButtonStyler } from 'sql/common/theme/styler';
import { Button } from 'sql/base/browser/ui/button/button';
import { SIDE_BAR_BACKGROUND, SIDE_BAR_TITLE_FOREGROUND } from 'vs/workbench/common/theme';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { focusBorder, foreground } from 'vs/platform/theme/common/colorRegistry';
import { Button } from 'sql/base/browser/ui/button/button';
import { Color } from 'vs/base/common/color';
@@ -42,9 +42,10 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
@ViewChild('fileInput', { read: ElementRef }) private _fileInputContainer: ElementRef;
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
@Inject(forwardRef(() => ElementRef)) el: ElementRef
) {
super(changeRef);
super(changeRef, el);
}
ngOnInit(): void {
@@ -63,7 +64,7 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
if (this._fileInputContainer) {
const self = this;
this._fileInputContainer.nativeElement.onchange = () => {
let file = self._fileInputContainer.nativeElement.files[0];
let file = self._fileInputContainer.nativeElement.files[0];
let reader = new FileReader();
reader.onload = (e) => {
let text = (<FileReader>e.target).result;
@@ -100,6 +101,7 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
super.setProperties(properties);
this._button.enabled = this.enabled;
this._button.label = this.label;
this._button.title = this.title;
if (this.width) {
this._button.setWidth(this.convertSize(this.width.toString()));
}
@@ -153,7 +155,7 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
this.setPropertyFromUI<sqlops.ButtonProperties, string>(this.setFileContentProperties, newValue);
}
private setFileContentProperties(properties: sqlops.ButtonProperties, fileContent: string) : void {
private setFileContentProperties(properties: sqlops.ButtonProperties, fileContent: string): void {
properties.fileContent = fileContent;
}
@@ -164,4 +166,13 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
private setFileProperties(properties: sqlops.ButtonProperties, isFile: boolean): void {
properties.isFile = isFile;
}
private get title(): string {
return this.getPropertyOrDefault<sqlops.ButtonProperties, string>((props) => props.title, '');
}
private set title(newValue: string) {
this.setPropertyFromUI<sqlops.ButtonProperties, string>((properties, title) => { properties.title = title; }, newValue);
}
}

View File

@@ -4,7 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./card';
import { Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver,
import {
Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver,
ViewChild, ViewChildren, ElementRef, Injector, OnDestroy, QueryList,
} from '@angular/core';
@@ -28,11 +29,11 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
private backgroundColor: string;
constructor(@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
constructor( @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService
) {
super(changeRef);
super(changeRef, el);
}
ngOnInit(): void {
@@ -70,7 +71,7 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
public getClass(): string {
return (this.selectable && this.selected || this._hasFocus) ? 'model-card selected' :
'model-card unselected';
'model-card unselected';
}
public onCardHoverChanged(event: any) {
@@ -81,7 +82,7 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
}
/// IComponent implementation
public setLayout (layout: any): void {
public setLayout(layout: any): void {
// TODO allow configuring the look and feel
this.layout();
}
@@ -141,7 +142,7 @@ export default class CardComponent extends ComponentWithIconBase implements ICom
public get statusColor(): string {
let status = this.getPropertyOrDefault<CardProperties, StatusIndicator>((props) => props.status, StatusIndicator.None);
switch(status) {
switch (status) {
case StatusIndicator.Ok:
return 'green';
case StatusIndicator.Warning:

View File

@@ -29,8 +29,9 @@ export default class CheckBoxComponent extends ComponentBase implements ICompone
@ViewChild('input', { read: ElementRef }) private _inputContainer: ElementRef;
constructor(
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
super(changeRef);
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
super(changeRef, el);
}
ngOnInit(): void {

View File

@@ -19,6 +19,7 @@ import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { ModelComponentWrapper } from 'sql/parts/modelComponents/modelComponentWrapper.component';
import URI from 'vs/base/common/uri';
import { Builder } from 'vs/base/browser/builder';
import { IdGenerator } from 'vs/base/common/idGenerator';
import { createCSSRule, removeCSSRulesContainingSelector } from 'vs/base/browser/dom';
import * as nls from 'vs/nls';
@@ -35,8 +36,11 @@ export abstract class ComponentBase extends Disposable implements IComponent, On
private _valid: boolean = true;
protected _validations: (() => boolean | Thenable<boolean>)[] = [];
private _eventQueue: IComponentEventArgs[] = [];
private _CSSStyles: { [key: string]: string } = {};
constructor(
protected _changeRef: ChangeDetectorRef) {
protected _changeRef: ChangeDetectorRef,
protected _el: ElementRef) {
super();
}
@@ -80,11 +84,20 @@ export abstract class ComponentBase extends Disposable implements IComponent, On
public refreshDataProvider(item: any): void {
}
public updateStyles() {
let element = new Builder(this._el.nativeElement);
this._CSSStyles = this.CSSStyles;
element.style(this._CSSStyles);
}
public setProperties(properties: { [key: string]: any; }): void {
if (!properties) {
this.properties = {};
}
this.properties = properties;
if (this.CSSStyles !== this._CSSStyles) {
this.updateStyles();
}
this.layout();
this.validate();
}
@@ -140,11 +153,19 @@ export abstract class ComponentBase extends Disposable implements IComponent, On
}
public get position(): string {
return this.getPropertyOrDefault<sqlops.EditorProperties, string>((props) => props.position, '');
return this.getPropertyOrDefault<sqlops.ComponentProperties, string>((props) => props.position, '');
}
public set position(newValue: string) {
this.setPropertyFromUI<sqlops.EditorProperties, string>((properties, position) => { properties.position = position; }, newValue);
this.setPropertyFromUI<sqlops.ComponentProperties, string>((properties, position) => { properties.position = position; }, newValue);
}
public get CSSStyles(): { [key: string]: string } {
return this.getPropertyOrDefault<sqlops.ComponentProperties, { [key: string]: string }>((props) => props.CSSStyles, {});
}
public set CSSStyles(newValue: { [key: string]: string }) {
this.setPropertyFromUI<sqlops.ComponentProperties, { [key: string]: string }>((properties, CSSStyles) => { properties.CSSStyles = CSSStyles; }, newValue);
}
public convertSizeToNumber(size: number | string): number {
@@ -223,9 +244,10 @@ export abstract class ContainerBase<T> extends ComponentBase {
@ViewChildren(ModelComponentWrapper) protected _componentWrappers: QueryList<ModelComponentWrapper>;
constructor(
_changeRef: ChangeDetectorRef
_changeRef: ChangeDetectorRef,
_el: ElementRef
) {
super(_changeRef);
super(_changeRef, _el);
this.items = [];
this._validations.push(() => this.items.every(item => {
return this.modelStore.getComponent(item.descriptor.id).valid;
@@ -239,7 +261,7 @@ export abstract class ContainerBase<T> extends ComponentBase {
}
if (index !== undefined && index !== null && index >= 0 && index < this.items.length) {
this.items.splice(index, 0, new ItemDescriptor(componentDescriptor, config));
} else if(!index) {
} else if (!index) {
this.items.push(new ItemDescriptor(componentDescriptor, config));
} else {
throw new Error(nls.localize('invalidIndex', 'The index is invalid.'));

View File

@@ -22,13 +22,16 @@ export class ItemDescriptor<T> {
constructor(public descriptor: IComponentDescriptor, public config: T) { }
}
const ids = new IdGenerator('model-view-component-icon-');
export abstract class ComponentWithIconBase extends ComponentBase {
protected _iconClass: string;
protected _iconPath: IUserFriendlyIcon;
constructor(
changeRef: ChangeDetectorRef) {
super(changeRef);
changeRef: ChangeDetectorRef,
el: ElementRef, ) {
super(changeRef, el);
}
/// IComponent implementation
@@ -41,7 +44,6 @@ export abstract class ComponentWithIconBase extends ComponentBase {
if (this.iconPath && this.iconPath !== this._iconPath) {
this._iconPath = this.iconPath;
if (!this._iconClass) {
const ids = new IdGenerator('model-view-component-icon-' + Math.round(Math.random() * 1000));
this._iconClass = ids.nextId();
}

View File

@@ -2,7 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import DivContainer from './divContainer.component';
import FlexContainer from './flexContainer.component';
import FormContainer from './formContainer.component';
import ToolbarContainer from './toolbarContainer.component';
@@ -22,9 +22,13 @@ import TextComponent from './text.component';
import LoadingComponent from './loadingComponent.component';
import FileBrowserTreeComponent from './fileBrowserTree.component';
import EditorComponent from './editor.component';
import DomComponent from './dom.component';
import { registerComponentType } from 'sql/platform/dashboard/common/modelComponentRegistry';
import { ModelComponentTypes } from 'sql/workbench/api/common/sqlExtHostTypes';
export const DIV_CONTAINER = 'div-container';
registerComponentType(DIV_CONTAINER, ModelComponentTypes.DivContainer, DivContainer);
export const FLEX_CONTAINER = 'flex-container';
registerComponentType(FLEX_CONTAINER, ModelComponentTypes.FlexContainer, FlexContainer);
@@ -82,3 +86,6 @@ registerComponentType(FILEBROWSERTREE_COMPONENT, ModelComponentTypes.FileBrowser
export const EDITOR_COMPONENT = 'editor-component';
registerComponentType(EDITOR_COMPONENT, ModelComponentTypes.Editor, EditorComponent);
export const DOM_COMPONENT = 'dom-component';
registerComponentType(DOM_COMPONENT, ModelComponentTypes.Dom, DomComponent);

View File

@@ -64,9 +64,10 @@ export default class DeclarativeTableComponent extends ComponentBase implements
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
@Inject(IContextViewService) private contextViewService: IContextViewService
@Inject(IContextViewService) private contextViewService: IContextViewService,
@Inject(forwardRef(() => ElementRef)) el: ElementRef
) {
super(changeRef);
super(changeRef, el);
}
ngOnInit(): void {
@@ -134,7 +135,7 @@ export default class DeclarativeTableComponent extends ComponentBase implements
private onCellDataChanged(newValue: any, row: number, cell: number): void {
this.data[row][cell] = newValue;
this.data = this.data;
let newCellData : sqlops.TableCell = {
let newCellData: sqlops.TableCell = {
row: row,
column: cell,
value: newValue

View 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 : {};
}
}

View File

@@ -0,0 +1,5 @@
.divContainer {
display: block;
height: 100%;
}

View File

@@ -0,0 +1,92 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./dom';
import 'vs/css!./highlight';
import 'vs/css!./markdown';
import {
Component, Input, Inject, ChangeDetectorRef, forwardRef, ComponentFactoryResolver,
ViewChild, ViewChildren, ElementRef, Injector, OnDestroy, QueryList
} from '@angular/core';
import * as sqlops from 'sqlops';
import * as DOM from 'vs/base/browser/dom';
import { $, Builder } from 'vs/base/browser/builder';
import { ComponentBase } from 'sql/parts/modelComponents/componentBase';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces';
@Component({
template: '',
selector: 'modelview-dom-component'
})
export default class DomComponent extends ComponentBase implements IComponent, OnDestroy {
@Input() descriptor: IComponentDescriptor;
@Input() modelStore: IModelStore;
private _renderedHtml: string;
private _rootElement: Builder;
private _bodyElement: Builder;
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef
) {
super(changeRef, el);
}
ngOnInit(): void {
this.baseInit();
this.createDomElement();
this._register(DOM.addDisposableListener(window, DOM.EventType.RESIZE, e => {
this.layout();
}));
}
ngOnDestroy(): void {
this.baseDestroy();
}
private createDomElement() {
this._rootElement = new Builder(this._el.nativeElement);
this._bodyElement = $('.dom-body');
this._rootElement.append(this._bodyElement);
}
/// Dom Functions
private setHtml(): void {
if (this.html) {
this._renderedHtml = this.html;
this._bodyElement.innerHtml(this._renderedHtml);
}
}
/// IComponent implementation
public layout(): void {
super.layout();
let element = <HTMLElement>this._el.nativeElement;
element.style.width = this.getWidth();
element.style.height = this.getHeight();
}
public setLayout(layout: any): void {
// TODO allow configuring the look and feel
this.layout();
}
public setProperties(properties: { [key: string]: any; }): void {
super.setProperties(properties);
if (this.html !== this._renderedHtml) {
this.setHtml();
}
}
// CSS-bound properties
public get html(): string {
return this.getPropertyOrDefault<sqlops.DomProperties, string>((props) => props.html, '');
}
public set html(newValue: string) {
this.setPropertyFromUI<sqlops.DomProperties, string>((properties, html) => { properties.html = html; }, newValue);
}
}

View File

@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
modelview-dom-component {
display: block;
-webkit-user-select: text;
}

View File

@@ -41,9 +41,10 @@ export default class DropDownComponent extends ComponentBase implements ICompone
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
@Inject(IContextViewService) private contextViewService: IContextViewService
@Inject(IContextViewService) private contextViewService: IContextViewService,
@Inject(forwardRef(() => ElementRef)) el: ElementRef
) {
super(changeRef);
super(changeRef, el);
}
ngOnInit(): void {

View File

@@ -41,12 +41,12 @@ export default class EditorComponent extends ComponentBase implements IComponent
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
@Inject(IModelService) private _modelService: IModelService,
@Inject(IModeService) private _modeService: IModeService
) {
super(changeRef);
super(changeRef, el);
}
ngOnInit(): void {
@@ -63,7 +63,7 @@ export default class EditorComponent extends ComponentBase implements IComponent
this._editor.create(this._el.nativeElement);
this._editor.setVisible(true);
let uri = this.createUri();
this._editorInput = instantiationService.createInstance(UntitledEditorInput, uri, false, 'sql', '', '');
this._editorInput = instantiationService.createInstance(UntitledEditorInput, uri, false, 'plaintext', '', '');
this._editor.setInput(this._editorInput, undefined);
this._editorInput.resolve().then(model => {
this._editorModel = model.textEditorModel;
@@ -107,7 +107,7 @@ export default class EditorComponent extends ComponentBase implements IComponent
this._editor.layout(new DOM.Dimension(
width && width > 0 ? width : DOM.getContentWidth(this._el.nativeElement),
height && height > 0 ? height : DOM.getContentHeight(this._el.nativeElement)));
let element = <HTMLElement> this._el.nativeElement;
let element = <HTMLElement>this._el.nativeElement;
element.style.position = this.position;
}
@@ -129,7 +129,6 @@ export default class EditorComponent extends ComponentBase implements IComponent
}
/// IComponent implementation
public setLayout(layout: any): void {
// TODO allow configuring the look and feel
this.layout();

View File

@@ -27,15 +27,16 @@ export default class FileBrowserTreeComponent extends ComponentBase implements I
@Input() modelStore: IModelStore;
private _treeView: FileBrowserTreeView;
private _viewModel: FileBrowserViewModel;
private _fileFilters: [{label: string, filters: string[]}] = [
private _fileFilters: [{ label: string, filters: string[] }] = [
{ label: 'All Files', filters: ['*'] }
];
@ViewChild('fileBrowserTree', { read: ElementRef }) private _treeContainer: ElementRef;
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(IInstantiationService) private _instantiationService: IInstantiationService) {
super(changeRef);
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
super(changeRef, el);
}
ngOnInit(): void {

View File

@@ -45,8 +45,11 @@ export default class FlexContainer extends ContainerBase<FlexItemLayout> impleme
private _width: string;
private _position: string;
constructor(@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
super(changeRef);
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef
) {
super(changeRef, el);
this._flexFlow = ''; // default
this._justifyContent = ''; // default
}

View File

@@ -106,8 +106,9 @@ export default class FormContainer extends ContainerBase<FormItemLayout> impleme
constructor(
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
super(changeRef);
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
super(changeRef, el);
}
ngOnInit(): void {

View File

@@ -45,8 +45,9 @@ export default class GroupContainer extends ContainerBase<GroupLayout> implement
constructor(
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
super(changeRef);
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
super(changeRef, el);
}
ngOnInit(): void {

View File

@@ -0,0 +1,183 @@
/*
https://raw.githubusercontent.com/isagalaev/highlight.js/master/src/styles/vs2015.css
*/
/*
* Visual Studio 2015 dark style
* Author: Nicolas LLOBERA <nllobera@gmail.com>
*/
modelview-dom-component .hljs-keyword,
modelview-dom-component .hljs-literal,
modelview-dom-component .hljs-symbol,
modelview-dom-component .hljs-name {
color: #569CD6;
}
modelview-dom-component .hljs-link {
color: #569CD6;
text-decoration: underline;
}
modelview-dom-component .hljs-built_in,
modelview-dom-component .hljs-type {
color: #4EC9B0;
}
modelview-dom-component .hljs-number,
modelview-dom-component .hljs-class {
color: #B8D7A3;
}
modelview-dom-component .hljs-string,
modelview-dom-component .hljs-meta-string {
color: #D69D85;
}
modelview-dom-component .hljs-regexp,
modelview-dom-component .hljs-template-tag {
color: #9A5334;
}
modelview-dom-component .hljs-subst,
modelview-dom-component .hljs-function,
modelview-dom-component .hljs-title,
modelview-dom-component .hljs-params,
modelview-dom-component .hljs-formula {
color: #DCDCDC;
}
modelview-dom-component .hljs-comment,
modelview-dom-component .hljs-quote {
color: #57A64A;
font-style: italic;
}
modelview-dom-component .hljs-doctag {
color: #608B4E;
}
modelview-dom-component .hljs-meta,
modelview-dom-component .hljs-meta-keyword,
modelview-dom-component .hljs-tag {
color: #9B9B9B;
}
modelview-dom-component .hljs-variable,
modelview-dom-component .hljs-template-variable {
color: #BD63C5;
}
modelview-dom-component .hljs-attr,
modelview-dom-component .hljs-attribute,
modelview-dom-component .hljs-builtin-name {
color: #9CDCFE;
}
modelview-dom-component .hljs-section {
color: gold;
}
modelview-dom-component .hljs-emphasis {
font-style: italic;
}
modelview-dom-component .hljs-strong {
font-weight: bold;
}
/*.hljs-code {
font-family:'Monospace';
}*/
modelview-dom-component .hljs-bullet,
modelview-dom-component .hljs-selector-tag,
modelview-dom-component .hljs-selector-id,
modelview-dom-component .hljs-selector-class,
modelview-dom-component .hljs-selector-attr,
modelview-dom-component .hljs-selector-pseudo {
color: #D7BA7D;
}
modelview-dom-component .hljs-addition {
background-color: #144212;
display: inline-block;
width: 100%;
}
modelview-dom-component .hljs-deletion {
background-color: #600;
display: inline-block;
width: 100%;
}
/*
From https://raw.githubusercontent.com/isagalaev/highlight.js/master/src/styles/vs.css
*/
/*
Visual Studio-like style based on original C# coloring by Jason Diamond <jason@diamond.name>
*/
/*
.vscode-light .hljs-function,
.vscode-light .hljs-params {
color: inherit;
}
.vscode-light .hljs-comment,
.vscode-light .hljs-quote,
.vscode-light .hljs-variable {
color: #008000;
}
.vscode-light .hljs-keyword,
.vscode-light .hljs-selector-tag,
.vscode-light .hljs-built_in,
.vscode-light .hljs-name,
.vscode-light .hljs-tag {
color: #00f;
}
.vscode-light .hljs-string,
.vscode-light .hljs-title,
.vscode-light .hljs-section,
.vscode-light .hljs-attribute,
.vscode-light .hljs-literal,
.vscode-light .hljs-template-tag,
.vscode-light .hljs-template-variable,
.vscode-light .hljs-type,
.vscode-light .hljs-addition {
color: #a31515;
}
.vscode-light .hljs-deletion,
.vscode-light .hljs-selector-attr,
.vscode-light .hljs-selector-pseudo,
.vscode-light .hljs-meta {
color: #2b91af;
}
.vscode-light .hljs-doctag {
color: #808080;
}
.vscode-light .hljs-attr {
color: #f00;
}
.vscode-light .hljs-symbol,
.vscode-light .hljs-bullet,
.vscode-light .hljs-link {
color: #00b0e8;
}
.vscode-light .hljs-emphasis {
font-style: italic;
}
.vscode-light .hljs-strong {
font-weight: bold;
}
*/

View File

@@ -42,9 +42,10 @@ export default class InputBoxComponent extends ComponentBase implements ICompone
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
@Inject(IContextViewService) private contextViewService: IContextViewService
@Inject(IContextViewService) private contextViewService: IContextViewService,
@Inject(forwardRef(() => ElementRef)) el: ElementRef
) {
super(changeRef);
super(changeRef, el);
}
ngOnInit(): void {

View File

@@ -37,9 +37,10 @@ export default class ListBoxComponent extends ComponentBase implements IComponen
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
@Inject(IContextViewService) private contextViewService: IContextViewService,
@Inject(IClipboardService) private clipboardService: IClipboardService
@Inject(IClipboardService) private clipboardService: IClipboardService,
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
) {
super(changeRef);
super(changeRef, el);
}
ngOnInit(): void {

View File

@@ -35,8 +35,9 @@ export default class LoadingComponent extends ComponentBase implements IComponen
@ViewChild('childElement', { read: ElementRef }) private _childElement: ElementRef;
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
super(changeRef);
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
super(changeRef, el);
this._validations.push(() => {
if (!this._component) {
return true;

View File

@@ -0,0 +1,239 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
modelview-dom-component {
font-family: "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
font-size: 14px;
padding: 0 26px;
line-height: 22px;
word-wrap: break-word;
}
modelview-dom-component #code-csp-warning {
position: fixed;
top: 0;
right: 0;
color: white;
margin: 16px;
text-align: center;
font-size: 12px;
font-family: sans-serif;
background-color:#444444;
cursor: pointer;
padding: 6px;
box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}
modelview-dom-component #code-csp-warning:hover {
text-decoration: none;
background-color:#007acc;
box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}
modelview-dom-component .scrollBeyondLastLine {
margin-bottom: calc(100vh - 22px);
}
modelview-dom-component .showEditorSelection .code-line {
position: relative;
}
modelview-dom-component .showEditorSelection .code-active-line:before,
modelview-dom-component .showEditorSelection .code-line:hover:before {
content: "";
display: block;
position: absolute;
top: 0;
left: -12px;
height: 100%;
}
modelview-dom-component .showEditorSelection li.code-active-line:before,
modelview-dom-component .showEditorSelection li.code-line:hover:before {
left: -30px;
}
modelview-dom-component .showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(0, 0, 0, 0.15);
}
modelview-dom-component .showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(0, 0, 0, 0.40);
}
modelview-dom-component .showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
.vs-dark .monaco-workbench modelview-dom-component .showEditorSelection .code-active-line:before
.hc-black .monaco-workbench modelview-dom-component .showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 255, 255, 0.4);
}
.vs-dark .monaco-workbench modelview-dom-component .showEditorSelection .code-line:hover:before
.hc-black .monaco-workbench modelview-dom-component .showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 255, 255, 0.60);
}
.vs-dark .monaco-workbench modelview-dom-component .showEditorSelection .code-line .code-line:hover:before
.hc-black .monaco-workbench modelview-dom-component .showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
.hc-black modelview-dom-component .showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 160, 0, 0.7);
}
.hc-black modelview-dom-component .showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 160, 0, 1);
}
modelview-dom-component .showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
modelview-dom-component img {
max-width: 100%;
max-height: 100%;
}
modelview-dom-component a, a:link{
text-decoration: none;
color: rgb(0, 0, 238) !important;
}
modelview-dom-component a:hover, a:link {
text-decoration: underline;
}
modelview-dom-component a:focus,
modelview-dom-component input:focus,
modelview-dom-component select:focus,
modelview-dom-component textarea:focus {
outline: 1px solid -webkit-focus-ring-color;
outline-offset: -1px;
}
modelview-dom-component hr {
border: 0;
height: 2px;
border-bottom: 2px solid;
}
modelview-dom-component h1 {
padding-bottom: 0.3em;
line-height: 1.2;
border-bottom-width: 1px;
border-bottom-style: solid;
}
modelview-dom-component h1,
modelview-dom-component h2,
modelview-dom-component h3 {
font-weight: normal;
}
modelview-dom-component h1 code,
modelview-dom-component h2 code,
modelview-dom-component h3 code,
modelview-dom-component h4 code,
modelview-dom-component h5 code,
modelview-dom-component h6 code {
font-size: inherit;
line-height: auto;
}
modelview-dom-component table {
border-collapse: collapse;
}
modelview-dom-component table > thead > tr > th {
text-align: left;
border-bottom: 1px solid;
}
modelview-dom-component table > thead > tr > th,
modelview-dom-component table > thead > tr > td,
modelview-dom-component table > tbody > tr > th,
modelview-dom-component table > tbody > tr > td {
padding: 5px 10px;
}
modelview-dom-component table > tbody > tr + tr > td {
border-top: 1px solid;
}
modelview-dom-component blockquote {
margin: 0 7px 0 5px;
padding: 0 16px 0 10px;
border-left-width: 5px;
border-left-style: solid;
}
modelview-dom-component code {
font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
font-size: 14px;
line-height: 19px;
}
modelview-dom-component .wordWrap pre {
white-space: pre-wrap;
}
modelview-dom-component .mac code {
font-size: 12px;
line-height: 18px;
}
modelview-dom-component pre:not(.hljs),
modelview-dom-component pre.hljs code > div {
padding: 16px;
border-radius: 3px;
overflow: auto;
}
/** Theming */
modelview-dom-component pre code {
color: var(--vscode-editor-foreground);
}
modelview-dom-component pre {
background-color: rgba(220, 220, 220, 0.4);
}
.vs-dark .monaco-workbench modelview-dom-component pre {
background-color: rgba(10, 10, 10, 0.4);
}
.hc-black .monaco-workbench modelview-dom-component pre {
background-color: rgb(0, 0, 0);
}
.hc-black .monaco-workbench modelview-dom-component h1 {
border-color: rgb(0, 0, 0);
}
modelview-dom-component table > thead > tr > th {
border-color: rgba(0, 0, 0, 0.69);
}
.vs-dark .monaco-workbench modelview-dom-component table > thead > tr > th {
border-color: rgba(255, 255, 255, 0.69);
}
modelview-dom-component h1,
modelview-dom-component hr,
modelview-dom-component table > tbody > tr + tr > td {
border-color: rgba(0, 0, 0, 0.18);
}
.vs-dark .monaco-workbench modelview-dom-component h1,
.vs-dark .monaco-workbench modelview-dom-component hr,
.vs-dark .monaco-workbench modelview-dom-component table > tbody > tr + tr > td {
border-color: rgba(255, 255, 255, 0.18);
}

View File

@@ -3,16 +3,50 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as sqlops from 'sqlops';
import { TPromise } from 'vs/base/common/winjs.base';
import { IEditorModel } from 'vs/platform/editor/common/editor';
import { EditorInput } from 'vs/workbench/common/editor';
import { EditorInput, EditorModel, ConfirmResult } from 'vs/workbench/common/editor';
import * as DOM from 'vs/base/browser/dom';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
import { DialogPane } from 'sql/platform/dialog/dialogPane';
import { Emitter, Event } from 'vs/base/common/event';
import * as sqlops from 'sqlops';
export type ModeViewSaveHandler = (handle: number) => Thenable<boolean>;
export class ModelViewInputModel extends EditorModel {
private dirty: boolean;
private readonly _onDidChangeDirty: Emitter<void> = this._register(new Emitter<void>());
get onDidChangeDirty(): Event<void> { return this._onDidChangeDirty.event; }
constructor(public readonly modelViewId, private readonly handle: number, private saveHandler?: ModeViewSaveHandler) {
super();
this.dirty = false;
}
get isDirty(): boolean {
return this.dirty;
}
public setDirty(dirty: boolean): void {
if (this.dirty === dirty) {
return;
}
this.dirty = dirty;
this._onDidChangeDirty.fire();
}
save(): TPromise<boolean> {
if (this.saveHandler) {
return TPromise.wrap(this.saveHandler(this.handle));
}
return TPromise.wrap(true);
}
}
export class ModelViewInput extends EditorInput {
public static ID: string = 'workbench.editorinputs.ModelViewEditorInput';
@@ -20,14 +54,15 @@ export class ModelViewInput extends EditorInput {
private _dialogPaneContainer: HTMLElement;
private _dialogPane: DialogPane;
constructor(private _title: string, private _modelViewId: string,
constructor(private _title: string, private _model: ModelViewInputModel,
private _options: sqlops.ModelViewEditorOptions,
@IInstantiationService private _instantiationService: IInstantiationService,
@IPartService private readonly _partService: IPartService
) {
super();
this._model.onDidChangeDirty(() => this._onDidChangeDirty.fire());
this._container = document.createElement('div');
this._container.id = `modelView-${_modelViewId}`;
this._container.id = `modelView-${_model.modelViewId}`;
this._partService.getContainer(Parts.EDITOR_PART).appendChild(this._container);
}
@@ -37,7 +72,7 @@ export class ModelViewInput extends EditorInput {
}
public get modelViewId(): string {
return this._modelViewId;
return this._model.modelViewId;
}
public getTypeId(): string {
@@ -85,6 +120,31 @@ export class ModelViewInput extends EditorInput {
return this._options;
}
/**
* An editor that is dirty will be asked to be saved once it closes.
*/
isDirty(): boolean {
return this._model.isDirty;
}
/**
* Subclasses should bring up a proper dialog for the user if the editor is dirty and return the result.
*/
confirmSave(): TPromise<ConfirmResult> {
// TODO #2530 support save on close / confirm save. This is significantly more work
// as we need to either integrate with textFileService (seems like this isn't viable)
// or register our own complimentary service that handles the lifecycle operations such
// as close all, auto save etc.
return TPromise.wrap(ConfirmResult.DONT_SAVE);
}
/**
* Saves the editor if it is dirty. Subclasses return a promise with a boolean indicating the success of the operation.
*/
save(): TPromise<boolean> {
return this._model.save();
}
public dispose(): void {
if (this._dialogPane) {
this._dialogPane.dispose();
@@ -93,6 +153,9 @@ export class ModelViewInput extends EditorInput {
this._container.remove();
this._container = undefined;
}
if (this._model) {
this._model.dispose();
}
super.dispose();
}
}

View File

@@ -33,8 +33,9 @@ export default class RadioButtonComponent extends ComponentBase implements IComp
@ViewChild('input', { read: ElementRef }) private _inputContainer: ElementRef;
constructor(
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
super(changeRef);
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
super(changeRef, el);
}
ngOnInit(): void {

View File

@@ -35,8 +35,9 @@ export default class TableComponent extends ComponentBase implements IComponent,
@ViewChild('table', { read: ElementRef }) private _inputContainer: ElementRef;
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService) {
super(changeRef);
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
super(changeRef, el);
}
ngOnInit(): void {

View File

@@ -6,7 +6,7 @@
import 'vs/css!./radioButton';
import {
Component, Input, Inject, ChangeDetectorRef, forwardRef,
OnDestroy, AfterViewInit
OnDestroy, AfterViewInit, ElementRef
} from '@angular/core';
import * as sqlops from 'sqlops';
@@ -26,8 +26,9 @@ export default class TextComponent extends ComponentBase implements IComponent,
constructor(
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
super(changeRef);
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
super(changeRef, el);
}
ngOnInit(): void {

View File

@@ -29,7 +29,7 @@ export class ToolbarItem {
template: `
<div #container *ngIf="items" [class]="toolbarClass" >
<ng-container *ngFor="let item of items">
<div class="modelview-toolbar-item" [title]="getItemTitle(item)" [style.paddingTop]="paddingTop" tabindex="0">
<div class="modelview-toolbar-item" [style.paddingTop]="paddingTop">
<div *ngIf="shouldShowTitle(item)" class="modelview-toolbar-title" >
{{getItemTitle(item)}}
</div>
@@ -52,8 +52,9 @@ export default class ToolbarContainer extends ContainerBase<ToolbarItemConfig> i
constructor(
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef) {
super(changeRef);
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
super(changeRef, el);
this._orientation = Orientation.Horizontal;
}
@@ -89,7 +90,7 @@ export default class ToolbarContainer extends ContainerBase<ToolbarItemConfig> i
}
public get paddingTop(): string {
return this.isHorizontal() ? '' : '10px';
return this.isHorizontal() ? '' : '';
}
public get toolbarClass(): string {

View File

@@ -30,6 +30,13 @@
padding-left: 10px;
}
.modelview-toolbar-container.toolbar-vertical .modelview-toolbar-item {
flex: 0 0;
flex-direction: row;
display: flex;
padding-left: 0px;
}
.modelview-toolbar-container .modelview-toolbar-title {
padding: 4px;
font-size: 14px;
@@ -46,4 +53,21 @@
padding-left: 15px;
background-size: 11px;
margin-right: 0.3em;
}
}
/* Vertical button handling */
.modelview-toolbar-container.toolbar-vertical .modelview-toolbar-component modelview-button .monaco-text-button.icon {
padding: 22px 16px 22px 16px;
background-size: 22px;
margin-right: 0.3em;
background-position: 50% 50%;
}
.modelview-toolbar-container .modelview-toolbar-component modelview-button .monaco-text-button.active {
-ms-transform: scale(1.272019649, 1.272019649); /* 1.272019649 = √φ */
-webkit-transform: scale(1.272019649, 1.272019649);
-moz-transform: scale(1.272019649, 1.272019649);
-o-transform: scale(1.272019649, 1.272019649);
transform: scale(1.272019649, 1.272019649);
}

View File

@@ -55,8 +55,10 @@ export default class TreeComponent extends ComponentBase implements IComponent,
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
@Inject(IContextViewService) private contextViewService: IContextViewService,
@Inject(IInstantiationService) private _instantiationService: IInstantiationService) {
super(changeRef);
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
@Inject(forwardRef(() => ElementRef)) el: ElementRef
) {
super(changeRef, el);
}
ngOnInit(): void {
@@ -112,7 +114,7 @@ export default class TreeComponent extends ComponentBase implements IComponent,
this._tree.domFocus();
this._register(this._tree);
this._register(attachListStyler(this._tree, this.themeService));
this._register(this._tree.onDidChangeSelection( e => {
this._register(this._tree.onDidChangeSelection(e => {
this._dataProvider.onNodeSelected(e.selection);
}));
this._tree.refresh();

View File

@@ -29,11 +29,6 @@ export class TreeViewDataProvider extends vsTreeView.TreeViewDataProvider implem
}
}
refresh(itemsToRefreshByHandle: { [treeItemHandle: string]: ITreeComponentItem }) {
}
getChildren(element?: ITreeComponentItem): TPromise<ITreeComponentItem[]> {
return undefined;
}
}

View File

@@ -26,6 +26,13 @@ import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } fro
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
function reviveWebviewOptions(options: vscode.WebviewOptions): vscode.WebviewOptions {
return {
...options,
localResourceRoots: Array.isArray(options.localResourceRoots) ? options.localResourceRoots.map(URI.revive) : undefined
};
}
@Component({
template: '',
selector: 'modelview-webview-component'
@@ -46,7 +53,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
constructor(
@Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface,
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef,
@Inject(IPartService) private partService: IPartService,
@Inject(IThemeService) private themeService: IThemeService,
@Inject(IEnvironmentService) private environmentService: IEnvironmentService,
@@ -56,7 +63,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
@Inject(IContextKeyService) contextKeyService: IContextKeyService
) {
super(changeRef);
super(changeRef, el);
}
ngOnInit(): void {
@@ -132,7 +139,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
/// IComponent implementation
public layout(): void {
let element = <HTMLElement> this._el.nativeElement;
let element = <HTMLElement>this._el.nativeElement;
element.style.position = this.position;
this._webview.layout();
}
@@ -192,6 +199,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
private getExtendedOptions(): WebviewOptions {
let options = this.options || { enableScripts: true };
options = reviveWebviewOptions(options);
return {
allowScripts: options.enableScripts,
allowSvgs: true,
@@ -208,4 +216,5 @@ export default class WebViewComponent extends ComponentBase implements IComponen
}
return rootPaths;
}
}

View File

@@ -72,6 +72,8 @@ export interface IObjectExplorerService {
getActiveConnectionNodes(): TreeNode[];
getTreeNode(connectionId: string, nodePath: string): Thenable<TreeNode>;
refreshNodeInView(connectionId: string, nodePath: string): Thenable<TreeNode>;
}
interface SessionStatus {
@@ -476,6 +478,20 @@ export class ObjectExplorerService implements IObjectExplorerService {
return Object.values(this._activeObjectExplorerNodes);
}
public async refreshNodeInView(connectionId: string, nodePath: string): Promise<TreeNode> {
// Get the tree node and call refresh from the provider
let treeNode = await this.getTreeNode(connectionId, nodePath);
await this.refreshTreeNode(treeNode.getSession(), treeNode);
// Get the new tree node, refresh it in the view, and expand it if needed
treeNode = await this.getTreeNode(connectionId, nodePath);
await this._serverTreeView.refreshElement(treeNode);
if (treeNode.children.length > 0) {
await treeNode.setExpandedState(TreeItemCollapsibleState.Expanded);
}
return treeNode;
}
private async setNodeExpandedState(treeNode: TreeNode, expandedState: TreeItemCollapsibleState): Promise<void> {
treeNode = await this.getUpdatedTreeNode(treeNode);
let expandNode = this.getTreeItem(treeNode);

View File

@@ -39,7 +39,7 @@ const viewletDescriptor = new ViewletDescriptor(
VIEWLET_ID,
'Servers',
'connectionViewlet',
-100
0
);
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(viewletDescriptor);

View File

@@ -167,12 +167,12 @@ export class ServerTreeActionProvider extends ContributableActionProvider {
if (TreeUpdateUtils.isDatabaseNode(treeNode)) {
if (TreeUpdateUtils.isAvailableDatabaseNode(treeNode)) {
actions.push(this._instantiationService.createInstance(ManageConnectionAction, ManageConnectionAction.ID, ManageConnectionAction.LABEL, context.tree));
this.addNewQueryAction(context, actions);
} else {
return actions;
}
}
this.addNewQueryAction(context, actions);
this.addScriptingActions(context, actions);
actions.push(this._instantiationService.createInstance(RefreshAction, RefreshAction.ID, RefreshAction.LABEL, context.tree, treeNode));

View File

@@ -7,7 +7,7 @@
import { ConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { ITree, IDataSource } from 'vs/base/parts/tree/browser/tree';
import { TreeNode } from 'sql/parts/objectExplorer/common/treeNode';
import { TreeNode, TreeItemCollapsibleState } from 'sql/parts/objectExplorer/common/treeNode';
import { IObjectExplorerService } from 'sql/parts/objectExplorer/common/objectExplorerService';
import { TPromise } from 'vs/base/common/winjs.base';
import { TreeUpdateUtils } from 'sql/parts/objectExplorer/viewlet/treeUpdateUtils';
@@ -72,9 +72,13 @@ export class ServerTreeDataSource implements IDataSource {
if (node.children) {
resolve(node.children);
} else {
// These similar changes are probably needed for a ConnectionProfile group element as well. However, we do not have a repro of a failiure in that scenario so they will be tackled in a future checkin.
// It has been tested for connecting to the server in profile itself and things work fine there.
this._objectExplorerService.resolveTreeNodeChildren(node.getSession(), node).then(() => {
resolve(node.children);
}, expandError => {
node.setExpandedState(TreeItemCollapsibleState.Collapsed);
node.errorStateMessage = expandError;
this.showError(expandError);
resolve([]);
});

View File

@@ -138,7 +138,7 @@ export class ServerTreeView {
let expandGroups: boolean = self._configurationService.getValue(SERVER_GROUP_CONFIG)[SERVER_GROUP_AUTOEXPAND_CONFIG];
if (expandGroups) {
self._tree.expandAll(ConnectionProfileGroup.getSubgroups(root));
self._tree.expandAll(ConnectionProfileGroup.getSubgroups(root));
}
if (root && !root.hasValidConnections) {
@@ -244,6 +244,10 @@ export class ServerTreeView {
TreeUpdateUtils.registeredServerUpdate(this._tree, this._connectionManagementService);
}
public refreshElement(element: any): Thenable<void> {
return this._tree.refresh(element);
}
/**
* Filter connections based on view (recent/active)
*/

View File

@@ -10,6 +10,27 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { EditorInput } from 'vs/workbench/common/editor';
import { Emitter } from 'vs/base/common/event';
import { GridPanelState } from 'sql/parts/query/editor/gridPanel';
import { MessagePanelState } from 'sql/parts/query/editor/messagePanel';
import { QueryPlanState } from 'sql/parts/queryPlan/queryPlan';
import { ChartState } from 'sql/parts/query/editor/charting/chartView';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
export class ResultsViewState {
public gridPanelState: GridPanelState = new GridPanelState();
public messagePanelState: MessagePanelState = new MessagePanelState(this.configurationService);
public chartState: ChartState = new ChartState();
public queryPlanState: QueryPlanState = new QueryPlanState();
public gridPanelSize: number;
public messagePanelSize: number;
public activeTab: string;
public visibleTabs: Set<string> = new Set<string>();
constructor(@IConfigurationService private configurationService: IConfigurationService) {
}
}
/**
* Input for the QueryResultsEditor. This input helps with logic for the viewing and editing of
* data in the results grid.
@@ -29,7 +50,11 @@ export class QueryResultsInput extends EditorInput {
public readonly onRestoreViewStateEmitter = new Emitter<void>();
public readonly onSaveViewStateEmitter = new Emitter<void>();
constructor(private _uri: string) {
public readonly state = new ResultsViewState(this.configurationService);
constructor(private _uri: string,
@IConfigurationService private configurationService: IConfigurationService
) {
super();
this._visible = false;
this._hasBootstrapped = false;

View File

@@ -82,12 +82,12 @@ export class RowCountStatusBarItem implements IStatusbarItem {
}
private _displayValue(runner: QueryRunner) {
let number = runner.batchSets.reduce((p, c) => {
let rowCount = runner.batchSets.reduce((p, c) => {
return p + c.resultSetSummaries.reduce((rp, rc) => {
return rp + rc.rowCount;
}, 0);
}, 0);
this._flavorElement.innerText = nls.localize('rowCount', "{0} rows", number);
this._flavorElement.innerText = nls.localize('rowCount', "{0} rows", rowCount);
show(this._flavorElement);
}
}

View File

@@ -11,13 +11,14 @@ import { localize } from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { ITree } from 'vs/base/parts/tree/browser/tree';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import QueryRunner from 'sql/parts/query/execution/queryRunner';
import { SaveFormat } from 'sql/parts/grid/common/interfaces';
import { Table } from 'sql/base/browser/ui/table/table';
import { GridTableState } from 'sql/parts/query/editor/gridPanel';
import { QueryEditor } from './queryEditor';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { CellSelectionModel } from 'sql/base/browser/ui/table/plugins/cellSelectionModel.plugin';
export interface IGridActionContext {
cell: { row: number; cell: number; };
@@ -26,6 +27,7 @@ export interface IGridActionContext {
batchId: number;
resultId: number;
table: Table<any>;
selectionModel: CellSelectionModel<any>;
tableState: GridTableState;
}
@@ -34,6 +36,14 @@ export interface IMessagesActionContext {
tree: ITree;
}
function mapForNumberColumn(ranges: Slick.Range[]): Slick.Range[] {
if (ranges) {
return ranges.map(e => new Slick.Range(e.fromRow, e.fromCell - 1, e.toRow, e.toCell ? e.toCell - 1 : undefined));
} else {
return undefined;
}
}
export class SaveResultAction extends Action {
public static SAVECSV_ID = 'grid.saveAsCsv';
public static SAVECSV_LABEL = localize('saveAsCsv', 'Save As CSV');
@@ -51,13 +61,19 @@ export class SaveResultAction extends Action {
id: string,
label: string,
icon: string,
private format: SaveFormat
private format: SaveFormat,
private accountForNumberColumn = true
) {
super(id, label, icon);
}
public run(context: IGridActionContext): TPromise<boolean> {
context.runner.serializeResults(context.batchId, context.resultId, this.format, context.selection);
if (this.accountForNumberColumn) {
context.runner.serializeResults(context.batchId, context.resultId, this.format,
mapForNumberColumn(context.selection));
} else {
context.runner.serializeResults(context.batchId, context.resultId, this.format, context.selection);
}
return TPromise.as(true);
}
}
@@ -73,12 +89,19 @@ export class CopyResultAction extends Action {
id: string,
label: string,
private copyHeader: boolean,
private accountForNumberColumn = true
) {
super(id, label);
}
public run(context: IGridActionContext): TPromise<boolean> {
context.runner.copyResults(context.selection, context.batchId, context.resultId, this.copyHeader);
if (this.accountForNumberColumn) {
context.runner.copyResults(
mapForNumberColumn(context.selection),
context.batchId, context.resultId, this.copyHeader);
} else {
context.runner.copyResults(context.selection, context.batchId, context.resultId, this.copyHeader);
}
return TPromise.as(true);
}
}
@@ -92,7 +115,7 @@ export class SelectAllGridAction extends Action {
}
public run(context: IGridActionContext): TPromise<boolean> {
context.table.setSelectedRows(true);
context.selectionModel.setSelectedRanges([new Slick.Range(0, 0, context.table.getData().getLength() - 1, context.table.columns.length - 1)]);
return TPromise.as(true);
}
}
@@ -146,13 +169,13 @@ export class MaximizeTableAction extends Action {
}
}
export class MinimizeTableAction extends Action {
public static ID = 'grid.minimize';
public static LABEL = localize('minimize', 'Minimize');
export class RestoreTableAction extends Action {
public static ID = 'grid.restore';
public static LABEL = localize('restore', 'Restore');
public static ICON = 'exitFullScreen';
constructor() {
super(MinimizeTableAction.ID, MinimizeTableAction.LABEL, MinimizeTableAction.ICON);
super(RestoreTableAction.ID, RestoreTableAction.LABEL, RestoreTableAction.ICON);
}
public run(context: IGridActionContext): TPromise<boolean> {
@@ -200,5 +223,4 @@ export class ShowQueryPlanAction extends Action {
return TPromise.as(false);
}
}
}

View File

@@ -8,10 +8,9 @@
import { localize } from 'vs/nls';
import { Registry } from 'vs/platform/registry/common/platform';
import { ChartType, DataDirection, LegendPosition } from 'sql/parts/dashboard/widgets/insights/views/charts/chartInsight.component';
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
import { DataType } from 'sql/parts/dashboard/widgets/insights/views/charts/types/lineChart.component';
import { InsightType, IInsightOptions } from './insights/interfaces';
import { DataDirection, ChartType, LegendPosition, DataType } from 'sql/parts/dashboard/widgets/insights/views/charts/interfaces';
const insightRegistry = Registry.as<IInsightRegistry>(Extensions.InsightContribution);

Some files were not shown because too many files have changed in this diff Show More