mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-24 11:01:38 -05:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b90530717 | ||
|
|
f199c7a63c | ||
|
|
50a2526d1f | ||
|
|
7fb8a28b59 | ||
|
|
30a825438e | ||
|
|
f63da13210 | ||
|
|
08d73675d4 | ||
|
|
f0f6c00a0e | ||
|
|
965458ca74 | ||
|
|
b30f7ee41c | ||
|
|
a2eb53ce0b | ||
|
|
619c816e7f | ||
|
|
3d6fb7a8fa | ||
|
|
891624c085 | ||
|
|
a7c4686980 | ||
|
|
93aa052856 | ||
|
|
61d05f6782 | ||
|
|
60ccae48f1 | ||
|
|
4b454581fd | ||
|
|
f0aadebd2c | ||
|
|
d3f0ac7954 | ||
|
|
134f76c17f | ||
|
|
b9c877a109 | ||
|
|
aa243a8aae | ||
|
|
e5c1c6f544 | ||
|
|
9e9f85079e | ||
|
|
ae8e2e1f89 | ||
|
|
b2c70e9301 | ||
|
|
e022f4a0d1 | ||
|
|
8bc32e6371 | ||
|
|
f739c47984 | ||
|
|
13fb9fdfd2 | ||
|
|
9a5f51bfbf | ||
|
|
06bab6a38c | ||
|
|
c35a14d8fd | ||
|
|
b914073147 | ||
|
|
04ae18143b | ||
|
|
efe8e81b6e | ||
|
|
c33ddfabf9 | ||
|
|
8ec5451e64 | ||
|
|
20853ddf7e | ||
|
|
091d4cb924 | ||
|
|
cd0210c88a | ||
|
|
ed10f984b6 |
3
.vscode/launch.json
vendored
3
.vscode/launch.json
vendored
@@ -89,7 +89,8 @@
|
|||||||
"skipFiles": [
|
"skipFiles": [
|
||||||
"**/winjs*.js"
|
"**/winjs*.js"
|
||||||
],
|
],
|
||||||
"webRoot": "${workspaceFolder}"
|
"webRoot": "${workspaceFolder}",
|
||||||
|
"timeout": 15000
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "node",
|
"type": "node",
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ gulp.task('mixin', function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
let serviceUrl = 'https://raw.githubusercontent.com/Microsoft/sqlopsstudio/release/extensions/extensionsGallery.json';
|
let serviceUrl = 'https://sqlopsextensions.blob.core.windows.net/marketplace/v1/extensionsGallery.json';
|
||||||
if (quality === 'insider') {
|
if (quality === 'insider') {
|
||||||
serviceUrl = `https://raw.githubusercontent.com/Microsoft/sqlopsstudio/release/extensions/extensionsGallery-${quality}.json`;
|
serviceUrl = `https://sqlopsextensions.blob.core.windows.net/marketplace/v1/extensionsGallery-${quality}.json`;
|
||||||
}
|
}
|
||||||
let newValues = {
|
let newValues = {
|
||||||
"updateUrl": updateUrl,
|
"updateUrl": updateUrl,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "agent",
|
"name": "agent",
|
||||||
"displayName": "SQL Server Agent",
|
"displayName": "SQL Server Agent",
|
||||||
"description": "Manage and troubleshoot SQL Server Agent jobs (early preview)",
|
"description": "Manage and troubleshoot SQL Server Agent jobs (early preview)",
|
||||||
"version": "0.28.0",
|
"version": "0.28.1",
|
||||||
"publisher": "Microsoft",
|
"publisher": "Microsoft",
|
||||||
"preview": true,
|
"preview": true,
|
||||||
"license": "https://raw.githubusercontent.com/Microsoft/sqlopsstudio/master/LICENSE.txt",
|
"license": "https://raw.githubusercontent.com/Microsoft/sqlopsstudio/master/LICENSE.txt",
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
"description": "Manage and troubleshoot SQL Agent jobs",
|
"description": "Manage and troubleshoot SQL Agent jobs",
|
||||||
"provider": "MSSQL",
|
"provider": "MSSQL",
|
||||||
"title": "SQL Agent",
|
"title": "SQL Agent",
|
||||||
|
"when": "connectionProvider == 'MSSQL' && !mssql:iscloud",
|
||||||
"container": {
|
"container": {
|
||||||
"controlhost-container": {
|
"controlhost-container": {
|
||||||
"type": "agent"
|
"type": "agent"
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ export class AutoFetcher {
|
|||||||
const yes: MessageItem = { title: localize('yes', "Yes") };
|
const yes: MessageItem = { title: localize('yes', "Yes") };
|
||||||
const no: MessageItem = { isCloseAffordance: true, title: localize('no', "No") };
|
const no: MessageItem = { isCloseAffordance: true, title: localize('no', "No") };
|
||||||
const askLater: MessageItem = { title: localize('not now', "Ask Me Later") };
|
const askLater: MessageItem = { title: localize('not now', "Ask Me Later") };
|
||||||
const result = await window.showInformationMessage(localize('suggest auto fetch', "Would you like Code to [periodically run 'git fetch']({0})?", 'https://go.microsoft.com/fwlink/?linkid=865294'), yes, no, askLater);
|
// {{SQL CARBON EDIT}}
|
||||||
|
const result = await window.showInformationMessage(localize('suggest auto fetch', "Would you like SQL Operations Studio to [periodically run 'git fetch']({0})?", 'https://go.microsoft.com/fwlink/?linkid=865294'), yes, no, askLater);
|
||||||
|
|
||||||
if (result === askLater) {
|
if (result === askLater) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
{
|
{
|
||||||
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
||||||
"version": "1.4.0-alpha.20",
|
"version": "1.4.0-alpha.23",
|
||||||
"downloadFileNames": {
|
"downloadFileNames": {
|
||||||
"Windows_86": "win-x86-netcoreapp2.0.zip",
|
"Windows_86": "win-x86-netcoreapp2.1.zip",
|
||||||
"Windows_64": "win-x64-netcoreapp2.0.zip",
|
"Windows_64": "win-x64-netcoreapp2.1.zip",
|
||||||
"OSX": "osx-x64-netcoreapp2.0.tar.gz",
|
"OSX": "osx-x64-netcoreapp2.1.tar.gz",
|
||||||
"CentOS_7": "rhel-x64-netcoreapp2.0.tar.gz",
|
"CentOS_7": "rhel-x64-netcoreapp2.1.tar.gz",
|
||||||
"Debian_8": "rhel-x64-netcoreapp2.0.tar.gz",
|
"Debian_8": "rhel-x64-netcoreapp2.1.tar.gz",
|
||||||
"Fedora_23": "rhel-x64-netcoreapp2.0.tar.gz",
|
"Fedora_23": "rhel-x64-netcoreapp2.1.tar.gz",
|
||||||
"OpenSUSE_13_2": "rhel-x64-netcoreapp2.0.tar.gz",
|
"OpenSUSE_13_2": "rhel-x64-netcoreapp2.1.tar.gz",
|
||||||
"RHEL_7": "rhel-x64-netcoreapp2.0.tar.gz",
|
"RHEL_7": "rhel-x64-netcoreapp2.1.tar.gz",
|
||||||
"SLES_12_2": "rhel-x64-netcoreapp2.0.tar.gz",
|
"SLES_12_2": "rhel-x64-netcoreapp2.1.tar.gz",
|
||||||
"Ubuntu_14": "rhel-x64-netcoreapp2.0.tar.gz",
|
"Ubuntu_14": "rhel-x64-netcoreapp2.1.tar.gz",
|
||||||
"Ubuntu_16": "rhel-x64-netcoreapp2.0.tar.gz"
|
"Ubuntu_16": "rhel-x64-netcoreapp2.1.tar.gz"
|
||||||
},
|
},
|
||||||
"installDirectory": "../sqltoolsservice/{#platform#}/{#version#}",
|
"installDirectory": "../sqltoolsservice/{#platform#}/{#version#}",
|
||||||
"executableFiles": ["MicrosoftSqlToolsServiceLayer.exe", "MicrosoftSqlToolsServiceLayer"]
|
"executableFiles": ["MicrosoftSqlToolsServiceLayer.exe", "MicrosoftSqlToolsServiceLayer"]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sqlops",
|
"name": "sqlops",
|
||||||
"version": "0.28.3",
|
"version": "0.28.5",
|
||||||
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
|
"distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Microsoft Corporation"
|
"name": "Microsoft Corporation"
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
"darwinBundleIdentifier": "com.sqlopsstudio.oss",
|
"darwinBundleIdentifier": "com.sqlopsstudio.oss",
|
||||||
"reportIssueUrl": "https://github.com/Microsoft/sqlopsstudio/issues/new?labels=customer%20reported%20issue",
|
"reportIssueUrl": "https://github.com/Microsoft/sqlopsstudio/issues/new?labels=customer%20reported%20issue",
|
||||||
"requestFeatureUrl": "https://github.com/Microsoft/sqlopsstudio/issues/new?labels=feature-request",
|
"requestFeatureUrl": "https://github.com/Microsoft/sqlopsstudio/issues/new?labels=feature-request",
|
||||||
|
"privacyStatementUrl": "https://privacy.microsoft.com/en-us/privacystatement",
|
||||||
|
"telemetryOptOutUrl": "https://github.com/Microsoft/sqlopsstudio/wiki/How-to-Disable-Telemetry-Reporting",
|
||||||
"urlProtocol": "sqlops",
|
"urlProtocol": "sqlops",
|
||||||
"enableTelemetry": true,
|
"enableTelemetry": true,
|
||||||
"aiConfig": {
|
"aiConfig": {
|
||||||
@@ -32,9 +34,10 @@
|
|||||||
"recommendedExtensions": [
|
"recommendedExtensions": [
|
||||||
"Microsoft.agent",
|
"Microsoft.agent",
|
||||||
"Microsoft.whoisactive",
|
"Microsoft.whoisactive",
|
||||||
"Microsoft.server-report"
|
"Microsoft.server-report",
|
||||||
|
"Redgate.sql-search"
|
||||||
],
|
],
|
||||||
"extensionsGallery": {
|
"extensionsGallery": {
|
||||||
"serviceUrl": "https://raw.githubusercontent.com/Microsoft/sqlopsstudio/release/extensions/extensionsGallery.json"
|
"serviceUrl": "https://sqlopsextensions.blob.core.windows.net/marketplace/v1/extensionsGallery.json"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
1
samples/sp_whoIsActive/.gitignore
vendored
1
samples/sp_whoIsActive/.gitignore
vendored
@@ -6,3 +6,4 @@ node_modules
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.idea
|
.idea
|
||||||
test-reports/**
|
test-reports/**
|
||||||
|
typings/sqlops.proposed.d.ts
|
||||||
|
|||||||
65
samples/sp_whoIsActive/.vscode/launch.json
vendored
65
samples/sp_whoIsActive/.vscode/launch.json
vendored
@@ -1,28 +1,57 @@
|
|||||||
|
// A launch configuration that launches the extension inside a new window
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
|
||||||
|
// To debug the extension:
|
||||||
|
// 1. please install the "SQL Operations Studio Debug" extension into VSCode
|
||||||
|
// 2. Ensure sqlops is added to your path:
|
||||||
|
// - open SQL Operations Studio
|
||||||
|
// - run the command "Install 'sqlops' command in PATH"
|
||||||
{
|
{
|
||||||
// Use IntelliSense to learn about possible attributes.
|
"version": "0.2.0",
|
||||||
// Hover to view descriptions of existing attributes.
|
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
|
||||||
{
|
{
|
||||||
"type": "node",
|
"name": "Debug in SqlOps install",
|
||||||
|
"type": "sqlopsExtensionHost",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"name": "Launch Program",
|
"runtimeExecutable": "sqlops",
|
||||||
"program": "${workspaceFolder}\\out\\src\\extension"
|
"args": [
|
||||||
|
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "attach",
|
"request": "attach",
|
||||||
"name": "Attach to Ops Studio",
|
"name": "Attach to Ops Studio",
|
||||||
"protocol": "inspector",
|
"protocol": "inspector",
|
||||||
"port": 5870,
|
"port": 5870,
|
||||||
"restart": true,
|
"restart": true,
|
||||||
"sourceMaps": true,
|
"sourceMaps": true,
|
||||||
"outFiles": [
|
"outFiles": [
|
||||||
"${workspaceRoot}/out/**/*.js"
|
"${workspaceRoot}/out/**/*.js"
|
||||||
],
|
],
|
||||||
"preLaunchTask": "",
|
"preLaunchTask": "",
|
||||||
"timeout": 25000
|
"timeout": 25000
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Debug in enlistment",
|
||||||
|
"type": "sqlopsExtensionHost",
|
||||||
|
"request": "launch",
|
||||||
|
"windows": {
|
||||||
|
"runtimeExecutable": "${workspaceFolder}/../../scripts/sql.bat"
|
||||||
|
},
|
||||||
|
"osx": {
|
||||||
|
"runtimeExecutable": "${workspaceFolder}/../../scripts/sql.sh"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"runtimeExecutable": "${workspaceFolder}/../../scripts/sql.sh"
|
||||||
|
},
|
||||||
|
"args": [
|
||||||
|
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||||
|
],
|
||||||
|
"timeout": 20000
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
926
samples/sp_whoIsActive/package-lock.json
generated
926
samples/sp_whoIsActive/package-lock.json
generated
@@ -625,6 +625,7 @@
|
|||||||
"anymatch": "2.0.0",
|
"anymatch": "2.0.0",
|
||||||
"async-each": "1.0.1",
|
"async-each": "1.0.1",
|
||||||
"braces": "2.3.1",
|
"braces": "2.3.1",
|
||||||
|
"fsevents": "1.2.0",
|
||||||
"glob-parent": "3.1.0",
|
"glob-parent": "3.1.0",
|
||||||
"inherits": "2.0.3",
|
"inherits": "2.0.3",
|
||||||
"is-binary-path": "1.0.1",
|
"is-binary-path": "1.0.1",
|
||||||
@@ -635,6 +636,13 @@
|
|||||||
"upath": "1.0.4"
|
"upath": "1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"chownr": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"circular-json": {
|
"circular-json": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
|
||||||
@@ -1715,6 +1723,16 @@
|
|||||||
"universalify": "0.1.1"
|
"universalify": "0.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fs-minipass": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"minipass": "2.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fs-mkdirp-stream": {
|
"fs-mkdirp-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
|
||||||
@@ -1730,6 +1748,815 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||||
},
|
},
|
||||||
|
"fsevents": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-ROrBIbmw4ulxmQTwYAAGyN/0xgIOAFd6gX/K3F1aGLP/K5KxkubrlGISMV5EEWEB7qtiEdE0HpaqvMMHR+Ib6w==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"nan": "2.10.0",
|
||||||
|
"node-pre-gyp": "0.9.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"abbrev": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"ajv": {
|
||||||
|
"version": "4.11.8",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"co": "4.6.0",
|
||||||
|
"json-stable-stringify": "1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ansi-regex": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"aproba": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"are-we-there-yet": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"delegates": "1.0.0",
|
||||||
|
"readable-stream": "2.2.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"asn1": {
|
||||||
|
"version": "0.2.3",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"assert-plus": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"aws-sign2": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"aws4": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"balanced-match": {
|
||||||
|
"version": "0.4.2",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"bcrypt-pbkdf": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"tweetnacl": "0.14.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"block-stream": {
|
||||||
|
"version": "0.0.9",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"inherits": "2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"boom": {
|
||||||
|
"version": "2.10.1",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"hoek": "2.16.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"brace-expansion": {
|
||||||
|
"version": "1.1.7",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"balanced-match": "0.4.2",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buffer-shims": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"caseless": {
|
||||||
|
"version": "0.12.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"co": {
|
||||||
|
"version": "4.6.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"code-point-at": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"combined-stream": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"delayed-stream": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"console-control-strings": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"core-util-is": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"cryptiles": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"boom": "2.10.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dashdash": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"assert-plus": "1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"assert-plus": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bundled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "2.6.8",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deep-extend": {
|
||||||
|
"version": "0.4.2",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"delegates": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"detect-libc": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"ecc-jsbn": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"jsbn": "0.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extend": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"extsprintf": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"forever-agent": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"form-data": {
|
||||||
|
"version": "2.1.4",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"asynckit": "0.4.0",
|
||||||
|
"combined-stream": "1.0.5",
|
||||||
|
"mime-types": "2.1.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fs.realpath": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"fstream": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "4.1.11",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"mkdirp": "0.5.1",
|
||||||
|
"rimraf": "2.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fstream-ignore": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"fstream": "1.0.11",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"minimatch": "3.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gauge": {
|
||||||
|
"version": "2.7.4",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"aproba": "1.1.1",
|
||||||
|
"console-control-strings": "1.1.0",
|
||||||
|
"has-unicode": "2.0.1",
|
||||||
|
"object-assign": "4.1.1",
|
||||||
|
"signal-exit": "3.0.2",
|
||||||
|
"string-width": "1.0.2",
|
||||||
|
"strip-ansi": "3.0.1",
|
||||||
|
"wide-align": "1.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"getpass": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"assert-plus": "1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"assert-plus": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bundled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"glob": {
|
||||||
|
"version": "7.1.2",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"fs.realpath": "1.0.0",
|
||||||
|
"inflight": "1.0.6",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"minimatch": "3.0.4",
|
||||||
|
"once": "1.4.0",
|
||||||
|
"path-is-absolute": "1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"graceful-fs": {
|
||||||
|
"version": "4.1.11",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"har-schema": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"har-validator": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"ajv": "4.11.8",
|
||||||
|
"har-schema": "1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-unicode": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"hawk": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"boom": "2.10.1",
|
||||||
|
"cryptiles": "2.0.5",
|
||||||
|
"hoek": "2.16.3",
|
||||||
|
"sntp": "1.0.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hoek": {
|
||||||
|
"version": "2.16.3",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"http-signature": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"assert-plus": "0.2.0",
|
||||||
|
"jsprim": "1.4.0",
|
||||||
|
"sshpk": "1.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inflight": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"once": "1.4.0",
|
||||||
|
"wrappy": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"ini": {
|
||||||
|
"version": "1.3.4",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"is-fullwidth-code-point": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"number-is-nan": "1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"is-typedarray": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"isarray": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"isstream": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"jodid25519": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"jsbn": "0.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jsbn": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"json-schema": {
|
||||||
|
"version": "0.2.3",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"json-stable-stringify": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"jsonify": "0.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"json-stringify-safe": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"jsonify": {
|
||||||
|
"version": "0.0.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"jsprim": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"assert-plus": "1.0.0",
|
||||||
|
"extsprintf": "1.0.2",
|
||||||
|
"json-schema": "0.2.3",
|
||||||
|
"verror": "1.3.6"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"assert-plus": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bundled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mime-db": {
|
||||||
|
"version": "1.27.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"mime-types": {
|
||||||
|
"version": "2.1.15",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"mime-db": "1.27.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimatch": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"brace-expansion": "1.1.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "0.0.8",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "0.0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"node-pre-gyp": {
|
||||||
|
"version": "0.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.9.1.tgz",
|
||||||
|
"integrity": "sha1-8RwHUW3ZL4cZnbx+GDjqt81WyeA=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"detect-libc": "1.0.2",
|
||||||
|
"mkdirp": "0.5.1",
|
||||||
|
"needle": "2.2.0",
|
||||||
|
"nopt": "4.0.1",
|
||||||
|
"npm-packlist": "1.1.10",
|
||||||
|
"npmlog": "4.1.0",
|
||||||
|
"rc": "1.2.1",
|
||||||
|
"rimraf": "2.6.1",
|
||||||
|
"semver": "5.3.0",
|
||||||
|
"tar": "4.4.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"tar": {
|
||||||
|
"version": "4.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz",
|
||||||
|
"integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"chownr": "1.0.1",
|
||||||
|
"fs-minipass": "1.2.5",
|
||||||
|
"minipass": "2.2.4",
|
||||||
|
"minizlib": "1.1.0",
|
||||||
|
"mkdirp": "0.5.1",
|
||||||
|
"safe-buffer": "5.1.1",
|
||||||
|
"yallist": "3.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nopt": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"abbrev": "1.1.0",
|
||||||
|
"osenv": "0.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"npmlog": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"are-we-there-yet": "1.1.4",
|
||||||
|
"console-control-strings": "1.1.0",
|
||||||
|
"gauge": "2.7.4",
|
||||||
|
"set-blocking": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number-is-nan": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"oauth-sign": {
|
||||||
|
"version": "0.8.2",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"wrappy": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"os-homedir": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"os-tmpdir": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"osenv": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"os-homedir": "1.0.2",
|
||||||
|
"os-tmpdir": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"path-is-absolute": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"performance-now": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"process-nextick-args": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"punycode": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"qs": {
|
||||||
|
"version": "6.4.0",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"rc": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"deep-extend": "0.4.2",
|
||||||
|
"ini": "1.3.4",
|
||||||
|
"minimist": "1.2.0",
|
||||||
|
"strip-json-comments": "2.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "2.2.9",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer-shims": "1.0.0",
|
||||||
|
"core-util-is": "1.0.2",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"isarray": "1.0.0",
|
||||||
|
"process-nextick-args": "1.0.7",
|
||||||
|
"string_decoder": "1.0.1",
|
||||||
|
"util-deprecate": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"request": {
|
||||||
|
"version": "2.81.0",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"aws-sign2": "0.6.0",
|
||||||
|
"aws4": "1.6.0",
|
||||||
|
"caseless": "0.12.0",
|
||||||
|
"combined-stream": "1.0.5",
|
||||||
|
"extend": "3.0.1",
|
||||||
|
"forever-agent": "0.6.1",
|
||||||
|
"form-data": "2.1.4",
|
||||||
|
"har-validator": "4.2.1",
|
||||||
|
"hawk": "3.1.3",
|
||||||
|
"http-signature": "1.1.1",
|
||||||
|
"is-typedarray": "1.0.0",
|
||||||
|
"isstream": "0.1.2",
|
||||||
|
"json-stringify-safe": "5.0.1",
|
||||||
|
"mime-types": "2.1.15",
|
||||||
|
"oauth-sign": "0.8.2",
|
||||||
|
"performance-now": "0.2.0",
|
||||||
|
"qs": "6.4.0",
|
||||||
|
"safe-buffer": "5.0.1",
|
||||||
|
"stringstream": "0.0.5",
|
||||||
|
"tough-cookie": "2.3.2",
|
||||||
|
"tunnel-agent": "0.6.0",
|
||||||
|
"uuid": "3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rimraf": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"glob": "7.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"set-blocking": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"signal-exit": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"sntp": {
|
||||||
|
"version": "1.0.9",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"hoek": "2.16.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sshpk": {
|
||||||
|
"version": "1.13.0",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"asn1": "0.2.3",
|
||||||
|
"assert-plus": "1.0.0",
|
||||||
|
"bcrypt-pbkdf": "1.0.1",
|
||||||
|
"dashdash": "1.14.1",
|
||||||
|
"ecc-jsbn": "0.1.1",
|
||||||
|
"getpass": "0.1.7",
|
||||||
|
"jodid25519": "1.0.2",
|
||||||
|
"jsbn": "0.1.1",
|
||||||
|
"tweetnacl": "0.14.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"assert-plus": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bundled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"string-width": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"code-point-at": "1.1.0",
|
||||||
|
"is-fullwidth-code-point": "1.0.0",
|
||||||
|
"strip-ansi": "3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stringstream": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"strip-json-comments": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"tar": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"block-stream": "0.0.9",
|
||||||
|
"fstream": "1.0.11",
|
||||||
|
"inherits": "2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tar-pack": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"debug": "2.6.8",
|
||||||
|
"fstream": "1.0.11",
|
||||||
|
"fstream-ignore": "1.0.5",
|
||||||
|
"once": "1.4.0",
|
||||||
|
"readable-stream": "2.2.9",
|
||||||
|
"rimraf": "2.6.1",
|
||||||
|
"tar": "2.2.1",
|
||||||
|
"uid-number": "0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tough-cookie": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"punycode": "1.4.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tunnel-agent": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tweetnacl": {
|
||||||
|
"version": "0.14.5",
|
||||||
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"uid-number": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"util-deprecate": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"verror": {
|
||||||
|
"version": "1.3.6",
|
||||||
|
"bundled": true,
|
||||||
|
"requires": {
|
||||||
|
"extsprintf": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wide-align": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"string-width": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"bundled": true
|
||||||
|
},
|
||||||
|
"yallist": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
|
||||||
|
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"fstream": {
|
"fstream": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
|
||||||
@@ -3195,6 +4022,26 @@
|
|||||||
"sshpk": "1.14.1"
|
"sshpk": "1.14.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"iconv-lite": {
|
||||||
|
"version": "0.4.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz",
|
||||||
|
"integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"safer-buffer": "2.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ignore-walk": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"minimatch": "3.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"inflight": {
|
"inflight": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||||
@@ -3998,6 +4845,34 @@
|
|||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
|
||||||
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
|
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
|
||||||
},
|
},
|
||||||
|
"minipass": {
|
||||||
|
"version": "2.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz",
|
||||||
|
"integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "5.1.1",
|
||||||
|
"yallist": "3.0.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"yallist": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
|
||||||
|
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minizlib": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"minipass": "2.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"mixin-deep": {
|
"mixin-deep": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
|
||||||
@@ -4105,6 +4980,13 @@
|
|||||||
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
|
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"nan": {
|
||||||
|
"version": "2.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
|
||||||
|
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"nanomatch": {
|
"nanomatch": {
|
||||||
"version": "1.2.9",
|
"version": "1.2.9",
|
||||||
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
|
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
|
||||||
@@ -4133,6 +5015,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"needle": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"iconv-lite": "0.4.21",
|
||||||
|
"sax": "1.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"next-tick": {
|
"next-tick": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
|
||||||
@@ -4182,6 +5076,24 @@
|
|||||||
"once": "1.4.0"
|
"once": "1.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"npm-bundled": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"npm-packlist": {
|
||||||
|
"version": "1.1.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz",
|
||||||
|
"integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"ignore-walk": "3.0.1",
|
||||||
|
"npm-bundled": "1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nth-check": {
|
"nth-check": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
|
||||||
@@ -5123,6 +6035,20 @@
|
|||||||
"ret": "0.1.15"
|
"ret": "0.1.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"safer-buffer": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"sax": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||||
|
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||||
|
|||||||
@@ -206,11 +206,11 @@
|
|||||||
"snippets": []
|
"snippets": []
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "node ./node_modules/sqlops/bin/install",
|
|
||||||
"build": "gulp build",
|
"build": "gulp build",
|
||||||
"compile": "gulp compile",
|
"compile": "gulp compile",
|
||||||
"watch": "gulp watch",
|
"watch": "gulp watch",
|
||||||
"postinstall": "node ./node_modules/vscode/bin/install"
|
"typings": "gulp copytypings",
|
||||||
|
"postinstall": "node ./node_modules/vscode/bin/install && node ./node_modules/sqlops/bin/install && gulp copytypings"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fs-extra": "^5.0.0",
|
"fs-extra": "^5.0.0",
|
||||||
|
|||||||
@@ -49,15 +49,12 @@ export default class MainController extends ControllerBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onExecute(connection: sqlops.IConnectionProfile, fileName: string): void {
|
private onExecute(connection: sqlops.IConnectionProfile, fileName: string): void {
|
||||||
let sqlFile = fs.readFileSync(path.join(__dirname, '..', 'sql', fileName)).toString();
|
let sqlContent = fs.readFileSync(path.join(__dirname, '..', 'sql', fileName)).toString();
|
||||||
this.openSQLFileWithContent(sqlFile);
|
vscode.workspace.openTextDocument({language: 'sql', content: sqlContent}).then(doc => {
|
||||||
}
|
vscode.window.showTextDocument(doc, vscode.ViewColumn.Active, false).then(() => {
|
||||||
|
let filePath = doc.uri.toString();
|
||||||
private openSQLFileWithContent(content: string): void {
|
sqlops.queryeditor.connect(filePath, connection.id).then(() => sqlops.queryeditor.runQuery(filePath));
|
||||||
vscode.workspace.openTextDocument({language: 'sql', content: content}).then(doc => {
|
});
|
||||||
vscode.window.showTextDocument(doc, vscode.ViewColumn.Active, false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@@ -116,3 +116,8 @@ gulp.task('test', (done) => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gulp.task('copytypings', function() {
|
||||||
|
return gulp.src(config.paths.project.root + '/../../src/sql/sqlops.proposed.d.ts')
|
||||||
|
.pipe(gulp.dest('typings/'));
|
||||||
|
});
|
||||||
|
|||||||
3
samples/sqlservices/.gitignore
vendored
Normal file
3
samples/sqlservices/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
*.vsix
|
||||||
|
typings/sqlops.proposed.d.ts
|
||||||
57
samples/sqlservices/.vscode/launch.json
vendored
Normal file
57
samples/sqlservices/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// A launch configuration that launches the extension inside a new window
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
|
||||||
|
// To debug the extension:
|
||||||
|
// 1. please install the "SQL Operations Studio Debug" extension into VSCode
|
||||||
|
// 2. Ensure sqlops is added to your path:
|
||||||
|
// - open SQL Operations Studio
|
||||||
|
// - run the command "Install 'sqlops' command in PATH"
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "Debug in SqlOps install",
|
||||||
|
"type": "sqlopsExtensionHost",
|
||||||
|
"request": "launch",
|
||||||
|
"runtimeExecutable": "sqlops",
|
||||||
|
"args": [
|
||||||
|
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "Attach to Ops Studio",
|
||||||
|
"protocol": "inspector",
|
||||||
|
"port": 5870,
|
||||||
|
"restart": true,
|
||||||
|
"sourceMaps": true,
|
||||||
|
"outFiles": [
|
||||||
|
"${workspaceRoot}/out/**/*.js"
|
||||||
|
],
|
||||||
|
"preLaunchTask": "",
|
||||||
|
"timeout": 25000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Debug in enlistment",
|
||||||
|
"type": "sqlopsExtensionHost",
|
||||||
|
"request": "launch",
|
||||||
|
"windows": {
|
||||||
|
"runtimeExecutable": "${workspaceFolder}/../../scripts/sql.bat"
|
||||||
|
},
|
||||||
|
"osx": {
|
||||||
|
"runtimeExecutable": "${workspaceFolder}/../../scripts/sql.sh"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"runtimeExecutable": "${workspaceFolder}/../../scripts/sql.sh"
|
||||||
|
},
|
||||||
|
"args": [
|
||||||
|
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||||
|
],
|
||||||
|
"timeout": 20000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
14
samples/sqlservices/.vscode/tasks.json
vendored
Normal file
14
samples/sqlservices/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "gulp",
|
||||||
|
"task": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gulp-tsc"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
4
samples/sqlservices/.vscodeignore
Normal file
4
samples/sqlservices/.vscodeignore
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.vscode/**
|
||||||
|
.vscode-test/**
|
||||||
|
.gitignore
|
||||||
|
vsc-extension-quickstart.md
|
||||||
1
samples/sqlservices/README.md
Normal file
1
samples/sqlservices/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
This is a sample extension that will show some basic model-backed UI scenarios. The long-term goal is to use SQL Service querying (e.g. see if Agent and other services are running) and visualize in interesting ways. Additional suggestions for improving this sample are welcome.
|
||||||
14
samples/sqlservices/gulpfile.js
Normal file
14
samples/sqlservices/gulpfile.js
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.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// NOTE: These are es6 gulpfiles
|
||||||
|
|
||||||
|
// Basic build tasks
|
||||||
|
require('./tasks/buildtasks');
|
||||||
|
|
||||||
|
// VSIX generation tasks
|
||||||
|
require('./tasks/packagetasks');
|
||||||
7118
samples/sqlservices/package-lock.json
generated
Normal file
7118
samples/sqlservices/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
81
samples/sqlservices/package.json
Normal file
81
samples/sqlservices/package.json
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
{
|
||||||
|
"name": "sqlservices",
|
||||||
|
"displayName": "sqlservices",
|
||||||
|
"description": "Lists SQL Server service status in the management dashboard for a server",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"publisher": "demo",
|
||||||
|
"engines": {
|
||||||
|
"vscode": "^1.21.0",
|
||||||
|
"sqlops": "*"
|
||||||
|
},
|
||||||
|
"categories": [
|
||||||
|
"Other"
|
||||||
|
],
|
||||||
|
"activationEvents": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"main": "./out/src/extension",
|
||||||
|
"contributes": {
|
||||||
|
"dashboard.tabs": [
|
||||||
|
{
|
||||||
|
"id": "sqlservices.tab",
|
||||||
|
"title": "sqlservices",
|
||||||
|
"icon": {
|
||||||
|
"light": "./out/src/media/insights.svg",
|
||||||
|
"dark": "./out/src/media/insights_inverse.svg"
|
||||||
|
},
|
||||||
|
"description": "Shows available services running in the SQL Server instance",
|
||||||
|
"container": {
|
||||||
|
"nav-section": [
|
||||||
|
{
|
||||||
|
"id": "sqlservices",
|
||||||
|
"title": "Services",
|
||||||
|
"gridItemConfig": {
|
||||||
|
"sizex": 2,
|
||||||
|
"sizey": 1
|
||||||
|
},
|
||||||
|
"container": {
|
||||||
|
"modelview-container": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "splitPanel",
|
||||||
|
"title": "SplitPanel",
|
||||||
|
"gridItemConfig": {
|
||||||
|
"sizex": 2,
|
||||||
|
"sizey": 1
|
||||||
|
},
|
||||||
|
"container": {
|
||||||
|
"modelview-container": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "gulp build",
|
||||||
|
"compile": "gulp compile",
|
||||||
|
"watch": "gulp watch",
|
||||||
|
"typings": "gulp copytypings",
|
||||||
|
"postinstall": "node ./node_modules/vscode/bin/install && node ./node_modules/sqlops/bin/install && gulp copytypings"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vscode-nls": "^3.2.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^7.0.43",
|
||||||
|
"child-process-promise": "^2.2.1",
|
||||||
|
"del": "^3.0.0",
|
||||||
|
"gulp": "^4.0.0",
|
||||||
|
"gulp-color": "0.0.1",
|
||||||
|
"gulp-sourcemaps": "^2.6.4",
|
||||||
|
"gulp-tslint": "^6.0.2",
|
||||||
|
"gulp-typescript": "^3.2.4",
|
||||||
|
"sqlops": "github:anthonydresser/sqlops-extension-sqlops",
|
||||||
|
"tslint": "^3.14.0",
|
||||||
|
"typescript": "^2.6.1",
|
||||||
|
"vscode": "^1.1.14"
|
||||||
|
}
|
||||||
|
}
|
||||||
9
samples/sqlservices/sql/query.sql
Normal file
9
samples/sqlservices/sql/query.sql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* This file should contain SQL code that returns a result set
|
||||||
|
* To get started, build your own queries in SQL Operations Studio and click the
|
||||||
|
* "View as Chart" button to get the correct chart format. Then choose "Create Insight"
|
||||||
|
* and update the package.json with the JSON contents, and this file with the query
|
||||||
|
* used to generate the chart.
|
||||||
|
*/
|
||||||
|
select 'My Label' as [Label], 1 as [Value]
|
||||||
10
samples/sqlservices/src/constants.ts
Normal file
10
samples/sqlservices/src/constants.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// CONFIG VALUES ///////////////////////////////////////////////////////////
|
||||||
|
export const extensionConfigSectionName = 'sqlservices';
|
||||||
|
export const configLogDebugInfo = 'logDebugInfo';
|
||||||
109
samples/sqlservices/src/controllers/mainController.ts
Normal file
109
samples/sqlservices/src/controllers/mainController.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.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import * as sqlops from 'sqlops';
|
||||||
|
import * as Utils from '../utils';
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import SplitPropertiesPanel from './splitPropertiesPanel';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main controller class that initializes the extension
|
||||||
|
*/
|
||||||
|
export default class MainController implements vscode.Disposable {
|
||||||
|
|
||||||
|
constructor(protected context: vscode.ExtensionContext) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public dispose(): void {
|
||||||
|
this.deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivates the extension
|
||||||
|
*/
|
||||||
|
public deactivate(): void {
|
||||||
|
Utils.logDebug('Main controller deactivated');
|
||||||
|
}
|
||||||
|
|
||||||
|
public activate(): Promise<boolean> {
|
||||||
|
this.registerSqlServicesModelView();
|
||||||
|
this.registerSplitPanelModelView();
|
||||||
|
|
||||||
|
sqlops.tasks.registerTask('sqlservices.clickTask', (profile) => {
|
||||||
|
vscode.window.showInformationMessage(`Clicked from profile ${profile.serverName}.${profile.databaseName}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
return Promise.resolve(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private registerSqlServicesModelView(): void {
|
||||||
|
sqlops.dashboard.registerModelViewProvider('sqlservices', async (view) => {
|
||||||
|
let flexModel = view.modelBuilder.flexContainer()
|
||||||
|
.withLayout({
|
||||||
|
flexFlow: 'row',
|
||||||
|
alignItems: 'center'
|
||||||
|
}).withItems([
|
||||||
|
// 1st child panel with N cards
|
||||||
|
view.modelBuilder.flexContainer()
|
||||||
|
.withLayout({
|
||||||
|
flexFlow: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
})
|
||||||
|
.withItems([
|
||||||
|
view.modelBuilder.card()
|
||||||
|
.withProperties<sqlops.CardProperties>({
|
||||||
|
label: 'label1',
|
||||||
|
value: 'value1',
|
||||||
|
actions: [{ label: 'action', taskId: 'sqlservices.clickTask' }]
|
||||||
|
})
|
||||||
|
.component()
|
||||||
|
]).component(),
|
||||||
|
// 2nd child panel with N cards
|
||||||
|
view.modelBuilder.flexContainer()
|
||||||
|
.withLayout({ flexFlow: 'column' })
|
||||||
|
.withItems([
|
||||||
|
view.modelBuilder.card()
|
||||||
|
.withProperties<sqlops.CardProperties>({
|
||||||
|
label: 'label2',
|
||||||
|
value: 'value2',
|
||||||
|
actions: [{ label: 'action', taskId: 'sqlservices.clickTask' }]
|
||||||
|
})
|
||||||
|
.component()
|
||||||
|
]).component()
|
||||||
|
], { flex: '1 1 50%' })
|
||||||
|
.component();
|
||||||
|
await view.initializeModel(flexModel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private registerSplitPanelModelView(): void {
|
||||||
|
sqlops.dashboard.registerModelViewProvider('splitPanel', async (view) => {
|
||||||
|
let numPanels = 3;
|
||||||
|
let splitPanel = new SplitPropertiesPanel(view, numPanels);
|
||||||
|
await view.initializeModel(splitPanel.modelBase);
|
||||||
|
|
||||||
|
// Add a bunch of cards after an initial timeout
|
||||||
|
setTimeout(async () => {
|
||||||
|
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
let panel = i % numPanels;
|
||||||
|
let card = view.modelBuilder.card().component();
|
||||||
|
card.label = `label${i.toString()}`;
|
||||||
|
|
||||||
|
splitPanel.addItem(card, panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
43
samples/sqlservices/src/controllers/splitPropertiesPanel.ts
Normal file
43
samples/sqlservices/src/controllers/splitPropertiesPanel.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 * as sqlops from 'sqlops';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main controller class that initializes the extension
|
||||||
|
*/
|
||||||
|
export default class SplitPropertiesPanel {
|
||||||
|
private panels: sqlops.FlexContainer[];
|
||||||
|
private _modelBase: sqlops.FlexContainer;
|
||||||
|
constructor(view: sqlops.ModelView, numPanels: number) {
|
||||||
|
this.panels = [];
|
||||||
|
let ratio = Math.round(100 / numPanels);
|
||||||
|
for (let i = 0; i < numPanels; i++) {
|
||||||
|
this.panels.push(view.modelBuilder.flexContainer()
|
||||||
|
.withLayout({ flexFlow: 'column' }).component());
|
||||||
|
}
|
||||||
|
this._modelBase = view.modelBuilder.flexContainer()
|
||||||
|
.withLayout({
|
||||||
|
flexFlow: 'row'
|
||||||
|
}).withItems(this.panels, {
|
||||||
|
flex: `0 1 ${ratio}%`
|
||||||
|
})
|
||||||
|
.component();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get modelBase(): sqlops.Component {
|
||||||
|
return this._modelBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addItem(item: sqlops.Component, panel: number): void {
|
||||||
|
if (panel >= this.panels.length) {
|
||||||
|
throw new Error(`Cannot add to panel ${panel} as only ${this.panels.length - 1} panels defined`);
|
||||||
|
}
|
||||||
|
this.panels[panel].addItem(item, undefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
37
samples/sqlservices/src/extension.ts
Normal file
37
samples/sqlservices/src/extension.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 * as vscode from 'vscode';
|
||||||
|
|
||||||
|
import MainController from './controllers/mainController';
|
||||||
|
|
||||||
|
let mainController: MainController;
|
||||||
|
|
||||||
|
export function activate(context: vscode.ExtensionContext): Promise<boolean> {
|
||||||
|
let activations: Promise<boolean>[] = [];
|
||||||
|
|
||||||
|
// Start the main controller
|
||||||
|
mainController = new MainController(context);
|
||||||
|
context.subscriptions.push(mainController);
|
||||||
|
activations.push(mainController.activate());
|
||||||
|
|
||||||
|
return Promise.all(activations)
|
||||||
|
.then((results: boolean[]) => {
|
||||||
|
for (let result of results) {
|
||||||
|
if (!result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deactivate(): void {
|
||||||
|
if (mainController) {
|
||||||
|
mainController.deactivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
1
samples/sqlservices/src/media/insights.svg
Normal file
1
samples/sqlservices/src/media/insights.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:#212121;}</style></defs><title>insights</title><path class="cls-1" d="M15,4V8H14V5.71L9.49,10.2l-2-2L2,13.71V14H15v1H1V1H2V12.29L7.49,6.8l2,2L13.28,5H11V4Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 282 B |
1
samples/sqlservices/src/media/insights_inverse.svg
Normal file
1
samples/sqlservices/src/media/insights_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;}</style></defs><title>insights_inverse</title><path class="cls-1" d="M15,4V8H14V5.71L9.49,10.2l-2-2L2,13.71V14H15v1H1V1H2V12.29L7.49,6.8l2,2L13.28,5H11V4Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 287 B |
52
samples/sqlservices/src/utils.ts
Normal file
52
samples/sqlservices/src/utils.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 * as fs from 'fs-extra';
|
||||||
|
import * as handlebars from 'handlebars';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
|
import * as Constants from './constants';
|
||||||
|
import * as nls from 'vscode-nls';
|
||||||
|
|
||||||
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to log messages to the developer console if enabled
|
||||||
|
* @param msg Message to log to the console
|
||||||
|
*/
|
||||||
|
export function logDebug(msg: any): void {
|
||||||
|
let config = vscode.workspace.getConfiguration(Constants.extensionConfigSectionName);
|
||||||
|
let logDebugInfo = config[Constants.configLogDebugInfo];
|
||||||
|
if (logDebugInfo === true) {
|
||||||
|
let currentTime = new Date().toLocaleTimeString();
|
||||||
|
let outputMsg = '[' + currentTime + ']: ' + msg ? msg.toString() : '';
|
||||||
|
console.log(outputMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderTemplateHtml(extensionPath: string, templateName: string, templateValues: object): Thenable<string> {
|
||||||
|
let templatePath = path.join(extensionPath, 'resources', templateName);
|
||||||
|
|
||||||
|
// 1) Read the template from the disk
|
||||||
|
// 2) Compile it as a handlebars template and render the HTML
|
||||||
|
// 3) On failure, return a simple string as an error
|
||||||
|
return fs.readFile(templatePath, 'utf-8')
|
||||||
|
.then(templateText => {
|
||||||
|
let template = handlebars.compile(templateText);
|
||||||
|
return template(templateValues);
|
||||||
|
})
|
||||||
|
.then(
|
||||||
|
undefined,
|
||||||
|
error => {
|
||||||
|
logDebug(error);
|
||||||
|
return localize('errorLoadingTab', 'An error occurred while loading the tab');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
124
samples/sqlservices/tasks/buildtasks.js
Normal file
124
samples/sqlservices/tasks/buildtasks.js
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
let del = require('del');
|
||||||
|
let gulp = require('gulp');
|
||||||
|
let srcmap = require('gulp-sourcemaps');
|
||||||
|
let tslint = require('gulp-tslint');
|
||||||
|
let ts = require('gulp-typescript');
|
||||||
|
let cproc = require('child_process');
|
||||||
|
let os = require('os');
|
||||||
|
|
||||||
|
let config = require('./config');
|
||||||
|
let tsProject = ts.createProject('tsconfig.json');
|
||||||
|
|
||||||
|
|
||||||
|
// GULP TASKS //////////////////////////////////////////////////////////////
|
||||||
|
gulp.task('clean', function(done) {
|
||||||
|
return del('out', done);
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('lint', () => {
|
||||||
|
return gulp.src([
|
||||||
|
config.paths.project.root + '/src/**/*.ts',
|
||||||
|
config.paths.project.root + '/test/**/*.ts'
|
||||||
|
])
|
||||||
|
.pipe((tslint({
|
||||||
|
formatter: "verbose"
|
||||||
|
})))
|
||||||
|
.pipe(tslint.report());
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('compile:src', function(done) {
|
||||||
|
gulp.src([
|
||||||
|
config.paths.project.root + '/src/**/*.sql',
|
||||||
|
config.paths.project.root + '/src/**/*.svg',
|
||||||
|
config.paths.project.root + '/src/**/*.html'
|
||||||
|
]).pipe(gulp.dest('out/src/'));
|
||||||
|
|
||||||
|
let srcFiles = [
|
||||||
|
config.paths.project.root + '/src/**/*.ts',
|
||||||
|
config.paths.project.root + '/src/**/*.js',
|
||||||
|
config.paths.project.root + '/typings/**/*.ts'
|
||||||
|
];
|
||||||
|
|
||||||
|
return gulp.src(srcFiles)
|
||||||
|
.pipe(srcmap.init())
|
||||||
|
.pipe(tsProject())
|
||||||
|
.on('error', function() {
|
||||||
|
if (process.env.BUILDMACHINE) {
|
||||||
|
done('Extension Tests failed to build. See Above.');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.pipe(srcmap.write('.', {
|
||||||
|
sourceRoot: function(file) {
|
||||||
|
return file.cwd + '/src';
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest('out/src/'));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('compile:test', function(done) {
|
||||||
|
let srcFiles = [
|
||||||
|
config.paths.project.root + '/test/**/*.ts',
|
||||||
|
config.paths.project.root + '/typings/**/*.ts'
|
||||||
|
];
|
||||||
|
|
||||||
|
return gulp.src(srcFiles)
|
||||||
|
.pipe(srcmap.init())
|
||||||
|
.pipe(tsProject())
|
||||||
|
.on('error', function() {
|
||||||
|
if(process.env.BUILDMACHINE) {
|
||||||
|
done('Failed to compile test source, see above.');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.pipe(srcmap.write('.', {sourceRoot: function(file) { return file.cwd + '/test'; }}))
|
||||||
|
.pipe(gulp.dest('out/test/'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// COMPOSED GULP TASKS /////////////////////////////////////////////////////
|
||||||
|
gulp.task("compile", gulp.series("compile:src", "compile:test"));
|
||||||
|
|
||||||
|
gulp.task("build", gulp.series("clean", "lint", "compile"));
|
||||||
|
|
||||||
|
gulp.task("watch", function() {
|
||||||
|
gulp.watch([config.paths.project.root + '/src/**/*',
|
||||||
|
config.paths.project.root + '/test/**/*.ts'],
|
||||||
|
gulp.series('build'));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('test', (done) => {
|
||||||
|
let workspace = process.env['WORKSPACE'];
|
||||||
|
if (!workspace) {
|
||||||
|
workspace = process.cwd();
|
||||||
|
}
|
||||||
|
process.env.JUNIT_REPORT_PATH = workspace + '/test-reports/ext_xunit.xml';
|
||||||
|
|
||||||
|
let sqlopsPath = 'sqlops';
|
||||||
|
if (process.env['SQLOPS_DEV']) {
|
||||||
|
let suffix = os.platform === 'win32' ? 'bat' : 'sh';
|
||||||
|
sqlopsPath = `${process.env['SQLOPS_DEV']}/scripts/sql-cli.${suffix}`;
|
||||||
|
}
|
||||||
|
console.log(`Using SQLOPS Path of ${sqlopsPath}`);
|
||||||
|
|
||||||
|
cproc.exec(`${sqlopsPath} --extensionDevelopmentPath="${workspace}" --extensionTestsPath="${workspace}/out/test" --verbose`, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
console.error(`exec error: ${error}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
console.log(`stdout: ${stdout}`);
|
||||||
|
console.log(`stderr: ${stderr}`);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('copytypings', function() {
|
||||||
|
return gulp.src(config.paths.project.root + '/../../src/sql/sqlops.proposed.d.ts')
|
||||||
|
.pipe(gulp.dest('typings/'));
|
||||||
|
});
|
||||||
24
samples/sqlservices/tasks/config.js
Normal file
24
samples/sqlservices/tasks/config.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
var projectRoot = path.resolve(path.dirname(__dirname));
|
||||||
|
var srcRoot = path.resolve(projectRoot, 'src');
|
||||||
|
var localization = path.resolve(projectRoot, 'localization');
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
paths: {
|
||||||
|
project: {
|
||||||
|
root: projectRoot,
|
||||||
|
localization: localization
|
||||||
|
},
|
||||||
|
extension: {
|
||||||
|
root: srcRoot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = config;
|
||||||
36
samples/sqlservices/tasks/packagetasks.js
Normal file
36
samples/sqlservices/tasks/packagetasks.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
let gulp = require('gulp');
|
||||||
|
let exec = require('child-process-promise').exec;
|
||||||
|
let color = require('gulp-color');
|
||||||
|
|
||||||
|
// CONSTANTS ///////////////////////////////////////////////////////////////
|
||||||
|
let packageVals = require('../package');
|
||||||
|
|
||||||
|
// HELPER FUNCTIONS ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
let buildPackage = function(packageName) {
|
||||||
|
// Make sure there are
|
||||||
|
if (!packageVals.repository) {
|
||||||
|
return Promise.reject("Repository field is not defined in package.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the package command with program and command
|
||||||
|
let vsceArgs = [];
|
||||||
|
vsceArgs.push('./node_modules/vsce/out/vsce');
|
||||||
|
vsceArgs.push('package'); // package command
|
||||||
|
|
||||||
|
// Add the package name
|
||||||
|
vsceArgs.push('-o');
|
||||||
|
vsceArgs.push(packageName);
|
||||||
|
|
||||||
|
// Put it all together and execute the command
|
||||||
|
let command = vsceArgs.join(' ');
|
||||||
|
console.log(command);
|
||||||
|
return exec(command);
|
||||||
|
};
|
||||||
16
samples/sqlservices/tsconfig.json
Normal file
16
samples/sqlservices/tsconfig.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"compileOnSave": true,
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "ES6",
|
||||||
|
"lib": [ "es6" ],
|
||||||
|
"sourceMap": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"rootDir": "."
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
".vscode-test"
|
||||||
|
]
|
||||||
|
}
|
||||||
123
samples/sqlservices/tslint.json
Normal file
123
samples/sqlservices/tslint.json
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
{
|
||||||
|
"rules": {
|
||||||
|
"align": [
|
||||||
|
true,
|
||||||
|
"parameters",
|
||||||
|
"statements"
|
||||||
|
],
|
||||||
|
"ban": false,
|
||||||
|
"class-name": true,
|
||||||
|
"comment-format": [
|
||||||
|
true,
|
||||||
|
"check-space"
|
||||||
|
],
|
||||||
|
"curly": true,
|
||||||
|
"eofline": true,
|
||||||
|
"forin": true,
|
||||||
|
"indent": [
|
||||||
|
true,
|
||||||
|
"tabs"
|
||||||
|
],
|
||||||
|
"interface-name": true,
|
||||||
|
"jsdoc-format": true,
|
||||||
|
"label-position": true,
|
||||||
|
"label-undefined": true,
|
||||||
|
"max-line-length": [
|
||||||
|
true,
|
||||||
|
160
|
||||||
|
],
|
||||||
|
"member-access": false,
|
||||||
|
"member-ordering": false,
|
||||||
|
"no-any": false,
|
||||||
|
"no-arg": true,
|
||||||
|
"no-bitwise": true,
|
||||||
|
"no-conditional-assignment": true,
|
||||||
|
"no-consecutive-blank-lines": false,
|
||||||
|
"no-console": [
|
||||||
|
true,
|
||||||
|
"debug",
|
||||||
|
"info",
|
||||||
|
"time",
|
||||||
|
"timeEnd",
|
||||||
|
"trace"
|
||||||
|
],
|
||||||
|
"no-construct": true,
|
||||||
|
"no-constructor-vars": false,
|
||||||
|
"no-debugger": true,
|
||||||
|
"no-duplicate-key": true,
|
||||||
|
"no-duplicate-variable": true,
|
||||||
|
"no-empty": true,
|
||||||
|
"no-eval": true,
|
||||||
|
"no-inferrable-types": false,
|
||||||
|
"no-internal-module": true,
|
||||||
|
"no-null-keyword": true,
|
||||||
|
"no-require-imports": false,
|
||||||
|
"no-shadowed-variable": true,
|
||||||
|
"no-string-literal": false,
|
||||||
|
"no-switch-case-fall-through": false,
|
||||||
|
"no-trailing-whitespace": true,
|
||||||
|
"no-unreachable": true,
|
||||||
|
"no-unused-expression": false,
|
||||||
|
"no-unused-variable": true,
|
||||||
|
"no-use-before-declare": true,
|
||||||
|
"no-var-keyword": true,
|
||||||
|
"no-var-requires": false,
|
||||||
|
"object-literal-sort-keys": false,
|
||||||
|
"one-line": [
|
||||||
|
true,
|
||||||
|
"check-open-brace",
|
||||||
|
"check-catch",
|
||||||
|
"check-else",
|
||||||
|
"check-finally",
|
||||||
|
"check-whitespace"
|
||||||
|
],
|
||||||
|
"quotemark": [
|
||||||
|
true,
|
||||||
|
"single",
|
||||||
|
"avoid-escape"
|
||||||
|
],
|
||||||
|
"radix": true,
|
||||||
|
"semicolon": true,
|
||||||
|
"switch-default": true,
|
||||||
|
"trailing-comma": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"multiline": "never",
|
||||||
|
"singleline": "never"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"triple-equals": [
|
||||||
|
true,
|
||||||
|
"allow-null-check"
|
||||||
|
],
|
||||||
|
"typedef": [
|
||||||
|
true,
|
||||||
|
"call-signature",
|
||||||
|
"property-declaration"
|
||||||
|
],
|
||||||
|
"typedef-whitespace": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"call-signature": "nospace",
|
||||||
|
"index-signature": "nospace",
|
||||||
|
"parameter": "nospace",
|
||||||
|
"property-declaration": "nospace",
|
||||||
|
"variable-declaration": "nospace"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"use-strict": false,
|
||||||
|
"variable-name": [
|
||||||
|
true,
|
||||||
|
"allow-leading-underscore",
|
||||||
|
"ban-keywords"
|
||||||
|
],
|
||||||
|
"whitespace": [
|
||||||
|
true,
|
||||||
|
"check-branch",
|
||||||
|
"check-decl",
|
||||||
|
"check-operator",
|
||||||
|
"check-separator",
|
||||||
|
"check-type"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
3689
samples/sqlservices/yarn.lock
Normal file
3689
samples/sqlservices/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,7 @@ export interface ICheckboxOptions {
|
|||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
checked?: boolean;
|
checked?: boolean;
|
||||||
onChange?: (val: boolean) => void;
|
onChange?: (val: boolean) => void;
|
||||||
|
ariaLabel?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Checkbox extends Widget {
|
export class Checkbox extends Widget {
|
||||||
@@ -27,6 +28,10 @@ export class Checkbox extends Widget {
|
|||||||
this._el = document.createElement('input');
|
this._el = document.createElement('input');
|
||||||
this._el.type = 'checkbox';
|
this._el.type = 'checkbox';
|
||||||
|
|
||||||
|
if (opts.ariaLabel) {
|
||||||
|
this._el.setAttribute('aria-label', opts.ariaLabel);
|
||||||
|
}
|
||||||
|
|
||||||
this.onchange(this._el, e => {
|
this.onchange(this._el, e => {
|
||||||
this._onChange.fire(this.checked);
|
this._onChange.fire(this.checked);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ export interface IDropdownOptions extends IDropdownStyles {
|
|||||||
* Error Message to show if input is not part of the supplied list, only used if strictSelection = false
|
* Error Message to show if input is not part of the supplied list, only used if strictSelection = false
|
||||||
*/
|
*/
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
|
/**
|
||||||
|
* Value to use as aria-label for the input box
|
||||||
|
*/
|
||||||
|
ariaLabel?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDropdownStyles {
|
export interface IDropdownStyles {
|
||||||
@@ -124,7 +128,8 @@ export class Dropdown extends Disposable {
|
|||||||
validation: v => this._inputValidator(v)
|
validation: v => this._inputValidator(v)
|
||||||
},
|
},
|
||||||
placeholder: this._options.placeholder,
|
placeholder: this._options.placeholder,
|
||||||
actions: [this._toggleAction]
|
actions: [this._toggleAction],
|
||||||
|
ariaLabel: this._options.ariaLabel
|
||||||
});
|
});
|
||||||
|
|
||||||
this._register(DOM.addDisposableListener(this._input.inputElement, DOM.EventType.FOCUS, () => {
|
this._register(DOM.addDisposableListener(this._input.inputElement, DOM.EventType.FOCUS, () => {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/cont
|
|||||||
import { Button } from 'sql/base/browser/ui/button/button';
|
import { Button } from 'sql/base/browser/ui/button/button';
|
||||||
import * as TelemetryUtils from 'sql/common/telemetryUtilities';
|
import * as TelemetryUtils from 'sql/common/telemetryUtilities';
|
||||||
import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
||||||
|
import { localize } from 'vs/nls';
|
||||||
|
|
||||||
export const MODAL_SHOWING_KEY = 'modalShowing';
|
export const MODAL_SHOWING_KEY = 'modalShowing';
|
||||||
export const MODAL_SHOWING_CONTEXT = new RawContextKey<Array<string>>(MODAL_SHOWING_KEY, []);
|
export const MODAL_SHOWING_CONTEXT = new RawContextKey<Array<string>>(MODAL_SHOWING_KEY, []);
|
||||||
@@ -155,6 +156,7 @@ export abstract class Modal extends Disposable implements IThemable {
|
|||||||
modalHeader.div({ class: 'modal-go-back' }, (cellContainer) => {
|
modalHeader.div({ class: 'modal-go-back' }, (cellContainer) => {
|
||||||
this._backButton = new Button(cellContainer);
|
this._backButton = new Button(cellContainer);
|
||||||
this._backButton.icon = 'backButtonIcon';
|
this._backButton.icon = 'backButtonIcon';
|
||||||
|
this._backButton.title = localize('modalBack', "Back");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this._modalOptions.hasTitleIcon) {
|
if (this._modalOptions.hasTitleIcon) {
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ export function createOptionElement(option: sqlops.ServiceOption, rowContainer:
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
ariaLabel: option.displayName
|
||||||
});
|
});
|
||||||
optionWidget.value = optionValue;
|
optionWidget.value = optionValue;
|
||||||
inputElement = this.findElement(rowContainer, 'input');
|
inputElement = this.findElement(rowContainer, 'input');
|
||||||
@@ -55,7 +56,8 @@ export function createOptionElement(option: sqlops.ServiceOption, rowContainer:
|
|||||||
optionWidget = new InputBox(rowContainer.getHTMLElement(), contextViewService, {
|
optionWidget = new InputBox(rowContainer.getHTMLElement(), contextViewService, {
|
||||||
validationOptions: {
|
validationOptions: {
|
||||||
validation: (value: string) => (!value && option.isRequired) ? ({ type: MessageType.ERROR, content: option.displayName + missingErrorMessage }) : null
|
validation: (value: string) => (!value && option.isRequired) ? ({ type: MessageType.ERROR, content: option.displayName + missingErrorMessage }) : null
|
||||||
}
|
},
|
||||||
|
ariaLabel: option.displayName
|
||||||
});
|
});
|
||||||
optionWidget.value = optionValue;
|
optionWidget.value = optionValue;
|
||||||
if (option.valueType === ServiceOptionType.password) {
|
if (option.valueType === ServiceOptionType.password) {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ let idPool = 0;
|
|||||||
|
|
||||||
<div class="tabbedPanel fullsize" #tabbedPanel>
|
<div class="tabbedPanel fullsize" #tabbedPanel>
|
||||||
<div *ngIf="!options.showTabsWhenOne ? _tabs.length !== 1 : true" class="composite title" #titleContainer>
|
<div *ngIf="!options.showTabsWhenOne ? _tabs.length !== 1 : true" class="composite title" #titleContainer>
|
||||||
<div class="tabList" #tabList>
|
<div class="tabList" #tabList role="tablist">
|
||||||
<div *ngFor="let tab of _tabs">
|
<div *ngFor="let tab of _tabs">
|
||||||
<tab-header [tab]="tab" [showIcon]="options.showIcon" (onSelectTab)='selectTab($event)' (onCloseTab)='closeTab($event)'> </tab-header>
|
<tab-header [tab]="tab" [showIcon]="options.showIcon" (onSelectTab)='selectTab($event)' (onCloseTab)='closeTab($event)'> </tab-header>
|
||||||
</div>
|
</div>
|
||||||
@@ -182,7 +182,7 @@ export class PanelComponent extends Disposable implements AfterContentInit, OnIn
|
|||||||
if (input instanceof TabComponent) {
|
if (input instanceof TabComponent) {
|
||||||
tab = input;
|
tab = input;
|
||||||
} else if (types.isNumber(input)) {
|
} else if (types.isNumber(input)) {
|
||||||
tab = this._tabs[input];
|
tab = this._tabs.toArray()[input];
|
||||||
} else if (types.isString(input)) {
|
} else if (types.isString(input)) {
|
||||||
tab = this._tabs.find(i => i.identifier === input);
|
tab = this._tabs.find(i => i.identifier === input);
|
||||||
}
|
}
|
||||||
@@ -226,6 +226,18 @@ export class PanelComponent extends Disposable implements AfterContentInit, OnIn
|
|||||||
return this._activeTab.identifier;
|
return this._activeTab.identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select on the next tab
|
||||||
|
*/
|
||||||
|
public selectOnNextTab(): void {
|
||||||
|
let activeIndex = this._tabs.toArray().findIndex(i => i === this._activeTab);
|
||||||
|
let nextTabIndex = activeIndex + 1;
|
||||||
|
if (nextTabIndex === this._tabs.length) {
|
||||||
|
nextTabIndex = 0;
|
||||||
|
}
|
||||||
|
this.selectTab(nextTabIndex);
|
||||||
|
}
|
||||||
|
|
||||||
private findAndRemoveTabFromMRU(tab: TabComponent): void {
|
private findAndRemoveTabFromMRU(tab: TabComponent): void {
|
||||||
let mruIndex = this._mru.findIndex(i => i === tab);
|
let mruIndex = this._mru.findIndex(i => i === tab);
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ export class TabbedPanel extends Disposable implements IThemable {
|
|||||||
this.$parent.appendTo(container);
|
this.$parent.appendTo(container);
|
||||||
this.$header = $('.composite.title');
|
this.$header = $('.composite.title');
|
||||||
this.$tabList = $('.tabList');
|
this.$tabList = $('.tabList');
|
||||||
|
this.$tabList.attr('role', 'tablist');
|
||||||
this.$tabList.style('height', this.headersize + 'px');
|
this.$tabList.style('height', this.headersize + 'px');
|
||||||
this.$header.append(this.$tabList);
|
this.$header.append(this.$tabList);
|
||||||
let actionbarcontainer = $('.title-actions');
|
let actionbarcontainer = $('.title-actions');
|
||||||
@@ -89,6 +90,9 @@ export class TabbedPanel extends Disposable implements IThemable {
|
|||||||
private _createTab(tab: IInternalPanelTab): void {
|
private _createTab(tab: IInternalPanelTab): void {
|
||||||
let tabHeaderElement = $('.tab-header');
|
let tabHeaderElement = $('.tab-header');
|
||||||
tabHeaderElement.attr('tabindex', '0');
|
tabHeaderElement.attr('tabindex', '0');
|
||||||
|
tabHeaderElement.attr('role', 'tab');
|
||||||
|
tabHeaderElement.attr('aria-selected', 'false');
|
||||||
|
tabHeaderElement.attr('aria-label', tab.title);
|
||||||
let tabElement = $('.tab');
|
let tabElement = $('.tab');
|
||||||
tabHeaderElement.append(tabElement);
|
tabHeaderElement.append(tabElement);
|
||||||
let tabLabel = $('a.tabLabel');
|
let tabLabel = $('a.tabLabel');
|
||||||
@@ -114,7 +118,7 @@ export class TabbedPanel extends Disposable implements IThemable {
|
|||||||
|
|
||||||
if (this._shownTab) {
|
if (this._shownTab) {
|
||||||
this._tabMap.get(this._shownTab).label.removeClass('active');
|
this._tabMap.get(this._shownTab).label.removeClass('active');
|
||||||
this._tabMap.get(this._shownTab).header.removeClass('active');
|
this._tabMap.get(this._shownTab).header.removeClass('active').attr('aria-selected', 'false');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._shownTab = id;
|
this._shownTab = id;
|
||||||
@@ -122,6 +126,7 @@ export class TabbedPanel extends Disposable implements IThemable {
|
|||||||
let tab = this._tabMap.get(this._shownTab);
|
let tab = this._tabMap.get(this._shownTab);
|
||||||
tab.label.addClass('active');
|
tab.label.addClass('active');
|
||||||
tab.header.addClass('active');
|
tab.header.addClass('active');
|
||||||
|
tab.header.attr('aria-selected', 'true');
|
||||||
tab.view.render(this.$body.getHTMLElement());
|
tab.view.render(this.$body.getHTMLElement());
|
||||||
this._onTabChange.fire(id);
|
this._onTabChange.fire(id);
|
||||||
if (this._currentDimensions) {
|
if (this._currentDimensions) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { CloseTabAction } from './tabActions';
|
|||||||
selector: 'tab-header',
|
selector: 'tab-header',
|
||||||
template: `
|
template: `
|
||||||
<div #actionHeader class="tab-header" style="flex: 0 0; flex-direction: row;" [class.active]="tab.active" tabindex="0" (keyup)="onKey($event)">
|
<div #actionHeader class="tab-header" style="flex: 0 0; flex-direction: row;" [class.active]="tab.active" tabindex="0" (keyup)="onKey($event)">
|
||||||
<span class="tab" (click)="selectTab(tab)">
|
<span class="tab" (click)="selectTab(tab)" role="tab" [attr.aria-selected]="tab.active" [attr.aria-label]="tab.title">
|
||||||
<a class="tabLabel" [class.active]="tab.active" #tabLabel>
|
<a class="tabLabel" [class.active]="tab.active" #tabLabel>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export class RowDetailView {
|
|||||||
this._options = mixin(options, this._defaults, false);
|
this._options = mixin(options, this._defaults, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(grid: any) {
|
public init(grid: any): void {
|
||||||
this._grid = grid;
|
this._grid = grid;
|
||||||
this._dataView = this._grid.getData();
|
this._dataView = this._grid.getData();
|
||||||
|
|
||||||
@@ -61,17 +61,17 @@ export class RowDetailView {
|
|||||||
this._options = $.extend(true, {}, this._options, options);
|
this._options = $.extend(true, {}, this._options, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public handleClick(e: any, args: any) {
|
public handleClick(e: any, args: any): void {
|
||||||
// clicking on a row select checkbox
|
// clicking on a row select checkbox
|
||||||
if (this._options.useRowClick || this._grid.getColumns()[args.cell].id === this._options.columnId && $(e.target).hasClass("detailView-toggle")) {
|
if (this._options.useRowClick || this._grid.getColumns()[args.cell].id === this._options.columnId && $(e.target).hasClass('detailView-toggle')) {
|
||||||
// if editing, try to commit
|
// if editing, try to commit
|
||||||
if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {
|
if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopImmediatePropagation();
|
e.stopImmediatePropagation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = this._dataView.getItem(args.row);
|
let item = this._dataView.getItem(args.row);
|
||||||
|
|
||||||
// trigger an event before toggling
|
// trigger an event before toggling
|
||||||
this.onBeforeRowDetailToggle.notify({
|
this.onBeforeRowDetailToggle.notify({
|
||||||
@@ -100,36 +100,35 @@ export class RowDetailView {
|
|||||||
// If we scroll save detail views that go out of cache range
|
// If we scroll save detail views that go out of cache range
|
||||||
public handleScroll(e, args) {
|
public handleScroll(e, args) {
|
||||||
|
|
||||||
var range = this._grid.getRenderedRange();
|
let range = this._grid.getRenderedRange();
|
||||||
|
|
||||||
var start = (range.top > 0 ? range.top : 0);
|
let start: number = (range.top > 0 ? range.top : 0);
|
||||||
var end = (range.bottom > this._dataView.getLength() ? range.bottom : this._dataView.getLength());
|
let end: number = (range.bottom > this._dataView.getLength() ? range.bottom : this._dataView.getLength());
|
||||||
|
if (end <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the item at the top of the view
|
// Get the item at the top of the view
|
||||||
var topMostItem = this._dataView.getItemByIdx(start);
|
let topMostItem = this._dataView.getItemByIdx(start);
|
||||||
|
|
||||||
// Check it is a parent item
|
// Check it is a parent item
|
||||||
if (topMostItem._parent === undefined)
|
if (topMostItem._parent === undefined) {
|
||||||
{
|
|
||||||
// This is a standard row as we have no parent.
|
// This is a standard row as we have no parent.
|
||||||
var nextItem = this._dataView.getItemByIdx(start + 1);
|
let nextItem = this._dataView.getItemByIdx(start + 1);
|
||||||
if(nextItem !== undefined && nextItem._parent !== undefined)
|
if (nextItem !== undefined && nextItem._parent !== undefined) {
|
||||||
{
|
|
||||||
// This is likely the expanded Detail Row View
|
// This is likely the expanded Detail Row View
|
||||||
// Check for safety
|
// Check for safety
|
||||||
if(nextItem._parent === topMostItem)
|
if (nextItem._parent === topMostItem) {
|
||||||
{
|
|
||||||
this.saveDetailView(topMostItem);
|
this.saveDetailView(topMostItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the bottom most item that is likely to go off screen
|
// Find the bottom most item that is likely to go off screen
|
||||||
var bottomMostItem = this._dataView.getItemByIdx(end - 1);
|
let bottomMostItem = this._dataView.getItemByIdx(end - 1);
|
||||||
|
|
||||||
// If we are a detailView and we are about to go out of cache view
|
// If we are a detailView and we are about to go out of cache view
|
||||||
if(bottomMostItem._parent !== undefined)
|
if (bottomMostItem._parent !== undefined) {
|
||||||
{
|
|
||||||
this.saveDetailView(bottomMostItem._parent);
|
this.saveDetailView(bottomMostItem._parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,17 +142,17 @@ export class RowDetailView {
|
|||||||
|
|
||||||
// Collapse all of the open items
|
// Collapse all of the open items
|
||||||
public collapseAll() {
|
public collapseAll() {
|
||||||
for (var i = this._expandedRows.length - 1; i >= 0; i--) {
|
for (let i = this._expandedRows.length - 1; i >= 0; i--) {
|
||||||
this.collapseItem(this._expandedRows[i]);
|
this.collapseItem(this._expandedRows[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saves the current state of the detail view
|
// Saves the current state of the detail view
|
||||||
public saveDetailView(item) {
|
public saveDetailView(item) {
|
||||||
var view = $('#innerDetailView_' + item.id);
|
let view = $('#innerDetailView_' + item.id);
|
||||||
if (view) {
|
if (view) {
|
||||||
var html = $('#innerDetailView_' + item.id).html();
|
let html = $('#innerDetailView_' + item.id).html();
|
||||||
if(html !== undefined) {
|
if (html !== undefined) {
|
||||||
item._detailContent = html;
|
item._detailContent = html;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,7 +229,7 @@ export class RowDetailView {
|
|||||||
|
|
||||||
args.itemDetail._detailViewLoaded = true;
|
args.itemDetail._detailViewLoaded = true;
|
||||||
|
|
||||||
var idxParent = this._dataView.getIdxById(args.itemDetail.id);
|
let idxParent = this._dataView.getIdxById(args.itemDetail.id);
|
||||||
this._dataView.updateItem(args.itemDetail.id, args.itemDetail);
|
this._dataView.updateItem(args.itemDetail.id, args.itemDetail);
|
||||||
|
|
||||||
// trigger an event once the post template is finished loading
|
// trigger an event once the post template is finished loading
|
||||||
@@ -254,7 +253,7 @@ export class RowDetailView {
|
|||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
public getPaddingItem(parent, offset) {
|
public getPaddingItem(parent, offset) {
|
||||||
var item: any = {};
|
let item: any = {};
|
||||||
|
|
||||||
for (let prop in this._grid.getData()) {
|
for (let prop in this._grid.getData()) {
|
||||||
item[prop] = null;
|
item[prop] = null;
|
||||||
@@ -270,10 +269,22 @@ export class RowDetailView {
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getErrorItem(parent, offset) {
|
||||||
|
let item: any = {};
|
||||||
|
item.id = parent.id + '.' + offset;
|
||||||
|
item._collapsed = true;
|
||||||
|
item._isPadding = false;
|
||||||
|
item._parent = parent;
|
||||||
|
item._offset = offset;
|
||||||
|
item.jobId = parent.jobId;
|
||||||
|
item.name = parent.message ? parent.message : 'Error';
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
//create the detail ctr node. this belongs to the dev & can be custom-styled as per
|
//create the detail ctr node. this belongs to the dev & can be custom-styled as per
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
public applyTemplateNewLineHeight(item) {
|
public applyTemplateNewLineHeight(item, showError = false) {
|
||||||
// the height seems to be calculated by the template row count (how many line of items does the template have)
|
// the height seems to be calculated by the template row count (how many line of items does the template have)
|
||||||
let rowCount = this._options.panelRows;
|
let rowCount = this._options.panelRows;
|
||||||
|
|
||||||
@@ -284,12 +295,15 @@ export class RowDetailView {
|
|||||||
item._height = (item._sizePadding * this._grid.getOptions().rowHeight);
|
item._height = (item._sizePadding * this._grid.getOptions().rowHeight);
|
||||||
|
|
||||||
let idxParent = this._dataView.getIdxById(item.id);
|
let idxParent = this._dataView.getIdxById(item.id);
|
||||||
for (var idx = 1; idx <= item._sizePadding; idx++) {
|
for (let idx = 1; idx <= item._sizePadding; idx++) {
|
||||||
this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));
|
if (showError) {
|
||||||
|
this._dataView.insertItem(idxParent + idx, this.getErrorItem(item, 'error'));
|
||||||
|
} else {
|
||||||
|
this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public getColumnDefinition() {
|
public getColumnDefinition() {
|
||||||
return {
|
return {
|
||||||
id: this._options.columnId,
|
id: this._options.columnId,
|
||||||
@@ -307,12 +321,12 @@ export class RowDetailView {
|
|||||||
public detailSelectionFormatter(row, cell, value, columnDef, dataContext) {
|
public detailSelectionFormatter(row, cell, value, columnDef, dataContext) {
|
||||||
|
|
||||||
if (dataContext._collapsed === undefined) {
|
if (dataContext._collapsed === undefined) {
|
||||||
dataContext._collapsed = true,
|
dataContext._collapsed = true;
|
||||||
dataContext._sizePadding = 0, //the required number of pading rows
|
dataContext._sizePadding = 0; //the required number of pading rows
|
||||||
dataContext._height = 0, //the actual height in pixels of the detail field
|
dataContext._height = 0; //the actual height in pixels of the detail field
|
||||||
dataContext._isPadding = false,
|
dataContext._isPadding = false;
|
||||||
dataContext._parent = undefined,
|
dataContext._parent = undefined;
|
||||||
dataContext._offset = 0
|
dataContext._offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataContext._isPadding === true) {
|
if (dataContext._isPadding === true) {
|
||||||
@@ -320,9 +334,9 @@ export class RowDetailView {
|
|||||||
} else if (dataContext._collapsed) {
|
} else if (dataContext._collapsed) {
|
||||||
return '<div class=\'detailView-toggle expand\'></div>';
|
return '<div class=\'detailView-toggle expand\'></div>';
|
||||||
} else {
|
} else {
|
||||||
var html = [];
|
let html = [];
|
||||||
var rowHeight = this._grid.getOptions().rowHeight;
|
let rowHeight = this._grid.getOptions().rowHeight;
|
||||||
var bottomMargin = 5;
|
let bottomMargin = 5;
|
||||||
|
|
||||||
//V313HAX:
|
//V313HAX:
|
||||||
//putting in an extra closing div after the closing toggle div and ommiting a
|
//putting in an extra closing div after the closing toggle div and ommiting a
|
||||||
@@ -339,7 +353,7 @@ export class RowDetailView {
|
|||||||
html.push("style='height:", dataContext._height, "px;"); //set total height of padding
|
html.push("style='height:", dataContext._height, "px;"); //set total height of padding
|
||||||
html.push("top:", rowHeight, "px'>"); //shift detail below 1st row
|
html.push("top:", rowHeight, "px'>"); //shift detail below 1st row
|
||||||
html.push("<div id='detailViewContainer_", dataContext.id, "' class='detail-container' style='max-height:" + (dataContext._height - rowHeight + bottomMargin) + "px'>"); //sub ctr for custom styling
|
html.push("<div id='detailViewContainer_", dataContext.id, "' class='detail-container' style='max-height:" + (dataContext._height - rowHeight + bottomMargin) + "px'>"); //sub ctr for custom styling
|
||||||
html.push("<div id='innerDetailView_" , dataContext.id , "'>" , dataContext._detailContent, "</div></div>");
|
html.push("<div id='innerDetailView_", dataContext.id, "'>", dataContext._detailContent, "</div></div>");
|
||||||
//&omit a final closing detail container </div> that would come next
|
//&omit a final closing detail container </div> that would come next
|
||||||
|
|
||||||
return html.join('');
|
return html.join('');
|
||||||
@@ -351,33 +365,32 @@ export class RowDetailView {
|
|||||||
if (!item) return;
|
if (!item) return;
|
||||||
|
|
||||||
// Grad each of the dom items
|
// Grad each of the dom items
|
||||||
var mainContainer = document.getElementById('detailViewContainer_' + item.id);
|
let mainContainer = document.getElementById('detailViewContainer_' + item.id);
|
||||||
var cellItem = document.getElementById('cellDetailView_' + item.id);
|
let cellItem = document.getElementById('cellDetailView_' + item.id);
|
||||||
var inner = document.getElementById('innerDetailView_' + item.id);
|
let inner = document.getElementById('innerDetailView_' + item.id);
|
||||||
|
|
||||||
if (!mainContainer || !cellItem || !inner) return;
|
if (!mainContainer || !cellItem || !inner) return;
|
||||||
|
|
||||||
for (var idx = 1; idx <= item._sizePadding; idx++) {
|
for (let idx = 1; idx <= item._sizePadding; idx++) {
|
||||||
this._dataView.deleteItem(item.id + "." + idx);
|
this._dataView.deleteItem(item.id + "." + idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
var rowHeight = this._grid.getOptions().rowHeight; // height of a row
|
let rowHeight = this._grid.getOptions().rowHeight; // height of a row
|
||||||
var lineHeight = 13; //we know cuz we wrote the custom css innit ;)
|
let lineHeight = 13; //we know cuz we wrote the custom css innit ;)
|
||||||
|
|
||||||
// Get the inner Item height as this will be the actual size
|
// Get the inner Item height as this will be the actual size
|
||||||
var itemHeight = inner.clientHeight;
|
let itemHeight = inner.clientHeight;
|
||||||
|
|
||||||
// Now work out how many rows
|
// Now work out how many rows
|
||||||
var rowCount = Math.ceil(itemHeight / rowHeight) + 1;
|
let rowCount = Math.ceil(itemHeight / rowHeight) + 1;
|
||||||
|
|
||||||
item._sizePadding = Math.ceil(((rowCount * 2) * lineHeight) / rowHeight);
|
item._sizePadding = Math.ceil(((rowCount * 2) * lineHeight) / rowHeight);
|
||||||
item._height = (item._sizePadding * rowHeight);
|
item._height = (item._sizePadding * rowHeight);
|
||||||
|
|
||||||
// If the padding is now more than the original minRowBuff we need to increase it
|
// If the padding is now more than the original minRowBuff we need to increase it
|
||||||
if (this._grid.getOptions().minRowBuffer < item._sizePadding)
|
if (this._grid.getOptions().minRowBuffer < item._sizePadding) {
|
||||||
{
|
|
||||||
// Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3
|
// Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3
|
||||||
this._grid.getOptions().minRowBuffer =item._sizePadding + 3;
|
this._grid.getOptions().minRowBuffer = item._sizePadding + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
mainContainer.setAttribute("style", "max-height: " + item._height + "px");
|
mainContainer.setAttribute("style", "max-height: " + item._height + "px");
|
||||||
@@ -386,7 +399,7 @@ export class RowDetailView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let idxParent = this._dataView.getIdxById(item.id);
|
let idxParent = this._dataView.getIdxById(item.id);
|
||||||
for (var idx = 1; idx <= item._sizePadding; idx++) {
|
for (let idx = 1; idx <= item._sizePadding; idx++) {
|
||||||
this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));
|
this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { mixin } from 'vs/base/common/objects';
|
|||||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { Dimension } from 'vs/base/browser/builder';
|
import { Dimension } from 'vs/base/browser/builder';
|
||||||
import { Orientation } from 'vs/base/browser/ui/splitview/splitview';
|
import { Orientation } from 'vs/base/browser/ui/splitview/splitview';
|
||||||
|
import { Widget } from 'vs/base/browser/ui/widget';
|
||||||
|
|
||||||
export interface ITableStyles extends IListStyles {
|
export interface ITableStyles extends IListStyles {
|
||||||
tableHeaderBackground?: Color;
|
tableHeaderBackground?: Color;
|
||||||
@@ -27,18 +28,22 @@ function getDefaultOptions<T>(): Slick.GridOptions<T> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Table<T extends Slick.SlickData> implements IThemable {
|
export class Table<T extends Slick.SlickData> extends Widget implements IThemable {
|
||||||
|
private styleElement: HTMLStyleElement;
|
||||||
|
private idPrefix: string;
|
||||||
|
|
||||||
private _grid: Slick.Grid<T>;
|
private _grid: Slick.Grid<T>;
|
||||||
private _columns: Slick.Column<T>[];
|
private _columns: Slick.Column<T>[];
|
||||||
private _data: TableDataView<T>;
|
private _data: TableDataView<T>;
|
||||||
private _styleElement: HTMLStyleElement;
|
|
||||||
private _idPrefix: string;
|
|
||||||
private _autoscroll: boolean;
|
private _autoscroll: boolean;
|
||||||
private _onRowCountChangeListener: IDisposable;
|
private _onRowCountChangeListener: IDisposable;
|
||||||
private _container: HTMLElement;
|
private _container: HTMLElement;
|
||||||
private _tableContainer: HTMLElement;
|
private _tableContainer: HTMLElement;
|
||||||
|
|
||||||
|
private _classChangeTimeout: number;
|
||||||
|
|
||||||
constructor(parent: HTMLElement, data?: Array<T> | TableDataView<T>, columns?: Slick.Column<T>[], options?: Slick.GridOptions<T>) {
|
constructor(parent: HTMLElement, data?: Array<T> | TableDataView<T>, columns?: Slick.Column<T>[], options?: Slick.GridOptions<T>) {
|
||||||
|
super();
|
||||||
if (data instanceof TableDataView) {
|
if (data instanceof TableDataView) {
|
||||||
this._data = data;
|
this._data = data;
|
||||||
} else {
|
} else {
|
||||||
@@ -55,13 +60,28 @@ export class Table<T extends Slick.SlickData> implements IThemable {
|
|||||||
|
|
||||||
this._container = document.createElement('div');
|
this._container = document.createElement('div');
|
||||||
this._container.className = 'monaco-table';
|
this._container.className = 'monaco-table';
|
||||||
|
this._register(DOM.addDisposableListener(this._container, DOM.EventType.FOCUS, () => {
|
||||||
|
clearTimeout(this._classChangeTimeout);
|
||||||
|
this._classChangeTimeout = setTimeout(() => {
|
||||||
|
DOM.addClass(this._container, 'focused');
|
||||||
|
}, 100);
|
||||||
|
}, true));
|
||||||
|
|
||||||
|
this._register(DOM.addDisposableListener(this._container, DOM.EventType.BLUR, () => {
|
||||||
|
clearTimeout(this._classChangeTimeout);
|
||||||
|
this._classChangeTimeout = setTimeout(() => {
|
||||||
|
DOM.removeClass(this._container, 'focused');
|
||||||
|
}, 100);
|
||||||
|
}, true));
|
||||||
|
|
||||||
parent.appendChild(this._container);
|
parent.appendChild(this._container);
|
||||||
this._styleElement = DOM.createStyleSheet(this._container);
|
this.styleElement = DOM.createStyleSheet(this._container);
|
||||||
this._tableContainer = document.createElement('div');
|
this._tableContainer = document.createElement('div');
|
||||||
this._container.appendChild(this._tableContainer);
|
this._container.appendChild(this._tableContainer);
|
||||||
this._styleElement = DOM.createStyleSheet(this._container);
|
this.styleElement = DOM.createStyleSheet(this._container);
|
||||||
this._grid = new Slick.Grid<T>(this._tableContainer, this._data, this._columns, newOptions);
|
this._grid = new Slick.Grid<T>(this._tableContainer, this._data, this._columns, newOptions);
|
||||||
this._idPrefix = this._tableContainer.classList[0];
|
this.idPrefix = this._tableContainer.classList[0];
|
||||||
|
DOM.addClass(this._container, this.idPrefix);
|
||||||
this._onRowCountChangeListener = this._data.onRowCountChange(() => this._handleRowCountChange());
|
this._onRowCountChangeListener = this._data.onRowCountChange(() => this._handleRowCountChange());
|
||||||
this._grid.onSort.subscribe((e, args) => {
|
this._grid.onSort.subscribe((e, args) => {
|
||||||
this._data.sort(args);
|
this._data.sort(args);
|
||||||
@@ -200,78 +220,77 @@ export class Table<T extends Slick.SlickData> implements IThemable {
|
|||||||
const content: string[] = [];
|
const content: string[] = [];
|
||||||
|
|
||||||
if (styles.tableHeaderBackground) {
|
if (styles.tableHeaderBackground) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-header .slick-header-column { background-color: ${styles.tableHeaderBackground}; }`);
|
content.push(`.monaco-table .${this.idPrefix} .slick-header .slick-header-column { background-color: ${styles.tableHeaderBackground}; }`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styles.tableHeaderForeground) {
|
if (styles.tableHeaderForeground) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-header .slick-header-column { color: ${styles.tableHeaderForeground}; }`);
|
content.push(`.monaco-table .${this.idPrefix} .slick-header .slick-header-column { color: ${styles.tableHeaderForeground}; }`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styles.listFocusBackground) {
|
if (styles.listFocusBackground) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-row .active { background-color: ${styles.listFocusBackground}; }`);
|
content.push(`.monaco-table.${this.idPrefix}.focused .slick-row .active { background-color: ${styles.listFocusBackground}; }`);
|
||||||
|
content.push(`.monaco-table.${this.idPrefix}.focused .slick-row .active:hover { background-color: ${styles.listFocusBackground}; }`); // overwrite :hover style in this case!
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styles.listFocusForeground) {
|
if (styles.listFocusForeground) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-row .active { color: ${styles.listFocusForeground}; }`);
|
content.push(`.monaco-table.${this.idPrefix}.focused .slick-row .active { color: ${styles.listFocusForeground}; }`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styles.listActiveSelectionBackground) {
|
if (styles.listActiveSelectionBackground) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-row .selected { background-color: ${styles.listActiveSelectionBackground}; }`);
|
content.push(`.monaco-table.${this.idPrefix}.focused .slick-row .selected { background-color: ${styles.listActiveSelectionBackground}; }`);
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-row .selected:hover { background-color: ${styles.listActiveSelectionBackground}; }`); // overwrite :hover style in this case!
|
content.push(`.monaco-table.${this.idPrefix}.focused .slick-row .selected:hover { background-color: ${styles.listActiveSelectionBackground}; }`); // overwrite :hover style in this case!
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styles.listActiveSelectionForeground) {
|
if (styles.listActiveSelectionForeground) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-row .selected { color: ${styles.listActiveSelectionForeground}; }`);
|
content.push(`.monaco-table.${this.idPrefix}.focused .slick-row .selected { color: ${styles.listActiveSelectionForeground}; }`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styles.listFocusAndSelectionBackground) {
|
if (styles.listFocusAndSelectionBackground) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-row .selected.active { background-color: ${styles.listFocusAndSelectionBackground}; }`);
|
content.push(`.monaco-table.${this.idPrefix}.focused .slick-row .selected.active { background-color: ${styles.listFocusAndSelectionBackground}; }`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styles.listFocusAndSelectionForeground) {
|
if (styles.listFocusAndSelectionForeground) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-row .selected.active { color: ${styles.listFocusAndSelectionForeground}; }`);
|
content.push(`.monaco-table.${this.idPrefix}.focused .slick-row .selected.active { color: ${styles.listFocusAndSelectionForeground}; }`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Commented out andresse 8/17/2017; keeping for reference as we iterate on the table styling */
|
if (styles.listInactiveFocusBackground) {
|
||||||
// if (styles.listInactiveFocusBackground) {
|
content.push(`.monaco-table.${this.idPrefix} .slick-row .selected.active { background-color: ${styles.listInactiveFocusBackground}; }`);
|
||||||
// content.push(`.monaco-table .${this._idPrefix} .slick-row.focused { background-color: ${styles.listInactiveFocusBackground}; }`);
|
content.push(`.monaco-table.${this.idPrefix} .slick-row .selected.active:hover { background-color: ${styles.listInactiveFocusBackground}; }`); // overwrite :hover style in this case!
|
||||||
// content.push(`.monaco-table .${this._idPrefix} .slick-row.focused:hover { background-color: ${styles.listInactiveFocusBackground}; }`); // overwrite :hover style in this case!
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// if (styles.listInactiveSelectionBackground) {
|
if (styles.listInactiveSelectionBackground) {
|
||||||
// content.push(`.monaco-table .${this._idPrefix} .slick-row .selected { background-color: ${styles.listInactiveSelectionBackground}; }`);
|
content.push(`.monaco-table.${this.idPrefix} .slick-row .selected { background-color: ${styles.listInactiveSelectionBackground}; }`);
|
||||||
// content.push(`.monaco-table .${this._idPrefix} .slick-row .selected:hover { background-color: ${styles.listInactiveSelectionBackground}; }`); // overwrite :hover style in this case!
|
content.push(`.monaco-table.${this.idPrefix} .slick-row .selected:hover { background-color: ${styles.listInactiveSelectionBackground}; }`); // overwrite :hover style in this case!
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if (styles.listInactiveSelectionForeground) {
|
if (styles.listInactiveSelectionForeground) {
|
||||||
// content.push(`.monaco-table .${this._idPrefix} .slick-row .selected { color: ${styles.listInactiveSelectionForeground}; }`);
|
content.push(`.monaco-table.${this.idPrefix} .slick-row .selected { color: ${styles.listInactiveSelectionForeground}; }`);
|
||||||
// }
|
}
|
||||||
|
|
||||||
if (styles.listHoverBackground) {
|
if (styles.listHoverBackground) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-row:hover { background-color: ${styles.listHoverBackground}; }`);
|
content.push(`.monaco-table.${this.idPrefix} .slick-row:hover { background-color: ${styles.listHoverBackground}; }`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styles.listHoverForeground) {
|
if (styles.listHoverForeground) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-row:hover { color: ${styles.listHoverForeground}; }`);
|
content.push(`.monaco-table.${this.idPrefix} .slick-row:hover { color: ${styles.listHoverForeground}; }`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styles.listSelectionOutline) {
|
if (styles.listSelectionOutline) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-row .selected.active { outline: 1px dotted ${styles.listSelectionOutline}; outline-offset: -1px; }`);
|
content.push(`.monaco-table.${this.idPrefix} .slick-row .selected.active { outline: 1px dotted ${styles.listSelectionOutline}; outline-offset: -1px; }`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Commented out andresse 8/17/2017; keeping for reference as we iterate on the table styling */
|
if (styles.listFocusOutline) {
|
||||||
// if (styles.listFocusOutline) {
|
content.push(`.monaco-table.${this.idPrefix}.focused .slick-row .selected { outline: 1px solid ${styles.listFocusOutline}; outline-offset: -1px; }`);
|
||||||
// content.push(`.monaco-table .${this._idPrefix}:focus .slick-row.focused { outline: 1px solid ${styles.listFocusOutline}; outline-offset: -1px; }`);
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// if (styles.listInactiveFocusOutline) {
|
if (styles.listInactiveFocusOutline) {
|
||||||
// content.push(`.monaco-table .${this._idPrefix} .slick-row.focused { outline: 1px dotted ${styles.listInactiveFocusOutline}; outline-offset: -1px; }`);
|
content.push(`.monaco-table.${this.idPrefix} .slick-row .selected .active { outline: 1px dotted ${styles.listInactiveFocusOutline}; outline-offset: -1px; }`);
|
||||||
// }
|
}
|
||||||
|
|
||||||
if (styles.listHoverOutline) {
|
if (styles.listHoverOutline) {
|
||||||
content.push(`.monaco-table .${this._idPrefix} .slick-row:hover { outline: 1px dashed ${styles.listHoverOutline}; outline-offset: -1px; }`);
|
content.push(`.monaco-table.${this.idPrefix} .slick-row:hover { outline: 1px dashed ${styles.listHoverOutline}; outline-offset: -1px; }`);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._styleElement.innerHTML = content.join('\n');
|
this.styleElement.innerHTML = content.join('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,12 +153,18 @@ export class ActionBar extends ActionRunner implements IActionRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateFocusedItem(): void {
|
private updateFocusedItem(): void {
|
||||||
|
let actionIndex = 0;
|
||||||
for (let i = 0; i < this._actionsList.children.length; i++) {
|
for (let i = 0; i < this._actionsList.children.length; i++) {
|
||||||
let elem = this._actionsList.children[i];
|
let elem = this._actionsList.children[i];
|
||||||
|
|
||||||
if (DOM.isAncestor(document.activeElement, elem)) {
|
if (DOM.isAncestor(document.activeElement, elem)) {
|
||||||
this._focusedItem = i;
|
this._focusedItem = actionIndex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (elem.classList.contains('action-item')) {
|
||||||
|
actionIndex++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,9 @@ export class AutoOAuthDialog extends Modal {
|
|||||||
});
|
});
|
||||||
|
|
||||||
inputContainer.div({ class: 'dialog-input' }, (inputCellContainer) => {
|
inputContainer.div({ class: 'dialog-input' }, (inputCellContainer) => {
|
||||||
inputBox = new InputBox(inputCellContainer.getHTMLElement(), this._contextViewService);
|
inputBox = new InputBox(inputCellContainer.getHTMLElement(), this._contextViewService, {
|
||||||
|
ariaLabel: label
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return inputBox;
|
return inputBox;
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
|||||||
// in case that other non-Azure sign in is to be used
|
// in case that other non-Azure sign in is to be used
|
||||||
const firewallHelpUri = 'https://aka.ms/sqlopsfirewallhelp';
|
const firewallHelpUri = 'https://aka.ms/sqlopsfirewallhelp';
|
||||||
|
|
||||||
|
const LocalizedStrings = {
|
||||||
|
FROM: localize('from', 'From'),
|
||||||
|
TO: localize('to', 'To')
|
||||||
|
};
|
||||||
|
|
||||||
export class FirewallRuleDialog extends Modal {
|
export class FirewallRuleDialog extends Modal {
|
||||||
public viewModel: FirewallRuleViewModel;
|
public viewModel: FirewallRuleViewModel;
|
||||||
private _createButton: Button;
|
private _createButton: Button;
|
||||||
@@ -140,19 +145,23 @@ export class FirewallRuleDialog extends Modal {
|
|||||||
subnetIPRangeSection = subnetIPRangeContainer.getHTMLElement();
|
subnetIPRangeSection = subnetIPRangeContainer.getHTMLElement();
|
||||||
subnetIPRangeContainer.div({ 'class': 'dialog-input-section' }, (inputContainer) => {
|
subnetIPRangeContainer.div({ 'class': 'dialog-input-section' }, (inputContainer) => {
|
||||||
inputContainer.div({ 'class': 'dialog-label' }, (labelContainer) => {
|
inputContainer.div({ 'class': 'dialog-label' }, (labelContainer) => {
|
||||||
labelContainer.innerHtml(localize('from', 'From'));
|
labelContainer.innerHtml(LocalizedStrings.FROM);
|
||||||
});
|
});
|
||||||
|
|
||||||
inputContainer.div({ 'class': 'dialog-input' }, (inputCellContainer) => {
|
inputContainer.div({ 'class': 'dialog-input' }, (inputCellContainer) => {
|
||||||
this._fromRangeinputBox = new InputBox(inputCellContainer.getHTMLElement(), this._contextViewService);
|
this._fromRangeinputBox = new InputBox(inputCellContainer.getHTMLElement(), this._contextViewService, {
|
||||||
|
ariaLabel: LocalizedStrings.FROM
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
inputContainer.div({ 'class': 'dialog-label' }, (labelContainer) => {
|
inputContainer.div({ 'class': 'dialog-label' }, (labelContainer) => {
|
||||||
labelContainer.innerHtml(localize('to', 'To'));
|
labelContainer.innerHtml(LocalizedStrings.TO);
|
||||||
});
|
});
|
||||||
|
|
||||||
inputContainer.div({ 'class': 'dialog-input' }, (inputCellContainer) => {
|
inputContainer.div({ 'class': 'dialog-input' }, (inputCellContainer) => {
|
||||||
this._toRangeinputBox = new InputBox(inputCellContainer.getHTMLElement(), this._contextViewService);
|
this._toRangeinputBox = new InputBox(inputCellContainer.getHTMLElement(), this._contextViewService, {
|
||||||
|
ariaLabel: LocalizedStrings.TO
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ export class ConnectionWidget {
|
|||||||
validationOptions: {
|
validationOptions: {
|
||||||
validation: (value: string) => !value ? ({ type: MessageType.ERROR, content: serverNameOption.displayName + errorMessage }) : null
|
validation: (value: string) => !value ? ({ type: MessageType.ERROR, content: serverNameOption.displayName + errorMessage }) : null
|
||||||
},
|
},
|
||||||
|
ariaLabel: serverNameOption.displayName
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this._optionsMaps[ConnectionOptionSpecialType.authType]) {
|
if (this._optionsMaps[ConnectionOptionSpecialType.authType]) {
|
||||||
@@ -141,12 +142,13 @@ export class ConnectionWidget {
|
|||||||
this._userNameInputBox = new InputBox(userNameBuilder.getHTMLElement(), this._contextViewService, {
|
this._userNameInputBox = new InputBox(userNameBuilder.getHTMLElement(), this._contextViewService, {
|
||||||
validationOptions: {
|
validationOptions: {
|
||||||
validation: (value: string) => self.validateUsername(value, userNameOption.isRequired) ? ({ type: MessageType.ERROR, content: userNameOption.displayName + errorMessage }) : null
|
validation: (value: string) => self.validateUsername(value, userNameOption.isRequired) ? ({ type: MessageType.ERROR, content: userNameOption.displayName + errorMessage }) : null
|
||||||
}
|
},
|
||||||
|
ariaLabel: userNameOption.displayName
|
||||||
});
|
});
|
||||||
|
|
||||||
let passwordOption = this._optionsMaps[ConnectionOptionSpecialType.password];
|
let passwordOption = this._optionsMaps[ConnectionOptionSpecialType.password];
|
||||||
let passwordBuilder = DialogHelper.appendRow(this._tableContainer, passwordOption.displayName, 'connection-label', 'connection-input');
|
let passwordBuilder = DialogHelper.appendRow(this._tableContainer, passwordOption.displayName, 'connection-label', 'connection-input');
|
||||||
this._passwordInputBox = new InputBox(passwordBuilder.getHTMLElement(), this._contextViewService);
|
this._passwordInputBox = new InputBox(passwordBuilder.getHTMLElement(), this._contextViewService, { ariaLabel: passwordOption.displayName });
|
||||||
this._passwordInputBox.inputElement.type = 'password';
|
this._passwordInputBox.inputElement.type = 'password';
|
||||||
this._password = '';
|
this._password = '';
|
||||||
|
|
||||||
@@ -158,9 +160,10 @@ export class ConnectionWidget {
|
|||||||
|
|
||||||
this._databaseNameInputBox = new Dropdown(databaseNameBuilder.getHTMLElement(), this._contextViewService, this._themeService, {
|
this._databaseNameInputBox = new Dropdown(databaseNameBuilder.getHTMLElement(), this._contextViewService, this._themeService, {
|
||||||
values: [this._defaultDatabaseName, this._loadingDatabaseName],
|
values: [this._defaultDatabaseName, this._loadingDatabaseName],
|
||||||
strictSelection : false,
|
strictSelection: false,
|
||||||
placeholder: this._defaultDatabaseName,
|
placeholder: this._defaultDatabaseName,
|
||||||
maxHeight: 125
|
maxHeight: 125,
|
||||||
|
ariaLabel: databaseOption.displayName
|
||||||
});
|
});
|
||||||
|
|
||||||
let serverGroupLabel = localize('serverGroup', 'Server group');
|
let serverGroupLabel = localize('serverGroup', 'Server group');
|
||||||
@@ -204,7 +207,7 @@ export class ConnectionWidget {
|
|||||||
container.element('tr', {}, (rowContainer) => {
|
container.element('tr', {}, (rowContainer) => {
|
||||||
rowContainer.element('td');
|
rowContainer.element('td');
|
||||||
rowContainer.element('td', { class: cellContainerClass }, (inputCellContainer) => {
|
rowContainer.element('td', { class: cellContainerClass }, (inputCellContainer) => {
|
||||||
checkbox = new Checkbox(inputCellContainer.getHTMLElement(), { label, checked: isChecked });
|
checkbox = new Checkbox(inputCellContainer.getHTMLElement(), { label, checked: isChecked, ariaLabel: label });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return checkbox;
|
return checkbox;
|
||||||
|
|||||||
@@ -210,7 +210,6 @@ export class CollapseWidgetAction extends Action {
|
|||||||
private _uri: string,
|
private _uri: string,
|
||||||
private _widgetUuid: string,
|
private _widgetUuid: string,
|
||||||
private collpasedState: boolean,
|
private collpasedState: boolean,
|
||||||
private collapsedStateChangedEvent: Event<boolean>,
|
|
||||||
@IAngularEventingService private _angularEventService: IAngularEventingService
|
@IAngularEventingService private _angularEventService: IAngularEventingService
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
@@ -218,7 +217,6 @@ export class CollapseWidgetAction extends Action {
|
|||||||
collpasedState ? CollapseWidgetAction.EXPAND_LABEL : CollapseWidgetAction.COLLPASE_LABEL,
|
collpasedState ? CollapseWidgetAction.EXPAND_LABEL : CollapseWidgetAction.COLLPASE_LABEL,
|
||||||
collpasedState ? CollapseWidgetAction.EXPAND_ICON : CollapseWidgetAction.COLLAPSE_ICON
|
collpasedState ? CollapseWidgetAction.EXPAND_ICON : CollapseWidgetAction.COLLAPSE_ICON
|
||||||
);
|
);
|
||||||
this.collapsedStateChangedEvent(collapsed => this._updateState(collapsed));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run(): TPromise<boolean> {
|
run(): TPromise<boolean> {
|
||||||
@@ -232,8 +230,15 @@ export class CollapseWidgetAction extends Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _updateState(collapsed: boolean): void {
|
private _updateState(collapsed: boolean): void {
|
||||||
|
if (collapsed === this.collpasedState) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.collpasedState = collapsed;
|
this.collpasedState = collapsed;
|
||||||
this._setClass(this.collpasedState ? CollapseWidgetAction.EXPAND_ICON : CollapseWidgetAction.COLLAPSE_ICON);
|
this._setClass(this.collpasedState ? CollapseWidgetAction.EXPAND_ICON : CollapseWidgetAction.COLLAPSE_ICON);
|
||||||
this._setLabel(this.collpasedState ? CollapseWidgetAction.EXPAND_LABEL : CollapseWidgetAction.COLLPASE_LABEL);
|
this._setLabel(this.collpasedState ? CollapseWidgetAction.EXPAND_LABEL : CollapseWidgetAction.COLLPASE_LABEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public set state(collapsed: boolean) {
|
||||||
|
this._updateState(collapsed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboar
|
|||||||
import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution';
|
import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution';
|
||||||
import { GRID_CONTAINER } from 'sql/parts/dashboard/containers/dashboardGridContainer.contribution';
|
import { GRID_CONTAINER } from 'sql/parts/dashboard/containers/dashboardGridContainer.contribution';
|
||||||
import { WEBVIEW_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWebviewContainer.contribution';
|
import { WEBVIEW_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWebviewContainer.contribution';
|
||||||
|
import { MODELVIEW_CONTAINER } from 'sql/parts/dashboard/containers/dashboardModelViewContainer.contribution';
|
||||||
import { CONTROLHOST_CONTAINER } from 'sql/parts/dashboard/containers/dashboardControlHostContainer.contribution';
|
import { CONTROLHOST_CONTAINER } from 'sql/parts/dashboard/containers/dashboardControlHostContainer.contribution';
|
||||||
import { NAV_SECTION } from 'sql/parts/dashboard/containers/dashboardNavSection.contribution';
|
import { NAV_SECTION } from 'sql/parts/dashboard/containers/dashboardNavSection.contribution';
|
||||||
import { IDashboardContainerRegistry, Extensions as DashboardContainerExtensions, IDashboardContainer, registerContainerType } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
import { IDashboardContainerRegistry, Extensions as DashboardContainerExtensions, IDashboardContainer, registerContainerType } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
||||||
@@ -25,6 +26,7 @@ const containerTypes = [
|
|||||||
WIDGETS_CONTAINER,
|
WIDGETS_CONTAINER,
|
||||||
GRID_CONTAINER,
|
GRID_CONTAINER,
|
||||||
WEBVIEW_CONTAINER,
|
WEBVIEW_CONTAINER,
|
||||||
|
MODELVIEW_CONTAINER,
|
||||||
CONTROLHOST_CONTAINER,
|
CONTROLHOST_CONTAINER,
|
||||||
NAV_SECTION
|
NAV_SECTION
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
</dashboard-webview-container>
|
</dashboard-webview-container>
|
||||||
<dashboard-widget-container *ngIf="getContentType(tab) === 'widgets-container'" [tab]="tab">
|
<dashboard-widget-container *ngIf="getContentType(tab) === 'widgets-container'" [tab]="tab">
|
||||||
</dashboard-widget-container>
|
</dashboard-widget-container>
|
||||||
|
<dashboard-modelview-container *ngIf="getContentType(tab) === 'modelview-container'" [tab]="tab">
|
||||||
|
</dashboard-modelview-container>
|
||||||
<dashboard-controlhost-container *ngIf="getContentType(tab) === 'controlhost-container'" [tab]="tab">
|
<dashboard-controlhost-container *ngIf="getContentType(tab) === 'controlhost-container'" [tab]="tab">
|
||||||
</dashboard-controlhost-container>
|
</dashboard-controlhost-container>
|
||||||
<dashboard-nav-section *ngIf="getContentType(tab) === 'nav-section'" [tab]="tab">
|
<dashboard-nav-section *ngIf="getContentType(tab) === 'nav-section'" [tab]="tab">
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'sql/parts/dashboard/common/dashboardPanelStyles';
|
|||||||
import { Component, Inject, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
import { Component, Inject, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
||||||
|
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { WidgetConfig, TabConfig, TabSettingConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { WidgetConfig, TabConfig, TabSettingConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
||||||
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
||||||
@@ -85,13 +86,15 @@ export abstract class DashboardPage extends AngularDisposable {
|
|||||||
|
|
||||||
protected abstract propertiesWidget: WidgetConfig;
|
protected abstract propertiesWidget: WidgetConfig;
|
||||||
protected abstract get context(): string;
|
protected abstract get context(): string;
|
||||||
|
protected dashboardService: DashboardServiceInterface;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) protected dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) protected commonService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ElementRef)) protected _el: ElementRef,
|
@Inject(forwardRef(() => ElementRef)) protected _el: ElementRef,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
|
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
this.dashboardService = commonService as DashboardServiceInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected init() {
|
protected init() {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
import 'vs/css!./dashboardControlHostContainer';
|
import 'vs/css!./dashboardControlHostContainer';
|
||||||
|
|
||||||
import { Component, forwardRef, Input, AfterContentInit, ViewChild } from '@angular/core';
|
import { Component, forwardRef, Input, AfterContentInit, ViewChild, OnChanges } from '@angular/core';
|
||||||
import Event, { Emitter } from 'vs/base/common/event';
|
import Event, { Emitter } from 'vs/base/common/event';
|
||||||
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
||||||
import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
@@ -18,6 +18,7 @@ import { ControlHostContent } from 'sql/parts/dashboard/contents/controlHostCont
|
|||||||
</controlhost-content>
|
</controlhost-content>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
|
|
||||||
export class DashboardControlHostContainer extends DashboardTab implements AfterContentInit {
|
export class DashboardControlHostContainer extends DashboardTab implements AfterContentInit {
|
||||||
@Input() private tab: TabConfig;
|
@Input() private tab: TabConfig;
|
||||||
|
|
||||||
@@ -53,6 +54,6 @@ export class DashboardControlHostContainer extends DashboardTab implements After
|
|||||||
}
|
}
|
||||||
|
|
||||||
public refresh(): void {
|
public refresh(): void {
|
||||||
// no op
|
this._hostContent.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export class DashboardErrorContainer extends DashboardTab implements AfterViewIn
|
|||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
let errorMessage = this._errorMessageContainer.nativeElement as HTMLElement;
|
let errorMessage = this._errorMessageContainer.nativeElement as HTMLElement;
|
||||||
errorMessage.innerHTML = nls.localize('dashboardNavSection_loadTabError', 'The {0} has an invalid content. Please contact extension owner.', this.tab.title);
|
errorMessage.innerHTML = nls.localize('dashboardNavSection_loadTabError', 'The "{0}" section has invalid content. Please contact extension owner.', this.tab.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get id(): string {
|
public get id(): string {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { Component, Inject, Input, forwardRef, ViewChild, ElementRef, ViewChildr
|
|||||||
import { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid';
|
import { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid';
|
||||||
|
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { TabConfig, WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { TabConfig, WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
||||||
import { subscriptionToDisposable } from 'sql/base/common/lifecycle';
|
import { subscriptionToDisposable } from 'sql/base/common/lifecycle';
|
||||||
@@ -153,7 +154,7 @@ export class DashboardGridContainer extends DashboardTab implements OnDestroy {
|
|||||||
@ViewChildren(DashboardWidgetWrapper) private _widgets: QueryList<DashboardWidgetWrapper>;
|
@ViewChildren(DashboardWidgetWrapper) private _widgets: QueryList<DashboardWidgetWrapper>;
|
||||||
@ViewChildren(WebviewContent) private _webViews: QueryList<WebviewContent>;
|
@ViewChildren(WebviewContent) private _webViews: QueryList<WebviewContent>;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) protected dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) protected dashboardService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ElementRef)) protected _el: ElementRef,
|
@Inject(forwardRef(() => ElementRef)) protected _el: ElementRef,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
|
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { DashboardWidgetContainer } from 'sql/parts/dashboard/containers/dashboa
|
|||||||
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
||||||
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { AngularEventType } from '../../../services/angularEventing/angularEventingService';
|
import { AngularEventType } from '../../../services/angularEventing/angularEventingService';
|
||||||
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
||||||
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||||
@@ -19,11 +20,13 @@ import { ConfigurationTarget } from 'vs/platform/configuration/common/configurat
|
|||||||
selector: 'dashboard-home-container',
|
selector: 'dashboard-home-container',
|
||||||
providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardHomeContainer) }],
|
providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardHomeContainer) }],
|
||||||
template: `
|
template: `
|
||||||
<dashboard-widget-wrapper #propertiesClass *ngIf="properties" [collapsable]="true" [_config]="properties"
|
<div class="fullsize" style="display: flex; flex-direction: column">
|
||||||
style="padding-left: 10px; padding-right: 10px; display: block" [style.height.px]="_propertiesClass?.collapsed ? '30' : '90'">
|
<dashboard-widget-wrapper #propertiesClass *ngIf="properties" [collapsable]="true" [_config]="properties"
|
||||||
</dashboard-widget-wrapper>
|
style="padding-left: 10px; padding-right: 10px; display: block; flex: 0" [style.height.px]="_propertiesClass?.collapsed ? '30' : '90'">
|
||||||
<widget-content [widgets]="widgets" [originalConfig]="tab.originalConfig" [context]="tab.context">
|
</dashboard-widget-wrapper>
|
||||||
</widget-content>
|
<widget-content style="flex: 1" [widgets]="widgets" [originalConfig]="tab.originalConfig" [context]="tab.context">
|
||||||
|
</widget-content>
|
||||||
|
</div>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
export class DashboardHomeContainer extends DashboardWidgetContainer {
|
export class DashboardHomeContainer extends DashboardWidgetContainer {
|
||||||
@@ -32,8 +35,7 @@ export class DashboardHomeContainer extends DashboardWidgetContainer {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) _cd: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) _cd: ChangeDetectorRef,
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) protected dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) protected dashboardService: DashboardServiceInterface
|
||||||
|
|
||||||
) {
|
) {
|
||||||
super(_cd);
|
super(_cd);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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!./dashboardWebviewContainer';
|
||||||
|
|
||||||
|
import { Component, forwardRef, Input, AfterContentInit, ViewChild } from '@angular/core';
|
||||||
|
|
||||||
|
import Event, { Emitter } from 'vs/base/common/event';
|
||||||
|
|
||||||
|
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
||||||
|
import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
|
import { ModelViewContent } from 'sql/parts/modelComponents/modelViewContent.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'dashboard-modelview-container',
|
||||||
|
providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardModelViewContainer) }],
|
||||||
|
template: `
|
||||||
|
<modelview-content [modelViewId]="tab.id">
|
||||||
|
</modelview-content>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
export class DashboardModelViewContainer extends DashboardTab implements AfterContentInit {
|
||||||
|
@Input() private tab: TabConfig;
|
||||||
|
|
||||||
|
private _onResize = new Emitter<void>();
|
||||||
|
public readonly onResize: Event<void> = this._onResize.event;
|
||||||
|
|
||||||
|
@ViewChild(ModelViewContent) private _modelViewContent: ModelViewContent;
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterContentInit(): void {
|
||||||
|
this._register(this._modelViewContent.onResize(() => {
|
||||||
|
this._onResize.fire();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public layout(): void {
|
||||||
|
this._modelViewContent.layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get id(): string {
|
||||||
|
return this.tab.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get editable(): boolean {
|
||||||
|
return this.tab.editable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public refresh(): void {
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||||
|
import * as nls from 'vs/nls';
|
||||||
|
|
||||||
|
import { registerContainerType, registerNavSectionContainerType } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
||||||
|
|
||||||
|
export const MODELVIEW_CONTAINER = 'modelview-container';
|
||||||
|
|
||||||
|
let modelviewSchema: IJSONSchema = {
|
||||||
|
type: 'null',
|
||||||
|
description: nls.localize('dashboard.container.modelview', "The model-backed view that will be displayed in this tab."),
|
||||||
|
default: null
|
||||||
|
};
|
||||||
|
|
||||||
|
registerContainerType(MODELVIEW_CONTAINER, modelviewSchema);
|
||||||
|
registerNavSectionContainerType(MODELVIEW_CONTAINER, modelviewSchema);
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
dashboard-modelview-container {
|
||||||
|
height: 100%;
|
||||||
|
width : 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
@@ -11,6 +11,8 @@
|
|||||||
</dashboard-webview-container>
|
</dashboard-webview-container>
|
||||||
<dashboard-widget-container *ngIf="getContentType(tab) === 'widgets-container'" [tab]="tab">
|
<dashboard-widget-container *ngIf="getContentType(tab) === 'widgets-container'" [tab]="tab">
|
||||||
</dashboard-widget-container>
|
</dashboard-widget-container>
|
||||||
|
<dashboard-modelview-container *ngIf="getContentType(tab) === 'modelview-container'" [tab]="tab">
|
||||||
|
</dashboard-modelview-container>
|
||||||
<dashboard-grid-container *ngIf="getContentType(tab) === 'grid-container'" [tab]="tab">
|
<dashboard-grid-container *ngIf="getContentType(tab) === 'grid-container'" [tab]="tab">
|
||||||
</dashboard-grid-container>
|
</dashboard-grid-container>
|
||||||
<dashboard-error-container *ngIf="getContentType(tab) === 'error-container'" [tab]="tab">
|
<dashboard-error-container *ngIf="getContentType(tab) === 'error-container'" [tab]="tab">
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'vs/css!./dashboardNavSection';
|
|||||||
import { Component, Inject, Input, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef, EventEmitter, OnChanges, AfterContentInit } from '@angular/core';
|
import { Component, Inject, Input, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef, EventEmitter, OnChanges, AfterContentInit } from '@angular/core';
|
||||||
|
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { WidgetConfig, TabConfig, NavSectionConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { WidgetConfig, TabConfig, NavSectionConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { PanelComponent, IPanelOptions, NavigationBarLayout } from 'sql/base/browser/ui/panel/panel.component';
|
import { PanelComponent, IPanelOptions, NavigationBarLayout } from 'sql/base/browser/ui/panel/panel.component';
|
||||||
import { TabComponent } from 'sql/base/browser/ui/panel/tab.component';
|
import { TabComponent } from 'sql/base/browser/ui/panel/tab.component';
|
||||||
@@ -53,7 +54,7 @@ export class DashboardNavSection extends DashboardTab implements OnDestroy, OnCh
|
|||||||
@ViewChildren(DashboardTab) private _tabs: QueryList<DashboardTab>;
|
@ViewChildren(DashboardTab) private _tabs: QueryList<DashboardTab>;
|
||||||
@ViewChild(PanelComponent) private _panel: PanelComponent;
|
@ViewChild(PanelComponent) private _panel: PanelComponent;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) protected dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) protected dashboardService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
|
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ import Event, { Emitter } from 'vs/base/common/event';
|
|||||||
</widget-content>
|
</widget-content>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, OnChanges, AfterContentInit {
|
export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, AfterContentInit {
|
||||||
@Input() private tab: TabConfig;
|
@Input() protected tab: TabConfig;
|
||||||
private widgets: WidgetConfig[];
|
protected widgets: WidgetConfig[];
|
||||||
private _onResize = new Emitter<void>();
|
private _onResize = new Emitter<void>();
|
||||||
public readonly onResize: Event<void> = this._onResize.event;
|
public readonly onResize: Event<void> = this._onResize.event;
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ export class DashboardWidgetContainer extends DashboardTab implements OnDestroy,
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnInit() {
|
||||||
if (this.tab.container) {
|
if (this.tab.container) {
|
||||||
this.widgets = Object.values(this.tab.container)[0];
|
this.widgets = Object.values(this.tab.container)[0];
|
||||||
this._cd.detectChanges();
|
this._cd.detectChanges();
|
||||||
|
|||||||
@@ -5,5 +5,4 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<agentview-component *ngIf="(controlType) === 'agent'">
|
<agentview-component #agent *ngIf="(controlType) === 'agent'"></agentview-component>
|
||||||
</agentview-component>
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
import 'vs/css!./controlHostContent';
|
import 'vs/css!./controlHostContent';
|
||||||
|
|
||||||
import { Component, forwardRef, Input, OnInit, Inject, ChangeDetectorRef, ElementRef } from '@angular/core';
|
import { Component, forwardRef, Input, OnInit, Inject, ChangeDetectorRef, ElementRef, ViewChild } from '@angular/core';
|
||||||
|
|
||||||
import Event, { Emitter } from 'vs/base/common/event';
|
import Event, { Emitter } from 'vs/base/common/event';
|
||||||
import { Parts } from 'vs/workbench/services/part/common/partService';
|
import { Parts } from 'vs/workbench/services/part/common/partService';
|
||||||
@@ -13,15 +13,17 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
|||||||
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
||||||
import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
|
|
||||||
import * as sqlops from 'sqlops';
|
import * as sqlops from 'sqlops';
|
||||||
import { memoize } from 'vs/base/common/decorators';
|
import { memoize } from 'vs/base/common/decorators';
|
||||||
|
import { AgentViewComponent } from '../../jobManagement/agent/agentView.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: decodeURI(require.toUrl('sql/parts/dashboard/contents/controlHostContent.component.html')),
|
templateUrl: decodeURI(require.toUrl('sql/parts/dashboard/contents/controlHostContent.component.html')),
|
||||||
selector: 'controlhost-content'
|
selector: 'controlhost-content'
|
||||||
})
|
})
|
||||||
export class ControlHostContent implements OnInit {
|
export class ControlHostContent {
|
||||||
@Input() private webviewId: string;
|
@Input() private webviewId: string;
|
||||||
|
|
||||||
private _onResize = new Emitter<void>();
|
private _onResize = new Emitter<void>();
|
||||||
@@ -32,16 +34,16 @@ export class ControlHostContent implements OnInit {
|
|||||||
private _onMessageDisposable: IDisposable;
|
private _onMessageDisposable: IDisposable;
|
||||||
private _type: string;
|
private _type: string;
|
||||||
|
|
||||||
|
/* Children components */
|
||||||
|
@ViewChild('agent') private _agentViewComponent: AgentViewComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) private _dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _dashboardService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef
|
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public layout(): void {
|
public layout(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,4 +75,8 @@ export class ControlHostContent implements OnInit {
|
|||||||
public get controlType(): string {
|
public get controlType(): string {
|
||||||
return this._type;
|
return this._type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public refresh() {
|
||||||
|
this._agentViewComponent.refresh = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { InsightsWidget } from 'sql/parts/dashboard/widgets/insights/insightsWid
|
|||||||
import { WebviewWidget } from 'sql/parts/dashboard/widgets/webview/webviewWidget.component';
|
import { WebviewWidget } from 'sql/parts/dashboard/widgets/webview/webviewWidget.component';
|
||||||
|
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
|
|
||||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
import { IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||||
@@ -53,6 +54,7 @@ export class DashboardWidgetWrapper extends AngularDisposable implements OnInit
|
|||||||
@Input() private _config: WidgetConfig;
|
@Input() private _config: WidgetConfig;
|
||||||
@Input() private collapsable = false;
|
@Input() private collapsable = false;
|
||||||
|
|
||||||
|
private _collapseAction: CollapseWidgetAction;
|
||||||
private _collapsed = false;
|
private _collapsed = false;
|
||||||
|
|
||||||
public get collapsed(): boolean {
|
public get collapsed(): boolean {
|
||||||
@@ -64,17 +66,13 @@ export class DashboardWidgetWrapper extends AngularDisposable implements OnInit
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._collapsed = val;
|
this._collapsed = val;
|
||||||
if (this.collapsedStateChangedEmitter) {
|
this._collapseAction.state = val;
|
||||||
this.collapsedStateChangedEmitter.fire(this._collapsed);
|
|
||||||
}
|
|
||||||
this._changeref.detectChanges();
|
this._changeref.detectChanges();
|
||||||
if (!val) {
|
if (!val) {
|
||||||
this.loadWidget();
|
this.loadWidget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private collapsedStateChangedEmitter: Emitter<boolean>;
|
|
||||||
|
|
||||||
@memoize
|
@memoize
|
||||||
public get guid(): string {
|
public get guid(): string {
|
||||||
return generateUuid();
|
return generateUuid();
|
||||||
@@ -91,7 +89,7 @@ export class DashboardWidgetWrapper extends AngularDisposable implements OnInit
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ComponentFactoryResolver)) private _componentFactoryResolver: ComponentFactoryResolver,
|
@Inject(forwardRef(() => ComponentFactoryResolver)) private _componentFactoryResolver: ComponentFactoryResolver,
|
||||||
@Inject(forwardRef(() => ElementRef)) private _ref: ElementRef,
|
@Inject(forwardRef(() => ElementRef)) private _ref: ElementRef,
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) private _bootstrap: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrap: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeref: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeref: ChangeDetectorRef,
|
||||||
@Inject(forwardRef(() => Injector)) private _injector: Injector
|
@Inject(forwardRef(() => Injector)) private _injector: Injector
|
||||||
) {
|
) {
|
||||||
@@ -114,8 +112,8 @@ export class DashboardWidgetWrapper extends AngularDisposable implements OnInit
|
|||||||
this._actionbar = new ActionBar(this._actionbarRef.nativeElement);
|
this._actionbar = new ActionBar(this._actionbarRef.nativeElement);
|
||||||
if (this._actions) {
|
if (this._actions) {
|
||||||
if (this.collapsable) {
|
if (this.collapsable) {
|
||||||
this.collapsedStateChangedEmitter = new Emitter<boolean>();
|
this._collapseAction = this._bootstrap.instantiationService.createInstance(CollapseWidgetAction, this._bootstrap.getUnderlyingUri(), this.guid, this.collapsed);
|
||||||
this._actionbar.push(this._bootstrap.instantiationService.createInstance(CollapseWidgetAction, this._bootstrap.getUnderlyingUri(), this.guid, this.collapsed, this.collapsedStateChangedEmitter.event), { icon: true, label: false });
|
this._actionbar.push(this._collapseAction, { icon: true, label: false });
|
||||||
}
|
}
|
||||||
this._actionbar.push(this._bootstrap.instantiationService.createInstance(ToggleMoreWidgetAction, this._actions, this._component.actionsContext), { icon: true, label: false });
|
this._actionbar.push(this._bootstrap.instantiationService.createInstance(ToggleMoreWidgetAction, this._actions, this._component.actionsContext), { icon: true, label: false });
|
||||||
}
|
}
|
||||||
@@ -123,13 +121,13 @@ export class DashboardWidgetWrapper extends AngularDisposable implements OnInit
|
|||||||
}
|
}
|
||||||
|
|
||||||
public refresh(): void {
|
public refresh(): void {
|
||||||
if (this._component && this._component.refresh) {
|
if (!this.collapsed && this._component && this._component.refresh) {
|
||||||
this._component.refresh();
|
this._component.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public layout(): void {
|
public layout(): void {
|
||||||
if (this._component && this._component.layout) {
|
if (!this.collapsed && this._component && this._component.layout) {
|
||||||
this._component.layout();
|
this._component.layout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,7 +168,7 @@ export class DashboardWidgetWrapper extends AngularDisposable implements OnInit
|
|||||||
this._component = componentRef.instance;
|
this._component = componentRef.instance;
|
||||||
let actions = componentRef.instance.actions;
|
let actions = componentRef.instance.actions;
|
||||||
if (componentRef.instance.refresh) {
|
if (componentRef.instance.refresh) {
|
||||||
actions.push(new RefreshWidgetAction(componentRef.instance.refresh, componentRef.instance));
|
actions.push(new RefreshWidgetAction(this.refresh, this));
|
||||||
}
|
}
|
||||||
if (actions !== undefined && actions.length > 0) {
|
if (actions !== undefined && actions.length > 0) {
|
||||||
this._actions = actions;
|
this._actions = actions;
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ import { memoize } from 'vs/base/common/decorators';
|
|||||||
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
||||||
import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
import { IDashboardWebview } from 'sql/services/dashboardWebview/common/dashboardWebviewService';
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
|
import { IDashboardWebview } from 'sql/services/dashboard/common/dashboardViewService';
|
||||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||||
|
|
||||||
import * as sqlops from 'sqlops';
|
import * as sqlops from 'sqlops';
|
||||||
@@ -36,17 +37,19 @@ export class WebviewContent extends AngularDisposable implements OnInit, IDashbo
|
|||||||
private _onMessageDisposable: IDisposable;
|
private _onMessageDisposable: IDisposable;
|
||||||
private _webview: Webview;
|
private _webview: Webview;
|
||||||
private _html: string;
|
private _html: string;
|
||||||
|
private _dashboardService: DashboardServiceInterface;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) private _dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private commonService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef
|
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
this._dashboardService = commonService as DashboardServiceInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this._dashboardService.dashboardWebviewService.registerWebview(this);
|
this._dashboardService.dashboardViewService.registerWebview(this);
|
||||||
this._createWebview();
|
this._createWebview();
|
||||||
this._register(addDisposableListener(window, EventType.RESIZE, e => {
|
this._register(addDisposableListener(window, EventType.RESIZE, e => {
|
||||||
this.layout();
|
this.layout();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { Component, Inject, Input, forwardRef, ViewChild, ViewChildren, QueryLis
|
|||||||
import { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid';
|
import { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid';
|
||||||
|
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
||||||
import { subscriptionToDisposable, AngularDisposable } from 'sql/base/common/lifecycle';
|
import { subscriptionToDisposable, AngularDisposable } from 'sql/base/common/lifecycle';
|
||||||
@@ -111,11 +112,14 @@ export class WidgetContent extends AngularDisposable implements AfterViewInit {
|
|||||||
@ViewChildren(NgGridItem) private _items: QueryList<NgGridItem>;
|
@ViewChildren(NgGridItem) private _items: QueryList<NgGridItem>;
|
||||||
@ViewChild('scrollable', { read: ElementRef }) private _scrollable: ElementRef;
|
@ViewChild('scrollable', { read: ElementRef }) private _scrollable: ElementRef;
|
||||||
@ViewChild('scrollContainer', { read: ElementRef }) private _scrollContainer: ElementRef;
|
@ViewChild('scrollContainer', { read: ElementRef }) private _scrollContainer: ElementRef;
|
||||||
|
|
||||||
|
protected dashboardService: DashboardServiceInterface;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) protected dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) protected commonService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
|
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
this.dashboardService = commonService as DashboardServiceInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { OnInit, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, O
|
|||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
import { DashboardServiceInterface } from './services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from './services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||||
import * as Utils from 'sql/parts/connection/common/utils';
|
import * as Utils from 'sql/parts/connection/common/utils';
|
||||||
import { RefreshWidgetAction, EditDashboardAction } from 'sql/parts/dashboard/common/actions';
|
import { RefreshWidgetAction, EditDashboardAction } from 'sql/parts/dashboard/common/actions';
|
||||||
@@ -36,7 +37,7 @@ export class DashboardComponent extends AngularDisposable implements OnInit {
|
|||||||
private editDisposable: IDisposable;
|
private editDisposable: IDisposable;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) private _bootstrapService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => Router)) private _router: Router,
|
@Inject(forwardRef(() => Router)) private _router: Router,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { ChartsModule } from 'ng2-charts/ng2-charts';
|
|||||||
import CustomUrlSerializer from 'sql/common/urlSerializer';
|
import CustomUrlSerializer from 'sql/common/urlSerializer';
|
||||||
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
|
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
|
||||||
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
||||||
|
import { Extensions as ComponentExtensions, IComponentRegistry } from 'sql/platform/dashboard/common/modelComponentRegistry';
|
||||||
|
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
|||||||
/* Services */
|
/* Services */
|
||||||
import { BreadcrumbService } from 'sql/parts/dashboard/services/breadcrumb.service';
|
import { BreadcrumbService } from 'sql/parts/dashboard/services/breadcrumb.service';
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
|
|
||||||
/* Directives */
|
/* Directives */
|
||||||
import { ComponentHostDirective } from 'sql/parts/dashboard/common/componentHost.directive';
|
import { ComponentHostDirective } from 'sql/parts/dashboard/common/componentHost.directive';
|
||||||
@@ -35,9 +37,12 @@ import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWi
|
|||||||
import { DashboardWidgetContainer } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.component';
|
import { DashboardWidgetContainer } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.component';
|
||||||
import { DashboardGridContainer } from 'sql/parts/dashboard/containers/dashboardGridContainer.component';
|
import { DashboardGridContainer } from 'sql/parts/dashboard/containers/dashboardGridContainer.component';
|
||||||
import { DashboardWebviewContainer } from 'sql/parts/dashboard/containers/dashboardWebviewContainer.component';
|
import { DashboardWebviewContainer } from 'sql/parts/dashboard/containers/dashboardWebviewContainer.component';
|
||||||
|
import { DashboardModelViewContainer } from 'sql/parts/dashboard/containers/dashboardModelViewContainer.component';
|
||||||
import { DashboardErrorContainer } from 'sql/parts/dashboard/containers/dashboardErrorContainer.component';
|
import { DashboardErrorContainer } from 'sql/parts/dashboard/containers/dashboardErrorContainer.component';
|
||||||
import { DashboardNavSection } from 'sql/parts/dashboard/containers/dashboardNavSection.component';
|
import { DashboardNavSection } from 'sql/parts/dashboard/containers/dashboardNavSection.component';
|
||||||
import { WidgetContent } from 'sql/parts/dashboard/contents/widgetContent.component';
|
import { WidgetContent } from 'sql/parts/dashboard/contents/widgetContent.component';
|
||||||
|
import { ModelViewContent } from 'sql/parts/modelComponents/modelViewContent.component';
|
||||||
|
import { ModelComponentWrapper } from 'sql/parts/modelComponents/modelComponentWrapper.component';
|
||||||
import { WebviewContent } from 'sql/parts/dashboard/contents/webviewContent.component';
|
import { WebviewContent } from 'sql/parts/dashboard/contents/webviewContent.component';
|
||||||
import { BreadcrumbComponent } from 'sql/base/browser/ui/breadcrumb/breadcrumb.component';
|
import { BreadcrumbComponent } from 'sql/base/browser/ui/breadcrumb/breadcrumb.component';
|
||||||
import { IBreadcrumbService } from 'sql/base/browser/ui/breadcrumb/interfaces';
|
import { IBreadcrumbService } from 'sql/base/browser/ui/breadcrumb/interfaces';
|
||||||
@@ -49,9 +54,9 @@ import { AgentViewComponent } from 'sql/parts/jobManagement/agent/agentView.comp
|
|||||||
import { JobHistoryComponent } from 'sql/parts/jobManagement/views/jobHistory.component';
|
import { JobHistoryComponent } from 'sql/parts/jobManagement/views/jobHistory.component';
|
||||||
|
|
||||||
let baseComponents = [DashboardHomeContainer, DashboardComponent, DashboardWidgetWrapper, DashboardWebviewContainer,
|
let baseComponents = [DashboardHomeContainer, DashboardComponent, DashboardWidgetWrapper, DashboardWebviewContainer,
|
||||||
DashboardWidgetContainer, DashboardGridContainer, DashboardErrorContainer, DashboardNavSection, WebviewContent, WidgetContent,
|
DashboardWidgetContainer, DashboardGridContainer, DashboardErrorContainer, DashboardNavSection, ModelViewContent, WebviewContent, WidgetContent,
|
||||||
ComponentHostDirective, BreadcrumbComponent, ControlHostContent, DashboardControlHostContainer,
|
ComponentHostDirective, BreadcrumbComponent, ControlHostContent, DashboardControlHostContainer,
|
||||||
JobsViewComponent, AgentViewComponent, JobHistoryComponent, JobStepsViewComponent];
|
JobsViewComponent, AgentViewComponent, JobHistoryComponent, JobStepsViewComponent, DashboardModelViewContainer, ModelComponentWrapper];
|
||||||
|
|
||||||
/* Panel */
|
/* Panel */
|
||||||
import { PanelModule } from 'sql/base/browser/ui/panel/panel.module';
|
import { PanelModule } from 'sql/base/browser/ui/panel/panel.module';
|
||||||
@@ -81,6 +86,9 @@ let widgetComponents = [
|
|||||||
/* Insights */
|
/* Insights */
|
||||||
let insightComponents = Registry.as<IInsightRegistry>(Extensions.InsightContribution).getAllCtors();
|
let insightComponents = Registry.as<IInsightRegistry>(Extensions.InsightContribution).getAllCtors();
|
||||||
|
|
||||||
|
/* Model-backed components */
|
||||||
|
let extensionComponents = Registry.as<IComponentRegistry>(ComponentExtensions.ComponentContribution).getAllCtors();
|
||||||
|
|
||||||
// Setup routes for various child components
|
// Setup routes for various child components
|
||||||
const appRoutes: Routes = [
|
const appRoutes: Routes = [
|
||||||
{ path: 'database-dashboard', component: DatabaseDashboardPage },
|
{ path: 'database-dashboard', component: DatabaseDashboardPage },
|
||||||
@@ -99,13 +107,15 @@ const appRoutes: Routes = [
|
|||||||
...baseComponents,
|
...baseComponents,
|
||||||
...pageComponents,
|
...pageComponents,
|
||||||
...widgetComponents,
|
...widgetComponents,
|
||||||
...insightComponents
|
...insightComponents,
|
||||||
|
...extensionComponents
|
||||||
],
|
],
|
||||||
// also for widgets
|
// also for widgets
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
DashboardComponent,
|
DashboardComponent,
|
||||||
...widgetComponents,
|
...widgetComponents,
|
||||||
...insightComponents
|
...insightComponents,
|
||||||
|
...extensionComponents
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@@ -119,18 +129,19 @@ const appRoutes: Routes = [
|
|||||||
providers: [
|
providers: [
|
||||||
{ provide: APP_BASE_HREF, useValue: '/' },
|
{ provide: APP_BASE_HREF, useValue: '/' },
|
||||||
{ provide: IBreadcrumbService, useClass: BreadcrumbService },
|
{ provide: IBreadcrumbService, useClass: BreadcrumbService },
|
||||||
DashboardServiceInterface,
|
{ provide: CommonServiceInterface, useClass: DashboardServiceInterface },
|
||||||
{ provide: UrlSerializer, useClass: CustomUrlSerializer }
|
{ provide: UrlSerializer, useClass: CustomUrlSerializer }
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class DashboardModule {
|
export class DashboardModule {
|
||||||
|
private _bootstrap: DashboardServiceInterface;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ComponentFactoryResolver)) private _resolver: ComponentFactoryResolver,
|
@Inject(forwardRef(() => ComponentFactoryResolver)) private _resolver: ComponentFactoryResolver,
|
||||||
@Inject(BOOTSTRAP_SERVICE_ID) private _bootstrapService: IBootstrapService,
|
@Inject(BOOTSTRAP_SERVICE_ID) private _bootstrapService: IBootstrapService,
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) private _bootstrap: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) bootstrap: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => Router)) private _router: Router
|
@Inject(forwardRef(() => Router)) private _router: Router
|
||||||
) {
|
) {
|
||||||
|
this._bootstrap = bootstrap as DashboardServiceInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngDoBootstrap(appRef: ApplicationRef) {
|
ngDoBootstrap(appRef: ApplicationRef) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/
|
|||||||
|
|
||||||
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
|
|
||||||
export class DatabaseDashboardPage extends DashboardPage implements OnInit {
|
export class DatabaseDashboardPage extends DashboardPage implements OnInit {
|
||||||
protected propertiesWidget: WidgetConfig = {
|
protected propertiesWidget: WidgetConfig = {
|
||||||
@@ -35,7 +36,7 @@ export class DatabaseDashboardPage extends DashboardPage implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => IBreadcrumbService)) private _breadcrumbService: IBreadcrumbService,
|
@Inject(forwardRef(() => IBreadcrumbService)) private _breadcrumbService: IBreadcrumbService,
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) dashboardService: DashboardServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) _cd: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) _cd: ChangeDetectorRef,
|
||||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { BreadcrumbClass } from 'sql/parts/dashboard/services/breadcrumb.service
|
|||||||
import { IBreadcrumbService } from 'sql/base/browser/ui/breadcrumb/interfaces';
|
import { IBreadcrumbService } from 'sql/base/browser/ui/breadcrumb/interfaces';
|
||||||
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
|
import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService';
|
||||||
|
|
||||||
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
||||||
@@ -36,7 +37,7 @@ export class ServerDashboardPage extends DashboardPage implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => IBreadcrumbService)) private breadcrumbService: IBreadcrumbService,
|
@Inject(forwardRef(() => IBreadcrumbService)) private breadcrumbService: IBreadcrumbService,
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) dashboardService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) _cd: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) _cd: ChangeDetectorRef,
|
||||||
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
@Inject(forwardRef(() => ElementRef)) el: ElementRef
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { Injectable, forwardRef, Inject, OnDestroy } from '@angular/core';
|
|||||||
import { Subject } from 'rxjs/Subject';
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
|
||||||
import { DashboardServiceInterface } from './dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from './dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { MenuItem, IBreadcrumbService } from 'sql/base/browser/ui/breadcrumb/interfaces';
|
import { MenuItem, IBreadcrumbService } from 'sql/base/browser/ui/breadcrumb/interfaces';
|
||||||
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
||||||
|
|
||||||
@@ -23,9 +24,11 @@ export class BreadcrumbService implements IBreadcrumbService {
|
|||||||
public breadcrumbItem: Subject<MenuItem[]>;
|
public breadcrumbItem: Subject<MenuItem[]>;
|
||||||
private itemBreadcrums: MenuItem[];
|
private itemBreadcrums: MenuItem[];
|
||||||
private _currentPage: BreadcrumbClass;
|
private _currentPage: BreadcrumbClass;
|
||||||
|
private _bootstrap: DashboardServiceInterface;
|
||||||
|
|
||||||
constructor( @Inject(forwardRef(() => DashboardServiceInterface)) private _bootstrap: DashboardServiceInterface) {
|
constructor( @Inject(forwardRef(() => CommonServiceInterface)) private commonService: CommonServiceInterface) {
|
||||||
_bootstrap.onUpdatePage(() => {
|
this._bootstrap = commonService as DashboardServiceInterface;
|
||||||
|
this._bootstrap.onUpdatePage(() => {
|
||||||
this.setBreadcrumbs(this._currentPage);
|
this.setBreadcrumbs(this._currentPage);
|
||||||
});
|
});
|
||||||
this.breadcrumbItem = new Subject<MenuItem[]>();
|
this.breadcrumbItem = new Subject<MenuItem[]>();
|
||||||
|
|||||||
@@ -23,9 +23,11 @@ import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
|||||||
import { AngularEventType, IAngularEvent, IAngularEventingService } from 'sql/services/angularEventing/angularEventingService';
|
import { AngularEventType, IAngularEvent, IAngularEventingService } from 'sql/services/angularEventing/angularEventingService';
|
||||||
import { IDashboardTab } from 'sql/platform/dashboard/common/dashboardRegistry';
|
import { IDashboardTab } from 'sql/platform/dashboard/common/dashboardRegistry';
|
||||||
import { TabSettingConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { TabSettingConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { IDashboardWebviewService } from 'sql/services/dashboardWebview/common/dashboardWebviewService';
|
import { IDashboardViewService } from 'sql/services/dashboard/common/dashboardViewService';
|
||||||
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
import { AngularDisposable } from 'sql/base/common/lifecycle';
|
||||||
import { ConnectionContextkey } from 'sql/parts/connection/common/connectionContextKey';
|
import { ConnectionContextkey } from 'sql/parts/connection/common/connectionContextKey';
|
||||||
|
import { SingleConnectionMetadataService, SingleConnectionManagementService, SingleAdminService, SingleQueryManagementService, CommonServiceInterface }
|
||||||
|
from 'sql/services/common/commonServiceInterface.service';
|
||||||
|
|
||||||
import { ProviderMetadata, DatabaseInfo, SimpleExecuteResult } from 'sqlops';
|
import { ProviderMetadata, DatabaseInfo, SimpleExecuteResult } from 'sqlops';
|
||||||
|
|
||||||
@@ -50,68 +52,6 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
|
|||||||
|
|
||||||
const DASHBOARD_SETTINGS = 'dashboard';
|
const DASHBOARD_SETTINGS = 'dashboard';
|
||||||
|
|
||||||
/* Wrapper for a metadata service that contains the uri string to use on each request */
|
|
||||||
export class SingleConnectionMetadataService {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private _metadataService: IMetadataService,
|
|
||||||
private _uri: string
|
|
||||||
) { }
|
|
||||||
|
|
||||||
get metadata(): Observable<ProviderMetadata> {
|
|
||||||
return Observable.fromPromise(this._metadataService.getMetadata(this._uri));
|
|
||||||
}
|
|
||||||
|
|
||||||
get databaseNames(): Observable<string[]> {
|
|
||||||
return Observable.fromPromise(this._metadataService.getDatabaseNames(this._uri));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wrapper for a connection service that contains the uri string to use on each request */
|
|
||||||
export class SingleConnectionManagementService {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private _connectionService: IConnectionManagementService,
|
|
||||||
private _uri: string,
|
|
||||||
private _contextKey: ConnectionContextkey
|
|
||||||
) { }
|
|
||||||
|
|
||||||
public changeDatabase(name: string): Thenable<boolean> {
|
|
||||||
return this._connectionService.changeDatabase(this._uri, name).then(e => {
|
|
||||||
// we need to update our context
|
|
||||||
this._contextKey.set(this.connectionInfo.connectionProfile);
|
|
||||||
return e;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public get connectionInfo(): ConnectionManagementInfo {
|
|
||||||
return this._connectionService.getConnectionInfo(this._uri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SingleAdminService {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private _adminService: IAdminService,
|
|
||||||
private _uri: string
|
|
||||||
) { }
|
|
||||||
|
|
||||||
public get databaseInfo(): Observable<DatabaseInfo> {
|
|
||||||
return Observable.fromPromise(this._adminService.getDatabaseInfo(this._uri));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SingleQueryManagementService {
|
|
||||||
constructor(
|
|
||||||
private _queryManagementService: IQueryManagementService,
|
|
||||||
private _uri: string
|
|
||||||
) { }
|
|
||||||
|
|
||||||
public runQueryAndReturn(queryString: string): Thenable<SimpleExecuteResult> {
|
|
||||||
return this._queryManagementService.runQueryAndReturn(this._uri, queryString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Providers a interface between a dashboard interface and the rest of carbon.
|
Providers a interface between a dashboard interface and the rest of carbon.
|
||||||
Stores the uri and unique selector of a dashboard instance and uses that
|
Stores the uri and unique selector of a dashboard instance and uses that
|
||||||
@@ -120,35 +60,12 @@ export class SingleQueryManagementService {
|
|||||||
usage of a widget.
|
usage of a widget.
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DashboardServiceInterface extends AngularDisposable {
|
export class DashboardServiceInterface extends CommonServiceInterface {
|
||||||
private _uniqueSelector: string;
|
|
||||||
private _uri: string;
|
|
||||||
private _bootstrapParams: DashboardComponentParams;
|
|
||||||
|
|
||||||
/* Static Services */
|
/* Static Services */
|
||||||
private _themeService = this._bootstrapService.themeService;
|
|
||||||
private _contextMenuService = this._bootstrapService.contextMenuService;
|
|
||||||
private _instantiationService = this._bootstrapService.instantiationService;
|
|
||||||
private _configService = this._bootstrapService.configurationService;
|
|
||||||
private _insightsDialogService = this._bootstrapService.insightsDialogService;
|
|
||||||
private _contextViewService = this._bootstrapService.contextViewService;
|
|
||||||
private _notificationService = this._bootstrapService.notificationService;
|
|
||||||
private _workspaceContextService = this._bootstrapService.workspaceContextService;
|
|
||||||
private _storageService = this._bootstrapService.storageService;
|
|
||||||
private _capabilitiesService = this._bootstrapService.capabilitiesService;
|
|
||||||
private _configurationEditingService = this._bootstrapService.configurationEditorService;
|
|
||||||
private _commandService = this._bootstrapService.commandService;
|
|
||||||
private _dashboardWebviewService = this._bootstrapService.dashboardWebviewService;
|
|
||||||
private _partService = this._bootstrapService.partService;
|
|
||||||
private _angularEventingService = this._bootstrapService.angularEventingService;
|
|
||||||
private _environmentService = this._bootstrapService.environmentService;
|
|
||||||
|
|
||||||
/* Special Services */
|
private _dashboardViewService = this._bootstrapService.dashboardViewService;
|
||||||
private _metadataService: SingleConnectionMetadataService;
|
|
||||||
private _connectionManagementService: SingleConnectionManagementService;
|
|
||||||
private _adminService: SingleAdminService;
|
|
||||||
private _queryManagementService: SingleQueryManagementService;
|
|
||||||
private _contextKeyService: IContextKeyService;
|
|
||||||
|
|
||||||
private _updatePage = new Emitter<void>();
|
private _updatePage = new Emitter<void>();
|
||||||
public readonly onUpdatePage: Event<void> = this._updatePage.event;
|
public readonly onUpdatePage: Event<void> = this._updatePage.event;
|
||||||
@@ -168,91 +85,17 @@ export class DashboardServiceInterface extends AngularDisposable {
|
|||||||
private _dashboardContextKey = new RawContextKey<string>('dashboardContext', undefined);
|
private _dashboardContextKey = new RawContextKey<string>('dashboardContext', undefined);
|
||||||
public dashboardContextKey: IContextKey<string>;
|
public dashboardContextKey: IContextKey<string>;
|
||||||
|
|
||||||
private _connectionContextKey: ConnectionContextkey;
|
|
||||||
|
|
||||||
private _numberOfPageNavigations = 0;
|
private _numberOfPageNavigations = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(BOOTSTRAP_SERVICE_ID) private _bootstrapService: IBootstrapService,
|
@Inject(BOOTSTRAP_SERVICE_ID) bootstrapService: IBootstrapService,
|
||||||
@Inject(forwardRef(() => Router)) private _router: Router,
|
@Inject(forwardRef(() => Router)) private _router: Router,
|
||||||
) {
|
) {
|
||||||
super();
|
super(bootstrapService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get notificationService(): INotificationService {
|
public get dashboardViewService(): IDashboardViewService {
|
||||||
return this._notificationService;
|
return this._dashboardViewService;
|
||||||
}
|
|
||||||
|
|
||||||
public get configurationEditingService(): ConfigurationEditingService {
|
|
||||||
return this._configurationEditingService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get metadataService(): SingleConnectionMetadataService {
|
|
||||||
return this._metadataService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get connectionManagementService(): SingleConnectionManagementService {
|
|
||||||
return this._connectionManagementService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get commandService(): ICommandService {
|
|
||||||
return this._commandService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get themeService(): IWorkbenchThemeService {
|
|
||||||
return this._themeService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get contextMenuService(): IContextMenuService {
|
|
||||||
return this._contextMenuService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get instantiationService(): IInstantiationService {
|
|
||||||
return this._instantiationService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get dashboardWebviewService(): IDashboardWebviewService {
|
|
||||||
return this._dashboardWebviewService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get partService(): IPartService {
|
|
||||||
return this._partService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get contextKeyService(): IContextKeyService {
|
|
||||||
return this._contextKeyService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get adminService(): SingleAdminService {
|
|
||||||
return this._adminService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get queryManagementService(): SingleQueryManagementService {
|
|
||||||
return this._queryManagementService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get environmentService(): IEnvironmentService {
|
|
||||||
return this._environmentService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get contextViewService(): IContextViewService {
|
|
||||||
return this._contextViewService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get workspaceContextService(): IWorkspaceContextService {
|
|
||||||
return this._workspaceContextService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get storageService(): IStorageService {
|
|
||||||
return this._storageService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get capabilitiesService(): ICapabilitiesService {
|
|
||||||
return this._capabilitiesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get angularEventingService(): IAngularEventingService {
|
|
||||||
return this._angularEventingService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -263,7 +106,7 @@ export class DashboardServiceInterface extends AngularDisposable {
|
|||||||
this._getbootstrapParams();
|
this._getbootstrapParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getbootstrapParams(): void {
|
protected _getbootstrapParams(): void {
|
||||||
this._bootstrapParams = this._bootstrapService.getBootstrapParams<DashboardComponentParams>(this._uniqueSelector);
|
this._bootstrapParams = this._bootstrapService.getBootstrapParams<DashboardComponentParams>(this._uniqueSelector);
|
||||||
this._contextKeyService = this._bootstrapParams.scopedContextService;
|
this._contextKeyService = this._bootstrapParams.scopedContextService;
|
||||||
this._connectionContextKey = this._bootstrapParams.connectionContextKey;
|
this._connectionContextKey = this._bootstrapParams.connectionContextKey;
|
||||||
@@ -275,27 +118,11 @@ export class DashboardServiceInterface extends AngularDisposable {
|
|||||||
* Set the uri for this dashboard instance, should only be set once
|
* Set the uri for this dashboard instance, should only be set once
|
||||||
* Inits all the services that depend on knowing a uri
|
* Inits all the services that depend on knowing a uri
|
||||||
*/
|
*/
|
||||||
private set uri(uri: string) {
|
protected set uri(uri: string) {
|
||||||
this._uri = uri;
|
super.setUri(uri);
|
||||||
this._metadataService = new SingleConnectionMetadataService(this._bootstrapService.metadataService, this._uri);
|
|
||||||
this._connectionManagementService = new SingleConnectionManagementService(this._bootstrapService.connectionManagementService, this._uri, this._connectionContextKey);
|
|
||||||
this._adminService = new SingleAdminService(this._bootstrapService.adminService, this._uri);
|
|
||||||
this._queryManagementService = new SingleQueryManagementService(this._bootstrapService.queryManagementService, this._uri);
|
|
||||||
this._register(toDisposableSubscription(this._bootstrapService.angularEventingService.onAngularEvent(this._uri, (event) => this.handleDashboardEvent(event))));
|
this._register(toDisposableSubscription(this._bootstrapService.angularEventingService.onAngularEvent(this._uri, (event) => this.handleDashboardEvent(event))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the underlying Uri for dashboard
|
|
||||||
* In general don't use this, use specific services instances exposed publically
|
|
||||||
*/
|
|
||||||
public getUnderlyingUri(): string {
|
|
||||||
return this._uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getOriginalConnectionProfile(): IConnectionProfile {
|
|
||||||
return this._bootstrapParams.connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the number of page navigation
|
* Gets the number of page navigation
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { Router } from '@angular/router';
|
|||||||
|
|
||||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||||
import { MetadataType } from 'sql/parts/connection/common/connectionManagement';
|
import { MetadataType } from 'sql/parts/connection/common/connectionManagement';
|
||||||
import { SingleConnectionManagementService } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { SingleConnectionManagementService } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import {
|
import {
|
||||||
NewQueryAction, ScriptSelectAction, EditDataAction, ScriptCreateAction, ScriptExecuteAction, ScriptAlterAction,
|
NewQueryAction, ScriptSelectAction, EditDataAction, ScriptCreateAction, ScriptExecuteAction, ScriptAlterAction,
|
||||||
BackupAction, ManageActionContext, BaseActionContext, ManageAction, RestoreAction
|
BackupAction, ManageActionContext, BaseActionContext, ManageAction, RestoreAction
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { Router } from '@angular/router';
|
|||||||
|
|
||||||
import { DashboardWidget, IDashboardWidget, WidgetConfig, WIDGET_CONFIG } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { DashboardWidget, IDashboardWidget, WidgetConfig, WIDGET_CONFIG } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { toDisposableSubscription } from 'sql/parts/common/rxjsUtils';
|
import { toDisposableSubscription } from 'sql/parts/common/rxjsUtils';
|
||||||
import { ExplorerFilter, ExplorerRenderer, ExplorerDataSource, ExplorerController, ObjectMetadataWrapper, ExplorerModel } from './explorerTree';
|
import { ExplorerFilter, ExplorerRenderer, ExplorerDataSource, ExplorerController, ObjectMetadataWrapper, ExplorerModel } from './explorerTree';
|
||||||
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
||||||
@@ -49,7 +50,7 @@ export class ExplorerWidget extends DashboardWidget implements IDashboardWidget,
|
|||||||
@ViewChild('table') private _tableContainer: ElementRef;
|
@ViewChild('table') private _tableContainer: ElementRef;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) private _bootstrap: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrap: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => Router)) private _router: Router,
|
@Inject(forwardRef(() => Router)) private _router: Router,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||||
@Inject(WIDGET_CONFIG) protected _config: WidgetConfig,
|
@Inject(WIDGET_CONFIG) protected _config: WidgetConfig,
|
||||||
@@ -62,8 +63,11 @@ export class ExplorerWidget extends DashboardWidget implements IDashboardWidget,
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this._inited = true;
|
this._inited = true;
|
||||||
|
|
||||||
|
let placeholderLabel = this._config.context === 'database' ? nls.localize('seachObjects', 'Search by name of type (a:, t:, v:, f:, or sp:)') : nls.localize('searchDatabases', 'Search databases');
|
||||||
|
|
||||||
let inputOptions: IInputOptions = {
|
let inputOptions: IInputOptions = {
|
||||||
placeholder: this._config.context === 'database' ? nls.localize('seachObjects', 'Search by name of type (a:, t:, v:, f:, or sp:)') : nls.localize('searchDatabases', 'Search databases')
|
placeholder: placeholderLabel,
|
||||||
|
ariaLabel: placeholderLabel
|
||||||
};
|
};
|
||||||
this._input = new InputBox(this._inputContainer.nativeElement, this._bootstrap.contextViewService, inputOptions);
|
this._input = new InputBox(this._inputContainer.nativeElement, this._bootstrap.contextViewService, inputOptions);
|
||||||
this._register(this._input.onDidChange(e => {
|
this._register(this._input.onDidChange(e => {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { Observable } from 'rxjs/Observable';
|
|||||||
|
|
||||||
import { DashboardWidget, IDashboardWidget, WIDGET_CONFIG, WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { DashboardWidget, IDashboardWidget, WIDGET_CONFIG, WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { ComponentHostDirective } from 'sql/parts/dashboard/common/componentHost.directive';
|
import { ComponentHostDirective } from 'sql/parts/dashboard/common/componentHost.directive';
|
||||||
import { InsightAction, InsightActionContext } from 'sql/workbench/common/actions';
|
import { InsightAction, InsightActionContext } from 'sql/workbench/common/actions';
|
||||||
import { toDisposableSubscription } from 'sql/parts/common/rxjsUtils';
|
import { toDisposableSubscription } from 'sql/parts/common/rxjsUtils';
|
||||||
@@ -26,6 +27,7 @@ import * as pfs from 'vs/base/node/pfs';
|
|||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
import { WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
import { WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||||
|
import { IntervalTimer } from 'vs/base/common/async';
|
||||||
|
|
||||||
const insightRegistry = Registry.as<IInsightRegistry>(Extensions.InsightContribution);
|
const insightRegistry = Registry.as<IInsightRegistry>(Extensions.InsightContribution);
|
||||||
|
|
||||||
@@ -51,13 +53,14 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget,
|
|||||||
|
|
||||||
private _typeKey: string;
|
private _typeKey: string;
|
||||||
private _init: boolean = false;
|
private _init: boolean = false;
|
||||||
|
private _intervalTimer: IntervalTimer;
|
||||||
|
|
||||||
public error: string;
|
public error: string;
|
||||||
public lastUpdated: string;
|
public lastUpdated: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ComponentFactoryResolver)) private _componentFactoryResolver: ComponentFactoryResolver,
|
@Inject(forwardRef(() => ComponentFactoryResolver)) private _componentFactoryResolver: ComponentFactoryResolver,
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) private dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private dashboardService: CommonServiceInterface,
|
||||||
@Inject(WIDGET_CONFIG) protected _config: WidgetConfig,
|
@Inject(WIDGET_CONFIG) protected _config: WidgetConfig,
|
||||||
@Inject(forwardRef(() => ViewContainerRef)) private viewContainerRef: ViewContainerRef,
|
@Inject(forwardRef(() => ViewContainerRef)) private viewContainerRef: ViewContainerRef,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef
|
||||||
@@ -75,6 +78,7 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget,
|
|||||||
result => {
|
result => {
|
||||||
if (this._init) {
|
if (this._init) {
|
||||||
this._updateChild(result);
|
this._updateChild(result);
|
||||||
|
this.setupInterval();
|
||||||
} else {
|
} else {
|
||||||
this.queryObv = Observable.fromPromise(Promise.resolve<SimpleExecuteResult>(result));
|
this.queryObv = Observable.fromPromise(Promise.resolve<SimpleExecuteResult>(result));
|
||||||
}
|
}
|
||||||
@@ -99,6 +103,7 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget,
|
|||||||
this._register(toDisposableSubscription(this.queryObv.subscribe(
|
this._register(toDisposableSubscription(this.queryObv.subscribe(
|
||||||
result => {
|
result => {
|
||||||
this._updateChild(result);
|
this._updateChild(result);
|
||||||
|
this.setupInterval();
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this.showError(error);
|
this.showError(error);
|
||||||
@@ -107,6 +112,14 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setupInterval(): void {
|
||||||
|
if (this.insightConfig.autoRefreshInterval) {
|
||||||
|
this._intervalTimer = new IntervalTimer();
|
||||||
|
this._register(this._intervalTimer);
|
||||||
|
this._intervalTimer.cancelAndSet(() => this.refresh(), this.insightConfig.autoRefreshInterval * 60 * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private showError(error: string): void {
|
private showError(error: string): void {
|
||||||
this.error = error;
|
this.error = error;
|
||||||
this._cd.detectChanges();
|
this._cd.detectChanges();
|
||||||
@@ -151,6 +164,7 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget,
|
|||||||
this.lastUpdated = nls.localize('insights.lastUpdated', "Last Updated: {0} {1}", date.toLocaleTimeString(), date.toLocaleDateString());
|
this.lastUpdated = nls.localize('insights.lastUpdated', "Last Updated: {0} {1}", date.toLocaleTimeString(), date.toLocaleDateString());
|
||||||
if (this._init) {
|
if (this._init) {
|
||||||
this._updateChild(storedResult.results);
|
this._updateChild(storedResult.results);
|
||||||
|
this.setupInterval();
|
||||||
this._cd.detectChanges();
|
this._cd.detectChanges();
|
||||||
} else {
|
} else {
|
||||||
this.queryObv = Observable.fromPromise(Promise.resolve<SimpleExecuteResult>(JSON.parse(storage)));
|
this.queryObv = Observable.fromPromise(Promise.resolve<SimpleExecuteResult>(JSON.parse(storage)));
|
||||||
@@ -230,6 +244,10 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget,
|
|||||||
throw new Error('No query was specified for this insight');
|
throw new Error('No query was specified for this insight');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.insightConfig.autoRefreshInterval && !types.isNumber(this.insightConfig.autoRefreshInterval)) {
|
||||||
|
throw new Error('Auto Refresh Interval must be a number if specified');
|
||||||
|
}
|
||||||
|
|
||||||
if (!types.isStringArray(this.insightConfig.query)
|
if (!types.isStringArray(this.insightConfig.query)
|
||||||
&& !types.isString(this.insightConfig.query)
|
&& !types.isString(this.insightConfig.query)
|
||||||
&& !types.isString(this.insightConfig.queryFile)) {
|
&& !types.isString(this.insightConfig.queryFile)) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { join } from 'path';
|
|||||||
|
|
||||||
import { registerDashboardWidget, registerNonCustomDashboardWidget } from 'sql/platform/dashboard/common/widgetRegistry';
|
import { registerDashboardWidget, registerNonCustomDashboardWidget } from 'sql/platform/dashboard/common/widgetRegistry';
|
||||||
import { Extensions as InsightExtensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
import { Extensions as InsightExtensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
||||||
import { IInsightsConfig } from './interfaces';
|
import { IInsightsConfig, IInsightTypeContrib } from './interfaces';
|
||||||
import { insightsContribution, insightsSchema } from 'sql/parts/dashboard/widgets/insights/insightsWidgetSchemas';
|
import { insightsContribution, insightsSchema } from 'sql/parts/dashboard/widgets/insights/insightsWidgetSchemas';
|
||||||
|
|
||||||
import { IExtensionPointUser, ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
import { IExtensionPointUser, ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||||
@@ -14,10 +14,6 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
|||||||
|
|
||||||
const insightRegistry = Registry.as<IInsightRegistry>(InsightExtensions.InsightContribution);
|
const insightRegistry = Registry.as<IInsightRegistry>(InsightExtensions.InsightContribution);
|
||||||
|
|
||||||
interface IInsightTypeContrib {
|
|
||||||
id: string;
|
|
||||||
contrib: IInsightsConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
registerDashboardWidget('insights-widget', '', insightsSchema);
|
registerDashboardWidget('insights-widget', '', insightsSchema);
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ export const insightsSchema: IJSONSchema = {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
description: nls.localize('insightQueryFileDescription', '[Optional] path to a file that contains a query. Use if "query" is not set')
|
description: nls.localize('insightQueryFileDescription', '[Optional] path to a file that contains a query. Use if "query" is not set')
|
||||||
},
|
},
|
||||||
|
autoRefreshInterval: {
|
||||||
|
type: 'number',
|
||||||
|
description: nls.localize('insightAutoRefreshIntervalDescription', '[Optional] Auto refresh interval in minutes, if not set, there will be no auto refresh')
|
||||||
|
},
|
||||||
details: {
|
details: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
@@ -93,15 +97,15 @@ export const insightsSchema: IJSONSchema = {
|
|||||||
},
|
},
|
||||||
database: {
|
database: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: nls.localize('actionDatabaseDescription', 'Target database for the action; can use the format "${columnName} to use a data driven column name.')
|
description: nls.localize('actionDatabaseDescription', 'Target database for the action; can use the format "${columnName}" to use a data driven column name.')
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: nls.localize('actionServerDescription', 'Target server for the action; can use the format "${columnName} to use a data driven column name.')
|
description: nls.localize('actionServerDescription', 'Target server for the action; can use the format "${columnName}" to use a data driven column name.')
|
||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: nls.localize('actionUserDescription', 'Target user for the action; can use the format "${columnName} to use a data driven column name.')
|
description: nls.localize('actionUserDescription', 'Target user for the action; can use the format "${columnName}" to use a data driven column name.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,4 +56,9 @@ export interface IInsightsConfig {
|
|||||||
query?: string | Array<string>;
|
query?: string | Array<string>;
|
||||||
queryFile?: string;
|
queryFile?: string;
|
||||||
details?: IInsightsConfigDetails;
|
details?: IInsightsConfigDetails;
|
||||||
|
autoRefreshInterval?: number;
|
||||||
|
}
|
||||||
|
export interface IInsightTypeContrib {
|
||||||
|
id: string;
|
||||||
|
contrib: IInsightsConfig;
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,7 @@ import { Color } from 'vs/base/common/color';
|
|||||||
import * as types from 'vs/base/common/types';
|
import * as types from 'vs/base/common/types';
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
import { IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||||
|
import * as nls from 'vs/nls';
|
||||||
|
|
||||||
export enum ChartType {
|
export enum ChartType {
|
||||||
Bar = 'bar',
|
Bar = 'bar',
|
||||||
@@ -79,6 +80,7 @@ export interface IChartConfig {
|
|||||||
legendPosition?: LegendPosition;
|
legendPosition?: LegendPosition;
|
||||||
dataDirection?: DataDirection;
|
dataDirection?: DataDirection;
|
||||||
columnsAsLabels?: boolean;
|
columnsAsLabels?: boolean;
|
||||||
|
showTopNData?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultChartConfig: IChartConfig = {
|
export const defaultChartConfig: IChartConfig = {
|
||||||
@@ -97,11 +99,13 @@ export const defaultChartConfig: IChartConfig = {
|
|||||||
[chartType]="chartType"
|
[chartType]="chartType"
|
||||||
[colors]="colors"
|
[colors]="colors"
|
||||||
[options]="_options"></canvas>
|
[options]="_options"></canvas>
|
||||||
|
<div *ngIf="_hasError">{{CHART_ERROR_MESSAGE}}</div>
|
||||||
</div>`
|
</div>`
|
||||||
})
|
})
|
||||||
export abstract class ChartInsight extends Disposable implements IInsightsView {
|
export abstract class ChartInsight extends Disposable implements IInsightsView {
|
||||||
private _isDataAvailable: boolean = false;
|
private _isDataAvailable: boolean = false;
|
||||||
private _hasInit: boolean = false;
|
private _hasInit: boolean = false;
|
||||||
|
private _hasError: boolean = false;
|
||||||
private _options: any = {};
|
private _options: any = {};
|
||||||
|
|
||||||
@ViewChild(BaseChartDirective) private _chart: BaseChartDirective;
|
@ViewChild(BaseChartDirective) private _chart: BaseChartDirective;
|
||||||
@@ -110,6 +114,8 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
|||||||
protected _config: IChartConfig;
|
protected _config: IChartConfig;
|
||||||
protected _data: IInsightData;
|
protected _data: IInsightData;
|
||||||
|
|
||||||
|
private readonly CHART_ERROR_MESSAGE = nls.localize('chartErrorMessage', 'Chart cannot be displayed with the given data');
|
||||||
|
|
||||||
protected abstract get chartType(): ChartType;
|
protected abstract get chartType(): ChartType;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -128,7 +134,14 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
|||||||
// hence it's easier to not render until ready
|
// hence it's easier to not render until ready
|
||||||
this.options = mixin(this.options, { maintainAspectRatio: false });
|
this.options = mixin(this.options, { maintainAspectRatio: false });
|
||||||
this._hasInit = true;
|
this._hasInit = true;
|
||||||
this._changeRef.detectChanges();
|
this._hasError = false;
|
||||||
|
try {
|
||||||
|
this._changeRef.detectChanges();
|
||||||
|
} catch (err) {
|
||||||
|
this._hasInit = false;
|
||||||
|
this._hasError = true;
|
||||||
|
this._changeRef.detectChanges();
|
||||||
|
}
|
||||||
TelemetryUtils.addTelemetry(this._bootstrapService.telemetryService, TelemetryKeys.ChartCreated, { type: this.chartType });
|
TelemetryUtils.addTelemetry(this._bootstrapService.telemetryService, TelemetryKeys.ChartCreated, { type: this.chartType });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +192,7 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
|||||||
// unmemoize chart data as the data needs to be recalced
|
// unmemoize chart data as the data needs to be recalced
|
||||||
unmemoize(this, 'chartData');
|
unmemoize(this, 'chartData');
|
||||||
unmemoize(this, 'labels');
|
unmemoize(this, 'labels');
|
||||||
this._data = data;
|
this._data = this.filterToTopNData(data);
|
||||||
if (isValidData(data)) {
|
if (isValidData(data)) {
|
||||||
this._isDataAvailable = true;
|
this._isDataAvailable = true;
|
||||||
}
|
}
|
||||||
@@ -187,6 +200,34 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
|||||||
this._changeRef.detectChanges();
|
this._changeRef.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private filterToTopNData(data: IInsightData): IInsightData {
|
||||||
|
if (this._config.dataDirection === 'horizontal') {
|
||||||
|
return {
|
||||||
|
columns: this.getTopNData(data.columns),
|
||||||
|
rows: data.rows.map((row) => {
|
||||||
|
return this.getTopNData(row);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
columns: data.columns,
|
||||||
|
rows: data.rows.slice(0, this._config.showTopNData)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getTopNData(data: any[]): any[] {
|
||||||
|
if (this._config.showTopNData) {
|
||||||
|
if (this._config.dataDirection === 'horizontal' && this._config.labelFirstColumn) {
|
||||||
|
return data.slice(0, this._config.showTopNData + 1);
|
||||||
|
} else {
|
||||||
|
return data.slice(0, this._config.showTopNData);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected clearMemoize(): void {
|
protected clearMemoize(): void {
|
||||||
// unmemoize getters since their result can be changed by a new config
|
// unmemoize getters since their result can be changed by a new config
|
||||||
unmemoize(this, 'getChartData');
|
unmemoize(this, 'getChartData');
|
||||||
@@ -226,17 +267,17 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this._config.columnsAsLabels) {
|
if (this._config.columnsAsLabels) {
|
||||||
return this._data.rows[0].map((row, i) => {
|
return this._data.rows[0].slice(1).map((row, i) => {
|
||||||
return {
|
return {
|
||||||
data: this._data.rows.map(row => Number(row[i])),
|
data: this._data.rows.map(row => Number(row[i + 1])),
|
||||||
label: this._data.columns[i]
|
label: this._data.columns[i + 1]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return this._data.rows[0].map((row, i) => {
|
return this._data.rows[0].slice(1).map((row, i) => {
|
||||||
return {
|
return {
|
||||||
data: this._data.rows.map(row => Number(row[i])),
|
data: this._data.rows.map(row => Number(row[i + 1])),
|
||||||
label: 'Series' + i
|
label: 'Series' + (i + 1)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -250,7 +291,11 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
|||||||
@memoize
|
@memoize
|
||||||
public getLabels(): Array<string> {
|
public getLabels(): Array<string> {
|
||||||
if (this._config.dataDirection === 'horizontal') {
|
if (this._config.dataDirection === 'horizontal') {
|
||||||
return this._data.columns;
|
if (this._config.labelFirstColumn) {
|
||||||
|
return this._data.columns.slice(1);
|
||||||
|
} else {
|
||||||
|
return this._data.columns;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return this._data.rows.map(row => row[0]);
|
return this._data.rows.map(row => row[0]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ export const chartInsightSchema: IJSONSchema = {
|
|||||||
default: 'vertical',
|
default: 'vertical',
|
||||||
enum: ['vertical', 'horizontal'],
|
enum: ['vertical', 'horizontal'],
|
||||||
enumDescriptions: ['When vertical, the first column is used to define the x-axis labels, with other columns expected to be numerical.', 'When horizontal, the column names are used as the x-axis labels.']
|
enumDescriptions: ['When vertical, the first column is used to define the x-axis labels, with other columns expected to be numerical.', 'When horizontal, the column names are used as the x-axis labels.']
|
||||||
|
},
|
||||||
|
showTopNData: {
|
||||||
|
type: 'number',
|
||||||
|
description: nls.localize('showTopNData', 'If showTopNData is set, showing only top N data in the chart.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -12,7 +12,7 @@ import { chartInsightSchema } from 'sql/parts/dashboard/widgets/insights/views/c
|
|||||||
|
|
||||||
import BarChart from './barChart.component';
|
import BarChart from './barChart.component';
|
||||||
|
|
||||||
export const properties: IJSONSchema = {
|
const properties: IJSONSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
yAxisMin: {
|
yAxisMin: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
@@ -41,6 +41,6 @@ export const properties: IJSONSchema = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const barSchema = mixin(clone(chartInsightSchema), properties) as IJSONSchema;
|
export const barChartSchema = mixin(clone(chartInsightSchema), properties) as IJSONSchema;
|
||||||
|
|
||||||
registerInsight('bar', '', barSchema, BarChart);
|
registerInsight('bar', '', barChartSchema, BarChart);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { mixin } from 'vs/base/common/objects';
|
|||||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||||
|
|
||||||
import { registerInsight } from 'sql/platform/dashboard/common/insightRegistry';
|
import { registerInsight } from 'sql/platform/dashboard/common/insightRegistry';
|
||||||
import { properties as BarChartSchema } from 'sql/parts/dashboard/widgets/insights/views/charts/types/barChart.contribution';
|
import { barChartSchema } from 'sql/parts/dashboard/widgets/insights/views/charts/types/barChart.contribution';
|
||||||
|
|
||||||
import HorizontalBarChart from './horizontalBarChart.component';
|
import HorizontalBarChart from './horizontalBarChart.component';
|
||||||
|
|
||||||
@@ -15,6 +15,6 @@ const properties: IJSONSchema = {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const horizontalBarSchema = mixin(clone(BarChartSchema), properties) as IJSONSchema;
|
const horizontalBarSchema = mixin(clone(barChartSchema), properties) as IJSONSchema;
|
||||||
|
|
||||||
registerInsight('horizontalBar', '', horizontalBarSchema, HorizontalBarChart);
|
registerInsight('horizontalBar', '', horizontalBarSchema, HorizontalBarChart);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
|||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
|
|
||||||
import { registerInsight } from 'sql/platform/dashboard/common/insightRegistry';
|
import { registerInsight } from 'sql/platform/dashboard/common/insightRegistry';
|
||||||
import { properties as BarChartSchema } from 'sql/parts/dashboard/widgets/insights/views/charts/types/barChart.contribution';
|
import { barChartSchema } from 'sql/parts/dashboard/widgets/insights/views/charts/types/barChart.contribution';
|
||||||
|
|
||||||
import LineChart from './lineChart.component';
|
import LineChart from './lineChart.component';
|
||||||
|
|
||||||
@@ -24,6 +24,6 @@ const properties: IJSONSchema = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const lineSchema = mixin(clone(BarChartSchema), properties) as IJSONSchema;
|
export const lineSchema = mixin(clone(barChartSchema), properties) as IJSONSchema;
|
||||||
|
|
||||||
registerInsight('line', '', lineSchema, LineChart);
|
registerInsight('line', '', lineSchema, LineChart);
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ import { clone } from 'sql/base/common/objects';
|
|||||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||||
|
|
||||||
import { registerInsight } from 'sql/platform/dashboard/common/insightRegistry';
|
import { registerInsight } from 'sql/platform/dashboard/common/insightRegistry';
|
||||||
import { properties as BarChartSchema } from 'sql/parts/dashboard/widgets/insights/views/charts/types/barChart.contribution';
|
import { barChartSchema } from 'sql/parts/dashboard/widgets/insights/views/charts/types/barChart.contribution';
|
||||||
|
|
||||||
import ScatterChart from './scatterChart.component';
|
import ScatterChart from './scatterChart.component';
|
||||||
|
|
||||||
const properties: IJSONSchema = {
|
const properties: IJSONSchema = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const scatterSchema = mixin(clone(BarChartSchema), properties) as IJSONSchema;
|
const scatterSchema = mixin(clone(barChartSchema), properties) as IJSONSchema;
|
||||||
|
|
||||||
registerInsight('scatter', '', scatterSchema, ScatterChart);
|
registerInsight('scatter', '', scatterSchema, ScatterChart);
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ import { clone } from 'sql/base/common/objects';
|
|||||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||||
|
|
||||||
import { registerInsight } from 'sql/platform/dashboard/common/insightRegistry';
|
import { registerInsight } from 'sql/platform/dashboard/common/insightRegistry';
|
||||||
import { properties as BarChartSchema } from 'sql/parts/dashboard/widgets/insights/views/charts/types/barChart.contribution';
|
import { barChartSchema } from 'sql/parts/dashboard/widgets/insights/views/charts/types/barChart.contribution';
|
||||||
|
|
||||||
import TimeSeriesChart from './timeSeriesChart.component';
|
import TimeSeriesChart from './timeSeriesChart.component';
|
||||||
|
|
||||||
const properties: IJSONSchema = {
|
const properties: IJSONSchema = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const timeSeriesSchema = mixin(clone(BarChartSchema), properties) as IJSONSchema;
|
const timeSeriesSchema = mixin(clone(barChartSchema), properties) as IJSONSchema;
|
||||||
|
|
||||||
registerInsight('timeSeries', '', timeSeriesSchema, TimeSeriesChart);
|
registerInsight('timeSeries', '', timeSeriesSchema, TimeSeriesChart);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const defaultConfig: IConfig = {
|
|||||||
})
|
})
|
||||||
export default class ImageInsight implements IInsightsView, OnInit {
|
export default class ImageInsight implements IInsightsView, OnInit {
|
||||||
private _rawSource: string;
|
private _rawSource: string;
|
||||||
private _config: IConfig;
|
private _config: IConfig = defaultConfig;
|
||||||
|
|
||||||
@ViewChild('image') private image: ElementRef;
|
@ViewChild('image') private image: ElementRef;
|
||||||
@ViewChild('container') private container: ElementRef;
|
@ViewChild('container') private container: ElementRef;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { Component, Inject, forwardRef, ChangeDetectorRef, OnInit, ElementRef, V
|
|||||||
|
|
||||||
import { DashboardWidget, IDashboardWidget, WidgetConfig, WIDGET_CONFIG } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { DashboardWidget, IDashboardWidget, WidgetConfig, WIDGET_CONFIG } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { ConnectionManagementInfo } from 'sql/parts/connection/common/connectionManagementInfo';
|
import { ConnectionManagementInfo } from 'sql/parts/connection/common/connectionManagementInfo';
|
||||||
import { toDisposableSubscription } from 'sql/parts/common/rxjsUtils';
|
import { toDisposableSubscription } from 'sql/parts/common/rxjsUtils';
|
||||||
import { error } from 'sql/base/common/log';
|
import { error } from 'sql/base/common/log';
|
||||||
@@ -68,7 +69,7 @@ export class PropertiesWidgetComponent extends DashboardWidget implements IDashb
|
|||||||
@ViewChild('parent', { read: ElementRef }) private _parent: ElementRef;
|
@ViewChild('parent', { read: ElementRef }) private _parent: ElementRef;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) private _bootstrap: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrap: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef,
|
||||||
@Inject(WIDGET_CONFIG) protected _config: WidgetConfig,
|
@Inject(WIDGET_CONFIG) protected _config: WidgetConfig,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { DomSanitizer } from '@angular/platform-browser';
|
|||||||
/* SQL imports */
|
/* SQL imports */
|
||||||
import { DashboardWidget, IDashboardWidget, WidgetConfig, WIDGET_CONFIG } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { DashboardWidget, IDashboardWidget, WidgetConfig, WIDGET_CONFIG } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
import { TaskRegistry } from 'sql/platform/tasks/common/tasks';
|
import { TaskRegistry } from 'sql/platform/tasks/common/tasks';
|
||||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||||
import { BaseActionContext } from 'sql/workbench/common/actions';
|
import { BaseActionContext } from 'sql/workbench/common/actions';
|
||||||
@@ -51,13 +52,14 @@ export class TasksWidget extends DashboardWidget implements IDashboardWidget, On
|
|||||||
private _profile: IConnectionProfile;
|
private _profile: IConnectionProfile;
|
||||||
private _scrollableElement: ScrollableElement;
|
private _scrollableElement: ScrollableElement;
|
||||||
private $container: Builder;
|
private $container: Builder;
|
||||||
|
static readonly ICON_PATH_TO_CSS_RULES: Map<string /* path*/, string /* CSS rule */> = new Map<string, string>();
|
||||||
|
|
||||||
private _inited = false;
|
private _inited = false;
|
||||||
|
|
||||||
@ViewChild('container', { read: ElementRef }) private _container: ElementRef;
|
@ViewChild('container', { read: ElementRef }) private _container: ElementRef;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) private _bootstrap: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrap: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => DomSanitizer)) private _sanitizer: DomSanitizer,
|
@Inject(forwardRef(() => DomSanitizer)) private _sanitizer: DomSanitizer,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeref: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeref: ChangeDetectorRef,
|
||||||
@Inject(WIDGET_CONFIG) protected _config: WidgetConfig
|
@Inject(WIDGET_CONFIG) protected _config: WidgetConfig
|
||||||
@@ -130,9 +132,9 @@ export class TasksWidget extends DashboardWidget implements IDashboardWidget, On
|
|||||||
let tile = $('div.task-tile').style('height', this._size + 'px').style('width', this._size + 'px');
|
let tile = $('div.task-tile').style('height', this._size + 'px').style('width', this._size + 'px');
|
||||||
let innerTile = $('div');
|
let innerTile = $('div');
|
||||||
|
|
||||||
// @SQLTODO - iconPath shouldn't be used as a CSS class
|
let iconClassName = TaskRegistry.getOrCreateTaskIconClassName(action);
|
||||||
if (action.iconPath && action.iconPath.dark) {
|
if (iconClassName) {
|
||||||
let icon = $('span.icon').addClass(action.iconPath.dark);
|
let icon = $('span.icon').addClass(iconClassName);
|
||||||
innerTile.append(icon);
|
innerTile.append(icon);
|
||||||
}
|
}
|
||||||
innerTile.append(label);
|
innerTile.append(label);
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ import { memoize } from 'vs/base/common/decorators';
|
|||||||
|
|
||||||
import { DashboardWidget, IDashboardWidget, WidgetConfig, WIDGET_CONFIG } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { DashboardWidget, IDashboardWidget, WidgetConfig, WIDGET_CONFIG } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
import { IDashboardWebview } from 'sql/services/dashboardWebview/common/dashboardWebviewService';
|
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
|
||||||
|
import { IDashboardWebview } from 'sql/services/dashboard/common/dashboardViewService';
|
||||||
|
|
||||||
import * as sqlops from 'sqlops';
|
import * as sqlops from 'sqlops';
|
||||||
|
|
||||||
@@ -35,19 +36,21 @@ export class WebviewWidget extends DashboardWidget implements IDashboardWidget,
|
|||||||
private _onMessage = new Emitter<string>();
|
private _onMessage = new Emitter<string>();
|
||||||
public readonly onMessage: Event<string> = this._onMessage.event;
|
public readonly onMessage: Event<string> = this._onMessage.event;
|
||||||
private _onMessageDisposable: IDisposable;
|
private _onMessageDisposable: IDisposable;
|
||||||
|
private _dashboardService: DashboardServiceInterface;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) private _dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private commonService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||||
@Inject(WIDGET_CONFIG) protected _config: WidgetConfig,
|
@Inject(WIDGET_CONFIG) protected _config: WidgetConfig,
|
||||||
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef
|
@Inject(forwardRef(() => ElementRef)) private _el: ElementRef
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._id = (_config.widget[selector] as IWebviewWidgetConfig).id;
|
this._id = (_config.widget[selector] as IWebviewWidgetConfig).id;
|
||||||
|
this._dashboardService = commonService as DashboardServiceInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this._dashboardService.dashboardWebviewService.registerWebview(this);
|
this._dashboardService.dashboardViewService.registerWebview(this);
|
||||||
this._createWebview();
|
this._createWebview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,24 +8,24 @@
|
|||||||
<div class="angular-modal-body" style="display: flex; flex-direction: column;">
|
<div class="angular-modal-body" style="display: flex; flex-direction: column;">
|
||||||
<div class="angular-modal-body-content">
|
<div class="angular-modal-body-content">
|
||||||
<div class="dialog-label">
|
<div class="dialog-label">
|
||||||
{{backupNameLabel}}
|
{{localizedStrings.BACKUP_NAME}}
|
||||||
</div>
|
</div>
|
||||||
<div class="input-divider" #backupsetName>
|
<div class="input-divider" #backupsetName>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-label">
|
<div class="dialog-label">
|
||||||
{{recoveryModelLabel}}
|
{{localizedStrings.RECOVERY_MODEL}}
|
||||||
</div>
|
</div>
|
||||||
<div class="input-divider" #recoveryModelContainer>
|
<div class="input-divider" #recoveryModelContainer>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-label">
|
<div class="dialog-label">
|
||||||
{{backupTypeLabel}}
|
{{localizedStrings.BACKUP_TYPE}}
|
||||||
</div>
|
</div>
|
||||||
<div class="input-divider" #backupTypeContainer>
|
<div class="input-divider" #backupTypeContainer>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-divider check" #copyOnlyContainer>
|
<div class="input-divider check" #copyOnlyContainer>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-label">
|
<div class="dialog-label">
|
||||||
{{backupDeviceLabel}}
|
{{localizedStrings.BACKUP_DEVICE}}
|
||||||
</div>
|
</div>
|
||||||
<div class="backup-path-list">
|
<div class="backup-path-list">
|
||||||
<div #pathContainer>
|
<div #pathContainer>
|
||||||
@@ -47,11 +47,11 @@
|
|||||||
<div class="advanced-main-body" #advancedOptionBodyContainer>
|
<div class="advanced-main-body" #advancedOptionBodyContainer>
|
||||||
<!-- Compression -->
|
<!-- Compression -->
|
||||||
<div class="dialog-label advanced-header">
|
<div class="dialog-label advanced-header">
|
||||||
{{compressionLabel}}
|
{{localizedStrings.COMPRESSION}}
|
||||||
</div>
|
</div>
|
||||||
<div class="indent">
|
<div class="indent">
|
||||||
<div class="dialog-label">
|
<div class="dialog-label">
|
||||||
{{setBackupCompressionLabel}}
|
{{localizedStrings.SET_BACKUP_COMPRESSION}}
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-label" #compressionContainer>
|
<div class="dialog-label" #compressionContainer>
|
||||||
</div>
|
</div>
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
<!-- Encryption -->
|
<!-- Encryption -->
|
||||||
<div class="dialog-label advanced-header">
|
<div class="dialog-label advanced-header">
|
||||||
{{encryptionLabel}}
|
{{localizedStrings.ENCRYPTION}}
|
||||||
</div>
|
</div>
|
||||||
<div class="indent">
|
<div class="indent">
|
||||||
<div class="option check" #encryptCheckContainer>
|
<div class="option check" #encryptCheckContainer>
|
||||||
@@ -68,17 +68,17 @@
|
|||||||
<div class="icon warning">
|
<div class="icon warning">
|
||||||
</div>
|
</div>
|
||||||
<div class="warning-message">
|
<div class="warning-message">
|
||||||
{{noEncryptorWarning}}
|
{{localizedStrings.NO_ENCRYPTOR_WARNING}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div #encryptContainer>
|
<div #encryptContainer>
|
||||||
<div class="dialog-label">
|
<div class="dialog-label">
|
||||||
{{algorithmLabel}}
|
{{localizedStrings.ALGORITHM}}
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-label" #algorithmContainer>
|
<div class="dialog-label" #algorithmContainer>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-label">
|
<div class="dialog-label">
|
||||||
{{certificateOrAsymmetricKeyLabel}}
|
{{localizedStrings.CERTIFICATE_OR_ASYMMETRIC_KEY}}
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-label" #encryptorContainer>
|
<div class="dialog-label" #encryptorContainer>
|
||||||
</div>
|
</div>
|
||||||
@@ -86,33 +86,33 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Overwrite media -->
|
<!-- Overwrite media -->
|
||||||
<div class="dialog-label advanced-header">
|
<div id="media" class="dialog-label advanced-header">
|
||||||
{{mediaLabel}}
|
{{localizedStrings.MEDIA}}
|
||||||
</div>
|
</div>
|
||||||
<div class="radio-indent">
|
<div role="radiogroup" aria-labelledby="media" class="radio-indent">
|
||||||
<div class="option">
|
<div class="option">
|
||||||
<input type="radio" name=media-option value="no_format" [checked]="!isFormatChecked" (change)="onChangeMediaFormat()" [disabled]="isEncryptChecked">{{mediaOptionLabel}}
|
<input role="radio" type="radio" name="media-option" value="no_format" [checked]="!isFormatChecked" (change)="onChangeMediaFormat()" [disabled]="isEncryptChecked" aria-labelledby="mediaOption"><span id="mediaOption">{{localizedStrings.MEDIA_OPTION}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-left:15px">
|
<div role="radiogroup" aria-labelledby="mediaOption" style="margin-left:15px">
|
||||||
<div class="option">
|
<div class="option">
|
||||||
<input type="radio" name=existing-media value="append" [(ngModel)]="selectedInitOption" [disabled]="isFormatChecked">{{existingMediaAppendLabel}}
|
<input role="radio" type="radio" name="existing-media" value="append" [(ngModel)]="selectedInitOption" [disabled]="isFormatChecked" aria-labelledby="existingMediaAppend"><span id="existingMediaAppend">{{localizedStrings.EXISTING_MEDIA_APPEND}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="option">
|
<div class="option">
|
||||||
<input type="radio" name=existing-media value="overwrite" [(ngModel)]="selectedInitOption" [disabled]="isFormatChecked">{{existingMediaOverwriteLabel}}
|
<input role="radio" type="radio" name="existing-media" value="overwrite" [(ngModel)]="selectedInitOption" [disabled]="isFormatChecked" aria-labelledby="existingMediaOverwrite"><span id="existingMediaOverwrite">{{localizedStrings.EXISTING_MEDIA_OVERWRITE}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="option">
|
<div class="option">
|
||||||
<input type="radio" name=media-option value="format" [checked]="isFormatChecked" (change)="onChangeMediaFormat()">{{mediaOptionFormatLabel}}
|
<input role="radio" type="radio" name="media-option" value="format" [checked]="isFormatChecked" (change)="onChangeMediaFormat()" aria-labelledby="mediaOptionFormat"><span id="mediaOptionFormat">{{localizedStrings.MEDIA_OPTION_FORMAT}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-left: 22px">
|
<div style="margin-left: 22px">
|
||||||
<div class="dialog-label">
|
<div class="dialog-label">
|
||||||
{{newMediaSetNameLabel}}
|
{{localizedStrings.NEW_MEDIA_SET_NAME}}
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-label" #mediaName>
|
<div class="dialog-label" #mediaName>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-label">
|
<div class="dialog-label">
|
||||||
{{newMediaSetDescriptionLabel}}
|
{{localizedStrings.NEW_MEDIA_SET_DESCRIPTION}}
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-label" #mediaDescription>
|
<div class="dialog-label" #mediaDescription>
|
||||||
</div>
|
</div>
|
||||||
@@ -120,21 +120,21 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Transaction log -->
|
<!-- Transaction log -->
|
||||||
<div class="dialog-label advanced-header">
|
<div id="transactionLog" class="dialog-label advanced-header">
|
||||||
{{transactionLogLabel}}
|
{{localizedStrings.TRANSACTION_LOG}}
|
||||||
</div>
|
</div>
|
||||||
<div class="radio-indent">
|
<div role="radiogroup" aria-labelledby="transactionLog" class="radio-indent">
|
||||||
<div class="option">
|
<div class="option">
|
||||||
<input type="radio" name=t-log value="truncate" [checked]="isTruncateChecked" (change)="onChangeTlog()" [disabled]="disableTlog">Truncate the transaction log
|
<input role="radio" type="radio" name="t-log" value="truncate" [checked]="isTruncateChecked" (change)="onChangeTlog()" [disabled]="disableTlog" aria-labelledby="truncateTransaction"><span id="truncateTransaction">{{localizedStrings.TRUNCATE_TRANSACTION_LOG}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="option">
|
<div class="option">
|
||||||
<input type="radio" name=t-log value="taillog" [checked]="isTaillogChecked" (change)="onChangeTlog()" [disabled]="disableTlog">Backup the tail of the log
|
<input role="radio" type="radio" name="t-log" value="taillog" [checked]="isTaillogChecked" (change)="onChangeTlog()" [disabled]="disableTlog" aria-labelledby="backupTail"><span id="backupTail">{{localizedStrings.BACKUP_TAIL}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Reliability -->
|
<!-- Reliability -->
|
||||||
<div class="dialog-label advanced-header">
|
<div class="dialog-label advanced-header">
|
||||||
{{reliabilityLabel}}
|
{{localizedStrings.RELIABILITY}}
|
||||||
</div>
|
</div>
|
||||||
<div class="indent">
|
<div class="indent">
|
||||||
<div class="option check" #checksumContainer>
|
<div class="option check" #checksumContainer>
|
||||||
@@ -147,11 +147,11 @@
|
|||||||
|
|
||||||
<!-- Backup expiration -->
|
<!-- Backup expiration -->
|
||||||
<div class="dialog-label advanced-header">
|
<div class="dialog-label advanced-header">
|
||||||
{{expirationLabel}}
|
{{localizedStrings.EXPIRATION}}
|
||||||
</div>
|
</div>
|
||||||
<div class="indent">
|
<div class="indent">
|
||||||
<div class="dialog-label">
|
<div class="dialog-label">
|
||||||
{{setBackupRetainDaysLabel}}
|
{{localizedStrings.SET_BACKUP_RETAIN_DAYS}}
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-label">
|
<div class="dialog-label">
|
||||||
<div #backupDaysContainer></div>
|
<div #backupDaysContainer></div>
|
||||||
|
|||||||
@@ -76,6 +76,38 @@ interface MssqlBackupInfo {
|
|||||||
encryptorName: string;
|
encryptorName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LocalizedStrings = {
|
||||||
|
BACKUP_NAME: localize('backup.backupName', 'Backup name'),
|
||||||
|
RECOVERY_MODEL: localize('backup.recoveryModel', 'Recovery model'),
|
||||||
|
BACKUP_TYPE: localize('backup.backupType', 'Backup type'),
|
||||||
|
BACKUP_DEVICE: localize('backup.backupDevice', 'Backup files'),
|
||||||
|
ALGORITHM: localize('backup.algorithm', 'Algorithm'),
|
||||||
|
CERTIFICATE_OR_ASYMMETRIC_KEY: localize('backup.certificateOrAsymmetricKey', 'Certificate or Asymmetric key'),
|
||||||
|
MEDIA: localize('backup.media', 'Media'),
|
||||||
|
MEDIA_OPTION: localize('backup.mediaOption', 'Backup to the existing media set'),
|
||||||
|
MEDIA_OPTION_FORMAT: localize('backup.mediaOptionFormat', 'Backup to a new media set'),
|
||||||
|
EXISTING_MEDIA_APPEND: localize('backup.existingMediaAppend', 'Append to the existing backup set'),
|
||||||
|
EXISTING_MEDIA_OVERWRITE: localize('backup.existingMediaOverwrite', 'Overwrite all existing backup sets'),
|
||||||
|
NEW_MEDIA_SET_NAME: localize('backup.newMediaSetName', 'New media set name'),
|
||||||
|
NEW_MEDIA_SET_DESCRIPTION: localize('backup.newMediaSetDescription', 'New media set description'),
|
||||||
|
CHECKSUM_CONTAINER: localize('backup.checksumContainer', 'Perform checksum before writing to media'),
|
||||||
|
VERIFY_CONTAINER: localize('backup.verifyContainer', 'Verify backup when finished'),
|
||||||
|
CONTINUE_ON_ERROR_CONTAINER: localize('backup.continueOnErrorContainer', 'Continue on error'),
|
||||||
|
EXPIRATION: localize('backup.expiration', 'Expiration'),
|
||||||
|
SET_BACKUP_RETAIN_DAYS: localize('backup.setBackupRetainDays', 'Set backup retain days'),
|
||||||
|
COPY_ONLY: localize('backup.copyOnly', 'Copy-only backup'),
|
||||||
|
ADVANCED_CONFIGURATION: localize('backup.advancedConfiguration', 'Advanced Configuration'),
|
||||||
|
COMPRESSION: localize('backup.compression', 'Compression'),
|
||||||
|
SET_BACKUP_COMPRESSION: localize('backup.setBackupCompression', 'Set backup compression'),
|
||||||
|
ENCRYPTION: localize('backup.encryption', 'Encryption'),
|
||||||
|
TRANSACTION_LOG: localize('backup.transactionLog', 'Transaction log'),
|
||||||
|
TRUNCATE_TRANSACTION_LOG: localize('backup.truncateTransactionLog', 'Truncate the transaction log'),
|
||||||
|
BACKUP_TAIL: localize('backup.backupTail', 'Backup the tail of the log'),
|
||||||
|
RELIABILITY: localize('backup.reliability', 'Reliability'),
|
||||||
|
MEDIA_NAME_REQUIRED_ERROR: localize('backup.mediaNameRequired', 'Media name is required'),
|
||||||
|
NO_ENCRYPTOR_WARNING: localize('backup.noEncryptorWarning', "No certificate or asymmetric key is available")
|
||||||
|
};
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: BACKUP_SELECTOR,
|
selector: BACKUP_SELECTOR,
|
||||||
templateUrl: decodeURI(require.toUrl('sql/parts/disasterRecovery/backup/backup.component.html'))
|
templateUrl: decodeURI(require.toUrl('sql/parts/disasterRecovery/backup/backup.component.html'))
|
||||||
@@ -109,36 +141,7 @@ export class BackupComponent {
|
|||||||
@ViewChild('advancedOptionContainer', { read: ElementRef }) advancedOptionElement;
|
@ViewChild('advancedOptionContainer', { read: ElementRef }) advancedOptionElement;
|
||||||
@ViewChild('advancedOptionBodyContainer', { read: ElementRef }) advancedOptionBodyElement;
|
@ViewChild('advancedOptionBodyContainer', { read: ElementRef }) advancedOptionBodyElement;
|
||||||
|
|
||||||
// tslint:disable:no-unused-variable
|
private localizedStrings = LocalizedStrings;
|
||||||
private readonly backupNameLabel: string = localize('backup.backupName', 'Backup name');
|
|
||||||
private readonly recoveryModelLabel: string = localize('backup.recoveryModel', 'Recovery model');
|
|
||||||
private readonly backupTypeLabel: string = localize('backup.backupType', 'Backup type');
|
|
||||||
private readonly backupDeviceLabel: string = localize('backup.backupDevice', 'Backup files');
|
|
||||||
private readonly algorithmLabel: string = localize('backup.algorithm', 'Algorithm');
|
|
||||||
private readonly certificateOrAsymmetricKeyLabel: string = localize('backup.certificateOrAsymmetricKey', 'Certificate or Asymmetric key');
|
|
||||||
private readonly mediaLabel: string = localize('backup.media', 'Media');
|
|
||||||
private readonly mediaOptionLabel: string = localize('backup.mediaOption', 'Backup to the existing media set');
|
|
||||||
private readonly mediaOptionFormatLabel: string = localize('backup.mediaOptionFormat', 'Backup to a new media set');
|
|
||||||
private readonly existingMediaAppendLabel: string = localize('backup.existingMediaAppend', 'Append to the existing backup set');
|
|
||||||
private readonly existingMediaOverwriteLabel: string = localize('backup.existingMediaOverwrite', 'Overwrite all existing backup sets');
|
|
||||||
private readonly newMediaSetNameLabel: string = localize('backup.newMediaSetName', 'New media set name');
|
|
||||||
private readonly newMediaSetDescriptionLabel: string = localize('backup.newMediaSetDescription', 'New media set description');
|
|
||||||
private readonly checksumContainerLabel: string = localize('backup.checksumContainer', 'Perform checksum before writing to media');
|
|
||||||
private readonly verifyContainerLabel: string = localize('backup.verifyContainer', 'Verify backup when finished');
|
|
||||||
private readonly continueOnErrorContainerLabel: string = localize('backup.continueOnErrorContainer', 'Continue on error');
|
|
||||||
private readonly expirationLabel: string = localize('backup.expiration', 'Expiration');
|
|
||||||
private readonly setBackupRetainDaysLabel: string = localize('backup.setBackupRetainDays', 'Set backup retain days');
|
|
||||||
private readonly copyOnlyLabel: string = localize('backup.copyOnly', 'Copy-only backup');
|
|
||||||
private readonly advancedConfigurationLabel: string = localize('backup.advancedConfiguration', 'Advanced Configuration');
|
|
||||||
private readonly compressionLabel: string = localize('backup.compression', 'Compression');
|
|
||||||
private readonly setBackupCompressionLabel: string = localize('backup.setBackupCompression', 'Set backup compression');
|
|
||||||
private readonly encryptionLabel: string = localize('backup.encryption', 'Encryption');
|
|
||||||
private readonly transactionLogLabel: string = localize('backup.transactionLog', 'Transaction log');
|
|
||||||
private readonly reliabilityLabel: string = localize('backup.reliability', 'Reliability');
|
|
||||||
private readonly mediaNameRequiredError: string = localize('backup.mediaNameRequired', 'Media name is required');
|
|
||||||
private readonly noEncryptorWarning: string = localize('backup.noEncryptorWarning', "No certificate or asymmetric key is available");
|
|
||||||
|
|
||||||
// tslint:enable:no-unused-variable
|
|
||||||
|
|
||||||
private _backupService: IBackupService;
|
private _backupService: IBackupService;
|
||||||
private _backupUiService: IBackupUiService;
|
private _backupUiService: IBackupUiService;
|
||||||
@@ -207,48 +210,58 @@ export class BackupComponent {
|
|||||||
let self = this;
|
let self = this;
|
||||||
this.addFooterButtons();
|
this.addFooterButtons();
|
||||||
|
|
||||||
this.recoveryBox = new InputBox(this.recoveryModelElement.nativeElement, this._bootstrapService.contextViewService, { placeholder: this.recoveryModel });
|
this.recoveryBox = new InputBox(this.recoveryModelElement.nativeElement, this._bootstrapService.contextViewService, {
|
||||||
|
placeholder: this.recoveryModel,
|
||||||
|
ariaLabel: LocalizedStrings.RECOVERY_MODEL
|
||||||
|
});
|
||||||
// Set backup type
|
// Set backup type
|
||||||
this.backupTypeSelectBox = new SelectBox([], '', this._bootstrapService.contextViewService);
|
this.backupTypeSelectBox = new SelectBox([], '', this._bootstrapService.contextViewService);
|
||||||
this.backupTypeSelectBox.render(this.backupTypeElement.nativeElement);
|
this.backupTypeSelectBox.render(this.backupTypeElement.nativeElement);
|
||||||
|
|
||||||
// Set copy-only check box
|
// Set copy-only check box
|
||||||
this.copyOnlyCheckBox = new Checkbox(this.copyOnlyElement.nativeElement, {
|
this.copyOnlyCheckBox = new Checkbox(this.copyOnlyElement.nativeElement, {
|
||||||
label: this.copyOnlyLabel,
|
label: LocalizedStrings.COPY_ONLY,
|
||||||
checked: false,
|
checked: false,
|
||||||
onChange: (viaKeyboard) => { }
|
onChange: (viaKeyboard) => { },
|
||||||
|
ariaLabel: LocalizedStrings.COPY_ONLY
|
||||||
});
|
});
|
||||||
|
|
||||||
// Encryption checkbox
|
// Encryption checkbox
|
||||||
this.encryptCheckBox = new Checkbox(this.encryptElement.nativeElement, {
|
this.encryptCheckBox = new Checkbox(this.encryptElement.nativeElement, {
|
||||||
label: this.encryptionLabel,
|
label: LocalizedStrings.ENCRYPTION,
|
||||||
checked: false,
|
checked: false,
|
||||||
onChange: (viaKeyboard) => self.onChangeEncrypt()
|
onChange: (viaKeyboard) => self.onChangeEncrypt(),
|
||||||
|
ariaLabel: LocalizedStrings.ENCRYPTION
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify backup checkbox
|
// Verify backup checkbox
|
||||||
this.verifyCheckBox = new Checkbox(this.verifyElement.nativeElement, {
|
this.verifyCheckBox = new Checkbox(this.verifyElement.nativeElement, {
|
||||||
label: this.verifyContainerLabel,
|
label: LocalizedStrings.VERIFY_CONTAINER,
|
||||||
checked: false,
|
checked: false,
|
||||||
onChange: (viaKeyboard) => { }
|
onChange: (viaKeyboard) => { },
|
||||||
|
ariaLabel: LocalizedStrings.VERIFY_CONTAINER
|
||||||
});
|
});
|
||||||
|
|
||||||
// Perform checksum checkbox
|
// Perform checksum checkbox
|
||||||
this.checksumCheckBox = new Checkbox(this.checksumElement.nativeElement, {
|
this.checksumCheckBox = new Checkbox(this.checksumElement.nativeElement, {
|
||||||
label: this.checksumContainerLabel,
|
label: LocalizedStrings.CHECKSUM_CONTAINER,
|
||||||
checked: false,
|
checked: false,
|
||||||
onChange: (viaKeyboard) => { }
|
onChange: (viaKeyboard) => { },
|
||||||
|
ariaLabel: LocalizedStrings.CHECKSUM_CONTAINER
|
||||||
});
|
});
|
||||||
|
|
||||||
// Continue on error checkbox
|
// Continue on error checkbox
|
||||||
this.continueOnErrorCheckBox = new Checkbox(this.continueOnErrorElement.nativeElement, {
|
this.continueOnErrorCheckBox = new Checkbox(this.continueOnErrorElement.nativeElement, {
|
||||||
label: this.continueOnErrorContainerLabel,
|
label: LocalizedStrings.CONTINUE_ON_ERROR_CONTAINER,
|
||||||
checked: false,
|
checked: false,
|
||||||
onChange: (viaKeyboard) => { }
|
onChange: (viaKeyboard) => { },
|
||||||
|
ariaLabel: LocalizedStrings.CONTINUE_ON_ERROR_CONTAINER
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set backup name
|
// Set backup name
|
||||||
this.backupNameBox = new InputBox(this.backupNameElement.nativeElement, this._bootstrapService.contextViewService);
|
this.backupNameBox = new InputBox(this.backupNameElement.nativeElement, this._bootstrapService.contextViewService, {
|
||||||
|
ariaLabel: LocalizedStrings.BACKUP_NAME
|
||||||
|
});
|
||||||
|
|
||||||
// Set backup path list
|
// Set backup path list
|
||||||
this.pathListBox = new ListBox([], '', this._bootstrapService.contextViewService, this._bootstrapService.clipboardService);
|
this.pathListBox = new ListBox([], '', this._bootstrapService.contextViewService, this._bootstrapService.clipboardService);
|
||||||
@@ -278,11 +291,15 @@ export class BackupComponent {
|
|||||||
this._bootstrapService.contextViewService,
|
this._bootstrapService.contextViewService,
|
||||||
{
|
{
|
||||||
validationOptions: {
|
validationOptions: {
|
||||||
validation: (value: string) => !value ? ({ type: MessageType.ERROR, content: this.mediaNameRequiredError }) : null
|
validation: (value: string) => !value ? ({ type: MessageType.ERROR, content: LocalizedStrings.MEDIA_NAME_REQUIRED_ERROR }) : null
|
||||||
}
|
},
|
||||||
});
|
ariaLabel: LocalizedStrings.NEW_MEDIA_SET_NAME
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
this.mediaDescriptionBox = new InputBox(this.mediaDescriptionElement.nativeElement, this._bootstrapService.contextViewService);
|
this.mediaDescriptionBox = new InputBox(this.mediaDescriptionElement.nativeElement, this._bootstrapService.contextViewService, {
|
||||||
|
ariaLabel: LocalizedStrings.NEW_MEDIA_SET_DESCRIPTION
|
||||||
|
});
|
||||||
|
|
||||||
// Set backup retain days
|
// Set backup retain days
|
||||||
let invalidInputMessage = localize('backupComponent.invalidInput', 'Invalid input. Value must be greater than or equal 0.');
|
let invalidInputMessage = localize('backupComponent.invalidInput', 'Invalid input. Value must be greater than or equal 0.');
|
||||||
@@ -300,7 +317,8 @@ export class BackupComponent {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
ariaLabel: LocalizedStrings.SET_BACKUP_RETAIN_DAYS
|
||||||
});
|
});
|
||||||
|
|
||||||
// Disable elements
|
// Disable elements
|
||||||
@@ -316,7 +334,7 @@ export class BackupComponent {
|
|||||||
// Set category view for advanced options. This should be defined in ngAfterViewInit so that it correctly calculates the text height after data binding.
|
// Set category view for advanced options. This should be defined in ngAfterViewInit so that it correctly calculates the text height after data binding.
|
||||||
var splitview = new SplitView(this.advancedOptionElement.nativeElement);
|
var splitview = new SplitView(this.advancedOptionElement.nativeElement);
|
||||||
var advancedBodySize = DOM.getTotalHeight(this.advancedOptionBodyElement.nativeElement);
|
var advancedBodySize = DOM.getTotalHeight(this.advancedOptionBodyElement.nativeElement);
|
||||||
var categoryView = new CategoryView(this.advancedConfigurationLabel, this.advancedOptionBodyElement.nativeElement, true, advancedBodySize, this._advancedHeaderSize);
|
var categoryView = new CategoryView(LocalizedStrings.ADVANCED_CONFIGURATION, this.advancedOptionBodyElement.nativeElement, true, advancedBodySize, this._advancedHeaderSize);
|
||||||
splitview.addView(categoryView);
|
splitview.addView(categoryView);
|
||||||
splitview.layout(advancedBodySize + this._advancedHeaderSize);
|
splitview.layout(advancedBodySize + this._advancedHeaderSize);
|
||||||
|
|
||||||
@@ -584,7 +602,7 @@ export class BackupComponent {
|
|||||||
if (strings.isFalsyOrWhitespace(this.mediaNameBox.value)) {
|
if (strings.isFalsyOrWhitespace(this.mediaNameBox.value)) {
|
||||||
this.backupEnabled = false;
|
this.backupEnabled = false;
|
||||||
this.backupButton.enabled = false;
|
this.backupButton.enabled = false;
|
||||||
this.mediaNameBox.showMessage({ type: MessageType.ERROR, content: this.mediaNameRequiredError });
|
this.mediaNameBox.showMessage({ type: MessageType.ERROR, content: LocalizedStrings.MEDIA_NAME_REQUIRED_ERROR });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.enableBackupButton();
|
this.enableBackupButton();
|
||||||
|
|||||||
@@ -145,23 +145,26 @@ export class BackupUiService implements IBackupUiService {
|
|||||||
|
|
||||||
let backupOptions = this.getOptions(this._currentProvider);
|
let backupOptions = this.getOptions(this._currentProvider);
|
||||||
return new TPromise<void>(() => {
|
return new TPromise<void>(() => {
|
||||||
|
let uri = this._connectionManagementService.getConnectionId(connection)
|
||||||
|
+ ProviderConnectionInfo.idSeparator
|
||||||
|
+ ConnectionUtils.ConnectionUriBackupIdAttributeName
|
||||||
|
+ ProviderConnectionInfo.nameValueSeparator
|
||||||
|
+ BackupUiService._connectionUniqueId;
|
||||||
|
|
||||||
|
this._connectionUri = uri;
|
||||||
|
|
||||||
|
BackupUiService._connectionUniqueId++;
|
||||||
|
|
||||||
|
// Create connection if needed
|
||||||
|
if (!this._connectionManagementService.isConnected(uri)) {
|
||||||
|
this._connectionManagementService.connect(connection, uri).then(() => {
|
||||||
|
this._onShowBackupEvent.fire({ connection: connection, ownerUri: uri });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (backupOptions) {
|
if (backupOptions) {
|
||||||
(backupDialog as OptionsDialog).open(backupOptions, self._optionValues);
|
(backupDialog as OptionsDialog).open(backupOptions, self._optionValues);
|
||||||
} else {
|
} else {
|
||||||
let uri = this._connectionManagementService.getConnectionId(connection)
|
|
||||||
+ ProviderConnectionInfo.idSeparator
|
|
||||||
+ ConnectionUtils.ConnectionUriBackupIdAttributeName
|
|
||||||
+ ProviderConnectionInfo.nameValueSeparator
|
|
||||||
+ BackupUiService._connectionUniqueId;
|
|
||||||
|
|
||||||
BackupUiService._connectionUniqueId++;
|
|
||||||
|
|
||||||
// Create connection if needed
|
|
||||||
if (!this._connectionManagementService.isConnected(uri)) {
|
|
||||||
this._connectionManagementService.connect(connection, uri).then(() => {
|
|
||||||
this._onShowBackupEvent.fire({ connection: connection, ownerUri: uri });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
(backupDialog as BackupDialog).open(connection);
|
(backupDialog as BackupDialog).open(connection);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import * as DOM from 'vs/base/browser/dom';
|
|||||||
import * as sqlops from 'sqlops';
|
import * as sqlops from 'sqlops';
|
||||||
import * as strings from 'vs/base/common/strings';
|
import * as strings from 'vs/base/common/strings';
|
||||||
import { ServiceOptionType } from 'sql/workbench/api/common/sqlExtHostTypes';
|
import { ServiceOptionType } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||||
|
import { mixin } from 'vs/base/common/objects';
|
||||||
|
|
||||||
interface FileListElement {
|
interface FileListElement {
|
||||||
logicalFileName: string;
|
logicalFileName: string;
|
||||||
@@ -48,6 +49,11 @@ interface FileListElement {
|
|||||||
restoreAs: string;
|
restoreAs: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LocalizedStrings = {
|
||||||
|
BACKFILEPATH: localize('backupFilePath', "Backup file path"),
|
||||||
|
TARGETDATABASE: localize('targetDatabase', 'Target database')
|
||||||
|
};
|
||||||
|
|
||||||
export class RestoreDialog extends Modal {
|
export class RestoreDialog extends Modal {
|
||||||
public viewModel: RestoreViewModel;
|
public viewModel: RestoreViewModel;
|
||||||
|
|
||||||
@@ -176,12 +182,13 @@ export class RestoreDialog extends Modal {
|
|||||||
validationOptions: {
|
validationOptions: {
|
||||||
validation: (value: string) => !value ? ({ type: MessageType.ERROR, content: errorMessage }) : null
|
validation: (value: string) => !value ? ({ type: MessageType.ERROR, content: errorMessage }) : null
|
||||||
},
|
},
|
||||||
placeholder: localize('multipleBackupFilePath', 'Please enter one or more file paths separated by commas')
|
placeholder: localize('multipleBackupFilePath', 'Please enter one or more file paths separated by commas'),
|
||||||
|
ariaLabel: LocalizedStrings.BACKFILEPATH
|
||||||
};
|
};
|
||||||
|
|
||||||
filePathContainer.div({ class: 'dialog-input-section' }, (inputContainer) => {
|
filePathContainer.div({ class: 'dialog-input-section' }, (inputContainer) => {
|
||||||
inputContainer.div({ class: 'dialog-label' }, (labelContainer) => {
|
inputContainer.div({ class: 'dialog-label' }, (labelContainer) => {
|
||||||
labelContainer.innerHtml(localize('backupFilePath', "Backup file path"));
|
labelContainer.safeInnerHtml(LocalizedStrings.BACKFILEPATH);
|
||||||
});
|
});
|
||||||
|
|
||||||
inputContainer.div({ class: 'dialog-input' }, (inputCellContainer) => {
|
inputContainer.div({ class: 'dialog-input' }, (inputCellContainer) => {
|
||||||
@@ -218,7 +225,7 @@ export class RestoreDialog extends Modal {
|
|||||||
|
|
||||||
destinationContainer.div({ class: 'dialog-input-section' }, (inputContainer) => {
|
destinationContainer.div({ class: 'dialog-input-section' }, (inputContainer) => {
|
||||||
inputContainer.div({ class: 'dialog-label' }, (labelContainer) => {
|
inputContainer.div({ class: 'dialog-label' }, (labelContainer) => {
|
||||||
labelContainer.innerHtml(localize('targetDatabase', 'Target database'));
|
labelContainer.innerHtml(LocalizedStrings.TARGETDATABASE);
|
||||||
});
|
});
|
||||||
|
|
||||||
inputContainer.div({ class: 'dialog-input' }, (inputCellContainer) => {
|
inputContainer.div({ class: 'dialog-input' }, (inputCellContainer) => {
|
||||||
@@ -226,7 +233,8 @@ export class RestoreDialog extends Modal {
|
|||||||
inputCellContainer.style('width', '100%');
|
inputCellContainer.style('width', '100%');
|
||||||
this._databaseDropdown = new Dropdown(inputCellContainer.getHTMLElement(), this._contextViewService, this._themeService,
|
this._databaseDropdown = new Dropdown(inputCellContainer.getHTMLElement(), this._contextViewService, this._themeService,
|
||||||
{
|
{
|
||||||
strictSelection: false
|
strictSelection: false,
|
||||||
|
ariaLabel: LocalizedStrings.TARGETDATABASE
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this._databaseDropdown.onValueChange(s => {
|
this._databaseDropdown.onValueChange(s => {
|
||||||
@@ -514,7 +522,8 @@ export class RestoreDialog extends Modal {
|
|||||||
checkbox = new Checkbox(inputCellContainer.getHTMLElement(), {
|
checkbox = new Checkbox(inputCellContainer.getHTMLElement(), {
|
||||||
label: label,
|
label: label,
|
||||||
checked: isChecked,
|
checked: isChecked,
|
||||||
onChange: onCheck
|
onChange: onCheck,
|
||||||
|
ariaLabel: label
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return checkbox;
|
return checkbox;
|
||||||
@@ -537,13 +546,16 @@ export class RestoreDialog extends Modal {
|
|||||||
|
|
||||||
private createInputBoxHelper(container: Builder, label: string, options?: IInputOptions): InputBox {
|
private createInputBoxHelper(container: Builder, label: string, options?: IInputOptions): InputBox {
|
||||||
let inputBox: InputBox;
|
let inputBox: InputBox;
|
||||||
|
let ariaOptions = {
|
||||||
|
ariaLabel: label
|
||||||
|
};
|
||||||
container.div({ class: 'dialog-input-section' }, (inputContainer) => {
|
container.div({ class: 'dialog-input-section' }, (inputContainer) => {
|
||||||
inputContainer.div({ class: 'dialog-label' }, (labelContainer) => {
|
inputContainer.div({ class: 'dialog-label' }, (labelContainer) => {
|
||||||
labelContainer.innerHtml(label);
|
labelContainer.safeInnerHtml(label);
|
||||||
});
|
});
|
||||||
|
|
||||||
inputContainer.div({ class: 'dialog-input' }, (inputCellContainer) => {
|
inputContainer.div({ class: 'dialog-input' }, (inputCellContainer) => {
|
||||||
inputBox = new InputBox(inputCellContainer.getHTMLElement(), this._contextViewService, options);
|
inputBox = new InputBox(inputCellContainer.getHTMLElement(), this._contextViewService, mixin(ariaOptions, options));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return inputBox;
|
return inputBox;
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import * as dom from 'vs/base/browser/dom';
|
|||||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||||
import { INotificationService, INotificationActions } from 'vs/platform/notification/common/notification';
|
import { INotificationService, INotificationActions } from 'vs/platform/notification/common/notification';
|
||||||
import Severity from 'vs/base/common/severity';
|
import Severity from 'vs/base/common/severity';
|
||||||
|
import { attachSelectBoxStyler } from 'vs/platform/theme/common/styler';
|
||||||
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
const $ = dom.$;
|
const $ = dom.$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,7 +156,8 @@ export class ChangeMaxRowsActionItem extends EventEmitter implements IActionItem
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _editor: EditDataEditor,
|
private _editor: EditDataEditor,
|
||||||
@IContextViewService contextViewService: IContextViewService) {
|
@IContextViewService contextViewService: IContextViewService,
|
||||||
|
@IThemeService private _themeService: IThemeService) {
|
||||||
super();
|
super();
|
||||||
this._options = ['200', '1000', '10000'];
|
this._options = ['200', '1000', '10000'];
|
||||||
this._currentOptionsIndex = 0;
|
this._currentOptionsIndex = 0;
|
||||||
@@ -204,5 +207,6 @@ export class ChangeMaxRowsActionItem extends EventEmitter implements IActionItem
|
|||||||
this._currentOptionsIndex = this._options.findIndex(x => x === selection.selected);
|
this._currentOptionsIndex = this._options.findIndex(x => x === selection.selected);
|
||||||
this._editor.editDataInput.onRowDropDownSet(Number(selection.selected));
|
this._editor.editDataInput.onRowDropDownSet(Number(selection.selected));
|
||||||
}));
|
}));
|
||||||
|
this.toDispose.push(attachSelectBoxStyler(this.selectBox, this._themeService));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
110
src/sql/parts/extensions/sqlExtensionsHelper.ts
Normal file
110
src/sql/parts/extensions/sqlExtensionsHelper.ts
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 'vs/css!vs/workbench/parts/extensions/browser/media/extensionEditor';
|
||||||
|
|
||||||
|
|
||||||
|
import { IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||||
|
import { Color } from 'vs/base/common/color';
|
||||||
|
import { append, $, addClass, removeClass, finalHandler, join, toggleClass } from 'vs/base/browser/dom';
|
||||||
|
import { IInsightTypeContrib } from 'sql/parts/dashboard/widgets/insights/interfaces';
|
||||||
|
import { IDashboardTabContrib } from 'sql/parts/dashboard/common/dashboardTab.contribution';
|
||||||
|
import { localize } from 'vs/nls';
|
||||||
|
|
||||||
|
class ContributionReader {
|
||||||
|
constructor(private manifest: IExtensionManifest) { }
|
||||||
|
|
||||||
|
public dashboardInsights(): IInsightTypeContrib[] {
|
||||||
|
let contributes = this.manifest.contributes;
|
||||||
|
if (contributes) {
|
||||||
|
let insights: IInsightTypeContrib | IInsightTypeContrib[] = contributes['dashboard.insights'];
|
||||||
|
if (insights) {
|
||||||
|
if (!Array.isArray(insights)) {
|
||||||
|
return [insights];
|
||||||
|
}
|
||||||
|
return insights;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public dashboardTabs(): IDashboardTabContrib[] {
|
||||||
|
let contributes = this.manifest.contributes;
|
||||||
|
if (contributes) {
|
||||||
|
let tabs: IDashboardTabContrib | IDashboardTabContrib[] = contributes['dashboard.tabs'];
|
||||||
|
if (tabs) {
|
||||||
|
if (!Array.isArray(tabs)) {
|
||||||
|
return [tabs];
|
||||||
|
}
|
||||||
|
return tabs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderDashboardContributions(container: HTMLElement, manifest: IExtensionManifest, onDetailsToggle: Function): boolean {
|
||||||
|
let contributionReader = new ContributionReader(manifest);
|
||||||
|
renderDashboardTabs(onDetailsToggle, contributionReader, container);
|
||||||
|
renderDashboardInsights(onDetailsToggle, contributionReader, container);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDashboardTabs(onDetailsToggle: Function, contributionReader: ContributionReader, container: HTMLElement): boolean {
|
||||||
|
let tabs = contributionReader.dashboardTabs();
|
||||||
|
|
||||||
|
if (!tabs || !tabs.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||||
|
$('summary', null, localize('tabs', "Dashboard Tabs ({0})", tabs.length)),
|
||||||
|
$('table', null,
|
||||||
|
$('tr', null,
|
||||||
|
$('th', null, localize('tabId', "Id")),
|
||||||
|
$('th', null, localize('tabTitle', "Title")),
|
||||||
|
$('th', null, localize('tabDescription', "Description"))
|
||||||
|
),
|
||||||
|
...tabs.map(tab => $('tr', null,
|
||||||
|
$('td', null, $('code', null, tab.id)),
|
||||||
|
$('td', null, tab.title ? tab.title : tab.id),
|
||||||
|
$('td', null, tab.description),
|
||||||
|
))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
append(container, details);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDashboardInsights(onDetailsToggle: Function, contributionReader: ContributionReader, container: HTMLElement): boolean {
|
||||||
|
let insights = contributionReader.dashboardInsights();
|
||||||
|
|
||||||
|
if (!insights || !insights.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||||
|
$('summary', null, localize('insights', "Dashboard Insights ({0})", insights.length)),
|
||||||
|
$('table', null,
|
||||||
|
$('tr', null,
|
||||||
|
$('th', null, localize('insightId', "Id")),
|
||||||
|
$('th', null, localize('name', "Name")),
|
||||||
|
$('th', null, localize('insight condition', "When"))
|
||||||
|
),
|
||||||
|
...insights.map(insight => $('tr', null,
|
||||||
|
$('td', null, $('code', null, insight.id)),
|
||||||
|
$('td', null, insight.contrib.name ? insight.contrib.name : insight.id),
|
||||||
|
$('td', null, insight.contrib.when),
|
||||||
|
))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
append(container, details);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -94,7 +94,9 @@ export class FileBrowserDialog extends Modal {
|
|||||||
tableWrapper.element('table', { class: 'file-table-content' }, (tableContainer) => {
|
tableWrapper.element('table', { class: 'file-table-content' }, (tableContainer) => {
|
||||||
let pathLabel = localize('filebrowser.filepath', 'Selected path');
|
let pathLabel = localize('filebrowser.filepath', 'Selected path');
|
||||||
let pathBuilder = DialogHelper.appendRow(tableContainer, pathLabel, 'file-input-label', 'file-input-box');
|
let pathBuilder = DialogHelper.appendRow(tableContainer, pathLabel, 'file-input-label', 'file-input-box');
|
||||||
this._filePathInputBox = new InputBox(pathBuilder.getHTMLElement(), this._contextViewService);
|
this._filePathInputBox = new InputBox(pathBuilder.getHTMLElement(), this._contextViewService, {
|
||||||
|
ariaLabel: pathLabel
|
||||||
|
});
|
||||||
|
|
||||||
this._fileFilterSelectBox = new SelectBox(['*'], '*', this._contextViewService);
|
this._fileFilterSelectBox = new SelectBox(['*'], '*', this._contextViewService);
|
||||||
let filterLabel = localize('fileFilter', 'Files of type');
|
let filterLabel = localize('fileFilter', 'Files of type');
|
||||||
|
|||||||
@@ -17,3 +17,4 @@ export let SelectAllMessages = 'SelectAllMessages';
|
|||||||
export let SaveAsCsv = 'SaveAsCSV';
|
export let SaveAsCsv = 'SaveAsCSV';
|
||||||
export let SaveAsJSON = 'SaveAsJSON';
|
export let SaveAsJSON = 'SaveAsJSON';
|
||||||
export let SaveAsExcel = 'SaveAsExcel';
|
export let SaveAsExcel = 'SaveAsExcel';
|
||||||
|
export let GoToNextQueryOutputTab = 'GoToNextQueryOutputTab';
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ export const MESSAGES_SELECTALL_ID = 'grid.messages.selectAll';
|
|||||||
export const MESSAGES_COPY_ID = 'grid.messages.copy';
|
export const MESSAGES_COPY_ID = 'grid.messages.copy';
|
||||||
export const TOGGLERESULTS_ID = 'grid.toggleResultPane';
|
export const TOGGLERESULTS_ID = 'grid.toggleResultPane';
|
||||||
export const TOGGLEMESSAGES_ID = 'grid.toggleMessagePane';
|
export const TOGGLEMESSAGES_ID = 'grid.toggleMessagePane';
|
||||||
|
export const GOTONEXTQUERYOUTPUTTAB_ID = 'query.goToNextQueryOutputTab';
|
||||||
|
|
||||||
|
|
||||||
export class GridActionProvider {
|
export class GridActionProvider {
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ export const toggleResultsPane = (accessor: ServicesAccessor) => {
|
|||||||
runActionOnActiveResultsEditor(accessor, GridContentEvents.ToggleResultPane);
|
runActionOnActiveResultsEditor(accessor, GridContentEvents.ToggleResultPane);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const goToNextQueryOutputTab = (accessor: ServicesAccessor) => {
|
||||||
|
runActionOnActiveResultsEditor(accessor, GridContentEvents.GoToNextQueryOutputTab);
|
||||||
|
};
|
||||||
|
|
||||||
export const saveAsCsv = (accessor: ServicesAccessor) => {
|
export const saveAsCsv = (accessor: ServicesAccessor) => {
|
||||||
runActionOnActiveResultsEditor(accessor, GridContentEvents.SaveAsCsv);
|
runActionOnActiveResultsEditor(accessor, GridContentEvents.SaveAsCsv);
|
||||||
};
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user