SQL Operations Studio Public Preview 1 (0.23) release source code

This commit is contained in:
Karl Burtram
2017-11-09 14:30:27 -08:00
parent b88ecb8d93
commit 3cdac41339
8829 changed files with 759707 additions and 286 deletions

View File

@@ -0,0 +1,31 @@
<?xml version='1.0' standalone='no' ?>
<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='10px' height='10px'>
<style>
circle {
animation: ball 0.6s linear infinite;
}
circle:nth-child(2) { animation-delay: 0.075s; }
circle:nth-child(3) { animation-delay: 0.15s; }
circle:nth-child(4) { animation-delay: 0.225s; }
circle:nth-child(5) { animation-delay: 0.3s; }
circle:nth-child(6) { animation-delay: 0.375s; }
circle:nth-child(7) { animation-delay: 0.45s; }
circle:nth-child(8) { animation-delay: 0.525s; }
@keyframes ball {
from { opacity: 1; }
to { opacity: 0.3; }
}
</style>
<g style="fill:white;">
<circle cx='5' cy='1' r='1' style='opacity:0.3;' />
<circle cx='7.8284' cy='2.1716' r='1' style='opacity:0.3;' />
<circle cx='9' cy='5' r='1' style='opacity:0.3;' />
<circle cx='7.8284' cy='7.8284' r='1' style='opacity:0.3;' />
<circle cx='5' cy='9' r='1' style='opacity:0.3;' />
<circle cx='2.1716' cy='7.8284' r='1' style='opacity:0.3;' />
<circle cx='1' cy='5' r='1' style='opacity:0.3;' />
<circle cx='2.1716' cy='2.1716' r='1' style='opacity:0.3;' />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,18 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-workbench > .part.statusbar > .statusbar-item.progress {
background-image: url(progress.svg);
background-repeat: no-repeat;
background-position: left;
padding-left: 14px;
display: inline;
}
.monaco-workbench .progress-badge > .badge-content {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMiAyIDE0IDE0IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDIgMiAxNCAxNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTkgMTZjLTMuODYgMC03LTMuMTQtNy03czMuMTQtNyA3LTdjMy44NTkgMCA3IDMuMTQxIDcgN3MtMy4xNDEgNy03IDd6bTAtMTIuNmMtMy4wODggMC01LjYgMi41MTMtNS42IDUuNnMyLjUxMiA1LjYgNS42IDUuNiA1LjYtMi41MTIgNS42LTUuNi0yLjUxMi01LjYtNS42LTUuNnptMy44NiA3LjFsLTMuMTYtMS44OTZ2LTMuODA0aC0xLjR2NC41OTZsMy44NCAyLjMwNS43Mi0xLjIwMXoiLz48L3N2Zz4=");
background-position: center center;
background-repeat: no-repeat;
}

View File

