Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15ae55136f | ||
|
|
b18abd954f | ||
|
|
b45f79a1f8 | ||
|
|
01a03b4c84 | ||
|
|
e48328af34 | ||
|
|
8925d44807 | ||
|
|
213283510f | ||
|
|
9f8190dc28 | ||
|
|
c32d4ee2f7 | ||
|
|
2c867a4b2c | ||
|
|
da5194bdcb | ||
|
|
bbb27aed10 | ||
|
|
c02fbaeae7 | ||
|
|
847218da73 | ||
|
|
90dc788893 | ||
|
|
f3525cc555 | ||
|
|
198f243181 | ||
|
|
8e049f4af5 | ||
|
|
ff465a59b6 | ||
|
|
68b4f3ca04 | ||
|
|
6b31f2b3f2 | ||
|
|
63cf0f1548 | ||
|
|
e607f68b3e | ||
|
|
db3bb82dbd | ||
|
|
5889c600fa | ||
|
|
d7d4c7236c | ||
|
|
f54d8ce36f | ||
|
|
43faa13cb5 | ||
|
|
85a2d994f3 | ||
|
|
d8cd78cd6b | ||
|
|
3e59a5bcd2 | ||
|
|
0efb89d6ff | ||
|
|
6697c075cb | ||
|
|
06660160e7 | ||
|
|
0b571737b7 | ||
|
|
0a486a280d | ||
|
|
bd53e685d0 | ||
|
|
a2bbf3f44e | ||
|
|
410bb62906 | ||
|
|
cbb4ac3e20 | ||
|
|
7508192ab9 | ||
|
|
bbf6cbd8fb | ||
|
|
9765269d27 | ||
|
|
61746b7ff7 | ||
|
|
e6066c2cb5 | ||
|
|
633a918590 | ||
|
|
71c14a0837 | ||
|
|
9bbed2c275 | ||
|
|
d9ba4d9130 | ||
|
|
ecd40de7ec | ||
|
|
e2bd6c06ec | ||
|
|
a26be76d79 | ||
|
|
3b68c1eb69 | ||
|
|
f7879bdbf9 | ||
|
|
dbb0fc519f | ||
|
|
5da89ac05b | ||
|
|
3c785ae7d8 | ||
|
|
d434724a54 | ||
|
|
fc3bf45a7f | ||
|
|
ac0ffab99c | ||
|
|
533f2734f1 | ||
|
|
2859bee4c0 | ||
|
|
972f857c71 | ||
|
|
d2eb1488fd | ||
|
|
508e4eac61 | ||
|
|
fd1d807012 | ||
|
|
906c4c7f39 | ||
|
|
668e43f57c | ||
|
|
6d260c195f | ||
|
|
fdfecbb3f7 |
58
.travis.yml
@@ -1,58 +0,0 @@
|
||||
sudo: false
|
||||
language: cpp
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/yarn
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
webhooks:
|
||||
- http://vscode-probot.westus.cloudapp.azure.com:3450/travis/notifications
|
||||
- http://vscode-test-probot.westus.cloudapp.azure.com:3450/travis/notifications
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-4.9
|
||||
- g++-4.9
|
||||
- gcc-4.9-multilib
|
||||
- g++-4.9-multilib
|
||||
- zip
|
||||
- libgtk2.0-0
|
||||
- libx11-dev
|
||||
- libxkbfile-dev
|
||||
- libsecret-1-dev
|
||||
|
||||
before_install:
|
||||
- git submodule update --init --recursive
|
||||
- nvm install 8.9.1
|
||||
- nvm use 8.9.1
|
||||
- npm i -g yarn
|
||||
# - npm config set python `which python`
|
||||
- if [ $TRAVIS_OS_NAME == "linux" ]; then
|
||||
export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0;
|
||||
sh -e /etc/init.d/xvfb start;
|
||||
sleep 3;
|
||||
fi
|
||||
# Make npm logs less verbose
|
||||
# - npm config set depth 0
|
||||
# - npm config set loglevel warn
|
||||
|
||||
install:
|
||||
- yarn
|
||||
|
||||
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
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./scripts/test.sh --coverage --reporter dot; else ./scripts/test.sh --reporter dot; fi
|
||||
|
||||
after_success:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then node_modules/.bin/coveralls < .build/coverage/lcov.info; fi
|
||||
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
|
||||
|
||||
20
README.md
@@ -1,6 +1,7 @@
|
||||
# Azure Data Studio
|
||||
|
||||
[](https://gitter.im/Microsoft/sqlopsstudio?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://dev.azure.com/ms/azuredatastudio/_build/latest?definitionId=4)
|
||||
|
||||
Azure Data Studio is a data management tool that enables you to work with SQL Server, Azure SQL DB and SQL DW from Windows, macOS and Linux.
|
||||
|
||||
@@ -8,12 +9,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 +62,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 +110,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
|
||||
|
||||
@@ -34,6 +34,7 @@ expressly granted herein, whether by implication, estoppel or otherwise.
|
||||
jquery-ui: https://github.com/jquery/jquery-ui
|
||||
jquery.event.drag: https://github.com/devongovett/jquery.event.drag
|
||||
jschardet: https://github.com/aadsm/jschardet
|
||||
JupyterLab: https://github.com/jupyterlab/jupyterlab
|
||||
make-error: https://github.com/JsCommunity/make-error
|
||||
minimist: https://github.com/substack/minimist
|
||||
moment: https://github.com/moment/moment
|
||||
@@ -1166,6 +1167,43 @@ That's all there is to it!
|
||||
=========================================
|
||||
END OF jschardet NOTICES AND INFORMATION
|
||||
|
||||
%% JupyterLab NOTICES AND INFORMATION BEGIN HERE
|
||||
Copyright (c) 2015 Project Jupyter Contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Semver File License
|
||||
===================
|
||||
|
||||
The semver.py file is from https://github.com/podhmo/python-semver
|
||||
which is licensed under the "MIT" license. See the semver.py file for details.
|
||||
|
||||
END OF JupyterLab NOTICES AND INFORMATION
|
||||
|
||||
%% make-error NOTICES AND INFORMATION BEGIN HERE
|
||||
=========================================
|
||||
ISC © Julien Fontanet
|
||||
|
||||
19
appveyor.yml
@@ -1,19 +0,0 @@
|
||||
environment:
|
||||
ELECTRON_RUN_AS_NODE: 1
|
||||
VSCODE_BUILD_VERBOSE: true
|
||||
|
||||
cache:
|
||||
- '%LOCALAPPDATA%\Yarn\cache'
|
||||
|
||||
install:
|
||||
- ps: Install-Product node 8.9.1 x64
|
||||
|
||||
build_script:
|
||||
- yarn
|
||||
- .\node_modules\.bin\gulp electron
|
||||
- npm run compile
|
||||
|
||||
test_script:
|
||||
- node --version
|
||||
- .\scripts\test.bat
|
||||
- .\scripts\test-integration.bat
|
||||
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()
|
||||
26
azure-pipelines-windows.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
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 --reporter mocha-junit-reporter
|
||||
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
|
||||
@@ -129,6 +129,7 @@ const vscodeResources = [
|
||||
'out-build/sql/parts/jobManagement/common/media/*.svg',
|
||||
'out-build/sql/media/objectTypes/*.svg',
|
||||
'out-build/sql/media/icons/*.svg',
|
||||
'out-build/sql/parts/notebook/media/**/*.svg',
|
||||
'!**/test/**'
|
||||
];
|
||||
|
||||
|
||||
@@ -9,20 +9,21 @@
|
||||
"@types/mime": "0.0.29",
|
||||
"@types/minimatch": "^3.0.3",
|
||||
"@types/node": "8.0.33",
|
||||
"@types/xml2js": "0.0.33",
|
||||
"@types/request": "^2.47.0",
|
||||
"@types/xml2js": "0.0.33",
|
||||
"azure-storage": "^2.1.0",
|
||||
"decompress": "^4.2.0",
|
||||
"del": "^3.0.0",
|
||||
"documentdb": "1.13.0",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||
"fs-extra-promise": "^1.0.1",
|
||||
"github-releases": "^0.4.1",
|
||||
"mime": "^1.3.4",
|
||||
"minimist": "^1.2.0",
|
||||
"request": "^2.85.0",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||
"typescript": "2.9.2",
|
||||
"vscode": "^1.0.1",
|
||||
"xml2js": "^0.4.17",
|
||||
"github-releases": "^0.4.1",
|
||||
"request": "^2.85.0"
|
||||
"xml2js": "^0.4.17"
|
||||
},
|
||||
"scripts": {
|
||||
"compile": "tsc -p tsconfig.build.json",
|
||||
@@ -30,4 +31,4 @@
|
||||
"postinstall": "npm run compile",
|
||||
"npmCheckJs": "tsc --noEmit"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
"@types/minimatch@^3.0.3":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||
|
||||
"@types/node@*":
|
||||
version "8.0.51"
|
||||
@@ -570,6 +571,18 @@ deep-assign@^1.0.0:
|
||||
dependencies:
|
||||
is-obj "^1.0.0"
|
||||
|
||||
del@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5"
|
||||
integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=
|
||||
dependencies:
|
||||
globby "^6.1.0"
|
||||
is-path-cwd "^1.0.0"
|
||||
is-path-in-cwd "^1.0.0"
|
||||
p-map "^1.1.1"
|
||||
pify "^3.0.0"
|
||||
rimraf "^2.2.8"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
@@ -941,6 +954,29 @@ glob@^5.0.3:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.0.3:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
|
||||
integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
globby@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c"
|
||||
integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=
|
||||
dependencies:
|
||||
array-union "^1.0.1"
|
||||
glob "^7.0.3"
|
||||
object-assign "^4.0.1"
|
||||
pify "^2.0.0"
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
glogg@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.1.tgz#dcf758e44789cc3f3d32c1f3562a3676e6a34810"
|
||||
@@ -1312,6 +1348,25 @@ is-obj@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
|
||||
integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
|
||||
|
||||
is-path-cwd@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
|
||||
integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=
|
||||
|
||||
is-path-in-cwd@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52"
|
||||
integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==
|
||||
dependencies:
|
||||
is-path-inside "^1.0.0"
|
||||
|
||||
is-path-inside@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
|
||||
integrity sha1-jvW33lBDej/cprToZe96pVy0gDY=
|
||||
dependencies:
|
||||
path-is-inside "^1.0.1"
|
||||
|
||||
is-posix-bracket@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
|
||||
@@ -1777,6 +1832,11 @@ os-tmpdir@~1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
|
||||
|
||||
p-map@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
|
||||
integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==
|
||||
|
||||
parse-glob@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
|
||||
@@ -1797,6 +1857,11 @@ path-is-absolute@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||
|
||||
path-is-inside@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
|
||||
integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
|
||||
|
||||
pause-stream@0.0.11:
|
||||
version "0.0.11"
|
||||
resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
|
||||
@@ -1819,7 +1884,7 @@ performance-now@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
pify@^2.3.0:
|
||||
pify@^2.0.0, pify@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||
integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
|
||||
@@ -2117,7 +2182,7 @@ requires-port@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
||||
|
||||
rimraf@2:
|
||||
rimraf@2, rimraf@^2.2.8:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
|
||||
integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==
|
||||
|
||||
1
docs/UX-Design-Guidelines.md
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"@types/node@^8.0.24":
|
||||
version "8.10.36"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.36.tgz#eac05d576fbcd0b4ea3c912dc58c20475c08d9e4"
|
||||
integrity sha512-SL6KhfM7PTqiFmbCW3eVNwVBZ+88Mrzbuvn9olPsfv43mbiWaFY+nRcz/TGGku0/lc2FepdMbImdMY1JrQ+zbw==
|
||||
|
||||
"@types/node@^8.0.47":
|
||||
version "8.10.30"
|
||||
@@ -41,18 +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"
|
||||
|
||||
ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
|
||||
asn1@0.1.11:
|
||||
version "0.1.11"
|
||||
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7"
|
||||
|
||||
asn1@~0.2.3:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
|
||||
@@ -65,10 +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"
|
||||
|
||||
async@2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.npmjs.org/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
|
||||
@@ -76,9 +61,10 @@ 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==
|
||||
dependencies:
|
||||
lodash "^4.17.10"
|
||||
|
||||
@@ -87,10 +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"
|
||||
|
||||
aws-sign2@~0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||
@@ -129,22 +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"
|
||||
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"
|
||||
|
||||
boom@2.x.x:
|
||||
version "2.10.1"
|
||||
resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
|
||||
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"
|
||||
@@ -163,25 +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"
|
||||
|
||||
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"
|
||||
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"
|
||||
@@ -199,9 +151,10 @@ 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==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
@@ -210,28 +163,15 @@ 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"
|
||||
|
||||
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"
|
||||
|
||||
cryptiles@2.x.x:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
|
||||
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-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
@@ -282,13 +222,15 @@ 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==
|
||||
|
||||
extsprintf@1.3.0:
|
||||
version "1.3.0"
|
||||
@@ -310,17 +252,10 @@ 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"
|
||||
|
||||
form-data@~1.0.0-rc1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c"
|
||||
dependencies:
|
||||
async "^2.0.1"
|
||||
combined-stream "^1.0.5"
|
||||
mime-types "^2.1.11"
|
||||
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
||||
|
||||
form-data@~2.3.2:
|
||||
version "2.3.2"
|
||||
@@ -336,18 +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"
|
||||
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"
|
||||
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"
|
||||
@@ -377,15 +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"
|
||||
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"
|
||||
@@ -394,43 +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"
|
||||
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"
|
||||
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"
|
||||
|
||||
http-signature@~0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-0.11.0.tgz#1796cf67a001ad5cd6849dca0991485f09089fe6"
|
||||
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"
|
||||
@@ -448,33 +335,16 @@ 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=
|
||||
|
||||
is-buffer@^1.1.6:
|
||||
version "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"
|
||||
|
||||
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"
|
||||
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"
|
||||
|
||||
is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
@@ -485,13 +355,10 @@ 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"
|
||||
|
||||
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=
|
||||
|
||||
jsbn@~0.1.0:
|
||||
version "0.1.1"
|
||||
@@ -508,13 +375,10 @@ 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"
|
||||
|
||||
jsonpointer@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
|
||||
jsprim@^1.2.2:
|
||||
version "1.4.1"
|
||||
@@ -553,9 +417,10 @@ 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==
|
||||
dependencies:
|
||||
mime-db "~1.36.0"
|
||||
|
||||
@@ -631,14 +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"
|
||||
|
||||
oauth-sign@~0.8.0:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
||||
|
||||
oauth-sign@~0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
@@ -666,10 +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"
|
||||
|
||||
psl@^1.1.24:
|
||||
version "1.1.29"
|
||||
resolved "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67"
|
||||
@@ -680,53 +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"
|
||||
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
@@ -804,12 +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"
|
||||
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"
|
||||
@@ -826,20 +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"
|
||||
|
||||
stringstream@~0.0.4:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72"
|
||||
|
||||
strip-ansi@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||
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"
|
||||
@@ -847,18 +641,15 @@ 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"
|
||||
|
||||
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==
|
||||
dependencies:
|
||||
psl "^1.1.24"
|
||||
punycode "^1.4.1"
|
||||
@@ -870,10 +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"
|
||||
|
||||
tunnel@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz#d1532254749ed36620fcd1010865495a1fa9d0ae"
|
||||
@@ -898,10 +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"
|
||||
|
||||
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"
|
||||
@@ -934,7 +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"
|
||||
|
||||
xtend@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.7",
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.10",
|
||||
"opener": "^1.4.3",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||
"vscode-extension-telemetry": "0.0.18",
|
||||
|
||||
@@ -11,7 +11,8 @@ agent-base@4, agent-base@^4.1.0:
|
||||
|
||||
applicationinsights@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz#53446b830fe8d5d619eee2a278b31d3d25030927"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.1.tgz#53446b830fe8d5d619eee2a278b31d3d25030927"
|
||||
integrity sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=
|
||||
dependencies:
|
||||
diagnostic-channel "0.2.0"
|
||||
diagnostic-channel-publishers "0.2.1"
|
||||
@@ -35,7 +36,7 @@ buffer-alloc-unsafe@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
|
||||
integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
|
||||
|
||||
buffer-alloc@^1.1.0:
|
||||
buffer-alloc@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
|
||||
integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
|
||||
@@ -74,19 +75,26 @@ core-util-is@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#0.2.7":
|
||||
version "0.2.6"
|
||||
resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/85653d8b305af8aef334728d71f07bdc240dfcb7"
|
||||
"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#0.2.10":
|
||||
version "0.2.10"
|
||||
resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/4de3f7caf0eba54159911b977ddb4f5d7c0a9ca8"
|
||||
dependencies:
|
||||
vscode-languageclient "3.5.1"
|
||||
|
||||
debug@3.1.0, debug@^3.1.0:
|
||||
debug@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.1.0:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1"
|
||||
@@ -142,11 +150,13 @@ decompress@^4.2.0:
|
||||
|
||||
diagnostic-channel-publishers@0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3"
|
||||
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3"
|
||||
integrity sha1-ji1geottef6IC1SLxYzGvrKIxPM=
|
||||
|
||||
diagnostic-channel@0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17"
|
||||
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17"
|
||||
integrity sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=
|
||||
dependencies:
|
||||
semver "^5.3.0"
|
||||
|
||||
@@ -158,9 +168,9 @@ end-of-stream@^1.0.0:
|
||||
once "^1.4.0"
|
||||
|
||||
es6-promise@^4.0.3:
|
||||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29"
|
||||
integrity sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==
|
||||
version "4.2.5"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054"
|
||||
integrity sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==
|
||||
|
||||
es6-promisify@^5.0.0:
|
||||
version "5.0.0"
|
||||
@@ -210,9 +220,9 @@ get-stream@^2.2.0:
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
graceful-fs@^4.1.10:
|
||||
version "4.1.11"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
|
||||
integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=
|
||||
version "4.1.15"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
|
||||
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
|
||||
|
||||
"graceful-readlink@>= 1.0.0":
|
||||
version "1.0.1"
|
||||
@@ -284,6 +294,11 @@ ms@2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
|
||||
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
|
||||
|
||||
object-assign@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
@@ -297,9 +312,9 @@ once@^1.4.0:
|
||||
wrappy "1"
|
||||
|
||||
opener@^1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8"
|
||||
integrity sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
|
||||
integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==
|
||||
|
||||
os-tmpdir@~1.0.2:
|
||||
version "1.0.2"
|
||||
@@ -365,7 +380,8 @@ seek-bzip@^1.0.5:
|
||||
|
||||
semver@^5.3.0:
|
||||
version "5.6.0"
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
|
||||
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
|
||||
|
||||
"service-downloader@github:anthonydresser/service-downloader#0.1.5":
|
||||
version "0.1.5"
|
||||
@@ -393,16 +409,16 @@ strip-dirs@^2.0.0:
|
||||
is-natural-number "^4.0.1"
|
||||
|
||||
tar-stream@^1.5.2:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.1.tgz#f84ef1696269d6223ca48f6e1eeede3f7e81f395"
|
||||
integrity sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555"
|
||||
integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==
|
||||
dependencies:
|
||||
bl "^1.0.0"
|
||||
buffer-alloc "^1.1.0"
|
||||
buffer-alloc "^1.2.0"
|
||||
end-of-stream "^1.0.0"
|
||||
fs-constants "^1.0.0"
|
||||
readable-stream "^2.3.0"
|
||||
to-buffer "^1.1.0"
|
||||
to-buffer "^1.1.1"
|
||||
xtend "^4.0.0"
|
||||
|
||||
through@^2.3.6:
|
||||
@@ -417,15 +433,15 @@ tmp@^0.0.33:
|
||||
dependencies:
|
||||
os-tmpdir "~1.0.2"
|
||||
|
||||
to-buffer@^1.1.0:
|
||||
to-buffer@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80"
|
||||
integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==
|
||||
|
||||
unbzip2-stream@^1.0.9:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz#73a033a567bbbde59654b193c44d48a7e4f43c47"
|
||||
integrity sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz#7854da51622a7e63624221196357803b552966a1"
|
||||
integrity sha512-fIZnvdjblYs7Cru/xC6tCPVhz7JkYcVQQkePwMLyQELzYTds2Xn8QefPVnvdVhhZqubxNA1cASXEH5wcK0Bucw==
|
||||
dependencies:
|
||||
buffer "^3.0.1"
|
||||
through "^2.3.6"
|
||||
@@ -437,7 +453,8 @@ util-deprecate@~1.0.1:
|
||||
|
||||
vscode-extension-telemetry@0.0.18:
|
||||
version "0.0.18"
|
||||
resolved "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327"
|
||||
integrity sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==
|
||||
dependencies:
|
||||
applicationinsights "1.0.1"
|
||||
|
||||
@@ -467,9 +484,9 @@ vscode-languageserver-types@3.5.0:
|
||||
integrity sha1-5I15li8LjgLelV4/UkkI4rGcA3Q=
|
||||
|
||||
vscode-nls@^3.2.1:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398"
|
||||
integrity sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==
|
||||
version "3.2.5"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.5.tgz#25520c1955108036dec607c85e00a522f247f1a4"
|
||||
integrity sha512-ITtoh3V4AkWXMmp3TB97vsMaHRgHhsSFPsUdzlueSL+dRZbSNTZeOmdQv60kjCV306ghPxhDeoNUEm3+EZMuyw==
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
@@ -491,4 +508,5 @@ yauzl@^2.4.2:
|
||||
|
||||
zone.js@0.7.6:
|
||||
version "0.7.6"
|
||||
resolved "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz#fbbc39d3e0261d0986f1ba06306eb3aeb0d22009"
|
||||
resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.7.6.tgz#fbbc39d3e0261d0986f1ba06306eb3aeb0d22009"
|
||||
integrity sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
"onCommand:markdown.showLockedPreviewToSide",
|
||||
"onCommand:markdown.showSource",
|
||||
"onCommand:markdown.showPreviewSecuritySelector",
|
||||
"onWebviewPanel:markdown.preview"
|
||||
"onWebviewPanel:markdown.preview",
|
||||
"onCommand:notebook.showPreview"
|
||||
],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
@@ -77,6 +78,11 @@
|
||||
"command": "markdown.preview.toggleLock",
|
||||
"title": "%markdown.preview.toggleLock.title%",
|
||||
"category": "Markdown"
|
||||
},
|
||||
{
|
||||
"command": "notebook.showPreview",
|
||||
"title": "notebook.showPreview",
|
||||
"category": "Notebook"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
@@ -154,6 +160,10 @@
|
||||
{
|
||||
"command": "markdown.preview.toggleLock",
|
||||
"when": "markdownPreviewFocus"
|
||||
},
|
||||
{
|
||||
"command": "notebook.showPreview",
|
||||
"when": "false"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -8,7 +8,8 @@ import * as vscode from 'vscode';
|
||||
export interface Command {
|
||||
readonly id: string;
|
||||
|
||||
execute(...args: any[]): void;
|
||||
// {{SQL CARBON EDIT}}
|
||||
execute(...args: any[]): any;
|
||||
}
|
||||
|
||||
export class CommandManager {
|
||||
@@ -26,7 +27,8 @@ export class CommandManager {
|
||||
return command;
|
||||
}
|
||||
|
||||
private registerCommand(id: string, impl: (...args: any[]) => void, thisArg?: any) {
|
||||
// {{SQL CARBON EDIT}}
|
||||
private registerCommand(id: string, impl: (...args: any[]) => any, thisArg?: any) {
|
||||
if (this.commands.has(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11,3 +11,5 @@ export { RefreshPreviewCommand } from './refreshPreview';
|
||||
export { ShowPreviewSecuritySelectorCommand } from './showPreviewSecuritySelector';
|
||||
export { MoveCursorToPositionCommand } from './moveCursorToPosition';
|
||||
export { ToggleLockCommand } from './toggleLock';
|
||||
// {{SQL CARBON EDIT}}
|
||||
export { ShowNotebookPreview } from './showNotebookPreview';
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { Command } from '../commandManager';
|
||||
import { MarkdownEngine } from '../markdownEngine';
|
||||
|
||||
export class ShowNotebookPreview implements Command {
|
||||
public readonly id = 'notebook.showPreview';
|
||||
|
||||
public constructor(
|
||||
private readonly engine: MarkdownEngine
|
||||
) { }
|
||||
|
||||
public async execute(document: vscode.Uri, textContent: string): Promise<string> {
|
||||
return this.engine.renderText(document, textContent);
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,8 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
commandManager.register(new commands.OnPreviewStyleLoadErrorCommand());
|
||||
commandManager.register(new commands.OpenDocumentLinkCommand(engine));
|
||||
commandManager.register(new commands.ToggleLockCommand(previewManager));
|
||||
// {{SQL CARBON EDIT}}
|
||||
commandManager.register(new commands.ShowNotebookPreview(engine));
|
||||
|
||||
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => {
|
||||
logger.updateConfiguration();
|
||||
|
||||
@@ -86,6 +86,12 @@ export class MarkdownEngine {
|
||||
return { text, offset };
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
public async renderText(document: vscode.Uri, text: string): Promise<string> {
|
||||
const engine = await this.getEngine(document);
|
||||
return engine.render(text);
|
||||
}
|
||||
|
||||
public async render(document: vscode.Uri, stripFrontmatter: boolean, text: string): Promise<string> {
|
||||
let offset = 0;
|
||||
if (stripFrontmatter) {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"update-grammar": "node ../../build/npm/update-grammar.js Microsoft/vscode-mssql syntaxes/SQL.plist ./syntaxes/sql.tmLanguage.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.8",
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.10",
|
||||
"opener": "^1.4.3",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||
"vscode-extension-telemetry": "^0.0.15"
|
||||
|
||||
@@ -163,6 +163,7 @@
|
||||
"\tFROM INFORMATION_SCHEMA.ROUTINES",
|
||||
"WHERE SPECIFIC_SCHEMA = N'${2:dbo}'",
|
||||
"\tAND SPECIFIC_NAME = N'${1:StoredProcedureName}'",
|
||||
"\tAND ROUTINE_TYPE = N'PROCEDURE'"
|
||||
")",
|
||||
"DROP PROCEDURE ${2:dbo}.${1:StoredProcedureName}",
|
||||
"GO",
|
||||
|
||||
@@ -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.58",
|
||||
"downloadFileNames": {
|
||||
"Windows_86": "win-x86-netcoreapp2.2.zip",
|
||||
"Windows_64": "win-x64-netcoreapp2.2.zip",
|
||||
|
||||
@@ -36,7 +36,7 @@ buffer-alloc-unsafe@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
|
||||
integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
|
||||
|
||||
buffer-alloc@^1.1.0:
|
||||
buffer-alloc@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
|
||||
integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
|
||||
@@ -75,19 +75,26 @@ core-util-is@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#0.2.8":
|
||||
version "0.2.8"
|
||||
resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/3ec3ec3fa63a8dae958c18a85b91fec74c50aec5"
|
||||
"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#0.2.10":
|
||||
version "0.2.10"
|
||||
resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/4de3f7caf0eba54159911b977ddb4f5d7c0a9ca8"
|
||||
dependencies:
|
||||
vscode-languageclient "3.5.1"
|
||||
|
||||
debug@3.1.0, debug@^3.1.0:
|
||||
debug@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.1.0:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1"
|
||||
@@ -161,9 +168,9 @@ end-of-stream@^1.0.0:
|
||||
once "^1.4.0"
|
||||
|
||||
es6-promise@^4.0.3:
|
||||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29"
|
||||
integrity sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==
|
||||
version "4.2.5"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054"
|
||||
integrity sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==
|
||||
|
||||
es6-promisify@^5.0.0:
|
||||
version "5.0.0"
|
||||
@@ -213,9 +220,9 @@ get-stream@^2.2.0:
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
graceful-fs@^4.1.10:
|
||||
version "4.1.11"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
|
||||
integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=
|
||||
version "4.1.15"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
|
||||
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
|
||||
|
||||
"graceful-readlink@>= 1.0.0":
|
||||
version "1.0.1"
|
||||
@@ -287,6 +294,11 @@ ms@2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
|
||||
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
|
||||
|
||||
object-assign@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
@@ -300,9 +312,9 @@ once@^1.4.0:
|
||||
wrappy "1"
|
||||
|
||||
opener@^1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8"
|
||||
integrity sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
|
||||
integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==
|
||||
|
||||
os-tmpdir@~1.0.2:
|
||||
version "1.0.2"
|
||||
@@ -367,9 +379,9 @@ seek-bzip@^1.0.5:
|
||||
commander "~2.8.1"
|
||||
|
||||
semver@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
||||
integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
|
||||
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
|
||||
|
||||
"service-downloader@github:anthonydresser/service-downloader#0.1.5":
|
||||
version "0.1.5"
|
||||
@@ -397,16 +409,16 @@ strip-dirs@^2.0.0:
|
||||
is-natural-number "^4.0.1"
|
||||
|
||||
tar-stream@^1.5.2:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.1.tgz#f84ef1696269d6223ca48f6e1eeede3f7e81f395"
|
||||
integrity sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555"
|
||||
integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==
|
||||
dependencies:
|
||||
bl "^1.0.0"
|
||||
buffer-alloc "^1.1.0"
|
||||
buffer-alloc "^1.2.0"
|
||||
end-of-stream "^1.0.0"
|
||||
fs-constants "^1.0.0"
|
||||
readable-stream "^2.3.0"
|
||||
to-buffer "^1.1.0"
|
||||
to-buffer "^1.1.1"
|
||||
xtend "^4.0.0"
|
||||
|
||||
through@^2.3.6:
|
||||
@@ -421,15 +433,15 @@ tmp@^0.0.33:
|
||||
dependencies:
|
||||
os-tmpdir "~1.0.2"
|
||||
|
||||
to-buffer@^1.1.0:
|
||||
to-buffer@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80"
|
||||
integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==
|
||||
|
||||
unbzip2-stream@^1.0.9:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz#73a033a567bbbde59654b193c44d48a7e4f43c47"
|
||||
integrity sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz#7854da51622a7e63624221196357803b552966a1"
|
||||
integrity sha512-fIZnvdjblYs7Cru/xC6tCPVhz7JkYcVQQkePwMLyQELzYTds2Xn8QefPVnvdVhhZqubxNA1cASXEH5wcK0Bucw==
|
||||
dependencies:
|
||||
buffer "^3.0.1"
|
||||
through "^2.3.6"
|
||||
|
||||
@@ -12,13 +12,10 @@ import { CreateSessionData } from '../data/createSessionData';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export class CreateSessionDialog {
|
||||
private readonly _providerType: string;
|
||||
|
||||
// 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');
|
||||
private readonly CreateButtonText: string = localize('createSessionDialog.create', 'Start');
|
||||
private readonly DialogTitleText: string = localize('createSessionDialog.title', 'Start New Profiler Session');
|
||||
|
||||
// UI Components
|
||||
private dialog: sqlops.window.modelviewdialog.Dialog;
|
||||
@@ -26,6 +23,7 @@ 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;
|
||||
@@ -46,7 +44,7 @@ export class CreateSessionDialog {
|
||||
}
|
||||
|
||||
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(() => { });
|
||||
@@ -70,6 +68,10 @@ export class CreateSessionDialog {
|
||||
value: ''
|
||||
}).component();
|
||||
|
||||
this.templatesBox.onValueChanged(() => {
|
||||
this.updateSessionName();
|
||||
});
|
||||
|
||||
let formModel = view.modelBuilder.formContainer()
|
||||
.withFormItems([{
|
||||
components: [{
|
||||
@@ -81,13 +83,14 @@ export class CreateSessionDialog {
|
||||
|
||||
title: localize('createSessionDialog.enterSessionName', "Enter session name:")
|
||||
}],
|
||||
title: this.DialogTitleText
|
||||
title: ''
|
||||
}]).withLayout({ width: '100%' }).component();
|
||||
|
||||
await view.initializeModel(formModel);
|
||||
|
||||
if (this.model.templates) {
|
||||
this.templatesBox.values = this.model.getTemplateNames();
|
||||
this.updateSessionName();
|
||||
}
|
||||
|
||||
this.sessionNameBox.onTextChanged(() => {
|
||||
@@ -101,6 +104,12 @@ export class CreateSessionDialog {
|
||||
});
|
||||
}
|
||||
|
||||
private updateSessionName() {
|
||||
if (this.templatesBox.value) {
|
||||
this.sessionNameBox.value = `ADS_${this.templatesBox.value.toString()}`
|
||||
}
|
||||
}
|
||||
|
||||
private async execute(): Promise<void> {
|
||||
let profilerService = sqlops.dataprotocol.getProvider<sqlops.ProfilerProvider>(this._providerType, sqlops.DataProviderType.ProfilerProvider);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "profiler",
|
||||
"displayName": "SQL Server Profiler",
|
||||
"description": "SQL Server Profiler for Azure Data Studio",
|
||||
"version": "0.3.0",
|
||||
"version": "0.5.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
|
||||
@@ -29,7 +29,7 @@
|
||||
"commands": [
|
||||
{
|
||||
"command": "profiler.newProfiler",
|
||||
"title": "New Profiler",
|
||||
"title": "Launch Profiler",
|
||||
"category": "Profiler"
|
||||
},
|
||||
{
|
||||
|
||||
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "azuredatastudio",
|
||||
"version": "1.2.4",
|
||||
"version": "1.3.3",
|
||||
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
@@ -37,8 +37,10 @@
|
||||
"@angular/router": "~4.1.3",
|
||||
"@angular/upgrade": "~4.1.3",
|
||||
"@types/chart.js": "^2.7.31",
|
||||
"@types/htmlparser2": "^3.7.31",
|
||||
"angular2-grid": "2.0.6",
|
||||
"angular2-slickgrid": "github:Microsoft/angular2-slickgrid#1.4.6",
|
||||
"ansi_up": "^3.0.0",
|
||||
"applicationinsights": "0.18.0",
|
||||
"chart.js": "^2.6.0",
|
||||
"fast-plist": "0.1.2",
|
||||
@@ -64,8 +66,9 @@
|
||||
"pretty-data": "^0.40.0",
|
||||
"reflect-metadata": "^0.1.8",
|
||||
"rxjs": "5.4.0",
|
||||
"sanitize-html": "^1.19.1",
|
||||
"semver": "^5.5.0",
|
||||
"slickgrid": "github:anthonydresser/SlickGrid#2.3.28",
|
||||
"slickgrid": "github:anthonydresser/SlickGrid#2.3.29",
|
||||
"spdlog": "0.7.1",
|
||||
"sudo-prompt": "8.2.0",
|
||||
"svg.js": "^2.2.5",
|
||||
@@ -85,6 +88,7 @@
|
||||
"@types/keytar": "4.0.1",
|
||||
"@types/minimist": "1.2.0",
|
||||
"@types/mocha": "2.2.39",
|
||||
"@types/sanitize-html": "^1.18.2",
|
||||
"@types/semver": "5.3.30",
|
||||
"@types/sinon": "1.16.34",
|
||||
"@types/winreg": "^1.2.30",
|
||||
@@ -98,7 +102,7 @@
|
||||
"documentdb": "^1.5.1",
|
||||
"electron-mksnapshot": "~1.7.0",
|
||||
"eslint": "^3.4.0",
|
||||
"event-stream": "^3.1.7",
|
||||
"event-stream": "^3.3.4",
|
||||
"express": "^4.13.1",
|
||||
"glob": "^5.0.13",
|
||||
"gulp": "^3.9.1",
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 "$@"
|
||||
|
||||
@@ -236,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -28,8 +28,11 @@ export class RadioButton extends Widget {
|
||||
super();
|
||||
this.inputElement = document.createElement('input');
|
||||
this.inputElement.type = 'radio';
|
||||
this.inputElement.style.verticalAlign = 'middle';
|
||||
this.inputElement.style.margin = '3px';
|
||||
|
||||
this._label = document.createElement('span');
|
||||
this._label.style.verticalAlign = 'middle';
|
||||
|
||||
this.label = opts.label;
|
||||
this.enabled = opts.enabled || true;
|
||||
|
||||
10
src/sql/base/browser/ui/selectBox/media/selectBox.css
Normal file
@@ -0,0 +1,10 @@
|
||||
.labelOnTopContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.labelOnLeftContainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-right: 5px;
|
||||
}
|
||||
@@ -4,6 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
import 'vs/css!./media/selectBox';
|
||||
|
||||
import { SelectBox as vsSelectBox, ISelectBoxStyles as vsISelectBoxStyles, ISelectBoxOptions } from 'vs/base/browser/ui/selectBox/selectBox';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { IContextViewProvider, AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
@@ -30,6 +32,7 @@ export class SelectBox extends vsSelectBox {
|
||||
private _optionsDictionary;
|
||||
private _dialogOptions: string[];
|
||||
private _selectedOption: string;
|
||||
private _selectBoxOptions: ISelectBoxOptions;
|
||||
private enabledSelectBackground: Color;
|
||||
private enabledSelectForeground: Color;
|
||||
private enabledSelectBorder: Color;
|
||||
@@ -72,6 +75,7 @@ export class SelectBox extends vsSelectBox {
|
||||
|
||||
// explicitly set the accessible role so that the screen readers can read the control type properly
|
||||
this.selectElement.setAttribute('role', 'combobox');
|
||||
this._selectBoxOptions = selectBoxOptions;
|
||||
}
|
||||
|
||||
public style(styles: ISelectBoxStyles): void {
|
||||
@@ -118,6 +122,10 @@ export class SelectBox extends vsSelectBox {
|
||||
return this._selectedOption;
|
||||
}
|
||||
|
||||
public get values(): string[] {
|
||||
return this._dialogOptions;
|
||||
}
|
||||
|
||||
public enable(): void {
|
||||
this.selectElement.disabled = false;
|
||||
this.selectBackground = this.enabledSelectBackground;
|
||||
@@ -226,4 +234,34 @@ export class SelectBox extends vsSelectBox {
|
||||
default: return { border: this.inputValidationErrorBorder, background: this.inputValidationErrorBackground };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public render(container: HTMLElement): void {
|
||||
let selectOptions: ISelectBoxOptionsWithLabel = this._selectBoxOptions as ISelectBoxOptionsWithLabel;
|
||||
|
||||
if (selectOptions && selectOptions.labelText && selectOptions.labelText !== undefined) {
|
||||
let outerContainer = document.createElement('div');
|
||||
let selectContainer = document.createElement('div');
|
||||
|
||||
outerContainer.className = selectOptions.labelOnTop ? 'labelOnTopContainer' : 'labelOnLeftContainer';
|
||||
|
||||
let labelText = document.createElement('div');
|
||||
labelText.className = 'action-item-label';
|
||||
labelText.innerHTML = selectOptions.labelText;
|
||||
|
||||
container.appendChild(outerContainer);
|
||||
outerContainer.appendChild(labelText);
|
||||
outerContainer.appendChild(selectContainer);
|
||||
|
||||
super.render(selectContainer);
|
||||
this.selectElement.classList.add('action-item-label');
|
||||
}
|
||||
else {
|
||||
super.render(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface ISelectBoxOptionsWithLabel extends ISelectBoxOptions {
|
||||
labelText?: string;
|
||||
labelOnTop?: boolean;
|
||||
}
|
||||
|
||||
@@ -9,36 +9,27 @@ 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;
|
||||
setCollectionChangedCallback(callback: (startIndex: number, count: number) => void): void;
|
||||
setLength(number): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export interface IGridDataRow {
|
||||
row?: number;
|
||||
values: any[];
|
||||
}
|
||||
|
||||
export enum CollectionChange {
|
||||
ItemsReplaced
|
||||
}
|
||||
|
||||
class LoadCancellationToken {
|
||||
isCancelled: boolean;
|
||||
}
|
||||
|
||||
class DataWindow<TData> {
|
||||
private _data: TData[];
|
||||
class DataWindow<T> {
|
||||
private _data: T[];
|
||||
private _length: number = 0;
|
||||
private _offsetFromDataSource: number = -1;
|
||||
|
||||
private lastLoadCancellationToken: LoadCancellationToken;
|
||||
|
||||
constructor(
|
||||
private loadFunction: (offset: number, count: number) => Thenable<TData[]>,
|
||||
private placeholderItemGenerator: (index: number) => TData,
|
||||
private loadFunction: (offset: number, count: number) => Thenable<T[]>,
|
||||
private placeholderItemGenerator: (index: number) => T,
|
||||
private loadCompleteCallback: (start: number, end: number) => void
|
||||
) {
|
||||
}
|
||||
) { }
|
||||
|
||||
dispose() {
|
||||
this._data = undefined;
|
||||
@@ -50,26 +41,26 @@ class DataWindow<TData> {
|
||||
}
|
||||
}
|
||||
|
||||
getStartIndex(): number {
|
||||
public getStartIndex(): number {
|
||||
return this._offsetFromDataSource;
|
||||
}
|
||||
|
||||
getEndIndex(): number {
|
||||
public getEndIndex(): number {
|
||||
return this._offsetFromDataSource + this._length;
|
||||
}
|
||||
|
||||
contains(dataSourceIndex: number): boolean {
|
||||
public contains(dataSourceIndex: number): boolean {
|
||||
return dataSourceIndex >= this.getStartIndex() && dataSourceIndex < this.getEndIndex();
|
||||
}
|
||||
|
||||
getItem(index: number): TData {
|
||||
public getItem(index: number): T {
|
||||
if (!this._data) {
|
||||
return this.placeholderItemGenerator(index);
|
||||
}
|
||||
return this._data[index - this._offsetFromDataSource];
|
||||
}
|
||||
|
||||
positionWindow(offset: number, length: number): void {
|
||||
public positionWindow(offset: number, length: number): void {
|
||||
this._offsetFromDataSource = offset;
|
||||
this._length = length;
|
||||
this._data = undefined;
|
||||
@@ -92,34 +83,28 @@ class DataWindow<TData> {
|
||||
}
|
||||
}
|
||||
|
||||
export class VirtualizedCollection<TData> implements IObservableCollection<TData> {
|
||||
export class VirtualizedCollection<T extends Slick.SlickData> implements IObservableCollection<T> {
|
||||
private _bufferWindowBefore: DataWindow<T>;
|
||||
private _window: DataWindow<T>;
|
||||
private _bufferWindowAfter: DataWindow<T>;
|
||||
|
||||
private _length: number;
|
||||
private _windowSize: number;
|
||||
private _bufferWindowBefore: DataWindow<TData>;
|
||||
private _window: DataWindow<TData>;
|
||||
private _bufferWindowAfter: DataWindow<TData>;
|
||||
|
||||
private collectionChangedCallback: (change: CollectionChange, startIndex: number, count: number) => void;
|
||||
private collectionChangedCallback: (startIndex: number, count: number) => void;
|
||||
|
||||
constructor(
|
||||
windowSize: number,
|
||||
length: number,
|
||||
loadFn: (offset: number, count: number) => Thenable<TData[]>,
|
||||
private _placeHolderGenerator: (index: number) => TData
|
||||
private readonly windowSize: number,
|
||||
private placeHolderGenerator: (index: number) => T,
|
||||
private length: number,
|
||||
loadFn: (offset: number, count: number) => Thenable<T[]>
|
||||
) {
|
||||
this._windowSize = windowSize;
|
||||
this._length = length;
|
||||
|
||||
let loadCompleteCallback = (start: number, end: number) => {
|
||||
if (this.collectionChangedCallback) {
|
||||
this.collectionChangedCallback(CollectionChange.ItemsReplaced, start, end - start);
|
||||
this.collectionChangedCallback(start, end - start);
|
||||
}
|
||||
};
|
||||
|
||||
this._bufferWindowBefore = new DataWindow(loadFn, _placeHolderGenerator, loadCompleteCallback);
|
||||
this._window = new DataWindow(loadFn, _placeHolderGenerator, loadCompleteCallback);
|
||||
this._bufferWindowAfter = new DataWindow(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() {
|
||||
@@ -128,19 +113,23 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
|
||||
this._window.dispose();
|
||||
}
|
||||
|
||||
setCollectionChangedCallback(callback: (change: CollectionChange, startIndex: number, count: number) => void): void {
|
||||
public setCollectionChangedCallback(callback: (startIndex: number, count: number) => void): void {
|
||||
this.collectionChangedCallback = callback;
|
||||
}
|
||||
|
||||
getLength(): number {
|
||||
return this._length;
|
||||
public getLength(): number {
|
||||
return this.length;
|
||||
}
|
||||
|
||||
at(index: number): TData {
|
||||
setLength(number: any): void {
|
||||
this.length = number;
|
||||
}
|
||||
|
||||
public at(index: number): T {
|
||||
return this.getRange(index, index + 1)[0];
|
||||
}
|
||||
|
||||
getRange(start: number, end: number): TData[] {
|
||||
public getRange(start: number, end: number): T[] {
|
||||
|
||||
// current data may contain placeholders
|
||||
let currentData = this.getRangeFromCurrent(start, end);
|
||||
@@ -155,7 +144,7 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
|
||||
this._bufferWindowAfter = this._window;
|
||||
this._window = this._bufferWindowBefore;
|
||||
this._bufferWindowBefore = windowToRecycle;
|
||||
let newWindowOffset = Math.max(0, this._window.getStartIndex() - this._windowSize);
|
||||
let newWindowOffset = Math.max(0, this._window.getStartIndex() - this.windowSize);
|
||||
|
||||
this._bufferWindowBefore.positionWindow(newWindowOffset, this._window.getStartIndex() - newWindowOffset);
|
||||
} else if (start >= this._bufferWindowAfter.getStartIndex()) {
|
||||
@@ -164,8 +153,8 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
|
||||
this._bufferWindowBefore = this._window;
|
||||
this._window = this._bufferWindowAfter;
|
||||
this._bufferWindowAfter = windowToRecycle;
|
||||
let newWindowOffset = Math.min(this._window.getStartIndex() + this._windowSize, this._length);
|
||||
let newWindowLength = Math.min(this._length - newWindowOffset, this._windowSize);
|
||||
let newWindowOffset = Math.min(this._window.getStartIndex() + this.windowSize, this.length);
|
||||
let newWindowLength = Math.min(this.length - newWindowOffset, this.windowSize);
|
||||
|
||||
this._bufferWindowAfter.positionWindow(newWindowOffset, newWindowLength);
|
||||
}
|
||||
@@ -173,7 +162,7 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
|
||||
return currentData;
|
||||
}
|
||||
|
||||
private getRangeFromCurrent(start: number, end: number): TData[] {
|
||||
private getRangeFromCurrent(start: number, end: number): T[] {
|
||||
let currentData = [];
|
||||
for (let i = 0; i < end - start; i++) {
|
||||
currentData.push(this.getDataFromCurrent(start + i));
|
||||
@@ -182,7 +171,7 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
|
||||
return currentData;
|
||||
}
|
||||
|
||||
private getDataFromCurrent(index: number): TData {
|
||||
private getDataFromCurrent(index: number): T {
|
||||
if (this._bufferWindowBefore.contains(index)) {
|
||||
return this._bufferWindowBefore.getItem(index);
|
||||
} else if (this._bufferWindowAfter.contains(index)) {
|
||||
@@ -191,39 +180,47 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
|
||||
return this._window.getItem(index);
|
||||
}
|
||||
|
||||
return this._placeHolderGenerator(index);
|
||||
return this.placeHolderGenerator(index);
|
||||
}
|
||||
|
||||
private resetWindowsAroundIndex(index: number): void {
|
||||
|
||||
let bufferWindowBeforeStart = Math.max(0, index - this._windowSize * 1.5);
|
||||
let bufferWindowBeforeEnd = Math.max(0, index - this._windowSize / 2);
|
||||
let bufferWindowBeforeStart = Math.max(0, index - this.windowSize * 1.5);
|
||||
let bufferWindowBeforeEnd = Math.max(0, index - this.windowSize / 2);
|
||||
this._bufferWindowBefore.positionWindow(bufferWindowBeforeStart, bufferWindowBeforeEnd - bufferWindowBeforeStart);
|
||||
|
||||
let mainWindowStart = bufferWindowBeforeEnd;
|
||||
let mainWindowEnd = Math.min(mainWindowStart + this._windowSize, this._length);
|
||||
let mainWindowEnd = Math.min(mainWindowStart + this.windowSize, this.length);
|
||||
this._window.positionWindow(mainWindowStart, mainWindowEnd - mainWindowStart);
|
||||
|
||||
let bufferWindowAfterStart = mainWindowEnd;
|
||||
let bufferWindowAfterEnd = Math.min(bufferWindowAfterStart + this._windowSize, this._length);
|
||||
let bufferWindowAfterEnd = Math.min(bufferWindowAfterStart + this.windowSize, this.length);
|
||||
this._bufferWindowAfter.positionWindow(bufferWindowAfterStart, bufferWindowAfterEnd - bufferWindowAfterStart);
|
||||
}
|
||||
}
|
||||
|
||||
export class AsyncDataProvider<TData extends IGridDataRow> implements IDisposableDataProvider<TData> {
|
||||
export class AsyncDataProvider<T extends Slick.SlickData> implements IDisposableDataProvider<T> {
|
||||
|
||||
constructor(private dataRows: IObservableCollection<TData>) { }
|
||||
constructor(public dataRows: IObservableCollection<T>) { }
|
||||
|
||||
public getLength(): number {
|
||||
return this.dataRows ? this.dataRows.getLength() : 0;
|
||||
return this.dataRows.getLength();
|
||||
}
|
||||
|
||||
public getItem(index: number): TData {
|
||||
return !this.dataRows ? undefined : this.dataRows.at(index);
|
||||
public getItem(index: number): T {
|
||||
return this.dataRows.at(index);
|
||||
}
|
||||
|
||||
public getRange(start: number, end: number): TData[] {
|
||||
return !this.dataRows ? undefined : this.dataRows.getRange(start, end);
|
||||
public getRange(start: number, end: number): T[] {
|
||||
return this.dataRows.getRange(start, end);
|
||||
}
|
||||
|
||||
public set length(length: number) {
|
||||
this.dataRows.setLength(length);
|
||||
}
|
||||
|
||||
public get length(): number {
|
||||
return this.dataRows.getLength();
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { range } from 'vs/base/common/arrays';
|
||||
|
||||
export interface IRowNumberColumnOptions {
|
||||
numberOfRows: number;
|
||||
cssClass?: string;
|
||||
@@ -17,7 +15,7 @@ const sizePerDigit = 15;
|
||||
export class RowNumberColumn<T> implements Slick.Plugin<T> {
|
||||
private handler = new Slick.EventHandler();
|
||||
private grid: Slick.Grid<T>;
|
||||
|
||||
private currentColumnWidth: number;
|
||||
|
||||
constructor(private options: IRowNumberColumnOptions) {
|
||||
}
|
||||
@@ -52,19 +50,25 @@ export class RowNumberColumn<T> implements Slick.Plugin<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public updateRowCount(rowNum: number) {
|
||||
this.options.numberOfRows = rowNum;
|
||||
let columnWidth = Math.max(this.options.numberOfRows.toString().length * sizePerDigit, 22);
|
||||
if (columnWidth !== this.currentColumnWidth) {
|
||||
this.grid.setColumnWidths([this.getColumnDefinition()]);
|
||||
}
|
||||
}
|
||||
|
||||
public getColumnDefinition(): Slick.Column<T> {
|
||||
// that smallest we can make it is 22 due to padding and margins in the cells
|
||||
let columnWidth = Math.max(this.options.numberOfRows.toString().length * sizePerDigit, 22);
|
||||
this.currentColumnWidth = Math.max(this.options.numberOfRows.toString().length * sizePerDigit, 22);
|
||||
return {
|
||||
id: 'rowNumber',
|
||||
name: '',
|
||||
field: 'rowNumber',
|
||||
width: columnWidth,
|
||||
minWidth: columnWidth,
|
||||
maxWidth: columnWidth,
|
||||
width: this.currentColumnWidth,
|
||||
resizable: false,
|
||||
cssClass: this.options.cssClass,
|
||||
focusable: false,
|
||||
focusable: true,
|
||||
selectable: false,
|
||||
formatter: (r, c, v, cd, dc) => this.formatter(r, c, v, cd, dc)
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
.carbon-taskbar {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
margin: 2px 0px 2px 0px;
|
||||
}
|
||||
|
||||
.carbon-taskbar.monaco-toolbar .monaco-action-bar.animated .actions-container {
|
||||
@@ -39,11 +40,6 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.carbon-taskbar {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.carbon-taskbar .action-item {
|
||||
margin-right: 5px;
|
||||
}
|
||||
@@ -54,6 +50,11 @@
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.carbon-taskbar .action-item-label {
|
||||
display: flex;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.listDatabasesSelectBox {
|
||||
padding-left: 2px;
|
||||
min-width: 100px;
|
||||
|
||||
@@ -146,4 +146,5 @@ export class Taskbar {
|
||||
public dispose(): void {
|
||||
this.actionBar.dispose();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 |
@@ -3,15 +3,22 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as path from 'path';
|
||||
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { EditorInput, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||
import { FileEditorInput } from 'vs/workbench/parts/files/common/editors/fileEditorInput';
|
||||
import URI from 'vs/base/common/uri';
|
||||
|
||||
import { QueryResultsInput } from 'sql/parts/query/common/queryResultsInput';
|
||||
import { QueryInput } from 'sql/parts/query/common/queryInput';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IQueryEditorOptions } from 'sql/parts/query/common/queryEditorService';
|
||||
import { QueryPlanInput } from 'sql/parts/queryPlan/queryPlanInput';
|
||||
import { NotebookInput, NotebookInputModel, NotebookInputValidator } from 'sql/parts/notebook/notebookInput';
|
||||
import { Extensions, INotebookProviderRegistry } from 'sql/services/notebook/notebookRegistry';
|
||||
import { DEFAULT_NOTEBOOK_PROVIDER } from 'sql/services/notebook/notebookService';
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
@@ -28,7 +35,7 @@ export const sqlModeId = 'sql';
|
||||
* to that type.
|
||||
* @param input The input to check for conversion
|
||||
* @param options Editor options for controlling the conversion
|
||||
* @param instantiationService The instatianation service to use to create the new input types
|
||||
* @param instantiationService The instantiation service to use to create the new input types
|
||||
*/
|
||||
export function convertEditorInput(input: EditorInput, options: IQueryEditorOptions, instantiationService: IInstantiationService): EditorInput {
|
||||
let denyQueryEditor = options && options.denyQueryEditor;
|
||||
@@ -48,8 +55,25 @@ export function convertEditorInput(input: EditorInput, options: IQueryEditorOpti
|
||||
let queryPlanInput: QueryPlanInput = instantiationService.createInstance(QueryPlanInput, queryPlanXml, 'aaa', undefined);
|
||||
return queryPlanInput;
|
||||
}
|
||||
}
|
||||
|
||||
//Notebook
|
||||
let notebookValidator = instantiationService.createInstance(NotebookInputValidator);
|
||||
uri = getNotebookEditorUri(input);
|
||||
if(uri && notebookValidator.isNotebookEnabled()){
|
||||
//TODO: We need to pass in notebook data either through notebook input or notebook service
|
||||
let fileName: string = 'untitled';
|
||||
let providerId: string = DEFAULT_NOTEBOOK_PROVIDER;
|
||||
if (input) {
|
||||
fileName = input.getName();
|
||||
providerId = getProviderForFileName(fileName);
|
||||
}
|
||||
let notebookInputModel = new NotebookInputModel(uri, undefined, false, undefined);
|
||||
notebookInputModel.providerId = providerId;
|
||||
//TO DO: Second parameter has to be the content.
|
||||
let notebookInput: NotebookInput = instantiationService.createInstance(NotebookInput, fileName, notebookInputModel);
|
||||
return notebookInput;
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
@@ -129,6 +153,47 @@ function getQueryPlanEditorUri(input: EditorInput): URI {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If input is a supported notebook editor file (.ipynb), return it's URI. Otherwise return undefined.
|
||||
* @param input The EditorInput to get the URI of.
|
||||
*/
|
||||
function getNotebookEditorUri(input: EditorInput): URI {
|
||||
if (!input || !input.getName()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// If this editor is not already of type notebook input
|
||||
if (!(input instanceof NotebookInput)) {
|
||||
let uri: URI = getSupportedInputResource(input);
|
||||
if (uri) {
|
||||
if (hasFileExtension(getNotebookFileExtensions(), input, false)) {
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getNotebookFileExtensions() {
|
||||
let notebookRegistry = Registry.as<INotebookProviderRegistry>(Extensions.NotebookProviderContribution);
|
||||
return notebookRegistry.getSupportedFileExtensions();
|
||||
}
|
||||
|
||||
function getProviderForFileName(fileName: string) {
|
||||
let fileExt = path.extname(fileName);
|
||||
if (fileExt && fileExt.startsWith('.')) {
|
||||
fileExt = fileExt.slice(1,fileExt.length);
|
||||
let notebookRegistry = Registry.as<INotebookProviderRegistry>(Extensions.NotebookProviderContribution);
|
||||
return notebookRegistry.getProviderForFileType(fileExt);
|
||||
}
|
||||
return DEFAULT_NOTEBOOK_PROVIDER;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the given EditorInput is set to either undefined or sql mode
|
||||
* @param input The EditorInput to check the mode of
|
||||
|
||||
@@ -83,6 +83,8 @@ export class ConnectionDialogWidget extends Modal {
|
||||
private _onResetConnection = new Emitter<void>();
|
||||
public onResetConnection: Event<void> = this._onResetConnection.event;
|
||||
|
||||
private _connecting = false;
|
||||
|
||||
constructor(
|
||||
private providerTypeOptions: string[],
|
||||
private selectedProviderType: string,
|
||||
@@ -248,6 +250,7 @@ export class ConnectionDialogWidget extends Modal {
|
||||
|
||||
private connect(element?: IConnectionProfile): void {
|
||||
if (this._connectButton.enabled) {
|
||||
this._connecting = true;
|
||||
this._connectButton.enabled = false;
|
||||
this._providerTypeSelectBox.disable();
|
||||
this.showSpinner();
|
||||
@@ -268,8 +271,9 @@ export class ConnectionDialogWidget extends Modal {
|
||||
}
|
||||
|
||||
private cancel() {
|
||||
let wasConnecting = this._connecting;
|
||||
this._onCancel.fire();
|
||||
if (!this._databaseDropdownExpanded) {
|
||||
if (!this._databaseDropdownExpanded && !wasConnecting) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
@@ -426,6 +430,7 @@ export class ConnectionDialogWidget extends Modal {
|
||||
this._connectButton.enabled = true;
|
||||
this._providerTypeSelectBox.enable();
|
||||
this._onResetConnection.fire();
|
||||
this._connecting = false;
|
||||
}
|
||||
|
||||
public get newConnectionParams(): INewConnectionParams {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { $ } from 'vs/base/browser/dom';
|
||||
import { escape } from 'sql/base/common/strings';
|
||||
|
||||
export class DBCellValue {
|
||||
@@ -41,20 +40,24 @@ export function hyperLinkFormatter(row: number, cell: any, value: any, columnDef
|
||||
*/
|
||||
export function textFormatter(row: number, cell: any, value: any, columnDef: any, dataContext: any): string {
|
||||
let cellClasses = 'grid-cell-value-container';
|
||||
let valueToDisplay: string = '';
|
||||
let valueToDisplay = '';
|
||||
let titleValue = '';
|
||||
|
||||
if (DBCellValue.isDBCellValue(value)) {
|
||||
valueToDisplay = 'NULL';
|
||||
if (!value.isNull) {
|
||||
valueToDisplay = escape(value.displayValue.replace(/(\r\n|\n|\r)/g, ' '));
|
||||
valueToDisplay = value.displayValue.replace(/(\r\n|\n|\r)/g, ' ');
|
||||
valueToDisplay = escape(valueToDisplay.length > 250 ? valueToDisplay.slice(0, 250) + '...' : valueToDisplay);
|
||||
titleValue = value.displayValue;
|
||||
} else {
|
||||
cellClasses += ' missing-value';
|
||||
}
|
||||
} else if (typeof value === 'string') {
|
||||
valueToDisplay = escape(value);
|
||||
valueToDisplay = escape(value.length > 250 ? value.slice(0, 250) + '...' : value);
|
||||
titleValue = value;
|
||||
}
|
||||
|
||||
return `<span title="${valueToDisplay}" class="${cellClasses}">${valueToDisplay}</span>`;
|
||||
return `<span title="${titleValue}" class="${cellClasses}">${valueToDisplay}</span>`;
|
||||
}
|
||||
|
||||
/** The following code is a rewrite over the both formatter function using dom builder
|
||||
|
||||
@@ -33,7 +33,7 @@ export class JobManagementUtilities {
|
||||
case(4): return nls.localize('agentUtilities.idle', 'Idle');
|
||||
case(5): return nls.localize('agentUtilities.suspended', 'Suspended');
|
||||
case(6): return nls.localize('agentUtilities.obsolete', '[Obsolete]');
|
||||
case(7): return nls.localize('agentUtilities.performingCompletionActions', 'PerformingCompletionActions');
|
||||
case(7): return 'PerformingCompletionActions';
|
||||
default: return nls.localize('agentUtilities.statusUnknown', 'Status Unknown');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,15 +304,15 @@ table.jobprevruns > tbody {
|
||||
background-image: url('refresh_inverse.svg');
|
||||
}
|
||||
|
||||
.actionbar-container .monaco-action-bar > ul.actions-container {
|
||||
.agent-actionbar-container .monaco-action-bar > ul.actions-container {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
jobsview-component .actionbar-container {
|
||||
jobsview-component .agent-actionbar-container {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.actionbar-container .monaco-action-bar > ul.actions-container > li.action-item {
|
||||
.agent-actionbar-container .monaco-action-bar > ul.actions-container > li.action-item {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,6 @@
|
||||
<div class="icon in-progress" *ngIf="_showProgressWheel === true"></div>
|
||||
</div>
|
||||
|
||||
<div #actionbarContainer class="actionbar-container"></div>
|
||||
<div #actionbarContainer class="agent-actionbar-container"></div>
|
||||
|
||||
<div #jobalertsgrid class="jobalertsview-grid"></div>
|
||||
|
||||
@@ -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 @@
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div #actionbarContainer class="actionbar-container"></div>
|
||||
<div #actionbarContainer class="agent-actionbar-container"></div>
|
||||
|
||||
<!-- Overview -->
|
||||
<div class="overview-container">
|
||||
|
||||
@@ -257,14 +257,14 @@ jobhistory-component > .jobhistory-heading-container > .icon.in-progress {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
jobhistory-component > .actionbar-container .monaco-action-bar > ul.actions-container {
|
||||
jobhistory-component > .agent-actionbar-container .monaco-action-bar > ul.actions-container {
|
||||
border-top: 3px solid #f4f4f4;
|
||||
}
|
||||
|
||||
.vs-dark jobhistory-component > .actionbar-container .monaco-action-bar > ul.actions-container {
|
||||
.vs-dark jobhistory-component > .agent-actionbar-container .monaco-action-bar > ul.actions-container {
|
||||
border-top: 3px solid #444444;
|
||||
}
|
||||
|
||||
.hc-black jobhistory-component > .actionbar-container .monaco-action-bar > ul.actions-container {
|
||||
.hc-black jobhistory-component > .agent-actionbar-container .monaco-action-bar > ul.actions-container {
|
||||
border-top: 3px solid #2b56f2;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,6 @@
|
||||
<div class="icon in-progress" *ngIf="_showProgressWheel === true"></div>
|
||||
</div>
|
||||
|
||||
<div #actionbarContainer class="actionbar-container"></div>
|
||||
<div #actionbarContainer class="agent-actionbar-container"></div>
|
||||
|
||||
<div #jobsgrid class="jobview-grid"></div>
|
||||
@@ -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,8 +129,12 @@ 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 jobsViewToolbar = $('jobsview-component .agent-actionbar-container').get(0);
|
||||
let statusBar = $('.part.statusbar').get(0);
|
||||
if (jobsViewToolbar && statusBar) {
|
||||
let toolbarBottom = jobsViewToolbar.getBoundingClientRect().bottom;
|
||||
@@ -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');
|
||||
|
||||
@@ -10,6 +10,6 @@
|
||||
<div class="icon in-progress" *ngIf="_showProgressWheel === true"></div>
|
||||
</div>
|
||||
|
||||
<div #actionbarContainer class="actionbar-container"></div>
|
||||
<div #actionbarContainer class="agent-actionbar-container"></div>
|
||||
|
||||
<div #operatorsgrid class="joboperatorsview-grid"></div>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,6 +10,6 @@
|
||||
<div class="icon in-progress" *ngIf="_showProgressWheel === true"></div>
|
||||
</div>
|
||||
|
||||
<div #actionbarContainer class="actionbar-container"></div>
|
||||
<div #actionbarContainer class="agent-actionbar-container"></div>
|
||||
|
||||
<div #proxiesgrid class="jobproxiesview-grid"></div>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import 'vs/css!./loadingComponent';
|
||||
import {
|
||||
Component, Input, Inject, ChangeDetectorRef, forwardRef, OnDestroy, AfterViewInit, ViewChild, ElementRef
|
||||
Component, Input, Inject, ChangeDetectorRef, forwardRef, OnDestroy, AfterViewInit, ElementRef
|
||||
} from '@angular/core';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
@@ -31,9 +31,6 @@ export default class LoadingComponent extends ComponentBase implements IComponen
|
||||
@Input() descriptor: IComponentDescriptor;
|
||||
@Input() modelStore: IModelStore;
|
||||
|
||||
@ViewChild('spinnerElement', { read: ElementRef }) private _spinnerElement: ElementRef;
|
||||
@ViewChild('childElement', { read: ElementRef }) private _childElement: ElementRef;
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||
|
||||
30
src/sql/parts/modelComponents/loadingSpinner.component.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./loadingComponent';
|
||||
import {
|
||||
Component, Input, Inject, ChangeDetectorRef, forwardRef, ElementRef
|
||||
} from '@angular/core';
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
|
||||
@Component({
|
||||
selector: 'loading-spinner',
|
||||
template: `
|
||||
<div class="modelview-loadingComponent-container" *ngIf="loading">
|
||||
<div class="modelview-loadingComponent-spinner" *ngIf="loading" [title]=_loadingTitle #spinnerElement></div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export default class LoadingSpinner {
|
||||
private readonly _loadingTitle = nls.localize('loadingMessage', 'Loading');
|
||||
|
||||
@Input() loading: boolean;
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
|
||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef) {
|
||||
}
|
||||
}
|
||||
@@ -70,6 +70,9 @@ export class QueryTextEditor extends BaseTextEditor {
|
||||
options.minimap = {
|
||||
enabled: false
|
||||
};
|
||||
options.overviewRulerLanes = 0;
|
||||
options.overviewRulerBorder = false;
|
||||
options.hideCursorInOverviewRuler = true;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
14
src/sql/parts/notebook/cellViews/code.component.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!--
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
-->
|
||||
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: row">
|
||||
<div #toolbar class="toolbar" style="flex: 0 0 auto; display: flex; flex-flow:column; width: 40px; min-height: 40px; padding-top: 10px; orientation: portrait">
|
||||
</div>
|
||||
<div #editor class="editor" style="flex: 1 1 auto; overflow: hidden;">
|
||||
</div>
|
||||
<div #moreactions class="toolbar" style="flex: 0 0 auto; display: flex; flex-flow:column; width: 20px; min-height: 20px; max-height: 20px; padding-top: 10px; orientation: portrait">
|
||||
</div>
|
||||
</div>
|
||||
187
src/sql/parts/notebook/cellViews/code.component.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'vs/css!./code';
|
||||
|
||||
import { OnInit, Component, Input, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild, Output, EventEmitter } from '@angular/core';
|
||||
|
||||
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { QueryTextEditor } from 'sql/parts/modelComponents/queryTextEditor';
|
||||
|
||||
import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import * as themeColors from 'vs/workbench/common/theme';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { SimpleProgressService } from 'vs/editor/standalone/browser/simpleServices';
|
||||
import { IProgressService } from 'vs/platform/progress/common/progress';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { ActionBar, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ICellModel } from 'sql/parts/notebook/models/modelInterfaces';
|
||||
import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar';
|
||||
import { RunCellAction, DeleteCellAction, AddCellAction, CellContext } from 'sql/parts/notebook/cellViews/codeActions';
|
||||
import { NotebookModel } from 'sql/parts/notebook/models/notebookModel';
|
||||
import { ToggleMoreWidgetAction } from 'sql/parts/dashboard/common/actions';
|
||||
import { CellTypes } from 'sql/parts/notebook/models/contracts';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
export const CODE_SELECTOR: string = 'code-component';
|
||||
|
||||
@Component({
|
||||
selector: CODE_SELECTOR,
|
||||
templateUrl: decodeURI(require.toUrl('./code.component.html'))
|
||||
})
|
||||
export class CodeComponent extends AngularDisposable implements OnInit {
|
||||
@ViewChild('toolbar', { read: ElementRef }) private toolbarElement: ElementRef;
|
||||
@ViewChild('moreactions', { read: ElementRef }) private moreactionsElement: ElementRef;
|
||||
@ViewChild('editor', { read: ElementRef }) private codeElement: ElementRef;
|
||||
@Input() cellModel: ICellModel;
|
||||
|
||||
@Output() public onContentChanged = new EventEmitter<void>();
|
||||
|
||||
@Input() set model(value: NotebookModel) {
|
||||
this._model = value;
|
||||
}
|
||||
|
||||
protected _actionBar: Taskbar;
|
||||
protected _moreActions: ActionBar;
|
||||
private readonly _minimumHeight = 30;
|
||||
private _editor: QueryTextEditor;
|
||||
private _editorInput: UntitledEditorInput;
|
||||
private _editorModel: ITextModel;
|
||||
private _uri: string;
|
||||
private _model: NotebookModel;
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface,
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||
@Inject(IInstantiationService) private _instantiationService: IInstantiationService,
|
||||
@Inject(IModelService) private _modelService: IModelService,
|
||||
@Inject(IModeService) private _modeService: IModeService,
|
||||
@Inject(IContextMenuService) private contextMenuService: IContextMenuService,
|
||||
@Inject(IContextViewService) private contextViewService: IContextViewService,
|
||||
@Inject(INotificationService) private notificationService: INotificationService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this));
|
||||
this.updateTheme(this.themeService.getColorTheme());
|
||||
this.initActionBar();
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
this.updateLanguageMode();
|
||||
this.updateModel();
|
||||
}
|
||||
|
||||
ngAfterContentInit(): void {
|
||||
this.createEditor();
|
||||
this._register(DOM.addDisposableListener(window, DOM.EventType.RESIZE, e => {
|
||||
this.layout();
|
||||
}));
|
||||
}
|
||||
|
||||
get model(): NotebookModel {
|
||||
return this._model;
|
||||
}
|
||||
|
||||
private createEditor(): void {
|
||||
let instantiationService = this._instantiationService.createChild(new ServiceCollection([IProgressService, new SimpleProgressService()]));
|
||||
this._editor = instantiationService.createInstance(QueryTextEditor);
|
||||
this._editor.create(this.codeElement.nativeElement);
|
||||
this._editor.setVisible(true);
|
||||
this._editor.setMinimumHeight(this._minimumHeight);
|
||||
let uri = this.createUri();
|
||||
this._editorInput = instantiationService.createInstance(UntitledEditorInput, uri, false, this.cellModel.language, '', '');
|
||||
this._editor.setInput(this._editorInput, undefined);
|
||||
this._editorInput.resolve().then(model => {
|
||||
this._editorModel = model.textEditorModel;
|
||||
this._modelService.updateModel(this._editorModel, this.cellModel.source);
|
||||
});
|
||||
|
||||
this._register(this._editor);
|
||||
this._register(this._editorInput);
|
||||
this._register(this._editorModel.onDidChangeContent(e => {
|
||||
this._editor.setHeightToScrollHeight();
|
||||
this.cellModel.source = this._editorModel.getValue();
|
||||
this.onContentChanged.emit();
|
||||
}));
|
||||
this.layout();
|
||||
}
|
||||
|
||||
public layout(): void {
|
||||
this._editor.layout(new DOM.Dimension(
|
||||
DOM.getContentWidth(this.codeElement.nativeElement),
|
||||
DOM.getContentHeight(this.codeElement.nativeElement)));
|
||||
this._editor.setHeightToScrollHeight();
|
||||
}
|
||||
|
||||
protected initActionBar() {
|
||||
let context = new CellContext(this.model, this.cellModel);
|
||||
let runCellAction = this._instantiationService.createInstance(RunCellAction);
|
||||
|
||||
let taskbar = <HTMLElement>this.toolbarElement.nativeElement;
|
||||
this._actionBar = new Taskbar(taskbar, this.contextMenuService);
|
||||
this._actionBar.context = context;
|
||||
this._actionBar.setContent([
|
||||
{ action: runCellAction }
|
||||
]);
|
||||
|
||||
let moreActionsElement = <HTMLElement>this.moreactionsElement.nativeElement;
|
||||
this._moreActions = new ActionBar(moreActionsElement, { orientation: ActionsOrientation.VERTICAL });
|
||||
this._moreActions.context = { target: moreActionsElement };
|
||||
|
||||
let actions: Action[] = [];
|
||||
actions.push(this._instantiationService.createInstance(AddCellAction, 'codeBefore', localize('codeBefore', 'Insert Code before'), CellTypes.Code, false));
|
||||
actions.push(this._instantiationService.createInstance(AddCellAction, 'codeAfter', localize('codeAfter', 'Insert Code after'), CellTypes.Code, true));
|
||||
actions.push(this._instantiationService.createInstance(AddCellAction, 'markdownBefore', localize('markdownBefore', 'Insert Markdown before'), CellTypes.Markdown, false));
|
||||
actions.push(this._instantiationService.createInstance(AddCellAction, 'markdownAfter', localize('markdownAfter', 'Insert Markdown after'), CellTypes.Markdown, true));
|
||||
actions.push(this._instantiationService.createInstance(DeleteCellAction, 'delete', localize('delete', 'Delete')));
|
||||
|
||||
this._moreActions.push(this._instantiationService.createInstance(ToggleMoreWidgetAction, actions, context), { icon: true, label: false });
|
||||
}
|
||||
|
||||
private createUri(): URI {
|
||||
let uri = URI.from({ scheme: Schemas.untitled, path: `notebook-editor-${this.cellModel.id}` });
|
||||
// Use this to set the internal (immutable) and public (shared with extension) uri properties
|
||||
this.cellModel.cellUri = uri;
|
||||
return uri;
|
||||
}
|
||||
|
||||
/// Editor Functions
|
||||
private updateModel() {
|
||||
if (this._editorModel) {
|
||||
this._modelService.updateModel(this._editorModel, this.cellModel.source);
|
||||
}
|
||||
}
|
||||
|
||||
private updateLanguageMode() {
|
||||
if (this._editorModel && this._editor) {
|
||||
this._modeService.getOrCreateMode(this.cellModel.language).then((modeValue) => {
|
||||
this._modelService.setMode(this._editorModel, modeValue);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private updateTheme(theme: IColorTheme): void {
|
||||
let toolbarEl = <HTMLElement>this.toolbarElement.nativeElement;
|
||||
toolbarEl.style.borderRightColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString();
|
||||
|
||||
let moreactionsEl = <HTMLElement>this.moreactionsElement.nativeElement;
|
||||
moreactionsEl.style.borderRightColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString();
|
||||
}
|
||||
|
||||
}
|
||||
57
src/sql/parts/notebook/cellViews/code.css
Normal file
@@ -0,0 +1,57 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
code-component {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
code-component .toolbar {
|
||||
border-right-width: 1px;
|
||||
border-right-style: solid;
|
||||
}
|
||||
|
||||
code-component .toolbarIconRun {
|
||||
height: 20px;
|
||||
background-image: url('../media/light/execute_cell.svg');
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.vs-dark code-component .toolbarIconRun,
|
||||
.hc-black code-component .toolbarIconRun {
|
||||
background-image: url('../media/dark/execute_cell_inverse.svg');
|
||||
}
|
||||
|
||||
code-component .toolbarIconStop {
|
||||
height: 20px;
|
||||
background-image: url('../media/light/stop_cell.svg');
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.vs-dark code-component .toolbarIconStop,
|
||||
.hc-black code-component .toolbarIconStop {
|
||||
background-image: url('../media/dark/stop_cell_inverse.svg');
|
||||
}
|
||||
|
||||
/* overview ruler */
|
||||
code-component .monaco-editor .decorationsOverviewRuler {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
code-component .carbon-taskbar .icon {
|
||||
background-size: 20px;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
code-component .action-label.icon.toggle-more {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
code-component .carbon-taskbar.monaco-toolbar .monaco-action-bar.animated .actions-container
|
||||
{
|
||||
padding-left: 10px
|
||||
}
|
||||
187
src/sql/parts/notebook/cellViews/codeActions.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { nb } from 'sqlops';
|
||||
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { localize } from 'vs/nls';
|
||||
import { CellType } from 'sql/parts/notebook/models/contracts';
|
||||
import { NotebookModel } from 'sql/parts/notebook/models/notebookModel';
|
||||
import { getErrorMessage } from 'sql/parts/notebook/notebookUtils';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { ICellModel, FutureInternal } from 'sql/parts/notebook/models/modelInterfaces';
|
||||
import { ToggleableAction } from 'sql/parts/notebook/notebookActions';
|
||||
|
||||
let notebookMoreActionMsg = localize('notebook.failed', "Please select active cell and try again");
|
||||
|
||||
function hasModelAndCell(context: CellContext, notificationService: INotificationService): boolean {
|
||||
if (!context || !context.model) {
|
||||
return false;
|
||||
}
|
||||
if (context.cell === undefined) {
|
||||
notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: notebookMoreActionMsg
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export class CellContext {
|
||||
constructor(public model: NotebookModel, private _cell?: ICellModel) {
|
||||
}
|
||||
|
||||
public get cell(): ICellModel {
|
||||
return this._cell ? this._cell : this.model.activeCell;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class CellActionBase extends Action {
|
||||
|
||||
constructor(id: string, label: string, icon: string, protected notificationService: INotificationService) {
|
||||
super(id, label, icon);
|
||||
}
|
||||
|
||||
public run(context: CellContext): TPromise<boolean> {
|
||||
if (hasModelAndCell(context, this.notificationService)) {
|
||||
return TPromise.wrap(this.runCellAction(context).then(() => true));
|
||||
}
|
||||
return TPromise.as(true);
|
||||
}
|
||||
|
||||
abstract runCellAction(context: CellContext): Promise<void>;
|
||||
}
|
||||
|
||||
export class RunCellAction extends ToggleableAction {
|
||||
public static ID = 'notebook.runCell';
|
||||
public static LABEL = 'Run cell';
|
||||
|
||||
constructor(@INotificationService private notificationService: INotificationService) {
|
||||
super(RunCellAction.ID, {
|
||||
shouldToggleTooltip: true,
|
||||
toggleOnLabel: localize('runCell', 'Run cell'),
|
||||
toggleOnClass: 'toolbarIconRun',
|
||||
toggleOffLabel: localize('stopCell', 'Cancel execution'),
|
||||
toggleOffClass: 'toolbarIconStop',
|
||||
isOn: true
|
||||
});
|
||||
}
|
||||
|
||||
public run(context: CellContext): TPromise<boolean> {
|
||||
if (hasModelAndCell(context, this.notificationService)) {
|
||||
return TPromise.wrap(this.runCellAction(context).then(() => true));
|
||||
}
|
||||
return TPromise.as(true);
|
||||
}
|
||||
|
||||
public async runCellAction(context: CellContext): Promise<void> {
|
||||
try {
|
||||
let model = context.model;
|
||||
let cell = context.cell;
|
||||
let kernel = await this.getOrStartKernel(model);
|
||||
if (!kernel) {
|
||||
return;
|
||||
}
|
||||
// If cell is currently running and user clicks the stop/cancel button, call kernel.interrupt()
|
||||
// This matches the same behavior as JupyterLab
|
||||
if (cell.future && cell.future.inProgress) {
|
||||
cell.future.inProgress = false;
|
||||
await kernel.interrupt();
|
||||
} else {
|
||||
// TODO update source based on editor component contents
|
||||
let content = cell.source;
|
||||
if (content) {
|
||||
this.toggle(false);
|
||||
let future = await kernel.requestExecute({
|
||||
code: content,
|
||||
stop_on_error: true
|
||||
}, false);
|
||||
cell.setFuture(future as FutureInternal);
|
||||
// For now, await future completion. Later we should just track and handle cancellation based on model notifications
|
||||
let reply = await future.done;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
let message = getErrorMessage(error);
|
||||
this.notificationService.error(message);
|
||||
} finally {
|
||||
this.toggle(true);
|
||||
}
|
||||
}
|
||||
|
||||
private async getOrStartKernel(model: NotebookModel): Promise<nb.IKernel> {
|
||||
let clientSession = model && model.clientSession;
|
||||
if (!clientSession) {
|
||||
this.notificationService.error(localize('notebookNotReady', 'The session for this notebook is not yet ready'));
|
||||
return undefined;
|
||||
} else if (!clientSession.isReady || clientSession.status === 'dead') {
|
||||
this.notificationService.info(localize('sessionNotReady', 'The session for this notebook will start momentarily'));
|
||||
await clientSession.kernelChangeCompleted;
|
||||
}
|
||||
if (!clientSession.kernel) {
|
||||
let defaultKernel = model && model.defaultKernel && model.defaultKernel.name;
|
||||
if (!defaultKernel) {
|
||||
this.notificationService.error(localize('noDefaultKernel', 'No kernel is available for this notebook'));
|
||||
return undefined;
|
||||
}
|
||||
await clientSession.changeKernel({
|
||||
name: defaultKernel
|
||||
});
|
||||
}
|
||||
return clientSession.kernel;
|
||||
}
|
||||
}
|
||||
|
||||
export class AddCellAction extends CellActionBase {
|
||||
constructor(
|
||||
id: string, label: string, private cellType: CellType, private isAfter: boolean,
|
||||
@INotificationService notificationService: INotificationService
|
||||
) {
|
||||
super(id, label, undefined, notificationService);
|
||||
}
|
||||
|
||||
runCellAction(context: CellContext): Promise<void> {
|
||||
try {
|
||||
let model = context.model;
|
||||
let index = model.cells.findIndex((cell) => cell.id === context.cell.id);
|
||||
if (index !== undefined && this.isAfter) {
|
||||
index += 1;
|
||||
}
|
||||
model.addCell(this.cellType, index);
|
||||
} catch (error) {
|
||||
let message = getErrorMessage(error);
|
||||
|
||||
this.notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: message
|
||||
});
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
export class DeleteCellAction extends CellActionBase {
|
||||
constructor(id: string, label: string,
|
||||
@INotificationService notificationService: INotificationService
|
||||
) {
|
||||
super(id, label, undefined, notificationService);
|
||||
}
|
||||
|
||||
runCellAction(context: CellContext): Promise<void> {
|
||||
try {
|
||||
context.model.deleteCell(context.cell);
|
||||
} catch (error) {
|
||||
let message = getErrorMessage(error);
|
||||
|
||||
this.notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: message
|
||||
});
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
15
src/sql/parts/notebook/cellViews/codeCell.component.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!--
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
-->
|
||||
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
|
||||
<div class="notebook-code" style="flex: 0 0 auto;">
|
||||
<code-component [cellModel]="cellModel" [model]="model"></code-component>
|
||||
</div>
|
||||
<div #codeCellOutput class="notebook-output" style="flex: 0 0 auto;">
|
||||
<output-area-component *ngIf="cellModel.outputs && cellModel.outputs.length > 0" [cellModel]="cellModel">
|
||||
</output-area-component>
|
||||
</div>
|
||||
</div>
|
||||
63
src/sql/parts/notebook/cellViews/codeCell.component.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'vs/css!./codeCell';
|
||||
|
||||
import { OnInit, Component, Input, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild } from '@angular/core';
|
||||
|
||||
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||
import { CellView } from 'sql/parts/notebook/cellViews/interfaces';
|
||||
|
||||
import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import * as themeColors from 'vs/workbench/common/theme';
|
||||
import { ICellModel } from 'sql/parts/notebook/models/modelInterfaces';
|
||||
import { NotebookModel } from 'sql/parts/notebook/models/notebookModel';
|
||||
|
||||
|
||||
export const CODE_SELECTOR: string = 'code-cell-component';
|
||||
|
||||
@Component({
|
||||
selector: CODE_SELECTOR,
|
||||
templateUrl: decodeURI(require.toUrl('./codeCell.component.html'))
|
||||
})
|
||||
export class CodeCellComponent extends CellView implements OnInit {
|
||||
@ViewChild('codeCellOutput', { read: ElementRef }) private outputPreview: ElementRef;
|
||||
private _model: NotebookModel;
|
||||
@Input() cellModel: ICellModel;
|
||||
@Input() set model(value: NotebookModel) {
|
||||
this._model = value;
|
||||
}
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this));
|
||||
this.updateTheme(this.themeService.getColorTheme());
|
||||
if (this.cellModel) {
|
||||
this.cellModel.onOutputsChanged(() => {
|
||||
this._changeRef.detectChanges();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: implement layout
|
||||
public layout() {
|
||||
|
||||
}
|
||||
|
||||
private updateTheme(theme: IColorTheme): void {
|
||||
let outputElement = <HTMLElement>this.outputPreview.nativeElement;
|
||||
outputElement.style.borderTopColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString();
|
||||
}
|
||||
|
||||
get model(): NotebookModel {
|
||||
return this._model;
|
||||
}
|
||||
|
||||
}
|
||||
14
src/sql/parts/notebook/cellViews/codeCell.css
Normal file
@@ -0,0 +1,14 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
code-cell-component {
|
||||
display: block;
|
||||
}
|
||||
|
||||
code-cell-component .notebook-output {
|
||||
border-top-width: 1px;
|
||||
border-top-style: solid;
|
||||
user-select: initial;
|
||||
}
|
||||
17
src/sql/parts/notebook/cellViews/interfaces.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { OnDestroy } from '@angular/core';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
|
||||
export abstract class CellView extends AngularDisposable implements OnDestroy {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public abstract layout(): void;
|
||||
}
|
||||
|
||||
|
||||
11
src/sql/parts/notebook/cellViews/output.component.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!--
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
-->
|
||||
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
|
||||
<div style="flex: 0 0 auto; user-select: initial;">
|
||||
<div #output ></div>
|
||||
</div>
|
||||
</div>
|
||||
95
src/sql/parts/notebook/cellViews/output.component.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'vs/css!./code';
|
||||
|
||||
import { OnInit, Component, Input, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild, Output, EventEmitter } from '@angular/core';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { nb } from 'sqlops';
|
||||
import { INotebookService } from 'sql/services/notebook/notebookService';
|
||||
import { MimeModel } from 'sql/parts/notebook/outputs/common/mimemodel';
|
||||
import * as outputProcessor from '../outputs/common/outputProcessor';
|
||||
import { RenderMimeRegistry } from 'sql/parts/notebook/outputs/registry';
|
||||
import 'vs/css!sql/parts/notebook/outputs/style/index';
|
||||
|
||||
export const OUTPUT_SELECTOR: string = 'output-component';
|
||||
|
||||
@Component({
|
||||
selector: OUTPUT_SELECTOR,
|
||||
templateUrl: decodeURI(require.toUrl('./output.component.html'))
|
||||
})
|
||||
export class OutputComponent extends AngularDisposable implements OnInit {
|
||||
@ViewChild('output', { read: ElementRef }) private outputElement: ElementRef;
|
||||
@Input() cellOutput: nb.ICellOutput;
|
||||
private _trusted: boolean;
|
||||
private _initialized: boolean = false;
|
||||
private readonly _minimumHeight = 30;
|
||||
registry: RenderMimeRegistry;
|
||||
|
||||
|
||||
constructor(
|
||||
@Inject(INotebookService) private _notebookService: INotebookService
|
||||
) {
|
||||
super();
|
||||
this.registry = _notebookService.getMimeRegistry();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.renderOutput();
|
||||
this._initialized = true;
|
||||
}
|
||||
|
||||
private renderOutput() {
|
||||
let node = this.outputElement.nativeElement;
|
||||
let output = this.cellOutput;
|
||||
let options = outputProcessor.getBundleOptions({ value: output, trusted: this.trustedMode });
|
||||
// TODO handle safe/unsafe mapping
|
||||
this.createRenderedMimetype(options, node);
|
||||
}
|
||||
|
||||
public layout(): void {
|
||||
}
|
||||
|
||||
get trustedMode(): boolean {
|
||||
return this._trusted;
|
||||
}
|
||||
|
||||
@Input()
|
||||
set trustedMode(value: boolean) {
|
||||
this._trusted = value;
|
||||
if (this._initialized) {
|
||||
this.renderOutput();
|
||||
}
|
||||
}
|
||||
|
||||
protected createRenderedMimetype(options: MimeModel.IOptions, node: HTMLElement): void {
|
||||
let mimeType = this.registry.preferredMimeType(
|
||||
options.data,
|
||||
options.trusted ? 'any' : 'ensure'
|
||||
);
|
||||
if (mimeType) {
|
||||
let output = this.registry.createRenderer(mimeType);
|
||||
output.node = node;
|
||||
let model = new MimeModel(options);
|
||||
output.renderModel(model).catch(error => {
|
||||
// Manually append error message to output
|
||||
output.node.innerHTML = `<pre>Javascript Error: ${error.message}</pre>`;
|
||||
// Remove mime-type-specific CSS classes
|
||||
output.node.className = 'p-Widget jp-RenderedText';
|
||||
output.node.setAttribute(
|
||||
'data-mime-type',
|
||||
'application/vnd.jupyter.stderr'
|
||||
);
|
||||
});
|
||||
//this.setState({ node: node });
|
||||
} else {
|
||||
// TODO Localize
|
||||
node.innerHTML =
|
||||
`No ${options.trusted ? '' : '(safe) '}renderer could be ` +
|
||||
'found for output. It has the following MIME types: ' +
|
||||
Object.keys(options.data).join(', ');
|
||||
//this.setState({ node: node });
|
||||
}
|
||||
}
|
||||
}
|
||||
12
src/sql/parts/notebook/cellViews/outputArea.component.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!--
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
-->
|
||||
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
|
||||
<div style="flex: 0 0 auto;">
|
||||
<output-component *ngFor="let output of cellModel.outputs" [cellOutput]="output" [trustedMode] = "cellModel.trustedMode" >
|
||||
</output-component>
|
||||
</div>
|
||||
</div>
|
||||
33
src/sql/parts/notebook/cellViews/outputArea.component.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'vs/css!./code';
|
||||
import { OnInit, Component, Input, Inject, forwardRef, ChangeDetectorRef } from '@angular/core';
|
||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||
import { ICellModel } from 'sql/parts/notebook/models/modelInterfaces';
|
||||
|
||||
export const OUTPUT_AREA_SELECTOR: string = 'output-area-component';
|
||||
|
||||
@Component({
|
||||
selector: OUTPUT_AREA_SELECTOR,
|
||||
templateUrl: decodeURI(require.toUrl('./outputArea.component.html'))
|
||||
})
|
||||
export class OutputAreaComponent extends AngularDisposable implements OnInit {
|
||||
@Input() cellModel: ICellModel;
|
||||
|
||||
private readonly _minimumHeight = 30;
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
ngOnInit(): void {
|
||||
if (this.cellModel) {
|
||||
this.cellModel.onOutputsChanged(() => {
|
||||
this._changeRef.detectChanges();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
13
src/sql/parts/notebook/cellViews/textCell.component.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!--
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
-->
|
||||
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
|
||||
<div class="notebook-text" style="flex: 0 0 auto;">
|
||||
<code-component *ngIf="isEditMode" [cellModel]="cellModel" (onContentChanged)="handleContentChanged()"></code-component>
|
||||
</div>
|
||||
<div #preview class="notebook-preview" style="flex: 0 0 auto;" (dblclick)="toggleEditMode()">
|
||||
</div>
|
||||
</div>
|
||||
109
src/sql/parts/notebook/cellViews/textCell.component.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'vs/css!./textCell';
|
||||
|
||||
import { OnInit, Component, Input, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild } from '@angular/core';
|
||||
|
||||
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||
import { CellView } from 'sql/parts/notebook/cellViews/interfaces';
|
||||
|
||||
import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import * as themeColors from 'vs/workbench/common/theme';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ICellModel } from 'sql/parts/notebook/models/modelInterfaces';
|
||||
import { ISanitizer, defaultSanitizer } from 'sql/parts/notebook/outputs/sanitizer';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
export const TEXT_SELECTOR: string = 'text-cell-component';
|
||||
|
||||
@Component({
|
||||
selector: TEXT_SELECTOR,
|
||||
templateUrl: decodeURI(require.toUrl('./textCell.component.html'))
|
||||
})
|
||||
export class TextCellComponent extends CellView implements OnInit {
|
||||
@ViewChild('preview', { read: ElementRef }) private output: ElementRef;
|
||||
@Input() cellModel: ICellModel;
|
||||
private _content: string;
|
||||
private isEditMode: boolean;
|
||||
private _sanitizer: ISanitizer;
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface,
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||
@Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService,
|
||||
@Inject(ICommandService) private _commandService: ICommandService
|
||||
) {
|
||||
super();
|
||||
this.isEditMode = false;
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
this.updatePreview();
|
||||
}
|
||||
|
||||
//Gets sanitizer from ISanitizer interface
|
||||
private get sanitizer(): ISanitizer {
|
||||
if (this._sanitizer) {
|
||||
return this._sanitizer;
|
||||
}
|
||||
return this._sanitizer = defaultSanitizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the preview of markdown component with latest changes
|
||||
* If content is empty and in non-edit mode, default it to 'Double-click to edit'
|
||||
* Sanitizes the data to be shown in markdown cell
|
||||
*/
|
||||
private updatePreview() {
|
||||
if (this._content !== this.cellModel.source) {
|
||||
if (!this.cellModel.source && !this.isEditMode) {
|
||||
(<HTMLElement>this.output.nativeElement).innerHTML = localize('doubleClickEdit', 'Double-click to edit');
|
||||
} else {
|
||||
this._content = this.sanitizeContent(this.cellModel.source);
|
||||
// todo: pass in the notebook filename instead of undefined value
|
||||
this._commandService.executeCommand<string>('notebook.showPreview', undefined, this._content).then((htmlcontent) => {
|
||||
let outputElement = <HTMLElement>this.output.nativeElement;
|
||||
outputElement.innerHTML = htmlcontent;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Sanitizes the content based on trusted mode of Cell Model
|
||||
private sanitizeContent(content: string): string {
|
||||
if (this.cellModel && !this.cellModel.trustedMode) {
|
||||
content = this.sanitizer.sanitize(content);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.updatePreview();
|
||||
this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this));
|
||||
this.updateTheme(this.themeService.getColorTheme());
|
||||
this.cellModel.onOutputsChanged(e => {
|
||||
this.updatePreview();
|
||||
});
|
||||
}
|
||||
|
||||
// Todo: implement layout
|
||||
public layout() {
|
||||
}
|
||||
|
||||
private updateTheme(theme: IColorTheme): void {
|
||||
let outputElement = <HTMLElement>this.output.nativeElement;
|
||||
outputElement.style.borderTopColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString();
|
||||
}
|
||||
|
||||
public handleContentChanged(): void {
|
||||
this.updatePreview();
|
||||
}
|
||||
|
||||
public toggleEditMode(): void {
|
||||
this.isEditMode = !this.isEditMode;
|
||||
this.updatePreview();
|
||||
this._changeRef.detectChanges();
|
||||
}
|
||||
}
|
||||
14
src/sql/parts/notebook/cellViews/textCell.css
Normal file
@@ -0,0 +1,14 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
text-cell-component {
|
||||
display: block;
|
||||
}
|
||||
|
||||
text-cell-component .notebook-preview {
|
||||
border-top-width: 1px;
|
||||
border-top-style: solid;
|
||||
user-select: initial;
|
||||
}
|
||||
1
src/sql/parts/notebook/media/dark/add_inverse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12"><defs><style>.cls-1{fill:#fff;}</style></defs><title>add_12x12</title><path class="cls-1" d="M6,.88a5.17,5.17,0,0,1,1.4.19A5.26,5.26,0,0,1,11,4.73a5.3,5.3,0,0,1,0,2.79,5.26,5.26,0,0,1-3.67,3.67,5.3,5.3,0,0,1-2.79,0A5.26,5.26,0,0,1,.9,7.53a5.3,5.3,0,0,1,0-2.79A5.26,5.26,0,0,1,4.57,1.07,5.17,5.17,0,0,1,6,.88Zm0,9.75a4.4,4.4,0,0,0,1.2-.16A4.56,4.56,0,0,0,8.24,10,4.5,4.5,0,0,0,9.85,8.4a4.56,4.56,0,0,0,.45-1.08,4.51,4.51,0,0,0,0-2.39,4.56,4.56,0,0,0-.45-1.08A4.5,4.5,0,0,0,8.24,2.24a4.56,4.56,0,0,0-1.08-.45,4.51,4.51,0,0,0-2.39,0,4.56,4.56,0,0,0-1.08.45A4.5,4.5,0,0,0,2.08,3.86a4.56,4.56,0,0,0-.45,1.08,4.51,4.51,0,0,0,0,2.39A4.56,4.56,0,0,0,2.08,8.4,4.5,4.5,0,0,0,3.7,10a4.56,4.56,0,0,0,1.08.45A4.4,4.4,0,0,0,6,10.63Zm.38-4.88H8.22V6.5H6.34V8.38H5.59V6.5H3.72V5.75H5.59V3.88h.75Z"/></svg>
|
||||
|
After Width: | Height: | Size: 882 B |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>execute_cell_inverse </title><circle class="cls-1" cx="8" cy="7.92" r="7.76"/><polygon points="10.7 8 6.67 11 6.67 5 10.7 8 10.7 8"/></svg>
|
||||
|
After Width: | Height: | Size: 285 B |
1
src/sql/parts/notebook/media/dark/nottrusted_inverse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#d02e00;}</style></defs><title>nontrust-inverse</title><path class="cls-1" d="M13.74,2a9.49,9.49,0,0,1-1.19-.17,7.1,7.1,0,0,1-1.14-.35A6.72,6.72,0,0,1,10.29.85,7.43,7.43,0,0,0,9.62.48,5.31,5.31,0,0,0,9,.22a4.18,4.18,0,0,0-.7-.16A6.07,6.07,0,0,0,7.5,0,4.81,4.81,0,0,0,6,.22,5.34,5.34,0,0,0,4.71.85a6.72,6.72,0,0,1-1.12.59,7.09,7.09,0,0,1-1.14.35A9.48,9.48,0,0,1,1.26,2C.85,2,.43,2,0,2V6A7.62,7.62,0,0,0,.29,8.17a9.15,9.15,0,0,0,.78,1.94,10.78,10.78,0,0,0,1.2,1.74,13.35,13.35,0,0,0,1.49,1.52,15.81,15.81,0,0,0,1.7,1.33c.59.42,1.19.8,1.8,1.15L7.5,16l.24-.14c.61-.35,1.21-.73,1.8-1.15a12.71,12.71,0,0,0,1.24-1l-.7-.7c-.32.27-.65.52-1,.76q-.8.55-1.59,1-.79-.46-1.59-1a15.89,15.89,0,0,1-1.51-1.2A13.66,13.66,0,0,1,3,11.22,9.59,9.59,0,0,1,2,9.66a8.52,8.52,0,0,1-.72-1.74A7.1,7.1,0,0,1,1,6V3a9.54,9.54,0,0,0,2.23-.37,8.08,8.08,0,0,0,2-.95,4.4,4.4,0,0,1,1.06-.5A3.87,3.87,0,0,1,7.5,1a3.87,3.87,0,0,1,1.16.16,4.4,4.4,0,0,1,1.06.5,8.08,8.08,0,0,0,2,.95A9.54,9.54,0,0,0,14,3V6a7.1,7.1,0,0,1-.26,1.91A8.51,8.51,0,0,1,13,9.66l-.1.18.73.73a3.14,3.14,0,0,0,.28-.46,9.15,9.15,0,0,0,.78-1.94A7.62,7.62,0,0,0,15,6V2C14.57,2,14.15,2,13.74,2Z"/><polygon class="cls-2" points="13.82 13.25 16 15.42 15.43 15.99 13.26 13.81 11.07 15.99 10.5 15.42 12.69 13.25 10.46 11.02 11.03 10.45 13.26 12.68 15.43 10.5 16 11.06 13.82 13.25"/></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
1
src/sql/parts/notebook/media/dark/stop_cell_inverse.svg
Executable file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>stop_cell_inverse</title><circle class="cls-1" cx="8" cy="7.92" r="7.76"/><rect x="5" y="4.92" width="6" height="6"/></svg>
|
||||
|
After Width: | Height: | Size: 269 B |
1
src/sql/parts/notebook/media/dark/trusted_inverse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#061c08;}.cls-3{fill:#3bb44a;}</style></defs><title>trust_inverse </title><path class="cls-1" d="M13.74,2a9.46,9.46,0,0,1-1.19-.17,8.28,8.28,0,0,1-1.14-.35A6.72,6.72,0,0,1,10.29.87,7.43,7.43,0,0,0,9.62.5,4,4,0,0,0,8.26.08,4.62,4.62,0,0,0,7.5,0,5.15,5.15,0,0,0,6,.23,5.39,5.39,0,0,0,4.71.87a6.72,6.72,0,0,1-1.12.59,8.28,8.28,0,0,1-1.14.35A9.46,9.46,0,0,1,1.26,2C.85,2,.43,2,0,2V6A7.62,7.62,0,0,0,.29,8.19a9.37,9.37,0,0,0,.78,1.94,10.69,10.69,0,0,0,1.2,1.73,14.32,14.32,0,0,0,1.49,1.53,15.82,15.82,0,0,0,1.7,1.33q.88.62,1.8,1.14L7.5,16l.24-.14c.28-.16.57-.33.85-.52l-.71-.72-.38.23q-.79-.46-1.59-1a15.89,15.89,0,0,1-1.51-1.2A14.78,14.78,0,0,1,3,11.24,9.26,9.26,0,0,1,2,9.67a8.29,8.29,0,0,1-.72-1.74A7,7,0,0,1,1,6V3a10.09,10.09,0,0,0,2.23-.37,8.08,8.08,0,0,0,2-1,4.05,4.05,0,0,1,1.06-.5A3.87,3.87,0,0,1,7.5,1a3.87,3.87,0,0,1,1.16.16,4.06,4.06,0,0,1,1.06.5,8.08,8.08,0,0,0,2,1A10.09,10.09,0,0,0,14,3V6a7,7,0,0,1-.26,1.9A8.29,8.29,0,0,1,13,9.67,9.26,9.26,0,0,1,12,11.24a10.85,10.85,0,0,1-.8.86l.71.71a12.86,12.86,0,0,0,.87-1,10.69,10.69,0,0,0,1.2-1.73,9.37,9.37,0,0,0,.78-1.94A7.62,7.62,0,0,0,15,6V2C14.57,2,14.15,2,13.74,2ZM10,13.1a9.54,9.54,0,0,1-.89.68l.54.55.16.16c.31-.21.61-.44.9-.68Z"/><polygon class="cls-2" points="16 10.94 11.15 15.79 10.49 15.13 9.85 14.49 9.69 14.33 9.15 13.78 8.81 13.44 9.59 12.66 10.04 13.1 10.75 13.81 10.85 13.91 11.15 14.21 15.22 10.15 15.33 10.26 16 10.94"/><polygon class="cls-3" points="16 10.94 11.15 15.79 10.49 15.13 9.85 14.49 9.69 14.33 9.15 13.78 8.81 13.44 9.59 12.66 10.04 13.1 10.75 13.81 10.85 13.91 11.15 14.21 15.22 10.15 15.33 10.26 16 10.94"/></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
1
src/sql/parts/notebook/media/light/add.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12"><title>add_16x16</title><path d="M6,1a5.17,5.17,0,0,1,1.4.19,5.26,5.26,0,0,1,3.67,3.67,5.3,5.3,0,0,1,0,2.79A5.26,5.26,0,0,1,7.4,11.32a5.3,5.3,0,0,1-2.79,0A5.26,5.26,0,0,1,.94,7.65a5.3,5.3,0,0,1,0-2.79A5.26,5.26,0,0,1,4.6,1.19,5.17,5.17,0,0,1,6,1Zm0,9.75a4.4,4.4,0,0,0,1.2-.16,4.56,4.56,0,0,0,1.08-.45A4.5,4.5,0,0,0,9.88,8.53a4.56,4.56,0,0,0,.45-1.08,4.51,4.51,0,0,0,0-2.39A4.56,4.56,0,0,0,9.88,4,4.5,4.5,0,0,0,8.27,2.37a4.56,4.56,0,0,0-1.08-.45,4.51,4.51,0,0,0-2.39,0,4.56,4.56,0,0,0-1.08.45A4.5,4.5,0,0,0,2.11,4a4.56,4.56,0,0,0-.45,1.08,4.51,4.51,0,0,0,0,2.39,4.56,4.56,0,0,0,.45,1.08,4.5,4.5,0,0,0,1.61,1.61,4.56,4.56,0,0,0,1.08.45A4.4,4.4,0,0,0,6,10.76Zm.38-4.88H8.25v.75H6.37V8.51H5.62V6.63H3.75V5.88H5.62V4h.75Z"/></svg>
|
||||
|
After Width: | Height: | Size: 818 B |
1
src/sql/parts/notebook/media/light/execute_cell.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>execute_cell</title><circle cx="8" cy="7.92" r="7.76"/><polygon class="cls-1" points="10.7 8 6.67 11 6.67 5 10.7 8 10.7 8"/></svg>
|
||||
|
After Width: | Height: | Size: 276 B |
1
src/sql/parts/notebook/media/light/nottrusted.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#d02e00;}</style></defs><title>nontrust</title><path d="M13.74,2a9.49,9.49,0,0,1-1.19-.17,7.1,7.1,0,0,1-1.14-.35A6.72,6.72,0,0,1,10.29.84,7.43,7.43,0,0,0,9.62.47,5.31,5.31,0,0,0,9,.21,4.18,4.18,0,0,0,8.26,0,6.07,6.07,0,0,0,7.5,0,4.81,4.81,0,0,0,6,.21,5.34,5.34,0,0,0,4.71.84a6.72,6.72,0,0,1-1.12.59,7.09,7.09,0,0,1-1.14.35A9.48,9.48,0,0,1,1.26,2C.85,2,.43,2,0,2V6A7.62,7.62,0,0,0,.29,8.16a9.15,9.15,0,0,0,.78,1.94,10.78,10.78,0,0,0,1.2,1.74,13.35,13.35,0,0,0,1.49,1.52,15.81,15.81,0,0,0,1.7,1.33c.59.42,1.19.8,1.8,1.15L7.5,16l.24-.14c.61-.35,1.21-.73,1.8-1.15a12.71,12.71,0,0,0,1.24-1l-.7-.7c-.32.27-.65.52-1,.76q-.8.55-1.59,1-.79-.46-1.59-1A15.89,15.89,0,0,1,4.4,12.6,13.66,13.66,0,0,1,3,11.21,9.59,9.59,0,0,1,2,9.65a8.52,8.52,0,0,1-.72-1.74A7.1,7.1,0,0,1,1,6V3a9.54,9.54,0,0,0,2.23-.37,8.08,8.08,0,0,0,2-.95,4.4,4.4,0,0,1,1.06-.5A3.87,3.87,0,0,1,7.5,1a3.87,3.87,0,0,1,1.16.16,4.4,4.4,0,0,1,1.06.5,8.08,8.08,0,0,0,2,.95A9.54,9.54,0,0,0,14,3V6a7.1,7.1,0,0,1-.26,1.91A8.51,8.51,0,0,1,13,9.65l-.1.18.73.73a3.14,3.14,0,0,0,.28-.46,9.15,9.15,0,0,0,.78-1.94A7.62,7.62,0,0,0,15,6V2C14.57,2,14.15,2,13.74,2Z"/><polygon class="cls-1" points="13.82 13.24 16 15.41 15.43 15.98 13.26 13.8 11.07 15.98 10.5 15.41 12.69 13.24 10.46 11.01 11.03 10.44 13.26 12.67 15.43 10.49 16 11.05 13.82 13.24"/></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
1
src/sql/parts/notebook/media/light/stop_cell.svg
Executable file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>stop_cell</title><circle cx="8" cy="7.92" r="7.76"/><rect class="cls-1" x="5" y="4.92" width="6" height="6"/></svg>
|
||||
|
After Width: | Height: | Size: 261 B |
1
src/sql/parts/notebook/media/light/trusted.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#061c08;}.cls-2{fill:#3bb44a;}</style></defs><title>trust</title><path d="M13.74,2a9.46,9.46,0,0,1-1.19-.17,8.28,8.28,0,0,1-1.14-.35A6.72,6.72,0,0,1,10.29.85,7.43,7.43,0,0,0,9.62.48,4,4,0,0,0,8.26.07,4.62,4.62,0,0,0,7.5,0,5.15,5.15,0,0,0,6,.21,5.39,5.39,0,0,0,4.71.85a6.72,6.72,0,0,1-1.12.59,8.28,8.28,0,0,1-1.14.35A9.46,9.46,0,0,1,1.26,2C.85,2,.43,2,0,2V6A7.62,7.62,0,0,0,.29,8.17a9.37,9.37,0,0,0,.78,1.94,10.69,10.69,0,0,0,1.2,1.73,14.32,14.32,0,0,0,1.49,1.53,15.82,15.82,0,0,0,1.7,1.33q.88.62,1.8,1.14L7.5,16l.24-.14c.28-.16.57-.33.85-.52l-.71-.72-.38.23q-.79-.46-1.59-1a15.89,15.89,0,0,1-1.51-1.2A14.78,14.78,0,0,1,3,11.22,9.26,9.26,0,0,1,2,9.65a8.29,8.29,0,0,1-.72-1.74A7,7,0,0,1,1,6V3a10.09,10.09,0,0,0,2.23-.37,8.08,8.08,0,0,0,2-1,4.05,4.05,0,0,1,1.06-.5A3.87,3.87,0,0,1,7.5,1a3.87,3.87,0,0,1,1.16.16,4.06,4.06,0,0,1,1.06.5,8.08,8.08,0,0,0,2,1A10.09,10.09,0,0,0,14,3V6a7,7,0,0,1-.26,1.9A8.29,8.29,0,0,1,13,9.65,9.26,9.26,0,0,1,12,11.22a10.85,10.85,0,0,1-.8.86l.71.71a12.86,12.86,0,0,0,.87-1,10.69,10.69,0,0,0,1.2-1.73,9.37,9.37,0,0,0,.78-1.94A7.62,7.62,0,0,0,15,6V2C14.57,2,14.15,2,13.74,2ZM10,13.08a9.54,9.54,0,0,1-.89.68l.54.55.16.16c.31-.21.61-.44.9-.68Z"/><polygon class="cls-1" points="16 10.93 11.15 15.78 10.49 15.12 9.85 14.47 9.69 14.31 9.15 13.77 8.81 13.43 9.59 12.64 10.04 13.09 10.75 13.79 10.85 13.89 11.15 14.2 15.22 10.13 15.33 10.24 16 10.93"/><polygon class="cls-2" points="16 10.93 11.15 15.78 10.49 15.12 9.85 14.47 9.69 14.31 9.15 13.77 8.81 13.43 9.59 12.64 10.04 13.09 10.75 13.79 10.85 13.89 11.15 14.2 15.22 10.13 15.33 10.24 16 10.93"/></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
322
src/sql/parts/notebook/models/cell.ts
Normal file
@@ -0,0 +1,322 @@
|
||||
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { Event, Emitter } from 'vs/base/common/event';
|
||||
import URI from 'vs/base/common/uri';
|
||||
|
||||
import { nb } from 'sqlops';
|
||||
import { ICellModelOptions, IModelFactory, FutureInternal } from './modelInterfaces';
|
||||
import * as notebookUtils from '../notebookUtils';
|
||||
import { CellTypes, CellType, NotebookChangeType } from 'sql/parts/notebook/models/contracts';
|
||||
import { ICellModel } from 'sql/parts/notebook/models/modelInterfaces';
|
||||
|
||||
let modelId = 0;
|
||||
|
||||
|
||||
export class CellModel implements ICellModel {
|
||||
private static LanguageMapping: Map<string, string>;
|
||||
|
||||
private _cellType: nb.CellType;
|
||||
private _source: string;
|
||||
private _language: string;
|
||||
private _future: FutureInternal;
|
||||
private _outputs: nb.ICellOutput[] = [];
|
||||
private _isEditMode: boolean;
|
||||
private _onOutputsChanged = new Emitter<ReadonlyArray<nb.ICellOutput>>();
|
||||
private _onCellModeChanged = new Emitter<boolean>();
|
||||
public id: string;
|
||||
private _isTrusted: boolean;
|
||||
private _active: boolean;
|
||||
private _cellUri: URI;
|
||||
|
||||
constructor(private factory: IModelFactory, cellData?: nb.ICell, private _options?: ICellModelOptions) {
|
||||
this.id = `${modelId++}`;
|
||||
CellModel.CreateLanguageMappings();
|
||||
// Do nothing for now
|
||||
if (cellData) {
|
||||
this.fromJSON(cellData);
|
||||
} else {
|
||||
this._cellType = CellTypes.Code;
|
||||
this._source = '';
|
||||
}
|
||||
this._isEditMode = this._cellType !== CellTypes.Markdown;
|
||||
this.setDefaultLanguage();
|
||||
if (_options && _options.isTrusted) {
|
||||
this._isTrusted = true;
|
||||
} else {
|
||||
this._isTrusted = false;
|
||||
}
|
||||
}
|
||||
|
||||
public equals(other: ICellModel) {
|
||||
return other && other.id === this.id;
|
||||
}
|
||||
|
||||
public get onOutputsChanged(): Event<ReadonlyArray<nb.ICellOutput>> {
|
||||
return this._onOutputsChanged.event;
|
||||
}
|
||||
|
||||
public get onCellModeChanged(): Event<boolean> {
|
||||
return this._onCellModeChanged.event;
|
||||
}
|
||||
|
||||
public get isEditMode(): boolean {
|
||||
return this._isEditMode;
|
||||
}
|
||||
|
||||
public get future(): FutureInternal {
|
||||
return this._future;
|
||||
}
|
||||
|
||||
public set isEditMode(isEditMode: boolean) {
|
||||
this._isEditMode = isEditMode;
|
||||
this._onCellModeChanged.fire(this._isEditMode);
|
||||
// Note: this does not require a notebook update as it does not change overall state
|
||||
}
|
||||
|
||||
public get trustedMode(): boolean {
|
||||
return this._isTrusted;
|
||||
}
|
||||
|
||||
public set trustedMode(isTrusted: boolean) {
|
||||
if (this._isTrusted !== isTrusted) {
|
||||
this._isTrusted = isTrusted;
|
||||
this._onOutputsChanged.fire(this._outputs);
|
||||
}
|
||||
}
|
||||
|
||||
public get active(): boolean {
|
||||
return this._active;
|
||||
}
|
||||
|
||||
public set active(value: boolean) {
|
||||
this._active = value;
|
||||
}
|
||||
|
||||
public get cellUri(): URI {
|
||||
return this._cellUri;
|
||||
}
|
||||
|
||||
public set cellUri(value: URI) {
|
||||
this._cellUri = value;
|
||||
}
|
||||
|
||||
public get options(): ICellModelOptions {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
public get cellType(): CellType {
|
||||
return this._cellType;
|
||||
}
|
||||
|
||||
public get source(): string {
|
||||
return this._source;
|
||||
}
|
||||
|
||||
public set source(newSource: string) {
|
||||
if (this._source !== newSource) {
|
||||
this._source = newSource;
|
||||
this.sendChangeToNotebook(NotebookChangeType.CellSourceUpdated);
|
||||
}
|
||||
}
|
||||
|
||||
public get language(): string {
|
||||
return this._language;
|
||||
}
|
||||
|
||||
public set language(newLanguage: string) {
|
||||
this._language = newLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the future which will be used to update the output
|
||||
* area for this cell
|
||||
*/
|
||||
setFuture(future: FutureInternal): void {
|
||||
if (this._future === future) {
|
||||
// Nothing to do
|
||||
return;
|
||||
}
|
||||
// Setting the future indicates the cell is running which enables trusted mode.
|
||||
// See https://jupyter-notebook.readthedocs.io/en/stable/security.html
|
||||
|
||||
this._isTrusted = true;
|
||||
|
||||
if (this._future) {
|
||||
this._future.dispose();
|
||||
}
|
||||
this.clearOutputs();
|
||||
this._future = future;
|
||||
future.setReplyHandler({ handle: (msg) => this.handleReply(msg) });
|
||||
future.setIOPubHandler({ handle: (msg) => this.handleIOPub(msg) });
|
||||
}
|
||||
|
||||
public clearOutputs(): void {
|
||||
this._outputs = [];
|
||||
this.fireOutputsChanged();
|
||||
}
|
||||
|
||||
private fireOutputsChanged(): void {
|
||||
this._onOutputsChanged.fire(this.outputs);
|
||||
this.sendChangeToNotebook(NotebookChangeType.CellOutputUpdated);
|
||||
}
|
||||
|
||||
private sendChangeToNotebook(change: NotebookChangeType): void {
|
||||
if (this._options && this._options.notebook) {
|
||||
this._options.notebook.onCellChange(this, change);
|
||||
}
|
||||
}
|
||||
|
||||
public get outputs(): Array<nb.ICellOutput> {
|
||||
return this._outputs;
|
||||
}
|
||||
|
||||
private handleReply(msg: nb.IShellMessage): void {
|
||||
// TODO #931 we should process this. There can be a payload attached which should be added to outputs.
|
||||
// In all other cases, it is a no-op
|
||||
let output: nb.ICellOutput = msg.content as nb.ICellOutput;
|
||||
}
|
||||
|
||||
private handleIOPub(msg: nb.IIOPubMessage): void {
|
||||
let msgType = msg.header.msg_type;
|
||||
let displayId = this.getDisplayId(msg);
|
||||
let output: nb.ICellOutput;
|
||||
switch (msgType) {
|
||||
case 'execute_result':
|
||||
case 'display_data':
|
||||
case 'stream':
|
||||
case 'error':
|
||||
output = msg.content as nb.ICellOutput;
|
||||
output.output_type = msgType;
|
||||
break;
|
||||
case 'clear_output':
|
||||
// TODO wait until next message before clearing
|
||||
// let wait = (msg as KernelMessage.IClearOutputMsg).content.wait;
|
||||
this.clearOutputs();
|
||||
break;
|
||||
case 'update_display_data':
|
||||
output = msg.content as nb.ICellOutput;
|
||||
output.output_type = 'display_data';
|
||||
// TODO #930 handle in-place update of displayed data
|
||||
// targets = this._displayIdMap.get(displayId);
|
||||
// if (targets) {
|
||||
// for (let index of targets) {
|
||||
// model.set(index, output);
|
||||
// }
|
||||
// }
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// TODO handle in-place update of displayed data
|
||||
// if (displayId && msgType === 'display_data') {
|
||||
// targets = this._displayIdMap.get(displayId) || [];
|
||||
// targets.push(model.length - 1);
|
||||
// this._displayIdMap.set(displayId, targets);
|
||||
// }
|
||||
if (output) {
|
||||
// deletes transient node in the serialized JSON
|
||||
delete output['transient'];
|
||||
this._outputs.push(output);
|
||||
this.fireOutputsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private getDisplayId(msg: nb.IIOPubMessage): string | undefined {
|
||||
let transient = (msg.content.transient || {});
|
||||
return transient['display_id'] as string;
|
||||
}
|
||||
|
||||
public toJSON(): nb.ICell {
|
||||
let cellJson: Partial<nb.ICell> = {
|
||||
cell_type: this._cellType,
|
||||
source: this._source,
|
||||
metadata: {
|
||||
}
|
||||
};
|
||||
if (this._cellType === CellTypes.Code) {
|
||||
cellJson.metadata.language = this._language,
|
||||
cellJson.outputs = this._outputs;
|
||||
cellJson.execution_count = 1; // TODO: keep track of actual execution count
|
||||
}
|
||||
return cellJson as nb.ICell;
|
||||
}
|
||||
|
||||
public fromJSON(cell: nb.ICell): void {
|
||||
if (!cell) {
|
||||
return;
|
||||
}
|
||||
this._cellType = cell.cell_type;
|
||||
this._source = Array.isArray(cell.source) ? cell.source.join('') : cell.source;
|
||||
this._language = (cell.metadata && cell.metadata.language) ? cell.metadata.language : 'python';
|
||||
if (cell.outputs) {
|
||||
for (let output of cell.outputs) {
|
||||
// For now, we're assuming it's OK to save these as-is with no modification
|
||||
this.addOutput(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private addOutput(output: nb.ICellOutput) {
|
||||
this._normalize(output);
|
||||
this._outputs.push(output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize an output.
|
||||
*/
|
||||
private _normalize(value: nb.ICellOutput): void {
|
||||
if (notebookUtils.isStream(value)) {
|
||||
if (Array.isArray(value.text)) {
|
||||
value.text = (value.text as string[]).join('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static CreateLanguageMappings(): void {
|
||||
if (CellModel.LanguageMapping) {
|
||||
return;
|
||||
}
|
||||
CellModel.LanguageMapping = new Map<string, string>();
|
||||
CellModel.LanguageMapping['pyspark'] = 'python';
|
||||
CellModel.LanguageMapping['pyspark3'] = 'python';
|
||||
CellModel.LanguageMapping['python'] = 'python';
|
||||
CellModel.LanguageMapping['scala'] = 'scala';
|
||||
}
|
||||
|
||||
private get languageInfo(): nb.ILanguageInfo {
|
||||
if (this._options && this._options.notebook && this._options.notebook.languageInfo) {
|
||||
return this._options.notebook.languageInfo;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private setDefaultLanguage(): void {
|
||||
this._language = 'python';
|
||||
// In languageInfo, set the language to the "name" property
|
||||
// If the "name" property isn't defined, check the "mimeType" property
|
||||
// Otherwise, default to python as the language
|
||||
let languageInfo = this.languageInfo;
|
||||
if (languageInfo) {
|
||||
if (languageInfo.name) {
|
||||
// check the LanguageMapping to determine if a mapping is necessary (example 'pyspark' -> 'python')
|
||||
if (CellModel.LanguageMapping[languageInfo.name]) {
|
||||
this._language = CellModel.LanguageMapping[languageInfo.name];
|
||||
} else {
|
||||
this._language = languageInfo.name;
|
||||
}
|
||||
} else if (languageInfo.mimetype) {
|
||||
this._language = languageInfo.mimetype;
|
||||
}
|
||||
}
|
||||
let mimeTypePrefix = 'x-';
|
||||
if (this._language.includes(mimeTypePrefix)) {
|
||||
this._language = this._language.replace(mimeTypePrefix, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
361
src/sql/parts/notebook/models/clientSession.ts
Normal file
@@ -0,0 +1,361 @@
|
||||
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// This code is based on @jupyterlab/packages/apputils/src/clientsession.tsx
|
||||
|
||||
'use strict';
|
||||
|
||||
import { nb } from 'sqlops';
|
||||
import * as nls from 'vs/nls';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
|
||||
import { IClientSession, IKernelPreference, IClientSessionOptions } from './modelInterfaces';
|
||||
import { Deferred } from 'sql/base/common/promise';
|
||||
|
||||
import * as notebookUtils from '../notebookUtils';
|
||||
import * as sparkUtils from '../spark/sparkUtils';
|
||||
import { INotebookManager } from 'sql/services/notebook/notebookService';
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { NotebookConnection } from 'sql/parts/notebook/models/notebookConnection';
|
||||
|
||||
/**
|
||||
* Implementation of a client session. This is a model over session operations,
|
||||
* which may come from the session manager or a specific session.
|
||||
*/
|
||||
export class ClientSession implements IClientSession {
|
||||
//#region private fields with public accessors
|
||||
private _terminatedEmitter = new Emitter<void>();
|
||||
private _kernelChangedEmitter = new Emitter<nb.IKernelChangedArgs>();
|
||||
private _statusChangedEmitter = new Emitter<nb.ISession>();
|
||||
private _iopubMessageEmitter = new Emitter<nb.IMessage>();
|
||||
private _unhandledMessageEmitter = new Emitter<nb.IMessage>();
|
||||
private _propertyChangedEmitter = new Emitter<'path' | 'name' | 'type'>();
|
||||
private _notebookUri: URI;
|
||||
private _type: string;
|
||||
private _name: string;
|
||||
private _isReady: boolean;
|
||||
private _ready: Deferred<void>;
|
||||
private _kernelChangeCompleted: Deferred<void>;
|
||||
private _kernelPreference: IKernelPreference;
|
||||
private _kernelDisplayName: string;
|
||||
private _errorMessage: string;
|
||||
//#endregion
|
||||
|
||||
private _serverLoadFinished: Promise<void>;
|
||||
private _session: nb.ISession;
|
||||
private isServerStarted: boolean;
|
||||
private notebookManager: INotebookManager;
|
||||
private _connection: NotebookConnection;
|
||||
private _kernelConfigActions: ((kernelName: string) => Promise<any>)[] = [];
|
||||
|
||||
constructor(private options: IClientSessionOptions) {
|
||||
this._notebookUri = options.notebookUri;
|
||||
this.notebookManager = options.notebookManager;
|
||||
this._isReady = false;
|
||||
this._ready = new Deferred<void>();
|
||||
this._kernelChangeCompleted = new Deferred<void>();
|
||||
}
|
||||
|
||||
public async initialize(connection?: NotebookConnection): Promise<void> {
|
||||
try {
|
||||
this._kernelConfigActions.push((kernelName: string) => { return this.runTasksBeforeSessionStart(kernelName); });
|
||||
this._connection = connection;
|
||||
this._serverLoadFinished = this.startServer();
|
||||
await this._serverLoadFinished;
|
||||
await this.initializeSession();
|
||||
} catch (err) {
|
||||
this._errorMessage = notebookUtils.getErrorMessage(err);
|
||||
}
|
||||
// Always resolving for now. It's up to callers to check for error case
|
||||
this._isReady = true;
|
||||
this._ready.resolve();
|
||||
this._kernelChangeCompleted.resolve();
|
||||
}
|
||||
|
||||
private async startServer(): Promise<void> {
|
||||
let serverManager = this.notebookManager.serverManager;
|
||||
if (serverManager && !serverManager.isStarted) {
|
||||
await serverManager.startServer();
|
||||
if (!serverManager.isStarted) {
|
||||
throw new Error(nls.localize('ServerNotStarted', 'Server did not start for unknown reason'));
|
||||
}
|
||||
this.isServerStarted = serverManager.isStarted;
|
||||
} else {
|
||||
this.isServerStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
private async initializeSession(): Promise<void> {
|
||||
await this._serverLoadFinished;
|
||||
if (this.isServerStarted) {
|
||||
if (!this.notebookManager.sessionManager.isReady) {
|
||||
await this.notebookManager.sessionManager.ready;
|
||||
}
|
||||
if (this._kernelPreference && this._kernelPreference.shouldStart) {
|
||||
await this.startSessionInstance(this._kernelPreference.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async startSessionInstance(kernelName: string): Promise<void> {
|
||||
let session: nb.ISession;
|
||||
try {
|
||||
// TODO #3164 should use URI instead of path for startNew
|
||||
session = await this.notebookManager.sessionManager.startNew({
|
||||
path: this.notebookUri.fsPath,
|
||||
kernelName: kernelName
|
||||
// TODO add kernel name if saved in the document
|
||||
});
|
||||
session.defaultKernelLoaded = true;
|
||||
} catch (err) {
|
||||
// TODO move registration
|
||||
if (err && err.response && err.response.status === 501) {
|
||||
this.options.notificationService.warn(nls.localize('sparkKernelRequiresConnection', 'Kernel {0} was not found. The default kernel will be used instead.', kernelName));
|
||||
session = await this.notebookManager.sessionManager.startNew({
|
||||
path: this.notebookUri.fsPath,
|
||||
kernelName: undefined
|
||||
});
|
||||
session.defaultKernelLoaded = false;
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
this._session = session;
|
||||
await this.runKernelConfigActions(kernelName);
|
||||
this._statusChangedEmitter.fire(session);
|
||||
}
|
||||
|
||||
private async runKernelConfigActions(kernelName: string): Promise<void> {
|
||||
for (let startAction of this._kernelConfigActions) {
|
||||
await startAction(kernelName);
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
// No-op for now
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the server has finished loading. It may have failed to load in
|
||||
* which case the view will be in an error state.
|
||||
*/
|
||||
public get serverLoadFinished(): Promise<void> {
|
||||
return this._serverLoadFinished;
|
||||
}
|
||||
|
||||
|
||||
//#region IClientSession Properties
|
||||
public get terminated(): Event<void> {
|
||||
return this._terminatedEmitter.event;
|
||||
}
|
||||
public get kernelChanged(): Event<nb.IKernelChangedArgs> {
|
||||
return this._kernelChangedEmitter.event;
|
||||
}
|
||||
public get statusChanged(): Event<nb.ISession> {
|
||||
return this._statusChangedEmitter.event;
|
||||
}
|
||||
public get iopubMessage(): Event<nb.IMessage> {
|
||||
return this._iopubMessageEmitter.event;
|
||||
}
|
||||
public get unhandledMessage(): Event<nb.IMessage> {
|
||||
return this._unhandledMessageEmitter.event;
|
||||
}
|
||||
public get propertyChanged(): Event<'path' | 'name' | 'type'> {
|
||||
return this._propertyChangedEmitter.event;
|
||||
}
|
||||
public get kernel(): nb.IKernel | null {
|
||||
return this._session ? this._session.kernel : undefined;
|
||||
}
|
||||
public get notebookUri(): URI {
|
||||
return this._notebookUri;
|
||||
}
|
||||
public get name(): string {
|
||||
return this._name;
|
||||
}
|
||||
public get type(): string {
|
||||
return this._type;
|
||||
}
|
||||
public get status(): nb.KernelStatus {
|
||||
if (!this.isReady) {
|
||||
return 'starting';
|
||||
}
|
||||
return this._session ? this._session.status : 'dead';
|
||||
}
|
||||
public get isReady(): boolean {
|
||||
return this._isReady;
|
||||
}
|
||||
public get ready(): Promise<void> {
|
||||
return this._ready.promise;
|
||||
}
|
||||
public get kernelChangeCompleted(): Promise<void> {
|
||||
return this._kernelChangeCompleted.promise;
|
||||
}
|
||||
public get kernelPreference(): IKernelPreference {
|
||||
return this._kernelPreference;
|
||||
}
|
||||
public set kernelPreference(value: IKernelPreference) {
|
||||
this._kernelPreference = value;
|
||||
}
|
||||
public get kernelDisplayName(): string {
|
||||
return this._kernelDisplayName;
|
||||
}
|
||||
public get errorMessage(): string {
|
||||
return this._errorMessage;
|
||||
}
|
||||
public get isInErrorState(): boolean {
|
||||
return !!this._errorMessage;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region Not Yet Implemented
|
||||
/**
|
||||
* Change the current kernel associated with the document.
|
||||
*/
|
||||
async changeKernel(options: nb.IKernelSpec): Promise<nb.IKernel> {
|
||||
this._kernelChangeCompleted = new Deferred<void>();
|
||||
this._isReady = false;
|
||||
let oldKernel = this.kernel;
|
||||
let newKernel = this.kernel;
|
||||
|
||||
let kernel = await this.doChangeKernel(options);
|
||||
try {
|
||||
await kernel.ready;
|
||||
} catch (error) {
|
||||
// Cleanup some state before re-throwing
|
||||
this._isReady = kernel.isReady;
|
||||
this._kernelChangeCompleted.resolve();
|
||||
throw error;
|
||||
}
|
||||
newKernel = this._session ? kernel : this._session.kernel;
|
||||
this._isReady = kernel.isReady;
|
||||
// Send resolution events to listeners
|
||||
this._kernelChangeCompleted.resolve();
|
||||
this._kernelChangedEmitter.fire({
|
||||
oldValue: oldKernel,
|
||||
newValue: newKernel
|
||||
});
|
||||
return kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to either call ChangeKernel on current session, or start a new session
|
||||
* @param options
|
||||
*/
|
||||
private async doChangeKernel(options: nb.IKernelSpec): Promise<nb.IKernel> {
|
||||
let kernel: nb.IKernel;
|
||||
if (this._session) {
|
||||
kernel = await this._session.changeKernel(options);
|
||||
await this.runKernelConfigActions(kernel.name);
|
||||
} else {
|
||||
kernel = await this.startSessionInstance(options.name).then(() => this.kernel);
|
||||
}
|
||||
return kernel;
|
||||
}
|
||||
|
||||
public async runTasksBeforeSessionStart(kernelName: string): Promise<void> {
|
||||
// TODO we should move all Spark-related code to SparkMagicContext
|
||||
if (this._session && this._connection && this.isSparkKernel(kernelName)) {
|
||||
// TODO may need to reenable a way to get the credential
|
||||
// await this._connection.getCredential();
|
||||
// %_do_not_call_change_endpoint is a SparkMagic command that lets users change endpoint options,
|
||||
// such as user/profile/host name/auth type
|
||||
|
||||
let server = URI.parse(sparkUtils.getLivyUrl(this._connection.host, this._connection.knoxport)).toString();
|
||||
let doNotCallChangeEndpointParams =
|
||||
`%_do_not_call_change_endpoint --username=${this._connection.user} --password=${this._connection.password} --server=${server} --auth=Basic_Access`;
|
||||
let future = this._session.kernel.requestExecute({
|
||||
code: doNotCallChangeEndpointParams
|
||||
}, true);
|
||||
await future.done;
|
||||
}
|
||||
}
|
||||
|
||||
public async updateConnection(connection: NotebookConnection): Promise<void> {
|
||||
if (!this.kernel) {
|
||||
// TODO is there any case where skipping causes errors? So far it seems like it gets called twice
|
||||
return;
|
||||
}
|
||||
this._connection = (connection.connectionProfile.id !== '-1') ? connection : this._connection;
|
||||
// if kernel is not set, don't run kernel config actions
|
||||
// this should only occur when a cell is cancelled, which interrupts the kernel
|
||||
if (this.kernel && this.kernel.name) {
|
||||
await this.runKernelConfigActions(this.kernel.name);
|
||||
}
|
||||
}
|
||||
|
||||
isSparkKernel(kernelName: string): any {
|
||||
return kernelName && kernelName.toLowerCase().indexOf('spark') > -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kill the kernel and shutdown the session.
|
||||
*
|
||||
* @returns A promise that resolves when the session is shut down.
|
||||
*/
|
||||
public async shutdown(): Promise<void> {
|
||||
// Always try to shut down session
|
||||
if (this._session && this._session.id) {
|
||||
await this.notebookManager.sessionManager.shutdown(this._session.id);
|
||||
}
|
||||
let serverManager = this.notebookManager.serverManager;
|
||||
if (serverManager) {
|
||||
await serverManager.stopServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a kernel for the session.
|
||||
*/
|
||||
selectKernel(): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* Restart the session.
|
||||
*
|
||||
* @returns A promise that resolves with whether the kernel has restarted.
|
||||
*
|
||||
* #### Notes
|
||||
* If there is a running kernel, present a dialog.
|
||||
* If there is no kernel, we start a kernel with the last run
|
||||
* kernel name and resolves with `true`. If no kernel has been started,
|
||||
* this is a no-op, and resolves with `false`.
|
||||
*/
|
||||
restart(): Promise<boolean> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the session path.
|
||||
*
|
||||
* @param path - The new session path.
|
||||
*
|
||||
* @returns A promise that resolves when the session has renamed.
|
||||
*
|
||||
* #### Notes
|
||||
* This uses the Jupyter REST API, and the response is validated.
|
||||
* The promise is fulfilled on a valid response and rejected otherwise.
|
||||
*/
|
||||
setPath(path: string): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the session name.
|
||||
*/
|
||||
setName(name: string): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the session type.
|
||||
*/
|
||||
setType(type: string): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
47
src/sql/parts/notebook/models/contracts.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export type CellType = 'code' | 'markdown' | 'raw';
|
||||
|
||||
export class CellTypes {
|
||||
public static readonly Code = 'code';
|
||||
public static readonly Markdown = 'markdown';
|
||||
public static readonly Raw = 'raw';
|
||||
}
|
||||
|
||||
// to do: add all mime types
|
||||
export type MimeType = 'text/plain' | 'text/html';
|
||||
|
||||
// to do: add all mime types
|
||||
export class MimeTypes {
|
||||
public static readonly PlainText = 'text/plain';
|
||||
public static readonly HTML = 'text/html';
|
||||
}
|
||||
|
||||
export type OutputType =
|
||||
| 'execute_result'
|
||||
| 'display_data'
|
||||
| 'stream'
|
||||
| 'error'
|
||||
| 'update_display_data';
|
||||
|
||||
export class OutputTypes {
|
||||
public static readonly ExecuteResult = 'execute_result';
|
||||
public static readonly DisplayData = 'display_data';
|
||||
public static readonly Stream = 'stream';
|
||||
public static readonly Error = 'error';
|
||||
public static readonly UpdateDisplayData = 'update_display_data';
|
||||
}
|
||||
|
||||
export enum NotebookChangeType {
|
||||
CellsAdded,
|
||||
CellDeleted,
|
||||
CellSourceUpdated,
|
||||
CellOutputUpdated,
|
||||
DirtyStateChanged
|
||||
}
|
||||
23
src/sql/parts/notebook/models/modelFactory.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { nb } from 'sqlops';
|
||||
|
||||
import { CellModel } from './cell';
|
||||
import { IClientSession, IClientSessionOptions, ICellModelOptions, ICellModel, IModelFactory } from './modelInterfaces';
|
||||
import { ClientSession } from './clientSession';
|
||||
|
||||
export class ModelFactory implements IModelFactory {
|
||||
|
||||
public createCell(cell: nb.ICell, options: ICellModelOptions): ICellModel {
|
||||
return new CellModel(this, cell, options);
|
||||
}
|
||||
|
||||
public createClientSession(options: IClientSessionOptions): IClientSession {
|
||||
return new ClientSession(options);
|
||||
}
|
||||
}
|
||||