Compare commits

...

521 Commits

Author SHA1 Message Date
Alan Ren
887f4e8985 Alanren/fix4001 (#4011)
* fix for 4001

* Revert "fix for 4001"

This reverts commit 91fed44f063acb44b844a206a13e4074150d8118.

* fix for issue 4001
2019-02-11 21:51:55 -08:00
Matt Irvine
c91c4b01f9 Fix bug minimizing a maximized result grid (#4007) 2019-02-11 21:51:06 -08:00
Yurong He
5f198dba08 Added hard coded pySpark3 kernel for analyze notebook. Good to know and fix it in time. (#4009) 2019-02-11 17:21:08 -08:00
Kevin Cunnane
67f9a7f5e4 Fix issues due to missing notebook values (specs and cells) (#4008)
- Fix #3844
    - Fix #3955
    - Specs can be null on early load of Jupyter kernels
    - Cells were missing in some reference test .ipynb files. We should be resilient to malformed files if possible.
2019-02-11 17:17:56 -08:00
Yurong He
62404721ed Fixed #3954 pass connection info to new notebook flow (#4000)
* Fixed #3954 
The problem is: connectionProfileId is not passed into New Notebook flow.
The fix is: plumbing connectionProfileId via NotebookInput.

* Resolved PR comments
2019-02-11 15:28:05 -08:00
Kevin Cunnane
6d37329e74 Fix #3989 notebook execution count should start empty (#4004)
- Fixed issues where we missed using actual execution count / starting from empty on this.
2019-02-11 15:18:54 -08:00
Karl Burtram
0c316d3225 Bump Azure Data Studio to 1.4.5 2019-02-11 09:17:37 -08:00
Kevin Cunnane
131644477d Beginning of fix for notebook perf (#3984)
Fixes #3843. Now includes full fix which limits length and ensures a scrollbar is available

- Set max size for editor. 4000px gets us 200-250 lines before needing a scrollbar. 
- Adds layout updating which should also ensure accurage line highlighting to the right of the editor. What's happening is initial size is slightly off, so need to layout a 2nd time (e.g. layout once, let flex figure things out, then layout a 2nd time). This isn't optimal as there's a minor perf hit but it isn't noticeable overall.

To consider in future PRs:
- Add user configurable setting for max length?
- Handle case where we scroll to bottom but scrollbar is at the top. 
- Consider how intellisense will work on this. We may need to split into a window around the current code when sending to the kernel as it's quite likely that doing a 12K line intellisense request will be too big.
2019-02-09 13:44:53 -08:00
Kevin Cunnane
b964dd0895 Fix #3985 Hide cell toolbar for markdown cells (#3987)
* Fix #3985 Hide cell toolbar for markdown cells
* Note that I'm still hiding the overall toolbar section per UX feedback
* Also now hiding line numbers per UX feedback..
2019-02-08 16:38:28 -08:00
Raj
7dd32ed44b Notebook server shutdown error (#3976)
* fix #3959 - Notebook shutdown error

* Removing the unit test case to stopserver from clientSession
2019-02-08 13:51:00 -08:00
Chris LaFreniere
0b6aedfc93 Address notebook margin and border CSS issues (#3977) 2019-02-08 10:01:09 -10:00
Chris LaFreniere
b692088c94 Stop map column names for notebook grid, instead use field with unique values (#3975) 2019-02-08 09:59:36 -10:00
Karl Burtram
160ab8d0ae Bump html_query_plan to 2.6 (#3982) 2019-02-08 11:47:33 -08:00
Kevin Cunnane
a599cb436a Run upgrade on npm and yarn packages to update lodash to 4.1.7.11 (#3983)
- This is a recommended update, let me know if you have concerns
- Updated all samples and Azure Data Studio specific extensions with lodash dependency
2019-02-08 11:44:08 -08:00
Yurong He
294aa81298 Added serverVersion to contextProvider key, so Sql server preview das… (#3981)
* Added serverVersion to contextProvider key, so Sql server preview dashboard tab could be filter by it.

* User major version instead of serverVersion
2019-02-08 11:17:46 -08:00
Kevin Cunnane
ddc4b3dd6e Support execution count in run button and align correctly (#3979)
Fixes #3931 
- Align run button correctly so it's centered in new cell
- Refactor to support multi-state button.
  - Hidden state is set to show execution count
  - Stopped state shows run button
  - Running state shows stop button
  - Error state (will) show error button. This isn't fully handled right now
- Add execution count to model and to SqlKernel, verify serialization, loading, update matches other notebook viewers

**Notes on implementation**:
I think this is a decent solution for a) showing execution count as text, and b) perfectly centering the run button.
 
The below solution shows count correctly up to 999 runs (that’s clicking 999 times in a single session), the icon lines up juuust about right with [ ] but for other numbers it is pretty close but probably not exactly right. I wish I could solve this to work better but trying to change text float to center etc. really isn’t working.
 
**Screenshots**:
![image](https://user-images.githubusercontent.com/10819925/52466366-e8794200-2b36-11e9-9a50-86893e75d5af.png)

With running cell:
![image](https://user-images.githubusercontent.com/10819925/52466378-f333d700-2b36-11e9-9e6c-3cee098790fd.png)
2019-02-08 11:05:03 -08:00
Matt Irvine
4c5bf3ad2b Add insiders build links to readme (#3980) 2019-02-08 09:42:46 -08:00
Aditya Bist
88c33214c6 Dataexplorer viewlet (#3967)
* added initial data explorer viewlet

* added dataexplorer contribution point

* removed test view

* remove unused imports

* added flag and tests

* CR comments

* added icon for data explorer
2019-02-07 17:18:05 -08:00
kisantia
393be65aa6 Add Deploy Plan page to DacFx wizard (#3911)
* upgrade plan is piped through and returns the xml plan

* Added review deploy plan page

* checkbox validation now working and columns formatted

* formatting and cleaning up code

* refactored populateTable()

* addressing comments

* addressing comments

* updating tooltips

* add padding to table cells to align with headers

* fix problems when going back and forth between pages and changing config options

* bump sqltoolsservice version to 71

* fix localization
2019-02-07 16:39:22 -08:00
Chris LaFreniere
9ce9a1598f Improve notebook editor height calculations (#3966)
* Improve notebook editor height calculations

* PR comments, hook up to onDidChangeConfiguration
2019-02-07 14:09:09 -10:00
Yurong He
d9079fe18e Fixed #3888. Don't know why it works in previous extension not in mssql after ported. But look like needs utils.getErrorMessage to get msg. (#3969) 2019-02-07 11:47:53 -08:00
Yurong He
3cde070d3b Added submit spark job to data service context menu (#3968) 2019-02-07 11:46:59 -08:00
Karl Burtram
b2a5f65a77 Add query action bar spacing for XML button (#3923) 2019-02-07 11:33:23 -08:00
Kevin Cunnane
69dff5a2cb Fix #3937 Create new notebook (Mac) and receive TypeError (#3965)
- Handles empty file scenario, with fixes along the way for missing metadata (bonus win)
- In non-empty file still shows error and kernel stuck in loading state. #3964 opened to track this issue and fix later
2019-02-07 10:35:19 -08:00
Kevin Cunnane
40e0d5cfbf Fix toggle more actions staying visible, and clickable issues (#3949)
- Fixed so it's now invisible instead of empty when not selected.
 - This fixes clickability and issue where it stayed visible in 1 fix
- Also fixed cell output action which used active cell instead of context cell.
2019-02-07 09:35:58 -08:00
Raj
5a0100757f Attach To is set to 'Localhost' upon cancelling the connection dialog (#3941)
* #3924: Attach To sets 'Localhost' upon cancelling the connection dialog

* Indentation
2019-02-06 16:05:42 -08:00
Kevin Cunnane
f9fe88898d Fix #3928 'Clear output' in ... for markdown cells (#3935)
- Add filtering support for actions, and use for the Clear Output action
2019-02-06 15:49:20 -08:00
Anthony Dresser
a2d6955f79 check for undefined on query info (#3933) 2019-02-06 15:17:45 -08:00
Yurong He
8fa247145e As PM suggested, moved it to Data Services node. (#3930) 2019-02-06 14:22:37 -08:00
Yurong He
04bb65dcf7 Fixe Linux EMFILE: too many open file problem. (#3912)
* Fixe Linux EMFILE: too many open file problem.
Separated mssql from packageTask like azurecore.

* Make mssql depends on azurecore

* Minor fixes
2019-02-06 14:09:19 -08:00
Karl Burtram
e4884c7835 Bump SQL Tools Service to 1.5.0-alpha.70 2019-02-06 12:06:23 -08:00
Gene Lee
8b9ce3e8de Spark features with dashboard are enabled (#3883)
* Spark features are enabled

* Fixed as PR comments

* minor change

* PR comments fixed

* minor fix

* change constant name to avoid conflicts with sqlopsextension

* sqlContext to context

* Changed tab name to SQL Server Big Data Cluster

* Added isCluster to ContextProvider to control display big data cluster dashboard tab
Ported New/open Notebook code to mssql extension and enable them in dashboard

* Fixed tslint
2019-02-06 11:54:25 -08:00
kisantia
327a5f5fae Add tooltip for table column headers and align header and cell (#3909)
* Adding tooltip and lining up header and cell

* moving padding to separate css class
2019-02-06 11:46:24 -08:00
gbritton1
50b971477b Removed reference to object explorer (#3463)
Removed reference to object explorer since ADS does not have one
2019-02-06 10:43:46 -08:00
Anthony Dresser
07c7eea2df reverse data array on repopulation (#3907) 2019-02-06 10:41:55 -08:00
Raj
42135d3e53 #3897: Unified connection integration - sql connection improvements (#3910)
* #3897: Unified connection integration - sql connection improvements

* variable name change

* Misc changes

* Misc change
2019-02-06 10:33:21 -08:00
Kevin Cunnane
d74e5e6457 Fix regression where border line between editor and output was lost (#3915) 2019-02-05 21:21:59 -08:00
Kevin Cunnane
a2c7377134 Improve notebook colors and UX (#3914)
This was reviewed / worked on with Smitha and will be signed off on by PM via mail.
1 thing left (make run button look better when not selected) will be one in separate review.

Changes
- Add top/bottom padding to editor so it's not cramped
- Added an (on by default) setting `notebook.overrideEditorTheming`. This controls whether new colors etc. are used for notebook editors or if users should see vanilla UI like in standard editor. Settings under this flag are:
  - When unselected, editor has same color as toolbar. On selection it goes back to regular editor view so colors work "right"
  - In standard light/dark themes we now use a filled in background color instead of border box.
2019-02-05 17:51:42 -08:00
Raj
0e54393d5a Unified connection in notebooks (#3898)
* yarn files

* #3897: Integrate unified connection with notebooks

* ConnectionProfile serialization in unified connection

* #3898 Handle connection validation from extension

* Removing unused namespaces

* Remove constant

* Show a detailed error message on changing context

* Indentation
2019-02-05 11:54:29 -08:00
Yurong He
8cf8cefc92 Removed dup OE contribution. The conflict wasn't detected during checkin. (#3906) 2019-02-05 11:36:33 -08:00
Kevin Cunnane
098c40e9ac Use document-style for Notebooks (#3902)
* Added hover support, adding box shadow and light outline on hovering and the "more actions" button showing on hover
* Added box shadow for dark themes (hooray!)
* Remove border from everything but the code cell unless a cell is selected or hovered over. This ensures this looks like a document
* Fix high contrast theming issues.
2019-02-05 11:28:07 -08:00
Yurong He
80c1c4c6c8 Mssql extension exposes OE getNode API for Sql-2019vNext extension (#3901)
* Mssql extension exposes OE getNode API for Sql-2019Vnext extension

* Resolved PR comments
2019-02-04 19:55:32 -08:00
Yurong He
ef8afab7e8 Added error node to OE tree (#3889)
* Add error node to OE tree

* Add globalerror_red.svg for error node.

* Fixed wrong import resolved automatically

* Resolve PR comments
2019-02-04 19:18:58 -08:00
Yurong He
84e0e08aec Ported Analyze notebook code from SqlOpsStudio and make it work. (#3899)
* Ported Analyze notebook code from SqlOpsStudio and make it work.
if config.notebook.sqlKernelEnabled is true, use SQL provider;
Use Jupyter provider if Python is install, otherwise use buildIn Kernel.

* Analyze in Notebook Kernel can only be Python or "No Kernel". So remove Sql Kernel.
2019-02-04 15:41:01 -08:00
Kevin Cunnane
2fce771214 Run and Add Cell keybinding support (#3896)
- As part of this, fixed bug in the insertCell API where it didn't add to the end / failed if no cells existed
2019-02-04 14:02:15 -08:00
Yurong He
15929e8cf2 Add new notebook to OE server context menu (#3892) 2019-02-04 11:25:33 -08:00
Kevin Cunnane
f1c8ec141a Make run cell button float so it's always visible (#3895)
- Make the toolbar sticky and remove overflow:hidden which blocked this working.
2019-02-04 09:32:38 -08:00
kisantia
a62393e0ed Add width and css options for TableColumn (#3893) 2019-02-02 19:27:35 -08:00
Yurong He
a6defd9b62 Fixed build issue: ERROR: D:/a/1/s/src/sql/workbench/services/notebook/common/sqlSessionManager.ts[21, 1]: Duplicate imports for 'sqlops'. (#3894) 2019-02-01 14:39:09 -08:00
Kevin Cunnane
374212beaa Fix bug where results were added to all cells, and support multiple resultsets (#3890)
- SQLKernel is the only place to listen for batch and query complete messages now
- It routes to the 1 and only future (since can only have 1 at a time
- It handles query cancelation and not-connected issues correctly
2019-02-01 13:53:10 -08:00
Kevin Cunnane
5132e62045 Fix #3734 Notebook cells are shown empty some times even when there is content (#3878)
- Editor layout gets called sometimes when other events happen (and Notebook isn't visible)
- Add in a layout call on re-setting input so the cell is updated. This fixes the problem by laying out once the UI is visible again.

Note: long term, should really be destroying the UI (while preserving the model), then restoring it including scroll selection etc. and hooking back up to the model. That is... much more work, but something we'll need long term to avoid issues where we have many Notebooks open at once. Not in scope for this PR
2019-02-01 10:11:45 -08:00
Kevin Cunnane
9504ede1f3 Fix #3875 Notebook stuck Loading Kernels if SQL flag disabled and Jupyter not installed (#3876) 2019-02-01 10:10:21 -08:00
Kevin Cunnane
afb6e6b5ba Fix some cell UI issues (toolbar background color, unselected cells) (#3881)
- Toolbar background is now differentiated from the editor
- For unselected cells there's no longer a line selection in the cell. This makes it clearer what the active cell is (and cleans the UI up)
2019-02-01 08:03:23 -08:00
Yurong He
60b2b92803 Fixed #3873 with update the version of vscode-nls (#3879)
Fixed #3873 with update the version of vscode-nls (#3879)
Added dependencies needed for prompts.
2019-01-31 17:57:04 -08:00
Aditya Bist
6113311fda preserve whitespace in messages (#3821) 2019-01-31 15:23:10 -08:00
Yurong He
ecac6201d0 Rename nodeType name in order to have file context menu in both mssql and SqlOpsStudio (#3862)
* Added data service context menu: file related operations. All new files are ported from SqlOpsStudio. Will remove these functionality from SqlOpsStudio.

* Used the existing constant hadoopKnoxEndpointName

* Rename nodeType name from hdfs to bdc. So we can have file context menu in both mssql and SqlOpsStudio. Need to add "Create External Table from CSV" support for bdc nodeType

* Rename bdc to mssqlcluster
2019-01-31 13:34:59 -08:00
Chris LaFreniere
90d8c37f91 Fix a not implemented issue when we were not sanitizing kernel display name (#3869)
Fixing an issue where we got a 501 Not Implemented because kernel display name sanitization was not occurring with the _defaultKernel case.

In addition, changed a method name to make it more clear, and removed an erroneous error that would occur every time you opened a notebook without any existing connections. I'm just removing this, as it adds no value.
2019-01-31 09:50:27 -08:00
Chris LaFreniere
c43085beab Fix weird exception when no connection is present for SQL kernel, Limit Max Rows to 2000 (#3870)
Fixes #3856. Matches the Jupyter behavior that we have, where we don't show any message when a connection is required. We no longer will throw a bizarre exception about getOptionsKey being undefined.

Also sets max rows returned to 2000.
2019-01-31 09:38:59 -08:00
Kevin Cunnane
d9c383b2ef Remove notebook.enabled feature flag (#3866)
* Remove notebook.enabled feature flag

* Fix build error with package.json typos
2019-01-31 09:34:50 -08:00
Matt Irvine
100938b0e5 Add bytes dependency to mssql (#3867) 2019-01-30 17:29:41 -08:00
Chris LaFreniere
83a6ee0a22 Change feature flag for SQL kernel to be user preference (#3838)
* Change feature flag for SQL kernel to be user preference

* fix test that was broken

* Tweak package.nls.json to show "(Preview)"
2019-01-30 17:29:08 -08:00
Chris LaFreniere
0dab7f02ed Notebooks: Grid Support (#3832)
* First grid support in notebooks

* still trying to get nteract ipynb to display grid correctly

* works opening with existing 'application/vnd.dataresource+json' table

* fixing merge issue due to core folder structure changing a bit

* PR feedback, fix for XSS
2019-01-30 16:56:14 -08:00
Chris LaFreniere
0e6f2eb1cd Only show placeholder when notebook isn't loading (#3863) 2019-01-30 16:22:24 -08:00
Chris LaFreniere
9a371f8998 Fix for Select Connection not showing up in Attach To (#3860) 2019-01-30 16:22:01 -08:00
David Shiflet
8a7bbd1795 Pass connectionid to registered commands from command line (#3861)
* pass connectionid to registered commands from commandline

* remove blank lines

* fix commandline unit test
2019-01-30 18:18:25 -05:00
Kevin Cunnane
d1fef24723 Support Notebook integration testing by adding APIs & fixing others (#3848)
- Added `runCell` API. Updated runCell button to listen to events on the model so it'll reflect run cell when called from other sources
- Plumbed through kernelspec info to the extension side so when changed, it's updated
- Fixed bug in ConnectionProfile where it didn't copy from options but instead overrode with empty wrapper functions

Here's the rough test code (it's in the sql-vnext extension and will be out in a separate PR)
```ts

    it('Should connect to local notebook server with result 2', async function() {
        this.timeout(60000);
        let pythonNotebook = Object.assign({}, expectedNotebookContent, { metadata: { kernelspec: { name: "python3", display_name: "Python 3" }}});
        let uri = writeNotebookToFile(pythonNotebook);
        await ensureJupyterInstalled();

        let notebook = await sqlops.nb.showNotebookDocument(uri);
        should(notebook.document.cells).have.length(1);
        let ran = await notebook.runCell(notebook.document.cells[0]);
        should(ran).be.true('Notebook runCell failed');
        let cellOutputs = notebook.document.cells[0].contents.outputs;
        should(cellOutputs).have.length(1);
        let result = (<sqlops.nb.IExecuteResult>cellOutputs[0]).data['text/plain'];
        should(result).equal('2');

        try {
            // TODO support closing the editor. Right now this prompts and there's no override for this. Need to fix in core
            // Close the editor using the recommended vscode API
            //await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
        }
        catch (e) {}
    });

    it('Should connect to remote spark server with result 2', async function() {
        this.timeout(240000);
        let uri = writeNotebookToFile(expectedNotebookContent);
        await ensureJupyterInstalled();

        // Given a connection to a server exists
        let connectionId = await connectToSparkIntegrationServer();

        // When I open a Spark notebook and run the cell
        let notebook = await sqlops.nb.showNotebookDocument(uri, {
            connectionId: connectionId
        });
        should(notebook.document.cells).have.length(1);
        let ran = await notebook.runCell(notebook.document.cells[0]);
        should(ran).be.true('Notebook runCell failed');

        // Then I expect to get the output result of 1+1, executed remotely against the Spark endpoint
        let cellOutputs = notebook.document.cells[0].contents.outputs;
        should(cellOutputs).have.length(4);
        let sparkResult = (<sqlops.nb.IStreamResult>cellOutputs[3]).text;
        should(sparkResult).equal('2');

        try {
            // TODO support closing the editor. Right now this prompts and there's no override for this. Need to fix in core
            // Close the editor using the recommended vscode API
            //await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
        }
        catch (e) {}
    });
});
```
2019-01-30 14:24:14 -08:00
Yurong He
3ddc5e7846 Added Unified connection support (#3785)
* Added Unified connection support

* Use generic way to do expandNode.
Cleanup the ported code and removed unreference code. Added as needed later.
Resolved PR comments.

* Minor fixes and removed timer for all expanders for now. If any providers can't response, the tree node will spin and wait. We may improve later.

* Change handSessionClose to not thenable.
Added a node to OE to show error message instead of reject. So we could show partial expanded result if get any.
Resolve PR comments

* Minor fixes of PR comments
2019-01-29 14:37:14 -08:00
Yurong He
b439ea45ec Bump to 69 to fix #3839 doesn't have model.sys.assemblies (#3842) 2019-01-29 10:09:45 -08:00
Karl Burtram
5680785f86 Bump Azure Data Studio to 1.4.4 2019-01-28 15:58:14 -08:00
Chris LaFreniere
e8eb7bec1b Fix notebook selection issues including from placeholder (#3836) 2019-01-28 14:02:23 -08:00
kisantia
565b7404f9 Add generate script option to DacFx wizard (#3789)
* Add generate script option to deploy scenario

* add action to summary page and fixed page adding/removing so that summary page will have the correct step number

* updating contract based on change in sqltoolsservice

* added enums to make index checks more clear

* cleaned up onPageChanged()

* bump sqltoolsservice version to 68
2019-01-28 10:48:36 -08:00
Chris LaFreniere
9cffe4d476 Allow for "when" clause filtering for Notebook Toolbar Given ProviderId Changes (#3712)
* Integrate first SQL Notebooks Bits into Master (#3679)

* First crack tsql notebook (no output rendered yet)

* getting messages back

* intellisense working first cell, no connection errors

* sql notebook cell output functioning

* Latest SQL noteobook changes

* Undo change to launch.json

* Plumbing providers through

* Kernels shown from multiple providers, can switch between them. No mementos yet

* Ensure we have a feature flag for SQL notebooks, ensure existing functionality still works

* Fix tslint duplicate imports issue

* Addressing PR comments

* second round of PR feedback to cleanup notebook service manager code

* merge latest from master

* Enable notebook toolbar actions to disable themselves on provider change

* Undo changes to taskbar/actionbar

* very minor change due to latest merge
2019-01-26 11:01:40 -08:00
Chris LaFreniere
43be88a37c SQL Kernel Improvements/Removing Spark Code from Core/Attach to Changes (#3790)
* Scenarios work besides loading saved kernel

* Fix compilation issue

* Save and load functional

* Fix loading kernesl issue when sql kernel is not enabled

* Fix language mapping to not be hardcoded any longer

* Remove unnecessary comment

* PR Comments vol. 1

* Code cleanup, use ConnectionProfile instead of IConnectionProfile when accessing serverName

* PR changes vol. 2

* One final comment for PR

* Fix linting issue
2019-01-25 18:54:04 -08:00
Anthony Dresser
ea67859de7 Initial Code Layering (#3788)
* working on formatting

* fixed basic lint errors; starting moving things to their appropriate location

* formatting

* update tslint to match the version of vscode we have

* remove unused code

* work in progress fixing layering

* formatting

* moved connection management service to platform

* formatting

* add missing file

* moving more servies

* formatting

* moving more services

* formatting

* wip

* moving more services

* formatting

* revert back tslint rules

* move css file

* add missing svgs
2019-01-25 14:52:35 -08:00
Aditya Bist
c8986464ec fixed arrows disappearing after tab change (#3829) 2019-01-25 13:29:39 -08:00
Aditya Bist
7804f94d8b Copy all messages when selecting all (#3818)
* copy all messages when selecting all

* added functionality for keyboard shortcuts

* fixed bug when select all then selection made

* made output similar to debug console
2019-01-25 12:10:00 -08:00
Alan Ren
bfa77aebfc add clear filter icon and update filter icon from Smitha (#3828) 2019-01-25 11:34:58 -08:00
Yurong He
487fb02313 Bump sqltoolservice version to 67 for unified connection support (#3827) 2019-01-25 11:24:26 -08:00
Aditya Bist
ef64038107 Added horizontal scrolling for explorer (#3819)
* added horizontal scrolling for explorer

* made horizontal scrolling auto
2019-01-24 13:31:19 -08:00
udeeshagautam
5d336accbc adding hover text for dashboard serach grid items (#3816)
Fix for issue : Search widget in Manage dashboard truncates long names with no hovertext to show full name (Ref issue: #3075)
2019-01-24 13:17:37 -08:00
Karl Burtram
99047b2866 Remove Ctrl-Alt keyboard shortcuts (#3810) 2019-01-23 17:23:59 -08:00
Aditya Bist
f611cf3b5a Improve Agent performance (#3804)
* pause and resume job history retrieval when opening dialogs

* review comments

* removed boolean for tab change
2019-01-23 14:25:54 -08:00
Karl Burtram
4ad059605c Update Azure account picker styles based on splitview change (#3791) 2019-01-23 10:50:41 -08:00
Karl Burtram
dc2ff97dd8 Bump Azure Data Studio to 1.4.3 2019-01-22 16:54:51 -08:00
Karl Burtram
2b5265c103 Fix infinite callbacks in Azure Resource Explorer (#3780) 2019-01-22 15:22:45 -08:00
Aditya Bist
2e98fde053 fixed resizing in agent because of slickgrid change (#3786) 2019-01-22 14:38:20 -08:00
Anthony Dresser
d5176e0eb7 remove updating row number column size (#3756) 2019-01-22 14:37:59 -08:00
Anthony Dresser
eb0b2a847b change stating to handle magnify state (#3746)
* change stating to handle magnify state

* fix magnify during state setup
2019-01-22 14:37:33 -08:00
Aditya Bist
cff5482f69 Show Azure Data Studio instead of azuredatastudio when updating (#3787)
* show Azure Data Studio instead of azuredatastudio when updating

* added sql carbon tag
2019-01-22 10:58:40 -08:00
Alan Ren
afc37973d0 Update readme.md 2019-01-22 10:53:26 -08:00
Alan Ren
3eada6c6ab Create readme.md 2019-01-22 10:21:18 -08:00
Aditya Bist
7c39268fe5 Agent - bug fixes and mini features (#3637)
* fixed scrollbar in jobs

* show steps tree when job history is opened

* cleaned and added edit job to job history

* scrollbars on step details

* steps scrolling done

* fixed styling

* fixed keyboard selection, navigation and UI

* fixed tabbing accessibility

* added refresh action to job history

* fixed focus on move step

* added remove schedule button

* fixed various bugs

* added errors for all actions

* review comments
2019-01-22 10:01:13 -08:00
Alan Ren
eb67b299de Alanren/integration test (#3657)
* add an extension for integration tests

* setup ads before running test

* test setup

* test cases

* bash script

* shorter temp folder name

* code cleanup

* add commented out original code

* fix test error

* test result path

* rename results file

* change file path

* report smoke test results

* test stablize

* test stablization and configurable test servers

* fix smoke test error

* connection provider

* simplify the integration test script

* add comment

* fix tslint error

* address PR comments

* add temp log to check whether the environment variable is already set

* remove temp log

* move api definition to testapi typing file

* exclude integration tests extension

* address comments
2019-01-18 17:00:30 -08:00
Alan Ren
3e7a09c1e3 Alanren/profiler filter (#3760)
* profiler filter

* add test cases

* perf improvement with bulk insert

* update dependency version and address comments
2019-01-18 16:25:18 -08:00
Karl Burtram
637dc9b9b2 Bump Azure Data Studio to 1.4.2 2019-01-18 09:48:44 -08:00
Karl Burtram
1de16d4715 Reset query messages for each execution (#3772) 2019-01-17 17:53:05 -08:00
Kevin Cunnane
49090d774d Null ref occurred when doing some UI interactions before the notebook model was set (#3769) 2019-01-17 14:41:56 -08:00
Karl Burtram
9a695b5cdd Reenable results stream by default (#3752) 2019-01-17 10:28:48 -08:00
Raj
e0339b50c0 #3753: User settings configuration - python installation path (#3754)
* #3753: User settings configuration - python installation path

* Text change

* #3753: Text change

* Message change
2019-01-16 16:29:06 -08:00
Karl Burtram
d0c584672f Fix Top Operations tab title (#3751) 2019-01-15 16:06:51 -08:00
Anthony Dresser
27816acaeb Remove custom splitview (#3467)
* working on options dialog

* working through options dialog

* trying to work through modifying options dialog

* working on converting scrollablesplitview

* fixed options working through profiler

* fix profiler

* fix account dialog

* trying to fix problems with splitpanel

* fix insights dialog

* moving through

* fix last list, need to verify looks and functionality

* fix look of account dialog

* formatting

* formatting

* working through scrollable bugs

* working on problem with view size

* fix margin issues

* fix styler for dialogs

* add panel styles to insights

* create instantiation issues

* fix test

* fix test

* remove unused code

* formatting

* working through insight dialog issues

* fix table updating

* remove console logs
2019-01-15 15:00:34 -08:00
Mustafa Sadedil
4de3cc8a09 Completed: Missing feature request: Save as XML (#3729)
* Save as XML feature added to grid

* Unrelated code removed
2019-01-15 14:36:42 -08:00
Karl Burtram
5c16ceb2fa Bump SQL Tools Service to pick up https://github.com/Microsoft/sqltoolsservice/pull/763 (#3748) 2019-01-15 14:12:20 -08:00
Raj
9db3f73413 Notebook Doesn't Prompt for Save even when isDirty #3568 (#3656)
This is temp fix until native save is implemented.
2019-01-15 11:41:05 -08:00
Chris LaFreniere
e0ceddce09 Notebooks: Add Placeholder Cell, Fix Link Styling (#3728)
* Placeholder cell to add new real cells

* Fix links in notebooks to show correct color, rely on angular ngif for placeholder

* Fix failing test where one cell was expected by default

* Remove unnecessary TODO
2019-01-14 17:29:06 -08:00
Chris LaFreniere
6dc4096299 Editor focus based on activeCell, create text in edit, scroll to active (#3725) 2019-01-14 16:39:36 -08:00
Chris LaFreniere
1fa03b5c74 Ensure we always get all providers (#3724) 2019-01-14 16:38:57 -08:00
Kevin Cunnane
f8f57a93c3 Fix #3736 Notebook: cannot connect to SQL big data cluster due to empty config.json file (#3738)
- Writing the config file in the core for now, will look to move to the extension in Feb release
2019-01-14 14:14:32 -08:00
Karl Burtram
960fe63312 Bump Data Protocol client to 0.2.11 (#3739) 2019-01-14 14:04:35 -08:00
Karl Burtram
7545b94128 Turn off "something went wrong" message (#3606) 2019-01-11 17:39:13 -08:00
Karl Burtram
1263a27c1c Fix date in change log to 2019 (#3726) 2019-01-11 16:55:18 -08:00
Anthony Dresser
e1c084d365 fix html formatting in grid (#3722) 2019-01-11 16:24:50 -08:00
Karl Burtram
7465ec0bbd Add connection dialog icon dark theme and HC styles (#3721) 2019-01-11 13:38:43 -08:00
Chris LaFreniere
17ed57836f Fix focus issue when opening notebooks (#3711) 2019-01-11 11:37:49 -08:00
Chris LaFreniere
d0acb51fd7 Fix contentManager undefined when builtin manager used (#3710)
* Fix for contentManager undefined for builtin manager

* Clean up code some more
2019-01-11 10:36:36 -08:00
Anthony Dresser
71c1ed6c49 Add state for column sizing (#3683)
* add state for column sizing

* work properly with auto size columns
2019-01-11 10:25:57 -08:00
AlexFsmn
bfb68254a4 Added context menu for DBs in explorer view to backup & restore db. (#2277)
* Added context menu for DBs in explorer view to backup & restore db.
Fixed bug where progress bar didn't complete on backup/restore menuclick
#2084

* Fix merge conflicts
2019-01-11 10:00:16 -08:00
Anthony Dresser
18f7662209 Duplicate Result sets (#3620)
* remove debouncing and echoing to fix rendering bug

* fix access of internal member

* fix issue with using splice rather than slice

* fix compile issues
2019-01-10 13:44:14 -08:00
Karl Burtram
a0d84f383c Generate temp files as not dirty (#3698)
* Generate temp files as not dirty

* Remove whitespace
2019-01-10 12:51:41 -08:00
Karl Burtram
1f447ae681 Add Idera extension to recommendation list (#3709) 2019-01-10 11:54:39 -08:00
Kevin Cunnane
8bd6691331 Added v3 Notebook format support (#3697)
* Added v3 format support
2019-01-09 17:00:56 -08:00
Chris LaFreniere
42afcf9322 Integrate first SQL Notebooks Bits into Master (#3679)
* First crack tsql notebook (no output rendered yet)

* getting messages back

* intellisense working first cell, no connection errors

* sql notebook cell output functioning

* Latest SQL noteobook changes

* Undo change to launch.json

* Plumbing providers through

* Kernels shown from multiple providers, can switch between them. No mementos yet

* Ensure we have a feature flag for SQL notebooks, ensure existing functionality still works

* Fix tslint duplicate imports issue

* Addressing PR comments

* second round of PR feedback to cleanup notebook service manager code

* merge latest from master
2019-01-09 14:58:57 -08:00
David Shiflet
3d3694bb8d Add --command command line argument (#3690) 2019-01-09 17:36:01 -05:00
Anthony Dresser
589b913960 Readd Top Operations (#3628)
* workin on top operations

* added top operations, changed default sorter to handle number string better
2019-01-09 13:52:38 -08:00
kisantia
7ba4f42494 Moving onValidityChanged listener to showPage() so that it gets added to pages that are added to the wizard after the initial start up (#3691) 2019-01-09 13:19:24 -08:00
Chris LaFreniere
c96118d2b5 Fix activeCell nullref issue (#3689) 2019-01-09 11:45:05 -08:00
Karl Burtram
0285d8cd38 Update readme for January release (#3595)
* Update readme for December release

* Fix spelling

* Update release date to 12/13

* added release note items and fixed a small misspell

* Update release date to Dec 18

* Update release date
2019-01-09 10:12:14 -08:00
Matt Irvine
ee87604a4d Save grid selection/vertical scroll when switching tabs (#3682) 2019-01-08 15:51:57 -08:00
Kevin Cunnane
2235ebaf20 Fix #3680 Notebooks: outputs with string arrays rendered incorrectly (#3681)
* Refactor JSON and format files to model and fix tabs -> spaces issues

This is in prep for some work to reuse these code files inside the model,
so pushing as its own PR to keep the next piece of work clean.

* Fix #3680 Notebooks: outputs with string arrays rendered incorrectly
- Add support for processing v4 format files loaded from disk
- Prep support for v3 notebooks by adding placeholder code for that

* Fix failing tests and add specific one for this bug

* Remove references to v5
2019-01-08 15:24:16 -08:00
Anthony Dresser
954d0d954f Auto Column Sizing (#2778)
* add auto column sizing

* add break for performance

* update with new library
2019-01-08 13:05:53 -08:00
Kevin Cunnane
e31747d087 Refactor JSON and format files to model and fix tabs -> spaces issues (#3675)
This is in prep for some work to reuse these code files inside the model,
so pushing as its own PR to keep the next piece of work clean.
2019-01-07 14:02:12 -08:00
Anthony Dresser
fc581253a4 Fix gap with result streaming (#3629)
* handle updating item sizing when being updated

* change back scrolling delay

* remove unused code
2019-01-07 12:58:00 -08:00
Chris LaFreniere
47c4609f23 Ensure we call Dispose() on NotebookModel when notebook component is destroyed (#3667) 2019-01-04 12:00:42 -08:00
Chris LaFreniere
2d52bc2a49 Notebooks: Fix Selection/Focus when New Cells Added (#3649)
* Improvemnents to Active Cell

* Fix minor spacing issue

* fix editor focus order

* Fix for add cell above/below

* cleanup logic to have activeCell logic all reside in notebook model
2019-01-02 15:20:05 -08:00
kisantia
5367101330 Fix database not getting set correctly in DacFx wizard deploy scenario (#3641)
* fix db not getting set correctly for deploy scenario if coming from import page

* removed space so that comments go directly after //
2018-12-19 18:45:40 -05:00
Matt Irvine
db145b4999 Run TSLint in Azure Pipelines (#3639) 2018-12-19 12:17:23 -08:00
Matt Irvine
7f950ddb80 Update edit data for result set streaming changes (#3634) 2018-12-18 11:07:26 -08:00
Vincent Feng
50e2251e74 Feature/extensible azure resource explorer (#3504)
Extensible Azure Resource Explorer
2018-12-18 15:44:08 +08:00
Karl Burtram
33d5455b6f Update Azure Data Studio to 1.4.1 2018-12-15 14:47:47 -08:00
khoiph1
ac018500cd Loc Update (#3548) 2018-12-13 09:53:22 -08:00
Aditya Bist
3e661db283 removed potentially PII (#3619) 2018-12-12 13:55:22 -08:00
Anthony Dresser
18fb78b3ec Account for different situations for stream setting (#3615)
* add cases for different situation

* default streaming setting false
2018-12-12 12:03:59 -08:00
Matt Irvine
58ff13d399 Fix some TSLint issues (#3605) 2018-12-11 16:27:32 -08:00
Anthony Dresser
0ac0175bb1 update table size on result set update (#3604) 2018-12-11 15:05:28 -08:00
Anthony Dresser
f39007cd2d wrong variable name (#3603) 2018-12-11 15:05:11 -08:00
Yurong He
2349aa4df8 Fixed #3596 by change URI.parse to URI.file to get the path (#3597) 2018-12-11 11:23:29 -08:00
Yurong He
a93a173183 The CSS class is overwritten by the previous change. Add it back (#3583) 2018-12-10 17:36:58 -08:00
Anthony Dresser
42e55dd2dd Result Streaming settings (#3537)
* add setting control for result streaming

* change default result streaming to true
2018-12-10 17:36:35 -08:00
Raj
ca3146d38f Filetype while prmopting for save #3552 (#3575) 2018-12-10 17:02:16 -08:00
Alan Ren
7f6cd514a5 Alanren/profiler search (#3525)
* further improve the search experience for profiler

* change the default value for parameter
2018-12-10 16:43:58 -08:00
Aditya Bist
88e24e92b5 Agent: features and suggestions (#3512)
* removed row highlighting overlap with scrollbars

* fixed more styling suggestions

* made async calls parallel and improved UI

* cleared style
2018-12-10 16:36:41 -08:00
Anthony Dresser
8b447e361f change cancelation in the async data loader to correctly cancel requests (#3516) 2018-12-10 16:29:02 -08:00
Chris LaFreniere
a92dd2d4e4 Fix for PySpark3 not being selected by default (#3554) 2018-12-10 16:26:57 -08:00
Karl Burtram
852ec44567 Fix DataTier wizard null ref looking up provider with no active connection (#3528) 2018-12-10 16:26:06 -08:00
Raj
b6e32cdeb4 Rename notebook editor (fixes #3521) (#3536)
* Rename notebook editor #3521

* Review comments #3521
2018-12-10 13:26:29 -08:00
Alan Yu
4bd264d9be Add feature request template (#3487)
* Add feature request template

Github recently added feature for issue templates to also automatically assign a label. By setting this template, we can have some guidance for users who want to ask a feature request instead of an issue.

We can also have this be the default within the product when a user clicks "request a missing feature" on the smiley face button

* update label
2018-12-10 11:40:39 -08:00
Karl Burtram
4a4b8574d0 Update Azure Data Studio to 1.3.8 2018-12-10 11:30:20 -08:00
Yurong He
ded073edd9 Added clear output to ToggleMoreAction and added it to markdown preview (#3535)
* Added toggleMoreActions to Markdown Preview only.
When it is in editor mode, only editor display ToggleMoreActions.

* Added clear output back
2018-12-10 11:17:35 -08:00
Alan Yu
568f95e7a3 Update SQL Server Import readme extension (#3519)
Added DacFx wizard text
2018-12-10 10:42:13 -08:00
Chris LaFreniere
5adcabc8de Add back Notebook Completion List IntelliSense (#3520)
* Static notebook intellisense working

* Intellisense dynamic cells working

* Remove launch.json erroneous change

* PR comments #1

* PR feedback to change a minor condition
2018-12-07 18:04:32 -08:00
Kevin Cunnane
e3bce7172c Handle delayed Notebook provider registration (#3526)
* Handle delayed Notebook provider registration
- Fixes #3197 Notebooks: builtin provider always used on reopen with notebook file visible
- Fixes #3414 Can't refresh kernel after connect to big data cluster

There are 3 parts to this fix:
- If no notebook provider other than the default is installed, we warn users and prompt to install the SQL2019 extension
- We wait on the extension host registration to complete before determining which provider to use
- We know that the extension registration of the provider instance will be after package.json is read, so if we wait after registration for 10 seconds to give this a chance to happen before returning a provider to the front end

* Remove launch.json change that was added accidentally

* Fix timeout not being the expected value

* Removed console log left in during debugging

* Remove unnecessary whitespace

* Fix unit test failure

* Name the registration better, and remove outdated comments
2018-12-07 17:56:21 -08:00
Raj
96fb618390 Notebook saves are broken #3432 (#3478)
* Notebook saves are broken #3432

* Misc change

* Save notebook uri to This

* Untitled notebook save including review comments #3432

* Cleanup

* Misc changes
2018-12-07 16:27:23 -08:00
Alan Yu
2d4fdcb661 Updated SQL Server Import extension readme
Added Data-Tier Application Wizard
2018-12-07 15:26:48 -08:00
Yurong He
7a84cff5b4 Fixed #3508 by removing the fixed height of toolbar (#3518) 2018-12-07 15:16:53 -08:00
Yurong He
2af627b704 Fixed #3497 (#3517) 2018-12-07 14:16:00 -08:00
Alan Ren
77fdf18686 improve the visual effect for selected card (#3509)
* improve the visual effect for selected card

* remove shadow for unselected card as per Smitha's suggestion

* fix the issue of status icon not changing when new theme selected
2018-12-07 14:13:52 -08:00
Yurong He
944a77fe42 Fixed #3287 adding loading-spinner to markdown cell (#3505) 2018-12-07 13:07:00 -08:00
Chris LaFreniere
049678b32e Change notebook width to 100 (#3423) 2018-12-07 12:22:19 -08:00
Kevin Cunnane
3325e4d854 Fix #3422 Notebooks opened from within ADS should be Trusted by default. (#3498) 2018-12-07 12:14:57 -08:00
Kevin Cunnane
1e90e88d4b Fix #3481 Notebook: Markdown coloring appears incorrect (#3499)
- Set markdown as language for markdown cell
- Fix issue where after loading language from cell metadata, always override it. This made the "language" feature irrelevant in the cell.
- Fixed tests with new behavior (assumption: cell-level language overrides notebook-level definition) and added new test to cover this too
2018-12-07 12:14:43 -08:00
Kevin Cunnane
8aeb33c98c Fix #3470 Notebook: Switching between Servers and File Explorer opens a duplicate notebook (#3500)
- We missed implementing matches functionality. This is required in order to skip reopening of the notebook
2018-12-07 12:14:26 -08:00
Yurong He
3b08721835 Fixed #3415 add padding-left/right 8px (#3462)
* Fixed #3415 add padding-left/right 8px

* We will keep CSS consistent for review and editing mode. So removed codes not used.
2018-12-07 09:02:20 -08:00
Karl Burtram
5a30878599 Bump agent, import, profiler extension versions 2018-12-06 18:11:11 -08:00
Karl Burtram
c8a8935db0 Bump SQL Tools Service to 1.5.0-alpha.63 2018-12-06 17:58:49 -08:00
Aditya Bist
ec196f57bb Agent feature - ability to start at step (#3483)
* added ability to start at certain step

* fixed width for scrollbar

* localized string
2018-12-06 17:43:26 -08:00
Matt Irvine
f7809ec3a7 Add ability to select AAD tenant when connecting (#3475) 2018-12-06 10:46:27 -08:00
Kevin Cunnane
71d3ec3616 Fix #3420 Analyze in notebook doesn't include text (#3482)
- Add edit API that can be used in the extension
- Separated document and editor classes out since this is the point those get big. I can refactor back in if needed to ease code review
- Based this off text editing APIs but tweaked for the fact this is a cell/array based set of edits
2018-12-06 10:33:32 -08:00
Yurong He
4a7cf8d870 Disable key binding for this release. (#3466) 2018-12-06 10:04:02 -08:00
Alan Ren
4bf8836c0a profiler extension bug fixes (#3490) 2018-12-06 09:58:33 -08:00
ranasaria
1ca36ee29c bumping to version 62 to toolsservice to pick up resutlstreaming backend fixes 2018-12-05 22:39:23 -08:00
Yurong He
3446ff88cf Fixed #3472 check SaveKernelInfo not null (#3473) 2018-12-05 14:21:14 -08:00
Chris LaFreniere
de5a91a13f Allow for Notebook Cell Unselection (#3460)
* Allow for cell unselection

* PR Feedback: use event.stopPropagation() when multiple events can fire

* Ensure markdown goes into Preview mode when  cell not selected
2018-12-05 13:22:56 -08:00
Karl Burtram
814cd73019 Dispose of query grid memory on tab switch (#3458) 2018-12-05 12:17:16 -08:00
Aditya Bist
c21611661b Agent feature usage metrics (#3346)
* agent feature usage metrics

* generalized feature telemetry via dialogs

* renamed eventName property to dialogName

* made dialogName an optional field
2018-12-05 11:01:46 -08:00
Yurong He
8f817ce689 Fixed Notebooks regression: invalid kernels aren't handled #3404 (#3447)
* Fixed the not supported kernel in saved notebook

* Resolve PR comment.
2018-12-05 10:54:37 -08:00
Aditya Bist
971b5111e7 Agent: Scrolling (#3427)
* change height calcs to proper tree height

* agent fixes

* fit step tree

* fix rendering issue

* fixed spinning wheel position

* added horizontal scrolling to steps tree

* removed typo
2018-12-05 10:16:39 -08:00
Chris LaFreniere
07069a64ae Tweak notebook cell box shadow/border-width (#3454) 2018-12-04 19:21:55 -08:00
Karl Burtram
6acea51f12 Bump SQL Tools to 1.5.0-alpha.61 2018-12-04 17:51:51 -08:00
Raj
7aa2dab307 Defaulting 'attach to' to localhost when no extension is installed #3419 (#3426) 2018-12-04 13:45:10 -08:00
Raj
3091be8f67 Set active editor with dirty value before and after save #3411 (#3417) 2018-12-04 13:21:13 -08:00
Kevin Cunnane
487531cc52 Fix build break due to rename of APIs prior to checkin of unit tests (#3418) 2018-12-04 10:42:32 -08:00
Yurong He
58bfcb4273 Fixed can't read indexof exception when no big data cluster connection and switch to PySpark3 (#3413) 2018-12-04 10:36:34 -08:00
Kevin Cunnane
8d8be27f22 Add basic notebook model tests (#3396)
- Ported from the extension
- Only adding tests that related to the internally implemented functionality, not to anything provider-specific.
2018-12-04 10:01:10 -08:00
Yurong He
27a978cba5 Fixed #3387 (#3401) 2018-12-04 09:41:31 -08:00
Chris LaFreniere
71b4e6afa4 Fix Notebook Code Cell Height when Lines Wrap (#3403)
* Fix Notebook Code Cell Height when Lines Wrap

* Addressing PR comments
2018-12-03 20:55:46 -08:00
Chris LaFreniere
e1f3b19c0c Ensure Selectboxes in Notebook Toolbar have Minimum Size (#3393)
* Setting minimum width on selectboxes in notebook toolbar

* Fix spacing
2018-12-03 20:31:08 -08:00
Kevin Cunnane
649c2aa5a6 Fix preview handling so the untitled notebooks are pinned by default (#3405) 2018-12-03 20:26:42 -08:00
Kevin Cunnane
cac8cc99e1 Notebook extensibility: Move New Notebook and configuration to an extension (#3382)
initial support for Notebook extensibility. Fixes #3148 , Fixes #3382.

## Design notes
The extensibility patterns are modeled after the VSCode Document and Editor APIs but need to be different since core editor concepts are different - for example Notebooks have cells, and cells have contents rather than editors which have text lines.

Most importantly, a lot of the code is based on the MainThreadDocumentsAndEditors class, with some related classes (the MainThreadDocuments, and MainThreadEditors) brought in too. Given our current limitations I felt moving to add 3 full sets of extension host API classes was overkill so am currently using one. Will see if we need to change this in the future based on what we add in the additional APIs

## Limitations
The current implementation is limited to visible editors, rather than all documents in the workspace. We are not following the `openDocument` -> `showDocument` pattern, but instead just supporting `showDocument` directly.

## Changes in this PR
- Renamed existing APIs to make clear that they were about notebook contents, not about notebook behavior
- Added new APIs for querying notebook documents and editors 
- Added new API for opening a notebook
- Moved `New Notebook` command to an extension, and added an `Open Notebook` command too
- Moved notebook feature flag to the extension

## Not covered in this PR
- Need to actually implement support for defining the provider and connection IDs for a notebook. this will be important to support New Notebook from a big data connection in Object Explorer
- Need to add APIs for adding cells, to support 
- Need to implement the metadata for getting full notebook contents. I've only implemented to key APIs needed to make this all work.
2018-12-03 18:50:44 -08:00
Raj
cb162b16f2 No kernel is shown when open a new notebook from command palette (#3374)
Fixes #3271. Ensure a provider is defined when opening through command palette
2018-12-03 18:12:25 -08:00
Karl Burtram
86e54ce145 Bump Azure Data Studio to 1.3.7 2018-12-03 17:43:12 -08:00
Anthony Dresser
efd809971f fix row select (#3390) 2018-12-03 14:10:50 -08:00
Karl Burtram
38ae14cc4d Use UTF8 for Azure token cache (#3391)
* Switch token cache encryption encoding to UTF8

* Try to parse as binary in fallback

* Code review feedback
2018-12-03 14:09:42 -08:00
Chris LaFreniere
c7e33a90fe Notebook toolbar extensibility (#3362)
* Notebook Toolbar Contribution

* Address CR comments, ensure CSS can be passed in for contributed items
2018-12-03 11:15:14 -08:00
Yurong He
5add835750 Fixed issue: Notebook: Can't use PySpark3 even though having big data cluster connected #3363 (#3380) 2018-12-03 10:53:04 -08:00
Karl Burtram
734c614cba Update installer to regkeys for per-user install (#3376) 2018-11-30 16:56:19 -08:00
Karl Burtram
f6b347fa62 Bump Azure Data Studio to 1.3.6 2018-11-30 16:51:27 -08:00
Alan Ren
08d2f3125e Fix for issue 3133 (#3375)
* Fix for issue 3133

* fix test error
2018-11-30 15:53:36 -08:00
Matt Irvine
385c48dcad Wait for account provider registration when using account service (#3221) 2018-11-30 11:52:01 -08:00
Yurong He
0926057bfe Fixed #3294 removed dead code for "attach to" and remove disable to make it respond theme change (#3349)
* Fixed #3294

* Fixed #3294
2018-11-29 19:28:08 -08:00
Karl Burtram
6912e3893e Bump Azure Data Studio to 1.3.5 2018-11-29 17:12:32 -08:00
Karl Burtram
d3052657df Bump SQL Tools to 1.5.0-alpha.60 2018-11-29 17:12:05 -08:00
Karl Burtram
a5ca4d8edf Add ALTER and PROC to the colorization list (#3353) 2018-11-29 17:04:45 -08:00
Anthony Dresser
afb1ebebd5 Result Streaming (#3319)
* handle releasing data when the grid is unrendered

* update sqlops

* add complete to sqlops

* update protocol

* update protocol

* formatting

* update sqlops.d.ts

* stash

* better handling of results streaming

* formatting

* improvments to result streaming

* bump slickgrid and address a performance bottleneck

* remove unnecessary code

* formatting

* update locks

* optimize large values in the grid

* formatting

* formatting

* update yarn

* bump packages

* yarn

* bump

* yarn lock

* locking

* yarn

* fix duplicate result sets

* fix event stream versions

* yarn
2018-11-29 15:16:53 -08:00
Matt Irvine
a04a9eb5ad Hide connection account picker when there are no auth type options (#3350) 2018-11-29 14:54:46 -08:00
Cory Rivera
027badd21f Fix capitalization in dataTierApplicationWizard imports. (#3351) 2018-11-29 14:32:45 -08:00
Raj
1affc760e6 Notebook save functionality through button (#3340)
* 3268: Notebook save using button

* 3268: Misc change

* Handle promise while saving notebook

* Async await functions to run action
2018-11-29 14:10:16 -08:00
Yurong He
3ca72b7398 Fixed Spark UI links within Notebooks are not working notebooks sql2019Preview (#3344)
#3277
2018-11-29 12:52:18 -08:00
Yurong He
702dbddd78 Fixed some issues for Markdown and CSS (#3336)
* Fixed few markdown cell issues
* Change the boolean value from 1 to true
2018-11-29 12:50:53 -08:00
Aditya Bist
8fbecc0227 Fixed agent step update (#3308)
* fixed agent step update

* enabled reordering of steps in edit job
2018-11-29 10:48:12 -08:00
Alan Ren
421271acfa hide the profiler commands meant for internal use (#3339) 2018-11-28 15:03:53 -08:00
Raj
98af76b3ac Build error (#3335) 2018-11-28 10:45:21 -08:00
Raj
3952fdbe2d 3240: Empty cells show thick border (#3242)
* 3240: Empty cells show thick border

* 3240: Refactoring code and markdown css selection +output UI improvement
2018-11-28 09:45:34 -08:00
Yurong He
bc13beaa85 Revert "Hide run button in markdown editor and pull toggleMoreAction to a seperate class (#3321)" (#3328)
This reverts commit 9ea8baca05.
2018-11-27 23:43:16 -08:00
Karl Burtram
59b2e706ca Bump Import extension to 0.4.2 2018-11-27 17:59:34 -08:00
Karl Burtram
8bf835c531 Update SQL Tools Service to 1.5.0-alpha.59 2018-11-27 16:37:46 -08:00
Matt Irvine
087ed7c132 Make resource parameter optional for getSecurityToken API (#3322) 2018-11-27 16:12:30 -08:00
kisantia
4c075df327 DacFx import/export wizard (#3162)
Basic wizard to import/export bacpacs and deploy/extract dacpacs
2018-11-27 16:10:17 -08:00
Yurong He
9ea8baca05 Hide run button in markdown editor and pull toggleMoreAction to a seperate class (#3321) 2018-11-27 15:32:20 -08:00
Karl Burtram
9b6784720e Add EXCEPT,INTERSECT and DATALENGTH to color syntax (#3320) 2018-11-27 13:52:07 -08:00
Karl Burtram
3761e1dd60 Port event-stream changes from vscode (#3317) 2018-11-27 12:55:44 -08:00
Yurong He
b3eb809550 Hide ToggleMoreAction for inactive cell (#3235)
* Hide ToggleMoreAction for inactive cell

* Revert wrong merge

* Undo bad merge

* Enable markdown to hide ToggleMoreAction

* Resolve PR comments

* Fixed the name

* Change name

* Fix toggleMoreActions by passing in CellContext instead of just nb model

* Fixed the warning by removing notificationService from the caller
2018-11-27 12:54:27 -08:00
Matt Irvine
cb72865dcc Enable Azure Active Directory MFA authentication (#3125) 2018-11-27 11:13:47 -08:00
Anthony Dresser
d646b4729b Revert "Result Streaming (#3124)" (#3312)
This reverts commit 8925d44807.
2018-11-27 10:42:41 -08:00
Karl Burtram
a2dd903d0d Bump import, profiler, and agent extensions 2018-11-27 07:25:31 -08:00
Karl Burtram
28ed378ee7 Bump Azure Data Studio to 1.3.4 2018-11-27 05:53:43 -08:00
Karl Burtram
15ae55136f Bump event-stream to 3.3.4 2018-11-26 16:34:03 -08:00
Karl Burtram
b18abd954f Update Azure Data Studio to 1.3.3 2018-11-26 16:32:34 -08:00
Allen Cook
b45f79a1f8 Add Routine_Type to CreateStoredProc fixes #3257 (#3286) 2018-11-26 15:26:12 -08:00
Alan Ren
01a03b4c84 revert the taskbar icon size change (#3306) 2018-11-26 15:14:36 -08:00
Anthony Dresser
e48328af34 Handle qp clear input correctly (#3258)
* handle clearing xml in qp view

* formatting
2018-11-26 14:49:06 -08:00
Anthony Dresser
8925d44807 Result Streaming (#3124)
* handle releasing data when the grid is unrendered

* update sqlops

* add complete to sqlops

* update protocol

* update protocol

* formatting

* update sqlops.d.ts

* stash

* better handling of results streaming

* formatting

* improvments to result streaming

* bump slickgrid and address a performance bottleneck

* remove unnecessary code

* formatting

* update locks

* optimize large values in the grid

* formatting

* formatting

* update yarn

* bump packages

* yarn

* bump

* yarn lock

* locking

* yarn
2018-11-26 14:30:35 -08:00
Karl Burtram
213283510f Bump SQL Tools to 1.5.0-alpha.58 for results streaming 2018-11-26 13:54:56 -08:00
Alan Ren
9f8190dc28 make taskbar more readable (#3290) 2018-11-20 15:09:24 -08:00
Alan Ren
c32d4ee2f7 fix for 3245 (#3281) 2018-11-19 14:47:41 -08:00
Aditya Bist
2c867a4b2c unlocalized string (#3259) 2018-11-17 08:37:42 -08:00
Alan Ren
da5194bdcb fix for 3262 (#3263) 2018-11-16 21:19:32 -08:00
Chris LaFreniere
bbb27aed10 Notebook: Re-Enable Attach to Dropdown Functionality (#3250)
* first attach to working

* Transfer changes from sqlopsstudioextensions PR 448

* Transfer changes from sqlopsstudioextensions PR 447

* Transfer changes from sqlopsstudioextensions PR 456

* Transfer changes from sqlopsstudioextensions PR 465

* Transfer changes from sqlopsstudioextensions PR 463

* Transfer changes from sqlopsstudioextensions PR 482

* Transfer changes from sqlopsstudioextensions PR 485

* Session and Kernel implementation except executeRequest

* Attach to port compiling

* Further tweaks to attach to dropdown, re-enable opening connection dialog

* Revert "Merge remote-tracking branch 'origin/Notebook/sessionExtension' into feature/workingAttachTo"

This reverts commit 94703db87c85416c4ae36762afc1094d6e71166a, reversing
changes made to e4dc25331036d259e9c762cfe8741f957bb5c590.

* Fix code formatting

* Fix for new Add new connection issue
2018-11-16 20:47:58 -08:00
Alan Ren
c02fbaeae7 min height for event detail view when expanding (#3255) 2018-11-16 15:07:56 -08:00
Karl Burtram
847218da73 Disconnect Object Explorer node when session is disconnected from SQL Tools Service (#3249)
* WIP

* WIP

* Send disconnect event to OE

* Bump dataprotocol to 0.2.9

* Cleanupps

* Address a couple feedback
2018-11-16 13:08:20 -08:00
Kevin Cunnane
90dc788893 Implement Session support through the extension host (#3228)
Full plumb through of Session support. Also fixed some test issues

- Load session and get necessary information in kernels list
- Run Cell button now works as expected
- Added a ToggleAction base class which can be used for anything that switches icons. I'd still prefer to have this be dynamic and as clean as the extension classes
- Fixed account test unhandled promise rejections (caused by incorrect / invalid tests) that made it hard to see all the test run output.
2018-11-16 10:35:03 -08:00
Karl Burtram
f3525cc555 Bump Azure Data Studio to 1.3.2 2018-11-15 17:24:12 -08:00
abist
198f243181 scoped the agent action bar class style 2018-11-15 16:11:20 -08:00
Alan Ren
8e049f4af5 align the radio button with text (#3241) 2018-11-15 14:01:32 -08:00
Danny McCormick
ff465a59b6 Remove travis and appveyor (#3234)
* Delete .travis.yml

* Delete appveyor.yml
2018-11-15 11:52:36 -08:00
Danny McCormick
68b4f3ca04 Add Azure Pipelines status badge (#3233) 2018-11-15 11:51:42 -08:00
Chris LaFreniere
6b31f2b3f2 Stop Showing Overview Rulers in Notebooks (#3226)
* Stop showing decorationsOverviewRuler in notebook code cells by setting hidden visibility in css

* Also change overviewRuler options in IEdtorOptions for safety

* address CR comments in css file
2018-11-15 11:47:03 -08:00
Raj
63cf0f1548 Trusted/Not-trusted functionality implementation (#3211)
* 3194: Hookup trusted/not-trusted functionality and css changes

* 3194: Trusted implementation changes

* 3194: Code review changes

* 3225: No border in between code-cell and output
2018-11-14 19:07:10 -08:00
Yurong He
e607f68b3e Add more actions to cell (#3217)
* Added toggle more actions to cell

* Resolve PR comments
-- Added INotificationService for notification msg

* Reduced ToggleMoreAction to smaller size. So the dropdown could be displayed closer to it instead of at the buttom of the cell.
2018-11-14 17:51:59 -08:00
Yurong He
db3bb82dbd Change code and text font to 11 (#3216)
Ajust the padding top to 0
Change task bar height to 36
2018-11-14 15:36:24 -08:00
Yurong He
5889c600fa Resend selectBox change to on against master. PR against nativeNotebook was approved already. (#3215) 2018-11-14 13:48:41 -08:00
Matt Irvine
d7d4c7236c Update azure-pipelines-windows file test path (#3214) 2018-11-14 13:41:55 -08:00
Kevin Cunnane
f54d8ce36f Merge changes from the Notebook feature branch.
These will be preserved as they have important history.
2018-11-14 11:33:59 -08:00
Kevin Cunnane
43faa13cb5 Add notebook feature flag that is enabled by default (#3210)
* Add notebook feature flag that is enabled by default
- After this, the `notebook.enabled` flag must be set to true when testing notebook integration
2018-11-14 11:33:22 -08:00
Matt Irvine
85a2d994f3 Don't close connection dialog when cancelling a connection (#3207) 2018-11-13 16:44:26 -08:00
Kevin Cunnane
d8cd78cd6b Merge master 2018-11-13 16:35:17 -08:00
Alan Ren
3e59a5bcd2 update version to 0.4.0 (#3205) 2018-11-13 15:20:31 -08:00
Aditya Bist
0efb89d6ff fix loading perf when switching tabs (#3169) 2018-11-13 13:06:45 -08:00
Matt Irvine
6697c075cb Use newer version of request in azurecore (#3202) 2018-11-13 12:59:16 -08:00
Chris LaFreniere
06660160e7 Vertical Toolbar Improvements and Fix for Untitled File Load Issue (#3189)
* Add horizontal toolbar

* Add vertical toolbar

* Fix for untitled scheme file load

* further fixes to vertical toolbar

* Addressing PR comments
2018-11-13 11:05:54 -08:00
Kevin Cunnane
0b571737b7 Support notebook file types contribution (#3196)
* Support notebook file types contribution
- Extensions can define a provider and what file types it should be used for
- Verified that this works for Jupyter Content & Server Managers.
- Starts Jupyter server as expected

Not in this PR:
- Support for session manager end to end
- Tests
2018-11-12 17:32:53 -08:00
Raj
0a486a280d 3190: Code and Text cells from tool bar (#3191)
* 3190: Code and Text cells from tool bar

* 3190: Adding images under media folder and to css
2018-11-12 11:41:02 -08:00
Alan Ren
bd53e685d0 bump to .53 (#3187) 2018-11-09 10:57:30 -08:00
Raj
a2bbf3f44e 3147: Notebook markdown cell should be opened in preview mode (#3168)
* 3147: Notebook markdown cell should be opened in preview mode

* 3147: Default ability to double click a cell to add text

* Misc changes

* CSS cleanup

* Localization stuff

* Remove constants file in Notebook codebase
2018-11-09 10:38:14 -08:00
Alan Ren
410bb62906 fix for stop session error and session selection lost issue (#3167)
* fix for stop session error and session selection lost issue

* remove the console.error call
2018-11-08 16:51:39 -08:00
Alan Ren
cbb4ac3e20 make it preserve the line breaks (#3176) 2018-11-08 16:34:27 -08:00
Yurong He
7508192ab9 Added empty kernel and hook up with Kernel drop down (#3173)
* Initial toolbar work
- This is in-progress and needs additional fixes

* Resolve PR comments

* Added empty kernel and hook up with Kernel dropdown

* Resolve PR comments
2018-11-08 14:27:20 -08:00
Raj
bbf6cbd8fb Hookup trusted flag to both code cell and markdown preview (#3166)
* 1133: Notebook file registration changes

* File registration stuff

* Yarn files

* Outputview Changes

* Misc changes

* Changes to code component name space

* Output view changes

* notebook output view changes

* Latest changes

* Output view changes

* Code review changes on output view

* CSS file and misc changes

* Hookup trusted mode to code cell and markdown

* Return default sanitizer

* Misc changes - code review comments
2018-11-08 14:12:59 -08:00
Kevin Cunnane
9765269d27 Begin defining Extension-based Notebook Provider (#3172)
Implements provider contribution in the MainThreadNotebook, with matching function calls in the ExtHostNotebook class. This will allow us to proxy through notebook providers (specifically, creation of a notebook manager with required content, server managers) from an extension up through to the main process.

Implemented in this PR:
- Callthroughs for content and server manager APIs
- Very basic unit tests covering provider & manager registration

Not implemented:
- Fuller unit tests on the specific callthrough methods for content & server manager.
- Contribution point needed to test this (so we can actually pass through the extension's existing Notebook implementation)
2018-11-08 13:06:40 -08:00
Alan Ren
61746b7ff7 Update UX-Design-Guidelines.md 2018-11-08 10:37:45 -08:00
Alan Ren
e6066c2cb5 Rename UX-Design-Guidelines to UX-Design-Guidelines.md 2018-11-08 10:29:43 -08:00
Alan Ren
633a918590 Create UX-Design-Guidelines 2018-11-08 10:29:16 -08:00
Raj
71c14a0837 Output view changes (#3146)
* 1133: Notebook file registration changes

* File registration stuff

* Yarn files

* Outputview Changes

* Misc changes

* Changes to code component name space

* Output view changes

* notebook output view changes

* Latest changes

* Output view changes

* Code review changes on output view

* CSS file and misc changes
2018-11-07 14:19:33 -08:00
Alan Ren
9bbed2c275 fix for issue 3157 (#3158)
* fix for issue 3157

* use state instead of _state
2018-11-07 12:00:51 -08:00
Alan Ren
d9ba4d9130 profiler improvements (#3151)
* profiler improvements

* fix for issue 3114
2018-11-07 11:25:24 -08:00
Kevin Cunnane
ecd40de7ec Integrate notebook service with notebook UI (#3143)
Port notebookView code over to notebook.component.ts.
Integrate loading of notebook contents into the UI
2018-11-06 16:31:37 -08:00
Olivier Truong
e2bd6c06ec typo (#3025)
without instead of wihtout
2018-11-06 11:22:27 -08:00
Karl Burtram
a26be76d79 Update readme for Nov release (#3138) 2018-11-06 11:21:40 -08:00
Danny McCormick
3b68c1eb69 Add Azure Pipelines (#3140)
* Adding ci files

* Single pipeline

* Add test reporting

* Try adding mocha-junit-reporter

* More complete test reporting

* Cleaning up

* Trying to find location of test file

* Added searching logic to wrong file

* Trying different method of getting test results

* Add reporter option

* Adding alternate way of getting mac os

* Get rid of bad comments
2018-11-06 11:21:26 -08:00
Alan Ren
f7879bdbf9 Alanren/custom message box location (#3139)
* make message box associated with wizard page

* missed one condition check after renaming

* fix compilation error
2018-11-06 10:44:02 -08:00
Karl Burtram
dbb0fc519f Update Azure Data Studio to 1.3.1 2018-11-06 10:40:58 -08:00
Alan Ren
b931ccfabf fix for 1705 (#3131) 2018-11-06 10:34:58 -08:00
Matt Irvine
eeab048f46 Use correct foreground color for copy details button (#3126) 2018-11-06 10:14:25 -08:00
Yurong He
5da89ac05b Add localContentManger and dummy sessionManager (#3130)
* - keyboard binding to arrow keys
- toggle markdown editor by double click

* Added localContentManger and dummpy sessionManager
2018-11-05 17:55:13 -08:00
Anthony Dresser
e2b446be1c change default setting for showing default connection info in settings (#3043) 2018-11-05 16:08:55 -08:00
Anthony Dresser
5f2e17a738 Query Editor Memory improvements (#3041)
* working through memory issues

* work in progress

* add missing value

* work in progress

* more work in progress

* various more memory fixes

* additional improvements

* fix imports

* change test that we dispose queries on close not dispose

* update tests
2018-11-05 16:08:41 -08:00
Aditya Bist
399d6d0045 fixed operator typo (#3113) 2018-11-05 10:19:50 -08:00
Alan Ren
f36f3ffd21 connect dialog ux improvement (#3105)
* connect dialog ux improvement

* more style updates
2018-11-04 17:10:05 -08:00
Kevin Cunnane
3c785ae7d8 Merge master 2018-11-04 15:15:27 -08:00
Kevin Cunnane
00cd772cbc Snippets: fix sqlCreateTable, remove database refs & use dbo schema (#3094)
- Fixed issues with sqlCreateTable snippet, which meant it couldn't effectively be used to tab through all fields and then hit execute without errors. Specifically fixed bugs where types like NVARCHAR were incorrectly escaped and the Id part of a column was outside the name section, both causing intellisense & execution breaks
- Changed SchemaName to dbo. This helps hit the "80% case" where objects are in the most common schema
- Removed DatabaseName from most snippets. The core issue is this requires you to manually type the exact database name into the snippet which is really hard. We should consider having separate "with Database" snippets or support SQLCMD variables which would let us default to the current database without needing users to manually type them in as alternatives, but having basic snippets just work on current DB is important.
2018-11-02 14:26:03 -07:00
Kevin Cunnane
d434724a54 Remove handle from API (#3093)
- This was missed in previous checkin
2018-11-01 17:00:46 -07:00
Karl Burtram
b6c9a3bb89 Bump Azure Data Studio to 1.2.4 2018-11-01 15:06:58 -07:00
Kevin Cunnane
fc3bf45a7f Port most notebook model code over to be behind a service (#3068)
- Defines a new NotebookService in Azure Data Studio which will be used to interact with notebooks. Since notebooks can require per-file instantiation the provider is just used to create & track managers for a given URI.
- Inject this into notebook.component.ts and pass required parameters that'll be used to properly initialize a manger into the method. Actual initialization not done yet.
- Port over & recompile notebook model code
- Define most required APIs in sqlops.proposed.d.ts. In the future, these will be used by extensions to contribute their own providers.
2018-10-31 22:01:40 -07:00
Karl Burtram
cbf6c06e4b Bump SQL Tools to 1.5.0-alpha.52 2018-10-31 20:37:47 -07:00
Anthony Dresser
cff21124da Auto Scale Axis (#3070)
* fix input to chart that was causes scales to not auto size

* formatting

* formatting

* added comments
2018-10-31 20:27:40 -07:00
Aditya Bist
ce7893c2e5 Agent/edit job logic (#3023)
* lumped stepdata with jobdata in job dialog

* fix bug with empty steps

* added clumped and update steps and schedules from job dialog

* edit data sends one call instead of multiple

* cleaned code
2018-10-31 16:40:36 -07:00
Alan Ren
f7dcaa38ff fix for issue 3065 (#3067)
* fix for 3065

* remove the parameter, no need to save connection
2018-10-31 16:13:09 -07:00
Karl Burtram
8ce1013a26 Remove SQL Import dashboard tab (#3064) 2018-10-31 15:23:24 -07:00
Aditya Bist
114d67b408 fixed null ref (#3061) 2018-10-31 13:50:44 -07:00
Alan Ren
56c2d16560 a few ux improvements (#3057)
* style update

* checkbox styler

* casing update
2018-10-31 13:44:12 -07:00
Alan Ren
2238c42432 fix for issue 2719 (#3060) 2018-10-31 13:22:08 -07:00
Karl Burtram
64f6cf6747 Bump SQL Tools to 1.5.0-alpha.51 2018-10-31 13:16:38 -07:00
Karl Burtram
c0e9f1ca43 Fix build break in previous Query Plan commit 2018-10-31 13:00:23 -07:00
David Shiflet
7f66087d8c Add a command line interface for connecting to a SQL Server (#3047)
* Add switches for server, database, user, integrated auth

* Refactor into new commandline service

* Open query editor when passed server on command line

* Add tests
2018-10-31 13:05:37 -04:00
Ryan
18671b7cca Add query plan theme support (#2991) (#3031)
Add monaco-editor and monaco-editor-hover to output otherwise backgrounds collide.
2018-10-31 10:03:02 -07:00
Alan Ren
233156c744 fix missing footer for backup dialog (#3056)
@MattIrv  Thanks for helping out
2018-10-30 16:17:14 -07:00
Kevin Cunnane
ac0ffab99c Merge remote-tracking branch 'origin/master' into feature/nativeNotebook 2018-10-30 16:08:19 -07:00
Ruturaj Gujar
5e964d2105 Fixed some typos and grammatical errors (#3027) 2018-10-30 11:54:48 -07:00
Karl Burtram
59e7a5fa4b Change 'None' to 'Do not save' in Connection Dialog (#3051) 2018-10-30 10:45:47 -07:00
Karl Burtram
8452f577d2 Bump Azure Data Studio to 1.2.3 2018-10-30 10:27:03 -07:00
Anthony Dresser
726eb8d0e1 Time elapsed status item (#3006)
* added time elapsed status item

* add missing files
2018-10-29 15:24:08 -07:00
Anthony Dresser
2c0d6b93ee move query actions from underneath scrollbar, permanently show scrollbar (#3007) 2018-10-29 15:23:55 -07:00
Karl Burtram
98d06b2892 Format JSON and XML output when clicking resultgrid link (#3024) 2018-10-26 17:33:46 -07:00
Abbie Petchtes
533f2734f1 Add markdown cell to Notebook (#3014)
* add markdown cell

* add markdown preview for Notebook

* formatting

* address comment
2018-10-26 16:20:06 -07:00
Karl Burtram
856c19fa17 Update SQL Tools Service to 1.5.0-alpha.48 2018-10-26 16:02:40 -07:00
Alan Ren
3237507bb2 Alanren/modal message high contrast fix (#3018)
* make modal dialog message section HC aware

* handle warning icon
2018-10-26 15:38:51 -07:00
Anthony Dresser
ff5a248240 Clean up result tab better (#3015)
* do a better job cleaning up results tab

* formatting
2018-10-26 13:27:01 -07:00
Adam Warner
fc3bdc9037 Update CONTRIBUTING.md (#3009)
Replace `�` with  👍 and 👎 reaction emojis to ensure it is clear which reactions to use when up/downvoting and issue.
2018-10-26 10:29:46 -07:00
Vincent Feng
533c0bf0b1 Azure Resource Explorer: fixed regular expressions in context item rules. (#3003)
* Azure Resource Explorer: fixed a bug in refresh button rule.

* Azure resource explorer: fixed regular expressions in context item rules.
2018-10-26 14:43:41 +08:00
linda07
afb6862035 Adjust notebook toolbar icon to 20px and font size to 13px (#3001) 2018-10-25 14:51:48 -07:00
Alan Ren
92d9d04a78 make checkbox vertically aligned and remove the x scroll for modaldialog (#3005) 2018-10-25 14:26:44 -07:00
Karl Burtram
0704e5ee67 Update SQL Tools to 1.5.0-alpha.47 2018-10-24 17:52:15 -07:00
Anthony Dresser
7dfcd89a04 Rework timeSeries in chart viewer (#2987)
* rework timeSeries in chart viewer

* rework important to fix tests
2018-10-24 14:58:24 -07:00
Raj
2859bee4c0 1133: Notebook file registration changes (#2969)
* 1133: Notebook file registration changes

* File registration stuff
2018-10-24 13:47:41 -07:00
Alan Ren
724c49f5c4 Fix for issue 2725 and ux fixes (#2992) 2018-10-24 11:02:08 -07:00
Raj
48c4a473df [2977]OpenConnectiondialog doesn't filter controls based on connection type (#2986)
* Get latest from master

* 2977: OpenConnectiondialog doesn't filter controls based on connection

* 2977: OpenConnectiondialog doesn't filter controls

* Misc change

* [2977]OpenConnectiondialog - code review changes
2018-10-24 10:47:12 -07:00
Aditya Bist
3d39272536 Agent/operators (#2962)
* added caching and view for operators

* fixed row detail import
2018-10-23 15:22:44 -07:00
Karl Burtram
0a63966cbd Update Azure Data Studio to 1.2.2 2018-10-23 14:52:32 -07:00
Aditya Bist
89e959c2e3 Agent/alerts (#2943)
* alerts view is now cached

* added styling to alerts page

* fixed row detail view import
2018-10-23 14:42:31 -07:00
hungrybear88
c56dd2cdbd add key command ctl + L to run query plan (#2952)
* add key command ctl + L to run query plan

* fix to match SSMS for getting query plan
2018-10-23 14:04:02 -07:00
Aditya Bist
363f28a46b Agent - proxies (#2970)
* initial proxy work

* fixed proxies view and cached the view
2018-10-23 13:55:19 -07:00
Anthony Dresser
5549f51a13 Fix time series (#2985)
* fix time series type string

* remove unused code
2018-10-23 13:52:35 -07:00
Abbie Petchtes
972f857c71 Cell code fit and finish (#2972)
* add the look and feel for code cell

* formatting

* adding the active cell

* formatting
2018-10-23 12:22:19 -07:00
AbbiePetcht
d2eb1488fd Merge branch 'master' into feature/nativeNotebook 2018-10-23 10:23:10 -07:00
Alan Ren
82486ee22e Wizard message UI improvement (#2971)
* improve the wizard message experience - WIP

* undo gitignorechanges

* fix expand button issue

* fix the cursor issue

* use flex to control height

* toggle message detail support

* apply style

* new images

* use template string

* address comments
2018-10-22 23:53:28 -07:00
Karl Burtram
29cc57f52a Remove unhandled exception telemetry (#2973)
* Remove unhandled exception telemetry

* Remove additional unhandled exception tests

* One more failing test
2018-10-22 22:05:01 -07:00
Karl Burtram
f7d92caae5 Correct SQL Tools Service filenames to netcoreapp2.2 2018-10-22 17:20:30 -07:00
Karl Burtram
201174e293 Bump Azure Data Studio to 1.2.1 2018-10-22 17:11:41 -07:00
Karl Burtram
dc2f6235a1 Update SQL Tools Service to 1.5.0-alpha.46 2018-10-22 17:04:54 -07:00
Todd Ortmann
0824c779db Fixed sync issue with my forked master so this commit is correct (#2948) 2018-10-19 16:16:40 -07:00
Anthony Dresser
e002ad3b6a fix test errors (#2938) 2018-10-18 13:27:30 -07:00
kenvanhyning
8a570069f8 Kenvh/editdatatabname (#2906)
* Remove unnecessary string encoding on edit data naming

* Cleaning up duplication in the naming methods.

* fix typo in method name
2018-10-18 12:58:07 -07:00
Karl Burtram
bfe44c1621 Update README for October release (#2950) 2018-10-18 07:35:44 -07:00
Karl Burtram
b17882a1c1 Bump agent and import extension versions (#2949) 2018-10-17 21:41:18 -07:00
Gene Lee
f309979126 Added feature to disable checkbox of checkboxTreeNode (#2942) 2018-10-17 19:26:56 -07:00
Matt Irvine
5a0490e81f Display multi-line messages correctly in query results (#2935) 2018-10-17 15:43:00 -07:00
Karl Burtram
2c007115f7 Fix query plan scrollbars (#2927)
* Fix query plan scrollbars

* Remove toString
2018-10-17 12:04:42 -07:00
AbbiePetcht
508e4eac61 Merge branch 'master' into feature/nativeNotebook 2018-10-17 10:58:49 -07:00
Chris LaFreniere
ac47fb84a8 Fix Default Height for Editor Component (#2920)
Editor component didn't have a minimum height set, so fixing this by passing through a minimum height to EditorComponent. Now, if the scrollable height of the editor is less than the minimum height, we use the minimum height as the height of the component.

Also fixed an issue where the markdown code editor's height was far too high. Now we're calculating the height on the layout() call, which gets called every time we display the markdown editor.
2018-10-17 10:18:04 -07:00
Aditya Bist
7ba14a3925 schedules now get added in edit job (#2915) 2018-10-16 22:51:54 -07:00
Anthony Dresser
67514ccc5f change scroll container to fix ui glitch (#2924) 2018-10-16 21:55:21 -07:00
Anthony Dresser
6ee3886ecf clear out plan xml on executes (#2921) 2018-10-16 18:31:19 -07:00
Anthony Dresser
76282ed1ef Look for showplan colum name (#2919)
* change method for finding show plan through column name

* formatting
2018-10-16 18:12:01 -07:00
AbbiePetcht
fd1d807012 Merge branch 'master' into feature/nativeNotebook 2018-10-16 16:30:11 -07:00
Abbie Petchtes
906c4c7f39 Add code cell (#2909)
* initial work for addig code and code cell type

* add cell model and create editor for each cell

* formatting

* fix resizing issue

* small changes

* address comment
2018-10-16 16:28:15 -07:00
Anthony Dresser
bfa9e8c495 Handle query plan flow problems (#2918)
* modify the query plan work flow to account for some errors

* formatting
2018-10-16 16:15:47 -07:00
Aditya Bist
425eecf692 Agent/edit steps (#2846)
* steps can be now edited

* edit jobs now works with steps, alerts, schedules etc

* fixed bug when new step in new dialog would fail
2018-10-16 13:24:43 -07:00
Anthony Dresser
ac1f7542a9 change way we show query plan (#2866) 2018-10-15 17:18:14 -07:00
Karl Burtram
225d168fdd Add SQL vNext to recommended extensions list (#2858) 2018-10-15 16:10:00 -07:00
Karl Burtram
e073b2cf42 Change 'Clear All' to 'Show All Connections' (#2865) 2018-10-15 16:04:36 -07:00
Karl Burtram
1cb366d822 Update product name in Register Files setup checkbox (#2857) 2018-10-15 13:55:02 -07:00
Kevin Cunnane
c9c8e30ced Remove os.tmpDir deprecation warning (#2855)
- Import extension used very old version of telemetry. Updating avoids sending deprecation warning to console which CSS requested we fix.
2018-10-15 13:41:54 -07:00
Karl Burtram
c50941ac7d Update Azure Data Studio to 1.1.3 2018-10-15 13:15:36 -07:00
Karl Burtram
58f950ffbd Bump version to 1.1.2 for next build. 2018-10-12 16:43:03 -07:00
Alan Ren
a1341ba503 revert row edit and dirty row fix (#2845)
* revert row edit and dirty row fix

* undo the dirtyRow change
2018-10-12 16:39:08 -07:00
Matt Irvine
620f4a8bfb Bring in tools service fix for expanding columns being slow (#2844) 2018-10-12 16:22:36 -07:00
AbbiePetcht
668e43f57c Merge branch 'master' into feature/nativeNotebook 2018-10-12 13:01:43 -07:00
Todd Ortmann
7f11d44130 Fixed when right clicking and selecting Manage-correct name displays (#2794) 2018-10-12 11:15:05 -07:00
Chris LaFreniere
5c77e752f6 Allow for auto-resizable editor component (#2818) 2018-10-11 16:18:58 -07:00
Abbie Petchtes
6d260c195f create new notebook editor and add the place holder for toolbar and cell list (#2817)
* create new notebook editor and add the place holder for toolbar and cell list

* address comments
2018-10-11 16:14:54 -07:00
AbbiePetcht
fdfecbb3f7 Merge branch 'master' into feature/nativeNotebook 2018-10-11 10:23:30 -07:00
Alan Ren
1d8132bcaa Alanren/edit data1004 (#2781)
* edit data bug fix

* rename the event and use undefined instead of null

* use thenable instead of callback

* handle the new SlickGrid OnRendered event to control the keyboard focus

* use the new event to control the focus and change the add row behavior
2018-10-11 09:53:41 -07:00
Karl Burtram
5f1bde5885 Merge azure account provider and azurecore extensions (#2810) 2018-10-11 09:52:43 -07:00
Anthony Dresser
0adb025573 add horizontal scroll to message pane (#2787) 2018-10-10 15:44:30 -07:00
Karl Burtram
f8e7623f23 Bump minimatch node module (#2808) 2018-10-10 11:49:37 -07:00
ranasaria
9243cceb9a Merge latest master into local repo 2018-10-10 11:36:48 -07:00
ranasaria
5a62035ed7 Support to configure logging levels for sqltools services (#2731)
* Adding support for configuring SqlTools log levels from user configuration. This also adds changes to see the tail of the sqltoolsservicelayer log file in the newly created 'Output->Log (SqlTools)' channel

* Three new user settings control how logging happens. tracingLevel, logRetentionMinutes & logFilesRemovalLimit. Default tracingLevel is set to 'Critical'. 

* The logfiles include ui Extension host process id in their log file names. This ensures that filenames from multiple instances of Azure Data Studio running do not collide with each other. Furthermore log directory for  being used for the tools service backend processes. This ensures that there is no name conflict when multiple instances of azuredatastudio are running on the same box. Also when azuredatastudio is started from vscode under debugger the log directory is set to %APPDATA%\Code\mssql while the official location is %APPDATA%\azuredatastudio\mssql. So dev environment should not affect other running instances. Kindly note that all debug runs of azuredatastudio share the same directory and all non debug runs share a directory different from those running under debugger. 

* Log files older than a week get cleaned up upon start-up. The log file cleanup behavior can be controlled at user level by  logRetentionMinutes & logFilesRemovalLimit settings.
2018-10-10 11:24:13 -07:00
Karl Burtram
c3a81b5bf3 Add back Azure Resource Explorer extension with updated build script (#2805)
* Revert "Revert "Port the Azure Resource Explorer extension to core." (#2770)"

This reverts commit 210447cd37.

* WIP1

* Add custom build task for azurecore extension

* Fix azurecore output path for macOS build

* Fix linux gulp task name
2018-10-09 19:43:55 -07:00
Matt Irvine
34f6811eea Bring back Connection Config tests (#2795) 2018-10-09 11:12:12 -07:00
Aditya Bist
c800e70ec1 Agent - Step Actions (#2779)
* fixed right click context menu bug in jobs view

* added stepInfo and edit job WIP

* show jobs in job edit

* added schedule description on select schedule

* fetch schedules during history and show in edit job

* added alerts to job histories and show in edit

* made history calls async

* filter menus now close when esc is pressed

* fixed bug where clicking on error row wouldnt populate job details

* added functionality to delete steps in a job

* added real time adding steps in edit job
2018-10-09 10:28:55 -07:00
Anthony Dresser
7aa2ee08bf properly reset to handle maximized grids (#2786) 2018-10-08 17:30:08 -07:00
Anthony Dresser
933aa88dc7 Account for Horizontal Scrolling in Grid (#2774)
* implement horizontal scroll login in the grid plugin

* remove commented code

* formatting
2018-10-08 17:24:40 -07:00
Matt Irvine
4b79ecc3d9 Fix bug disconnecting during stuck OE operation (#2773) 2018-10-08 15:42:13 -07:00
Matt Irvine
0bd179c6ca Fix bug where connections edited in connection dialog moved to bottom of group (#2782) 2018-10-08 15:41:55 -07:00
Keith Stolte
70141bd049 Fix Invalid Configuration in Launch.json (#2789) 2018-10-08 13:58:18 -07:00
Keith Stolte
65cc585697 Fixing a reference to SQL Ops Studio (#2788)
📝 (Contributing) Fixing a reference to SQL ops studio to match new branding of Azure Data Studio.
2018-10-08 13:57:54 -07:00
Karl Burtram
bd39468b96 Bump SQL Tools Service to 1.5.0-alpha.41 2018-10-08 13:49:08 -07:00
Matt Irvine
dad831bc8c Fix bug where failed OE expands could not be retried (#2780) 2018-10-08 11:16:11 -07:00
Matt Irvine
8a8745701b Stop OE connection spinner when user closes connection dialog (#2777) 2018-10-05 14:14:19 -07:00
anthonypants
48b899b5d0 Typo (#2775)
Adam Mechanic => Adam Machanic
2018-10-05 13:02:06 -07:00
Karl Burtram
210447cd37 Revert "Port the Azure Resource Explorer extension to core." (#2770)
* Revert "change how query plan is handled (#2735)"

This reverts commit 0693080630.

* Revert "center the icon (#2760)"

This reverts commit 75d27837c2.

* Revert "Alanren/edit data improvement (#2748)"

This reverts commit 597f29e90a.

* Revert "Port the Azure Resource Explorer extension to core. (#2701)"

This reverts commit a77bb50b9e.
2018-10-05 12:40:56 -07:00
Anthony Dresser
e672fbf6e2 change selection on header selection to provide 1 selection not 1 million (#2757) 2018-10-05 11:25:28 -07:00
Matt Irvine
004464c699 Fix tab color break caused by VS Code merge (#2761) 2018-10-04 15:33:03 -07:00
Aditya Bist
6f39a37656 Agent/history update (#2756)
* refresh history when job is run

* refresh history and jobs when stopped
2018-10-04 13:54:17 -07:00
Aditya Bist
b097b54792 Agent: Edit Job improvements (#2721)
* fixed right click context menu bug in jobs view

* added stepInfo and edit job WIP

* show jobs in job edit

* added schedule description on select schedule

* fetch schedules during history and show in edit job

* added alerts to job histories and show in edit

* made history calls async

* filter menus now close when esc is pressed

* fixed bug where clicking on error row wouldnt populate job details
2018-10-04 13:52:25 -07:00
Anthony Dresser
0693080630 change how query plan is handled (#2735) 2018-10-04 11:48:41 -07:00
Phil Campbell
75d27837c2 center the icon (#2760) 2018-10-04 11:44:26 -07:00
Alan Ren
597f29e90a Alanren/edit data improvement (#2748)
* improvements for dirty indicator and tab switching scenario

* rename the event

* update the angular2-slickgrid version
2018-10-03 13:13:21 -07:00
Kevin Cunnane
a77bb50b9e Port the Azure Resource Explorer extension to core. (#2701)
* Port the Azure Resource Explorer extension to core.

This will enable Azure viewlet by default in the next release.

- Moving this code from the SQL Server 2019 extension to Azure Data Studio core
- Ported tests and verified they work in the integration tests.sh file
- Fixed an issue that caused integration tests to fail if you have a SQL Server 2019 big data cluster endpoint listed, but the extension isn't installed.
2018-10-03 10:41:07 -07:00
Dinakar Nethi
3f84e8e652 Updated formatting changes (#2747) 2018-10-02 17:27:32 -07:00
kenvanhyning
1df7f25cad add sql class for task icon images (#2736) 2018-10-02 11:25:01 -07:00
Gene Lee
a0c30517bd Fix for broken checkbox status in checkbox tree node (#2705) 2018-10-01 16:58:22 -07:00
ranasaria
dc36a9c3e7 Merge branch 'master' of https://github.com/Microsoft/azuredatastudio 2018-09-28 17:10:39 -07:00
Karl Burtram
0e61ad27da Bump Azure Data Studio to 1.0.1 2018-09-28 13:52:34 -07:00
ranasaria
b3009c3366 Merge branch 'master' of https://github.com/Microsoft/azuredatastudio 2018-09-26 17:44:40 -07:00
Matt Irvine
810073a79b Make sure new queries are connected for unsaved password (#2633) 2018-09-26 16:21:07 -04:00
Karl Burtram
79c69d03fa Fix Gitter link (fix typo) 2018-09-26 11:26:35 -07:00
Karl Burtram
22996da737 Fix Gitter link in readme (#2698) 2018-09-26 11:24:26 -07:00
ranasaria
82d0b6c9f0 Bumping toolservice version to 36 2018-09-26 10:32:12 -07:00
Alan Ren
77c997b91e make events to open new sql query window (#2688) 2018-09-25 09:47:52 -07:00
Karl Burtram
bb5d52d72c Merge Azure Data Studio branding changes (#2689)
* Bump Electron to 2.0.8 and SQL Ops to 0.33.3 (#2466)

* Merged PR 328: Initial "Azure Data Studio" branding changes

* Alanren/icon overwrite issue (#2484)

* fix the error icon too large issue

* formatting

* add logic to hide and add grid panel based on size (#2481)

* add grid styles (#2483)

* Add check for potential failure in handling drag (#2499)

* add check for potential failure in handling drag

* move check to avoid ui glitches

* Reorder Connection Name field in Connection Dialog (#2498)

* change cursor in message panel to default (#2494)

* add select all handler to grid (#2496)

* Fix macOS titlebar branding

* add animation when button is clicked and fix title in button (#2488)

* add animation similar to toolbar in vscode and fix title in button

* remove bur method in button

* Disable the User Setup prompt (#2501)

* fixes a rendering problem in splitview (#2512)

* add listener to change action bar on maximize change (#2505)

* fix the save and save all for untitled file (#2526)

* add check for selection model in edit data (#2517)

* add min size for row num column (#2518)

* expand messages panel on error (#2519)

* Selection in grid context (#2527)

* update action context on selection change

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

* add required functions to typings

* Fixes #2523 (#2528)

The IdGenerator was recreated each time and had a high likelihood of conflicts. Invitably after adding dozens or hundreds of icons you'll start seeing the CSS class replaced and overridden.

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

Side note is that it'd be a good idea to cache CSS rules with the same iconPath so we don't create lots of additional rules unnecessarily. If we reuse the same icon a bunch we should cache them - #2524 is tracking this.

* Fix grid gaps (#2531)

* modifying grid gaps

* reduce gaps and increase gap for action bar

* fix grid action bar not updating (#2532)

* Turn-off Git missing prompt (#2533)

* Reduce message panel min size to 0 (#2534)

* reduce message panel minimum size to 0; attempt to restore panel sizing on requery sizes; default grid panel size to 80%

* formatting

* Fix bug around debounced event not being flushed in time (#2536)

* fix bug around debounced event not being flushed in time

* add comment

* Fix build break in Git extension (#2538)

* Update SQL Ops to 0.33.4

* Fix sizing error when switching windows (#2544)

* add work around for when we need to resize while we don't have a dimension to resize off of

* formatting

* change active cell during change to fix focus shift (#2545)

* fix the account not found error when creating firewall rules (#2543)

* Support isDirty flag for model view editors and begin plumb through of save support (#2547)

* Add dirty and save support to model view

* Add issue # for a TODO

* add divcontainer in modelview (#2559)

* add divcontainer in modelview

* address comment

* Bug/extension contribution (#2560)

* revert 4ab5d84b94

* fixed extensions

* Merged PR 352: Switch settings folder back to .sqlops

Switch settings folder back to .sqlops

* fix the connection issue when opening new query after connection (#2561)

* Update SQL Ops to 0.33.5

* Disabled connection name input when connecting to a server. (#2566)

* Disabled connection name input when connecting to a server.
#2557

* Fixed reset state of connection inputs

* added context to chart buttons so they work (#2575)

* accessibility setting based select database dropdown (#2579)

* Maintain Query State (#2571)

* add results view stating

* working through the bugs

* handle various resizing bugs

* gnale resizing better

* fix tests by adding missing node module

* formatting

* refactor interfaces out to get around testing restrictions

* more refactoring of importants to avoid loading errors

* use latest slickgrid library (#2584)

* Add OE node refresh API method (#2578)

* Initial working commit for refreshing OE node via API

* Add test and fix up code

* Run tsfmt

* Fix test

* Merged PR 356: Fix getDefaultLogLocation to use 'Azure Data Studio'

Update getDefaultLogLocation to use 'Azure Data Studio' to fix Azure Account creation on macOS.

* Update SQL Ops to 0.33.6

* Fix crash when reverting in edit data with no changes (#2594)

* edit data issue with column index handling (#2595)

* fixed insights crash (#2596)

* Changed the "Configure" link to "Learn How To Configure The Dashboard". (#2599)

* Changed the "Configure" link to "Learn How To Configure the Dashboard".
This inlcudes the command as well as the tile label
#1227

* Capitalizing first character in each word

* The "New Query" context menu is now only available from the server & db (#2598)

#1890

* Merged PR 366: Revert to using 'sqlops' so settings are maintained during upgraded

Revert to using 'sqlops' so settings are maintained during upgraded

* Merged PR 371: Fix casing for AZURE DATA STUDIO in EULA

Fix casing for AZURE DATA STUDIO in EULA

* Merged PR 375: Create new appid

Create new appid

* Merged PR 376: Update settings path back to  'azuredatastudio'

Update settings path back to  'azuredatastudio'

* Fix/bump dependency versions (#2608)

* Use version 2.0.9 of electron (#2606)

* fixes scrolling in query plan (#2609)

* Dashboard: Fixed all insight bugs (#2612)

* fixed all insight bugs

* removed unused imports

* added comment

* add view area options to pick up chart background fix (#2613)

* Respect message settings (#2614)

* add results view stating

* working through the bugs

* handle various resizing bugs

* gnale resizing better

* add configuration to state

* address comments

* Fix stating for scrolls (#2615)

* nearly working

* add accounting for the downsides to slickgrid

* Update SQL Ops to 0.33.7

* Added text underline CSS for DB NULL values when editing / showing data (#2597)

* Added text underline CSS for DB NULL values when editing / showing data
#217

* Changed db nulls styling to italic

* Bug/oetimeout Fix - When timeout happens while fetching node children, the node becomes unusable (#2616)

This commit fixes issue when multiple OE nodes are expanded simultaneously. While the error was getting displayed the node was left in incorrect state which was leading to the node being unusable in future. This commit repairs this defect.

* fixed actual show plan command (#2620)

* Bump SQL Tools Service to 1.5.0-alpha.34 (#2621)

* Feat/add dom component (#2622)

* add dom component for model view

* formatting

* make css style hardcoded in dom.component

* comment out the unused CSS

* address comments

* address comment

* Hide tabs on reexecute (#2624)

* add logic to hide tabs when a query rerun is executed

* remove double entry in the map

* Bump Azure Data Studio to 1.0.0

* Bump Azure Data Studio to 0.33.8

* Scroll query editor when clicking batch links (#2644)

* Fix broken 'Clear Token Cache' command (#2643)

* fixed right click context menu bug in jobs view (#2632)

* fix css issue (#2650)

* reload the chart types when we actually need it (#2651)

* Bump Azure Data Studio to 1.0.0

* Fix chart error that caused query editor to close (#2652)

* Bump Agent, Import and Profiler extension versions
2018-09-24 15:39:19 -07:00
Alan Ren
1474bab34a use a more specific class to control the width (#2664) 2018-09-24 10:21:52 -07:00
Matt Irvine
05f6f4ea5b Scroll query editor when clicking on global find result (#2665) 2018-09-24 08:46:14 -07:00
Karl Burtram
05feb39501 Fix typo in changelog 2018-09-24 08:38:32 -07:00
Karl Burtram
ce92c3329b Update README for 1.0 release (#2677) 2018-09-24 08:37:49 -07:00
Matt Irvine
216b6eecc0 Fix chart error that caused query editor to close (#2652) 2018-09-20 14:29:05 -07:00
Alan Ren
c0917e9276 reload the chart types when we actually need it (#2651) 2018-09-20 12:38:36 -07:00
Abbie Petchtes
0bbcbf0d2d fix css issue (#2650) 2018-09-20 12:16:20 -07:00
Aditya Bist
9b998e3fca fixed right click context menu bug in jobs view (#2632) 2018-09-19 20:19:48 -07:00
Matt Irvine
d7d65cdf21 Fix broken 'Clear Token Cache' command (#2643) 2018-09-19 18:31:23 -07:00
Matt Irvine
27925289d4 Scroll query editor when clicking batch links (#2644) 2018-09-19 17:27:10 -07:00
Anthony Dresser
03ea265bab Hide tabs on reexecute (#2624)
* add logic to hide tabs when a query rerun is executed

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

* formatting

* make css style hardcoded in dom.component

* comment out the unused CSS

* address comments

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

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

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

* working through the bugs

* handle various resizing bugs

* gnale resizing better

* add configuration to state

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

* removed unused imports

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

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

* Add test and fix up code

* Run tsfmt

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

* working through the bugs

* handle various resizing bugs

* gnale resizing better

* fix tests by adding missing node module

* formatting

* refactor interfaces out to get around testing restrictions

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* added sql carbon tag

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

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

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

* Fixed bugs.

* Make everything in IConnectionCompletionOptions optional except saveConnection.

* showConnectionDialogOnError & showFirewallRuleOnError default to true.

* Use types.isUndefinedOrNull to do value checking.

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

* formatting

* formatting

* small typo

* small typo

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

* Fixed bugs in extHostAccountManagement.test.ts

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

* Clean up code

* Update tests

* Remove unused imports

* Update message and options

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

View File

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

View File

@@ -1,9 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature request
assignees: ''
---
<!-- Please search existing issues to avoid creating duplicates. -->
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
<!-- Describe the feature you'd like. -->
**Describe the solution or feature you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

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

View File

@@ -1,58 +0,0 @@
sudo: false
language: cpp
os:
- linux
- osx
cache:
directories:
- $HOME/.cache/yarn
notifications:
email: false
webhooks:
- http://vscode-probot.westus.cloudapp.azure.com:3450/travis/notifications
- http://vscode-test-probot.westus.cloudapp.azure.com:3450/travis/notifications
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.9
- g++-4.9
- gcc-4.9-multilib
- g++-4.9-multilib
- zip
- libgtk2.0-0
- libx11-dev
- libxkbfile-dev
- libsecret-1-dev
before_install:
- git submodule update --init --recursive
- nvm install 8.9.1
- nvm use 8.9.1
- npm i -g yarn
# - npm config set python `which python`
- if [ $TRAVIS_OS_NAME == "linux" ]; then
export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0;
sh -e /etc/init.d/xvfb start;
sleep 3;
fi
# Make npm logs less verbose
# - npm config set depth 0
# - npm config set loglevel warn
install:
- yarn
script:
- node_modules/.bin/gulp electron --silent
- node_modules/.bin/gulp compile --silent --max_old_space_size=4096
- node_modules/.bin/gulp optimize-vscode --silent --max_old_space_size=4096
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./scripts/test.sh --coverage --reporter dot; else ./scripts/test.sh --reporter dot; fi
after_success:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then node_modules/.bin/coveralls < .build/coverage/lcov.info; fi

54
.vscode/launch.json vendored
View File

@@ -66,13 +66,13 @@
{
"type": "chrome",
"request": "attach",
"name": "Attach to sqlops",
"name": "Attach to azuredatastudio",
"port": 9222
},
{
"type": "chrome",
"request": "launch",
"name": "Launch sqlops",
"name": "Launch azuredatastudio",
"windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.bat"
},
@@ -90,7 +90,31 @@
"**/winjs*.js"
],
"webRoot": "${workspaceFolder}",
"timeout": 15000
"timeout": 45000
},
{
"type": "chrome",
"request": "launch",
"name": "Launch azuredatastudio with new notebook command",
"windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.bat"
},
"osx": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
},
"linux": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
},
"urlFilter": "*index.html*",
"runtimeArgs": [
"--inspect=5875",
"--command=notebook.command.new"
],
"skipFiles": [
"**/winjs*.js"
],
"webRoot": "${workspaceFolder}",
"timeout": 45000
},
{
"type": "node",
@@ -98,12 +122,12 @@
"name": "Unit Tests",
"protocol": "inspector",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"runtimeExecutable": "${workspaceFolder}/.build/electron/SQL Operations Studio.app/Contents/MacOS/Electron",
"runtimeExecutable": "${workspaceFolder}/.build/electron/Azure Data Studio.app/Contents/MacOS/Electron",
"windows": {
"runtimeExecutable": "${workspaceFolder}/.build/electron/sqlops.exe"
"runtimeExecutable": "${workspaceFolder}/.build/electron/azuredatastudio.exe"
},
"linux": {
"runtimeExecutable": "${workspaceFolder}/.build/electron/sqlops"
"runtimeExecutable": "${workspaceFolder}/.build/electron/azuredatastudio"
},
"stopOnEntry": false,
"outputCapture": "std",
@@ -128,27 +152,37 @@
"args": [
"--extensionDevelopmentPath=${workspaceRoot}/extensions/debug-auto-launch"
]
},
{
"type": "node",
"request": "launch",
"name": "Launch Smoke Test",
"program": "${workspaceFolder}/test/smoke/test/index.js",
"cwd": "${workspaceFolder}/test/smoke",
"env": {
"BUILD_ARTIFACTSTAGINGDIRECTORY": "${workspaceFolder}"
}
}
],
"compounds": [
{
"name": "Debug sqlops Main and Renderer",
"name": "Debug azuredatastudio Main and Renderer",
"configurations": [
"Launch sqlops",
"Launch azuredatastudio",
"Attach to Main Process"
]
},
{
"name": "Search and Renderer processes",
"configurations": [
"Launch sqlops",
"Launch azuredatastudio",
"Attach to Search Process"
]
},
{
"name": "Renderer and Extension Host processes",
"configurations": [
"Launch SQL Ops",
"Launch azuredatastudio",
"Attach to Extension Host"
]
}

View File

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

View File

@@ -1,5 +1,88 @@
# Change Log
## Version 1.3.8
* Release date: January 9, 2019
* Release status: General Availability
## What's new in this version
* #13 Feature Request: Azure Active Directory Authentication
* #1040 Stream initial query results as they become available
* #3298 Сan't add an azure account.
* #2387 Support Per-User Installer
* SQL Server Import updates for DACPAC\BACPAC
* SQL Server Profiler UI and UX improvements
* Updates to [SQL Server 2019 extension](https://docs.microsoft.com/sql/azure-data-studio/sql-server-2019-extension?view=sql-server-ver15)
* **sp_executesql to SQL** and **New Database** extensions
## Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* Tarig0 for `Add Routine_Type to CreateStoredProc fixes #3257 (#3286)`
* oltruong for `typo fix #3025'`
* Thomas-S-B for `Removed unnecessary IErrorDetectionStrategy #749`
* Thomas-S-B for `Simplified code #750`
## Version 1.2.4
* Release date: November 6, 2018
* Release status: General Availability
## What's new in this version
* Update to the SQL Server 2019 Preview extension
* Introducing Paste the Plan extension
* Introducing High Color queries extension, including SSMS editor theme
* Fixes in SQL Server Agent, Profiler, and Import extensions
* Fix .Net Core Socket KeepAlive issue causing dropped inactive connections on macOS
* Upgrade SQL Tools Service to .Net Core 2.2 Preview 3 (for eventual AAD support)
* Fix customer reported GitHub issues
## Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* rdaniels6813 for `Add query plan theme support #3031`
* Ruturaj123 for `Fixed some typos and grammatical errors #3027`
* PromoFaux for `Use emoji shortcodes in CONTRIBUTING.md instead of <20> #3009`
* ckaczor for `Fix: DATETIMEOFFSET data types should be ISO formatted #714`
* hi-im-T0dd for `Fixed sync issue with my forked master so this commit is correct #2948`
* hi-im-T0dd for `Fixed when right clicking and selecting Manage-correct name displays #2794`
## Version 1.1.3
* Release date: October 18, 2018
* Release status: General Availability
## What's new in this version
* Introducing the Azure Resource Explorer to browse Azure SQL Databases
* Improve Object Explorer and Query Editor connectivity robustness
* SQL Server 2019 and SQL Agent extension improvements
## Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* philoushka for `center the icon #2760`
* anthonypants for `Typo #2775`
* kstolte for `Fix Invalid Configuration in Launch.json #2789`
* kstolte for `Fixing a reference to SQL Ops Studio #2788`
## Version 1.0.0
* Release date: September 24, 2018
* Release status: General Availability
## What's new in this version
* Announcing the SQL Server 2019 Preview extension.
* Support for SQL Server 2019 preview features including big data cluster support.
* Azure Data Studio Notebooks
* The Azure Resource Explorer viewlets you browse data-related endpoints for your Azure accounts and create connections to them in Object Explorer. In this release Azure SQL Databases and servers are supported.
* SQL Server Polybase Create External Table Wizard
* Query Results Grid performance and UX improvements for large number of result sets.
* Visual Studio Code source code refresh from 1.23 to 1.26.1 with Grid Layout and Improved Settings Editor (preview).
* Accessibility improvements for screen reader, keyboard navigation and high-contrast.
* Added Connection name option to provide an alternative display name in the Servers viewlet.
## Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* AlexFsmn `Feature: Ability to add connection name #2332`
* AlexFsmn `Disabled connection name input when connecting to a server. #2566`
## Version 0.33.7
* Release date: August 30, 2018
* Release status: Public Preview
@@ -31,13 +114,13 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release status: Public Preview
## What's new in this version
* SQL Server Agent for SQL Operations Studio extension improvements
* SQL Server Agent for Azure Data Studio extension improvements
* Added view of Alerts, Operators, and Proxies and icons on left pane
* Added dialogs for New Job, New Job Step, New Alert, and New Operator
* Added Delete Job, Delete Alert, and Delete Operator (right-click)
* Added Previous Runs visualization
* Added Filters for each column name
* SQL Server Profiler for SQL Operations Studio extension improvements
* SQL Server Profiler for Azure Data Studio extension improvements
* Added Hotkeys to quickly launch and start/stop Profiler
* Added 5 Default Templates to view Extended Events
* Added Server/Database connection name
@@ -52,10 +135,10 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release status: Public Preview
## What's new in this version
* **SQL Server Profiler for SQL Operations Studio *Preview*** extension initial release
* **SQL Server Profiler for Azure Data Studio *Preview*** extension initial release
* The new **SQL Data Warehouse** extension includes rich customizable dashboard widgets surfacing insights to your data warehouse. This unlocks key scenarios around managing and tuning your data warehouse to ensure it is optimized for consistent performance.
* **Edit Data "Filtering and Sorting"** support
* **SQL Server Agent for SQL Operations Studio *Preview*** extension enhancements for Jobs and Job History views
* **SQL Server Agent for Azure Data Studio *Preview*** extension enhancements for Jobs and Job History views
* Improved **Wizard & Dialog UI Builder Framework** extensibility APIs
* Update VS Code Platform source code integrating [March 2018 (1.22)](https://code.visualstudio.com/updates/v1_22) and [April 2018 (1.23)](https://code.visualstudio.com/updates/v1_23) releases
* Fix GitHub Issues
@@ -69,7 +152,7 @@ The May release is focused on stabilization and bug fixes leading up to the Buil
* Announcing **Redgate SQL Search** extension available in Extension Manager
* Community Localization available for 10 languages: **German, Spanish, French, Italian, Japanese, Korean, Portuguese, Russian, Simplified Chinese and Traditional Chinese!**
* Reduced telemetry collection, improved [opt-out](https://github.com/Microsoft/sqlopsstudio/wiki/How-to-Disable-Telemetry-Reporting) experience and in-product links to [Privacy Statement](https://privacy.microsoft.com/en-us/privacystatement)
* Reduced telemetry collection, improved [opt-out](https://github.com/Microsoft/azuredatastudio/wiki/How-to-Disable-Telemetry-Reporting) experience and in-product links to [Privacy Statement](https://privacy.microsoft.com/en-us/privacystatement)
* Extension Manager has improved Marketplace experience to easily discover community extensions
* SQL Agent extension Jobs and Job History view improvement
* Updates for **whoisactive** and **Server Reports** extensions
@@ -95,8 +178,8 @@ The April Public Preview release contains some of the following highlights.
* Release status: Public Preview
## What's new in this version
The March Public Preview release enables some key aspects of the SQL Operations
Studio extensibility story. Here are some highlights in this release.
The March Public Preview release enables some key aspects of the Azure Data Studio
extensibility story. Here are some highlights in this release.
* Enhance the Manage Dashboard extensibility model to support tabbed Insights and Configuration panes
* Dashboard Insights extensions for `sp_whoisactive` from [whoisactive.com](http://whoisactive.com)

View File

@@ -1,13 +1,13 @@
## Contributing Issues
### Before Submitting an Issue
First, please do a search in [open issues](https://github.com/Microsoft/sqlopsstudio/issues) to see if the issue or feature request has already been filed. Use this [query](https://github.com/Microsoft/sqlopsstudio/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc) to search for the most popular feature requests.
First, please do a search in [open issues](https://github.com/Microsoft/azuredatastudio/issues) to see if the issue or feature request has already been filed. Use this [query](https://github.com/Microsoft/azuredatastudio/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc) to search for the most popular feature requests.
If you find your issue already exists, make relevant comments and add your [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments). Use a reaction in place of a "+1" comment.
<EFBFBD> - upvote
:+1: - upvote
<EFBFBD> - downvote
:-1: - downvote
If you cannot find an existing issue that describes your bug or feature, submit an issue using the guidelines below.
@@ -22,9 +22,9 @@ The more information you can provide, the more likely someone will be successful
Please include the following with each issue.
* Version of SQL Ops Studio
* Version of Azure Data Studio (formerly SQL Operations Studio).
> **Tip:** You can easily create an issue using `Report Issues` from SQL Operations Studio Help menu.
> **Tip:** You can easily create an issue using `Report Issues` from Azure Data Studio Help menu.
* Reproducible steps (1... 2... 3...) and what you expected versus what you actually saw.
* Images, animations, or a link to a video.
@@ -43,4 +43,4 @@ Don't feel bad if we can't reproduce the issue and ask for more information!
## Contributing Fixes
If you are interested in fixing issues and contributing directly to the code base,
please see the document [How to Contribute](https://github.com/Microsoft/sqlopsstudio/wiki/How-to-Contribute).
please see the document [How to Contribute](https://github.com/Microsoft/azuredatastudio/wiki/How-to-Contribute).

View File

@@ -1,6 +1,6 @@
MICROSOFT SOFTWARE LICENSE TERMS
MICROSOFT SQL OPERATIONS STUDIO
MICROSOFT AZURE DATA STUDIO
Microsoft Corporation ("Microsoft") grants you a nonexclusive, perpetual,
royalty-free right to use, copy, and modify the software code provided by us

View File

@@ -1,25 +1,32 @@
# SQL Operations Studio
# Azure Data Studio
[![Join the chat at https://gitter.im/Microsoft/sqlopsstudio](https://badges.gitter.im/Microsoft/sqlopsstudio.svg)](https://gitter.im/Microsoft/sqlopsstudio?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://dev.azure.com/ms/azuredatastudio/_apis/build/status/Microsoft.azuredatastudio)](https://dev.azure.com/ms/azuredatastudio/_build/latest?definitionId=4)
SQL Operations Studio is a data management tool that enables you to work with SQL Server, Azure SQL DB and SQL DW from Windows, macOS and Linux.
Azure Data Studio is a data management tool that enables you to work with SQL Server, Azure SQL DB and SQL DW from Windows, macOS and Linux.
**Download SQL Operations Studio August Public Preview**
**Download the latest Azure Data Studio release**
Platform | Link
-- | --
Windows Setup Installer | https://go.microsoft.com/fwlink/?linkid=2013365
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=2013712
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=2013715
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=2013718
Linux RPM | https://go.microsoft.com/fwlink/?linkid=2013830
Linux DEB | https://go.microsoft.com/fwlink/?linkid=2013833
Windows User Installer | https://go.microsoft.com/fwlink/?linkid=2049972
Windows System Installer | https://go.microsoft.com/fwlink/?linkid=2049975
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=2050146
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=2049981
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=2049986
Linux RPM | https://go.microsoft.com/fwlink/?linkid=2049989
Linux DEB | https://go.microsoft.com/fwlink/?linkid=2050157
Go to our [download page](https://aka.ms/sqlopsstudio) for more specific instructions.
Go to our [download page](https://aka.ms/azuredatastudio) for more specific instructions.
Try out the latest insiders build from `master` at https://github.com/Microsoft/sqlopsstudio/releases.
Try out the latest insiders build from `master`:
- [Windows User Installer - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/win32-x64-user/insider)
- [Windows System Installer - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/win32-x64/insider)
- [Windows ZIP - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/win32-x64-archive/insider)
- [macOS ZIP - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/darwin/insider)
- [Linux TAR.GZ - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/linux-x64/insider)
See the [change log](https://github.com/Microsoft/sqlopsstudio/blob/master/CHANGELOG.md) for additional details of what's in this release.
See the [change log](https://github.com/Microsoft/azuredatastudio/blob/master/CHANGELOG.md) for additional details of what's in this release.
**Feature Highlights**
@@ -34,58 +41,74 @@ See the [change log](https://github.com/Microsoft/sqlopsstudio/blob/master/CHANG
- Task History window to view current task execution status, completion results with error messages and task T-SQL scripting
- Scripting support to generate CREATE, SELECT, ALTER and DROP statements for database objects
- Workspaces with full Git integration and Find In Files support to managing T-SQL script libraries
- Modern light-weight shell with theming, user settings, full screen support, integrated terminal and numerous other features
- Modern light-weight shell with theming, user settings, full-screen support, integrated terminal and numerous other features
Here's some of these features in action.
Here are some of these features in action.
<img src='https://github.com/Microsoft/sqlopsstudio/blob/master/docs/overview_screen.jpg' width='800px'>
<img src='https://github.com/Microsoft/azuredatastudio/blob/master/docs/overview_screen.jpg' width='800px'>
## Contributing
If you are interested in fixing issues and contributing directly to the code base,
please see the document [How to Contribute](https://github.com/Microsoft/sqlopsstudio/wiki/How-to-Contribute), which covers the following:
please see the document [How to Contribute](https://github.com/Microsoft/azuredatastudio/wiki/How-to-Contribute), which covers the following:
* [How to build and run from source](https://github.com/Microsoft/sqlopsstudio/wiki/How-to-Contribute#Build-and-Run-From-Source)
* [The development workflow, including debugging and running tests](https://github.com/Microsoft/sqlopsstudio/wiki/How-to-Contribute#development-workflow)
* [Submitting pull requests](https://github.com/Microsoft/sqlopsstudio/wiki/How-to-Contribute#pull-requests)
* [How to build and run from source](https://github.com/Microsoft/azuredatastudio/wiki/How-to-Contribute#Build-and-Run-From-Source)
* [The development workflow, including debugging and running tests](https://github.com/Microsoft/azuredatastudio/wiki/How-to-Contribute#development-workflow)
* [Submitting pull requests](https://github.com/Microsoft/azuredatastudio/wiki/How-to-Contribute#pull-requests)
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Localization
SQL Operations Studio localization is now open for community contributions. You can contribute to localization for both software and docs. https://aka.ms/SQLOpsStudioLoc
Azure Data Studio localization is now open for community contributions. You can contribute to localization for both software and docs. https://aka.ms/SQLOpsStudioLoc
Localization is now opened for 10 languages: French, Italian, German, Spanish, Simplified Chinese, Traditional Chinese, Japanese, Korean, Russian, and Portuguese (Brazil). Help us make SQL Operations Studio available in your language!
Localization is now opened for 10 languages: French, Italian, German, Spanish, Simplified Chinese, Traditional Chinese, Japanese, Korean, Russian, and Portuguese (Brazil). Help us make Azure Data Studio available in your language!
## Privacy Statement
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/en-us/privacystatement) describes the privacy statement of this software.
## Contributions and "thank you"
## Contributions and "Thank You"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* Tarig0 for `Add Routine_Type to CreateStoredProc fixes #3257 (#3286)`
* oltruong for `typo fix #3025'`
* Thomas-S-B for `Removed unnecessary IErrorDetectionStrategy #749`
* Thomas-S-B for `Simplified code #750`
* rdaniels6813 for `Add query plan theme support #3031`
* Ruturaj123 for `Fixed some typos and grammatical errors #3027`
* PromoFaux for `Use emoji shortcodes in CONTRIBUTING.md instead of <20> #3009`
* ckaczor for `Fix: DATETIMEOFFSET data types should be ISO formatted #714`
* hi-im-T0dd for `Fixed sync issue with my forked master so this commit is correct #2948`
* hi-im-T0dd for `Fixed when right clicking and selecting Manage-correct name displays #2794`
* philoushka for `center the icon #2760`
* anthonypants for `Typo #2775`
* kstolte for `Fix Invalid Configuration in Launch.json #2789`
* kstolte for `Fixing a reference to SQL Ops Studio #2788`
* AlexFsmn `Feature: Ability to add connection name #2332`
* AlexFsmn `Disabled connection name input when connecting to a server. #2566`
* SebastianPfliegel `Added more saveAsCsv options #2099`
* ianychoi `Fixes a typo: Mimunum -> Minimum #1994`
* AlexFsmn `Fixed bug where proper file extension wasn't appended to filename. #2151`
* AlexFsmn `Fixed bug where proper file extension wasn't appended to the filename. #2151`
* AlexFsmn `Added functionality for adding any file to import wizard #2329`
* AlexFsmn `Fixed background issue when copying a chart to clipboard #2215`
* AlexFsmn `Fixed problem where vertical charts didn't display labels correctly. #2263`
* AlexFsmn `Fixed Initial values for charts to match visuals #2266`
* AlexFsmn `Renamed chart option labels #2264`
* AlexFsmn `Added feature for opening file after exporting to CSV/XLS/JSON & query files #2216`
* AlexFsmn `Added feature for the opening file after exporting to CSV/XLS/JSON & query files #2216`
* AlexFsmm `Get Connection String should copy to clipboard #2175`
* lanceklinger `Fix for double clicking column handle in results table #1504`
* lanceklinger `Fix for double-clicking column handle in results table #1504`
* westerncj for `Removed duplicate contribution from README.md (#753)`
* ntovas for `Fix for duplicate extensions shown in "Save File" dialog. (#779)`
* SebastianPfliegel for `Add cursor snippet (#475)`
* mikaoelitiana for fix: `revert README and CONTRIBUTING after last VSCode merge (#574)`
* mikaoelitiana for the fix: `revert README and CONTRIBUTING after last VSCode merge (#574)`
* alextercete for `Reinstate menu item to install from VSIX (#682)`
* alextercete for `Fix "No extension gallery service configured" error (#427)`
* mwiedemeyer for `Fix #58: Default sort order for DB size widget (#111)`
* AlexTroshkin for `Show disconnect in context menu only when connectionProfile connected (#150)`
* AlexTroshkin for `Fix #138: Invalid syntax color highlighting (identity not highlighting) (#140))`
* stebet for `Fix #153: Fixing sql snippets that failed on a DB with case-sensitive collation. (#152)`
* stebet for `Fix #153: Fixing sql snippets that failed on a DB with a case-sensitive collation. (#152)`
* SebastianPfliegel `Remove sqlExtensionHelp (#312)`
* olljanat for `Implemented npm version check (#314)`
* Adam Mechanic for helping with the `whoisactive` extension
* All community localization contributors
* Adam Machanic for helping with the `whoisactive` extension
* All community localization contributors:
* French: Adrien Clerbois, ANAS BELABBES, Antoine Griffard, Arian Papillon, Eric Macarez, Eric Van Thorre, Jérémy LANDON, Matthias GROSPERRIN, Maxime COQUEREL, Olivier Guinart, thierry DEMAN-BARCELÒ, Thomas Potier
* Italian: Aldo Donetti, Alessandro Alpi, Andrea Dottor, Bruni Luca, Gianluca Hotz, Luca Nardi, Luigi Bruno, Marco Dal Pino, Mirco Vanini, Pasquale Ceglie, Riccardo Cappello, Sergio Govoni, Stefano Demiliani
* German: Anna Henke-Gunvaldson, Ben Weissman, David Ullmer, J.M. ., Kai Modo, Konstantin Staschill, Kostja Klein, Lennart Trunk, Markus Ehrenmüller-Jensen, Mascha Kroenlein, Matthias Knoll, Mourad Louha, Thomas Hütter, Wolfgang Straßer
@@ -97,8 +120,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Russian: Andrey Veselov, Anton Fontanov, Anton Savin, Elena Ostrovskaia, Igor Babichev, Maxim Zelensky, Rodion Fedechkin, Tasha T, Vladimir Zyryanov
* Portuguese Brazil: Daniel de Sousa, Diogo Duarte, Douglas Correa, Douglas Eccker, José Emanuel Mendes, Marcelo Fernandes, Marcondes Alexandre, Roberto Fonseca, Rodrigo Crespi
And of course we'd like to thank the authors of all upstream dependencies. Please see a full list in the [ThirdPartyNotices.txt](https://raw.githubusercontent.com/Microsoft/sqlopsstudio/master/ThirdPartyNotices.txt)
And of course, we'd like to thank the authors of all upstream dependencies. Please see a full list in the [ThirdPartyNotices.txt](https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/ThirdPartyNotices.txt)
## License

View File

@@ -1,4 +1,4 @@
MICROSOFT SQL OPERATIONS STUDIO
MICROSOFT Azure Data Studio
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
Do Not Translate or Localize
@@ -21,6 +21,7 @@ expressly granted herein, whether by implication, estoppel or otherwise.
error-ex: https://github.com/Qix-/node-error-ex
escape-string-regexp: https://github.com/sindresorhus/escape-string-regexp
fast-plist: https://github.com/Microsoft/node-fast-plist
find-remove: https://www.npmjs.com/package/find-remove
fs-extra: https://github.com/jprichardson/node-fs-extra
gc-signals: https://github.com/Microsoft/node-gc-signals
getmac: https://github.com/bevry/getmac
@@ -33,6 +34,7 @@ expressly granted herein, whether by implication, estoppel or otherwise.
jquery-ui: https://github.com/jquery/jquery-ui
jquery.event.drag: https://github.com/devongovett/jquery.event.drag
jschardet: https://github.com/aadsm/jschardet
JupyterLab: https://github.com/jupyterlab/jupyterlab
make-error: https://github.com/JsCommunity/make-error
minimist: https://github.com/substack/minimist
moment: https://github.com/moment/moment
@@ -1165,6 +1167,43 @@ That's all there is to it!
=========================================
END OF jschardet NOTICES AND INFORMATION
%% JupyterLab NOTICES AND INFORMATION BEGIN HERE
Copyright (c) 2015 Project Jupyter Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Semver File License
===================
The semver.py file is from https://github.com/podhmo/python-semver
which is licensed under the "MIT" license. See the semver.py file for details.
END OF JupyterLab NOTICES AND INFORMATION
%% make-error NOTICES AND INFORMATION BEGIN HERE
=========================================
ISC © Julien Fontanet

View File

@@ -1,19 +0,0 @@
environment:
ELECTRON_RUN_AS_NODE: 1
VSCODE_BUILD_VERBOSE: true
cache:
- '%LOCALAPPDATA%\Yarn\cache'
install:
- ps: Install-Product node 8.9.1 x64
build_script:
- yarn
- .\node_modules\.bin\gulp electron
- npm run compile
test_script:
- node --version
- .\scripts\test.bat
- .\scripts\test-integration.bat

View File

@@ -0,0 +1,42 @@
steps:
- task: NodeTool@0
inputs:
versionSpec: '8.x'
displayName: 'Install Node.js'
- script: |
git submodule update --init --recursive
nvm install 8.9.1
nvm use 8.9.1
npm i -g yarn
displayName: 'preinstall'
- script: |
export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0
sh -e /etc/init.d/xvfb start
sleep 3
displayName: 'Linux preinstall'
condition: eq(variables['Agent.OS'], 'Linux')
- script: |
yarn
displayName: 'Install'
- script: |
node_modules/.bin/gulp electron --silent
node_modules/.bin/gulp compile --silent --max_old_space_size=4096
node_modules/.bin/gulp optimize-vscode --silent --max_old_space_size=4096
displayName: 'Scripts'
- script: |
./scripts/test.sh --reporter mocha-junit-reporter
displayName: 'Tests'
- task: PublishTestResults@2
inputs:
testResultsFiles: '**/test-results.xml'
condition: succeededOrFailed()
- script: |
yarn run tslint
displayName: 'Run TSLint'

View File

@@ -0,0 +1,30 @@
steps:
- task: NodeTool@0
inputs:
versionSpec: '8.9'
displayName: 'Install Node.js'
- script: |
yarn
displayName: 'Yarn Install'
- script: |
.\node_modules\.bin\gulp electron
displayName: 'Electron'
- script: |
npm run compile
displayName: 'Compile'
- script: |
.\scripts\test.bat --reporter mocha-junit-reporter
displayName: 'Test'
- task: PublishTestResults@2
inputs:
testResultsFiles: 'test-results.xml'
condition: succeededOrFailed()
- script: |
yarn run tslint
displayName: 'Run TSLint'

29
azure-pipelines.yml Normal file
View File

@@ -0,0 +1,29 @@
trigger:
- master
- releases/*
jobs:
# All tasks on Windows
- job: build_all_windows
displayName: Build all tasks (Windows)
pool:
vmImage: vs2017-win2016
steps:
- template: azure-pipelines-windows.yml
# All tasks on Linux
- job: build_all_linux
displayName: Build all tasks (Linux)
pool:
vmImage: 'Ubuntu 16.04'
steps:
- template: azure-pipelines-linux-mac.yml
# All tasks on macOS
- job: build_all_darwin
displayName: Build all tasks (macOS)
pool:
vmImage: macos-10.13
steps:
- template: azure-pipelines-linux-mac.yml

View File

@@ -65,6 +65,8 @@ const excludedExtensions = [
'vscode-colorize-tests',
'ms-vscode.node-debug',
'ms-vscode.node-debug2',
// {{SQL CARBON EDIT}}
'integration-tests',
];
// {{SQL CARBON EDIT}}
@@ -76,6 +78,7 @@ const sqlBuiltInExtensions = [
'import',
'profiler'
];
var azureExtensions = [ 'azurecore', 'mssql'];
const vscodeEntryPoints = _.flatten([
buildfile.entrypoint('vs/workbench/workbench.main'),
@@ -128,6 +131,7 @@ const vscodeResources = [
'out-build/sql/parts/jobManagement/common/media/*.svg',
'out-build/sql/media/objectTypes/*.svg',
'out-build/sql/media/icons/*.svg',
'out-build/sql/parts/notebook/media/**/*.svg',
'!**/test/**'
];
@@ -276,11 +280,44 @@ function packageBuiltInExtensions() {
});
}
function packageExtensionTask(extensionName, platform, arch) {
var destination = path.join(path.dirname(root), 'azuredatastudio') + (platform ? '-' + platform : '') + (arch ? '-' + arch : '');
if (platform === 'darwin') {
destination = path.join(destination, 'Azure Data Studio.app', 'Contents', 'Resources', 'app', 'extensions', extensionName);
} else {
destination = path.join(destination, 'resources', 'app', 'extensions', extensionName);
}
platform = platform || process.platform;
return () => {
const root = path.resolve(path.join(__dirname, '..'));
const localExtensionDescriptions = glob.sync('extensions/*/package.json')
.map(manifestPath => {
const extensionPath = path.dirname(path.join(root, manifestPath));
const extensionName = path.basename(extensionPath);
return { name: extensionName, path: extensionPath };
})
.filter(({ name }) => extensionName === name);
const localExtensions = es.merge(...localExtensionDescriptions.map(extension => {
return ext.fromLocal(extension.path);
}));
let result = localExtensions
.pipe(util.skipDirectories())
.pipe(util.fixWin32DirectoryPermissions())
.pipe(filter(['**', '!LICENSE', '!LICENSES.chromium.html', '!version']));
return result.pipe(vfs.dest(destination));
};
}
function packageTask(platform, arch, opts) {
opts = opts || {};
// {{SQL CARBON EDIT}}
const destination = path.join(path.dirname(root), 'sqlops') + (platform ? '-' + platform : '') + (arch ? '-' + arch : '');
const destination = path.join(path.dirname(root), 'azuredatastudio') + (platform ? '-' + platform : '') + (arch ? '-' + arch : '');
platform = platform || process.platform;
return () => {
@@ -307,7 +344,9 @@ function packageTask(platform, arch, opts) {
.filter(({ name }) => excludedExtensions.indexOf(name) === -1)
.filter(({ name }) => builtInExtensions.every(b => b.name !== name))
// {{SQL CARBON EDIT}}
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) === -1);
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) === -1)
.filter(({ name }) => azureExtensions.indexOf(name) === -1);
packageBuiltInExtensions();
const localExtensions = es.merge(...localExtensionDescriptions.map(extension => {
@@ -325,7 +364,6 @@ function packageTask(platform, arch, opts) {
.pipe(util.cleanNodeModule('account-provider-azure', ['node_modules/date-utils/doc/**', 'node_modules/adal_node/node_modules/**'], undefined))
.pipe(util.cleanNodeModule('typescript', ['**/**'], undefined));
const sources = es.merge(src, localExtensions, localExtensionDependencies)
.pipe(util.setExecutableBit(['**/*.sh']))
.pipe(filter(['**', '!**/*.js.map']));
@@ -338,7 +376,8 @@ function packageTask(platform, arch, opts) {
version += '-' + quality;
}
const name = product.nameShort;
// {{SQL CARBON EDIT}}
const name = (platform === 'darwin') ? 'Azure Data Studio' : product.nameShort;
const packageJsonStream = gulp.src(['package.json'], { base: '.' })
.pipe(json({ name, version }));
@@ -460,18 +499,26 @@ function packageTask(platform, arch, opts) {
const buildRoot = path.dirname(root);
// {{SQL CARBON EDIT}}
gulp.task('clean-vscode-win32-ia32', util.rimraf(path.join(buildRoot, 'sqlops-win32-ia32')));
gulp.task('clean-vscode-win32-x64', util.rimraf(path.join(buildRoot, 'sqlops-win32-x64')));
gulp.task('clean-vscode-darwin', util.rimraf(path.join(buildRoot, 'sqlops-darwin')));
gulp.task('clean-vscode-linux-ia32', util.rimraf(path.join(buildRoot, 'sqlops-linux-ia32')));
gulp.task('clean-vscode-linux-x64', util.rimraf(path.join(buildRoot, 'sqlops-linux-x64')));
gulp.task('clean-vscode-linux-arm', util.rimraf(path.join(buildRoot, 'sqlops-linux-arm')));
gulp.task('vscode-win32-x64-azurecore', ['optimize-vscode'], packageExtensionTask('azurecore', 'win32', 'x64'));
gulp.task('vscode-darwin-azurecore', ['optimize-vscode'], packageExtensionTask('azurecore', 'darwin'));
gulp.task('vscode-linux-x64-azurecore', ['optimize-vscode'], packageExtensionTask('azurecore', 'linux', 'x64'));
gulp.task('vscode-win32-x64-mssql', ['vscode-linux-x64-azurecore', 'optimize-vscode'], packageExtensionTask('mssql', 'win32', 'x64'));
gulp.task('vscode-darwin-mssql', ['vscode-linux-x64-azurecore', 'optimize-vscode'], packageExtensionTask('mssql', 'darwin'));
gulp.task('vscode-linux-x64-mssql', ['vscode-linux-x64-azurecore', 'optimize-vscode'], packageExtensionTask('mssql', 'linux', 'x64'));
gulp.task('clean-vscode-win32-ia32', util.rimraf(path.join(buildRoot, 'azuredatastudio-win32-ia32')));
gulp.task('clean-vscode-win32-x64', util.rimraf(path.join(buildRoot, 'azuredatastudio-win32-x64')));
gulp.task('clean-vscode-darwin', util.rimraf(path.join(buildRoot, 'azuredatastudio-darwin')));
gulp.task('clean-vscode-linux-ia32', util.rimraf(path.join(buildRoot, 'azuredatastudio-linux-ia32')));
gulp.task('clean-vscode-linux-x64', util.rimraf(path.join(buildRoot, 'azuredatastudio-linux-x64')));
gulp.task('clean-vscode-linux-arm', util.rimraf(path.join(buildRoot, 'azuredatastudio-linux-arm')));
gulp.task('vscode-win32-ia32', ['optimize-vscode', 'clean-vscode-win32-ia32'], packageTask('win32', 'ia32'));
gulp.task('vscode-win32-x64', ['optimize-vscode', 'clean-vscode-win32-x64'], packageTask('win32', 'x64'));
gulp.task('vscode-darwin', ['optimize-vscode', 'clean-vscode-darwin'], packageTask('darwin'));
gulp.task('vscode-win32-x64', ['vscode-win32-x64-azurecore', 'vscode-win32-x64-mssql', 'optimize-vscode', 'clean-vscode-win32-x64'], packageTask('win32', 'x64'));
gulp.task('vscode-darwin', ['vscode-darwin-azurecore', 'vscode-darwin-mssql', 'optimize-vscode', 'clean-vscode-darwin'], packageTask('darwin'));
gulp.task('vscode-linux-ia32', ['optimize-vscode', 'clean-vscode-linux-ia32'], packageTask('linux', 'ia32'));
gulp.task('vscode-linux-x64', ['optimize-vscode', 'clean-vscode-linux-x64'], packageTask('linux', 'x64'));
gulp.task('vscode-linux-x64', ['vscode-linux-x64-azurecore', 'vscode-linux-x64-mssql', 'optimize-vscode', 'clean-vscode-linux-x64'], packageTask('linux', 'x64'));
gulp.task('vscode-linux-arm', ['optimize-vscode', 'clean-vscode-linux-arm'], packageTask('linux', 'arm'));
gulp.task('vscode-win32-ia32-min', ['minify-vscode', 'clean-vscode-win32-ia32'], packageTask('win32', 'ia32', { minified: true }));

View File

@@ -24,7 +24,7 @@ function getDebPackageArch(arch) {
function prepareDebPackage(arch) {
// {{SQL CARBON EDIT}}
const binaryDir = '../sqlops-linux-' + arch;
const binaryDir = '../azuredatastudio-linux-' + arch;
const debArch = getDebPackageArch(arch);
const destination = '.build/linux/deb/' + debArch + '/' + product.applicationName + '-' + debArch;
@@ -104,7 +104,7 @@ function getRpmPackageArch(arch) {
function prepareRpmPackage(arch) {
// {{SQL CARBON EDIT}}
const binaryDir = '../sqlops-linux-' + arch;
const binaryDir = '../azuredatastudio-linux-' + arch;
const rpmArch = getRpmPackageArch(arch);
return function () {
@@ -213,7 +213,7 @@ function getFlatpakArch(arch) {
function prepareFlatpak(arch) {
// {{SQL CARBON EDIT}}
const binaryDir = '../sqlops-linux-' + arch;
const binaryDir = '../azuredatastudio-linux-' + arch;
const flatpakArch = getFlatpakArch(arch);
const destination = '.build/linux/flatpak/' + flatpakArch;

View File

@@ -19,7 +19,7 @@ const mkdirp = require('mkdirp');
const repoPath = path.dirname(__dirname);
// {{SQL CARBON EDIT}}
const buildPath = arch => path.join(path.dirname(repoPath), `sqlops-win32-${arch}`);
const buildPath = arch => path.join(path.dirname(repoPath), `azuredatastudio-win32-${arch}`);
const zipDir = arch => path.join(repoPath, '.build', `win32-${arch}`, 'archive');
const zipPath = arch => path.join(zipDir(arch), `VSCode-win32-${arch}.zip`);
const setupDir = (arch, target) => path.join(repoPath, '.build', `win32-${arch}`, `${target}-setup`);

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
{
"name": "sqlops-oss-dev-build",
"name": "azuredatastudio-oss-dev-build",
"version": "1.0.0",
"devDependencies": {
"@types/azure": "0.9.19",
@@ -7,21 +7,23 @@
"@types/es6-collections": "0.5.31",
"@types/es6-promise": "0.0.33",
"@types/mime": "0.0.29",
"@types/minimatch": "^3.0.3",
"@types/node": "8.0.33",
"@types/xml2js": "0.0.33",
"@types/request": "^2.47.0",
"@types/xml2js": "0.0.33",
"azure-storage": "^2.1.0",
"decompress": "^4.2.0",
"del": "^3.0.0",
"documentdb": "1.13.0",
"service-downloader": "github:anthonydresser/service-downloader#0.1.2",
"fs-extra-promise": "^1.0.1",
"github-releases": "^0.4.1",
"mime": "^1.3.4",
"minimist": "^1.2.0",
"request": "^2.85.0",
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
"typescript": "2.9.2",
"vscode": "^1.0.1",
"xml2js": "^0.4.17",
"github-releases": "^0.4.1",
"request": "^2.85.0"
"xml2js": "^0.4.17"
},
"scripts": {
"compile": "tsc -p tsconfig.build.json",

View File

@@ -8,14 +8,14 @@ AppId={#AppId}
AppName={#NameLong}
AppVerName={#NameVersion}
AppPublisher=Microsoft Corporation
AppPublisherURL=https://github.com/Microsoft/sqlopsstudio
AppSupportURL=https://github.com/Microsoft/sqlopsstudio
AppUpdatesURL=https://github.com/Microsoft/sqlopsstudio
AppPublisherURL=https://github.com/Microsoft/azuredatastudio
AppSupportURL=https://github.com/Microsoft/azuredatastudio
AppUpdatesURL=https://github.com/Microsoft/azuredatastudio
DefaultGroupName={#NameLong}
AllowNoIcons=yes
OutputDir={#OutputDir}
OutputBaseFilename=SqlOpsStudioSetup
OutputBaseFilename=AzureDataStudioSetup
Compression=lzma
SolidCompression=yes
AppMutex={code:GetAppMutex}
@@ -68,7 +68,7 @@ Type: filesandordirs; Name: "{app}\_"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkedonce; Check: IsNotUpdate
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
Name: "associatewithfiles"; Description: "{cm:AssociateWithFiles,{#NameShort}}"; GroupDescription: "{cm:Other}"; Flags: unchecked
Name: "associatewithfiles"; Description: "{cm:AssociateWithFiles,{#NameLong}}"; GroupDescription: "{cm:Other}"; Flags: unchecked
Name: "addtopath"; Description: "{cm:AddToPath}"; GroupDescription: "{cm:Other}"
Name: "runcode"; Description: "{cm:RunAfter,{#NameShort}}"; GroupDescription: "{cm:Other}"; Check: WizardSilent
@@ -91,17 +91,17 @@ Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong
#else
#define SoftwareClassesRootKey "HKLM"
#endif
Root: HKCR; Subkey: "{#RegValueName}SourceFile"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,{#NameLong}}"; Flags: uninsdeletekey
Root: HKCR; Subkey: "{#RegValueName}SourceFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\code_file.ico"
Root: HKCR; Subkey: "{#RegValueName}SourceFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}SourceFile"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,{#NameLong}}"; Flags: uninsdeletekey
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}SourceFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\code_file.ico"
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}SourceFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};{app}\bin"; Tasks: addtopath; Check: NeedsAddPath(ExpandConstant('{app}\bin'))
Root: HKCU; Subkey: "Software\Classes\.sql\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles
Root: HKCU; Subkey: "Software\Classes\.sql\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.sql"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
Root: HKCU; Subkey: "Software\Classes\{#RegValueName}.sql"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,SQL}"; Flags: uninsdeletekey; Tasks: associatewithfiles
Root: HKCU; Subkey: "Software\Classes\{#RegValueName}.sql"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles
Root: HKCU; Subkey: "Software\Classes\{#RegValueName}.sql\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\code_file.ico"; Tasks: associatewithfiles
Root: HKCU; Subkey: "Software\Classes\{#RegValueName}.sql\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.sql\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.sql\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.sql"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sql"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,SQL}"; Flags: uninsdeletekey; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sql"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sql\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\code_file.ico"; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sql\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles
; Environment
#if "user" == InstallTarget
#define EnvironmentRootKey "HKCU"
@@ -180,9 +180,9 @@ begin
Result := not IsBackgroundUpdate();
end;
// SqlOps will create a flag file before the update starts (/update=C:\foo\bar)
// - if the file exists at this point, the user quit SqlOps before the update finished, so don't start SqlOps after update
// - otherwise, the user has accepted to apply the update and SqlOps should start
// AzureDataStudio will create a flag file before the update starts (/update=C:\foo\bar)
// - if the file exists at this point, the user quit AzureDataStudio before the update finished, so don't start AzureDataStudio after update
// - otherwise, the user has accepted to apply the update and AzureDataStudio should start
function LockFileExists(): Boolean;
begin
Result := FileExists(ExpandConstant('{param:update}'))

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@

View File

@@ -1,3 +0,0 @@
src/**
tsconfig.json
npm-shrinkwrap.json

View File

@@ -1,348 +0,0 @@
{
"name": "account-provider-azure",
"version": "0.0.1",
"dependencies": {
"@types/node": {
"version": "8.5.1",
"from": "@types/node@>=8.0.47 <9.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.1.tgz"
},
"adal-node": {
"version": "0.1.25",
"from": "adal-node@0.1.25",
"resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.25.tgz"
},
"ansi-regex": {
"version": "2.1.1",
"from": "ansi-regex@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz"
},
"ansi-styles": {
"version": "2.2.1",
"from": "ansi-styles@>=2.2.1 <3.0.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
},
"asn1": {
"version": "0.1.11",
"from": "asn1@0.1.11",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz"
},
"assert-plus": {
"version": "0.1.5",
"from": "assert-plus@>=0.1.5 <0.2.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz"
},
"async": {
"version": "2.6.0",
"from": "async@>=0.6.0",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz"
},
"aws-sign2": {
"version": "0.5.0",
"from": "aws-sign2@>=0.5.0 <0.6.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz"
},
"base64url": {
"version": "2.0.0",
"from": "base64url@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz"
},
"bl": {
"version": "1.0.3",
"from": "bl@>=1.0.0 <1.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.0.3.tgz"
},
"bluebird": {
"version": "2.11.0",
"from": "bluebird@>=2.9.30 <3.0.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz"
},
"boom": {
"version": "2.10.1",
"from": "boom@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz"
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"from": "buffer-equal-constant-time@1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz"
},
"caseless": {
"version": "0.11.0",
"from": "caseless@>=0.11.0 <0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz"
},
"chalk": {
"version": "1.1.3",
"from": "chalk@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz"
},
"combined-stream": {
"version": "1.0.5",
"from": "combined-stream@>=1.0.1 <1.1.0",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz"
},
"commander": {
"version": "2.12.2",
"from": "commander@>=2.8.1 <3.0.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz"
},
"core-util-is": {
"version": "1.0.2",
"from": "core-util-is@>=1.0.0 <1.1.0",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
},
"cryptiles": {
"version": "2.0.5",
"from": "cryptiles@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz"
},
"ctype": {
"version": "0.5.3",
"from": "ctype@0.5.3",
"resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz"
},
"date-utils": {
"version": "1.2.21",
"from": "date-utils@*",
"resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz"
},
"delayed-stream": {
"version": "1.0.0",
"from": "delayed-stream@>=1.0.0 <1.1.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
},
"ecdsa-sig-formatter": {
"version": "1.0.9",
"from": "ecdsa-sig-formatter@1.0.9",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz"
},
"escape-string-regexp": {
"version": "1.0.5",
"from": "escape-string-regexp@>=1.0.2 <2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
},
"extend": {
"version": "3.0.1",
"from": "extend@>=3.0.0 <3.1.0",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz"
},
"forever-agent": {
"version": "0.6.1",
"from": "forever-agent@>=0.6.0 <0.7.0",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
},
"form-data": {
"version": "1.0.1",
"from": "form-data@>=1.0.0-rc1 <1.1.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz"
},
"generate-function": {
"version": "2.0.0",
"from": "generate-function@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz"
},
"generate-object-property": {
"version": "1.2.0",
"from": "generate-object-property@>=1.1.0 <2.0.0",
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz"
},
"har-validator": {
"version": "1.8.0",
"from": "har-validator@>=1.6.1 <2.0.0",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.8.0.tgz"
},
"has-ansi": {
"version": "2.0.0",
"from": "has-ansi@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz"
},
"hawk": {
"version": "3.1.3",
"from": "hawk@>=3.1.0 <3.2.0",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz"
},
"hoek": {
"version": "2.16.3",
"from": "hoek@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz"
},
"http-signature": {
"version": "0.11.0",
"from": "http-signature@>=0.11.0 <0.12.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.11.0.tgz"
},
"inherits": {
"version": "2.0.3",
"from": "inherits@>=2.0.1 <2.1.0",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
},
"is-my-json-valid": {
"version": "2.17.1",
"from": "is-my-json-valid@>=2.12.0 <3.0.0",
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz"
},
"is-property": {
"version": "1.0.2",
"from": "is-property@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
},
"isarray": {
"version": "1.0.0",
"from": "isarray@>=1.0.0 <1.1.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
},
"isstream": {
"version": "0.1.2",
"from": "isstream@>=0.1.1 <0.2.0",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz"
},
"json-stringify-safe": {
"version": "5.0.1",
"from": "json-stringify-safe@>=5.0.0 <5.1.0",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
},
"jsonpointer": {
"version": "4.0.1",
"from": "jsonpointer@>=4.0.0 <5.0.0",
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz"
},
"jwa": {
"version": "1.1.5",
"from": "jwa@>=1.1.4 <2.0.0",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.5.tgz"
},
"jws": {
"version": "3.1.4",
"from": "jws@>=3.0.0 <4.0.0",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz"
},
"lodash": {
"version": "4.17.4",
"from": "lodash@>=4.14.0 <5.0.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz"
},
"mime-db": {
"version": "1.30.0",
"from": "mime-db@>=1.30.0 <1.31.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz"
},
"mime-types": {
"version": "2.1.17",
"from": "mime-types@>=2.1.2 <2.2.0",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz"
},
"oauth-sign": {
"version": "0.8.2",
"from": "oauth-sign@>=0.8.0 <0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz"
},
"process-nextick-args": {
"version": "1.0.7",
"from": "process-nextick-args@>=1.0.6 <1.1.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
},
"punycode": {
"version": "1.4.1",
"from": "punycode@>=1.4.1 <2.0.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz"
},
"qs": {
"version": "5.1.0",
"from": "qs@>=5.1.0 <5.2.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz"
},
"readable-stream": {
"version": "2.0.6",
"from": "readable-stream@>=2.0.5 <2.1.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz"
},
"request": {
"version": "2.63.0",
"from": "request@2.63.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.63.0.tgz",
"dependencies": {
"node-uuid": {
"version": "1.4.8",
"from": "node-uuid@>=1.4.0 <1.5.0",
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz"
}
}
},
"safe-buffer": {
"version": "5.1.1",
"from": "safe-buffer@>=5.0.1 <6.0.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz"
},
"sntp": {
"version": "1.0.9",
"from": "sntp@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz"
},
"string_decoder": {
"version": "0.10.31",
"from": "string_decoder@>=0.10.0 <0.11.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
},
"stringstream": {
"version": "0.0.5",
"from": "stringstream@>=0.0.4 <0.1.0",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz"
},
"strip-ansi": {
"version": "3.0.1",
"from": "strip-ansi@>=3.0.0 <4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz"
},
"supports-color": {
"version": "2.0.0",
"from": "supports-color@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
},
"tough-cookie": {
"version": "2.3.3",
"from": "tough-cookie@>=0.12.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz"
},
"tunnel-agent": {
"version": "0.4.3",
"from": "tunnel-agent@>=0.4.0 <0.5.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz"
},
"underscore": {
"version": "1.8.3",
"from": "underscore@>=1.3.1",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz"
},
"util-deprecate": {
"version": "1.0.2",
"from": "util-deprecate@>=1.0.1 <1.1.0",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
},
"uuid": {
"version": "3.1.0",
"from": "uuid@>=3.1.0 <4.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz"
},
"vscode-nls": {
"version": "2.0.2",
"from": "vscode-nls@2.0.2",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
},
"xmldom": {
"version": "0.1.27",
"from": "xmldom@>=0.1.0",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz"
},
"xpath.js": {
"version": "1.0.7",
"from": "xpath.js@>=1.0.5 <1.1.0",
"resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.0.7.tgz"
},
"xtend": {
"version": "4.0.1",
"from": "xtend@>=4.0.0 <5.0.0",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz"
}
}
}

View File

@@ -1,55 +0,0 @@
{
"name": "account-provider-azure",
"version": "0.0.1",
"publisher": "Microsoft",
"engines": { "vscode": "*" },
"main": "./out/main",
"activationEvents": [ "*" ],
"scripts": {
"compile": "gulp compile-extension:account-provider-azure"
},
"dependencies": {
"adal-node": "0.1.25",
"request": "2.63.0",
"vscode-nls": "^3.2.1"
},
"devDependencies": {
"@types/node": "^8.0.24"
},
"contributes": {
"commands": [
{
"command": "accounts.clearTokenCache",
"title": "%accounts.clearTokenCache%",
"category": "Azure Accounts"
}
],
"configuration": {
"type": "object",
"title": "Azure Account Configuration",
"properties": {
"accounts.azure.enablePublicCloud": {
"type": "boolean",
"default": true,
"description": "%config.enablePublicCloudDescription%"
}
}
},
"account-type": [
{
"id": "microsoft",
"icon": {
"light": "./out/account-provider/media/microsoft_account_light.svg",
"dark": "./out/account-provider/media/microsoft_account_dark.svg"
}
},
{
"id": "work_school",
"icon": {
"light": "./out/account-provider/media/work_school_account_light.svg",
"dark": "./out/account-provider/media/work_school_account_dark.svg"
}
}
]
}
}

View File

@@ -1,7 +0,0 @@
{
"accounts.clearTokenCache": "Clear Azure Account Token Cache",
"config.enablePublicCloudDescription": "Should Azure public cloud integration be enabled",
"config.enableUsGovCloudDescription": "Should US Government Azure cloud (Fairfax) integration be enabled",
"config.enableChinaCloudDescription": "Should Azure China integration be enabled",
"config.enableGermanyCloudDescription": "Should Azure Germany integration be enabled"
}

View File

@@ -1,51 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as fs from 'fs';
import * as path from 'path';
import * as vscode from 'vscode';
import * as os from 'os';
import * as constants from './constants';
import { AzureAccountProviderService } from './account-provider/azureAccountProviderService';
// The function is a duplicate of \src\paths.js. IT would be better to import path.js but it doesn't
// work for now because the extension is running in different process.
export function getAppDataPath() {
var platform = process.platform;
switch (platform) {
case 'win32': return process.env['APPDATA'] || path.join(process.env['USERPROFILE'], 'AppData', 'Roaming');
case 'darwin': return path.join(os.homedir(), 'Library', 'Application Support');
case 'linux': return process.env['XDG_CONFIG_HOME'] || path.join(os.homedir(), '.config');
default: throw new Error('Platform not supported');
}
}
export function getDefaultLogLocation() {
return path.join(getAppDataPath(), 'sqlops');
}
// EXTENSION ACTIVATION ////////////////////////////////////////////////////
export function activate(context: vscode.ExtensionContext): void {
// Create the folder for storing the token caches
let storagePath = path.join(getDefaultLogLocation(), constants.extensionName);
try {
if (!fs.existsSync(storagePath)) {
fs.mkdirSync(storagePath);
console.log('Initialized Azure account extension storage.');
}
} catch (e) {
console.error(`Initialization of Azure account extension storage failed: ${e}`);
console.error('Azure accounts will not be available');
return;
}
// Create the provider service and activate
const accountProviderService = new AzureAccountProviderService(context, storagePath);
context.subscriptions.push(accountProviderService);
accountProviderService.activate();
}

View File

@@ -1,608 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/node@^8.0.24", "@types/node@^8.0.47":
version "8.5.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.9.tgz#7155cfb4ae405bca4dd8df1a214c339e939109bf"
adal-node@0.1.25:
version "0.1.25"
resolved "https://registry.yarnpkg.com/adal-node/-/adal-node-0.1.25.tgz#6554350ab42914870004c45c0d64448f3dbfcd03"
dependencies:
"@types/node" "^8.0.47"
async ">=0.6.0"
date-utils "*"
jws "3.x.x"
request ">= 2.52.0"
underscore ">= 1.3.1"
uuid "^3.1.0"
xmldom ">= 0.1.x"
xpath.js "~1.0.5"
ajv@^5.1.0:
version "5.5.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
asn1@0.1.11:
version "0.1.11"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7"
asn1@~0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
assert-plus@^0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160"
async@>=0.6.0, async@^2.0.1:
version "2.6.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
dependencies:
lodash "^4.14.0"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
aws-sign2@~0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.5.0.tgz#c57103f7a17fc037f02d7c2e64b602ea223f7d63"
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
aws4@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
base64url@2.0.0, base64url@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/base64url/-/base64url-2.0.0.tgz#eac16e03ea1438eff9423d69baa36262ed1f70bb"
bcrypt-pbkdf@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
dependencies:
tweetnacl "^0.14.3"
bl@~1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/bl/-/bl-1.0.3.tgz#fc5421a28fd4226036c3b3891a66a25bc64d226e"
dependencies:
readable-stream "~2.0.5"
bluebird@^2.9.30:
version "2.11.0"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
boom@2.x.x:
version "2.10.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
dependencies:
hoek "2.x.x"
boom@4.x.x:
version "4.3.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
dependencies:
hoek "4.x.x"
boom@5.x.x:
version "5.2.0"
resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
dependencies:
hoek "4.x.x"
buffer-equal-constant-time@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
caseless@~0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
chalk@^1.0.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
ansi-styles "^2.2.1"
escape-string-regexp "^1.0.2"
has-ansi "^2.0.0"
strip-ansi "^3.0.0"
supports-color "^2.0.0"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
combined-stream@^1.0.5, combined-stream@~1.0.1, combined-stream@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
dependencies:
delayed-stream "~1.0.0"
commander@^2.8.1:
version "2.13.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
cryptiles@2.x.x:
version "2.0.5"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
dependencies:
boom "2.x.x"
cryptiles@3.x.x:
version "3.1.2"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
dependencies:
boom "5.x.x"
ctype@0.5.3:
version "0.5.3"
resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f"
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
dependencies:
assert-plus "^1.0.0"
date-utils@*:
version "1.2.21"
resolved "https://registry.yarnpkg.com/date-utils/-/date-utils-1.2.21.tgz#61fb16cdc1274b3c9acaaffe9fc69df8720a2b64"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
dependencies:
jsbn "~0.1.0"
ecdsa-sig-formatter@1.0.9:
version "1.0.9"
resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz#4bc926274ec3b5abb5016e7e1d60921ac262b2a1"
dependencies:
base64url "^2.0.0"
safe-buffer "^5.0.1"
escape-string-regexp@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
extend@~3.0.0, extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
extsprintf@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
fast-deep-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
forever-agent@~0.6.0, forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
form-data@~1.0.0-rc1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c"
dependencies:
async "^2.0.1"
combined-stream "^1.0.5"
mime-types "^2.1.11"
form-data@~2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.5"
mime-types "^2.1.12"
generate-function@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
generate-object-property@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
dependencies:
is-property "^1.0.0"
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
dependencies:
assert-plus "^1.0.0"
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
har-validator@^1.6.1:
version "1.8.0"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-1.8.0.tgz#d83842b0eb4c435960aeb108a067a3aa94c0eeb2"
dependencies:
bluebird "^2.9.30"
chalk "^1.0.0"
commander "^2.8.1"
is-my-json-valid "^2.12.0"
har-validator@~5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
dependencies:
ajv "^5.1.0"
har-schema "^2.0.0"
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
dependencies:
ansi-regex "^2.0.0"
hawk@~3.1.0:
version "3.1.3"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
dependencies:
boom "2.x.x"
cryptiles "2.x.x"
hoek "2.x.x"
sntp "1.x.x"
hawk@~6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
dependencies:
boom "4.x.x"
cryptiles "3.x.x"
hoek "4.x.x"
sntp "2.x.x"
hoek@2.x.x:
version "2.16.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
hoek@4.x.x:
version "4.2.0"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
http-signature@~0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-0.11.0.tgz#1796cf67a001ad5cd6849dca0991485f09089fe6"
dependencies:
asn1 "0.1.11"
assert-plus "^0.1.5"
ctype "0.5.3"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
inherits@~2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
is-my-json-valid@^2.12.0:
version "2.17.1"
resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz#3da98914a70a22f0a8563ef1511a246c6fc55471"
dependencies:
generate-function "^2.0.0"
generate-object-property "^1.1.0"
jsonpointer "^4.0.0"
xtend "^4.0.0"
is-property@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isstream@~0.1.1, isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
json-schema-traverse@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
json-stringify-safe@~5.0.0, json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
jsonpointer@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.2.3"
verror "1.10.0"
jwa@^1.1.4:
version "1.1.5"
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.5.tgz#a0552ce0220742cd52e153774a32905c30e756e5"
dependencies:
base64url "2.0.0"
buffer-equal-constant-time "1.0.1"
ecdsa-sig-formatter "1.0.9"
safe-buffer "^5.0.1"
jws@3.x.x:
version "3.1.4"
resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.4.tgz#f9e8b9338e8a847277d6444b1464f61880e050a2"
dependencies:
base64url "^2.0.0"
jwa "^1.1.4"
safe-buffer "^5.0.1"
lodash@^4.14.0:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
mime-db@~1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.2:
version "2.1.17"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
dependencies:
mime-db "~1.30.0"
node-uuid@~1.4.0:
version "1.4.8"
resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907"
oauth-sign@~0.8.0, oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
qs@~5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9"
qs@~6.5.1:
version "6.5.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
readable-stream@~2.0.5:
version "2.0.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "~1.0.0"
process-nextick-args "~1.0.6"
string_decoder "~0.10.x"
util-deprecate "~1.0.1"
request@2.63.0:
version "2.63.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.63.0.tgz#c83e7c3485e5d9bf9b146318429bc48f1253d8be"
dependencies:
aws-sign2 "~0.5.0"
bl "~1.0.0"
caseless "~0.11.0"
combined-stream "~1.0.1"
extend "~3.0.0"
forever-agent "~0.6.0"
form-data "~1.0.0-rc1"
har-validator "^1.6.1"
hawk "~3.1.0"
http-signature "~0.11.0"
isstream "~0.1.1"
json-stringify-safe "~5.0.0"
mime-types "~2.1.2"
node-uuid "~1.4.0"
oauth-sign "~0.8.0"
qs "~5.1.0"
stringstream "~0.0.4"
tough-cookie ">=0.12.0"
tunnel-agent "~0.4.0"
"request@>= 2.52.0":
version "2.83.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
dependencies:
aws-sign2 "~0.7.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.3.1"
har-validator "~5.0.3"
hawk "~6.0.2"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.17"
oauth-sign "~0.8.2"
performance-now "^2.1.0"
qs "~6.5.1"
safe-buffer "^5.1.1"
stringstream "~0.0.5"
tough-cookie "~2.3.3"
tunnel-agent "^0.6.0"
uuid "^3.1.0"
safe-buffer@^5.0.1, safe-buffer@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
sntp@1.x.x:
version "1.0.9"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
dependencies:
hoek "2.x.x"
sntp@2.x.x:
version "2.1.0"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
dependencies:
hoek "4.x.x"
sshpk@^1.7.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
dashdash "^1.12.0"
getpass "^0.1.1"
optionalDependencies:
bcrypt-pbkdf "^1.0.0"
ecc-jsbn "~0.1.1"
jsbn "~0.1.0"
tweetnacl "~0.14.0"
string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
stringstream@~0.0.4, stringstream@~0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
dependencies:
ansi-regex "^2.0.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
tough-cookie@>=0.12.0, tough-cookie@~2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
dependencies:
punycode "^1.4.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
dependencies:
safe-buffer "^5.0.1"
tunnel-agent@~0.4.0:
version "0.4.3"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
"underscore@>= 1.3.1":
version "1.8.3"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
uuid@^3.1.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
vscode-nls@^3.2.1:
version "3.2.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.2.tgz#3817eca5b985c2393de325197cf4e15eb2aa5350"
"xmldom@>= 0.1.x":
version "0.1.27"
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"
xpath.js@~1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/xpath.js/-/xpath.js-1.0.7.tgz#7e94627f541276cbc6a6b02b5d35e9418565b3e4"
xtend@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"

View File

@@ -1,6 +1,6 @@
# Microsoft SQL Server Agent for SQL Operations Studio
# Microsoft SQL Server Agent for Azure Data Studio
Welcome to Microsoft SQL Server Agent for SQL Operations Studio! An extension for managing and troubleshooting
Welcome to Microsoft SQL Server Agent for Azure Data Studio! An extension for managing and troubleshooting
SQL Server Agent jobs and configuration. The current is an early release of this extension that provides
basic functionality for the following.
@@ -22,4 +22,4 @@ The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.micro
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the [Source EULA](https://raw.githubusercontent.com/Microsoft/sqlopsstudio/master/LICENSE.txt).
Licensed under the [Source EULA](https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt).

View File

@@ -2,10 +2,10 @@
"name": "agent",
"displayName": "SQL Server Agent",
"description": "Manage and troubleshoot SQL Server Agent jobs",
"version": "0.32.7",
"version": "0.35.2",
"publisher": "Microsoft",
"preview": true,
"license": "https://raw.githubusercontent.com/Microsoft/sqlopsstudio/master/LICENSE.txt",
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
"icon": "images/sqlserver.png",
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
"engines": {
@@ -17,7 +17,7 @@
"main": "./out/main",
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/sqlopsstudio.git"
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"extensionDependencies": [
"Microsoft.mssql"
@@ -26,12 +26,6 @@
"outputChannels": [
"sqlagent"
],
"commands": [
{
"command": "agent.openNewStepDialog",
"title": "agent.openNewStepDialog"
}
],
"dashboard.tabs": [
{
"id": "data-management-agent",

View File

@@ -35,4 +35,5 @@ export class AgentUtils {
}
return this._queryProvider;
}
}

View File

@@ -9,6 +9,7 @@ import * as vscode from 'vscode';
import * as sqlops from 'sqlops';
import { AgentUtils } from '../agentUtils';
import { IAgentDialogData, AgentDialogMode } from '../interfaces';
import { JobData } from './jobData';
const localize = nls.loadMessageBundle();
@@ -45,8 +46,19 @@ export class AlertData implements IAgentDialogData {
wmiEventNamespace: string;
wmiEventQuery: string;
constructor(ownerUri:string, alertInfo: sqlops.AgentAlertInfo) {
private viaJobDialog: boolean;
private jobModel: JobData;
constructor(
ownerUri:string,
alertInfo: sqlops.AgentAlertInfo,
jobModel?: JobData,
viaJobDialog: boolean = false
) {
this.ownerUri = ownerUri;
this.viaJobDialog = viaJobDialog;
this.jobModel = jobModel;
this.jobName = this.jobName ? this.jobName : this.jobModel.name;
if (alertInfo) {
this.dialogMode = AgentDialogMode.EDIT;
@@ -57,10 +69,9 @@ export class AlertData implements IAgentDialogData {
this.eventDescriptionKeyword = alertInfo.eventDescriptionKeyword;
this.eventSource = alertInfo.eventSource;
this.hasNotification = alertInfo.hasNotification;
this.includeEventDescription = alertInfo.includeEventDescription.toString();
this.includeEventDescription = alertInfo.includeEventDescription ? alertInfo.includeEventDescription.toString() : null;
this.isEnabled = alertInfo.isEnabled;
this.jobId = alertInfo.jobId;
this.jobName = alertInfo.jobName;
this.lastOccurrenceDate = alertInfo.lastOccurrenceDate;
this.lastResponseDate = alertInfo.lastResponseDate;
this.messageId = alertInfo.messageId;
@@ -71,7 +82,7 @@ export class AlertData implements IAgentDialogData {
this.databaseName = alertInfo.databaseName;
this.countResetDate = alertInfo.countResetDate;
this.categoryName = alertInfo.categoryName;
this.alertType = alertInfo.alertType.toString();
this.alertType = alertInfo.alertType ? alertInfo.alertType.toString() : null;
this.wmiEventNamespace = alertInfo.wmiEventNamespace;
this.wmiEventQuery = alertInfo.wmiEventQuery;
}
@@ -82,10 +93,18 @@ export class AlertData implements IAgentDialogData {
public async save() {
let agentService = await AgentUtils.getAgentService();
let result = this.dialogMode === AgentDialogMode.CREATE
? await agentService.createAlert(this.ownerUri, this.toAgentAlertInfo())
: await agentService.updateAlert(this.ownerUri, this.originalName, this.toAgentAlertInfo());
let result: any;
// if it's called via the job dialog, add it to the
// job model
if (this.viaJobDialog) {
if (this.jobModel) {
Promise.resolve(this);
return;
}
} else {
// has to be a create alert
result = await agentService.createAlert(this.ownerUri, this.toAgentAlertInfo());
}
if (!result || !result.success) {
vscode.window.showErrorMessage(
localize('alertData.saveErrorMessage', "Alert update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown'));

View File

@@ -26,6 +26,7 @@ export class JobData implements IAgentDialogData {
private _operators: string[];
private _defaultOwner: string;
private _jobCompletionActionConditions: sqlops.CategoryValue[];
private _jobCategoryIdsMap: sqlops.AgentJobCategory[];
public dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
public name: string;
@@ -44,6 +45,9 @@ export class JobData implements IAgentDialogData {
public jobSteps: sqlops.AgentJobStepInfo[];
public jobSchedules: sqlops.AgentJobScheduleInfo[];
public alerts: sqlops.AgentAlertInfo[];
public jobId: string;
public startStepId: number;
public categoryType: number;
constructor(
ownerUri: string,
@@ -59,6 +63,13 @@ export class JobData implements IAgentDialogData {
this.category = jobInfo.category;
this.description = jobInfo.description;
this.enabled = jobInfo.enabled;
this.jobSteps = jobInfo.jobSteps;
this.jobSchedules = jobInfo.jobSchedules;
this.alerts = jobInfo.alerts;
this.jobId = jobInfo.jobId;
this.startStepId = jobInfo.startStepId;
this.categoryId = jobInfo.categoryId;
this.categoryType = jobInfo.categoryType;
}
}
@@ -66,6 +77,10 @@ export class JobData implements IAgentDialogData {
return this._jobCategories;
}
public get jobCategoryIdsMap(): sqlops.AgentJobCategory[] {
return this._jobCategoryIdsMap;
}
public get operators(): string[] {
return this._operators;
}
@@ -89,7 +104,7 @@ export class JobData implements IAgentDialogData {
this._jobCategories = jobDefaults.categories.map((cat) => {
return cat.name;
});
this._jobCategoryIdsMap = jobDefaults.categories;
this._defaultOwner = jobDefaults.owner;
this._operators = ['', this._defaultOwner];
@@ -105,8 +120,6 @@ export class JobData implements IAgentDialogData {
displayName: this.JobCompletionActionCondition_Always,
name: sqlops.JobCompletionActionCondition.Always.toString()
}];
this.jobSchedules = [];
}
public async save() {
@@ -114,7 +127,6 @@ export class JobData implements IAgentDialogData {
let result = this.dialogMode === AgentDialogMode.CREATE
? await this._agentService.createJob(this.ownerUri, jobInfo)
: await this._agentService.updateJob(this.ownerUri, this.originalName, jobInfo);
if (!result || !result.success) {
vscode.window.showErrorMessage(
localize('jobData.saveErrorMessage', "Job update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown'));
@@ -134,29 +146,22 @@ export class JobData implements IAgentDialogData {
};
}
public addJobSchedule(schedule: sqlops.AgentJobScheduleInfo) {
let existingSchedule = this.jobSchedules.find(item => item.name === schedule.name);
if (!existingSchedule) {
this.jobSchedules.push(schedule);
}
}
public toAgentJobInfo(): sqlops.AgentJobInfo {
return {
name: this.name,
owner: this.owner,
description: this.description,
EmailLevel: this.emailLevel,
PageLevel: this.pageLevel,
EventLogLevel: this.eventLogLevel,
DeleteLevel: this.deleteLevel,
OperatorToEmail: this.operatorToEmail,
OperatorToPage: this.operatorToPage,
emailLevel: this.emailLevel,
pageLevel: this.pageLevel,
eventLogLevel: this.eventLogLevel,
deleteLevel: this.deleteLevel,
operatorToEmail: this.operatorToEmail,
operatorToPage: this.operatorToPage,
enabled: this.enabled,
category: this.category,
Alerts: this.alerts,
JobSchedules: this.jobSchedules,
JobSteps: this.jobSteps,
alerts: this.alerts,
jobSchedules: this.jobSchedules,
jobSteps: this.jobSteps,
// The properties below are not collected from UI
// We could consider using a seperate class for create job request
//
@@ -167,11 +172,12 @@ export class JobData implements IAgentDialogData {
hasSchedule: false,
hasStep: false,
runnable: true,
categoryId: 0,
categoryType: 1, // LocalJob, hard-coding the value, corresponds to the target tab in SSMS
categoryId: this.categoryId,
categoryType: this.categoryType,
lastRun: '',
nextRun: '',
jobId: ''
jobId: this.jobId,
startStepId: this.startStepId
};
}
}

View File

@@ -4,39 +4,55 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as sqlops from 'sqlops';
import * as nls from 'vscode-nls';
import * as vscode from 'vscode';
import { AgentUtils } from '../agentUtils';
import { IAgentDialogData, AgentDialogMode } from '../interfaces';
import { JobData } from './jobData';
const localize = nls.loadMessageBundle();
export class JobStepData implements IAgentDialogData {
public dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
// Error Messages
private static readonly CreateStepErrorMessage_JobNameIsEmpty = localize('stepData.jobNameRequired', 'Job name must be provided');
private static readonly CreateStepErrorMessage_StepNameIsEmpty = localize('stepData.stepNameRequired', 'Step name must be provided');
public dialogMode: AgentDialogMode;
public ownerUri: string;
public jobId: string; //
public jobId: string;
public jobName: string;
public script: string; //
public script: string;
public scriptName: string;
public stepName: string; //
public subSystem: string; //
public stepName: string;
public subSystem: string;
public id: number;
public failureAction: string; //
public successAction: string; //
public failStepId: number;
public failureAction: string;
public successAction: string;
public successStepId: number;
public failStepId: number;
public command: string;
public commandExecutionSuccessCode: number;
public databaseName: string; //
public databaseName: string;
public databaseUserName: string;
public server: string;
public outputFileName: string; //
public outputFileName: string;
public appendToLogFile: boolean;
public appendToStepHist: boolean;
public writeLogToTable: boolean;
public appendLogToTable: boolean;
public retryAttempts: number; //
public retryInterval: number; //
public retryAttempts: number;
public retryInterval: number;
public proxyName: string;
private jobModel: JobData;
private viaJobDialog: boolean;
constructor(ownerUri:string) {
constructor(ownerUri:string, jobModel?: JobData, viaJobDialog: boolean = false) {
this.ownerUri = ownerUri;
this.jobName = jobModel.name;
this.jobModel = jobModel;
this.viaJobDialog = viaJobDialog;
}
public async initialize() {
@@ -44,33 +60,101 @@ export class JobStepData implements IAgentDialogData {
public async save() {
let agentService = await AgentUtils.getAgentService();
agentService.createJobStep(this.ownerUri, {
jobId: this.jobId,
jobName: this.jobName,
script: this.script,
scriptName: this.scriptName,
stepName: this.stepName,
subSystem: this.subSystem,
id: 1,
failureAction: this.failureAction,
successAction: this.successAction,
failStepId: this.failStepId,
successStepId: this.successStepId,
command: this.command,
commandExecutionSuccessCode: this.commandExecutionSuccessCode,
databaseName: this.databaseName,
databaseUserName: this.databaseUserName,
server: this.server,
outputFileName: this.outputFileName,
appendToLogFile: this.appendToLogFile,
appendToStepHist: this.appendToStepHist,
writeLogToTable: this.writeLogToTable,
appendLogToTable: this.appendLogToTable,
retryAttempts: this.retryAttempts,
retryInterval: this.retryInterval,
proxyName: this.proxyName
}).then(result => {
console.info(result);
});
let result: any;
// if it's called via the job dialog, add it to the
// job model
if (this.viaJobDialog) {
if (this.jobModel) {
Promise.resolve(this);
return;
}
} else {
// has to be a create step
result = await agentService.createJobStep(this.ownerUri, JobStepData.convertToAgentJobStepInfo(this));
}
if (!result || !result.success) {
vscode.window.showErrorMessage(
localize('jobStepData.saveErrorMessage', "Step update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown'));
}
}
public validate(): { valid: boolean, errorMessages: string[] } {
let validationErrors: string[] = [];
if (!(this.stepName && this.stepName.trim())) {
validationErrors.push(JobStepData.CreateStepErrorMessage_StepNameIsEmpty);
}
if (!(this.jobName && this.jobName.trim())) {
validationErrors.push(JobStepData.CreateStepErrorMessage_JobNameIsEmpty);
}
return {
valid: validationErrors.length === 0,
errorMessages: validationErrors
};
}
public static convertToJobStepData(jobStepInfo: sqlops.AgentJobStepInfo, jobData: JobData) {
let stepData = new JobStepData(jobData.ownerUri, jobData);
stepData.ownerUri = jobData.ownerUri;
stepData.jobId = jobStepInfo.jobId;
stepData.jobName = jobStepInfo.jobName;
stepData.script = jobStepInfo.script;
stepData.scriptName = jobStepInfo.scriptName,
stepData.stepName = jobStepInfo.stepName,
stepData.subSystem = jobStepInfo.subSystem,
stepData.id = jobStepInfo.id,
stepData.failureAction = jobStepInfo.failureAction,
stepData.successAction = jobStepInfo.successAction,
stepData.failStepId = jobStepInfo.failStepId,
stepData.successStepId = jobStepInfo.successStepId,
stepData.command = jobStepInfo.command,
stepData.commandExecutionSuccessCode = jobStepInfo.commandExecutionSuccessCode,
stepData.databaseName = jobStepInfo.databaseName,
stepData.databaseUserName = jobStepInfo.databaseUserName,
stepData.server = jobStepInfo.server,
stepData.outputFileName = jobStepInfo.outputFileName,
stepData.appendToLogFile = jobStepInfo.appendToLogFile,
stepData.appendToStepHist = jobStepInfo.appendToStepHist,
stepData.writeLogToTable = jobStepInfo.writeLogToTable,
stepData.appendLogToTable = jobStepInfo.appendLogToTable,
stepData.retryAttempts = jobStepInfo.retryAttempts,
stepData.retryInterval = jobStepInfo.retryInterval,
stepData.proxyName = jobStepInfo.proxyName;
stepData.dialogMode = AgentDialogMode.EDIT;
stepData.viaJobDialog = true;
return stepData;
}
public static convertToAgentJobStepInfo(jobStepData: JobStepData): sqlops.AgentJobStepInfo {
let result: sqlops.AgentJobStepInfo = {
jobId: jobStepData.jobId,
jobName: jobStepData.jobName,
script: jobStepData.script,
scriptName: jobStepData.scriptName,
stepName: jobStepData.stepName,
subSystem: jobStepData.subSystem,
id: jobStepData.id,
failureAction: jobStepData.failureAction,
successAction: jobStepData.successAction,
failStepId: jobStepData.failStepId,
successStepId: jobStepData.successStepId,
command: jobStepData.command,
commandExecutionSuccessCode: jobStepData.commandExecutionSuccessCode,
databaseName: jobStepData.databaseName,
databaseUserName: jobStepData.databaseUserName,
server: jobStepData.server,
outputFileName: jobStepData.outputFileName,
appendToLogFile: jobStepData.appendToLogFile,
appendToStepHist: jobStepData.appendToStepHist,
writeLogToTable: jobStepData.writeLogToTable,
appendLogToTable: jobStepData.appendLogToTable,
retryAttempts: jobStepData.retryAttempts,
retryInterval: jobStepData.retryInterval,
proxyName: jobStepData.proxyName
};
return result;
}
}

View File

@@ -13,9 +13,11 @@ export class PickScheduleData implements IAgentDialogData {
public ownerUri: string;
public schedules: sqlops.AgentJobScheduleInfo[];
public selectedSchedule: sqlops.AgentJobScheduleInfo;
private jobName: string;
constructor(ownerUri:string) {
constructor(ownerUri:string, jobName: string) {
this.ownerUri = ownerUri;
this.jobName = jobName;
}
public async initialize() {
@@ -27,5 +29,6 @@ export class PickScheduleData implements IAgentDialogData {
}
public async save() {
this.selectedSchedule.jobName = this.jobName;
}
}

View File

@@ -20,6 +20,9 @@ export abstract class AgentDialog<T extends IAgentDialogData> {
public readonly onSuccess: vscode.Event<T> = this._onSuccess.event;
public dialog: sqlops.window.modelviewdialog.Dialog;
// Dialog Name for Telemetry
public dialogName: string;
constructor(public ownerUri: string, public model: T, public title: string) {
}
@@ -31,8 +34,9 @@ export abstract class AgentDialog<T extends IAgentDialogData> {
protected abstract async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog);
public async openDialog() {
this.dialog = sqlops.window.modelviewdialog.createDialog(this.title);
public async openDialog(dialogName?: string) {
let event = dialogName ? dialogName : null;
this.dialog = sqlops.window.modelviewdialog.createDialog(this.title, event);
await this.model.initialize();
@@ -49,11 +53,9 @@ export abstract class AgentDialog<T extends IAgentDialogData> {
protected async execute() {
this.updateModel();
let success = await this.model.save();
if (success) {
await this.model.save();
this._onSuccess.fire(this.model);
}
}
protected async cancel() {
}

View File

@@ -12,6 +12,7 @@ import { AgentUtils } from '../agentUtils';
import { AlertData } from '../data/alertData';
import { OperatorDialog } from './operatorDialog';
import { JobDialog } from './jobDialog';
import { JobData } from '../data/jobData';
const localize = nls.loadMessageBundle();
@@ -115,6 +116,10 @@ export class AlertDialog extends AgentDialog<AlertData> {
private static readonly DelayMinutesTextBoxLabel: string = localize('alertDialog.DelayMinutes', 'Delay Minutes');
private static readonly DelaySecondsTextBoxLabel: string = localize('alertDialog.DelaySeconds', 'Delay Seconds');
// Event Name strings
private readonly NewAlertDialog = 'NewAlertDialogOpen';
private readonly EditAlertDialog = 'EditAlertDialogOpened';
// UI Components
private generalTab: sqlops.window.modelviewdialog.DialogTab;
private responseTab: sqlops.window.modelviewdialog.DialogTab;
@@ -148,14 +153,26 @@ export class AlertDialog extends AgentDialog<AlertData> {
private delayMinutesTextBox: sqlops.InputBoxComponent;
private delaySecondsTextBox: sqlops.InputBoxComponent;
private jobs: string[];
private isEdit: boolean = false;
private databases: string[];
private jobModel: JobData;
public jobId: string;
public jobName: string;
constructor(ownerUri: string, alertInfo: sqlops.AgentAlertInfo = undefined, jobs: string[]) {
constructor(
ownerUri: string,
jobModel: JobData,
alertInfo: sqlops.AgentAlertInfo = undefined,
viaJobDialog: boolean = false
) {
super(ownerUri,
new AlertData(ownerUri, alertInfo),
new AlertData(ownerUri, alertInfo, jobModel, viaJobDialog),
alertInfo ? AlertDialog.EditDialogTitle : AlertDialog.CreateDialogTitle);
this.jobs = jobs;
this.jobModel = jobModel;
this.jobId = this.jobId ? this.jobId : this.jobModel.jobId;
this.jobName = this.jobName ? this.jobName : this.jobModel.name;
this.isEdit = alertInfo ? true : false;
this.dialogName = this.isEdit ? this.EditAlertDialog : this.NewAlertDialog;
}
protected async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog) {
@@ -512,7 +529,8 @@ export class AlertDialog extends AgentDialog<AlertData> {
protected updateModel() {
this.model.name = this.nameTextBox.value;
this.model.isEnabled = this.enabledCheckBox.checked;
this.model.jobId = this.jobId;
this.model.jobName = this.jobName;
this.model.alertType = this.getDropdownValue(this.typeDropDown);
let databaseName = this.getDropdownValue(this.databaseDropDown);
this.model.databaseName = (databaseName !== AlertDialog.AllDatabases) ? databaseName : undefined;

View File

@@ -10,6 +10,8 @@ import { JobStepDialog } from './jobStepDialog';
import { PickScheduleDialog } from './pickScheduleDialog';
import { AlertDialog } from './alertDialog';
import { AgentDialog } from './agentDialog';
import { AgentUtils } from '../agentUtils';
import { JobStepData } from '../data/jobStepData';
const localize = nls.loadMessageBundle();
@@ -40,11 +42,12 @@ export class JobDialog extends AgentDialog<JobData> {
private readonly StepsTable_TypeColumnString: string = localize('jobDialog.type', 'Type');
private readonly StepsTable_SuccessColumnString: string = localize('jobDialog.onSuccess', 'On Success');
private readonly StepsTable_FailureColumnString: string = localize('jobDialog.onFailure', 'On Failure');
private readonly NewStepButtonString: string = localize('jobDialog.new', 'New...');
private readonly EditStepButtonString: string = localize('jobDialog.edit', 'Edit');
private readonly DeleteStepButtonString: string = localize('jobDialog.delete', 'Delete');
private readonly NewStepButtonString: string = localize('jobDialog.new', 'New Step');
private readonly EditStepButtonString: string = localize('jobDialog.edit', 'Edit Step');
private readonly DeleteStepButtonString: string = localize('jobDialog.delete', 'Delete Step');
private readonly MoveStepUpButtonString: string = localize('jobDialog.moveUp', 'Move Step Up');
private readonly MoveStepDownButtonString: string = localize('jobDialog.moveDown', 'Move Step Up');
private readonly MoveStepDownButtonString: string = localize('jobDialog.moveDown', 'Move Step Down');
private readonly StartStepDropdownString: string = localize('jobDialog.startStepAt', 'Start step');
// Notifications tab strings
private readonly NotificationsTabTopLabelString: string = localize('jobDialog.notificationsTabTop', 'Actions to perform when the job completes');
@@ -62,6 +65,12 @@ export class JobDialog extends AgentDialog<JobData> {
private readonly AlertsTopLabelString: string = localize('jobDialog.alertsList', 'Alerts list');
private readonly NewAlertButtonString: string = localize('jobDialog.newAlert', 'New Alert');
private readonly AlertNameLabelString: string = localize('jobDialog.alertNameLabel', 'Alert Name');
private readonly AlertEnabledLabelString: string = localize('jobDialog.alertEnabledLabel', 'Enabled');
private readonly AlertTypeLabelString: string = localize('jobDialog.alertTypeLabel', 'Type');
// Event Name strings
private readonly NewJobDialogEvent: string = 'NewJobDialogOpened';
private readonly EditJobDialogEvent: string = 'EditJobDialogOpened';
// UI Components
private generalTab: sqlops.window.modelviewdialog.DialogTab;
@@ -85,6 +94,9 @@ export class JobDialog extends AgentDialog<JobData> {
private editStepButton: sqlops.ButtonComponent;
private deleteStepButton: sqlops.ButtonComponent;
// Schedule tab controls
private removeScheduleButton: sqlops.ButtonComponent;
// Notifications tab controls
private notificationsTabTopLabel: sqlops.TextComponent;
private emailCheckBox: sqlops.CheckBoxComponent;
@@ -97,6 +109,7 @@ export class JobDialog extends AgentDialog<JobData> {
private eventLogConditionDropdown: sqlops.DropDownComponent;
private deleteJobCheckBox: sqlops.CheckBoxComponent;
private deleteJobConditionDropdown: sqlops.DropDownComponent;
private startStepDropdown: sqlops.DropDownComponent;
// Schedule tab controls
private schedulesTable: sqlops.TableComponent;
@@ -105,12 +118,24 @@ export class JobDialog extends AgentDialog<JobData> {
// Alert tab controls
private alertsTable: sqlops.TableComponent;
private newAlertButton: sqlops.ButtonComponent;
private isEdit: boolean = false;
// Job objects
private steps: sqlops.AgentJobStepInfo[];
private schedules: sqlops.AgentJobScheduleInfo[];
private alerts: sqlops.AgentAlertInfo[] = [];
private startStepDropdownValues: sqlops.CategoryValue[] = [];
constructor(ownerUri: string, jobInfo: sqlops.AgentJobInfo = undefined) {
super(
ownerUri,
new JobData(ownerUri, jobInfo),
jobInfo ? JobDialog.EditDialogTitle : JobDialog.CreateDialogTitle);
this.steps = this.model.jobSteps ? this.model.jobSteps : [];
this.schedules = this.model.jobSchedules ? this.model.jobSchedules : [];
this.alerts = this.model.alerts ? this.model.alerts : [];
this.isEdit = jobInfo ? true : false;
this.dialogName = this.isEdit ? this.EditJobDialogEvent : this.NewJobDialogEvent;
}
protected async initializeDialog() {
@@ -193,10 +218,7 @@ export class JobDialog extends AgentDialog<JobData> {
private initializeStepsTab() {
this.stepsTab.registerContent(async view => {
let previewTag = view.modelBuilder.text()
.withProperties({
value: 'Feature Preview'
}).component();
let data = this.steps ? this.convertStepsToData(this.steps) : [];
this.stepsTable = view.modelBuilder.table()
.withProperties({
columns: [
@@ -206,20 +228,27 @@ export class JobDialog extends AgentDialog<JobData> {
this.StepsTable_SuccessColumnString,
this.StepsTable_FailureColumnString
],
data: [],
height: 430
data: data,
height: 650
}).component();
this.startStepDropdown = view.modelBuilder.dropDown().withProperties({ width: 180 }).component();
this.startStepDropdown.enabled = this.steps.length > 1 ? true : false;
this.steps.forEach((step) => {
this.startStepDropdownValues.push({ displayName: step.id + ': ' + step.stepName, name: step.id.toString() });
});
this.startStepDropdown.values = this.startStepDropdownValues;
this.moveStepUpButton = view.modelBuilder.button()
.withProperties({
label: this.MoveStepUpButtonString,
width: 80
width: 120
}).component();
this.moveStepDownButton = view.modelBuilder.button()
.withProperties({
label: this.MoveStepDownButtonString,
width: 80
width: 120
}).component();
this.moveStepUpButton.enabled = false;
@@ -227,13 +256,24 @@ export class JobDialog extends AgentDialog<JobData> {
this.newStepButton = view.modelBuilder.button().withProperties({
label: this.NewStepButtonString,
width: 80
width: 140
}).component();
let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, null, true);
stepDialog.onSuccess((step) => {
let stepInfo = JobStepData.convertToAgentJobStepInfo(step);
this.steps.push(stepInfo);
this.stepsTable.data = this.convertStepsToData(this.steps);
this.startStepDropdownValues = [];
this.steps.forEach((step) => {
this.startStepDropdownValues.push({ displayName: step.id + ': ' + step.stepName, name: step.id.toString() });
});
this.startStepDropdown.values = this.startStepDropdownValues;
});
this.newStepButton.onDidClick((e)=>{
if (this.nameTextBox.value && this.nameTextBox.value.length > 0) {
let stepDialog = new JobStepDialog(this.model.ownerUri, this.nameTextBox.value, '' , 1, this.model);
stepDialog.openNewStepDialog();
stepDialog.jobName = this.nameTextBox.value;
stepDialog.openDialog();
} else {
this.dialog.message = { text: this.BlankJobNameErrorText };
}
@@ -241,43 +281,155 @@ export class JobDialog extends AgentDialog<JobData> {
this.editStepButton = view.modelBuilder.button().withProperties({
label: this.EditStepButtonString,
width: 80
width: 140
}).component();
this.deleteStepButton = view.modelBuilder.button().withProperties({
label: this.DeleteStepButtonString,
width: 80
width: 140
}).component();
this.stepsTable.enabled = false;
this.editStepButton.enabled = false;
this.deleteStepButton.enabled = false;
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: previewTag,
title: ''
},
this.moveStepUpButton.onDidClick(() => {
let rowNumber = this.stepsTable.selectedRows[0];
let previousRow = rowNumber - 1;
let previousStep = this.steps[previousRow];
let previousStepId = this.steps[previousRow].id;
let currentStep = this.steps[rowNumber];
let currentStepId = this.steps[rowNumber].id;
this.steps[previousRow] = currentStep;
this.steps[rowNumber] = previousStep;
this.stepsTable.data = this.convertStepsToData(this.steps);
this.steps[previousRow].id = previousStepId;
this.steps[rowNumber].id = currentStepId;
this.stepsTable.selectedRows = [previousRow];
});
this.moveStepDownButton.onDidClick(() => {
let rowNumber = this.stepsTable.selectedRows[0];
let nextRow = rowNumber + 1;
let nextStep = this.steps[nextRow];
let nextStepId = this.steps[nextRow].id;
let currentStep = this.steps[rowNumber];
let currentStepId = this.steps[rowNumber].id;
this.steps[nextRow] = currentStep;
this.steps[rowNumber] = nextStep;
this.stepsTable.data = this.convertStepsToData(this.steps);
this.steps[nextRow].id = nextStepId;
this.steps[rowNumber].id = currentStepId;
this.stepsTable.selectedRows = [nextRow];
});
this.editStepButton.onDidClick(() => {
if (this.stepsTable.selectedRows.length === 1) {
let rowNumber = this.stepsTable.selectedRows[0];
let stepData = this.model.jobSteps[rowNumber];
let editStepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, stepData, true);
editStepDialog.onSuccess((step) => {
let stepInfo = JobStepData.convertToAgentJobStepInfo(step);
for (let i = 0; i < this.steps.length; i++) {
if (this.steps[i].id === stepInfo.id) {
this.steps[i] = stepInfo;
}
}
this.stepsTable.data = this.convertStepsToData(this.steps);
this.startStepDropdownValues = [];
this.steps.forEach((step) => {
this.startStepDropdownValues.push({ displayName: step.id + ': ' + step.stepName, name: step.id.toString() });
});
this.startStepDropdown.values = this.startStepDropdownValues;
});
editStepDialog.openDialog();
}
});
this.deleteStepButton.onDidClick(() => {
if (this.stepsTable.selectedRows.length === 1) {
let rowNumber = this.stepsTable.selectedRows[0];
AgentUtils.getAgentService().then((agentService) => {
let stepData = this.steps[rowNumber];
if (stepData.jobId) {
agentService.deleteJobStep(this.ownerUri, stepData).then((result) => {
if (result && result.success) {
this.steps.splice(rowNumber, 1);
let data = this.convertStepsToData(this.steps);
this.stepsTable.data = data;
this.startStepDropdownValues = [];
this.steps.forEach((step) => {
this.startStepDropdownValues.push({ displayName: step.id + ': ' + step.stepName, name: step.id.toString() });
});
this.startStepDropdown.values = this.startStepDropdownValues;
}
});
} else {
this.steps.splice(rowNumber, 1);
let data = this.convertStepsToData(this.steps);
this.stepsTable.data = data;
this.startStepDropdownValues = [];
this.steps.forEach((step) => {
this.startStepDropdownValues.push({ displayName: step.id + ': ' + step.stepName, name: step.id.toString() });
});
this.startStepDropdown.values = this.startStepDropdownValues;
}
});
}
});
this.stepsTable.onRowSelected((row) => {
// only let edit or delete steps if there's
// one step selection
if (this.stepsTable.selectedRows.length === 1) {
let rowNumber = this.stepsTable.selectedRows[0];
// if it's not the last step
if (this.steps.length !== rowNumber + 1) {
this.moveStepDownButton.enabled = true;
}
// if it's not the first step
if (rowNumber !== 0) {
this.moveStepUpButton.enabled = true;
}
this.deleteStepButton.enabled = true;
this.editStepButton.enabled = true;
}
});
let stepMoveContainer = this.createRowContainer(view).withItems([this.startStepDropdown, this.moveStepUpButton, this.moveStepDownButton]).component();
let stepsDialogContainer = this.createRowContainer(view).withItems([this.newStepButton, this.editStepButton, this.deleteStepButton]).component();
let formModel = view.modelBuilder.formContainer().withFormItems([
{
component: this.stepsTable,
title: this.JobStepsTopLabelString,
actions: [this.moveStepUpButton, this.moveStepDownButton, this.newStepButton, this.editStepButton, this.deleteStepButton]
}]).withLayout({ width: '100%' }).component();
title: this.JobStepsTopLabelString
},
{
component: stepMoveContainer,
title: this.StartStepDropdownString
},
{
component: stepsDialogContainer,
title: ''
}
]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
this.setConditionDropdownSelectedValue(this.startStepDropdown, this.model.startStepId);
});
}
private initializeAlertsTab() {
this.alertsTab.registerContent(async view => {
let previewTag = view.modelBuilder.text()
.withProperties({
value: 'Feature Preview'
}).component();
let alerts = this.model.alerts ? this.model.alerts : [];
let data = this.convertAlertsToData(alerts);
this.alertsTable = view.modelBuilder.table()
.withProperties({
columns: [
this.AlertNameLabelString
this.AlertNameLabelString,
this.AlertEnabledLabelString,
this.AlertTypeLabelString
],
data: [],
height: 430,
data: data,
height: 750,
width: 400
}).component();
@@ -286,18 +438,24 @@ export class JobDialog extends AgentDialog<JobData> {
width: 80
}).component();
this.newAlertButton.onDidClick((e)=>{
let alertDialog = new AlertDialog(this.model.ownerUri, null, []);
alertDialog.onSuccess((dialogModel) => {
let alertDialog = new AlertDialog(this.model.ownerUri, this.model, null, true);
alertDialog.onSuccess((alert) => {
let alertInfo = alert.toAgentAlertInfo();
this.alerts.push(alertInfo);
this.alertsTable.data = this.convertAlertsToData(this.alerts);
});
this.newAlertButton.onDidClick(()=>{
if (this.nameTextBox.value && this.nameTextBox.value.length > 0) {
alertDialog.jobId = this.model.jobId;
alertDialog.jobName = this.model.name ? this.model.name : this.nameTextBox.value;
alertDialog.openDialog();
} else {
this.dialog.message = { text: this.BlankJobNameErrorText };
}
});
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: previewTag,
title: ''
}, {
component: this.alertsTable,
title: this.AlertsTopLabelString,
actions: [this.newAlertButton]
@@ -312,10 +470,12 @@ export class JobDialog extends AgentDialog<JobData> {
this.schedulesTable = view.modelBuilder.table()
.withProperties({
columns: [
this.ScheduleNameLabelString
PickScheduleDialog.SchedulesIDText,
PickScheduleDialog.ScheduleNameLabelText,
PickScheduleDialog.ScheduleDescription
],
data: [],
height: 430,
height: 750,
width: 420
}).component();
@@ -323,24 +483,42 @@ export class JobDialog extends AgentDialog<JobData> {
label: this.PickScheduleButtonString,
width: 80
}).component();
this.pickScheduleButton.onDidClick((e)=>{
let pickScheduleDialog = new PickScheduleDialog(this.model.ownerUri);
this.removeScheduleButton = view.modelBuilder.button().withProperties({
label: 'Remove schedule',
width: 100
}).component();
this.pickScheduleButton.onDidClick(()=>{
let pickScheduleDialog = new PickScheduleDialog(this.model.ownerUri, this.model.name);
pickScheduleDialog.onSuccess((dialogModel) => {
let selectedSchedule = dialogModel.selectedSchedule;
if (selectedSchedule) {
this.model.addJobSchedule(selectedSchedule);
let existingSchedule = this.schedules.find(item => item.name === selectedSchedule.name);
if (!existingSchedule) {
selectedSchedule.jobName = this.model.name ? this.model.name : this.nameTextBox.value;
this.schedules.push(selectedSchedule);
}
this.populateScheduleTable();
}
});
pickScheduleDialog.showDialog();
});
this.removeScheduleButton.onDidClick(() => {
if (this.schedulesTable.selectedRows.length === 1) {
let selectedRow = this.schedulesTable.selectedRows[0];
let selectedScheduleName = this.schedulesTable.data[selectedRow][1];
for (let i = 0; i < this.schedules.length; i++) {
if (this.schedules[i].name === selectedScheduleName) {
this.schedules.splice(i, 1);
}
}
this.populateScheduleTable();
}
});
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.schedulesTable,
title: this.SchedulesTopLabelString,
actions: [this.pickScheduleButton]
actions: [this.pickScheduleButton, this.removeScheduleButton]
}]).withLayout({ width: '100%' }).component();
await view.initializeModel(formModel);
@@ -350,14 +528,10 @@ export class JobDialog extends AgentDialog<JobData> {
}
private populateScheduleTable() {
if (this.model.jobSchedules) {
let data: any[][] = [];
for (let i = 0; i < this.model.jobSchedules.length; ++i) {
let schedule = this.model.jobSchedules[i];
data[i] = [ schedule.name ];
}
let data = this.convertSchedulesToData(this.schedules);
this.schedulesTable.data = data;
}
this.schedulesTable.height = 750;
}
private initializeNotificationsTab() {
@@ -466,6 +640,44 @@ export class JobDialog extends AgentDialog<JobData> {
});
}
private convertStepsToData(jobSteps: sqlops.AgentJobStepInfo[]): any[][] {
let result = [];
jobSteps.forEach(jobStep => {
let cols = [];
cols.push(jobStep.id);
cols.push(jobStep.stepName);
cols.push(jobStep.subSystem);
cols.push(jobStep.successAction);
cols.push(jobStep.failureAction);
result.push(cols);
});
return result;
}
private convertSchedulesToData(jobSchedules: sqlops.AgentJobScheduleInfo[]): any[][] {
let result = [];
jobSchedules.forEach(schedule => {
let cols = [];
cols.push(schedule.id);
cols.push(schedule.name);
cols.push(schedule.description);
result.push(cols);
});
return result;
}
private convertAlertsToData(alerts: sqlops.AgentAlertInfo[]): any[][] {
let result = [];
alerts.forEach(alert => {
let cols = [];
cols.push(alert.name);
cols.push(alert.isEnabled);
cols.push(alert.alertType.toString());
result.push(cols);
});
return result;
}
protected updateModel() {
this.model.name = this.nameTextBox.value;
this.model.owner = this.ownerTextBox.value;
@@ -478,5 +690,19 @@ export class JobDialog extends AgentDialog<JobData> {
this.model.pageLevel = this.getActualConditionValue(this.pagerCheckBox, this.pagerConditionDropdown);
this.model.eventLogLevel = this.getActualConditionValue(this.eventLogCheckBox, this.eventLogConditionDropdown);
this.model.deleteLevel = this.getActualConditionValue(this.deleteJobCheckBox, this.deleteJobConditionDropdown);
this.model.startStepId = +this.getDropdownValue(this.startStepDropdown);
if (!this.model.jobSteps) {
this.model.jobSteps = [];
}
this.model.jobSteps = this.steps;
if (!this.model.jobSchedules) {
this.model.jobSchedules = [];
}
this.model.jobSchedules = this.schedules;
if (!this.model.alerts) {
this.model.alerts = [];
}
this.model.alerts = this.alerts;
this.model.categoryId = +this.model.jobCategoryIdsMap.find(cat => cat.name === this.model.category).id;
}
}

View File

@@ -9,16 +9,19 @@ import * as vscode from 'vscode';
import { JobStepData } from '../data/jobStepData';
import { AgentUtils } from '../agentUtils';
import { JobData } from '../data/jobData';
import { AgentDialog } from './agentDialog';
import { AgentDialogMode } from '../interfaces';
const path = require('path');
const localize = nls.loadMessageBundle();
export class JobStepDialog {
export class JobStepDialog extends AgentDialog<JobStepData> {
// TODO: localize
// Top level
//
private readonly DialogTitle: string = localize('jobStepDialog.newJobStep', 'New Job Step');
private static readonly NewDialogTitle: string = localize('jobStepDialog.newJobStep', 'New Job Step');
private static readonly EditDialogTitle: string = localize('jobStepDialog.editJobStep', 'Edit Job Step');
private readonly FileBrowserDialogTitle: string = localize('jobStepDialog.fileBrowserTitle', 'Locate Database Files - ');
private readonly OkButtonText: string = localize('jobStepDialog.ok', 'OK');
private readonly CancelButtonText: string = localize('jobStepDialog.cancel', 'Cancel');
@@ -26,11 +29,10 @@ export class JobStepDialog {
private readonly AdvancedTabText: string = localize('jobStepDialog.advanced', 'Advanced');
private readonly OpenCommandText: string = localize('jobStepDialog.open', 'Open...');
private readonly ParseCommandText: string = localize('jobStepDialog.parse','Parse');
private readonly NextButtonText: string = localize('jobStepDialog.next', 'Next');
private readonly PreviousButtonText: string = localize('jobStepDialog.previous','Previous');
private readonly SuccessfulParseText: string = localize('jobStepDialog.successParse', 'The command was successfully parsed.');
private readonly FailureParseText: string = localize('jobStepDialog.failParse', 'The command failed.');
private readonly BlankStepNameErrorText: string = localize('jobStepDialog.blankStepName', 'The step name cannot be left blank');
private readonly ProcessExitCodeText: string = localize('jobStepDialog.processExitCode', 'Process exit code of a successful command:');
// General Control Titles
private readonly StepNameLabelString: string = localize('jobStepDialog.stepNameLabel', 'Step Name');
@@ -59,15 +61,19 @@ export class JobStepDialog {
// Dropdown options
private readonly TSQLScript: string = localize('jobStepDialog.TSQL', 'Transact-SQL script (T-SQL)');
private readonly Powershell: string = localize('jobStepDialog.powershell', 'PowerShell');
private readonly CmdExec: string = localize('jobStepDialog.CmdExec', 'Operating system (CmdExec)');
private readonly AgentServiceAccount: string = localize('jobStepDialog.agentServiceAccount', 'SQL Server Agent Service Account');
private readonly NextStep: string = localize('jobStepDialog.nextStep', 'Go to the next step');
private readonly QuitJobReportingSuccess: string = localize('jobStepDialog.quitJobSuccess', 'Quit the job reporting success');
private readonly QuitJobReportingFailure: string = localize('jobStepDialog.quitJobFailure', 'Quit the job reporting failure');
// Event Name strings
private readonly NewStepDialog = 'NewStepDialogOpened';
private readonly EditStepDialog = 'EditStepDialogOpened';
// UI Components
// Dialogs
private dialog: sqlops.window.modelviewdialog.Dialog;
private fileBrowserDialog: sqlops.window.modelviewdialog.Dialog;
// Dialog tabs
@@ -83,6 +89,7 @@ export class JobStepDialog {
private outputFileNameBox: sqlops.InputBoxComponent;
private fileBrowserNameBox: sqlops.InputBoxComponent;
private userInputBox: sqlops.InputBoxComponent;
private processExitCodeBox: sqlops.InputBoxComponent;
// Dropdowns
private typeDropdown: sqlops.DropDownComponent;
@@ -95,45 +102,45 @@ export class JobStepDialog {
// Buttons
private openButton: sqlops.ButtonComponent;
private parseButton: sqlops.ButtonComponent;
private nextButton: sqlops.ButtonComponent;
private previousButton: sqlops.ButtonComponent;
private outputFileBrowserButton: sqlops.ButtonComponent;
// Checkbox
private appendToExistingFileCheckbox: sqlops.CheckBoxComponent;
private logToTableCheckbox: sqlops.CheckBoxComponent;
private logStepOutputHistoryCheckbox: sqlops.CheckBoxComponent;
private fileBrowserTree: sqlops.FileBrowserTreeComponent;
private jobModel: JobData;
private model: JobStepData;
private ownerUri: string;
private jobName: string;
public jobName: string;
private server: string;
private stepId: number;
private isEdit: boolean;
constructor(
ownerUri: string,
jobName: string,
server: string,
stepId: number,
jobModel?: JobData
jobModel: JobData,
jobStepInfo?: sqlops.AgentJobStepInfo,
viaJobDialog: boolean = false
) {
this.model = new JobStepData(ownerUri);
this.stepId = stepId;
this.ownerUri = ownerUri;
this.jobName = jobName;
this.server = server;
super(ownerUri,
jobStepInfo ? JobStepData.convertToJobStepData(jobStepInfo, jobModel) : new JobStepData(ownerUri, jobModel, viaJobDialog),
jobStepInfo ? JobStepDialog.EditDialogTitle : JobStepDialog.NewDialogTitle);
this.stepId = jobStepInfo ?
jobStepInfo.id : jobModel.jobSteps ?
jobModel.jobSteps.length + 1 : 1;
this.isEdit = jobStepInfo ? true : false;
this.model.dialogMode = this.isEdit ? AgentDialogMode.EDIT : AgentDialogMode.CREATE;
this.jobModel = jobModel;
this.jobName = this.jobName ? this.jobName : this.jobModel.name;
this.server = server;
this.dialogName = this.isEdit ? this.EditStepDialog : this.NewStepDialog;
}
private initializeUIComponents() {
this.dialog = sqlops.window.modelviewdialog.createDialog(this.DialogTitle);
this.generalTab = sqlops.window.modelviewdialog.createTab(this.GeneralTabText);
this.advancedTab = sqlops.window.modelviewdialog.createTab(this.AdvancedTabText);
this.dialog.content = [this.generalTab, this.advancedTab];
this.dialog.okButton.onClick(async () => await this.execute());
this.dialog.okButton.label = this.OkButtonText;
this.dialog.cancelButton.label = this.CancelButtonText;
}
private createCommands(view, queryProvider: sqlops.QueryProvider) {
@@ -172,18 +179,6 @@ export class JobStepDialog {
inputType: 'text'
})
.component();
this.nextButton = view.modelBuilder.button()
.withProperties({
label: this.NextButtonText,
enabled: false,
width: '80px'
}).component();
this.previousButton = view.modelBuilder.button()
.withProperties({
label: this.PreviousButtonText,
enabled: false,
width: '80px'
}).component();
}
private createGeneralTab(databases: string[], queryProvider: sqlops.QueryProvider) {
@@ -201,7 +196,7 @@ export class JobStepDialog {
this.typeDropdown = view.modelBuilder.dropDown()
.withProperties({
value: this.TSQLScript,
values: [this.TSQLScript]
values: [this.TSQLScript, this.CmdExec, this.Powershell]
})
.component();
this.runAsDropdown = view.modelBuilder.dropDown()
@@ -211,33 +206,20 @@ export class JobStepDialog {
})
.component();
this.runAsDropdown.enabled = false;
this.typeDropdown.onValueChanged((type) => {
if (type.selected !== this.TSQLScript) {
this.runAsDropdown.value = this.AgentServiceAccount;
this.runAsDropdown.values = [this.runAsDropdown.value];
} else {
this.runAsDropdown.value = '';
this.runAsDropdown.values = [''];
}
});
this.databaseDropdown = view.modelBuilder.dropDown()
.withProperties({
value: databases[0],
values: databases
}).component();
this.processExitCodeBox = view.modelBuilder.inputBox()
.withProperties({
}).component();
this.processExitCodeBox.enabled = false;
// create the commands section
this.createCommands(view, queryProvider);
let buttonContainer = view.modelBuilder.flexContainer()
.withLayout({
flexFlow: 'row',
justifyContent: 'space-between',
width: 420
}).withItems([this.openButton, this.parseButton, this.previousButton, this.nextButton], {
flex: '1 1 50%'
}).component();
let formModel = view.modelBuilder.formContainer()
.withFormItems([{
component: this.nameTextBox,
@@ -251,17 +233,63 @@ export class JobStepDialog {
}, {
component: this.databaseDropdown,
title: this.DatabaseLabelString
}, {
component: this.processExitCodeBox,
title: this.ProcessExitCodeText
}, {
component: this.commandTextBox,
title: this.CommandLabelString,
actions: [buttonContainer]
actions: [this.openButton, this.parseButton]
}], {
horizontal: false,
componentWidth: 420
}).component();
this.typeDropdown.onValueChanged((type) => {
switch (type.selected) {
case(this.TSQLScript):
this.runAsDropdown.value = '';
this.runAsDropdown.values = [''];
this.runAsDropdown.enabled = false;
this.databaseDropdown.enabled = true;
this.databaseDropdown.values = databases;
this.databaseDropdown.value = databases[0];
this.processExitCodeBox.value = '';
this.processExitCodeBox.enabled = false;
break;
case(this.Powershell):
this.runAsDropdown.value = this.AgentServiceAccount;
this.runAsDropdown.values = [this.runAsDropdown.value];
this.runAsDropdown.enabled = true;
this.databaseDropdown.enabled = false;
this.databaseDropdown.values = [''];
this.databaseDropdown.value = '';
this.processExitCodeBox.value = '';
this.processExitCodeBox.enabled = false;
break;
case(this.CmdExec):
this.databaseDropdown.enabled = false;
this.databaseDropdown.values = [''];
this.databaseDropdown.value = '';
this.runAsDropdown.value = this.AgentServiceAccount;
this.runAsDropdown.values = [this.runAsDropdown.value];
this.runAsDropdown.enabled = true;
this.processExitCodeBox.enabled = true;
this.processExitCodeBox.value = '0';
break;
}
});
let formWrapper = view.modelBuilder.loadingComponent().withItem(formModel).component();
formWrapper.loading = false;
await view.initializeModel(formWrapper);
// Load values for edit scenario
if (this.isEdit) {
this.nameTextBox.value = this.model.stepName;
this.typeDropdown.value = this.model.subSystem;
this.databaseDropdown.value = this.model.databaseName;
this.commandTextBox.value = this.model.command;
}
});
}
@@ -298,7 +326,7 @@ export class JobStepDialog {
let logToTableContainer = view.modelBuilder.flexContainer()
.withLayout({ flexFlow: 'row', justifyContent: 'space-between', width: 300 })
.withItems([this.logToTableCheckbox]).component();
let logStepOutputHistoryCheckbox = view.modelBuilder.checkBox()
this.logStepOutputHistoryCheckbox = view.modelBuilder.checkBox()
.withProperties({ label: this.IncludeStepOutputHistoryLabel }).component();
this.userInputBox = view.modelBuilder.inputBox()
.withProperties({ inputType: 'text', width: '100%' }).component();
@@ -323,7 +351,7 @@ export class JobStepDialog {
component: appendCheckboxContainer,
title: ' '
}, {
component: logStepOutputHistoryCheckbox,
component: this.logStepOutputHistoryCheckbox,
title: ''
}, {
component: this.userInputBox,
@@ -334,7 +362,19 @@ export class JobStepDialog {
let formWrapper = view.modelBuilder.loadingComponent().withItem(formModel).component();
formWrapper.loading = false;
view.initializeModel(formWrapper);
await view.initializeModel(formWrapper);
if (this.isEdit) {
this.successActionDropdown.value = this.model.successAction;
this.retryAttemptsBox.value = this.model.retryAttempts.toString();
this.retryIntervalBox.value = this.model.retryInterval.toString();
this.failureActionDropdown.value = this.model.failureAction;
this.outputFileNameBox.value = this.model.outputFileName;
this.appendToExistingFileCheckbox.checked = this.model.appendToLogFile;
this.logToTableCheckbox.checked = this.model.appendLogToTable;
this.logStepOutputHistoryCheckbox.checked = this.model.appendToStepHist;
this.userInputBox.value = this.model.databaseUserName;
}
});
}
@@ -478,7 +518,7 @@ export class JobStepDialog {
return outputFileForm;
}
protected execute() {
protected updateModel() {
this.model.stepName = this.nameTextBox.value;
if (!this.model.stepName || this.model.stepName.length === 0) {
this.dialog.message = this.dialog.message = { text: this.BlankStepNameErrorText };
@@ -487,7 +527,6 @@ export class JobStepDialog {
this.model.jobName = this.jobName;
this.model.id = this.stepId;
this.model.server = this.server;
this.model.stepName = this.nameTextBox.value;
this.model.subSystem = this.typeDropdown.value as string;
this.model.databaseName = this.databaseDropdown.value as string;
this.model.script = this.commandTextBox.value;
@@ -497,14 +536,24 @@ export class JobStepDialog {
this.model.failureAction = this.failureActionDropdown.value as string;
this.model.outputFileName = this.outputFileNameBox.value;
this.model.appendToLogFile = this.appendToExistingFileCheckbox.checked;
this.model.command = this.commandTextBox.value ? this.commandTextBox.value : '';
this.model.commandExecutionSuccessCode = this.processExitCodeBox.value ? +this.processExitCodeBox.value : 0;
}
public async openNewStepDialog() {
public async initializeDialog() {
let databases = await AgentUtils.getDatabases(this.ownerUri);
let queryProvider = await AgentUtils.getQueryProvider();
this.initializeUIComponents();
this.createGeneralTab(databases, queryProvider);
this.createAdvancedTab();
sqlops.window.modelviewdialog.openDialog(this.dialog);
this.dialog.registerCloseValidator(() => {
this.updateModel();
let validationResult = this.model.validate();
if (!validationResult.valid) {
// TODO: Show Error Messages
console.error(validationResult.errorMessages.join(','));
}
return validationResult.valid;
});
}
}

View File

@@ -35,7 +35,7 @@ export class OperatorDialog extends AgentDialog<OperatorData> {
private static readonly PagerSundayCheckBoxLabel: string = localize('createOperator.PagerSundayCheckBox', 'Sunday');
private static readonly WorkdayBeginLabel: string = localize('createOperator.workdayBegin', 'Workday begin');
private static readonly WorkdayEndLabel: string = localize('createOperator.workdayEnd', 'Workday end');
private static readonly PagerDutyScheduleLabel: string = localize('createOperator.PagerDutySchedule', 'Pager on duty schdule');
private static readonly PagerDutyScheduleLabel: string = localize('createOperator.PagerDutySchedule', 'Pager on duty schedule');
// Notifications tab strings
private static readonly AlertsTableLabel: string = localize('createOperator.AlertListHeading', 'Alert list');
@@ -43,6 +43,10 @@ export class OperatorDialog extends AgentDialog<OperatorData> {
private static readonly AlertEmailColumnLabel: string = localize('createOperator.AlertEmailColumnLabel', 'E-mail');
private static readonly AlertPagerColumnLabel: string = localize('createOperator.AlertPagerColumnLabel', 'Pager');
// Event strings
private readonly NewOperatorDialog = 'NewOperatorDialogOpened';
private readonly EditOperatorDialog = 'EditOperatorDialogOpened';
// UI Components
private generalTab: sqlops.window.modelviewdialog.DialogTab;
private notificationsTab: sqlops.window.modelviewdialog.DialogTab;
@@ -68,12 +72,15 @@ export class OperatorDialog extends AgentDialog<OperatorData> {
// Notification tab controls
private alertsTable: sqlops.TableComponent;
private isEdit: boolean = false;
constructor(ownerUri: string, operatorInfo: sqlops.AgentOperatorInfo = undefined) {
super(
ownerUri,
new OperatorData(ownerUri, operatorInfo),
operatorInfo ? OperatorDialog.EditDialogTitle : OperatorDialog.CreateDialogTitle);
this.isEdit = operatorInfo ? true : false;
this.dialogName = this.isEdit ? this.EditOperatorDialog : this.NewOperatorDialog;
}
protected async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog) {

View File

@@ -18,8 +18,11 @@ export class PickScheduleDialog {
private readonly DialogTitle: string = localize('pickSchedule.jobSchedules', 'Job Schedules');
private readonly OkButtonText: string = localize('pickSchedule.ok', 'OK');
private readonly CancelButtonText: string = localize('pickSchedule.cancel', 'Cancel');
private readonly ScheduleNameLabelText: string = localize('pickSchedule.scheduleName', 'Schedule Name');
private readonly SchedulesLabelText: string = localize('pickSchedule.schedules', 'Schedules');
private readonly SchedulesLabelText: string = localize('pickSchedule.availableSchedules', 'Available Schedules:');
public static readonly ScheduleNameLabelText: string = localize('pickSchedule.scheduleName', 'Name');
public static readonly SchedulesIDText: string = localize('pickSchedule.scheduleID','ID');
public static readonly ScheduleDescription: string = localize('pickSchedule.description','Description');
// UI Components
private dialog: sqlops.window.modelviewdialog.Dialog;
@@ -30,8 +33,8 @@ export class PickScheduleDialog {
private _onSuccess: vscode.EventEmitter<PickScheduleData> = new vscode.EventEmitter<PickScheduleData>();
public readonly onSuccess: vscode.Event<PickScheduleData> = this._onSuccess.event;
constructor(ownerUri: string) {
this.model = new PickScheduleData(ownerUri);
constructor(ownerUri: string, jobName: string) {
this.model = new PickScheduleData(ownerUri, jobName);
}
public async showDialog() {
@@ -50,11 +53,13 @@ export class PickScheduleDialog {
this.schedulesTable = view.modelBuilder.table()
.withProperties({
columns: [
this.ScheduleNameLabelText
PickScheduleDialog.SchedulesIDText,
PickScheduleDialog.ScheduleNameLabelText,
PickScheduleDialog.ScheduleDescription
],
data: [],
height: '80em',
width: '40em'
height: 750,
width: 430
}).component();
let formModel = view.modelBuilder.formContainer()
@@ -69,7 +74,7 @@ export class PickScheduleDialog {
let data: any[][] = [];
for (let i = 0; i < this.model.schedules.length; ++i) {
let schedule = this.model.schedules[i];
data[i] = [ schedule.name ];
data[i] = [ schedule.id, schedule.name, schedule.description ];
}
this.schedulesTable.data = data;
}

View File

@@ -36,6 +36,9 @@ export class ProxyDialog extends AgentDialog<ProxyData> {
private static readonly PowerShellLabel: string = localize('createProxy.PowerShell', 'PowerShell');
private static readonly SubSystemHeadingLabel: string = localize('createProxy.subSystemHeading', 'Active to the following subsytems');
private readonly NewProxyDialog = 'NewProxyDialogOpened';
private readonly EditProxyDialog = 'EditProxyDialogOpened';
// UI Components
private generalTab: sqlops.window.modelviewdialog.DialogTab;
@@ -56,6 +59,7 @@ export class ProxyDialog extends AgentDialog<ProxyData> {
private powershellCheckBox: sqlops.CheckBoxComponent;
private credentials: sqlops.CredentialInfo[];
private isEdit: boolean = false;
constructor(ownerUri: string, proxyInfo: sqlops.AgentProxyInfo = undefined, credentials: sqlops.CredentialInfo[]) {
super(
@@ -63,6 +67,8 @@ export class ProxyDialog extends AgentDialog<ProxyData> {
new ProxyData(ownerUri, proxyInfo),
proxyInfo ? ProxyDialog.EditDialogTitle : ProxyDialog.CreateDialogTitle);
this.credentials = credentials;
this.isEdit = proxyInfo ? true : false;
this.dialogName = this.isEdit ? this.EditProxyDialog : this.NewProxyDialog;
}
protected async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog) {

View File

@@ -13,5 +13,5 @@ export enum AgentDialogMode {
export interface IAgentDialogData {
dialogMode: AgentDialogMode;
initialize(): void;
save(): void;
save(): Promise<void>;
}

View File

@@ -13,6 +13,8 @@ import { OperatorDialog } from './dialogs/operatorDialog';
import { ProxyDialog } from './dialogs/proxyDialog';
import { JobStepDialog } from './dialogs/jobStepDialog';
import { PickScheduleDialog } from './dialogs/pickScheduleDialog';
import { JobData } from './data/jobData';
import { AgentUtils } from './agentUtils';
const localize = nls.loadMessageBundle();
@@ -38,29 +40,33 @@ export class MainController {
public activate(): void {
vscode.commands.registerCommand('agent.openJobDialog', (ownerUri: string, jobInfo: sqlops.AgentJobInfo) => {
let dialog = new JobDialog(ownerUri, jobInfo);
dialog.openDialog();
dialog.dialogName ? dialog.openDialog(dialog.dialogName) : dialog.openDialog();
});
vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, jobId: string, server: string, stepId: number) => {
let dialog = new JobStepDialog(ownerUri, jobId, server, stepId);
dialog.openNewStepDialog();
vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, jobInfo: sqlops.AgentJobInfo, jobStepInfo: sqlops.AgentJobStepInfo) => {
AgentUtils.getAgentService().then((agentService) => {
let jobData: JobData = new JobData(ownerUri, jobInfo, agentService);
let dialog = new JobStepDialog(ownerUri, server, jobData, jobStepInfo, false);
dialog.dialogName ? dialog.openDialog(dialog.dialogName) : dialog.openDialog();
});
vscode.commands.registerCommand('agent.openPickScheduleDialog', (ownerUri: string) => {
let dialog = new PickScheduleDialog(ownerUri);
});
vscode.commands.registerCommand('agent.openPickScheduleDialog', (ownerUri: string, jobName: string) => {
let dialog = new PickScheduleDialog(ownerUri, jobName);
dialog.showDialog();
});
vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, alertInfo: sqlops.AgentAlertInfo, jobs: string[]) => {
let dialog = new AlertDialog(ownerUri, alertInfo, jobs);
dialog.openDialog();
vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, jobInfo: sqlops.AgentJobInfo, alertInfo: sqlops.AgentAlertInfo) => {
AgentUtils.getAgentService().then((agentService) => {
let jobData: JobData = new JobData(ownerUri, jobInfo, agentService);
let dialog = new AlertDialog(ownerUri, jobData, alertInfo, false);
dialog.dialogName ? dialog.openDialog(dialog.dialogName) : dialog.openDialog();
});
});
vscode.commands.registerCommand('agent.openOperatorDialog', (ownerUri: string, operatorInfo: sqlops.AgentOperatorInfo) => {
let dialog = new OperatorDialog(ownerUri, operatorInfo);
dialog.openDialog();
dialog.dialogName ? dialog.openDialog(dialog.dialogName) : dialog.openDialog();
});
vscode.commands.registerCommand('agent.openProxyDialog', (ownerUri: string, proxyInfo: sqlops.AgentProxyInfo, credentials: sqlops.CredentialInfo[]) => {
//@TODO: reenable create proxy after snapping July release (7/14/18)
// let dialog = new ProxyDialog(ownerUri, proxyInfo, credentials);
// dialog.openDialog();
MainController.showNotYetImplemented();
let dialog = new ProxyDialog(ownerUri, proxyInfo, credentials);
dialog.dialogName ? dialog.openDialog(dialog.dialogName) : dialog.openDialog();
});
}

View File

@@ -14,7 +14,7 @@ export class TestAgentService implements sqlops.AgentServicesProvider {
getJobs(ownerUri: string): Thenable<sqlops.AgentJobsResult> {
return undefined;
}
getJobHistory(ownerUri: string, jobId: string): Thenable<sqlops.AgentJobHistoryResult> {
getJobHistory(ownerUri: string, jobId: string, jobName: string): Thenable<sqlops.AgentJobHistoryResult> {
return undefined;
}
jobAction(ownerUri: string, jobName: string, action: string): Thenable<sqlops.ResultStatus> {

View File

@@ -5,38 +5,46 @@
ansi-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
charenc@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
debug@^2.2.0:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
debug@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
dependencies:
ms "2.0.0"
ms "^2.1.1"
is-buffer@~1.1.1:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
lodash@^4.16.4:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
md5@^2.1.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=
dependencies:
charenc "~0.0.1"
crypt "~0.0.1"
@@ -45,16 +53,19 @@ md5@^2.1.0:
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
dependencies:
minimist "0.0.8"
mocha-junit-reporter@^1.17.0:
version "1.17.0"
resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-1.17.0.tgz#2e5149ed40fc5d2e3ca71e42db5ab1fec9c6d85c"
version "1.18.0"
resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-1.18.0.tgz#9209a3fba30025ae3ae5e6bfe7f9c5bc3c2e8ee2"
integrity sha512-y3XuqKa2+HRYtg0wYyhW/XsLm2Ps+pqf9HaTAt7+MVUAKFJaNAHOrNseTZo9KCxjfIbxUWwckP5qCDDPUmjSWA==
dependencies:
debug "^2.2.0"
md5 "^2.1.0"
@@ -65,6 +76,7 @@ mocha-junit-reporter@^1.17.0:
mocha-multi-reporters@^1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/mocha-multi-reporters/-/mocha-multi-reporters-1.1.7.tgz#cc7f3f4d32f478520941d852abb64d9988587d82"
integrity sha1-zH8/TTL0eFIJQdhSq7ZNmYhYfYI=
dependencies:
debug "^3.1.0"
lodash "^4.16.4"
@@ -72,17 +84,26 @@ mocha-multi-reporters@^1.1.7:
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
ms@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
strip-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
dependencies:
ansi-regex "^3.0.0"
vscode-nls@^3.2.1:
version "3.2.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.2.tgz#3817eca5b985c2393de325197cf4e15eb2aa5350"
version "3.2.5"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.5.tgz#25520c1955108036dec607c85e00a522f247f1a4"
integrity sha512-ITtoh3V4AkWXMmp3TB97vsMaHRgHhsSFPsUdzlueSL+dRZbSNTZeOmdQv60kjCV306ghPxhDeoNUEm3+EZMuyw==
xml@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=

View File

@@ -0,0 +1,21 @@
# Azure (Core) extension for Azure Data Studio
Welcome to the Azure (Core) extension for Azure Data Studio! This extension supports core Azure functionality such as browsing and connecting to Azure data endpoints. In the current release the following features are supported:
* Log in to Azure and browse your accounts, subscriptions and data resources
* See Azure SQL Databases and Servers in the tree, and open these connections in Object Explorer
* Filter the list of subscriptions for a given account, to make finding specific databases easier
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Privacy Statement
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/en-us/privacystatement) describes the privacy statement of this software.
## License
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the [Source EULA](https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt).

View File

@@ -0,0 +1,180 @@
{
"name": "azurecore",
"displayName": "%azure.displayName%",
"description": "%azure.description",
"version": "0.1.0",
"publisher": "Microsoft",
"preview": true,
"engines": {
"vscode": "^1.25.0",
"sqlops": "*"
},
"activationEvents": [
"*"
],
"main": "./out/extension",
"contributes": {
"configuration": [
{
"type": "object",
"title": "%azure.resource.config.title%",
"properties": {
"azure.resource.config.filter": {
"type": "array",
"default": null,
"description": "%azure.resource.config.filter.description%"
}
}
},
{
"type": "object",
"title": "Azure Account Configuration",
"properties": {
"accounts.azure.enablePublicCloud": {
"type": "boolean",
"default": true,
"description": "%config.enablePublicCloudDescription%"
}
}
}
],
"account-type": [
{
"id": "microsoft",
"icon": {
"light": "./out/account-provider/media/microsoft_account_light.svg",
"dark": "./out/account-provider/media/microsoft_account_dark.svg"
}
},
{
"id": "work_school",
"icon": {
"light": "./out/account-provider/media/work_school_account_light.svg",
"dark": "./out/account-provider/media/work_school_account_dark.svg"
}
}
],
"commands": [
{
"command": "accounts.clearTokenCache",
"title": "%accounts.clearTokenCache%",
"category": "Azure Accounts"
},
{
"command": "azure.resource.refreshall",
"title": "%azure.resource.refreshall.title%",
"icon": {
"dark": "resources/dark/refresh_inverse.svg",
"light": "resources/light/refresh.svg"
}
},
{
"command": "azure.resource.refresh",
"title": "%azure.resource.refresh.title%",
"icon": {
"dark": "resources/dark/refresh_inverse.svg",
"light": "resources/light/refresh.svg"
}
},
{
"command": "azure.resource.signin",
"title": "%azure.resource.signin.title%"
},
{
"command": "azure.resource.selectsubscriptions",
"title": "%azure.resource.selectsubscriptions.title%",
"icon": {
"dark": "resources/dark/filter_inverse.svg",
"light": "resources/light/filter.svg"
}
},
{
"command": "azure.resource.connectsqlserver",
"title": "%azure.resource.connectsqlserver.title%",
"icon": {
"dark": "resources/dark/connect_to_inverse.svg",
"light": "resources/light/connect_to.svg"
}
},
{
"command": "azure.resource.connectsqldb",
"title": "%azure.resource.connectsqldb.title%",
"icon": {
"dark": "resources/dark/connect_to_inverse.svg",
"light": "resources/light/connect_to.svg"
}
}
],
"viewsContainers": {
"activitybar": [
{
"id": "azureResource",
"title": "%azure.title%",
"icon": "resources/azure.svg"
}
]
},
"views": {
"azureResource": [
{
"id": "azureResourceExplorer",
"name": "%azure.resource.explorer.title%"
}
]
},
"dataExplorer": {
"azureResource": [
{
"id": "azureResourceExplorer",
"name": "%azure.resource.explorer.title%"
}
]
},
"menus": {
"view/title": [
{
"command": "azure.resource.refreshall",
"when": "view == azureResourceExplorer",
"group": "navigation@1"
}
],
"view/item/context": [
{
"command": "azure.resource.selectsubscriptions",
"when": "viewItem == azure.resource.itemType.account",
"group": "inline"
},
{
"command": "azure.resource.refresh",
"when": "viewItem =~ /^azure\\.resource\\.itemType\\.(?:account|subscription|databaseContainer|databaseServerContainer)$/",
"group": "inline"
},
{
"command": "azure.resource.connectsqlserver",
"when": "viewItem == azure.resource.itemType.databaseServer",
"group": "inline"
},
{
"command": "azure.resource.connectsqldb",
"when": "viewItem == azure.resource.itemType.database",
"group": "inline"
}
]
},
"hasAzureResourceProviders": true
},
"dependencies": {
"azure-arm-resource": "^7.0.0",
"azure-arm-sql": "^5.0.1",
"request": "2.88.0",
"vscode-nls": "^4.0.0"
},
"devDependencies": {
"@types/mocha": "^5.2.5",
"@types/node": "^8.0.24",
"mocha": "^5.2.0",
"should": "^13.2.1",
"typemoq": "^2.1.0",
"vscode": "^1.1.26"
}
}

View File

@@ -0,0 +1,22 @@
{
"azure.displayName": "Azure (Core)",
"azure.description": "Browse and work with Azure resources",
"azure.title": "Azure",
"azure.resource.config.title": "Azure Resource Configuration",
"azure.resource.config.filter.description": "The resource filter, each element is an account id, a subscription id and name separated by a slash",
"azure.resource.explorer.title": "Resource Explorer",
"azure.resource.refreshall.title": "Refresh All",
"azure.resource.refresh.title": "Refresh",
"azure.resource.signin.title": "Sign In",
"azure.resource.selectsubscriptions.title": "Select Subscriptions",
"azure.resource.connectsqlserver.title": "Connect",
"azure.resource.connectsqldb.title": "Connect",
"accounts.clearTokenCache": "Clear Azure Account Token Cache",
"config.enablePublicCloudDescription": "Should Azure public cloud integration be enabled",
"config.enableUsGovCloudDescription": "Should US Government Azure cloud (Fairfax) integration be enabled",
"config.enableChinaCloudDescription": "Should Azure China integration be enabled",
"config.enableGermanyCloudDescription": "Should Azure Germany integration be enabled"
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="28" width="28" version="1.1" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
<g>
<path fill="#0072C6" d="M11.423,44.326l23.623-4.156L22.894,25.748l6.328-17.346L50,44.33L11.423,44.326z M27.566,5.67L11.469,40.109v-0.034H0l12.717-21.975L27.566,5.67z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 331 B

View 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>account_inverse</title><path class="cls-1" d="M8,.11a7.71,7.71,0,1,0,7.72,7.72A7.73,7.73,0,0,0,8,.11ZM4.2,13.36a4,4,0,0,1,.13-.93,3.69,3.69,0,0,1,1-1.66A3.56,3.56,0,0,1,6,10.19a4,4,0,0,1,.9-.38,4.17,4.17,0,0,1,1-.13A3.79,3.79,0,0,1,9.43,10a3.61,3.61,0,0,1,2,2,3.74,3.74,0,0,1,.29,1.47A6.62,6.62,0,0,1,8,14.54,6.71,6.71,0,0,1,4.2,13.36Zm2-5a2.76,2.76,0,0,1-.54-.79,2.43,2.43,0,0,1-.19-1,2.4,2.4,0,0,1,.19-1,2.82,2.82,0,0,1,.54-.8A2.81,2.81,0,0,1,7,4.25a2.4,2.4,0,0,1,1-.19,2.43,2.43,0,0,1,1,.19,2.76,2.76,0,0,1,.79.54,2.46,2.46,0,0,1,.54.8,2.4,2.4,0,0,1,.2,1,2.44,2.44,0,0,1-.2,1A2.59,2.59,0,0,1,8.92,8.86a2.44,2.44,0,0,1-1,.2,2.4,2.4,0,0,1-1-.2A2.46,2.46,0,0,1,6.18,8.32ZM12.3,13a4.39,4.39,0,0,0-.18-.89,4.22,4.22,0,0,0-.57-1.19A4.24,4.24,0,0,0,9.44,9.31a3.41,3.41,0,0,0,.68-.5A3.36,3.36,0,0,0,11,7.39a3.32,3.32,0,0,0,.11-.83,3.09,3.09,0,0,0-.24-1.22,3.26,3.26,0,0,0-.67-1,3,3,0,0,0-1-.67,3,3,0,0,0-1.22-.25,2.93,2.93,0,0,0-1.22.25A3.07,3.07,0,0,0,5.07,5.34a2.93,2.93,0,0,0-.25,1.22,3,3,0,0,0,.12.84,3,3,0,0,0,.32.76,3.3,3.3,0,0,0,.52.65,3.06,3.06,0,0,0,.68.5A4.41,4.41,0,0,0,5.27,10a4.1,4.1,0,0,0-.91,1,4.18,4.18,0,0,0-.58,1.18,4.41,4.41,0,0,0-.18.8A6.66,6.66,0,0,1,1.28,7.83,6.72,6.72,0,1,1,12.3,13Z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16"><defs><style>.cls-1,.cls-2{clip-rule:evenodd;}.cls-2,.cls-5,.cls-7{fill:#fff;}.cls-3,.cls-5{fill-rule:evenodd;}.cls-4{clip-path:url(#clip-path);}.cls-6{clip-path:url(#clip-path-2);}</style><clipPath id="clip-path"><path class="cls-1" d="M11.5-15.92v3.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5-9v6h-1V-9a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05,3.4,3.4,0,0,1-.23-1.24v-3.5h1v-3h1v3h3v-3h1v3Zm-1,1h-5v2.5a2.45,2.45,0,0,0,.2,1,2.53,2.53,0,0,0,.53.8,2.53,2.53,0,0,0,.8.53,2.45,2.45,0,0,0,1,.2,2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/></clipPath><clipPath id="clip-path-2"><path class="cls-2" d="M11.5,3V6.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5,10v6h-1V10a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05A3.4,3.4,0,0,1,4.5,6.5V3h1V0h1V3h3V0h1V3Zm-1,1h-5V6.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,8.8,2.45,2.45,0,0,0,8,9a2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/></clipPath></defs><title>connect_to_inverse</title><path class="cls-3" d="M11.5-15.92v3.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5-9v6h-1V-9a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05,3.4,3.4,0,0,1-.23-1.24v-3.5h1v-3h1v3h3v-3h1v3Zm-1,1h-5v2.5a2.45,2.45,0,0,0,.2,1,2.53,2.53,0,0,0,.53.8,2.53,2.53,0,0,0,.8.53,2.45,2.45,0,0,0,1,.2,2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/><g class="cls-4"><rect x="-0.5" y="-23.92" width="17" height="26"/></g><path class="cls-5" d="M11.5,3V6.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5,10v6h-1V10a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05A3.4,3.4,0,0,1,4.5,6.5V3h1V0h1V3h3V0h1V3Zm-1,1h-5V6.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,8.8,2.45,2.45,0,0,0,8,9a2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/><g class="cls-6"><rect class="cls-7" x="-0.5" y="-5" width="17" height="26"/></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View 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{font-size:12px;font-family:FullMDL2Assets, Full MDL2 Assets;}.cls-1,.cls-2{fill:#fff;}</style></defs><title>filter_inverse_16x16</title><text class="cls-1" transform="translate(0.03 12.1)"> </text><path class="cls-2" d="M.05,1.63H16V3.33l-6,6v6.27H6V9.31l-6-6ZM15,2.91V2.62H1v.29l6,6v5.69H9V8.89Z"/></svg>

After

Width:  |  Height:  |  Size: 418 B

View 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:#231f20;}.cls-2{fill:#fff;}</style></defs><title>folder_inverse_16x16</title><polygon class="cls-1" points="13.59 2.34 13.58 2.35 13.58 2.33 13.59 2.34"/><text></text><path class="cls-2" d="M16,14.13H0v-12a1,1,0,0,1,.08-.39,1,1,0,0,1,.53-.53A1,1,0,0,1,1,1.13H4.75a2.16,2.16,0,0,1,.61.07,2.26,2.26,0,0,1,.45.18,2.14,2.14,0,0,1,.36.24l.32.24a1.8,1.8,0,0,0,.34.18,1.12,1.12,0,0,0,.43.07H15a1,1,0,0,1,.39.08,1,1,0,0,1,.53.53,1,1,0,0,1,.08.39ZM1,2.13v1H4.75a1.36,1.36,0,0,0,.33,0A1,1,0,0,0,5.34,3l.23-.16.25-.21-.25-.21-.23-.16a1,1,0,0,0-.26-.1,1.36,1.36,0,0,0-.33,0Zm14,11v-10H7.25a1.12,1.12,0,0,0-.43.07,1.8,1.8,0,0,0-.34.18l-.32.24a2.14,2.14,0,0,1-.36.24,2.26,2.26,0,0,1-.45.18,2.16,2.16,0,0,1-.61.07H1v9Z"/></svg>

After

Width:  |  Height:  |  Size: 830 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z" fill="#2D2D30"/><path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z" fill="#C5C5C5"/></svg>

After

Width:  |  Height:  |  Size: 986 B

View 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>sql_database_inverse</title><g id="iconBg"><rect class="cls-1" x="8" y="8" width="1.12" height="3.35"/><path class="cls-1" d="M7.75.13C4.25.13,1.3,1.34,1.3,2.59V13.3c0,1.36,3.67,2.57,7.13,2.57s6.27-1.15,6.27-2.46V2.7C14.7,1.39,11.26.13,7.75.13ZM5.77,8H3.53V9.12H5.77v3.35H2.42V11.35H4.65V10.23H2.42V6.89H5.77Zm-.5-4.51L5,3.42a5.74,5.74,0,0,1-.7-.23,1.92,1.92,0,0,1-.56-.33.51.51,0,0,1-.2-.37c0-.69,2-1.25,4.46-1.25s4.47.56,4.47,1.25a.51.51,0,0,1-.2.37,1.92,1.92,0,0,1-.56.33,6.38,6.38,0,0,1-.7.23l-.31.07-.6.11A13.55,13.55,0,0,1,8,3.75a13.55,13.55,0,0,1-2.1-.15ZM11,14,9.44,12.47H6.88V6.89h3.35v4.79l1.51,1.51Zm2.63-1.51H11.35V6.89h1.11v4.46h1.12Z"/></g></svg>

After

Width:  |  Height:  |  Size: 806 B

View 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>sql_server_inverse</title><path id="iconBg" class="cls-1" d="M6.43.14C3,.14.15,1.31.15,2.53V13c0,1.32,3.58,2.49,6.94,2.49a12.79,12.79,0,0,0,1.41-.07,4.86,4.86,0,0,1-1.77-3.24H5.59V6.71H8.85v.82A4.88,4.88,0,0,1,9.93,7v-.3H11v0a4.94,4.94,0,0,1,.54,0,4.86,4.86,0,0,1,1.63.3V2.63C13.19,1.36,9.84.14,6.43.14ZM4.5,7.79H2.33V8.88H4.5v3.26H1.24V11H3.41V10H1.24V6.71H4.5ZM6.64,3.65c-2.4,0-4.34-.55-4.34-1.22S4.24,1.21,6.64,1.21,11,1.75,11,2.43,9,3.65,6.64,3.65Zm0,4.14V11h.06a4.87,4.87,0,0,1,1-2.49V7.79Zm4.89,2.72a1.09,1.09,0,1,0,1.09,1.09A1.08,1.08,0,0,0,11.56,10.51Zm0,0a1.09,1.09,0,1,0,1.09,1.09A1.08,1.08,0,0,0,11.56,10.51Zm0,0a1.09,1.09,0,1,0,1.09,1.09A1.08,1.08,0,0,0,11.56,10.51Zm0,0a1.09,1.09,0,1,0,1.09,1.09A1.08,1.08,0,0,0,11.56,10.51Zm4.29,1.63a3.18,3.18,0,0,0,.06-.54,3.3,3.3,0,0,0-.06-.55l-1.34-.17a2.85,2.85,0,0,0-.36-.86L15,8.95a4.79,4.79,0,0,0-.78-.78L13.14,9a2.85,2.85,0,0,0-.86-.36l-.17-1.34a3.31,3.31,0,0,0-.55-.06,3.31,3.31,0,0,0-.54.06l-.17,1.34A2.85,2.85,0,0,0,10,9L8.91,8.17a4.74,4.74,0,0,0-.77.78L9,10a3.13,3.13,0,0,0-.36.86L7.27,11a4.89,4.89,0,0,0,0,.55,5.12,5.12,0,0,0,0,.55l1.35.16a2.77,2.77,0,0,0,.36.87l-.84,1.07a4,4,0,0,0,.77.77L10,14.19a3.13,3.13,0,0,0,.86.36L11,15.89a5,5,0,0,0,.54.06,4.86,4.86,0,0,0,.55-.06l.17-1.34a3.13,3.13,0,0,0,.86-.36l1.07.83a4.37,4.37,0,0,0,.78-.77l-.84-1.07a3,3,0,0,0,.36-.87Zm-4.29,1.63a2.17,2.17,0,1,1,2.18-2.17A2.17,2.17,0,0,1,11.56,13.77Zm0-3.26a1.09,1.09,0,1,0,1.09,1.09A1.08,1.08,0,0,0,11.56,10.51Zm0,0a1.09,1.09,0,1,0,1.09,1.09A1.08,1.08,0,0,0,11.56,10.51Zm0,0a1.09,1.09,0,1,0,1.09,1.09A1.08,1.08,0,0,0,11.56,10.51Zm0,0a1.09,1.09,0,1,0,1.09,1.09A1.08,1.08,0,0,0,11.56,10.51Zm0,0a1.09,1.09,0,1,0,1.09,1.09A1.08,1.08,0,0,0,11.56,10.51Z"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View 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>subscription_inverse</title><path class="cls-1" d="M15.63,5.94A8.32,8.32,0,0,0,14.83,4a8.36,8.36,0,0,0-1.24-1.6A7.69,7.69,0,0,0,12,1.21,7.57,7.57,0,0,0,10.1.41a7.75,7.75,0,0,0-4.2,0A7.9,7.9,0,0,0,4,1.21,7.63,7.63,0,0,0,2.4,2.45,8,8,0,0,0,1.17,4a7.9,7.9,0,0,0-.8,1.89A7.76,7.76,0,0,0,.08,8a7.66,7.66,0,0,0,.28,2.1A7.9,7.9,0,0,0,1.17,12a7.71,7.71,0,0,0,1.24,1.6A8,8,0,0,0,4,14.88a7.78,7.78,0,0,0,1.9.79,7.71,7.71,0,0,0,4.19,0A7.55,7.55,0,0,0,12,14.88,8.1,8.1,0,0,0,14.83,12a8.32,8.32,0,0,0,.8-1.89A7.66,7.66,0,0,0,15.92,8,7.76,7.76,0,0,0,15.63,5.94Zm-1.09,3.9a6.87,6.87,0,0,1-.69,1.62,6.5,6.5,0,0,1-1.06,1.38,7.07,7.07,0,0,1-1.37,1.06,7.21,7.21,0,0,1-1.62.68,6.64,6.64,0,0,1-3.61,0,6.85,6.85,0,0,1-1.62-.68A7.07,7.07,0,0,1,3.2,12.84a5.73,5.73,0,0,1-.9-1.13L5.92,8.1l2.25,2.25,4.5-4.5V8.31h.75V4.56H9.67v.75h2.47l-4,4L5.92,7l-4,4a6.92,6.92,0,0,1-.46-1.2A6.63,6.63,0,0,1,1.21,8a6.74,6.74,0,0,1,.24-1.8,6.48,6.48,0,0,1,.69-1.62A6.42,6.42,0,0,1,3.2,3.24,7.07,7.07,0,0,1,4.57,2.18,6.85,6.85,0,0,1,6.2,1.5a6.91,6.91,0,0,1,3.61,0,7.21,7.21,0,0,1,1.62.68A7.07,7.07,0,0,1,12.8,3.24a6.76,6.76,0,0,1,1.06,1.38,6.87,6.87,0,0,1,.69,1.62A6.74,6.74,0,0,1,14.79,8,6.63,6.63,0,0,1,14.55,9.84Z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><title>account</title><path d="M8,.52a7.71,7.71,0,1,0,7.72,7.72A7.73,7.73,0,0,0,8,.52ZM4.2,13.77a4,4,0,0,1,.13-.93,3.69,3.69,0,0,1,1-1.66A3.56,3.56,0,0,1,6,10.6a4,4,0,0,1,.9-.38,4.17,4.17,0,0,1,1-.13,3.79,3.79,0,0,1,1.48.29,3.61,3.61,0,0,1,2,2,3.74,3.74,0,0,1,.29,1.47A6.62,6.62,0,0,1,8,15,6.71,6.71,0,0,1,4.2,13.77Zm2-5a2.76,2.76,0,0,1-.54-.79,2.43,2.43,0,0,1-.19-1,2.4,2.4,0,0,1,.19-1,2.82,2.82,0,0,1,.54-.8A2.81,2.81,0,0,1,7,4.66a2.4,2.4,0,0,1,1-.19,2.43,2.43,0,0,1,1,.19,2.76,2.76,0,0,1,.79.54,2.46,2.46,0,0,1,.54.8,2.4,2.4,0,0,1,.2,1,2.44,2.44,0,0,1-.2,1A2.59,2.59,0,0,1,8.92,9.27a2.44,2.44,0,0,1-1,.2,2.4,2.4,0,0,1-1-.2A2.46,2.46,0,0,1,6.18,8.73Zm6.12,4.66a4.39,4.39,0,0,0-.18-.89,4.22,4.22,0,0,0-.57-1.19A4.24,4.24,0,0,0,9.44,9.72a3.41,3.41,0,0,0,.68-.5A3.36,3.36,0,0,0,11,7.8,3.32,3.32,0,0,0,11.07,7a3.09,3.09,0,0,0-.24-1.22,3.26,3.26,0,0,0-.67-1,3,3,0,0,0-1-.67,3,3,0,0,0-1.22-.25,2.93,2.93,0,0,0-1.22.25A3.07,3.07,0,0,0,5.07,5.75,2.93,2.93,0,0,0,4.82,7a3,3,0,0,0,.12.84,3,3,0,0,0,.32.76,3.3,3.3,0,0,0,.52.65,3.06,3.06,0,0,0,.68.5,4.41,4.41,0,0,0-1.19.65,4.1,4.1,0,0,0-.91,1,4.18,4.18,0,0,0-.58,1.18,4.41,4.41,0,0,0-.18.8A6.66,6.66,0,0,1,1.28,8.24a6.72,6.72,0,1,1,11,5.15Z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16"><defs><style>.cls-1,.cls-2{clip-rule:evenodd;}.cls-2,.cls-5,.cls-7{fill:#fff;}.cls-3,.cls-5{fill-rule:evenodd;}.cls-4{clip-path:url(#clip-path);}.cls-6{clip-path:url(#clip-path-2);}</style><clipPath id="clip-path"><path class="cls-1" d="M11.5,3V6.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5,10v6h-1V10a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05A3.4,3.4,0,0,1,4.5,6.5V3h1V0h1V3h3V0h1V3Zm-1,1h-5V6.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,8.8,2.45,2.45,0,0,0,8,9a2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/></clipPath><clipPath id="clip-path-2"><path class="cls-2" d="M11.5,21.92v3.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77,3.43,3.43,0,0,1-1.19.4v6h-1v-6a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05,3.4,3.4,0,0,1-.23-1.24v-3.5h1v-3h1v3h3v-3h1v3Zm-1,1h-5v2.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,27.72a2.45,2.45,0,0,0,1,.2,2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/></clipPath></defs><title>connect_to</title><path class="cls-3" d="M11.5,3V6.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5,10v6h-1V10a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05A3.4,3.4,0,0,1,4.5,6.5V3h1V0h1V3h3V0h1V3Zm-1,1h-5V6.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,8.8,2.45,2.45,0,0,0,8,9a2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/><g class="cls-4"><rect x="-0.5" y="-5" width="17" height="26"/></g><path class="cls-5" d="M11.5,21.92v3.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77,3.43,3.43,0,0,1-1.19.4v6h-1v-6a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05,3.4,3.4,0,0,1-.23-1.24v-3.5h1v-3h1v3h3v-3h1v3Zm-1,1h-5v2.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,27.72a2.45,2.45,0,0,0,1,.2,2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/><g class="cls-6"><rect class="cls-7" x="-0.5" y="13.92" width="17" height="26"/></g></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View 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{font-size:12px;font-family:FullMDL2Assets, Full MDL2 Assets;}</style></defs><title>filter_16x16</title><text class="cls-1" transform="translate(0 12)"> </text><path d="M0,1.53H16V3.24l-6,6v6.27H6V9.22l-6-6ZM15,2.82V2.53H1v.29l6,6v5.69H9V8.8Z"/></svg>

After

Width:  |  Height:  |  Size: 363 B

View 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:#231f20;}</style></defs><title>folder_16x16</title><polygon class="cls-1" points="13.59 2.21 13.58 2.22 13.58 2.2 13.59 2.21"/><text></text><path d="M16,14H0V2a1,1,0,0,1,.08-.39,1,1,0,0,1,.53-.53A1,1,0,0,1,1,1H4.75a2.16,2.16,0,0,1,.61.07,2.26,2.26,0,0,1,.45.18,2.14,2.14,0,0,1,.36.24l.32.24a1.8,1.8,0,0,0,.34.18A1.12,1.12,0,0,0,7.25,2H15a1,1,0,0,1,.39.08,1,1,0,0,1,.53.53A1,1,0,0,1,16,3ZM1,2V3H4.75a1.36,1.36,0,0,0,.33,0,1,1,0,0,0,.26-.1l.23-.16.25-.21-.25-.21-.23-.16A1,1,0,0,0,5.08,2a1.36,1.36,0,0,0-.33,0ZM15,13V3H7.25a1.12,1.12,0,0,0-.43.07,1.8,1.8,0,0,0-.34.18l-.32.24a2.14,2.14,0,0,1-.36.24,2.26,2.26,0,0,1-.45.18A2.16,2.16,0,0,1,4.75,4H1v9Z"/></svg>

After

Width:  |  Height:  |  Size: 774 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z" fill="#F6F6F6"/><path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z" fill="#424242"/></svg>

After

Width:  |  Height:  |  Size: 986 B

View 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;}.cls-2{fill:#fff;}</style></defs><title>sql_database</title><g id="iconBg"><path class="cls-1" d="M8,8H9.12v3.35H8Z"/><path class="cls-1" d="M7.75.13C4.25.13,1.3,1.34,1.3,2.59V13.3c0,1.36,3.67,2.56,7.12,2.56s6.27-1.15,6.27-2.46V2.7C14.7,1.39,11.26.13,7.75.13ZM8,1.24c2.46,0,4.46.56,4.46,1.25S10.43,3.74,8,3.74,3.5,3.18,3.5,2.49,5.5,1.24,8,1.24ZM5.77,8H3.54V9.12H5.77v3.35H2.42V11.35H4.65V10.23H2.42V6.88H5.77ZM11,14,9.44,12.46H6.88V6.88h3.35v4.79l1.51,1.51Zm2.63-1.51H11.35V6.88h1.12v4.46h1.12Z"/></g><g id="iconFg"><path class="cls-2" d="M3.54,8V9.12H5.77v3.35H2.42V11.35H4.65V10.23H2.42V6.88H5.77V8ZM11,14,9.44,12.46H6.88V6.88h3.35v4.79l1.51,1.51ZM8,11.35H9.12V8H8Zm4.46,0V6.88H11.35v5.58h2.23V11.35Zm-9-8.86c0,.69,2,1.25,4.46,1.25s4.46-.56,4.46-1.25S10.43,1.23,8,1.23,3.5,1.8,3.5,2.49Z"/></g></svg>

After

Width:  |  Height:  |  Size: 928 B

View 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;}.cls-2{fill:#fff;}</style></defs><title>sql_server</title><path id="iconBg" class="cls-1" d="M6.72,12.14H5.58V6.71H8.84v.83A4.85,4.85,0,0,1,9.93,7v-.3H11v.05a5,5,0,0,1,.54-.05,4.83,4.83,0,0,1,1.63.3V2.63c0-1.27-3.35-2.5-6.76-2.5S.15,1.31.15,2.53V13c0,1.32,3.57,2.5,6.94,2.5.49,0,1,0,1.41-.07A4.86,4.86,0,0,1,6.72,12.14ZM6.64,1.21C9,1.21,11,1.75,11,2.43S9,3.65,6.64,3.65,2.29,3.1,2.29,2.43,4.24,1.21,6.64,1.21ZM4.5,7.79H2.32V8.88H4.5v3.26H1.24V11.05H3.41V10H1.24V6.71H4.5Zm2.23,3.26H6.67V7.79H7.76v.76A4.84,4.84,0,0,0,6.72,11.05Zm7.79,1.26a3.06,3.06,0,0,1-.36.86L15,14.24a4.32,4.32,0,0,1-.77.77l-1.07-.83a3,3,0,0,1-.86.36l-.17,1.34a4.17,4.17,0,0,1-.55.06,4.14,4.14,0,0,1-.55-.06l-.17-1.34a3,3,0,0,1-.86-.36L8.91,15a4.32,4.32,0,0,1-.77-.77L9,13.18a3,3,0,0,1-.36-.86l-1.34-.17a4,4,0,0,1-.06-.55A4.14,4.14,0,0,1,7.27,11l1.34-.17A3,3,0,0,1,9,10L8.14,8.95a4.32,4.32,0,0,1,.77-.77L10,9a3,3,0,0,1,.86-.36L11,7.31a4.14,4.14,0,0,1,.55-.06,4.14,4.14,0,0,1,.55.06l.17,1.34a3,3,0,0,1,.86.36l1.07-.83a4.32,4.32,0,0,1,.77.77L14.15,10a3,3,0,0,1,.36.86l1.34.17a4.14,4.14,0,0,1,.06.55,4.14,4.14,0,0,1-.06.55ZM11.56,9.42a2.17,2.17,0,1,0,2.17,2.17,2.17,2.17,0,0,0-2.17-2.17Zm0,1.09a1.09,1.09,0,1,0,1.09,1.09A1.09,1.09,0,0,0,11.56,10.51Z"/><g id="iconFg"><path class="cls-2" d="M9.93,6.71H11v.05A4.87,4.87,0,0,0,9.93,7ZM6.64,3.65C9,3.65,11,3.1,11,2.43S9,1.2,6.64,1.2s-4.34.55-4.34,1.22S4.24,3.65,6.64,3.65ZM1.24,6.71V10H3.41v1.09H1.24v1.09H4.5V8.88H2.32V7.79H4.5V6.71ZM6.67,11.6a5,5,0,0,1,.05-.54H6.67V7.79H7.76v.76a4.92,4.92,0,0,1,1.09-1V6.71H5.58v5.43H6.72A5,5,0,0,1,6.67,11.6Z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><title>subscription</title><path d="M15.63,5.9A8.32,8.32,0,0,0,14.83,4a8.36,8.36,0,0,0-1.24-1.6A7.69,7.69,0,0,0,12,1.17,7.57,7.57,0,0,0,10.1.37a7.75,7.75,0,0,0-4.2,0A7.9,7.9,0,0,0,4,1.17,7.63,7.63,0,0,0,2.4,2.41,8,8,0,0,0,1.17,4,7.9,7.9,0,0,0,.37,5.9,7.76,7.76,0,0,0,.08,8a7.66,7.66,0,0,0,.28,2.1A7.9,7.9,0,0,0,1.17,12a7.71,7.71,0,0,0,1.24,1.6A8,8,0,0,0,4,14.84a7.78,7.78,0,0,0,1.9.79,7.71,7.71,0,0,0,4.19,0A7.55,7.55,0,0,0,12,14.84,8.1,8.1,0,0,0,14.83,12a8.32,8.32,0,0,0,.8-1.89A7.66,7.66,0,0,0,15.92,8,7.76,7.76,0,0,0,15.63,5.9ZM14.55,9.8a6.87,6.87,0,0,1-.69,1.62A6.5,6.5,0,0,1,12.8,12.8a7.07,7.07,0,0,1-1.37,1.06,7.21,7.21,0,0,1-1.62.68,6.64,6.64,0,0,1-3.61,0,6.85,6.85,0,0,1-1.62-.68A7.07,7.07,0,0,1,3.2,12.8a5.73,5.73,0,0,1-.9-1.13L5.92,8.06l2.25,2.25,4.5-4.5V8.27h.75V4.52H9.67v.75h2.47l-4,4L5.92,7l-4,4a6.92,6.92,0,0,1-.46-1.2A6.63,6.63,0,0,1,1.21,8a6.74,6.74,0,0,1,.24-1.8,6.48,6.48,0,0,1,.69-1.62A6.42,6.42,0,0,1,3.2,3.2,7.07,7.07,0,0,1,4.57,2.14,6.85,6.85,0,0,1,6.2,1.46a6.91,6.91,0,0,1,3.61,0,7.21,7.21,0,0,1,1.62.68A7.07,7.07,0,0,1,12.8,3.2a6.76,6.76,0,0,1,1.06,1.38,6.87,6.87,0,0,1,.69,1.62A6.74,6.74,0,0,1,14.79,8,6.63,6.63,0,0,1,14.55,9.8Z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -69,8 +69,8 @@ export class AzureAccountProvider implements sqlops.AccountProvider {
return this._tokenCache.clear();
}
public getSecurityToken(account: AzureAccount): Thenable<AzureAccountSecurityTokenCollection> {
return this.doIfInitialized(() => this.getAccessTokens(account));
public getSecurityToken(account: AzureAccount, resource: sqlops.AzureResource): Thenable<AzureAccountSecurityTokenCollection> {
return this.doIfInitialized(() => this.getAccessTokens(account, resource));
}
public initialize(restoredAccounts: sqlops.Account[]): Thenable<sqlops.Account[]> {
@@ -90,7 +90,7 @@ export class AzureAccountProvider implements sqlops.AccountProvider {
// Attempt to get fresh tokens. If this fails then the account is stale.
// NOTE: Based on ADAL implementation, getting tokens should use the refresh token if necessary
let task = this.getAccessTokens(account)
let task = this.getAccessTokens(account, sqlops.AzureResource.ResourceManagement)
.then(
() => {
return account;
@@ -161,9 +161,14 @@ export class AzureAccountProvider implements sqlops.AccountProvider {
: Promise.reject(localize('accountProviderNotInitialized', 'Account provider not initialized, cannot perform action'));
}
private getAccessTokens(account: AzureAccount): Thenable<AzureAccountSecurityTokenCollection> {
private getAccessTokens(account: AzureAccount, resource: sqlops.AzureResource): Thenable<AzureAccountSecurityTokenCollection> {
let self = this;
const resourceIdMap = new Map<sqlops.AzureResource, string>([
[sqlops.AzureResource.ResourceManagement, self._metadata.settings.armResource.id],
[sqlops.AzureResource.Sql, self._metadata.settings.sqlResource.id]
]);
let accessTokenPromises: Thenable<void>[] = [];
let tokenCollection: AzureAccountSecurityTokenCollection = {};
for (let tenant of account.properties.tenants) {
@@ -172,7 +177,7 @@ export class AzureAccountProvider implements sqlops.AccountProvider {
let context = new adal.AuthenticationContext(authorityUrl, null, self._tokenCache);
context.acquireToken(
self._metadata.settings.armResource.id,
resourceIdMap.get(resource),
tenant.userId,
self._metadata.settings.clientId,
(error: Error, response: adal.TokenResponse | adal.ErrorResponse) => {

View File

@@ -20,7 +20,7 @@ let localize = nls.loadMessageBundle();
export class AzureAccountProviderService implements vscode.Disposable {
// CONSTANTS ///////////////////////////////////////////////////////////////
private static CommandClearTokenCache = 'accounts.azure.clearTokenCache';
private static CommandClearTokenCache = 'accounts.clearTokenCache';
private static ConfigurationSection = 'accounts.azure';
private static CredentialNamespace = 'azureAccountProviderCredentials';

View File

@@ -81,6 +81,11 @@ export interface Settings {
*/
armResource?: Resource;
/**
* Information that describes the SQL Azure resource
*/
sqlResource?: Resource;
/**
* A list of tenant IDs to authenticate against. If defined, then these IDs will be used
* instead of querying the tenants endpoint of the armResource

View File

@@ -27,6 +27,10 @@ const publicAzureSettings: ProviderSettings = {
id: 'https://management.core.windows.net/',
endpoint: 'https://management.azure.com'
},
sqlResource: {
id: 'https://database.windows.net/',
endpoint: 'https://database.windows.net'
},
redirectUri: 'http://localhost/redirect'
}
}

View File

@@ -223,11 +223,30 @@ export default class TokenCache implements adal.TokenCache {
return this.getOrCreateEncryptionParams()
.then(encryptionParams => {
try {
let cacheCipher = fs.readFileSync(self._cacheSerializationPath, TokenCache.FsOptions);
return self.decryptCache('utf8', encryptionParams);
} catch (e) {
try {
// try to parse using 'binary' encoding and rewrite cache as UTF8
let response = self.decryptCache('binary', encryptionParams);
self.writeCache(response);
return response;
} catch (e) {
throw e;
}
}
})
.then(null, err => {
// If reading the token cache fails, we'll just assume the tokens are garbage
console.warn(`Failed to read token cache: ${err}`);
return [];
});
}
private decryptCache(encoding: crypto.Utf8AsciiBinaryEncoding, encryptionParams: EncryptionParams): adal.TokenResponse[] {
let cacheCipher = fs.readFileSync(this._cacheSerializationPath, TokenCache.FsOptions);
let decipher = crypto.createDecipheriv(TokenCache.CipherAlgorithm, encryptionParams.key, encryptionParams.initializationVector);
let cacheJson = decipher.update(cacheCipher, 'hex', 'binary');
cacheJson += decipher.final('binary');
let cacheJson = decipher.update(cacheCipher, 'hex', encoding);
cacheJson += decipher.final(encoding);
// Deserialize the JSON into the array of tokens
let cacheObj = <adal.TokenResponse[]>JSON.parse(cacheJson);
@@ -237,15 +256,6 @@ export default class TokenCache implements adal.TokenCache {
}
return cacheObj;
} catch (e) {
throw e;
}
})
.then(null, err => {
// If reading the token cache fails, we'll just assume the tokens are garbage
console.warn(`Failed to read token cache: ${err}`);
return [];
});
}
private removeFromCache(cache: adal.TokenResponse[], entries: adal.TokenResponse[]): adal.TokenResponse[] {
@@ -274,7 +284,7 @@ export default class TokenCache implements adal.TokenCache {
let cacheJson = JSON.stringify(cache);
let cipher = crypto.createCipheriv(TokenCache.CipherAlgorithm, encryptionParams.key, encryptionParams.initializationVector);
let cacheCipher = cipher.update(cacheJson, 'binary', 'hex');
let cacheCipher = cipher.update(cacheJson, 'utf8', 'hex');
cacheCipher += cipher.final('hex');
fs.writeFileSync(self._cacheSerializationPath, cacheCipher, TokenCache.FsOptions);

View File

@@ -0,0 +1,225 @@
/*---------------------------------------------------------------------------------------------
* 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 * as sqlops from 'sqlops';
import * as constants from './constants';
/**
* Wrapper class to act as a facade over VSCode and Data APIs and allow us to test / mock callbacks into
* this API from our code
*
* @export
* @class ApiWrapper
*/
export class ApiWrapper {
// Data APIs
public registerConnectionProvider(provider: sqlops.ConnectionProvider): vscode.Disposable {
return sqlops.dataprotocol.registerConnectionProvider(provider);
}
public registerObjectExplorerProvider(provider: sqlops.ObjectExplorerProvider): vscode.Disposable {
return sqlops.dataprotocol.registerObjectExplorerProvider(provider);
}
public registerTaskServicesProvider(provider: sqlops.TaskServicesProvider): vscode.Disposable {
return sqlops.dataprotocol.registerTaskServicesProvider(provider);
}
public registerFileBrowserProvider(provider: sqlops.FileBrowserProvider): vscode.Disposable {
return sqlops.dataprotocol.registerFileBrowserProvider(provider);
}
public registerCapabilitiesServiceProvider(provider: sqlops.CapabilitiesProvider): vscode.Disposable {
return sqlops.dataprotocol.registerCapabilitiesServiceProvider(provider);
}
public registerModelViewProvider(widgetId: string, handler: (modelView: sqlops.ModelView) => void): void {
return sqlops.ui.registerModelViewProvider(widgetId, handler);
}
public registerWebviewProvider(widgetId: string, handler: (webview: sqlops.DashboardWebview) => void): void {
return sqlops.dashboard.registerWebviewProvider(widgetId, handler);
}
public createDialog(title: string): sqlops.window.modelviewdialog.Dialog {
return sqlops.window.modelviewdialog.createDialog(title);
}
public openDialog(dialog: sqlops.window.modelviewdialog.Dialog): void {
return sqlops.window.modelviewdialog.openDialog(dialog);
}
public closeDialog(dialog: sqlops.window.modelviewdialog.Dialog): void {
return sqlops.window.modelviewdialog.closeDialog(dialog);
}
public registerTaskHandler(taskId: string, handler: (profile: sqlops.IConnectionProfile) => void): void {
sqlops.tasks.registerTask(taskId, handler);
}
public startBackgroundOperation(operationInfo: sqlops.BackgroundOperationInfo): void {
sqlops.tasks.startBackgroundOperation(operationInfo);
}
public getActiveConnections(): Thenable<sqlops.connection.Connection[]> {
return sqlops.connection.getActiveConnections();
}
public getCurrentConnection(): Thenable<sqlops.connection.Connection> {
return sqlops.connection.getCurrentConnection();
}
public createModelViewEditor(title: string, options?: sqlops.ModelViewEditorOptions): sqlops.workspace.ModelViewEditor {
return sqlops.workspace.createModelViewEditor(title, options);
}
// VSCode APIs
public createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): vscode.Terminal {
return vscode.window.createTerminal(name, shellPath, shellArgs);
}
public createTerminalWithOptions(options: vscode.TerminalOptions): vscode.Terminal {
return vscode.window.createTerminal(options);
}
public executeCommand(command: string, ...rest: any[]): Thenable<any> {
return vscode.commands.executeCommand(command, ...rest);
}
public getFilePathRelativeToWorkspace(uri: vscode.Uri): string {
return vscode.workspace.asRelativePath(uri);
}
public getWorkspaceFolders(): vscode.WorkspaceFolder[] {
return vscode.workspace.workspaceFolders;
}
public getWorkspacePathFromUri(uri: vscode.Uri): string | undefined {
let workspaceFolder = vscode.workspace.getWorkspaceFolder(uri);
return workspaceFolder ? workspaceFolder.uri.fsPath : undefined;
}
public registerCommand(command: string, callback: (...args: any[]) => any, thisArg?: any): vscode.Disposable {
return vscode.commands.registerCommand(command, callback, thisArg);
}
public registerDocumentOpenHandler(handler: (doc: vscode.TextDocument) => any): vscode.Disposable {
return vscode.workspace.onDidOpenTextDocument(handler);
}
public registerTreeDataProvider<T>(viewId: string, treeDataProvider: vscode.TreeDataProvider<T>): vscode.Disposable {
return vscode.window.registerTreeDataProvider(viewId, treeDataProvider);
}
public setCommandContext(key: string, value: any): Thenable<any> {
return vscode.commands.executeCommand(constants.BuiltInCommands.SetContext, key, value);
}
/**
* Get the configuration for a extensionName
* @param extensionName The string name of the extension to get the configuration for
* @param resource The optional URI, as a URI object or a string, to use to get resource-scoped configurations
*/
public getConfiguration(extensionName?: string, resource?: vscode.Uri | string): vscode.WorkspaceConfiguration {
if (typeof resource === 'string') {
try {
resource = this.parseUri(resource);
} catch (e) {
resource = undefined;
}
}
return vscode.workspace.getConfiguration(extensionName, resource as vscode.Uri);
}
public getExtensionConfiguration(): vscode.WorkspaceConfiguration {
return this.getConfiguration(constants.extensionConfigSectionName);
}
/**
* Parse uri
*/
public parseUri(uri: string): vscode.Uri {
return vscode.Uri.parse(uri);
}
public showOpenDialog(options: vscode.OpenDialogOptions): Thenable<vscode.Uri[] | undefined> {
return vscode.window.showOpenDialog(options);
}
public showSaveDialog(options: vscode.SaveDialogOptions): Thenable<vscode.Uri> {
return vscode.window.showSaveDialog(options);
}
public openTextDocument(uri: vscode.Uri): Thenable<vscode.TextDocument>;
public openTextDocument(options: { language?: string; content?: string; }): Thenable<vscode.TextDocument>;
public openTextDocument(uriOrOptions): Thenable<vscode.TextDocument> {
return vscode.workspace.openTextDocument(uriOrOptions);
}
public showTextDocument(document: vscode.TextDocument, column?: vscode.ViewColumn, preserveFocus?: boolean, preview?: boolean): Thenable<vscode.TextEditor> {
let options: vscode.TextDocumentShowOptions = {
viewColumn: column,
preserveFocus: preserveFocus,
preview: preview
};
return vscode.window.showTextDocument(document, options);
}
public showErrorMessage(message: string, ...items: string[]): Thenable<string | undefined> {
return vscode.window.showErrorMessage(message, ...items);
}
public showWarningMessage(message: string, ...items: string[]): Thenable<string | undefined> {
return vscode.window.showWarningMessage(message, ...items);
}
public showInformationMessage(message: string, ...items: string[]): Thenable<string | undefined> {
return vscode.window.showInformationMessage(message, ...items);
}
public createStatusBarItem(alignment?: vscode.StatusBarAlignment, priority?: number): vscode.StatusBarItem {
return vscode.window.createStatusBarItem(alignment, priority);
}
public get workspaceFolders(): vscode.WorkspaceFolder[] {
return vscode.workspace.workspaceFolders;
}
public createOutputChannel(name: string): vscode.OutputChannel {
return vscode.window.createOutputChannel(name);
}
public createWizardPage(title: string): sqlops.window.modelviewdialog.WizardPage {
return sqlops.window.modelviewdialog.createWizardPage(title);
}
public registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, ...triggerCharacters: string[]): vscode.Disposable {
return vscode.languages.registerCompletionItemProvider(selector, provider, ...triggerCharacters);
}
public createTab(title: string): sqlops.window.modelviewdialog.DialogTab {
return sqlops.window.modelviewdialog.createTab(title);
}
// Account APIs
public getAllAccounts(): Thenable<sqlops.Account[]> {
return sqlops.accounts.getAllAccounts();
}
public getSecurityToken(account: sqlops.Account, resource: sqlops.AzureResource): Thenable<{}> {
return sqlops.accounts.getSecurityToken(account, resource);
}
public readonly onDidChangeAccounts = sqlops.accounts.onDidChangeAccounts;
// Connection APIs
public openConnectionDialog(providers: string[], initialConnectionProfile?: sqlops.IConnectionProfile, connectionCompletionOptions?: sqlops.IConnectionCompletionOptions): Thenable<sqlops.connection.Connection> {
return sqlops.connection.openConnectionDialog(providers, initialConnectionProfile, connectionCompletionOptions);
}
}

View File

@@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* 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 { ApiWrapper } from './apiWrapper';
/**
* Global context for the application
*/
export class AppContext {
private serviceMap: Map<string, any> = new Map();
constructor(public readonly extensionContext: vscode.ExtensionContext, public readonly apiWrapper: ApiWrapper) {
this.apiWrapper = apiWrapper || new ApiWrapper();
}
public getService<T>(serviceName: string): T {
return this.serviceMap.get(serviceName) as T;
}
public registerService<T>(serviceName: string, service: T): void {
this.serviceMap.set(serviceName, service);
}
}

View File

@@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { TreeDataProvider, TreeItem } from 'vscode';
import { DataProvider, Account } from 'sqlops';
export namespace azureResource {
export interface IAzureResourceProvider extends DataProvider {
getTreeDataProvider(): IAzureResourceTreeDataProvider;
}
export interface IAzureResourceTreeDataProvider extends TreeDataProvider<IAzureResourceNode> {
}
export interface IAzureResourceNode {
readonly account: Account;
readonly subscription: AzureResourceSubscription;
readonly tenantId: string;
readonly treeItem: TreeItem;
}
export interface AzureResourceSubscription {
id: string;
name: string;
}
}

View File

@@ -0,0 +1,89 @@
/*---------------------------------------------------------------------------------------------
* 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 { window, QuickPickItem } from 'vscode';
import { AzureResource } from 'sqlops';
import { TokenCredentials } from 'ms-rest';
import { AppContext } from '../appContext';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { azureResource } from './azure-resource';
import { TreeNode } from './treeNode';
import { AzureResourceCredentialError } from './errors';
import { AzureResourceTreeProvider } from './tree/treeProvider';
import { AzureResourceAccountTreeNode } from './tree/accountTreeNode';
import { IAzureResourceSubscriptionService, IAzureResourceSubscriptionFilterService } from '../azureResource/interfaces';
import { AzureResourceServiceNames } from './constants';
export function registerAzureResourceCommands(appContext: AppContext, tree: AzureResourceTreeProvider): void {
appContext.apiWrapper.registerCommand('azure.resource.selectsubscriptions', async (node?: TreeNode) => {
if (!(node instanceof AzureResourceAccountTreeNode)) {
return;
}
const subscriptionService = appContext.getService<IAzureResourceSubscriptionService>(AzureResourceServiceNames.subscriptionService);
const subscriptionFilterService = appContext.getService<IAzureResourceSubscriptionFilterService>(AzureResourceServiceNames.subscriptionFilterService);
const accountNode = node as AzureResourceAccountTreeNode;
const subscriptions = (await accountNode.getCachedSubscriptions()) || <azureResource.AzureResourceSubscription[]>[];
if (subscriptions.length === 0) {
try {
const tokens = await this.servicePool.apiWrapper.getSecurityToken(this.account, AzureResource.ResourceManagement);
for (const tenant of this.account.properties.tenants) {
const token = tokens[tenant.id].token;
const tokenType = tokens[tenant.id].tokenType;
subscriptions.push(...await subscriptionService.getSubscriptions(accountNode.account, new TokenCredentials(token, tokenType)));
}
} catch (error) {
throw new AzureResourceCredentialError(localize('azure.resource.selectsubscriptions.credentialError', 'Failed to get credential for account {0}. Please refresh the account.', this.account.key.accountId), error);
}
}
let selectedSubscriptions = (await subscriptionFilterService.getSelectedSubscriptions(accountNode.account)) || <azureResource.AzureResourceSubscription[]>[];
const selectedSubscriptionIds: string[] = [];
if (selectedSubscriptions.length > 0) {
selectedSubscriptionIds.push(...selectedSubscriptions.map((subscription) => subscription.id));
} else {
// ALL subscriptions are selected by default
selectedSubscriptionIds.push(...subscriptions.map((subscription) => subscription.id));
}
interface AzureResourceSubscriptionQuickPickItem extends QuickPickItem {
subscription: azureResource.AzureResourceSubscription;
}
const subscriptionQuickPickItems: AzureResourceSubscriptionQuickPickItem[] = subscriptions.map((subscription) => {
return {
label: subscription.name,
picked: selectedSubscriptionIds.indexOf(subscription.id) !== -1,
subscription: subscription
};
});
const selectedSubscriptionQuickPickItems = (await window.showQuickPick(subscriptionQuickPickItems, { canPickMany: true }));
if (selectedSubscriptionQuickPickItems && selectedSubscriptionQuickPickItems.length > 0) {
tree.refresh(node, false);
selectedSubscriptions = selectedSubscriptionQuickPickItems.map((subscriptionItem) => subscriptionItem.subscription);
await subscriptionFilterService.saveSelectedSubscriptions(accountNode.account, selectedSubscriptions);
}
});
appContext.apiWrapper.registerCommand('azure.resource.refreshall', () => tree.notifyNodeChanged(undefined));
appContext.apiWrapper.registerCommand('azure.resource.refresh', async (node?: TreeNode) => {
tree.refresh(node, true);
});
appContext.apiWrapper.registerCommand('azure.resource.signin', async (node?: TreeNode) => {
appContext.apiWrapper.executeCommand('sql.action.accounts.manageLinkedAccount');
});
}

View 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.
*--------------------------------------------------------------------------------------------*/
'use strict';
export enum AzureResourceItemType {
account = 'azure.resource.itemType.account',
subscription = 'azure.resource.itemType.subscription',
databaseContainer = 'azure.resource.itemType.databaseContainer',
database = 'azure.resource.itemType.database',
databaseServerContainer = 'azure.resource.itemType.databaseServerContainer',
databaseServer = 'azure.resource.itemType.databaseServer',
message = 'azure.resource.itemType.message'
}
export enum AzureResourceServiceNames {
cacheService = 'AzureResourceCacheService',
accountService = 'AzureResourceAccountService',
subscriptionService = 'AzureResourceSubscriptionService',
subscriptionFilterService = 'AzureResourceSubscriptionFilterService',
tenantService = 'AzureResourceTenantService'
}

View File

@@ -0,0 +1,15 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export class AzureResourceCredentialError extends Error {
constructor(
message: string,
public readonly innerError: Error
) {
super(message);
}
}

View File

@@ -0,0 +1,45 @@
/*---------------------------------------------------------------------------------------------
* 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 { ServiceClientCredentials } from 'ms-rest';
import { Account, DidChangeAccountsParams } from 'sqlops';
import { Event } from 'vscode';
import { azureResource } from './azure-resource';
export interface IAzureResourceAccountService {
getAccounts(): Promise<Account[]>;
readonly onDidChangeAccounts: Event<DidChangeAccountsParams>;
}
export interface IAzureResourceSubscriptionService {
getSubscriptions(account: Account, credential: ServiceClientCredentials): Promise<azureResource.AzureResourceSubscription[]>;
}
export interface IAzureResourceSubscriptionFilterService {
getSelectedSubscriptions(account: Account): Promise<azureResource.AzureResourceSubscription[]>;
saveSelectedSubscriptions(account: Account, selectedSubscriptions: azureResource.AzureResourceSubscription[]): Promise<void>;
}
export interface IAzureResourceCacheService {
generateKey(id: string): string;
get<T>(key: string): T | undefined;
update<T>(key: string, value: T): void;
}
export interface IAzureResourceTenantService {
getTenantId(subscription: azureResource.AzureResourceSubscription): Promise<string>;
}
export interface IAzureResourceNodeWithProviderId {
resourceProviderId: string;
resourceNode: azureResource.IAzureResourceNode;
}

View File

@@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------------------------
* 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 { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { NodeInfo } from 'sqlops';
import { TreeNode } from './treeNode';
import { AzureResourceItemType } from './constants';
export class AzureResourceMessageTreeNode extends TreeNode {
public constructor(
public readonly message: string,
parent: TreeNode
) {
super();
this.parent = parent;
this._id = `message_${AzureResourceMessageTreeNode._messageNum++}`;
}
public static create(message: string, parent: TreeNode): AzureResourceMessageTreeNode {
return new AzureResourceMessageTreeNode(message, parent);
}
public getChildren(): TreeNode[] | Promise<TreeNode[]> {
return [];
}
public getTreeItem(): TreeItem | Promise<TreeItem> {
let item = new TreeItem(this.message, TreeItemCollapsibleState.None);
item.contextValue = AzureResourceItemType.message;
return item;
}
public getNodeInfo(): NodeInfo {
return {
label: this.message,
isLeaf: true,
errorMessage: undefined,
metadata: undefined,
nodePath: this.generateNodePath(),
nodeStatus: undefined,
nodeType: AzureResourceItemType.message,
nodeSubType: undefined,
iconType: AzureResourceItemType.message
};
}
public get nodePathValue(): string {
return this._id;
}
private _id: string;
private static _messageNum: number = 0;
}

View File

@@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------------------------
* 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 { IConnectionProfile } from 'sqlops';
import { AppContext } from '../../../appContext';
import { TreeNode } from '../../treeNode';
import { generateGuid } from '../../utils';
import { AzureResourceItemType } from '../../constants';
import { IAzureResourceDatabaseNode } from './interfaces';
import { AzureResourceResourceTreeNode } from '../../resourceTreeNode';
export function registerAzureResourceDatabaseCommands(appContext: AppContext): void {
appContext.apiWrapper.registerCommand('azure.resource.connectsqldb', async (node?: TreeNode) => {
if (!node)
{
return;
}
const treeItem = await node.getTreeItem();
if (treeItem.contextValue !== AzureResourceItemType.database) {
return;
}
const resourceNode = (node as AzureResourceResourceTreeNode).resourceNodeWithProviderId.resourceNode;
const database = (resourceNode as IAzureResourceDatabaseNode).database;
let connectionProfile: IConnectionProfile = {
id: generateGuid(),
connectionName: undefined,
serverName: database.serverFullName,
databaseName: database.name,
userName: database.loginName,
password: '',
authenticationType: 'SqlLogin',
savePassword: true,
groupFullName: '',
groupId: '',
providerName: 'MSSQL',
saveProfile: true,
options: {}
};
const conn = await appContext.apiWrapper.openConnectionDialog(undefined, connectionProfile, { saveConnection: true, showDashboard: true });
if (conn) {
appContext.apiWrapper.executeCommand('workbench.view.connections');
}
});
}

View 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 { ExtensionContext } from 'vscode';
import { ApiWrapper } from '../../../apiWrapper';
import { azureResource } from '../../azure-resource';
import { IAzureResourceDatabaseService } from './interfaces';
import { AzureResourceDatabaseTreeDataProvider } from './databaseTreeDataProvider';
export class AzureResourceDatabaseProvider implements azureResource.IAzureResourceProvider {
public constructor(
databaseService: IAzureResourceDatabaseService,
apiWrapper: ApiWrapper,
extensionContext: ExtensionContext
) {
this._databaseService = databaseService;
this._apiWrapper = apiWrapper;
this._extensionContext = extensionContext;
}
public getTreeDataProvider(): azureResource.IAzureResourceTreeDataProvider {
return new AzureResourceDatabaseTreeDataProvider(this._databaseService, this._apiWrapper, this._extensionContext);
}
public get providerId(): string {
return 'azure.resource.providers.database';
}
private _databaseService: IAzureResourceDatabaseService = undefined;
private _apiWrapper: ApiWrapper = undefined;
private _extensionContext: ExtensionContext = undefined;
}

View File

@@ -0,0 +1,41 @@
/*---------------------------------------------------------------------------------------------
* 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 { ServiceClientCredentials } from 'ms-rest';
import { SqlManagementClient } from 'azure-arm-sql';
import { azureResource } from '../../azure-resource';
import { IAzureResourceDatabaseService } from './interfaces';
import { AzureResourceDatabase } from './models';
export class AzureResourceDatabaseService implements IAzureResourceDatabaseService {
public async getDatabases(subscription: azureResource.AzureResourceSubscription, credential: ServiceClientCredentials): Promise<AzureResourceDatabase[]> {
const databases: AzureResourceDatabase[] = [];
const sqlManagementClient = new SqlManagementClient(credential, subscription.id);
const svrs = await sqlManagementClient.servers.list();
for (const svr of svrs) {
// Extract resource group name from svr.id
const svrIdRegExp = new RegExp(`\/subscriptions\/${subscription.id}\/resourceGroups\/(.+)\/providers\/Microsoft\.Sql\/servers\/${svr.name}`);
if (!svrIdRegExp.test(svr.id)) {
continue;
}
const founds = svrIdRegExp.exec(svr.id);
const resouceGroup = founds[1];
const dbs = await sqlManagementClient.databases.listByServer(resouceGroup, svr.name);
dbs.forEach((db) => databases.push({
name: db.name,
serverName: svr.name,
serverFullName: svr.fullyQualifiedDomainName,
loginName: svr.administratorLogin
}));
}
return databases;
}
}

View File

@@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------------------------
* 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 { AzureResource } from 'sqlops';
import { TreeItem, TreeItemCollapsibleState, ExtensionContext } from 'vscode';
import { TokenCredentials } from 'ms-rest';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { azureResource } from '../../azure-resource';
import { IAzureResourceDatabaseService, IAzureResourceDatabaseNode } from './interfaces';
import { AzureResourceDatabase } from './models';
import { AzureResourceItemType } from '../../../azureResource/constants';
import { ApiWrapper } from '../../../apiWrapper';
export class AzureResourceDatabaseTreeDataProvider implements azureResource.IAzureResourceTreeDataProvider {
public constructor(
databaseService: IAzureResourceDatabaseService,
apiWrapper: ApiWrapper,
extensionContext: ExtensionContext
) {
this._databaseService = databaseService;
this._apiWrapper = apiWrapper;
this._extensionContext = extensionContext;
}
public getTreeItem(element: azureResource.IAzureResourceNode): TreeItem | Thenable<TreeItem> {
return element.treeItem;
}
public async getChildren(element?: azureResource.IAzureResourceNode): Promise<azureResource.IAzureResourceNode[]> {
if (!element) {
return [this.createContainerNode()];
}
const tokens = await this._apiWrapper.getSecurityToken(element.account, AzureResource.ResourceManagement);
const credential = new TokenCredentials(tokens[element.tenantId].token, tokens[element.tenantId].tokenType);
const databases: AzureResourceDatabase[] = (await this._databaseService.getDatabases(element.subscription, credential)) || <AzureResourceDatabase[]>[];
return databases.map((database) => <IAzureResourceDatabaseNode>{
account: element.account,
subscription: element.subscription,
tenantId: element.tenantId,
database: database,
treeItem: {
id: `databaseServer_${database.serverFullName}.database_${database.name}`,
label: `${database.name} (${database.serverName})`,
iconPath: {
dark: this._extensionContext.asAbsolutePath('resources/dark/sql_database_inverse.svg'),
light: this._extensionContext.asAbsolutePath('resources/light/sql_database.svg')
},
collapsibleState: TreeItemCollapsibleState.None,
contextValue: AzureResourceItemType.database
}
});
}
private createContainerNode(): azureResource.IAzureResourceNode {
return {
account: undefined,
subscription: undefined,
tenantId: undefined,
treeItem: {
id: AzureResourceDatabaseTreeDataProvider.containerId,
label: AzureResourceDatabaseTreeDataProvider.containerLabel,
iconPath: {
dark: this._extensionContext.asAbsolutePath('resources/dark/folder_inverse.svg'),
light: this._extensionContext.asAbsolutePath('resources/light/folder.svg')
},
collapsibleState: TreeItemCollapsibleState.Collapsed,
contextValue: AzureResourceItemType.databaseContainer
}
};
}
private _databaseService: IAzureResourceDatabaseService = undefined;
private _apiWrapper: ApiWrapper = undefined;
private _extensionContext: ExtensionContext = undefined;
private static readonly containerId = 'azure.resource.providers.database.treeDataProvider.databaseContainer';
private static readonly containerLabel = localize('azure.resource.providers.database.treeDataProvider.databaseContainerLabel', 'SQL Databases');
}

View File

@@ -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.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ServiceClientCredentials } from 'ms-rest';
import { azureResource } from '../../azure-resource';
import { AzureResourceDatabase } from './models';
export interface IAzureResourceDatabaseService {
getDatabases(subscription: azureResource.AzureResourceSubscription, credential: ServiceClientCredentials): Promise<AzureResourceDatabase[]>;
}
export interface IAzureResourceDatabaseNode extends azureResource.IAzureResourceNode {
readonly database: AzureResourceDatabase;
}

View File

@@ -0,0 +1,13 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export interface AzureResourceDatabase {
name: string;
serverName: string;
serverFullName: string;
loginName: string;
}

View File

@@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------------------------
* 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 { IConnectionProfile } from 'sqlops';
import { AppContext } from '../../../appContext';
import { TreeNode } from '../../treeNode';
import { generateGuid } from '../../utils';
import { AzureResourceItemType } from '../../constants';
import { IAzureResourceDatabaseServerNode } from './interfaces';
import { AzureResourceResourceTreeNode } from '../../resourceTreeNode';
export function registerAzureResourceDatabaseServerCommands(appContext: AppContext): void {
appContext.apiWrapper.registerCommand('azure.resource.connectsqlserver', async (node?: TreeNode) => {
if (!node)
{
return;
}
const treeItem = await node.getTreeItem();
if (treeItem.contextValue !== AzureResourceItemType.databaseServer) {
return;
}
const resourceNode = (node as AzureResourceResourceTreeNode).resourceNodeWithProviderId.resourceNode;
const databaseServer = (resourceNode as IAzureResourceDatabaseServerNode).databaseServer;
let connectionProfile: IConnectionProfile = {
id: generateGuid(),
connectionName: undefined,
serverName: databaseServer.fullName,
databaseName: databaseServer.defaultDatabaseName,
userName: databaseServer.loginName,
password: '',
authenticationType: 'SqlLogin',
savePassword: true,
groupFullName: '',
groupId: '',
providerName: 'MSSQL',
saveProfile: true,
options: {}
};
const conn = await appContext.apiWrapper.openConnectionDialog(undefined, connectionProfile, { saveConnection: true, showDashboard: true });
if (conn) {
appContext.apiWrapper.executeCommand('workbench.view.connections');
}
});
}

View 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 { ExtensionContext } from 'vscode';
import { ApiWrapper } from '../../../apiWrapper';
import { azureResource } from '../../azure-resource';
import { IAzureResourceDatabaseServerService } from './interfaces';
import { AzureResourceDatabaseServerTreeDataProvider } from './databaseServerTreeDataProvider';
export class AzureResourceDatabaseServerProvider implements azureResource.IAzureResourceProvider {
public constructor(
databaseServerService: IAzureResourceDatabaseServerService,
apiWrapper: ApiWrapper,
extensionContext: ExtensionContext
) {
this._databaseServerService = databaseServerService;
this._apiWrapper = apiWrapper;
this._extensionContext = extensionContext;
}
public getTreeDataProvider(): azureResource.IAzureResourceTreeDataProvider {
return new AzureResourceDatabaseServerTreeDataProvider(this._databaseServerService, this._apiWrapper, this._extensionContext);
}
public get providerId(): string {
return 'azure.resource.providers.databaseServer';
}
private _databaseServerService: IAzureResourceDatabaseServerService = undefined;
private _apiWrapper: ApiWrapper = undefined;
private _extensionContext: ExtensionContext = undefined;
}

View File

@@ -0,0 +1,31 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ServiceClientCredentials } from 'ms-rest';
import { SqlManagementClient } from 'azure-arm-sql';
import { azureResource } from '../../azure-resource';
import { IAzureResourceDatabaseServerService } from './interfaces';
import { AzureResourceDatabaseServer } from './models';
export class AzureResourceDatabaseServerService implements IAzureResourceDatabaseServerService {
public async getDatabaseServers(subscription: azureResource.AzureResourceSubscription, credential: ServiceClientCredentials): Promise<AzureResourceDatabaseServer[]> {
const databaseServers: AzureResourceDatabaseServer[] = [];
const sqlManagementClient = new SqlManagementClient(credential, subscription.id);
const svrs = await sqlManagementClient.servers.list();
svrs.forEach((svr) => databaseServers.push({
name: svr.name,
fullName: svr.fullyQualifiedDomainName,
loginName: svr.administratorLogin,
defaultDatabaseName: 'master'
}));
return databaseServers;
}
}

View File

@@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------------------------
* 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 { AzureResource } from 'sqlops';
import { TreeItem, TreeItemCollapsibleState, ExtensionContext } from 'vscode';
import { TokenCredentials } from 'ms-rest';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { azureResource } from '../../azure-resource';
import { IAzureResourceDatabaseServerService, IAzureResourceDatabaseServerNode } from './interfaces';
import { AzureResourceDatabaseServer } from './models';
import { AzureResourceItemType } from '../../../azureResource/constants';
import { ApiWrapper } from '../../../apiWrapper';
export class AzureResourceDatabaseServerTreeDataProvider implements azureResource.IAzureResourceTreeDataProvider {
public constructor(
databaseServerService: IAzureResourceDatabaseServerService,
apiWrapper: ApiWrapper,
extensionContext: ExtensionContext
) {
this._databaseServerService = databaseServerService;
this._apiWrapper = apiWrapper;
this._extensionContext = extensionContext;
}
public getTreeItem(element: azureResource.IAzureResourceNode): TreeItem | Thenable<TreeItem> {
return element.treeItem;
}
public async getChildren(element?: azureResource.IAzureResourceNode): Promise<azureResource.IAzureResourceNode[]> {
if (!element) {
return [this.createContainerNode()];
}
const tokens = await this._apiWrapper.getSecurityToken(element.account, AzureResource.ResourceManagement);
const credential = new TokenCredentials(tokens[element.tenantId].token, tokens[element.tenantId].tokenType);
const databaseServers: AzureResourceDatabaseServer[] = (await this._databaseServerService.getDatabaseServers(element.subscription, credential)) || <AzureResourceDatabaseServer[]>[];
return databaseServers.map((databaseServer) => <IAzureResourceDatabaseServerNode>{
account: element.account,
subscription: element.subscription,
tenantId: element.tenantId,
databaseServer: databaseServer,
treeItem: {
id: `databaseServer_${databaseServer.name}`,
label: databaseServer.name,
iconPath: {
dark: this._extensionContext.asAbsolutePath('resources/dark/sql_server_inverse.svg'),
light: this._extensionContext.asAbsolutePath('resources/light/sql_server.svg')
},
collapsibleState: TreeItemCollapsibleState.None,
contextValue: AzureResourceItemType.databaseServer
}
});
}
private createContainerNode(): azureResource.IAzureResourceNode {
return {
account: undefined,
subscription: undefined,
tenantId: undefined,
treeItem: {
id: AzureResourceDatabaseServerTreeDataProvider.containerId,
label: AzureResourceDatabaseServerTreeDataProvider.containerLabel,
iconPath: {
dark: this._extensionContext.asAbsolutePath('resources/dark/folder_inverse.svg'),
light: this._extensionContext.asAbsolutePath('resources/light/folder.svg')
},
collapsibleState: TreeItemCollapsibleState.Collapsed,
contextValue: AzureResourceItemType.databaseServerContainer
}
};
}
private _databaseServerService: IAzureResourceDatabaseServerService = undefined;
private _apiWrapper: ApiWrapper = undefined;
private _extensionContext: ExtensionContext = undefined;
private static readonly containerId = 'azure.resource.providers.databaseServer.treeDataProvider.databaseServerContainer';
private static readonly containerLabel = localize('azure.resource.providers.databaseServer.treeDataProvider.databaseServerContainerLabel', 'SQL Servers');
}

View File

@@ -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.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ServiceClientCredentials } from 'ms-rest';
import { azureResource } from '../../azure-resource';
import { AzureResourceDatabaseServer } from './models';
export interface IAzureResourceDatabaseServerService {
getDatabaseServers(subscription: azureResource.AzureResourceSubscription, credentials: ServiceClientCredentials): Promise<AzureResourceDatabaseServer[]>;
}
export interface IAzureResourceDatabaseServerNode extends azureResource.IAzureResourceNode {
readonly databaseServer: AzureResourceDatabaseServer;
}

View File

@@ -0,0 +1,13 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export interface AzureResourceDatabaseServer {
name: string;
fullName: string;
loginName: string;
defaultDatabaseName: string;
}

View File

@@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------------------------
* 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 { extensions, TreeItem } from 'vscode';
import { Account } from 'sqlops';
import { azureResource } from './azure-resource';
import { IAzureResourceNodeWithProviderId } from './interfaces';
export class AzureResourceService {
private constructor() {
}
public static getInstance(): AzureResourceService {
return AzureResourceService._instance;
}
public async listResourceProviderIds(): Promise<string[]> {
await this.ensureResourceProvidersRegistered();
return Object.keys(this._resourceProviders);
}
public registerResourceProvider(resourceProvider: azureResource.IAzureResourceProvider): void {
this.doRegisterResourceProvider(resourceProvider);
}
public clearResourceProviders(): void {
this._resourceProviders = {};
this._treeDataProviders = {};
this._areResourceProvidersLoaded = false;
}
public async getRootChildren(resourceProviderId: string, account: Account, subscription: azureResource.AzureResourceSubscription, tenatId: string): Promise<IAzureResourceNodeWithProviderId[]> {
await this.ensureResourceProvidersRegistered();
if (!(resourceProviderId in this._resourceProviders)) {
throw new Error(`Azure resource provider doesn't exist. Id: ${resourceProviderId}`);
}
const treeDataProvider = this._treeDataProviders[resourceProviderId];
const children = await treeDataProvider.getChildren();
return children.map((child) => <IAzureResourceNodeWithProviderId>{
resourceProviderId: resourceProviderId,
resourceNode: <azureResource.IAzureResourceNode>{
account: account,
subscription: subscription,
tenantId: tenatId,
treeItem: child.treeItem
}
});
}
public async getChildren(resourceProviderId: string, element: azureResource.IAzureResourceNode): Promise<IAzureResourceNodeWithProviderId[]> {
await this.ensureResourceProvidersRegistered();
if (!(resourceProviderId in this._resourceProviders)) {
throw new Error(`Azure resource provider doesn't exist. Id: ${resourceProviderId}`);
}
const treeDataProvider = this._treeDataProviders[resourceProviderId];
const children = await treeDataProvider.getChildren(element);
return children.map((child) => <IAzureResourceNodeWithProviderId>{
resourceProviderId: resourceProviderId,
resourceNode: child
});
}
public async getTreeItem(resourceProviderId: string, element?: azureResource.IAzureResourceNode): Promise<TreeItem> {
await this.ensureResourceProvidersRegistered();
if (!(resourceProviderId in this._resourceProviders)) {
throw new Error(`Azure resource provider doesn't exist. Id: ${resourceProviderId}`);
}
const treeDataProvider = this._treeDataProviders[resourceProviderId];
return treeDataProvider.getTreeItem(element);
}
public get areResourceProvidersLoaded(): boolean {
return this._areResourceProvidersLoaded;
}
public set areResourceProvidersLoaded(value: boolean) {
this._areResourceProvidersLoaded = value;
}
private async ensureResourceProvidersRegistered(): Promise<void> {
if (this._areResourceProvidersLoaded) {
return;
}
for (const extension of extensions.all) {
const contributes = extension.packageJSON && extension.packageJSON.contributes;
if (!contributes) {
continue;
}
if (contributes['hasAzureResourceProviders']) {
await extension.activate();
if (extension.exports && extension.exports.provideResources) {
for (const resourceProvider of <azureResource.IAzureResourceProvider[]>extension.exports.provideResources()) {
this.doRegisterResourceProvider(resourceProvider);
}
}
}
}
this._areResourceProvidersLoaded = true;
}
private doRegisterResourceProvider(resourceProvider: azureResource.IAzureResourceProvider): void {
this._resourceProviders[resourceProvider.providerId] = resourceProvider;
this._treeDataProviders[resourceProvider.providerId] = resourceProvider.getTreeDataProvider();
}
private _areResourceProvidersLoaded: boolean = false;
private _resourceProviders: { [resourceProviderId: string]: azureResource.IAzureResourceProvider } = {};
private _treeDataProviders: { [resourceProviderId: string]: azureResource.IAzureResourceTreeDataProvider } = {};
private static readonly _instance = new AzureResourceService();
}

View File

@@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------------------------
* 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 { NodeInfo } from 'sqlops';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { TreeNode } from './treeNode';
import { AzureResourceService } from './resourceService';
import { IAzureResourceNodeWithProviderId } from './interfaces';
import { AzureResourceMessageTreeNode } from './messageTreeNode';
import { AzureResourceErrorMessageUtil } from './utils';
export class AzureResourceResourceTreeNode extends TreeNode {
public constructor(
public readonly resourceNodeWithProviderId: IAzureResourceNodeWithProviderId,
parent: TreeNode
) {
super();
this.parent = parent;
}
public async getChildren(): Promise<TreeNode[]> {
// It is a leaf node.
if (this.resourceNodeWithProviderId.resourceNode.treeItem.collapsibleState === TreeItemCollapsibleState.None) {
return <TreeNode[]>[];
}
try {
const children = await this._resourceService.getChildren(this.resourceNodeWithProviderId.resourceProviderId, this.resourceNodeWithProviderId.resourceNode);
if (children.length === 0) {
return [AzureResourceMessageTreeNode.create(AzureResourceResourceTreeNode.noResourcesLabel, this)];
} else {
return children.map((child) => {
// To make tree node's id unique, otherwise, treeModel.js would complain 'item already registered'
child.resourceNode.treeItem.id = `${this.resourceNodeWithProviderId.resourceNode.treeItem.id}.${child.resourceNode.treeItem.id}`;
return new AzureResourceResourceTreeNode(child, this);
});
}
} catch (error) {
return [AzureResourceMessageTreeNode.create(AzureResourceErrorMessageUtil.getErrorMessage(error), this)];
}
}
public getTreeItem(): TreeItem | Promise<TreeItem> {
return this._resourceService.getTreeItem(this.resourceNodeWithProviderId.resourceProviderId, this.resourceNodeWithProviderId.resourceNode);
}
public getNodeInfo(): NodeInfo {
const treeItem = this.resourceNodeWithProviderId.resourceNode.treeItem;
return {
label: treeItem.label,
isLeaf: treeItem.collapsibleState === TreeItemCollapsibleState.None ? true : false,
errorMessage: undefined,
metadata: undefined,
nodePath: this.generateNodePath(),
nodeStatus: undefined,
nodeType: treeItem.contextValue,
nodeSubType: undefined,
iconType: treeItem.contextValue
};
}
public get nodePathValue(): string {
return this.resourceNodeWithProviderId.resourceNode.treeItem.id;
}
private _resourceService = AzureResourceService.getInstance();
private static readonly noResourcesLabel = localize('azure.resource.resourceTreeNode.noResourcesLabel', 'No Resources found.');
}

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