@@ -0,0 +1,257 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import lifecycle = require('vs/base/common/lifecycle');
import { TPromise } from 'vs/base/common/winjs.base';
import types = require('vs/base/common/types');
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { IProgressService, IProgressRunner } from 'vs/platform/progress/common/progress';
interface ProgressState {
infinite?: boolean;
total?: number;
worked?: number;
done?: boolean;
whilePromise?: TPromise<any>;
}
export abstract class ScopedService {
protected toDispose: lifecycle.IDisposable[];
constructor(private viewletService: IViewletService, private panelService: IPanelService, private scopeId: string) {
this.toDispose = [];
this.registerListeners();
}
public registerListeners(): void {
this.toDispose.push(this.viewletService.onDidViewletOpen(viewlet => this.onScopeOpened(viewlet.getId())));
this.toDispose.push(this.panelService.onDidPanelOpen(panel => this.onScopeOpened(panel.getId())));
this.toDispose.push(this.viewletService.onDidViewletClose(viewlet => this.onScopeClosed(viewlet.getId())));
this.toDispose.push(this.panelService.onDidPanelClose(panel => this.onScopeClosed(panel.getId())));
}
private onScopeClosed(scopeId: string) {
if (scopeId === this.scopeId) {
this.onScopeDeactivated();
}
}
private onScopeOpened(scopeId: string) {
if (scopeId === this.scopeId) {
this.onScopeActivated();
}
}
public abstract onScopeActivated(): void;
public abstract onScopeDeactivated(): void;
}
export class WorkbenchProgressService extends ScopedService implements IProgressService {
public _serviceBrand: any;
private isActive: boolean;
private progressbar: ProgressBar;
private progressState: ProgressState;
constructor(
progressbar: ProgressBar,
scopeId: string,
isActive: boolean,
@IViewletService viewletService: IViewletService,
@IPanelService panelService: IPanelService
) {
super(viewletService, panelService, scopeId);
this.progressbar = progressbar;
this.isActive = isActive || types.isUndefinedOrNull(scopeId); // If service is unscoped, enable by default
this.progressState = Object.create(null);
}
public onScopeDeactivated(): void {
this.isActive = false;
}
public onScopeActivated(): void {
this.isActive = true;
// Return early if progress state indicates that progress is done
if (this.progressState.done) {
return;
}
// Replay Infinite Progress from Promise
if (this.progressState.whilePromise) {
this.doShowWhile();
}
// Replay Infinite Progress
else if (this.progressState.infinite) {
this.progressbar.infinite().getContainer().show();
}
// Replay Finite Progress (Total & Worked)
else {
if (this.progressState.total) {
this.progressbar.total(this.progressState.total).getContainer().show();
}
if (this.progressState.worked) {
this.progressbar.worked(this.progressState.worked).getContainer().show();
}
}
}
private clearProgressState(): void {
this.progressState.infinite = void 0;
this.progressState.done = void 0;
this.progressState.worked = void 0;
this.progressState.total = void 0;
this.progressState.whilePromise = void 0;
}
public show(infinite: boolean, delay?: number): IProgressRunner;
public show(total: number, delay?: number): IProgressRunner;
public show(infiniteOrTotal: any, delay?: number): IProgressRunner {
let infinite: boolean;
let total: number;
// Sort out Arguments
if (infiniteOrTotal === false || infiniteOrTotal === true) {
infinite = infiniteOrTotal;
} else {
total = infiniteOrTotal;
}
// Reset State
this.clearProgressState();
// Keep in State
this.progressState.infinite = infinite;
this.progressState.total = total;
// Active: Show Progress
if (this.isActive) {
// Infinite: Start Progressbar and Show after Delay
if (!types.isUndefinedOrNull(infinite)) {
if (types.isUndefinedOrNull(delay)) {
this.progressbar.infinite().getContainer().show();
} else {
this.progressbar.infinite().getContainer().showDelayed(delay);
}
}
// Finite: Start Progressbar and Show after Delay
else if (!types.isUndefinedOrNull(total)) {
if (types.isUndefinedOrNull(delay)) {
this.progressbar.total(total).getContainer().show();
} else {
this.progressbar.total(total).getContainer().showDelayed(delay);
}
}
}
return {
total: (total: number) => {
this.progressState.infinite = false;
this.progressState.total = total;
if (this.isActive) {
this.progressbar.total(total);
}
},
worked: (worked: number) => {
// Verify first that we are either not active or the progressbar has a total set
if (!this.isActive || this.progressbar.hasTotal()) {
this.progressState.infinite = false;
if (this.progressState.worked) {
this.progressState.worked += worked;
} else {
this.progressState.worked = worked;
}
if (this.isActive) {
this.progressbar.worked(worked);
}
}
// Otherwise the progress bar does not support worked(), we fallback to infinite() progress
else {
this.progressState.infinite = true;
this.progressState.worked = void 0;
this.progressState.total = void 0;
this.progressbar.infinite().getContainer().show();
}
},
done: () => {
this.progressState.infinite = false;
this.progressState.done = true;
if (this.isActive) {
this.progressbar.stop().getContainer().hide();
}
}
};
}
public showWhile(promise: TPromise<any>, delay?: number): TPromise<void> {
let stack: boolean = !!this.progressState.whilePromise;
// Reset State
if (!stack) {
this.clearProgressState();
}
// Otherwise join with existing running promise to ensure progress is accurate
else {
promise = TPromise.join([promise, this.progressState.whilePromise]);
}
// Keep Promise in State
this.progressState.whilePromise = promise;
let stop = () => {
// If this is not the last promise in the list of joined promises, return early
if (!!this.progressState.whilePromise && this.progressState.whilePromise !== promise) {
return;
}
// The while promise is either null or equal the promise we last hooked on
this.clearProgressState();
if (this.isActive) {
this.progressbar.stop().getContainer().hide();
}
};
this.doShowWhile(delay);
return promise.then(stop, stop);
}
private doShowWhile(delay?: number): void {
// Show Progress when active
if (this.isActive) {
if (types.isUndefinedOrNull(delay)) {
this.progressbar.infinite().getContainer().show();
} else {
this.progressbar.infinite().getContainer().showDelayed(delay);
}
}
}
public dispose(): void {
this.toDispose = lifecycle.dispose(this.toDispose);
}
}

View File

