Merge master
23
CHANGELOG.md
@@ -1,5 +1,28 @@
|
||||
# Change Log
|
||||
|
||||
## Version 1.2.4
|
||||
* Release date: November 6, 2018
|
||||
* Release status: General Availability
|
||||
|
||||
## What's new in this version
|
||||
* Update to the SQL Server 2019 Preview extension
|
||||
* Introducing Paste the Plan extension
|
||||
* Introducing High Color queries extension, including SSMS editor theme
|
||||
* Fixes in SQL Server Agent, Profiler, and Import extensions
|
||||
* Fix .Net Core Socket KeepAlive issue causing dropped inactive connections on macOS
|
||||
* Upgrade SQL Tools Service to .Net Core 2.2 Preview 3 (for eventual AAD support)
|
||||
* Fix customer reported GitHub issues
|
||||
|
||||
## Contributions and "thank you"
|
||||
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
|
||||
|
||||
* rdaniels6813 for `Add query plan theme support #3031`
|
||||
* Ruturaj123 for `Fixed some typos and grammatical errors #3027`
|
||||
* PromoFaux for `Use emoji shortcodes in CONTRIBUTING.md instead of <20> #3009`
|
||||
* ckaczor for `Fix: DATETIMEOFFSET data types should be ISO formatted #714`
|
||||
* hi-im-T0dd for `Fixed sync issue with my forked master so this commit is correct #2948`
|
||||
* hi-im-T0dd for `Fixed when right clicking and selecting Manage-correct name displays #2794`
|
||||
|
||||
## Version 1.1.3
|
||||
* Release date: October 18, 2018
|
||||
* Release status: General Availability
|
||||
|
||||
19
README.md
@@ -8,12 +8,12 @@ Azure Data Studio is a data management tool that enables you to work with SQL Se
|
||||
|
||||
Platform | Link
|
||||
-- | --
|
||||
Windows Setup Installer | https://go.microsoft.com/fwlink/?linkid=2030731
|
||||
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=2030736
|
||||
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=2030738
|
||||
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=2030741
|
||||
Linux RPM | https://go.microsoft.com/fwlink/?linkid=2030746
|
||||
Linux DEB | https://go.microsoft.com/fwlink/?linkid=2030750
|
||||
Windows Setup Installer | https://go.microsoft.com/fwlink/?linkid=2038320
|
||||
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=2038323
|
||||
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=2038327
|
||||
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=2038332
|
||||
Linux RPM | https://go.microsoft.com/fwlink/?linkid=2038401
|
||||
Linux DEB | https://go.microsoft.com/fwlink/?linkid=2038405
|
||||
|
||||
Go to our [download page](https://aka.ms/azuredatastudio) for more specific instructions.
|
||||
|
||||
@@ -61,6 +61,12 @@ The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.micro
|
||||
## Contributions and "Thank You"
|
||||
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
|
||||
|
||||
* rdaniels6813 for `Add query plan theme support #3031`
|
||||
* Ruturaj123 for `Fixed some typos and grammatical errors #3027`
|
||||
* PromoFaux for `Use emoji shortcodes in CONTRIBUTING.md instead of <20> #3009`
|
||||
* ckaczor for `Fix: DATETIMEOFFSET data types should be ISO formatted #714`
|
||||
* hi-im-T0dd for `Fixed sync issue with my forked master so this commit is correct #2948`
|
||||
* hi-im-T0dd for `Fixed when right clicking and selecting Manage-correct name displays #2794`
|
||||
* philoushka for `center the icon #2760`
|
||||
* anthonypants for `Typo #2775`
|
||||
* kstolte for `Fix Invalid Configuration in Launch.json #2789`
|
||||
@@ -103,7 +109,6 @@ We would like to thank all our users who raised issues, and in particular the fo
|
||||
* Russian: Andrey Veselov, Anton Fontanov, Anton Savin, Elena Ostrovskaia, Igor Babichev, Maxim Zelensky, Rodion Fedechkin, Tasha T, Vladimir Zyryanov
|
||||
* Portuguese Brazil: Daniel de Sousa, Diogo Duarte, Douglas Correa, Douglas Eccker, José Emanuel Mendes, Marcelo Fernandes, Marcondes Alexandre, Roberto Fonseca, Rodrigo Crespi
|
||||
|
||||
|
||||
And of course, we'd like to thank the authors of all upstream dependencies. Please see a full list in the [ThirdPartyNotices.txt](https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/ThirdPartyNotices.txt)
|
||||
|
||||
## License
|
||||
|
||||
38
azure-pipelines-linux-mac.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '8.x'
|
||||
displayName: 'Install Node.js'
|
||||
|
||||
- script: |
|
||||
git submodule update --init --recursive
|
||||
nvm install 8.9.1
|
||||
nvm use 8.9.1
|
||||
npm i -g yarn
|
||||
displayName: 'preinstall'
|
||||
|
||||
- script: |
|
||||
export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0
|
||||
sh -e /etc/init.d/xvfb start
|
||||
sleep 3
|
||||
displayName: 'Linux preinstall'
|
||||
condition: eq(variables['Agent.OS'], 'Linux')
|
||||
|
||||
- script: |
|
||||
yarn
|
||||
displayName: 'Install'
|
||||
|
||||
- script: |
|
||||
node_modules/.bin/gulp electron --silent
|
||||
node_modules/.bin/gulp compile --silent --max_old_space_size=4096
|
||||
node_modules/.bin/gulp optimize-vscode --silent --max_old_space_size=4096
|
||||
displayName: 'Scripts'
|
||||
|
||||
- script: |
|
||||
./scripts/test.sh --reporter mocha-junit-reporter
|
||||
displayName: 'Tests'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFiles: '**/test-results.xml'
|
||||
condition: succeededOrFailed()
|
||||
27
azure-pipelines-windows.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '8.9'
|
||||
displayName: 'Install Node.js'
|
||||
|
||||
- script: |
|
||||
yarn
|
||||
displayName: 'Yarn Install'
|
||||
|
||||
- script: |
|
||||
.\node_modules\.bin\gulp electron
|
||||
displayName: 'Electron'
|
||||
|
||||
- script: |
|
||||
npm run compile
|
||||
displayName: 'Compile'
|
||||
|
||||
- script: |
|
||||
.\scripts\test.bat
|
||||
.\scripts\test-integration.bat
|
||||
displayName: 'Test'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFiles: '**/test-results.xml'
|
||||
condition: succeededOrFailed()
|
||||
29
azure-pipelines.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
trigger:
|
||||
- master
|
||||
- releases/*
|
||||
|
||||
jobs:
|
||||
|
||||
# All tasks on Windows
|
||||
- job: build_all_windows
|
||||
displayName: Build all tasks (Windows)
|
||||
pool:
|
||||
vmImage: vs2017-win2016
|
||||
steps:
|
||||
- template: azure-pipelines-windows.yml
|
||||
|
||||
# All tasks on Linux
|
||||
- job: build_all_linux
|
||||
displayName: Build all tasks (Linux)
|
||||
pool:
|
||||
vmImage: 'Ubuntu 16.04'
|
||||
steps:
|
||||
- template: azure-pipelines-linux-mac.yml
|
||||
|
||||
# All tasks on macOS
|
||||
- job: build_all_darwin
|
||||
displayName: Build all tasks (macOS)
|
||||
pool:
|
||||
vmImage: macos-10.13
|
||||
steps:
|
||||
- template: azure-pipelines-linux-mac.yml
|
||||
1
docs/UX-Design-Guidelines.md
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -35,7 +35,7 @@ export class OperatorDialog extends AgentDialog<OperatorData> {
|
||||
private static readonly PagerSundayCheckBoxLabel: string = localize('createOperator.PagerSundayCheckBox', 'Sunday');
|
||||
private static readonly WorkdayBeginLabel: string = localize('createOperator.workdayBegin', 'Workday begin');
|
||||
private static readonly WorkdayEndLabel: string = localize('createOperator.workdayEnd', 'Workday end');
|
||||
private static readonly PagerDutyScheduleLabel: string = localize('createOperator.PagerDutySchedule', 'Pager on duty schdule');
|
||||
private static readonly PagerDutyScheduleLabel: string = localize('createOperator.PagerDutySchedule', 'Pager on duty schedule');
|
||||
|
||||
// Notifications tab strings
|
||||
private static readonly AlertsTableLabel: string = localize('createOperator.AlertListHeading', 'Alert list');
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"request": "2.63.0",
|
||||
"request": "2.88.0",
|
||||
"azure-arm-resource": "^7.0.0",
|
||||
"azure-arm-sql": "^5.0.1",
|
||||
"vscode-nls": "^4.0.0"
|
||||
|
||||
@@ -42,21 +42,6 @@ ajv@^5.3.0:
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.3.0"
|
||||
|
||||
ansi-regex@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
|
||||
|
||||
ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
|
||||
|
||||
asn1@0.1.11:
|
||||
version "0.1.11"
|
||||
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7"
|
||||
integrity sha1-VZvhg3bQik7E2+gId9J4GGObLfc=
|
||||
|
||||
asn1@~0.2.3:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
|
||||
@@ -69,11 +54,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
||||
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
|
||||
|
||||
assert-plus@^0.1.5:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160"
|
||||
integrity sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=
|
||||
|
||||
async@2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.npmjs.org/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
|
||||
@@ -81,7 +61,7 @@ async@2.6.0:
|
||||
dependencies:
|
||||
lodash "^4.14.0"
|
||||
|
||||
async@>=0.6.0, async@^2.0.1:
|
||||
async@>=0.6.0:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
|
||||
integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==
|
||||
@@ -93,11 +73,6 @@ asynckit@^0.4.0:
|
||||
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||
|
||||
aws-sign2@~0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.5.0.tgz#c57103f7a17fc037f02d7c2e64b602ea223f7d63"
|
||||
integrity sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=
|
||||
|
||||
aws-sign2@~0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||
@@ -136,25 +111,6 @@ bcrypt-pbkdf@^1.0.0:
|
||||
dependencies:
|
||||
tweetnacl "^0.14.3"
|
||||
|
||||
bl@~1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "http://registry.npmjs.org/bl/-/bl-1.0.3.tgz#fc5421a28fd4226036c3b3891a66a25bc64d226e"
|
||||
integrity sha1-/FQhoo/UImA2w7OJGmaiW8ZNIm4=
|
||||
dependencies:
|
||||
readable-stream "~2.0.5"
|
||||
|
||||
bluebird@^2.9.30:
|
||||
version "2.11.0"
|
||||
resolved "http://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
|
||||
integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=
|
||||
|
||||
boom@2.x.x:
|
||||
version "2.10.1"
|
||||
resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
|
||||
integrity sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=
|
||||
dependencies:
|
||||
hoek "2.x.x"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
@@ -173,27 +129,11 @@ buffer-equal-constant-time@1.0.1:
|
||||
resolved "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
||||
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
|
||||
|
||||
caseless@~0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7"
|
||||
integrity sha1-cVuW6phBWTzDMGeSP17GDr2k99c=
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||
|
||||
chalk@^1.0.0:
|
||||
version "1.1.3"
|
||||
resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
||||
integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
|
||||
dependencies:
|
||||
ansi-styles "^2.2.1"
|
||||
escape-string-regexp "^1.0.2"
|
||||
has-ansi "^2.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
circular-json@^0.3.1:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
|
||||
@@ -211,7 +151,7 @@ combined-stream@1.0.6:
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
combined-stream@^1.0.5, combined-stream@~1.0.1, combined-stream@~1.0.6:
|
||||
combined-stream@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
|
||||
integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==
|
||||
@@ -223,33 +163,16 @@ commander@2.15.1:
|
||||
resolved "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
|
||||
integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
|
||||
|
||||
commander@^2.8.1:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
|
||||
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
core-util-is@1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
cryptiles@2.x.x:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
|
||||
integrity sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=
|
||||
dependencies:
|
||||
boom "2.x.x"
|
||||
|
||||
ctype@0.5.3:
|
||||
version "0.5.3"
|
||||
resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f"
|
||||
integrity sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
||||
@@ -299,12 +222,12 @@ ecdsa-sig-formatter@1.0.10:
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2:
|
||||
escape-string-regexp@1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
extend@~3.0.0, extend@~3.0.2:
|
||||
extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
@@ -329,20 +252,11 @@ fast-json-stable-stringify@^2.0.0:
|
||||
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
|
||||
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
|
||||
|
||||
forever-agent@~0.6.0, forever-agent@~0.6.1:
|
||||
forever-agent@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
||||
|
||||
form-data@~1.0.0-rc1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c"
|
||||
integrity sha1-rjFduaSQf6BlUCMEpm13M0de43w=
|
||||
dependencies:
|
||||
async "^2.0.1"
|
||||
combined-stream "^1.0.5"
|
||||
mime-types "^2.1.11"
|
||||
|
||||
form-data@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099"
|
||||
@@ -357,20 +271,6 @@ fs.realpath@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
generate-function@^2.0.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f"
|
||||
integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==
|
||||
dependencies:
|
||||
is-property "^1.0.2"
|
||||
|
||||
generate-object-property@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
|
||||
integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=
|
||||
dependencies:
|
||||
is-property "^1.0.0"
|
||||
|
||||
getpass@^0.1.1:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
||||
@@ -400,16 +300,6 @@ har-schema@^2.0.0:
|
||||
resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
||||
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
|
||||
|
||||
har-validator@^1.6.1:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-1.8.0.tgz#d83842b0eb4c435960aeb108a067a3aa94c0eeb2"
|
||||
integrity sha1-2DhCsOtMQ1lgrrEIoGejqpTA7rI=
|
||||
dependencies:
|
||||
bluebird "^2.9.30"
|
||||
chalk "^1.0.0"
|
||||
commander "^2.8.1"
|
||||
is-my-json-valid "^2.12.0"
|
||||
|
||||
har-validator@~5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29"
|
||||
@@ -418,47 +308,16 @@ har-validator@~5.1.0:
|
||||
ajv "^5.3.0"
|
||||
har-schema "^2.0.0"
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
||||
integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||
|
||||
hawk@~3.1.0:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
|
||||
integrity sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=
|
||||
dependencies:
|
||||
boom "2.x.x"
|
||||
cryptiles "2.x.x"
|
||||
hoek "2.x.x"
|
||||
sntp "1.x.x"
|
||||
|
||||
he@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
||||
integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0=
|
||||
|
||||
hoek@2.x.x:
|
||||
version "2.16.3"
|
||||
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
|
||||
integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=
|
||||
|
||||
http-signature@~0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-0.11.0.tgz#1796cf67a001ad5cd6849dca0991485f09089fe6"
|
||||
integrity sha1-F5bPZ6ABrVzWhJ3KCZFIXwkIn+Y=
|
||||
dependencies:
|
||||
asn1 "0.1.11"
|
||||
assert-plus "^0.1.5"
|
||||
ctype "0.5.3"
|
||||
|
||||
http-signature@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
||||
@@ -476,7 +335,7 @@ inflight@^1.0.4:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@~2.0.1:
|
||||
inherits@2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
@@ -486,27 +345,6 @@ is-buffer@^1.1.6:
|
||||
resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
||||
|
||||
is-my-ip-valid@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824"
|
||||
integrity sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==
|
||||
|
||||
is-my-json-valid@^2.12.0:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz#8fd6e40363cd06b963fa877d444bfb5eddc62175"
|
||||
integrity sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==
|
||||
dependencies:
|
||||
generate-function "^2.0.0"
|
||||
generate-object-property "^1.1.0"
|
||||
is-my-ip-valid "^1.0.0"
|
||||
jsonpointer "^4.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
is-property@^1.0.0, is-property@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
|
||||
integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=
|
||||
|
||||
is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
@@ -517,12 +355,7 @@ is-typedarray@~1.0.0:
|
||||
resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
||||
|
||||
isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
||||
|
||||
isstream@~0.1.1, isstream@~0.1.2:
|
||||
isstream@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
|
||||
@@ -542,16 +375,11 @@ json-schema@0.2.3:
|
||||
resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
|
||||
json-stringify-safe@~5.0.0, json-stringify-safe@~5.0.1:
|
||||
json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
|
||||
jsonpointer@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
|
||||
integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk=
|
||||
|
||||
jsprim@^1.2.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
||||
@@ -589,7 +417,7 @@ mime-db@~1.36.0:
|
||||
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397"
|
||||
integrity sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==
|
||||
|
||||
mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.2:
|
||||
mime-types@^2.1.12, mime-types@~2.1.19:
|
||||
version "2.1.20"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19"
|
||||
integrity sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==
|
||||
@@ -668,16 +496,6 @@ ms@2.0.0:
|
||||
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
node-uuid@~1.4.0:
|
||||
version "1.4.8"
|
||||
resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907"
|
||||
integrity sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=
|
||||
|
||||
oauth-sign@~0.8.0:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
||||
integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=
|
||||
|
||||
oauth-sign@~0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
@@ -705,11 +523,6 @@ postinstall-build@^5.0.1:
|
||||
resolved "https://registry.npmjs.org/postinstall-build/-/postinstall-build-5.0.3.tgz#238692f712a481d8f5bc8960e94786036241efc7"
|
||||
integrity sha512-vPvPe8TKgp4FLgY3+DfxCE5PIfoXBK2lyLfNCxsRbDsV6vS4oU5RG/IWxrblMn6heagbnMED3MemUQllQ2bQUg==
|
||||
|
||||
process-nextick-args@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
|
||||
integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=
|
||||
|
||||
psl@^1.1.24:
|
||||
version "1.1.29"
|
||||
resolved "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67"
|
||||
@@ -720,56 +533,14 @@ punycode@^1.4.1:
|
||||
resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
|
||||
|
||||
qs@~5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9"
|
||||
integrity sha1-TZMuXH6kEcynajEtOaYGIA/VDNk=
|
||||
|
||||
qs@~6.5.2:
|
||||
version "6.5.2"
|
||||
resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
||||
|
||||
readable-stream@~2.0.5:
|
||||
version "2.0.6"
|
||||
resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
|
||||
integrity sha1-j5A0HmilPMySh4jaz80Rs265t44=
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.1"
|
||||
isarray "~1.0.0"
|
||||
process-nextick-args "~1.0.6"
|
||||
string_decoder "~0.10.x"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
request@2.63.0:
|
||||
version "2.63.0"
|
||||
resolved "http://registry.npmjs.org/request/-/request-2.63.0.tgz#c83e7c3485e5d9bf9b146318429bc48f1253d8be"
|
||||
integrity sha1-yD58NIXl2b+bFGMYQpvEjxJT2L4=
|
||||
dependencies:
|
||||
aws-sign2 "~0.5.0"
|
||||
bl "~1.0.0"
|
||||
caseless "~0.11.0"
|
||||
combined-stream "~1.0.1"
|
||||
extend "~3.0.0"
|
||||
forever-agent "~0.6.0"
|
||||
form-data "~1.0.0-rc1"
|
||||
har-validator "^1.6.1"
|
||||
hawk "~3.1.0"
|
||||
http-signature "~0.11.0"
|
||||
isstream "~0.1.1"
|
||||
json-stringify-safe "~5.0.0"
|
||||
mime-types "~2.1.2"
|
||||
node-uuid "~1.4.0"
|
||||
oauth-sign "~0.8.0"
|
||||
qs "~5.1.0"
|
||||
stringstream "~0.0.4"
|
||||
tough-cookie ">=0.12.0"
|
||||
tunnel-agent "~0.4.0"
|
||||
|
||||
"request@>= 2.52.0", request@^2.88.0:
|
||||
request@2.88.0, "request@>= 2.52.0", request@^2.88.0:
|
||||
version "2.88.0"
|
||||
resolved "https://registry.npmjs.org/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
|
||||
integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
|
||||
dependencies:
|
||||
aws-sign2 "~0.7.0"
|
||||
@@ -847,13 +618,6 @@ should@^13.2.1:
|
||||
should-type-adaptors "^1.0.1"
|
||||
should-util "^1.0.0"
|
||||
|
||||
sntp@1.x.x:
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
|
||||
integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=
|
||||
dependencies:
|
||||
hoek "2.x.x"
|
||||
|
||||
sshpk@^1.7.0:
|
||||
version "1.14.2"
|
||||
resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98"
|
||||
@@ -870,23 +634,6 @@ sshpk@^1.7.0:
|
||||
jsbn "~0.1.0"
|
||||
tweetnacl "~0.14.0"
|
||||
|
||||
string_decoder@~0.10.x:
|
||||
version "0.10.31"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
|
||||
integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
|
||||
|
||||
stringstream@~0.0.4:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72"
|
||||
integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==
|
||||
|
||||
strip-ansi@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||
integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
supports-color@5.4.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
|
||||
@@ -894,17 +641,12 @@ supports-color@5.4.0:
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
|
||||
|
||||
through@^2.3.8:
|
||||
version "2.3.8"
|
||||
resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
|
||||
tough-cookie@>=0.12.0, tough-cookie@~2.4.3:
|
||||
tough-cookie@~2.4.3:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
|
||||
integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
|
||||
@@ -919,11 +661,6 @@ tunnel-agent@^0.6.0:
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
tunnel-agent@~0.4.0:
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb"
|
||||
integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=
|
||||
|
||||
tunnel@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz#d1532254749ed36620fcd1010865495a1fa9d0ae"
|
||||
@@ -948,11 +685,6 @@ typemoq@^2.1.0:
|
||||
resolved "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961"
|
||||
integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==
|
||||
|
||||
util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
|
||||
uuid@^3.1.0, uuid@^3.2.1, uuid@^3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
|
||||
@@ -985,9 +717,3 @@ wrappy@1:
|
||||
xpath.js@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz#3816a44ed4bb352091083d002a383dd5104a5ff1"
|
||||
integrity sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==
|
||||
|
||||
xtend@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
|
||||
integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68=
|
||||
|
||||
@@ -345,7 +345,7 @@
|
||||
"specialValueType": null,
|
||||
"isIdentity": false,
|
||||
"name": "asynchronousProcessing",
|
||||
"displayName": "Asynchronous processing enabled",
|
||||
"displayName": "Asynchronous processing",
|
||||
"description": "When true, enables usage of the Asynchronous functionality in the .Net Framework Data Provider",
|
||||
"groupName": "Initialization",
|
||||
"valueType": "boolean",
|
||||
@@ -387,7 +387,7 @@
|
||||
"specialValueType": null,
|
||||
"isIdentity": false,
|
||||
"name": "columnEncryptionSetting",
|
||||
"displayName": "Column encryption setting",
|
||||
"displayName": "Column encryption",
|
||||
"description": "Default column encryption setting for all the commands on the connection",
|
||||
"groupName": "Security",
|
||||
"valueType": "category",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
||||
"version": "1.5.0-alpha.52",
|
||||
"version": "1.5.0-alpha.53",
|
||||
"downloadFileNames": {
|
||||
"Windows_86": "win-x86-netcoreapp2.2.zip",
|
||||
"Windows_64": "win-x64-netcoreapp2.2.zip",
|
||||
|
||||
@@ -12,9 +12,7 @@ import { CreateSessionData } from '../data/createSessionData';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export class CreateSessionDialog {
|
||||
|
||||
// Top level
|
||||
private readonly DialogTitle: string = localize('createSessionDialog.newSession', 'New Session');
|
||||
private readonly CancelButtonText: string = localize('createSessionDialog.cancel', 'Cancel');
|
||||
private readonly CreateButtonText: string = localize('createSessionDialog.create', 'Create');
|
||||
private readonly DialogTitleText: string = localize('createSessionDialog.title', 'Create New Profiler Session');
|
||||
@@ -25,23 +23,28 @@ export class CreateSessionDialog {
|
||||
private sessionNameBox: sqlops.InputBoxComponent;
|
||||
|
||||
private model: CreateSessionData;
|
||||
private readonly _providerType: string;
|
||||
|
||||
private _onSuccess: vscode.EventEmitter<CreateSessionData> = new vscode.EventEmitter<CreateSessionData>();
|
||||
public readonly onSuccess: vscode.Event<CreateSessionData> = this._onSuccess.event;
|
||||
|
||||
|
||||
constructor(ownerUri: string, templates: Array<sqlops.ProfilerSessionTemplate>) {
|
||||
constructor(ownerUri: string, providerType: string, templates: Array<sqlops.ProfilerSessionTemplate>) {
|
||||
if (typeof (templates) === 'undefined' || templates === null) {
|
||||
throw new Error(localize('createSessionDialog.templatesInvalid', "Invalid templates list, cannot open dialog"));
|
||||
}
|
||||
if (typeof (ownerUri) === 'undefined' || ownerUri === null) {
|
||||
throw new Error(localize('createSessionDialog.dialogOwnerInvalid', "Invalid dialog owner, cannot open dialog"));
|
||||
}
|
||||
if (typeof (providerType) === 'undefined' || providerType === null) {
|
||||
throw new Error(localize('createSessionDialog.invalidProviderType', "Invalid provider type, cannot open dialog"));
|
||||
}
|
||||
this._providerType = providerType;
|
||||
this.model = new CreateSessionData(ownerUri, templates);
|
||||
}
|
||||
|
||||
public async showDialog(): Promise<void> {
|
||||
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
|
||||
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitleText);
|
||||
this.initializeContent();
|
||||
this.dialog.okButton.onClick(() => this.execute());
|
||||
this.dialog.cancelButton.onClick(() => { });
|
||||
@@ -76,7 +79,7 @@ export class CreateSessionDialog {
|
||||
|
||||
title: localize('createSessionDialog.enterSessionName', "Enter session name:")
|
||||
}],
|
||||
title: this.DialogTitleText
|
||||
title: ''
|
||||
}]).withLayout({ width: '100%' }).component();
|
||||
|
||||
await view.initializeModel(formModel);
|
||||
@@ -97,8 +100,7 @@ export class CreateSessionDialog {
|
||||
}
|
||||
|
||||
private async execute(): Promise<void> {
|
||||
let currentConnection = await sqlops.connection.getCurrentConnection();
|
||||
let profilerService = sqlops.dataprotocol.getProvider<sqlops.ProfilerProvider>(currentConnection.providerName, sqlops.DataProviderType.ProfilerProvider);
|
||||
let profilerService = sqlops.dataprotocol.getProvider<sqlops.ProfilerProvider>(this._providerType, sqlops.DataProviderType.ProfilerProvider);
|
||||
|
||||
let name = this.sessionNameBox.value;
|
||||
let selected = this.templatesBox.value.toString();
|
||||
|
||||
@@ -29,8 +29,8 @@ export class MainController {
|
||||
}
|
||||
|
||||
public activate(): void {
|
||||
vscode.commands.registerCommand('profiler.openCreateSessionDialog', (ownerUri: string, templates: Array<sqlops.ProfilerSessionTemplate>) => {
|
||||
let dialog = new CreateSessionDialog(ownerUri, templates);
|
||||
vscode.commands.registerCommand('profiler.openCreateSessionDialog', (ownerUri: string, providerType: string, templates: Array<sqlops.ProfilerSessionTemplate>) => {
|
||||
let dialog = new CreateSessionDialog(ownerUri, providerType, templates);
|
||||
dialog.showDialog();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "profiler",
|
||||
"displayName": "SQL Server Profiler",
|
||||
"description": "SQL Server Profiler for Azure Data Studio",
|
||||
"version": "0.3.0",
|
||||
"version": "0.4.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
|
||||
@@ -26,11 +26,10 @@
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
"contributes": {
|
||||
|
||||
"commands": [
|
||||
{
|
||||
"command": "profiler.newProfiler",
|
||||
"title": "New Profiler",
|
||||
"title": "Launch Profiler",
|
||||
"category": "Profiler"
|
||||
},
|
||||
{
|
||||
@@ -49,6 +48,15 @@
|
||||
"category": "Profiler"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"objectExplorer/item/context": [
|
||||
{
|
||||
"command": "profiler.newProfiler",
|
||||
"when": "connectionProvider == MSSQL && nodeType && nodeType == Server",
|
||||
"group": "profiler"
|
||||
}
|
||||
]
|
||||
},
|
||||
"outputChannels": [
|
||||
"sqlprofiler"
|
||||
]
|
||||
@@ -59,4 +67,4 @@
|
||||
"devDependencies": {
|
||||
"vscode": "1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,8 @@
|
||||
"panel.background": "#212121",
|
||||
"panel.border": "#515151",
|
||||
"panelTitle.activeForeground": "#ffffff",
|
||||
"panelTitle.inactiveForeground": "#888888"
|
||||
"panelTitle.inactiveForeground": "#888888",
|
||||
"panelTitle.activeBorder": "#026dc8"
|
||||
},
|
||||
"tokenColors": [
|
||||
{
|
||||
|
||||
@@ -77,7 +77,8 @@
|
||||
"panel.background": "#ffffff",
|
||||
"panel.border": "#c8c8c8",
|
||||
"panelTitle.activeForeground": "#212121",
|
||||
"panelTitle.inactiveForeground": "#757575"
|
||||
"panelTitle.inactiveForeground": "#757575",
|
||||
"panelTitle.activeBorder": "#026dc8"
|
||||
},
|
||||
"tokenColors": [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "azuredatastudio",
|
||||
"version": "1.2.4",
|
||||
"version": "1.3.1",
|
||||
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
|
||||
@@ -611,7 +611,7 @@
|
||||
</body></file>
|
||||
<file original="src/sql/parts/connection/common/connectionActions" source-language="en" datatype="plaintext"><body>
|
||||
<trans-unit id="ClearRecentlyUsedLabel">
|
||||
<source xml:lang="en">Clear Recent Connections List</source>
|
||||
<source xml:lang="en">Clear List</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="ClearedRecentConnections">
|
||||
<source xml:lang="en">Recent connections list cleared</source>
|
||||
@@ -1039,10 +1039,10 @@
|
||||
<source xml:lang="en">Connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="recentConnectionTitle">
|
||||
<source xml:lang="en">Recent connections</source>
|
||||
<source xml:lang="en">Recent Connections</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="savedConnectionTitle">
|
||||
<source xml:lang="en">Saved connections</source>
|
||||
<source xml:lang="en">Saved Connections</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="connectType">
|
||||
<source xml:lang="en">Connection type</source>
|
||||
@@ -1520,9 +1520,6 @@
|
||||
</trans-unit>
|
||||
</body></file>
|
||||
<file original="src/sql/parts/profiler/contrib/profilerActions" source-language="en" datatype="plaintext"><body>
|
||||
<trans-unit id="profiler.connect">
|
||||
<source xml:lang="en">Connect</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="profilerAction.disconnect">
|
||||
<source xml:lang="en">Disconnect</source>
|
||||
</trans-unit>
|
||||
@@ -1533,16 +1530,13 @@
|
||||
<source xml:lang="en">Start</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="create">
|
||||
<source xml:lang="en">Create</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="profiler.capture">
|
||||
<source xml:lang="en">Pause Capture</source>
|
||||
<source xml:lang="en">New Session</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="profilerAction.resumeCapture">
|
||||
<source xml:lang="en">Resume Capture</source>
|
||||
<source xml:lang="en">Resume</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="profilerAction.pauseCapture">
|
||||
<source xml:lang="en">Pause Capture</source>
|
||||
<source xml:lang="en">Pause</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="profilerStop.stop">
|
||||
<source xml:lang="en">Stop</source>
|
||||
@@ -1550,9 +1544,6 @@
|
||||
<trans-unit id="profiler.clear">
|
||||
<source xml:lang="en">Clear Data</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="profiler.autoscrollOn">
|
||||
<source xml:lang="en">Auto Scroll: On</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="profilerAction.autoscrollOn">
|
||||
<source xml:lang="en">Auto Scroll: On</source>
|
||||
</trans-unit>
|
||||
@@ -1572,7 +1563,7 @@
|
||||
<source xml:lang="en">Find Previous String</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="profilerAction.newProfiler">
|
||||
<source xml:lang="en">New Profiler</source>
|
||||
<source xml:lang="en">Launch Profiler</source>
|
||||
</trans-unit>
|
||||
</body></file>
|
||||
<file original="src/sql/base/browser/ui/selectBox/selectBox" source-language="en" datatype="plaintext"><body>
|
||||
@@ -1644,7 +1635,7 @@
|
||||
</body></file>
|
||||
<file original="src/sql/parts/connection/connectionDialog/advancedPropertiesController" source-language="en" datatype="plaintext"><body>
|
||||
<trans-unit id="connectionAdvancedProperties">
|
||||
<source xml:lang="en">Advanced properties</source>
|
||||
<source xml:lang="en">Advanced Properties</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="advancedProperties.discard">
|
||||
<source xml:lang="en">Discard</source>
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file original="extensions/profiler/client\out/dialogs/profilerCreateSessionDialog" source-language="en" datatype="plaintext"><body>
|
||||
<trans-unit id="createSessionDialog.newSession">
|
||||
<source xml:lang="en">New Session</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="createSessionDialog.cancel">
|
||||
<source xml:lang="en">Cancel</source>
|
||||
</trans-unit>
|
||||
|
||||
@@ -12,12 +12,18 @@ set CODE=".build\electron\%NAMESHORT%"
|
||||
|
||||
rem TFS Builds
|
||||
if not "%BUILD_BUILDID%" == "" (
|
||||
%CODE% .\node_modules\mocha\bin\_mocha %*
|
||||
if not "%ADD_REPORTER%" == "" (
|
||||
%CODE% .\node_modules\mocha\bin\_mocha --reporter mocha-junit-reporter %*
|
||||
)
|
||||
|
||||
if "%ADD_REPORTER%" == "" (
|
||||
%CODE% .\node_modules\mocha\bin\_mocha %*
|
||||
)
|
||||
)
|
||||
|
||||
rem Otherwise
|
||||
if "%BUILD_BUILDID%" == "" (
|
||||
%CODE% .\node_modules\mocha\bin\_mocha --reporter dot %*
|
||||
%CODE% .\node_modules\mocha\bin\_mocha --reporter mocha-junit-reporter %*
|
||||
)
|
||||
popd
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
if [[ "$OSTYPE" == "darwin"* ]] || [[ "$AGENT_OS" == "Darwin"* ]]; then
|
||||
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
|
||||
ROOT=$(dirname $(dirname $(realpath "$0")))
|
||||
|
||||
@@ -14,7 +14,7 @@ fi
|
||||
|
||||
cd $ROOT
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
if [[ "$OSTYPE" == "darwin"* ]] || [[ "$AGENT_OS" == "Darwin"* ]]; then
|
||||
NAME=`node -p "require('./product.json').nameLong"`
|
||||
CODE="./.build/electron/$NAME.app/Contents/MacOS/Electron"
|
||||
else
|
||||
@@ -30,7 +30,7 @@ node build/lib/electron.js || ./node_modules/.bin/gulp electron
|
||||
|
||||
# Unit Tests
|
||||
export ELECTRON_RUN_AS_NODE=1
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
if [[ "$OSTYPE" == "darwin"* ]] || [[ "$AGENT_OS" == "Darwin"* ]]; then
|
||||
cd $ROOT ; ulimit -n 4096 ; \
|
||||
"$CODE" \
|
||||
node_modules/mocha/bin/_mocha "$@"
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
|
||||
.modal .modal-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.modal .modal-title-icon {
|
||||
@@ -147,7 +148,7 @@
|
||||
}
|
||||
|
||||
.modal .footer-button {
|
||||
margin-right: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.modal .right-footer .footer-button:last-of-type {
|
||||
@@ -235,8 +236,8 @@
|
||||
|
||||
.modal.flyout-dialog .dialog-message-detail {
|
||||
margin-top: 5px;
|
||||
white-space: normal;
|
||||
-webkit-user-select: text;
|
||||
white-space: pre-wrap;
|
||||
user-select: text;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,34 @@
|
||||
}
|
||||
|
||||
.optionsDialog-options-groups {
|
||||
padding: 15px;
|
||||
height: calc(100% - 150px);
|
||||
margin-top: 10px;
|
||||
flex: 1 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.optionsDialog-options-groups {
|
||||
margin: 10px 0px;
|
||||
flex: 1 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.vs .optionsDialog-options-groups {
|
||||
box-shadow: 0 1px 4px 1px rgba(220, 220, 220, 0.71);
|
||||
}
|
||||
|
||||
.vs-dark .optionsDialog-options-groups {
|
||||
box-shadow: 0 4px 5px 0px rgba(0, 0, 0, 0.71);
|
||||
}
|
||||
|
||||
.optionsDialog-options-groups .split-view-view .header {
|
||||
padding-left: 28px !important;
|
||||
background-position-x: 8px !important;
|
||||
}
|
||||
|
||||
.optionsDialog-options-groups .split-view-view .body {
|
||||
padding-left: 5px !important;
|
||||
}
|
||||
|
||||
.backButtonIcon {
|
||||
content: url('back.svg');
|
||||
width: 20px;
|
||||
@@ -33,21 +56,42 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.vs-dark.monaco-shell .backButtonIcon {
|
||||
.hc-black .backButtonIcon,
|
||||
.vs-dark .backButtonIcon {
|
||||
content: url('back_inverse.svg');
|
||||
}
|
||||
|
||||
.optionsDialog-description {
|
||||
padding: 15px;
|
||||
overflow-y: auto;
|
||||
height: 90px;
|
||||
margin: 15px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.optionsDialog-description .modal-title {
|
||||
background-repeat: no-repeat;
|
||||
background-position: 2px center;
|
||||
padding-left: 25px;
|
||||
background-size: 16px;
|
||||
}
|
||||
|
||||
.vs .optionsDialog-description .modal-title {
|
||||
background-image: url('info_notification.svg')
|
||||
}
|
||||
|
||||
.vs-dark .optionsDialog-description .modal-title,
|
||||
.hc-black .optionsDialog-description .modal-title {
|
||||
background-image: url('info_notification_inverse.svg')
|
||||
}
|
||||
|
||||
.optionsDialog-options {
|
||||
height: calc(100% - 30px);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.optionsDialog-description-content {
|
||||
padding: 10px;
|
||||
padding-top: 10px;
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.optionsDialog-table{
|
||||
|
||||
@@ -72,8 +72,8 @@ const defaultOptions: IModalOptions = {
|
||||
};
|
||||
|
||||
export abstract class Modal extends Disposable implements IThemable {
|
||||
|
||||
private _messageElement: HTMLElement;
|
||||
protected _useDefaultMessageBoxLocation: boolean = true;
|
||||
protected _messageElement: HTMLElement;
|
||||
private _messageIcon: HTMLElement;
|
||||
private _messageSeverity: Builder;
|
||||
private _messageSummary: Builder;
|
||||
@@ -253,7 +253,9 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
this._messageElement = this._modalMessageSection.getHTMLElement();
|
||||
this.updateElementVisibility(this._messageElement, false);
|
||||
|
||||
parts.push(this._messageElement);
|
||||
if (this._useDefaultMessageBoxLocation) {
|
||||
parts.push(this._messageElement);
|
||||
}
|
||||
}
|
||||
|
||||
// This modal body section refers to the body of of the dialog
|
||||
|
||||
@@ -125,7 +125,7 @@ export class OptionsDialog extends Modal {
|
||||
});
|
||||
|
||||
let builder = new Builder(this._body);
|
||||
builder.div({ class: 'Connection-divider' }, (dividerContainer) => {
|
||||
builder.div({}, (dividerContainer) => {
|
||||
this._dividerBuilder = dividerContainer;
|
||||
});
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ panel {
|
||||
}
|
||||
|
||||
.tabbedPanel .tabList .tab .tabLabel {
|
||||
text-transform: uppercase;
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
padding-bottom: 4px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tabbedPanel.vertical .tabList .tab .tabLabel {
|
||||
|
||||
@@ -36,7 +36,6 @@ export interface IPanelTab {
|
||||
interface IInternalPanelTab extends IPanelTab {
|
||||
header: HTMLElement;
|
||||
label: HTMLElement;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
const defaultOptions: IPanelOptions = {
|
||||
@@ -143,8 +142,6 @@ export class TabbedPanel extends Disposable implements IThemable {
|
||||
this.tabList.appendChild(tabHeaderElement);
|
||||
tab.header = tabHeaderElement;
|
||||
tab.label = tabLabel;
|
||||
tab.dispose = () => { };
|
||||
this._register(tab);
|
||||
}
|
||||
|
||||
public showTab(id: PanelTabIdentifier): void {
|
||||
|
||||
@@ -19,6 +19,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
.tabbedPanel > .title .tabList .tab .tabLabel.active {
|
||||
color: ${titleActive};
|
||||
border-bottom-color: ${titleActiveBorder};
|
||||
border-bottom-width: 2px;
|
||||
}
|
||||
|
||||
.tabbedPanel > .title .tabList .tab-header.active {
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IDisposableDataProvider } from 'sql/base/browser/ui/table/interfaces';
|
||||
|
||||
export interface IObservableCollection<T> {
|
||||
getLength(): number;
|
||||
at(index: number): T;
|
||||
getRange(start: number, end: number): T[];
|
||||
setCollectionChangedCallback(callback: (change: CollectionChange, startIndex: number, count: number) => void): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export interface IGridDataRow {
|
||||
@@ -24,24 +27,27 @@ class LoadCancellationToken {
|
||||
}
|
||||
|
||||
class DataWindow<TData> {
|
||||
private _dataSourceLength: number;
|
||||
private _data: TData[];
|
||||
private _length: number = 0;
|
||||
private _offsetFromDataSource: number = -1;
|
||||
|
||||
private loadFunction: (offset: number, count: number) => Thenable<TData[]>;
|
||||
private lastLoadCancellationToken: LoadCancellationToken;
|
||||
private loadCompleteCallback: (start: number, end: number) => void;
|
||||
private placeholderItemGenerator: (index: number) => TData;
|
||||
|
||||
constructor(dataSourceLength: number,
|
||||
loadFunction: (offset: number, count: number) => Thenable<TData[]>,
|
||||
placeholderItemGenerator: (index: number) => TData,
|
||||
loadCompleteCallback: (start: number, end: number) => void) {
|
||||
this._dataSourceLength = dataSourceLength;
|
||||
this.loadFunction = loadFunction;
|
||||
this.placeholderItemGenerator = placeholderItemGenerator;
|
||||
this.loadCompleteCallback = loadCompleteCallback;
|
||||
constructor(
|
||||
private loadFunction: (offset: number, count: number) => Thenable<TData[]>,
|
||||
private placeholderItemGenerator: (index: number) => TData,
|
||||
private loadCompleteCallback: (start: number, end: number) => void
|
||||
) {
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._data = undefined;
|
||||
this.loadFunction = undefined;
|
||||
this.placeholderItemGenerator = undefined;
|
||||
this.loadCompleteCallback = undefined;
|
||||
if (this.lastLoadCancellationToken) {
|
||||
this.lastLoadCancellationToken.isCancelled = true;
|
||||
}
|
||||
}
|
||||
|
||||
getStartIndex(): number {
|
||||
@@ -76,10 +82,9 @@ class DataWindow<TData> {
|
||||
return;
|
||||
}
|
||||
|
||||
let cancellationToken = new LoadCancellationToken();
|
||||
this.lastLoadCancellationToken = cancellationToken;
|
||||
this.lastLoadCancellationToken = new LoadCancellationToken();
|
||||
this.loadFunction(offset, length).then(data => {
|
||||
if (!cancellationToken.isCancelled) {
|
||||
if (!this.lastLoadCancellationToken.isCancelled) {
|
||||
this._data = data;
|
||||
this.loadCompleteCallback(this._offsetFromDataSource, this._offsetFromDataSource + this._length);
|
||||
}
|
||||
@@ -97,10 +102,12 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
|
||||
|
||||
private collectionChangedCallback: (change: CollectionChange, startIndex: number, count: number) => void;
|
||||
|
||||
constructor(windowSize: number,
|
||||
constructor(
|
||||
windowSize: number,
|
||||
length: number,
|
||||
loadFn: (offset: number, count: number) => Thenable<TData[]>,
|
||||
private _placeHolderGenerator: (index: number) => TData) {
|
||||
private _placeHolderGenerator: (index: number) => TData
|
||||
) {
|
||||
this._windowSize = windowSize;
|
||||
this._length = length;
|
||||
|
||||
@@ -110,9 +117,15 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
|
||||
}
|
||||
};
|
||||
|
||||
this._bufferWindowBefore = new DataWindow(length, loadFn, _placeHolderGenerator, loadCompleteCallback);
|
||||
this._window = new DataWindow(length, loadFn, _placeHolderGenerator, loadCompleteCallback);
|
||||
this._bufferWindowAfter = new DataWindow(length, loadFn, _placeHolderGenerator, loadCompleteCallback);
|
||||
this._bufferWindowBefore = new DataWindow(loadFn, _placeHolderGenerator, loadCompleteCallback);
|
||||
this._window = new DataWindow(loadFn, _placeHolderGenerator, loadCompleteCallback);
|
||||
this._bufferWindowAfter = new DataWindow(loadFn, _placeHolderGenerator, loadCompleteCallback);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._bufferWindowAfter.dispose();
|
||||
this._bufferWindowBefore.dispose();
|
||||
this._window.dispose();
|
||||
}
|
||||
|
||||
setCollectionChangedCallback(callback: (change: CollectionChange, startIndex: number, count: number) => void): void {
|
||||
@@ -197,7 +210,7 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
|
||||
}
|
||||
}
|
||||
|
||||
export class AsyncDataProvider<TData extends IGridDataRow> implements Slick.DataProvider<TData> {
|
||||
export class AsyncDataProvider<TData extends IGridDataRow> implements IDisposableDataProvider<TData> {
|
||||
|
||||
constructor(private dataRows: IObservableCollection<TData>) { }
|
||||
|
||||
@@ -212,4 +225,8 @@ export class AsyncDataProvider<TData extends IGridDataRow> implements Slick.Data
|
||||
public getRange(start: number, end: number): TData[] {
|
||||
return !this.dataRows ? undefined : this.dataRows.getRange(start, end);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.dataRows.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
31
src/sql/base/browser/ui/table/interfaces.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IListStyles } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
|
||||
export interface IDisposableDataProvider<T> extends Slick.DataProvider<T> {
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export interface ITableMouseEvent {
|
||||
anchor: HTMLElement | { x: number, y: number };
|
||||
cell?: { row: number, cell: number };
|
||||
}
|
||||
|
||||
export interface ITableStyles extends IListStyles {
|
||||
tableHeaderBackground?: Color;
|
||||
tableHeaderForeground?: Color;
|
||||
}
|
||||
|
||||
export interface ITableSorter<T> {
|
||||
sort(args: Slick.OnSortEventArgs<T>);
|
||||
}
|
||||
|
||||
export interface ITableConfiguration<T> {
|
||||
dataProvider?: IDisposableDataProvider<T> | Array<T>;
|
||||
columns?: Slick.Column<T>[];
|
||||
sorter?: ITableSorter<T>;
|
||||
}
|
||||
@@ -5,28 +5,18 @@
|
||||
|
||||
import 'vs/css!./media/table';
|
||||
import { TableDataView } from './tableDataView';
|
||||
import { IDisposableDataProvider, ITableSorter, ITableMouseEvent, ITableConfiguration, ITableStyles } from 'sql/base/browser/ui/table/interfaces';
|
||||
|
||||
import { IThemable } from 'vs/platform/theme/common/styler';
|
||||
import { IListStyles } from 'vs/base/browser/ui/list/listWidget';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Orientation } from 'vs/base/browser/ui/splitview/splitview';
|
||||
import { Widget } from 'vs/base/browser/ui/widget';
|
||||
import { isArray, isBoolean } from 'vs/base/common/types';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { range } from 'vs/base/common/arrays';
|
||||
|
||||
export interface ITableMouseEvent {
|
||||
anchor: HTMLElement | { x: number, y: number };
|
||||
cell?: { row: number, cell: number };
|
||||
}
|
||||
|
||||
export interface ITableStyles extends IListStyles {
|
||||
tableHeaderBackground?: Color;
|
||||
tableHeaderForeground?: Color;
|
||||
}
|
||||
import { $ } from 'vs/base/browser/builder';
|
||||
|
||||
function getDefaultOptions<T>(): Slick.GridOptions<T> {
|
||||
return <Slick.GridOptions<T>>{
|
||||
@@ -35,23 +25,13 @@ function getDefaultOptions<T>(): Slick.GridOptions<T> {
|
||||
};
|
||||
}
|
||||
|
||||
export interface ITableSorter<T> {
|
||||
sort(args: Slick.OnSortEventArgs<T>);
|
||||
}
|
||||
|
||||
export interface ITableConfiguration<T> {
|
||||
dataProvider?: Slick.DataProvider<T> | Array<T>;
|
||||
columns?: Slick.Column<T>[];
|
||||
sorter?: ITableSorter<T>;
|
||||
}
|
||||
|
||||
export class Table<T extends Slick.SlickData> extends Widget implements IThemable, IDisposable {
|
||||
private styleElement: HTMLStyleElement;
|
||||
private idPrefix: string;
|
||||
|
||||
private _grid: Slick.Grid<T>;
|
||||
private _columns: Slick.Column<T>[];
|
||||
private _data: Slick.DataProvider<T>;
|
||||
private _data: IDisposableDataProvider<T>;
|
||||
private _sorter: ITableSorter<T>;
|
||||
|
||||
private _autoscroll: boolean;
|
||||
@@ -60,8 +40,6 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
|
||||
|
||||
private _classChangeTimeout: number;
|
||||
|
||||
private _disposables: IDisposable[] = [];
|
||||
|
||||
private _onContextMenu = new Emitter<ITableMouseEvent>();
|
||||
public readonly onContextMenu: Event<ITableMouseEvent> = this._onContextMenu.event;
|
||||
|
||||
@@ -76,6 +54,8 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
|
||||
this._data = configuration.dataProvider;
|
||||
}
|
||||
|
||||
this._register(this._data);
|
||||
|
||||
if (configuration && configuration.columns) {
|
||||
this._columns = configuration.columns;
|
||||
} else {
|
||||
@@ -117,6 +97,12 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
|
||||
});
|
||||
}
|
||||
|
||||
this._register({
|
||||
dispose: () => {
|
||||
this._grid.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
this.mapMouseEvent(this._grid.onContextMenu, this._onContextMenu);
|
||||
this.mapMouseEvent(this._grid.onClick, this._onClick);
|
||||
}
|
||||
@@ -131,7 +117,8 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
dispose(this._disposables);
|
||||
$(this._container).dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public invalidateRows(rows: number[], keepEditor: boolean) {
|
||||
@@ -166,7 +153,7 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
|
||||
this._grid.setData(this._data, true);
|
||||
}
|
||||
|
||||
getData(): Slick.DataProvider<T> {
|
||||
getData(): IDisposableDataProvider<T> {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as types from 'vs/base/common/types';
|
||||
|
||||
import { IDisposableDataProvider } from 'sql/base/browser/ui/table/interfaces';
|
||||
|
||||
export interface IFindPosition {
|
||||
col: number;
|
||||
row: number;
|
||||
@@ -20,7 +22,7 @@ function defaultSort<T>(args: Slick.OnSortEventArgs<T>, data: Array<T>): Array<T
|
||||
return data.sort((a, b) => (a[field] === b[field] ? 0 : (a[field] > b[field] ? 1 : -1)) * sign);
|
||||
}
|
||||
|
||||
export class TableDataView<T extends Slick.SlickData> implements Slick.DataProvider<T> {
|
||||
export class TableDataView<T extends Slick.SlickData> implements IDisposableDataProvider<T> {
|
||||
private _data: Array<T>;
|
||||
private _findArray: Array<IFindPosition>;
|
||||
private _findObs: Observable<IFindPosition>;
|
||||
@@ -154,4 +156,10 @@ export class TableDataView<T extends Slick.SlickData> implements Slick.DataProvi
|
||||
get findCount(): number {
|
||||
return types.isUndefinedOrNull(this._findArray) ? 0 : this._findArray.length;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._data = undefined;
|
||||
this._findArray = undefined;
|
||||
this._findObs = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
.carbon-taskbar.monaco-toolbar .monaco-action-bar.animated .actions-container {
|
||||
justify-content: flex-start;
|
||||
padding-left: 15px;
|
||||
padding: 5px 5px 5px 15px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
|
||||
1
src/sql/media/icons/check.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="-2 -2 16 16" enable-background="new -2 -2 16 16"><polygon fill="#424242" points="9,0 4.5,9 3,6 0,6 3,12 6,12 12,0"/></svg>
|
||||
|
After Width: | Height: | Size: 194 B |
1
src/sql/media/icons/check_inverse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="-2 -2 16 16" enable-background="new -2 -2 16 16"><polygon fill="#C5C5C5" points="9,0 4.5,9 3,6 0,6 3,12 6,12 12,0"/></svg>
|
||||
|
After Width: | Height: | Size: 194 B |
@@ -227,6 +227,51 @@
|
||||
background: url('unpin.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs .sql.icon.pause {
|
||||
background-image: url('pause.svg')
|
||||
}
|
||||
|
||||
.vs-dark .sql.icon.pause,
|
||||
.hc-black .sql.icon.pause {
|
||||
background-image: url('pause_inverse.svg')
|
||||
}
|
||||
|
||||
.vs .sql.icon.continue {
|
||||
background-image: url('continue.svg')
|
||||
}
|
||||
|
||||
.vs-dark .sql.icon.continue,
|
||||
.hc-black .sql.icon.continue {
|
||||
background-image: url('continue_inverse.svg')
|
||||
}
|
||||
|
||||
.vs .sql.icon.checked {
|
||||
background-image: url('check.svg')
|
||||
}
|
||||
|
||||
.vs-dark .sql.icon.checked,
|
||||
.hc-black .sql.icon.checked {
|
||||
background-image: url('check_inverse.svg')
|
||||
}
|
||||
|
||||
.vs .sql.icon.start {
|
||||
background-image: url('start.svg')
|
||||
}
|
||||
|
||||
.vs-dark .sql.icon.start,
|
||||
.hc-black .sql.icon.start {
|
||||
background-image: url('start_inverse.svg')
|
||||
}
|
||||
|
||||
.vs .sql.icon.stop {
|
||||
background-image: url('stop.svg')
|
||||
}
|
||||
|
||||
.vs-dark .sql.icon.stop,
|
||||
.hc-black .sql.icon.stop {
|
||||
background-image: url('stop_inverse.svg')
|
||||
}
|
||||
|
||||
.small {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
1
src/sql/media/icons/continue.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-action-blue{fill:#00539c;}</style></defs><title>continue</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M15.64,8l-7.8,6H2V2H7.84Z"/></g><g id="iconBg"><path class="icon-vs-action-blue" d="M3,3H5V13H3ZM7.5,3V13L14,8Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 502 B |
1
src/sql/media/icons/continue_inverse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-action-blue{fill:#75beff;}</style></defs><title>continue</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M15.64,8l-7.8,6H2V2H7.84Z"/></g><g id="iconBg"><path class="icon-vs-action-blue" d="M3,3H5V13H3ZM7.5,3V13L14,8Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 502 B |
1
src/sql/media/icons/pause.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-action-blue{fill:#00539c;}</style></defs><title>pause</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M13,2V14H8.5V2ZM3,14H7.5V2H3Z"/></g><g id="iconBg"><path class="icon-vs-action-blue" d="M4,3H6.5V13H4ZM9.5,3V13H12V3Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 505 B |
1
src/sql/media/icons/pause_inverse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-action-blue{fill:#75beff;}</style></defs><title>pause</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M13,2V14H8.5V2ZM3,14H7.5V2H3Z"/></g><g id="iconBg"><path class="icon-vs-action-blue" d="M4,3H6.5V13H4ZM9.5,3V13H12V3Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 505 B |
1
src/sql/media/icons/start.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-action-green{fill:#388a34;}</style></defs><title>continue</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14.334,8,3.667,16H3V0h.667Z"/></g><g id="iconBg"><path class="icon-vs-action-green" d="M4,1.5v13L12.667,8,4,1.5Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 505 B |
1
src/sql/media/icons/start_inverse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-action-green{fill:#89d185;}</style></defs><title>continue</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14.334,8,3.667,16H3V0h.667Z"/></g><g id="iconBg"><path class="icon-vs-action-green" d="M4,1.5v13L12.667,8,4,1.5Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 505 B |
1
src/sql/media/icons/stop.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-action-red{fill:#a1260d;}</style></defs><title>stop</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14,2V14H2V2Z"/></g><g id="iconBg"><path class="icon-vs-action-red" d="M13,3V13H3V3Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 470 B |
1
src/sql/media/icons/stop_inverse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-action-red{fill:#f48771;}</style></defs><title>stop</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14,2V14H2V2Z"/></g><g id="iconBg"><path class="icon-vs-action-red" d="M13,3V13H3V3Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 470 B |
@@ -26,7 +26,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService
|
||||
export class ClearRecentConnectionsAction extends Action {
|
||||
|
||||
public static ID = 'clearRecentConnectionsAction';
|
||||
public static LABEL = nls.localize('ClearRecentlyUsedLabel', 'Clear Recent Connections List');
|
||||
public static LABEL = nls.localize('ClearRecentlyUsedLabel', 'Clear List');
|
||||
public static ICON = 'search-action clear-search-results';
|
||||
|
||||
private _onRecentConnectionsRemoved = new Emitter<void>();
|
||||
@@ -83,7 +83,7 @@ export class ClearRecentConnectionsAction extends Action {
|
||||
{ key: nls.localize('connectionAction.no', 'No'), value: false }
|
||||
];
|
||||
|
||||
self._quickOpenService.pick(choices.map(x => x.key), { placeHolder: nls.localize('ClearRecentlyUsedLabel', 'Clear Recent Connections List'), ignoreFocusLost: true }).then((choice) => {
|
||||
self._quickOpenService.pick(choices.map(x => x.key), { placeHolder: nls.localize('ClearRecentlyUsedLabel', 'Clear List'), ignoreFocusLost: true }).then((choice) => {
|
||||
let confirm = choices.find(x => x.key === choice);
|
||||
resolve(confirm && confirm.value);
|
||||
});
|
||||
|
||||
@@ -38,7 +38,7 @@ export class AdvancedPropertiesController {
|
||||
public get advancedDialog() {
|
||||
if (!this._advancedDialog) {
|
||||
this._advancedDialog = this._instantiationService.createInstance(
|
||||
OptionsDialog, localize('connectionAdvancedProperties', 'Advanced properties'), TelemetryKeys.ConnectionAdvancedProperties, { hasBackButton: true });
|
||||
OptionsDialog, localize('connectionAdvancedProperties', 'Advanced Properties'), TelemetryKeys.ConnectionAdvancedProperties, { hasBackButton: true });
|
||||
this._advancedDialog.cancelLabel = localize('advancedProperties.discard', 'Discard');
|
||||
this._advancedDialog.onCloseEvent(() => this._onCloseAdvancedProperties());
|
||||
this._advancedDialog.onOk(() => this.handleOnOk());
|
||||
|
||||
@@ -37,6 +37,7 @@ import * as styler from 'vs/platform/theme/common/styler';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
|
||||
export interface OnShowUIResponse {
|
||||
selectedProviderType: string;
|
||||
@@ -49,7 +50,7 @@ export class ConnectionDialogWidget extends Modal {
|
||||
private _noRecentConnectionBuilder: Builder;
|
||||
private _savedConnectionBuilder: Builder;
|
||||
private _noSavedConnectionBuilder: Builder;
|
||||
private _dividerBuilder: Builder;
|
||||
private _connectionDetailTitle: Builder;
|
||||
private _connectButton: Button;
|
||||
private _closeButton: Button;
|
||||
private _providerTypeSelectBox: SelectBox;
|
||||
@@ -143,7 +144,7 @@ export class ConnectionDialogWidget extends Modal {
|
||||
this._panel = new TabbedPanel(connectionContainer.getHTMLElement());
|
||||
this._recentConnectionTabId = this._panel.pushTab({
|
||||
identifier: 'recent_connection',
|
||||
title: localize('recentConnectionTitle', 'Recent connections'),
|
||||
title: localize('recentConnectionTitle', 'Recent Connections'),
|
||||
view: {
|
||||
render: c => {
|
||||
recentConnectionTab.appendTo(c);
|
||||
@@ -154,7 +155,7 @@ export class ConnectionDialogWidget extends Modal {
|
||||
|
||||
let savedConnectionTabId = this._panel.pushTab({
|
||||
identifier: 'saved_connection',
|
||||
title: localize('savedConnectionTitle', 'Saved connections'),
|
||||
title: localize('savedConnectionTitle', 'Saved Connections'),
|
||||
view: {
|
||||
layout: () => { },
|
||||
render: c => {
|
||||
@@ -179,8 +180,9 @@ export class ConnectionDialogWidget extends Modal {
|
||||
}
|
||||
});
|
||||
|
||||
this._bodyBuilder.div({ class: 'Connection-divider' }, (dividerContainer) => {
|
||||
this._dividerBuilder = dividerContainer;
|
||||
this._bodyBuilder.div({ class: 'connection-details-title' }, (dividerContainer) => {
|
||||
this._connectionDetailTitle = dividerContainer;
|
||||
this._connectionDetailTitle.text(localize('connectionDetailsTitle', 'Connection Details'));
|
||||
});
|
||||
|
||||
this._bodyBuilder.div({ class: 'connection-type' }, (modelTableContent) => {
|
||||
@@ -217,10 +219,12 @@ export class ConnectionDialogWidget extends Modal {
|
||||
private updateTheme(theme: IColorTheme): void {
|
||||
let borderColor = theme.getColor(contrastBorder);
|
||||
let border = borderColor ? borderColor.toString() : null;
|
||||
if (this._dividerBuilder) {
|
||||
this._dividerBuilder.style('border-top-width', border ? '1px' : null);
|
||||
this._dividerBuilder.style('border-top-style', border ? 'solid' : null);
|
||||
this._dividerBuilder.style('border-top-color', border);
|
||||
let backgroundColor = theme.getColor(SIDE_BAR_BACKGROUND);
|
||||
if (this._connectionDetailTitle) {
|
||||
this._connectionDetailTitle.style('border-width', border ? '1px 0px' : null);
|
||||
this._connectionDetailTitle.style('border-style', border ? 'solid none' : null);
|
||||
this._connectionDetailTitle.style('border-color', border);
|
||||
this._connectionDetailTitle.style('background-color', backgroundColor ? backgroundColor.toString() : null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,17 +281,13 @@ export class ConnectionDialogWidget extends Modal {
|
||||
|
||||
private createRecentConnectionList(): void {
|
||||
this._recentConnectionBuilder.div({ class: 'connection-recent-content' }, (recentConnectionContainer) => {
|
||||
let recentHistoryLabel = localize('recentHistory', 'Recent history');
|
||||
recentConnectionContainer.div({ class: 'recent-titles-container' }, (container) => {
|
||||
container.div({ class: 'connection-history-label' }, (recentTitle) => {
|
||||
recentTitle.text(recentHistoryLabel);
|
||||
});
|
||||
container.div({ class: 'connection-history-actions' }, (actionsContainer) => {
|
||||
this._actionbar = this._register(new ActionBar(actionsContainer.getHTMLElement(), { animated: false }));
|
||||
let clearAction = this._instantiationService.createInstance(ClearRecentConnectionsAction, ClearRecentConnectionsAction.ID, ClearRecentConnectionsAction.LABEL);
|
||||
clearAction.useConfirmationMessage = true;
|
||||
clearAction.onRecentConnectionsRemoved(() => this.open(false));
|
||||
this._actionbar.push(clearAction, { icon: true, label: false });
|
||||
this._actionbar.push(clearAction, { icon: true, label: true });
|
||||
});
|
||||
});
|
||||
recentConnectionContainer.div({ class: 'server-explorer-viewlet' }, (divContainer: Builder) => {
|
||||
|
||||
@@ -9,25 +9,35 @@
|
||||
}
|
||||
|
||||
.connection-input {
|
||||
padding-right:8px;
|
||||
width: 200px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.connection-dialog {
|
||||
height: calc(100% - 20px);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.connection-dialog .tabbedPanel {
|
||||
border-top-color: transparent;
|
||||
height: calc(100% - 350px);
|
||||
display: block;
|
||||
flex: 1 1;
|
||||
min-height: 120px;
|
||||
overflow: hidden;
|
||||
margin: 0px 11px;
|
||||
}
|
||||
.connection-dialog .tabBody {
|
||||
overflow: hidden;
|
||||
flex: 1 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.connection-recent, .connection-saved {
|
||||
margin: 15px;
|
||||
height: calc(100% - 60px);
|
||||
margin: 5px;
|
||||
flex: 1 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@@ -45,6 +55,8 @@
|
||||
.recent-titles-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 5px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.connection-provider-info {
|
||||
@@ -53,7 +65,13 @@
|
||||
}
|
||||
|
||||
.connection-recent-content {
|
||||
height: calc(100% - 20px);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.connection-recent-content .server-explorer-viewlet {
|
||||
flex: 1 1;
|
||||
}
|
||||
|
||||
.connection-table-content {
|
||||
@@ -66,8 +84,9 @@
|
||||
}
|
||||
|
||||
.connection-type {
|
||||
margin: 15px;
|
||||
overflow-y: hidden;
|
||||
flex: 0 0 auto;
|
||||
overflow: hidden;
|
||||
margin: 0px 13px;
|
||||
}
|
||||
|
||||
.connection-dialog .connection-history-actions .action-label.icon {
|
||||
@@ -76,8 +95,9 @@
|
||||
line-height: 20px;
|
||||
min-width: 20px;
|
||||
background-size: 16px;
|
||||
background-position: center center;
|
||||
background-position: 2px center;
|
||||
background-repeat: no-repeat;
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.search-action.clear-search-results {
|
||||
@@ -87,4 +107,11 @@
|
||||
.vs-dark .search-action.clear-search-results,
|
||||
.hc-black .search-action.clear-search-results {
|
||||
background: url('clear-search-results-dark.svg');
|
||||
}
|
||||
|
||||
.connection-details-title {
|
||||
font-size: 14px;
|
||||
margin: 5px 0px;
|
||||
padding: 5px 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -5,6 +5,5 @@
|
||||
|
||||
.advanced-button {
|
||||
width: 100px;
|
||||
padding-right:8px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import 'vs/css!sql/base/browser/ui/table/media/table';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import * as nls from 'vs/nls';
|
||||
import * as sqlops from 'sqlops';
|
||||
import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnInit } from '@angular/core';
|
||||
import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnInit, OnDestroy } from '@angular/core';
|
||||
import { TabChild } from 'sql/base/browser/ui/panel/tab.component';
|
||||
import { Table } from 'sql/base/browser/ui/table/table';
|
||||
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
|
||||
@@ -41,7 +41,7 @@ export const ROW_HEIGHT: number = 45;
|
||||
templateUrl: decodeURI(require.toUrl('./alertsView.component.html')),
|
||||
providers: [{ provide: TabChild, useExisting: forwardRef(() => AlertsViewComponent) }],
|
||||
})
|
||||
export class AlertsViewComponent extends JobManagementView implements OnInit {
|
||||
export class AlertsViewComponent extends JobManagementView implements OnInit, OnDestroy {
|
||||
|
||||
private columns: Array<Slick.Column<any>> = [
|
||||
{
|
||||
@@ -69,6 +69,7 @@ export class AlertsViewComponent extends JobManagementView implements OnInit {
|
||||
private _isCloud: boolean;
|
||||
private _alertsCacheObject: AlertsCacheObject;
|
||||
|
||||
private _didTabChange: boolean;
|
||||
@ViewChild('jobalertsgrid') _gridEl: ElementRef;
|
||||
|
||||
public alerts: sqlops.AgentAlertInfo[];
|
||||
@@ -86,6 +87,7 @@ export class AlertsViewComponent extends JobManagementView implements OnInit {
|
||||
@Inject(IKeybindingService) keybindingService: IKeybindingService,
|
||||
@Inject(IDashboardService) _dashboardService: IDashboardService) {
|
||||
super(commonService, _dashboardService, contextMenuService, keybindingService, instantiationService);
|
||||
this._didTabChange = false;
|
||||
this._isCloud = commonService.connectionManagementService.connectionInfo.serverInfo.isCloud;
|
||||
let alertsCacheObjectMap = this._jobManagementService.alertsCacheObjectMap;
|
||||
let alertsCache = alertsCacheObjectMap[this._serverName];
|
||||
@@ -102,7 +104,11 @@ export class AlertsViewComponent extends JobManagementView implements OnInit {
|
||||
// set base class elements
|
||||
this._visibilityElement = this._gridEl;
|
||||
this._parentComponent = this._agentViewComponent;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._didTabChange = true;
|
||||
}
|
||||
|
||||
public layout() {
|
||||
let height = dom.getContentHeight(this._gridEl.nativeElement) - 10;
|
||||
@@ -166,8 +172,10 @@ export class AlertsViewComponent extends JobManagementView implements OnInit {
|
||||
// TODO: handle error
|
||||
}
|
||||
this._showProgressWheel = false;
|
||||
if (this.isVisible) {
|
||||
if (this.isVisible && !this._didTabChange) {
|
||||
this._cd.detectChanges();
|
||||
} else if (this._didTabChange) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import 'vs/css!sql/base/browser/ui/table/media/table';
|
||||
import * as sqlops from 'sqlops';
|
||||
import * as nls from 'vs/nls';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnInit } from '@angular/core';
|
||||
import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnInit, OnDestroy } from '@angular/core';
|
||||
import { TabChild } from 'sql/base/browser/ui/panel/tab.component';
|
||||
import { Table } from 'sql/base/browser/ui/table/table';
|
||||
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
|
||||
@@ -47,7 +47,7 @@ export const ROW_HEIGHT: number = 45;
|
||||
providers: [{ provide: TabChild, useExisting: forwardRef(() => JobsViewComponent) }],
|
||||
})
|
||||
|
||||
export class JobsViewComponent extends JobManagementView implements OnInit {
|
||||
export class JobsViewComponent extends JobManagementView implements OnInit, OnDestroy {
|
||||
|
||||
private columns: Array<Slick.Column<any>> = [
|
||||
{
|
||||
@@ -91,6 +91,8 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
|
||||
private jobSchedules: { [jobId: string]: sqlops.AgentJobScheduleInfo[]; } = Object.create(null);
|
||||
public contextAction = NewJobAction;
|
||||
|
||||
private _didTabChange: boolean;
|
||||
|
||||
@ViewChild('jobsgrid') _gridEl: ElementRef;
|
||||
|
||||
constructor(
|
||||
@@ -107,6 +109,7 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
|
||||
@Inject(IDashboardService) _dashboardService: IDashboardService
|
||||
) {
|
||||
super(commonService, _dashboardService, contextMenuService, keybindingService, instantiationService);
|
||||
this._didTabChange = false;
|
||||
let jobCacheObjectMap = this._jobManagementService.jobCacheObjectMap;
|
||||
let jobCache = jobCacheObjectMap[this._serverName];
|
||||
if (jobCache) {
|
||||
@@ -126,6 +129,10 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
|
||||
this._register(this._themeService.onDidColorThemeChange(e => this.updateTheme(e)));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._didTabChange = true;
|
||||
}
|
||||
|
||||
public layout() {
|
||||
let jobsViewToolbar = $('jobsview-component .actionbar-container').get(0);
|
||||
let statusBar = $('.part.statusbar').get(0);
|
||||
@@ -208,8 +215,10 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
|
||||
}
|
||||
|
||||
this._showProgressWheel = false;
|
||||
if (this.isVisible) {
|
||||
if (this.isVisible && !this._didTabChange) {
|
||||
this._cd.detectChanges();
|
||||
} else if (this._didTabChange) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -579,7 +588,7 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
|
||||
private async curateJobHistory(jobs: sqlops.AgentJobInfo[], ownerUri: string) {
|
||||
const self = this;
|
||||
jobs.forEach(async (job) => {
|
||||
await this._jobManagementService.getJobHistory(ownerUri, job.jobId, job.name).then((result) => {
|
||||
await this._jobManagementService.getJobHistory(ownerUri, job.jobId, job.name).then(async(result) => {
|
||||
if (result) {
|
||||
self.jobSteps[job.jobId] = result.steps ? result.steps : [];
|
||||
self.jobAlerts[job.jobId] = result.alerts ? result.alerts : [];
|
||||
@@ -594,7 +603,10 @@ export class JobsViewComponent extends JobManagementView implements OnInit {
|
||||
} else {
|
||||
previousRuns = jobHistories;
|
||||
}
|
||||
self.createJobChart(job.jobId, previousRuns);
|
||||
// dont create the charts if the tab changed
|
||||
if (!self._didTabChange) {
|
||||
self.createJobChart(job.jobId, previousRuns);
|
||||
}
|
||||
if (self._agentViewComponent.expanded.has(job.jobId)) {
|
||||
let lastJobHistory = jobHistories[jobHistories.length - 1];
|
||||
let item = self.dataView.getItemById(job.jobId + '.error');
|
||||
|
||||
@@ -15,7 +15,7 @@ import 'vs/css!sql/base/browser/ui/table/media/table';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import * as nls from 'vs/nls';
|
||||
import * as sqlops from 'sqlops';
|
||||
import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnInit } from '@angular/core';
|
||||
import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Table } from 'sql/base/browser/ui/table/table';
|
||||
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
|
||||
import { IJobManagementService } from 'sql/parts/jobManagement/common/interfaces';
|
||||
@@ -42,7 +42,7 @@ export const ROW_HEIGHT: number = 45;
|
||||
providers: [{ provide: TabChild, useExisting: forwardRef(() => OperatorsViewComponent) }],
|
||||
})
|
||||
|
||||
export class OperatorsViewComponent extends JobManagementView implements OnInit {
|
||||
export class OperatorsViewComponent extends JobManagementView implements OnInit, OnDestroy {
|
||||
|
||||
private columns: Array<Slick.Column<any>> = [
|
||||
{
|
||||
@@ -68,6 +68,7 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit
|
||||
private _isCloud: boolean;
|
||||
private _operatorsCacheObject: OperatorsCacheObject;
|
||||
|
||||
private _didTabChange: boolean;
|
||||
@ViewChild('operatorsgrid') _gridEl: ElementRef;
|
||||
|
||||
public operators: sqlops.AgentOperatorInfo[];
|
||||
@@ -104,6 +105,10 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit
|
||||
this._parentComponent = this._agentViewComponent;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._didTabChange = true;
|
||||
}
|
||||
|
||||
public layout() {
|
||||
let height = dom.getContentHeight(this._gridEl.nativeElement) - 10;
|
||||
if (height < 0) {
|
||||
@@ -169,8 +174,10 @@ export class OperatorsViewComponent extends JobManagementView implements OnInit
|
||||
// TODO: handle error
|
||||
}
|
||||
this._showProgressWheel = false;
|
||||
if (this.isVisible) {
|
||||
if (this.isVisible && !this._didTabChange) {
|
||||
this._cd.detectChanges();
|
||||
} else if (this._didTabChange) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import 'vs/css!sql/base/browser/ui/table/media/table';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import * as sqlops from 'sqlops';
|
||||
import * as nls from 'vs/nls';
|
||||
import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnInit } from '@angular/core';
|
||||
import { Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Table } from 'sql/base/browser/ui/table/table';
|
||||
import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.component';
|
||||
import { IJobManagementService } from 'sql/parts/jobManagement/common/interfaces';
|
||||
@@ -42,7 +42,7 @@ export const ROW_HEIGHT: number = 45;
|
||||
providers: [{ provide: TabChild, useExisting: forwardRef(() => ProxiesViewComponent) }],
|
||||
})
|
||||
|
||||
export class ProxiesViewComponent extends JobManagementView implements OnInit {
|
||||
export class ProxiesViewComponent extends JobManagementView implements OnInit, OnDestroy {
|
||||
|
||||
private NewProxyText: string = nls.localize('jobProxyToolbar-NewItem', "New Proxy");
|
||||
private RefreshText: string = nls.localize('jobProxyToolbar-Refresh', "Refresh");
|
||||
@@ -75,6 +75,7 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit {
|
||||
public proxies: sqlops.AgentProxyInfo[];
|
||||
public readonly contextAction = NewProxyAction;
|
||||
|
||||
private _didTabChange: boolean;
|
||||
@ViewChild('proxiesgrid') _gridEl: ElementRef;
|
||||
|
||||
constructor(
|
||||
@@ -108,6 +109,10 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit {
|
||||
this._parentComponent = this._agentViewComponent;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._didTabChange = true;
|
||||
}
|
||||
|
||||
public layout() {
|
||||
let height = dom.getContentHeight(this._gridEl.nativeElement) - 10;
|
||||
if (height < 0) {
|
||||
@@ -172,8 +177,10 @@ export class ProxiesViewComponent extends JobManagementView implements OnInit {
|
||||
// TODO: handle error
|
||||
}
|
||||
this._showProgressWheel = false;
|
||||
if (this.isVisible) {
|
||||
if (this.isVisible && !this._didTabChange) {
|
||||
this._cd.detectChanges();
|
||||
} else if (this._didTabChange) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import { TreeNode } from 'sql/parts/objectExplorer/common/treeNode';
|
||||
import { NodeType } from 'sql/parts/objectExplorer/common/nodeType';
|
||||
import { ConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
|
||||
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
||||
import { NewProfilerAction } from 'sql/parts/profiler/contrib/profilerActions';
|
||||
import { TreeUpdateUtils } from 'sql/parts/objectExplorer/viewlet/treeUpdateUtils';
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { MenuId, IMenuService } from 'vs/platform/actions/common/actions';
|
||||
@@ -90,9 +89,11 @@ export class ServerTreeActionProvider extends ContributableActionProvider {
|
||||
* Return actions for connection elements
|
||||
*/
|
||||
public getConnectionActions(tree: ITree, profile: ConnectionProfile): IAction[] {
|
||||
let node = new TreeNode(NodeType.Server, '', false, '', '', '', undefined, undefined, undefined, undefined);
|
||||
return this.getAllActions({
|
||||
tree: tree,
|
||||
profile: profile
|
||||
profile: profile,
|
||||
treeNode: node
|
||||
}, (context) => this.getBuiltinConnectionActions(context));
|
||||
}
|
||||
|
||||
@@ -125,10 +126,6 @@ export class ServerTreeActionProvider extends ContributableActionProvider {
|
||||
actions.push(this._instantiationService.createInstance(DeleteConnectionAction, DeleteConnectionAction.ID, DeleteConnectionAction.DELETE_CONNECTION_LABEL, context.profile));
|
||||
actions.push(this._instantiationService.createInstance(RefreshAction, RefreshAction.ID, RefreshAction.LABEL, context.tree, context.profile));
|
||||
|
||||
if (process.env['VSCODE_DEV'] && constants.MssqlProviderId === context.profile.providerName) {
|
||||
actions.push(this._instantiationService.createInstance(OEAction, NewProfilerAction.ID, NewProfilerAction.LABEL));
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ export class TreeCreationUtils {
|
||||
|
||||
return new Tree(treeContainer, { dataSource, renderer, controller, dnd, filter, sorter, accessibilityProvider },
|
||||
{
|
||||
indentPixels: 10,
|
||||
twistiePixels: 20,
|
||||
indentPixels: 0,
|
||||
twistiePixels: 0,
|
||||
ariaLabel: nls.localize('treeAriaLabel', "Recent Connections")
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiati
|
||||
import * as nls from 'vs/nls';
|
||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IConnectionManagementService, IConnectionDialogService} from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IObjectExplorerService } from '../../objectExplorer/common/objectExplorerService';
|
||||
import { ProfilerInput } from 'sql/parts/profiler/editor/profilerInput';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
@@ -18,6 +18,10 @@ import { IProfilerService } from '../service/interfaces';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { KeyCode, KeyMod } from 'vs/editor/editor.api';
|
||||
import { ProfilerEditor } from '../editor/profilerEditor';
|
||||
import { ObjectExplorerActionsContext } from 'sql/parts/objectExplorer/viewlet/objectExplorerActions';
|
||||
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
||||
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
|
||||
import { mssqlProviderName } from 'sql/parts/connection/common/constants';
|
||||
|
||||
// Contribute Global Actions
|
||||
const category = nls.localize('profilerCategory', "Profiler");
|
||||
@@ -30,15 +34,45 @@ const newProfilerSchema: IJSONSchema = {
|
||||
|
||||
CommandsRegistry.registerCommand({
|
||||
id: 'profiler.newProfiler',
|
||||
handler: (accessor: ServicesAccessor) => {
|
||||
let editorService: IEditorService = accessor.get(IEditorService);
|
||||
handler: (accessor: ServicesAccessor, ...args: any[]) => {
|
||||
let connectionProfile: ConnectionProfile = undefined;
|
||||
let instantiationService: IInstantiationService = accessor.get(IInstantiationService);
|
||||
let editorService: IEditorService = accessor.get(IEditorService);
|
||||
let connectionService: IConnectionManagementService = accessor.get(IConnectionManagementService);
|
||||
let objectExplorerService: IObjectExplorerService = accessor.get(IObjectExplorerService);
|
||||
let connectionDialogService: IConnectionDialogService = accessor.get(IConnectionDialogService);
|
||||
let capabilitiesService: ICapabilitiesService = accessor.get(ICapabilitiesService);
|
||||
|
||||
let connectionProfile = TaskUtilities.getCurrentGlobalConnection(objectExplorerService, connectionService, editorService);
|
||||
let profilerInput = instantiationService.createInstance(ProfilerInput, connectionProfile);
|
||||
return editorService.openEditor(profilerInput, { pinned: true }, ACTIVE_GROUP).then(() => TPromise.as(true));
|
||||
// If a context is available if invoked from the context menu, we will use the connection profiler of the server node
|
||||
if (args && args.length === 1 && args[0] && args[0] instanceof ObjectExplorerActionsContext) {
|
||||
let context = args[0] as ObjectExplorerActionsContext;
|
||||
connectionProfile = ConnectionProfile.fromIConnectionProfile(capabilitiesService, context.connectionProfile);
|
||||
}
|
||||
else {
|
||||
// No context available, we will try to get the current global active connection
|
||||
connectionProfile = TaskUtilities.getCurrentGlobalConnection(objectExplorerService, connectionService, editorService) as ConnectionProfile;
|
||||
}
|
||||
|
||||
let promise;
|
||||
if (connectionProfile) {
|
||||
promise = connectionService.connectIfNotConnected(connectionProfile);
|
||||
} else {
|
||||
// if still no luck, we will open the Connection dialog and let user connect to a server
|
||||
promise = connectionDialogService.openDialogAndWait(connectionService, { connectionType: 1, providers: [mssqlProviderName] }).then((profile) => {
|
||||
connectionProfile = profile as ConnectionProfile;
|
||||
});
|
||||
}
|
||||
|
||||
return promise.then(() => {
|
||||
if (!connectionProfile) {
|
||||
connectionProfile = TaskUtilities.getCurrentGlobalConnection(objectExplorerService, connectionService, editorService) as ConnectionProfile;
|
||||
}
|
||||
|
||||
if (connectionProfile && connectionProfile.providerName === mssqlProviderName) {
|
||||
let profilerInput = instantiationService.createInstance(ProfilerInput, connectionProfile);
|
||||
editorService.openEditor(profilerInput, { pinned: true }, ACTIVE_GROUP).then(() => TPromise.as(true));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import { IProfilerController } from 'sql/parts/profiler/editor/controller/interf
|
||||
import { ProfilerInput } from 'sql/parts/profiler/editor/profilerInput';
|
||||
import { BaseActionContext } from 'sql/workbench/common/actions';
|
||||
import { Task } from 'sql/platform/tasks/common/tasks';
|
||||
import { ObjectExplorerActionsContext } from 'sql/parts/objectExplorer/viewlet/objectExplorerActions';
|
||||
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
||||
import { IConnectionManagementService, IConnectionCompletionOptions, ConnectionType } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
@@ -25,8 +24,11 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
export class ProfilerConnect extends Action {
|
||||
private static readonly ConnectText = nls.localize('profilerAction.connect', 'Connect');
|
||||
private static readonly DisconnectText = nls.localize('profilerAction.disconnect', 'Disconnect');
|
||||
|
||||
public static ID = 'profiler.connect';
|
||||
public static LABEL = nls.localize('profiler.connect', "Connect");
|
||||
public static LABEL = ProfilerConnect.ConnectText;
|
||||
|
||||
private _connected: boolean = false;
|
||||
|
||||
@@ -59,7 +61,7 @@ export class ProfilerConnect extends Action {
|
||||
public set connected(value: boolean) {
|
||||
this._connected = value;
|
||||
this._setClass(value ? 'disconnect' : 'connect');
|
||||
this._setLabel(value ? nls.localize('profilerAction.disconnect', 'Disconnect') : nls.localize('profilerAction.connect', "Connect"));
|
||||
this._setLabel(value ? ProfilerConnect.DisconnectText : ProfilerConnect.ConnectText);
|
||||
}
|
||||
|
||||
public get connected(): boolean {
|
||||
@@ -75,7 +77,7 @@ export class ProfilerStart extends Action {
|
||||
id: string, label: string,
|
||||
@IProfilerService private _profilerService: IProfilerService
|
||||
) {
|
||||
super(id, label, 'start');
|
||||
super(id, label, 'sql start');
|
||||
}
|
||||
|
||||
public run(input: ProfilerInput): TPromise<boolean> {
|
||||
@@ -86,7 +88,7 @@ export class ProfilerStart extends Action {
|
||||
|
||||
export class ProfilerCreate extends Action {
|
||||
public static ID = 'profiler.create';
|
||||
public static LABEL = nls.localize('create', "Create");
|
||||
public static LABEL = nls.localize('create', "New Session");
|
||||
|
||||
constructor(
|
||||
id: string, label: string,
|
||||
@@ -105,8 +107,13 @@ export class ProfilerCreate extends Action {
|
||||
}
|
||||
|
||||
export class ProfilerPause extends Action {
|
||||
private static readonly PauseText = nls.localize('profilerAction.pauseCapture', 'Pause');
|
||||
private static readonly ResumeText = nls.localize('profilerAction.resumeCapture', 'Resume');
|
||||
private static readonly PauseCssClass = 'sql pause';
|
||||
private static readonly ResumeCssClass = 'sql continue';
|
||||
|
||||
public static ID = 'profiler.pause';
|
||||
public static LABEL = nls.localize('profiler.capture', "Pause Capture");
|
||||
public static LABEL = ProfilerPause.PauseText;
|
||||
|
||||
private _paused: boolean = false;
|
||||
|
||||
@@ -114,7 +121,7 @@ export class ProfilerPause extends Action {
|
||||
id: string, label: string,
|
||||
@IProfilerService private _profilerService: IProfilerService
|
||||
) {
|
||||
super(id, label, 'stop');
|
||||
super(id, label, ProfilerPause.PauseCssClass);
|
||||
}
|
||||
|
||||
public run(input: ProfilerInput): TPromise<boolean> {
|
||||
@@ -127,8 +134,8 @@ export class ProfilerPause extends Action {
|
||||
|
||||
public set paused(value: boolean) {
|
||||
this._paused = value;
|
||||
this._setClass(value ? 'start' : 'stop');
|
||||
this._setLabel(value ? nls.localize('profilerAction.resumeCapture', "Resume Capture") : nls.localize('profilerAction.pauseCapture', "Pause Capture"));
|
||||
this._setClass(value ? ProfilerPause.ResumeCssClass : ProfilerPause.PauseCssClass);
|
||||
this._setLabel(value ? ProfilerPause.ResumeText : ProfilerPause.PauseText);
|
||||
}
|
||||
|
||||
public get paused(): boolean {
|
||||
@@ -144,7 +151,7 @@ export class ProfilerStop extends Action {
|
||||
id: string, label: string,
|
||||
@IProfilerService private _profilerService: IProfilerService
|
||||
) {
|
||||
super(id, label, 'stop');
|
||||
super(id, label, 'sql stop');
|
||||
}
|
||||
|
||||
public run(input: ProfilerInput): TPromise<boolean> {
|
||||
@@ -167,16 +174,21 @@ export class ProfilerClear extends Action {
|
||||
}
|
||||
|
||||
export class ProfilerAutoScroll extends Action {
|
||||
private static readonly AutoScrollOnText = nls.localize('profilerAction.autoscrollOn', 'Auto Scroll: On');
|
||||
private static readonly AutoScrollOffText = nls.localize('profilerAction.autoscrollOff', 'Auto Scroll: Off');
|
||||
private static readonly CheckedCssClass = 'sql checked';
|
||||
|
||||
public static ID = 'profiler.autoscroll';
|
||||
public static LABEL = nls.localize('profiler.autoscrollOn', "Auto Scroll: On");
|
||||
public static LABEL = ProfilerAutoScroll.AutoScrollOnText;
|
||||
|
||||
constructor(id: string, label: string) {
|
||||
super(id, label);
|
||||
super(id, label, ProfilerAutoScroll.CheckedCssClass);
|
||||
}
|
||||
|
||||
run(input: ProfilerInput): TPromise<boolean> {
|
||||
this.checked = !this.checked;
|
||||
this._setLabel(this.checked ? nls.localize('profilerAction.autoscrollOn', "Auto Scroll: On") : nls.localize('profilerAction.autoscrollOff', "Auto Scroll: Off"));
|
||||
this._setLabel(this.checked ? ProfilerAutoScroll.AutoScrollOnText : ProfilerAutoScroll.AutoScrollOffText);
|
||||
this._setClass(this.checked ? ProfilerAutoScroll.CheckedCssClass : '');
|
||||
input.state.change({ autoscroll: this.checked });
|
||||
return TPromise.as(true);
|
||||
}
|
||||
@@ -256,7 +268,7 @@ export class ProfilerFindPrevious implements IEditorAction {
|
||||
|
||||
export class NewProfilerAction extends Task {
|
||||
public static readonly ID = 'profiler.newProfiler';
|
||||
public static readonly LABEL = nls.localize('profilerAction.newProfiler', 'New Profiler');
|
||||
public static readonly LABEL = nls.localize('profilerAction.newProfiler', 'Launch Profiler');
|
||||
public static readonly ICON = 'profile';
|
||||
|
||||
private _connectionProfile: ConnectionProfile;
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { ProfilerInput } from 'sql/parts/profiler/editor/profilerInput';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import * as nls from 'vs/nls';
|
||||
|
||||
import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
|
||||
export class GlobalNewProfilerAction extends Action {
|
||||
public static ID = 'explorer.newProfiler';
|
||||
public static LABEL = nls.localize('profilerWorkbenchAction.newProfiler', "New Profiler");
|
||||
|
||||
constructor(
|
||||
id: string, label: string,
|
||||
@IEditorService private _editorService: IEditorService,
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
@IConnectionManagementService private _connectionService: IConnectionManagementService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(context?: any): TPromise<boolean> {
|
||||
// TODO: for test-only, grab the first MSSQL active connection for the profiler session
|
||||
// TODO: when finishing the feature the connection should come from the launch context
|
||||
let connectionProfile: IConnectionProfile;
|
||||
if (context && context.connectionProfile) {
|
||||
connectionProfile = context.connectionProfile;
|
||||
} else {
|
||||
let activeConnections = this._connectionService.getActiveConnections();
|
||||
if (activeConnections) {
|
||||
for (let i = 0; i < activeConnections.length; ++i) {
|
||||
if (activeConnections[i].providerName === 'MSSQL') {
|
||||
connectionProfile = activeConnections[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let profilerInput = this._instantiationService.createInstance(ProfilerInput, connectionProfile);
|
||||
return this._editorService.openEditor(profilerInput, { pinned: true }, ACTIVE_GROUP).then(() => TPromise.as(true));
|
||||
}
|
||||
}
|
||||
@@ -122,7 +122,6 @@ export class ProfilerEditor extends BaseEditor {
|
||||
private _viewTemplates: Array<IProfilerViewTemplate>;
|
||||
private _sessionSelector: SelectBox;
|
||||
private _sessionsList: Array<string>;
|
||||
private _connectionInfoText: HTMLElement;
|
||||
|
||||
// Actions
|
||||
private _connectAction: Actions.ProfilerConnect;
|
||||
@@ -211,6 +210,7 @@ export class ProfilerEditor extends BaseEditor {
|
||||
|
||||
this._viewTemplates = this._profilerService.getViewTemplates();
|
||||
this._viewTemplateSelector = new SelectBox(this._viewTemplates.map(i => i.name), 'Standard View', this._contextViewService);
|
||||
this._viewTemplateSelector.setAriaLabel(nls.localize('profiler.viewSelectAccessibleName', 'Select View'));
|
||||
this._register(this._viewTemplateSelector.onDidSelect(e => {
|
||||
if (this.input) {
|
||||
this.input.viewTemplate = this._viewTemplates.find(i => i.name === e.selected);
|
||||
@@ -223,6 +223,7 @@ export class ProfilerEditor extends BaseEditor {
|
||||
|
||||
this._sessionsList = [''];
|
||||
this._sessionSelector = new SelectBox(this._sessionsList, '', this._contextViewService);
|
||||
this._sessionSelector.setAriaLabel(nls.localize('profiler.sessionSelectAccessibleName', 'Select Session'));
|
||||
this._register(this._sessionSelector.onDidSelect(e => {
|
||||
if (this.input) {
|
||||
this.input.sessionName = e.selected;
|
||||
@@ -233,32 +234,36 @@ export class ProfilerEditor extends BaseEditor {
|
||||
sessionsContainer.style.paddingRight = '5px';
|
||||
this._sessionSelector.render(sessionsContainer);
|
||||
|
||||
this._connectionInfoText = document.createElement('div');
|
||||
this._connectionInfoText.style.paddingRight = '5px';
|
||||
this._connectionInfoText.innerText = '';
|
||||
this._connectionInfoText.style.textAlign = 'center';
|
||||
this._connectionInfoText.style.display = 'flex';
|
||||
this._connectionInfoText.style.alignItems = 'center';
|
||||
|
||||
this._register(attachSelectBoxStyler(this._viewTemplateSelector, this.themeService));
|
||||
this._register(attachSelectBoxStyler(this._sessionSelector, this.themeService));
|
||||
|
||||
this._actionBar.setContent([
|
||||
{ action: this._startAction },
|
||||
{ action: this._stopAction },
|
||||
{ element: sessionsContainer },
|
||||
{ action: this._createAction },
|
||||
{ element: Taskbar.createTaskbarSeparator() },
|
||||
{ element: this._createTextElement(nls.localize('profiler.sessionSelectLabel', 'Select Session:')) },
|
||||
{ element: sessionsContainer },
|
||||
{ action: this._startAction },
|
||||
{ action: this._stopAction },
|
||||
{ action: this._pauseAction },
|
||||
{ action: this._autoscrollAction },
|
||||
{ action: this._instantiationService.createInstance(Actions.ProfilerClear, Actions.ProfilerClear.ID, Actions.ProfilerClear.LABEL) },
|
||||
{ element: Taskbar.createTaskbarSeparator() },
|
||||
{ element: this._createTextElement(nls.localize('profiler.viewSelectLabel', 'Select View:')) },
|
||||
{ element: viewTemplateContainer },
|
||||
{ element: Taskbar.createTaskbarSeparator() },
|
||||
{ element: this._connectionInfoText }
|
||||
{ action: this._autoscrollAction },
|
||||
{ action: this._instantiationService.createInstance(Actions.ProfilerClear, Actions.ProfilerClear.ID, Actions.ProfilerClear.LABEL) }
|
||||
]);
|
||||
}
|
||||
|
||||
private _createTextElement(text: string): HTMLDivElement {
|
||||
let textElement = document.createElement('div');
|
||||
textElement.style.paddingRight = '10px';
|
||||
textElement.innerText = text;
|
||||
textElement.style.textAlign = 'center';
|
||||
textElement.style.display = 'flex';
|
||||
textElement.style.alignItems = 'center';
|
||||
return textElement;
|
||||
}
|
||||
|
||||
private _createProfilerTable(): HTMLElement {
|
||||
let profilerTableContainer = document.createElement('div');
|
||||
profilerTableContainer.className = 'profiler-table monaco-editor';
|
||||
@@ -417,7 +422,6 @@ export class ProfilerEditor extends BaseEditor {
|
||||
autoscroll: true,
|
||||
isPanelCollapsed: true
|
||||
});
|
||||
this._connectionInfoText.innerText = input.connectionName;
|
||||
this._profilerTableEditor.updateState();
|
||||
this._splitView.layout();
|
||||
this._profilerTableEditor.focus();
|
||||
@@ -464,34 +468,16 @@ export class ProfilerEditor extends BaseEditor {
|
||||
this._connectAction.connected = this.input.state.isConnected;
|
||||
|
||||
if (this.input.state.isConnected) {
|
||||
|
||||
this._updateToolbar();
|
||||
this._sessionSelector.enable();
|
||||
this._profilerService.getXEventSessions(this.input.id).then((r) => {
|
||||
// set undefined result to empty list
|
||||
if (!r) {
|
||||
r = [];
|
||||
}
|
||||
|
||||
this._sessionSelector.setOptions(r);
|
||||
this._sessionsList = r;
|
||||
if ((this.input.sessionName === undefined || this.input.sessionName === '') && this._sessionsList.length > 0) {
|
||||
let sessionIndex: number = 0;
|
||||
let uiState = this._profilerService.getSessionViewState(this.input.id);
|
||||
if (uiState && uiState.previousSessionName) {
|
||||
sessionIndex = this._sessionsList.indexOf(uiState.previousSessionName);
|
||||
} else {
|
||||
this._profilerService.launchCreateSessionDialog(this.input);
|
||||
}
|
||||
// Launch the create session dialog if openning a new window.
|
||||
let uiState = this._profilerService.getSessionViewState(this.input.id);
|
||||
let previousSessionName = uiState && uiState.previousSessionName;
|
||||
if (!this.input.sessionName && !previousSessionName) {
|
||||
this._profilerService.launchCreateSessionDialog(this.input);
|
||||
}
|
||||
|
||||
if (sessionIndex < 0) {
|
||||
sessionIndex = 0;
|
||||
}
|
||||
|
||||
this.input.sessionName = this._sessionsList[sessionIndex];
|
||||
this._sessionSelector.selectWithOptionName(this.input.sessionName);
|
||||
}
|
||||
});
|
||||
this._updateSessionSelector(previousSessionName);
|
||||
} else {
|
||||
this._startAction.enabled = false;
|
||||
this._stopAction.enabled = false;
|
||||
@@ -517,23 +503,35 @@ export class ProfilerEditor extends BaseEditor {
|
||||
}
|
||||
if (this.input.state.isStopped) {
|
||||
this._updateToolbar();
|
||||
this._sessionSelector.enable();
|
||||
this._profilerService.getXEventSessions(this.input.id).then((r) => {
|
||||
// set undefined result to empty list
|
||||
if (!r) {
|
||||
r = [];
|
||||
}
|
||||
|
||||
this._sessionsList = r;
|
||||
this._sessionSelector.setOptions(r);
|
||||
if ((this.input.sessionName === undefined || this.input.sessionName === '') && this._sessionsList.length > 0) {
|
||||
this.input.sessionName = this._sessionsList[0];
|
||||
}
|
||||
});
|
||||
this._updateSessionSelector();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _updateSessionSelector(previousSessionName: string = undefined) {
|
||||
this._sessionSelector.enable();
|
||||
this._profilerService.getXEventSessions(this.input.id).then((r) => {
|
||||
if (!r) {
|
||||
r = [];
|
||||
}
|
||||
|
||||
this._sessionSelector.setOptions(r);
|
||||
this._sessionsList = r;
|
||||
if (this._sessionsList.length > 0) {
|
||||
if (!this.input.sessionName) {
|
||||
this.input.sessionName = previousSessionName;
|
||||
}
|
||||
|
||||
if (this._sessionsList.indexOf(this.input.sessionName) === -1) {
|
||||
this.input.sessionName = this._sessionsList[0];
|
||||
}
|
||||
|
||||
this._sessionSelector.selectWithOptionName(this.input.sessionName);
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private _updateToolbar(): void {
|
||||
this._startAction.enabled = !this.input.state.isRunning && !this.input.state.isPaused && this.input.state.isConnected;
|
||||
this._createAction.enabled = !this.input.state.isRunning && !this.input.state.isPaused && this.input.state.isConnected;
|
||||
|
||||
@@ -12,7 +12,7 @@ import * as sqlops from 'sqlops';
|
||||
import * as nls from 'vs/nls';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { EditorInput } from 'vs/workbench/common/editor';
|
||||
import { EditorInput, ConfirmResult } from 'vs/workbench/common/editor';
|
||||
import { IEditorModel } from 'vs/platform/editor/common/editor';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
@@ -22,6 +22,7 @@ import { IDialogService, IConfirmation, IConfirmationResult } from 'vs/platform/
|
||||
import { escape } from 'sql/base/common/strings';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
|
||||
export class ProfilerInput extends EditorInput implements IProfilerSession {
|
||||
|
||||
@@ -41,7 +42,7 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
||||
public onColumnsChanged: Event<Slick.Column<Slick.SlickData>[]> = this._onColumnsChanged.event;
|
||||
|
||||
constructor(
|
||||
private _connection: IConnectionProfile,
|
||||
public connection: IConnectionProfile,
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
@IProfilerService private _profilerService: IProfilerService,
|
||||
@INotificationService private _notificationService: INotificationService,
|
||||
@@ -58,7 +59,7 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
||||
autoscroll: true
|
||||
});
|
||||
|
||||
this._profilerService.registerSession(generateUuid(), _connection, this).then((id) => {
|
||||
this._profilerService.registerSession(generateUuid(), connection, this).then((id) => {
|
||||
this._id = id;
|
||||
this.state.change({ isConnected: true });
|
||||
});
|
||||
@@ -72,23 +73,10 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
||||
return ret;
|
||||
};
|
||||
this._data = new TableDataView<Slick.SlickData>(undefined, searchFn);
|
||||
}
|
||||
|
||||
this.onDispose(() => {
|
||||
if (this._state.isRunning || this.state.isPaused) {
|
||||
let confirm: IConfirmation = {
|
||||
message: nls.localize('confirmStopProfilerSession', "Would you like to stop the running XEvent session?"),
|
||||
primaryButton: nls.localize('profilerClosingActions.yes', 'Yes'),
|
||||
secondaryButton: nls.localize('profilerClosingActions.no', 'No'),
|
||||
type: 'question'
|
||||
};
|
||||
|
||||
this._dialogService.confirm(confirm).then(result => {
|
||||
if (result.confirmed) {
|
||||
this._profilerService.stopSession(this.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
public get providerType(): string {
|
||||
return this.connection ? this.connection.providerName : undefined;
|
||||
}
|
||||
|
||||
public set viewTemplate(template: IProfilerViewTemplate) {
|
||||
@@ -114,7 +102,7 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
||||
}
|
||||
|
||||
public set sessionName(name: string) {
|
||||
if (!this._state.isRunning || !this.state.isPaused) {
|
||||
if (!this.state.isRunning || !this.state.isPaused) {
|
||||
this._sessionName = name;
|
||||
}
|
||||
}
|
||||
@@ -133,10 +121,10 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
||||
|
||||
public getName(): string {
|
||||
let name: string = nls.localize('profilerInput.profiler', 'Profiler');
|
||||
if (!this._connection) {
|
||||
if (!this.connection) {
|
||||
return name;
|
||||
}
|
||||
name += ': ' + this._connection.serverName.substring(0, 20);
|
||||
name += ': ' + this.connection.serverName.substring(0, 20);
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -178,11 +166,11 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
||||
}
|
||||
|
||||
public get connectionName(): string {
|
||||
if (!types.isUndefinedOrNull(this._connection)) {
|
||||
if (this._connection.databaseName) {
|
||||
return `${this._connection.serverName} ${this._connection.databaseName}`;
|
||||
if (!types.isUndefinedOrNull(this.connection)) {
|
||||
if (this.connection.databaseName) {
|
||||
return `${this.connection.serverName} ${this.connection.databaseName}`;
|
||||
} else {
|
||||
return `${this._connection.serverName}`;
|
||||
return `${this.connection.serverName}`;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -199,7 +187,7 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
||||
}
|
||||
|
||||
public onSessionStopped(notification: sqlops.ProfilerSessionStoppedParams) {
|
||||
this._notificationService.error(nls.localize("profiler.sessionStopped", "XEvent Profiler Session stopped unexpectedly on the server {0}.", this._connection.serverName));
|
||||
this._notificationService.error(nls.localize("profiler.sessionStopped", "XEvent Profiler Session stopped unexpectedly on the server {0}.", this.connection.serverName));
|
||||
|
||||
this.state.change({
|
||||
isStopped: true,
|
||||
@@ -240,7 +228,7 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
||||
|
||||
public onMoreRows(eventMessage: sqlops.ProfilerSessionEvents) {
|
||||
if (eventMessage.eventsLost) {
|
||||
this._notificationService.warn(nls.localize("profiler.eventsLost", "The XEvent Profiler session for {0} has lost events.", this._connection.serverName));
|
||||
this._notificationService.warn(nls.localize("profiler.eventsLost", "The XEvent Profiler session for {0} has lost events.", this.connection.serverName));
|
||||
}
|
||||
|
||||
for (let i: number = 0; i < eventMessage.events.length && i < 500; ++i) {
|
||||
@@ -264,4 +252,31 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
confirmSave(): TPromise<ConfirmResult> {
|
||||
if (this.state.isRunning || this.state.isPaused) {
|
||||
return this._dialogService.show(Severity.Warning,
|
||||
nls.localize('confirmStopProfilerSession', "Would you like to stop the running XEvent session?"),
|
||||
[
|
||||
nls.localize('profilerClosingActions.yes', 'Yes'),
|
||||
nls.localize('profilerClosingActions.no', 'No'),
|
||||
nls.localize('profilerClosingActions.cancel', 'Cancel')
|
||||
]).then((selection: number) => {
|
||||
if (selection === 0) {
|
||||
this._profilerService.stopSession(this.id);
|
||||
return ConfirmResult.DONT_SAVE;
|
||||
} else if (selection === 1) {
|
||||
return ConfirmResult.DONT_SAVE;
|
||||
} else {
|
||||
return ConfirmResult.CANCEL;
|
||||
}
|
||||
});;
|
||||
} else {
|
||||
return TPromise.wrap(ConfirmResult.DONT_SAVE);
|
||||
}
|
||||
}
|
||||
|
||||
isDirty(): boolean {
|
||||
return this.state.isRunning || this.state.isPaused;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,10 @@ export class ProfilerService implements IProfilerService {
|
||||
this._sessionMap.get(this._idMap.reverseGet(id)).onSessionStateChanged({ isStopped: true, isPaused: false, isRunning: false });
|
||||
return true;
|
||||
}, (reason) => {
|
||||
this._notificationService.error(reason.message);
|
||||
// The error won't be actionable to the user, so only log it to console.
|
||||
// In case of error, the state of the UI is not usable, makes more sense to
|
||||
// set it to stopped so that user can restart it or pick a different session
|
||||
this._sessionMap.get(this._idMap.reverseGet(id)).onSessionStateChanged({ isStopped: true, isPaused: false, isRunning: false });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -228,6 +231,6 @@ export class ProfilerService implements IProfilerService {
|
||||
}
|
||||
|
||||
public launchCreateSessionDialog(input?: ProfilerInput): Thenable<void> {
|
||||
return this._commandService.executeCommand('profiler.openCreateSessionDialog', input.id, this.getSessionTemplates());
|
||||
return this._commandService.executeCommand('profiler.openCreateSessionDialog', input.id, input.providerType, this.getSessionTemplates());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ let registryProperties = {
|
||||
'sql.showConnectionInfoInTitle': {
|
||||
'type': 'boolean',
|
||||
'description': localize('showConnectionInfoInTitle', "Controls whether to show the connection info for a tab in the title."),
|
||||
'default': false
|
||||
'default': true
|
||||
},
|
||||
'mssql.intelliSense.enableIntelliSense': {
|
||||
'type': 'boolean',
|
||||
|
||||
@@ -32,9 +32,6 @@ export interface IQueryEditorService {
|
||||
// Creates new edit data session
|
||||
newEditDataEditor(schemaName: string, tableName: string, queryString: string): Promise<IConnectableInput>;
|
||||
|
||||
// Clears any QueryEditor data for the given URI held by this service
|
||||
onQueryInputClosed(uri: string): void;
|
||||
|
||||
/**
|
||||
* Handles updating of SQL files on a save as event. These need special consideration
|
||||
* due to query results and other information being tied to the URI of the file
|
||||
|
||||
@@ -116,11 +116,11 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
||||
}
|
||||
|
||||
if (this._configurationService) {
|
||||
this._configurationService.onDidChangeConfiguration(e => {
|
||||
this._toDispose.push(this._configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectedKeys.includes('sql.showConnectionInfoInTitle')) {
|
||||
this._onDidChangeLabel.fire();
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
this.onDisconnect();
|
||||
@@ -196,17 +196,17 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
||||
|
||||
// State update funtions
|
||||
public runQuery(selection: ISelectionData, executePlanOptions?: ExecutionPlanOptions): void {
|
||||
this._queryModelService.runQuery(this.uri, selection, this.uri, this, executePlanOptions);
|
||||
this._queryModelService.runQuery(this.uri, selection, this, executePlanOptions);
|
||||
this.showQueryResultsEditor();
|
||||
}
|
||||
|
||||
public runQueryStatement(selection: ISelectionData): void {
|
||||
this._queryModelService.runQueryStatement(this.uri, selection, this.uri, this);
|
||||
this._queryModelService.runQueryStatement(this.uri, selection, this);
|
||||
this.showQueryResultsEditor();
|
||||
}
|
||||
|
||||
public runQueryString(text: string): void {
|
||||
this._queryModelService.runQueryString(this.uri, text, this.uri, this);
|
||||
this._queryModelService.runQueryString(this.uri, text, this);
|
||||
this.showQueryResultsEditor();
|
||||
}
|
||||
|
||||
@@ -276,7 +276,6 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
||||
|
||||
// Clean up functions
|
||||
public dispose(): void {
|
||||
this._queryModelService.disposeQuery(this.uri);
|
||||
this._sql.dispose();
|
||||
this._results.dispose();
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
@@ -285,7 +284,7 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
this._queryEditorService.onQueryInputClosed(this.uri);
|
||||
this._queryModelService.disposeQuery(this.uri);
|
||||
this._connectionManagementService.disconnectEditor(this, true);
|
||||
|
||||
this._sql.close();
|
||||
|
||||
@@ -215,6 +215,7 @@ export class QueryManagementService implements IQueryManagementService {
|
||||
});
|
||||
}
|
||||
public disposeQuery(ownerUri: string): Thenable<void> {
|
||||
this._queryRunners.delete(ownerUri);
|
||||
return this._runAction(ownerUri, (runner) => {
|
||||
return runner.disposeQuery(ownerUri);
|
||||
});
|
||||
|
||||
@@ -29,6 +29,13 @@ export class ResultsViewState {
|
||||
constructor(@IConfigurationService private configurationService: IConfigurationService) {
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.gridPanelState.dispose();
|
||||
this.messagePanelState.dispose();
|
||||
this.chartState.dispose();
|
||||
this.queryPlanState.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +57,11 @@ export class QueryResultsInput extends EditorInput {
|
||||
public readonly onRestoreViewStateEmitter = new Emitter<void>();
|
||||
public readonly onSaveViewStateEmitter = new Emitter<void>();
|
||||
|
||||
public readonly state = new ResultsViewState(this.configurationService);
|
||||
private _state = new ResultsViewState(this.configurationService);
|
||||
|
||||
public get state(): ResultsViewState {
|
||||
return this._state;
|
||||
}
|
||||
|
||||
constructor(private _uri: string,
|
||||
@IConfigurationService private configurationService: IConfigurationService
|
||||
@@ -60,6 +71,12 @@ export class QueryResultsInput extends EditorInput {
|
||||
this._hasBootstrapped = false;
|
||||
}
|
||||
|
||||
close() {
|
||||
this.state.dispose();
|
||||
this._state = undefined;
|
||||
super.close();
|
||||
}
|
||||
|
||||
getTypeId(): string {
|
||||
return QueryResultsInput.ID;
|
||||
}
|
||||
|
||||
@@ -33,4 +33,8 @@ export class ChartTab implements IPanelTab {
|
||||
public dispose() {
|
||||
this.view.dispose();
|
||||
}
|
||||
|
||||
public clear() {
|
||||
this.view.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ export class ChartState {
|
||||
options: IInsightOptions = {
|
||||
type: ChartType.Bar
|
||||
};
|
||||
|
||||
dispose() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
declare class Proxy {
|
||||
@@ -134,6 +138,15 @@ export class ChartView extends Disposable implements IPanelView {
|
||||
this.buildOptions();
|
||||
}
|
||||
|
||||
public clear() {
|
||||
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
dispose(this.optionDisposables);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
if (!this.container) {
|
||||
this.container = $('div.chart-parent-container');
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import { attachTableStyler } from 'sql/common/theme/styler';
|
||||
import QueryRunner from 'sql/parts/query/execution/queryRunner';
|
||||
import { VirtualizedCollection, AsyncDataProvider } from 'sql/base/browser/ui/table/asyncDataView';
|
||||
import { Table, ITableStyles, ITableMouseEvent } from 'sql/base/browser/ui/table/table';
|
||||
import { Table } from 'sql/base/browser/ui/table/table';
|
||||
import { ScrollableSplitView } from 'sql/base/browser/ui/scrollableSplitview/scrollableSplitview';
|
||||
import { MouseWheelSupport } from 'sql/base/browser/ui/table/plugins/mousewheelTableScroll.plugin';
|
||||
import { AutoColumnSize } from 'sql/base/browser/ui/table/plugins/autoSizeColumns.plugin';
|
||||
@@ -19,6 +19,7 @@ import { escape } from 'sql/base/common/strings';
|
||||
import { hyperLinkFormatter, textFormatter } from 'sql/parts/grid/services/sharedServices';
|
||||
import { CopyKeybind } from 'sql/base/browser/ui/table/plugins/copyKeybind.plugin';
|
||||
import { AdditionalKeyBindings } from 'sql/base/browser/ui/table/plugins/additionalKeyBindings.plugin';
|
||||
import { ITableStyles, ITableMouseEvent } from 'sql/base/browser/ui/table/interfaces';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import * as pretty from 'pretty-data';
|
||||
@@ -61,6 +62,10 @@ export class GridPanelState {
|
||||
public tableStates: GridTableState[] = [];
|
||||
public scrollPosition: number;
|
||||
public collapsed = false;
|
||||
|
||||
dispose() {
|
||||
dispose(this.tableStates);
|
||||
}
|
||||
}
|
||||
|
||||
export interface IGridTableState {
|
||||
@@ -68,14 +73,14 @@ export interface IGridTableState {
|
||||
maximized: boolean;
|
||||
}
|
||||
|
||||
export class GridTableState {
|
||||
export class GridTableState extends Disposable {
|
||||
|
||||
private _maximized: boolean;
|
||||
|
||||
private _onMaximizedChange = new Emitter<boolean>();
|
||||
private _onMaximizedChange = this._register(new Emitter<boolean>());
|
||||
public onMaximizedChange: Event<boolean> = this._onMaximizedChange.event;
|
||||
|
||||
private _onCanBeMaximizedChange = new Emitter<boolean>();
|
||||
private _onCanBeMaximizedChange = this._register(new Emitter<boolean>());
|
||||
public onCanBeMaximizedChange: Event<boolean> = this._onCanBeMaximizedChange.event;
|
||||
|
||||
private _canBeMaximized: boolean;
|
||||
@@ -86,6 +91,7 @@ export class GridTableState {
|
||||
public activeCell: Slick.Cell;
|
||||
|
||||
constructor(public readonly resultId: number, public readonly batchId: number) {
|
||||
super();
|
||||
}
|
||||
|
||||
public get canBeMaximized(): boolean {
|
||||
@@ -217,13 +223,13 @@ export class GridPanel extends ViewletPanel {
|
||||
}
|
||||
let table = this.instantiationService.createInstance(GridTable, this.runner, set);
|
||||
table.state = tableState;
|
||||
tableState.onMaximizedChange(e => {
|
||||
this.tableDisposable.push(tableState.onMaximizedChange(e => {
|
||||
if (e) {
|
||||
this.maximizeTable(table.id);
|
||||
} else {
|
||||
this.minimizeTables();
|
||||
}
|
||||
});
|
||||
}));
|
||||
this.tableDisposable.push(attachTableStyler(table, this.themeService));
|
||||
|
||||
tables.push(table);
|
||||
@@ -238,11 +244,17 @@ export class GridPanel extends ViewletPanel {
|
||||
this.tables = this.tables.concat(tables);
|
||||
}
|
||||
|
||||
public clear() {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
private reset() {
|
||||
for (let i = this.splitView.length - 1; i >= 0; i--) {
|
||||
this.splitView.removeView(i);
|
||||
}
|
||||
dispose(this.tables);
|
||||
dispose(this.tableDisposable);
|
||||
this.tableDisposable = [];
|
||||
this.tables = [];
|
||||
this.maximizedGrid = undefined;
|
||||
|
||||
@@ -293,6 +305,15 @@ export class GridPanel extends ViewletPanel {
|
||||
public get state(): GridPanelState {
|
||||
return this._state;
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
dispose(this.queryRunnerDisposables);
|
||||
dispose(this.tableDisposable);
|
||||
dispose(this.tables);
|
||||
this.tableDisposable = undefined;
|
||||
this.tables = undefined;
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class GridTable<T> extends Disposable implements IView {
|
||||
@@ -444,9 +465,9 @@ class GridTable<T> extends Disposable implements IView {
|
||||
|
||||
private setupState() {
|
||||
// change actionbar on maximize change
|
||||
this.state.onMaximizedChange(this.rebuildActionBar, this);
|
||||
this._register(this.state.onMaximizedChange(this.rebuildActionBar, this));
|
||||
|
||||
this.state.onCanBeMaximizedChange(this.rebuildActionBar, this);
|
||||
this._register(this.state.onCanBeMaximizedChange(this.rebuildActionBar, this));
|
||||
|
||||
if (this.state.scrollPosition) {
|
||||
// most of the time this won't do anything
|
||||
@@ -656,6 +677,8 @@ class GridTable<T> extends Disposable implements IView {
|
||||
|
||||
public dispose() {
|
||||
$(this.container).destroy();
|
||||
this.table.dispose();
|
||||
this.actionBar.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import 'vs/css!./media/messagePanel';
|
||||
import { IMessagesActionContext, SelectAllMessagesAction, CopyMessagesAction } from './actions';
|
||||
import QueryRunner from 'sql/parts/query/execution/queryRunner';
|
||||
import { QueryInput } from 'sql/parts/query/common/queryInput';
|
||||
|
||||
import { IResultMessage, ISelectionData } from 'sqlops';
|
||||
|
||||
@@ -28,8 +29,6 @@ import { $ } from 'vs/base/browser/builder';
|
||||
import { isArray, isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditor } from 'vs/editor/common/editorCommon';
|
||||
import { QueryInput } from 'sql/parts/query/common/queryInput';
|
||||
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
|
||||
export interface IResultMessageIntern extends IResultMessage {
|
||||
@@ -71,6 +70,10 @@ export class MessagePanelState {
|
||||
this.collapsed = !messagesOpenedSettings;
|
||||
}
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export class MessagePanel extends ViewletPanel {
|
||||
@@ -102,6 +105,7 @@ export class MessagePanel extends ViewletPanel {
|
||||
renderer: this.renderer,
|
||||
controller: this.controller
|
||||
}, { keyboardSupport: false, horizontalScrollMode: ScrollbarVisibility.Auto });
|
||||
this.disposables.push(this.tree);
|
||||
this.tree.onDidScroll(e => {
|
||||
if (this.state) {
|
||||
this.state.scrollPosition = this.tree.getScrollPosition();
|
||||
@@ -117,7 +121,7 @@ export class MessagePanel extends ViewletPanel {
|
||||
protected renderBody(container: HTMLElement): void {
|
||||
this.container.style.width = '100%';
|
||||
this.container.style.height = '100%';
|
||||
attachListStyler(this.tree, this.themeService);
|
||||
this.disposables.push(attachListStyler(this.tree, this.themeService));
|
||||
container.appendChild(this.container);
|
||||
this.tree.setInput(this.model);
|
||||
}
|
||||
@@ -193,9 +197,19 @@ export class MessagePanel extends ViewletPanel {
|
||||
}
|
||||
this.setExpanded(!this.state.collapsed);
|
||||
}
|
||||
|
||||
public get state(): MessagePanelState {
|
||||
return this._state;
|
||||
}
|
||||
|
||||
public clear() {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
dispose(this.queryRunnerDisposables);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class MessageDataSource implements IDataSource {
|
||||
|
||||
@@ -478,11 +478,11 @@ export class QueryEditor extends BaseEditor {
|
||||
|
||||
this.setTaskbarContent();
|
||||
|
||||
this._configurationService.onDidChangeConfiguration(e => {
|
||||
this._toDispose.push(this._configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectedKeys.includes('workbench.enablePreviewFeatures')) {
|
||||
this.setTaskbarContent();
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
private setTaskbarContent(): void {
|
||||
|
||||
@@ -90,7 +90,6 @@ export class QueryResultsEditor extends BaseEditor {
|
||||
public static ID: string = 'workbench.editor.queryResultsEditor';
|
||||
public static AngularSelectorString: string = 'slickgrid-container.slickgridContainer';
|
||||
protected _rawOptions: BareResultsGridInfo;
|
||||
protected _input: QueryResultsInput;
|
||||
|
||||
private resultsView: QueryResultsView;
|
||||
private styleSheet = DOM.createStyleSheet();
|
||||
@@ -104,17 +103,17 @@ export class QueryResultsEditor extends BaseEditor {
|
||||
) {
|
||||
super(QueryResultsEditor.ID, telemetryService, themeService);
|
||||
this._rawOptions = BareResultsGridInfo.createFromRawSettings(this._configurationService.getValue('resultsGrid'), getZoomLevel());
|
||||
this._configurationService.onDidChangeConfiguration(e => {
|
||||
this._register(this._configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('resultsGrid')) {
|
||||
this._rawOptions = BareResultsGridInfo.createFromRawSettings(this._configurationService.getValue('resultsGrid'), getZoomLevel());
|
||||
this.applySettings();
|
||||
}
|
||||
});
|
||||
}));
|
||||
this.applySettings();
|
||||
}
|
||||
|
||||
public get input(): QueryResultsInput {
|
||||
return this._input;
|
||||
return this._input as QueryResultsInput;
|
||||
}
|
||||
|
||||
private applySettings() {
|
||||
@@ -133,10 +132,16 @@ export class QueryResultsEditor extends BaseEditor {
|
||||
this.styleSheet.remove();
|
||||
parent.appendChild(this.styleSheet);
|
||||
if (!this.resultsView) {
|
||||
this.resultsView = new QueryResultsView(parent, this._instantiationService, this._queryModelService);
|
||||
this.resultsView = this._register(new QueryResultsView(parent, this._instantiationService, this._queryModelService));
|
||||
}
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.styleSheet.remove();
|
||||
this.styleSheet = undefined;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
layout(dimension: DOM.Dimension): void {
|
||||
this.resultsView.layout(dimension);
|
||||
}
|
||||
@@ -147,6 +152,11 @@ export class QueryResultsEditor extends BaseEditor {
|
||||
return TPromise.wrap<void>(null);
|
||||
}
|
||||
|
||||
clearInput() {
|
||||
this.resultsView.clearInput();
|
||||
super.clearInput();
|
||||
}
|
||||
|
||||
public chart(dataId: { batchId: number, resultId: number }) {
|
||||
this.resultsView.chartData(dataId);
|
||||
}
|
||||
@@ -154,11 +164,4 @@ export class QueryResultsEditor extends BaseEditor {
|
||||
public showQueryPlan(xml: string) {
|
||||
this.resultsView.showPlan(xml);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
if (this.resultsView) {
|
||||
this.resultsView.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,15 @@ class ResultsView extends Disposable implements IPanelView {
|
||||
}
|
||||
}
|
||||
|
||||
dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public clear() {
|
||||
this.gridPanel.clear();
|
||||
this.messagePanel.clear();
|
||||
}
|
||||
|
||||
remove(): void {
|
||||
this.container.remove();
|
||||
}
|
||||
@@ -151,6 +160,10 @@ class ResultsTab implements IPanelTab {
|
||||
public dispose() {
|
||||
dispose(this.view);
|
||||
}
|
||||
|
||||
public clear() {
|
||||
this.view.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export class QueryResultsView extends Disposable {
|
||||
@@ -221,8 +234,11 @@ export class QueryResultsView extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
this._panelView.dispose();
|
||||
clearInput() {
|
||||
this._input = undefined;
|
||||
this.resultsTab.clear();
|
||||
this.qpTab.clear();
|
||||
this.chartTab.clear();
|
||||
}
|
||||
|
||||
public get input(): QueryResultsInput {
|
||||
@@ -264,4 +280,8 @@ export class QueryResultsView extends Disposable {
|
||||
this._panelView.removeTab(this.qpTab.identifier);
|
||||
}
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ export interface IQueryModelService {
|
||||
getConfig(): Promise<{ [key: string]: any }>;
|
||||
getShortcuts(): Promise<any>;
|
||||
getQueryRows(uri: string, rowStart: number, numberOfRows: number, batchId: number, resultId: number): Thenable<ResultSetSubset>;
|
||||
runQuery(uri: string, selection: ISelectionData, title: string, queryInput: QueryInput, runOptions?: ExecutionPlanOptions): void;
|
||||
runQueryStatement(uri: string, selection: ISelectionData, title: string, queryInput: QueryInput): void;
|
||||
runQueryString(uri: string, selection: string, title: string, queryInput: QueryInput);
|
||||
runQuery(uri: string, selection: ISelectionData, queryInput: QueryInput, runOptions?: ExecutionPlanOptions): void;
|
||||
runQueryStatement(uri: string, selection: ISelectionData, queryInput: QueryInput): void;
|
||||
runQueryString(uri: string, selection: string, queryInput: QueryInput);
|
||||
cancelQuery(input: QueryRunner | string): void;
|
||||
disposeQuery(uri: string): void;
|
||||
isRunningQuery(uri: string): boolean;
|
||||
|
||||
@@ -209,32 +209,28 @@ export class QueryModelService implements IQueryModelService {
|
||||
/**
|
||||
* Run a query for the given URI with the given text selection
|
||||
*/
|
||||
public runQuery(uri: string, selection: sqlops.ISelectionData,
|
||||
title: string, queryInput: QueryInput, runOptions?: sqlops.ExecutionPlanOptions): void {
|
||||
this.doRunQuery(uri, selection, title, queryInput, false, runOptions);
|
||||
public runQuery(uri: string, selection: sqlops.ISelectionData, queryInput: QueryInput, runOptions?: sqlops.ExecutionPlanOptions): void {
|
||||
this.doRunQuery(uri, selection, queryInput, false, runOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the current SQL statement for the given URI
|
||||
*/
|
||||
public runQueryStatement(uri: string, selection: sqlops.ISelectionData,
|
||||
title: string, queryInput: QueryInput): void {
|
||||
this.doRunQuery(uri, selection, title, queryInput, true);
|
||||
public runQueryStatement(uri: string, selection: sqlops.ISelectionData, queryInput: QueryInput): void {
|
||||
this.doRunQuery(uri, selection, queryInput, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the current SQL statement for the given URI
|
||||
*/
|
||||
public runQueryString(uri: string, selection: string,
|
||||
title: string, queryInput: QueryInput): void {
|
||||
this.doRunQuery(uri, selection, title, queryInput, true);
|
||||
public runQueryString(uri: string, selection: string, queryInput: QueryInput): void {
|
||||
this.doRunQuery(uri, selection, queryInput, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Query implementation
|
||||
*/
|
||||
private doRunQuery(uri: string, selection: sqlops.ISelectionData | string,
|
||||
title: string, queryInput: QueryInput,
|
||||
private doRunQuery(uri: string, selection: sqlops.ISelectionData | string, queryInput: QueryInput,
|
||||
runCurrentStatement: boolean, runOptions?: sqlops.ExecutionPlanOptions): void {
|
||||
// Reuse existing query runner if it exists
|
||||
let queryRunner: QueryRunner;
|
||||
@@ -256,7 +252,7 @@ export class QueryModelService implements IQueryModelService {
|
||||
} else {
|
||||
// We do not have a query runner for this editor, so create a new one
|
||||
// and map it to the results uri
|
||||
info = this.initQueryRunner(uri, title);
|
||||
info = this.initQueryRunner(uri);
|
||||
queryRunner = info.queryRunner;
|
||||
}
|
||||
|
||||
@@ -277,8 +273,8 @@ export class QueryModelService implements IQueryModelService {
|
||||
}
|
||||
}
|
||||
|
||||
private initQueryRunner(uri: string, title: string): QueryInfo {
|
||||
let queryRunner = this._instantiationService.createInstance(QueryRunner, uri, title);
|
||||
private initQueryRunner(uri: string): QueryInfo {
|
||||
let queryRunner = this._instantiationService.createInstance(QueryRunner, uri);
|
||||
let info = new QueryInfo();
|
||||
queryRunner.addListener(QREvents.RESULT_SET, e => {
|
||||
this._fireQueryEvent(uri, 'resultSet', e);
|
||||
@@ -363,6 +359,10 @@ export class QueryModelService implements IQueryModelService {
|
||||
if (queryRunner) {
|
||||
queryRunner.disposeQuery();
|
||||
}
|
||||
// remove our info map
|
||||
if (this._queryInfoMap.has(ownerUri)) {
|
||||
this._queryInfoMap.delete(ownerUri);
|
||||
}
|
||||
}
|
||||
|
||||
// EDIT DATA METHODS /////////////////////////////////////////////////////
|
||||
@@ -386,7 +386,7 @@ export class QueryModelService implements IQueryModelService {
|
||||
|
||||
// We do not have a query runner for this editor, so create a new one
|
||||
// and map it to the results uri
|
||||
queryRunner = this._instantiationService.createInstance(QueryRunner, ownerUri, ownerUri);
|
||||
queryRunner = this._instantiationService.createInstance(QueryRunner, ownerUri);
|
||||
queryRunner.addListener(QREvents.RESULT_SET, resultSet => {
|
||||
this._fireQueryEvent(ownerUri, 'resultSet', resultSet);
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ import * as nls from 'vs/nls';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { EventEmitter } from 'sql/base/common/eventEmitter';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -62,7 +62,7 @@ export interface IGridMessage extends sqlops.IResultMessage {
|
||||
* Query Runner class which handles running a query, reports the results to the content manager,
|
||||
* and handles getting more rows from the service layer and disposing when the content is closed.
|
||||
*/
|
||||
export default class QueryRunner {
|
||||
export default class QueryRunner extends Disposable {
|
||||
// MEMBER VARIABLES ////////////////////////////////////////////////////
|
||||
private _resultLineOffset: number;
|
||||
private _totalElapsedMilliseconds: number = 0;
|
||||
@@ -76,7 +76,7 @@ export default class QueryRunner {
|
||||
private _planXml = new Deferred<string>();
|
||||
public get planXml(): Thenable<string> { return this._planXml.promise; }
|
||||
|
||||
private _onMessage = new Emitter<sqlops.IResultMessage>();
|
||||
private _onMessage = this._register(new Emitter<sqlops.IResultMessage>());
|
||||
private _debouncedMessage = debounceEvent<sqlops.IResultMessage, sqlops.IResultMessage[]>(this._onMessage.event, (l, e) => {
|
||||
// on first run
|
||||
if (types.isUndefinedOrNull(l)) {
|
||||
@@ -88,7 +88,7 @@ export default class QueryRunner {
|
||||
private _echoedMessages = echo(this._debouncedMessage.event);
|
||||
public readonly onMessage = this._echoedMessages.event;
|
||||
|
||||
private _onResultSet = new Emitter<sqlops.ResultSetSummary>();
|
||||
private _onResultSet = this._register(new Emitter<sqlops.ResultSetSummary>());
|
||||
private _debouncedResultSet = debounceEvent<sqlops.ResultSetSummary, sqlops.ResultSetSummary[]>(this._onResultSet.event, (l, e) => {
|
||||
// on first run
|
||||
if (types.isUndefinedOrNull(l)) {
|
||||
@@ -100,16 +100,16 @@ export default class QueryRunner {
|
||||
private _echoedResultSet = echo(this._debouncedResultSet.event);
|
||||
public readonly onResultSet = this._echoedResultSet.event;
|
||||
|
||||
private _onQueryStart = new Emitter<void>();
|
||||
private _onQueryStart = this._register(new Emitter<void>());
|
||||
public readonly onQueryStart: Event<void> = this._onQueryStart.event;
|
||||
|
||||
private _onQueryEnd = new Emitter<string>();
|
||||
private _onQueryEnd = this._register(new Emitter<string>());
|
||||
public readonly onQueryEnd: Event<string> = this._onQueryEnd.event;
|
||||
|
||||
private _onBatchStart = new Emitter<sqlops.BatchSummary>();
|
||||
private _onBatchStart = this._register(new Emitter<sqlops.BatchSummary>());
|
||||
public readonly onBatchStart: Event<sqlops.BatchSummary> = this._onBatchStart.event;
|
||||
|
||||
private _onBatchEnd = new Emitter<sqlops.BatchSummary>();
|
||||
private _onBatchEnd = this._register(new Emitter<sqlops.BatchSummary>());
|
||||
public readonly onBatchEnd: Event<sqlops.BatchSummary> = this._onBatchEnd.event;
|
||||
|
||||
private _queryStartTime: Date;
|
||||
@@ -124,13 +124,14 @@ export default class QueryRunner {
|
||||
// CONSTRUCTOR /////////////////////////////////////////////////////////
|
||||
constructor(
|
||||
public uri: string,
|
||||
public title: string,
|
||||
@IQueryManagementService private _queryManagementService: IQueryManagementService,
|
||||
@INotificationService private _notificationService: INotificationService,
|
||||
@IWorkspaceConfigurationService private _workspaceConfigurationService: IWorkspaceConfigurationService,
|
||||
@IClipboardService private _clipboardService: IClipboardService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) { }
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
get isExecuting(): boolean {
|
||||
return this._isExecuting;
|
||||
@@ -504,10 +505,16 @@ export default class QueryRunner {
|
||||
|
||||
/**
|
||||
* Disposes the Query from the service client
|
||||
* @returns A promise that will be rejected if a problem occured
|
||||
*/
|
||||
public disposeQuery(): void {
|
||||
this._queryManagementService.disposeQuery(this.uri);
|
||||
this._queryManagementService.disposeQuery(this.uri).then(() => {
|
||||
this.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
this._batchSets = undefined;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
get totalElapsedMilliseconds(): number {
|
||||
|
||||
@@ -152,12 +152,6 @@ export class QueryEditorService implements IQueryEditorService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears any QueryEditor data for the given URI held by this service
|
||||
*/
|
||||
public onQueryInputClosed(uri: string): void {
|
||||
}
|
||||
|
||||
onSaveAsCompleted(oldResource: URI, newResource: URI): void {
|
||||
let oldResourceString: string = oldResource.toString();
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@ import { dispose, Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export class QueryPlanState {
|
||||
xml: string;
|
||||
dispose() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export class QueryPlanTab implements IPanelTab {
|
||||
@@ -29,6 +32,10 @@ export class QueryPlanTab implements IPanelTab {
|
||||
public dispose() {
|
||||
dispose(this.view);
|
||||
}
|
||||
|
||||
public clear() {
|
||||
this.view.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export class QueryPlanView implements IPanelView {
|
||||
@@ -59,6 +66,12 @@ export class QueryPlanView implements IPanelView {
|
||||
this.container.style.height = dimension.height + 'px';
|
||||
}
|
||||
|
||||
public clear() {
|
||||
if (this.qp) {
|
||||
this.qp.xml = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public showPlan(xml: string) {
|
||||
if (this.qp) {
|
||||
this.qp.xml = xml;
|
||||
|
||||
@@ -16,6 +16,18 @@
|
||||
min-width: 800px;
|
||||
}
|
||||
|
||||
.dialog-message-and-page-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dialogModal-page-container {
|
||||
flex: 1 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dialogModal-pane {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -34,6 +34,9 @@ export class WizardModal extends Modal {
|
||||
// Wizard HTML elements
|
||||
private _body: HTMLElement;
|
||||
|
||||
private _messageAndPageContainer: HTMLElement;
|
||||
private _pageContainer: HTMLElement;
|
||||
|
||||
// Buttons
|
||||
private _previousButton: Button;
|
||||
private _nextButton: Button;
|
||||
@@ -53,6 +56,7 @@ export class WizardModal extends Modal {
|
||||
@IClipboardService clipboardService: IClipboardService
|
||||
) {
|
||||
super(_wizard.title, name, partService, telemetryService, clipboardService, themeService, contextKeyService, options);
|
||||
this._useDefaultMessageBoxLocation = false;
|
||||
}
|
||||
|
||||
public layout(): void {
|
||||
@@ -126,12 +130,21 @@ export class WizardModal extends Modal {
|
||||
}
|
||||
|
||||
protected renderBody(container: HTMLElement): void {
|
||||
let bodyBuilderObj;
|
||||
new Builder(container).div({ class: 'dialogModal-body' }, (bodyBuilder) => {
|
||||
bodyBuilderObj = bodyBuilder;
|
||||
this._body = bodyBuilder.getHTMLElement();
|
||||
});
|
||||
|
||||
this.initializeNavigation(this._body);
|
||||
|
||||
bodyBuilderObj.div({ class: 'dialog-message-and-page-container' }, (mpContainer) => {
|
||||
this._messageAndPageContainer = mpContainer.getHTMLElement();
|
||||
mpContainer.append(this._messageElement);
|
||||
this._pageContainer = mpContainer.div({ class: 'dialogModal-page-container' }).getHTMLElement();
|
||||
});
|
||||
|
||||
|
||||
this._wizard.pages.forEach(page => {
|
||||
this.registerPage(page);
|
||||
});
|
||||
@@ -159,7 +172,7 @@ export class WizardModal extends Modal {
|
||||
|
||||
private registerPage(page: WizardPage): void {
|
||||
let dialogPane = new DialogPane(page.title, page.content, valid => page.notifyValidityChanged(valid), this._instantiationService, this._wizard.displayPageTitles, page.description);
|
||||
dialogPane.createBody(this._body);
|
||||
dialogPane.createBody(this._pageContainer);
|
||||
this._dialogPanes.set(page, dialogPane);
|
||||
page.onUpdate(() => this.setButtonsForPage(this._wizard.currentPage));
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import { IObjectExplorerService } from 'sql/parts/objectExplorer/common/objectEx
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { QueryInput } from 'sql/parts/query/common/queryInput';
|
||||
import { DashboardInput } from 'sql/parts/dashboard/dashboardInput';
|
||||
import { ProfilerInput } from 'sql/parts/profiler/editor/profilerInput';
|
||||
|
||||
// map for the version of SQL Server (default is 140)
|
||||
const scriptCompatibilityOptionMap = {
|
||||
@@ -400,6 +401,9 @@ export function getCurrentGlobalConnection(objectExplorerService: IObjectExplore
|
||||
if (activeInput instanceof QueryInput || activeInput instanceof EditDataInput || activeInput instanceof DashboardInput) {
|
||||
connection = connectionManagementService.getConnectionProfile(activeInput.uri);
|
||||
}
|
||||
else if (activeInput instanceof ProfilerInput) {
|
||||
connection = activeInput.connection;
|
||||
}
|
||||
}
|
||||
|
||||
return connection;
|
||||
|
||||
@@ -14,7 +14,7 @@ import { attachButtonStyler, attachModalDialogStyler } from 'sql/common/theme/st
|
||||
import { Builder } from 'vs/base/browser/builder';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { SIDE_BAR_BACKGROUND, SIDE_BAR_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
@@ -76,7 +76,7 @@ export class ErrorMessageDialog extends Modal {
|
||||
this._copyButton = this.addFooterButton(copyButtonLabel, () => this._clipboardService.writeText(this._messageDetails), 'left');
|
||||
this._copyButton.icon = 'icon scriptToClipboard';
|
||||
this._copyButton.element.title = copyButtonLabel;
|
||||
this._register(attachButtonStyler(this._copyButton, this._themeService, { buttonBackground: SIDE_BAR_BACKGROUND, buttonHoverBackground: SIDE_BAR_BACKGROUND }));
|
||||
this._register(attachButtonStyler(this._copyButton, this._themeService, { buttonBackground: SIDE_BAR_BACKGROUND, buttonHoverBackground: SIDE_BAR_BACKGROUND, buttonForeground: SIDE_BAR_FOREGROUND }));
|
||||
}
|
||||
|
||||
private createStandardButton(label: string, onSelect: () => void): Button {
|
||||
|
||||
@@ -141,6 +141,8 @@ suite('SQL QueryEditor Tests', () => {
|
||||
connectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, memento.object, undefined);
|
||||
connectionManagementService.callBase = true;
|
||||
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAny())).returns(() => false);
|
||||
connectionManagementService.setup(x => x.disconnectEditor(TypeMoq.It.isAny())).returns(() => void 0);
|
||||
connectionManagementService.setup(x => x.ensureDefaultLanguageFlavor(TypeMoq.It.isAnyString())).returns(() => void 0);
|
||||
|
||||
// Create a QueryModelService
|
||||
queryModelService = new QueryModelService(instantiationService.object, notificationService.object);
|
||||
@@ -328,6 +330,9 @@ suite('SQL QueryEditor Tests', () => {
|
||||
queryConnectionService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, memento.object, undefined);
|
||||
queryConnectionService.callBase = true;
|
||||
|
||||
queryConnectionService.setup(x => x.disconnectEditor(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => void 0);
|
||||
queryConnectionService.setup(x => x.ensureDefaultLanguageFlavor(TypeMoq.It.isAnyString())).returns(() => void 0);
|
||||
|
||||
// Mock InstantiationService to give us the actions
|
||||
queryActionInstantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
|
||||
|
||||
@@ -354,12 +359,13 @@ suite('SQL QueryEditor Tests', () => {
|
||||
let fileInput = new UntitledEditorInput(URI.parse('testUri'), false, '', '', '', instantiationService.object, undefined, undefined, undefined);
|
||||
queryModelService = TypeMoq.Mock.ofType(QueryModelService, TypeMoq.MockBehavior.Loose, undefined, undefined);
|
||||
queryModelService.callBase = true;
|
||||
queryModelService.setup(x => x.disposeQuery(TypeMoq.It.isAny())).returns(() => void 0);
|
||||
queryInput = new QueryInput(
|
||||
'',
|
||||
fileInput,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
connectionManagementService.object,
|
||||
queryModelService.object,
|
||||
undefined,
|
||||
undefined
|
||||
@@ -395,7 +401,7 @@ suite('SQL QueryEditor Tests', () => {
|
||||
test('Test that we attempt to dispose query when the queryInput is disposed', (done) => {
|
||||
let queryResultsInput = new QueryResultsInput('testUri', configurationService.object);
|
||||
queryInput['_results'] = queryResultsInput;
|
||||
queryInput.dispose();
|
||||
queryInput.close();
|
||||
queryModelService.verify(x => x.disposeQuery(TypeMoq.It.isAnyString()), TypeMoq.Times.once());
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -199,7 +199,7 @@ suite('Keybindings Editor Model test', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('convert with title and wihtout binding to entry', () => {
|
||||
test('convert with title and without binding to entry', () => {
|
||||
const id = 'a' + uuid.generateUuid();
|
||||
registerCommandWithTitle(id, 'some title');
|
||||
prepareKeybindingService();
|
||||
|
||||