@@ -0,0 +1,188 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!./media/progressService2';
import * as dom from 'vs/base/browser/dom';
import { localize } from 'vs/nls';
import { IActivityBarService, ProgressBadge } from 'vs/workbench/services/activity/common/activityBarService';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IProgressService2, IProgressOptions, ProgressLocation, IProgress, IProgressStep, Progress, emptyProgress } from 'vs/platform/progress/common/progress';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel';
import { Registry } from 'vs/platform/registry/common/platform';
import { StatusbarAlignment, IStatusbarRegistry, StatusbarItemDescriptor, Extensions, IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar';
import { TPromise } from 'vs/base/common/winjs.base';
import { always } from 'vs/base/common/async';
class WindowProgressItem implements IStatusbarItem {
static Instance: WindowProgressItem;
private _element: HTMLElement;
private _label: OcticonLabel;
constructor() {
WindowProgressItem.Instance = this;
}
render(element: HTMLElement): IDisposable {
this._element = element;
this._label = new OcticonLabel(this._element);
this._element.classList.add('progress');
this.hide();
return null;
}
set text(value: string) {
this._label.text = value;
}
set title(value: string) {
this._label.title = value;
}
hide() {
dom.hide(this._element);
}
show() {
dom.show(this._element);
}
}
export class ProgressService2 implements IProgressService2 {
_serviceBrand: any;
private _stack: [IProgressOptions, Progress<IProgressStep>][] = [];
constructor(
@IActivityBarService private _activityBar: IActivityBarService,
@IViewletService private _viewletService: IViewletService
) {
//
}
withProgress(options: IProgressOptions, task: (progress: IProgress<{ message?: string, percentage?: number }>) => TPromise<any>): void {
const { location } = options;
switch (location) {
case ProgressLocation.Window:
this._withWindowProgress(options, task);
break;
case ProgressLocation.Scm:
this._withViewletProgress('workbench.view.scm', task);
break;
default:
console.warn(`Bad progress location: ${location}`);
}
}
private _withWindowProgress(options: IProgressOptions, callback: (progress: IProgress<{ message?: string, percentage?: number }>) => TPromise<any>): void {
const task: [IProgressOptions, Progress<IProgressStep>] = [options, new Progress<IProgressStep>(() => this._updateWindowProgress())];
const promise = callback(task[1]);
let delayHandle = setTimeout(() => {
delayHandle = undefined;
this._stack.unshift(task);
this._updateWindowProgress();
// show progress for at least 150ms
always(TPromise.join([
TPromise.timeout(150),
promise
]), () => {
const idx = this._stack.indexOf(task);
this._stack.splice(idx, 1);
this._updateWindowProgress();
});
}, 150);
// cancel delay if promise finishes below 150ms
always(promise, () => clearTimeout(delayHandle));
}
private _updateWindowProgress(idx: number = 0) {
if (idx >= this._stack.length) {
WindowProgressItem.Instance.hide();
} else {
const [options, progress] = this._stack[idx];
let text = options.title;
if (progress.value && progress.value.message) {
text = progress.value.message;
}
if (!text) {
// no message -> no progress. try with next on stack
this._updateWindowProgress(idx + 1);
return;
}
let title = text;
if (options.title && options.title !== title) {
title = localize('progress.subtitle', "{0} - {1}", options.title, title);
}
if (options.tooltip) {
title = localize('progress.title', "{0}: {1}", options.tooltip, title);
}
WindowProgressItem.Instance.text = text;
WindowProgressItem.Instance.title = title;
WindowProgressItem.Instance.show();
}
}
private _withViewletProgress(viewletId: string, task: (progress: IProgress<{ message?: string, percentage?: number }>) => TPromise<any>): void {
const promise = task(emptyProgress);
// show in viewlet
const viewletProgress = this._viewletService.getProgressIndicator(viewletId);
if (viewletProgress) {
viewletProgress.showWhile(promise);
}
// show activity bar
let activityProgress: IDisposable;
let delayHandle = setTimeout(() => {
delayHandle = undefined;
const handle = this._activityBar.showActivity(
viewletId,
new ProgressBadge(() => ''),
'progress-badge'
);
const startTimeVisible = Date.now();
const minTimeVisible = 300;
activityProgress = {
dispose() {
const d = Date.now() - startTimeVisible;
if (d < minTimeVisible) {
// should at least show for Nms
setTimeout(() => handle.dispose(), minTimeVisible - d);
} else {
// shown long enough
handle.dispose();
}
}
};
}, 300);
always(promise, () => {
clearTimeout(delayHandle);
dispose(activityProgress);
});
}
}
Registry.as<IStatusbarRegistry>(Extensions.Statusbar).registerStatusbarItem(
new StatusbarItemDescriptor(WindowProgressItem, StatusbarAlignment.LEFT)
);