mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-30 00:30:29 -04:00
Merge from vscode 6268feb42ba4f2e2fa15484e88c9af60d254998c (#6530)
This commit is contained in:
@@ -13,9 +13,9 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Cache, CacheResult } from 'vs/base/common/cache';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
import { dispose, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { dispose, toDisposable, Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { append, $, addClass, removeClass, finalHandler, join, toggleClass, hide, show } from 'vs/base/browser/dom';
|
||||
import { append, $, addClass, removeClass, finalHandler, join, toggleClass, hide, show, addDisposableListener, EventType } from 'vs/base/browser/dom';
|
||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
@@ -52,6 +52,7 @@ import { isUndefined } from 'vs/base/common/types';
|
||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/webview';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
import { renderDashboardContributions } from 'sql/workbench/parts/extensions/browser/contributionRenders';
|
||||
@@ -280,6 +281,20 @@ export class ExtensionEditor extends BaseEditor {
|
||||
this.content = append(body, $('.content'));
|
||||
}
|
||||
|
||||
private onClick(element: HTMLElement, callback: () => void): IDisposable {
|
||||
const disposables: DisposableStore = new DisposableStore();
|
||||
disposables.add(addDisposableListener(element, EventType.CLICK, finalHandler(callback)));
|
||||
disposables.add(addDisposableListener(element, EventType.KEY_UP, e => {
|
||||
const keyboardEvent = new StandardKeyboardEvent(e);
|
||||
if (keyboardEvent.equals(KeyCode.Space) || keyboardEvent.equals(KeyCode.Enter)) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
callback();
|
||||
}
|
||||
}));
|
||||
return disposables;
|
||||
}
|
||||
|
||||
async setInput(input: ExtensionsInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
const runningExtensions = await this.extensionService.getExtensions();
|
||||
const colorThemes = await this.workbenchThemeService.getColorThemes();
|
||||
@@ -328,26 +343,21 @@ export class ExtensionEditor extends BaseEditor {
|
||||
toggleClass(this.publisher, 'clickable', !!extension.url);
|
||||
toggleClass(this.rating, 'clickable', !!extension.url);
|
||||
if (extension.url) {
|
||||
this.name.onclick = finalHandler(() => window.open(extension.url));
|
||||
this.rating.onclick = finalHandler(() => window.open(`${extension.url}#review-details`));
|
||||
this.publisher.onclick = finalHandler(() => {
|
||||
this.transientDisposables.add(this.onClick(this.name, () => window.open(extension.url)));
|
||||
this.transientDisposables.add(this.onClick(this.rating, () => window.open(`${extension.url}#review-details`)));
|
||||
this.transientDisposables.add(this.onClick(this.publisher, () => {
|
||||
this.viewletService.openViewlet(VIEWLET_ID, true)
|
||||
.then(viewlet => viewlet as IExtensionsViewlet)
|
||||
.then(viewlet => viewlet.search(`publisher:"${extension.publisherDisplayName}"`));
|
||||
});
|
||||
}));
|
||||
|
||||
if (extension.licenseUrl) {
|
||||
this.license.onclick = finalHandler(() => window.open(extension.licenseUrl));
|
||||
this.transientDisposables.add(this.onClick(this.license, () => window.open(extension.licenseUrl)));
|
||||
this.license.style.display = 'initial';
|
||||
} else {
|
||||
this.license.onclick = null;
|
||||
this.license.style.display = 'none';
|
||||
}
|
||||
} else {
|
||||
this.name.onclick = null;
|
||||
this.rating.onclick = null;
|
||||
this.publisher.onclick = null;
|
||||
this.license.onclick = null;
|
||||
this.license.style.display = 'none';
|
||||
}
|
||||
|
||||
@@ -362,11 +372,10 @@ export class ExtensionEditor extends BaseEditor {
|
||||
// {{SQL CARBON EDIT}} - End
|
||||
|
||||
if (extension.repository) {
|
||||
this.repository.onclick = finalHandler(() => window.open(extension.repository));
|
||||
this.transientDisposables.add(this.onClick(this.repository, () => window.open(extension.repository)));
|
||||
this.repository.style.display = 'initial';
|
||||
}
|
||||
else {
|
||||
this.repository.onclick = null;
|
||||
this.repository.style.display = 'none';
|
||||
}
|
||||
|
||||
@@ -712,7 +721,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', undefined, localize('settings', "Settings ({0})", contrib.length)),
|
||||
$('summary', { tabindex: '0' }, localize('settings', "Settings ({0})", contrib.length)),
|
||||
$('table', undefined,
|
||||
$('tr', undefined,
|
||||
$('th', undefined, localize('setting name', "Name")),
|
||||
@@ -740,7 +749,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', undefined, localize('debuggers', "Debuggers ({0})", contrib.length)),
|
||||
$('summary', { tabindex: '0' }, localize('debuggers', "Debuggers ({0})", contrib.length)),
|
||||
$('table', undefined,
|
||||
$('tr', undefined,
|
||||
$('th', undefined, localize('debugger name', "Name")),
|
||||
@@ -771,7 +780,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', undefined, localize('viewContainers', "View Containers ({0})", viewContainers.length)),
|
||||
$('summary', { tabindex: '0' }, localize('viewContainers', "View Containers ({0})", viewContainers.length)),
|
||||
$('table', undefined,
|
||||
$('tr', undefined, $('th', undefined, localize('view container id', "ID")), $('th', undefined, localize('view container title', "Title")), $('th', undefined, localize('view container location', "Where"))),
|
||||
...viewContainers.map(viewContainer => $('tr', undefined, $('td', undefined, viewContainer.id), $('td', undefined, viewContainer.title), $('td', undefined, viewContainer.location)))
|
||||
@@ -797,7 +806,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', undefined, localize('views', "Views ({0})", views.length)),
|
||||
$('summary', { tabindex: '0' }, localize('views', "Views ({0})", views.length)),
|
||||
$('table', undefined,
|
||||
$('tr', undefined, $('th', undefined, localize('view id', "ID")), $('th', undefined, localize('view name', "Name")), $('th', undefined, localize('view location', "Where"))),
|
||||
...views.map(view => $('tr', undefined, $('td', undefined, view.id), $('td', undefined, view.name), $('td', undefined, view.location)))
|
||||
@@ -817,7 +826,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', undefined, localize('localizations', "Localizations ({0})", localizations.length)),
|
||||
$('summary', { tabindex: '0' }, localize('localizations', "Localizations ({0})", localizations.length)),
|
||||
$('table', undefined,
|
||||
$('tr', undefined, $('th', undefined, localize('localizations language id', "Language Id")), $('th', undefined, localize('localizations language name', "Language Name")), $('th', undefined, localize('localizations localized language name', "Language Name (Localized)"))),
|
||||
...localizations.map(localization => $('tr', undefined, $('td', undefined, localization.languageId), $('td', undefined, localization.languageName || ''), $('td', undefined, localization.localizedLanguageName || '')))
|
||||
@@ -837,7 +846,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', undefined, localize('colorThemes', "Color Themes ({0})", contrib.length)),
|
||||
$('summary', { tabindex: '0' }, localize('colorThemes', "Color Themes ({0})", contrib.length)),
|
||||
$('ul', undefined, ...contrib.map(theme => $('li', undefined, theme.label)))
|
||||
);
|
||||
|
||||
@@ -854,7 +863,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', undefined, localize('iconThemes', "Icon Themes ({0})", contrib.length)),
|
||||
$('summary', { tabindex: '0' }, localize('iconThemes', "Icon Themes ({0})", contrib.length)),
|
||||
$('ul', undefined, ...contrib.map(theme => $('li', undefined, theme.label)))
|
||||
);
|
||||
|
||||
@@ -883,7 +892,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', undefined, localize('colors', "Colors ({0})", colors.length)),
|
||||
$('summary', { tabindex: '0' }, localize('colors', "Colors ({0})", colors.length)),
|
||||
$('table', undefined,
|
||||
$('tr', undefined,
|
||||
$('th', undefined, localize('colorId', "Id")),
|
||||
@@ -916,7 +925,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', undefined, localize('JSON Validation', "JSON Validation ({0})", contrib.length)),
|
||||
$('summary', { tabindex: '0' }, localize('JSON Validation', "JSON Validation ({0})", contrib.length)),
|
||||
$('table', undefined,
|
||||
$('tr', undefined,
|
||||
$('th', undefined, localize('fileMatch', "File Match")),
|
||||
@@ -990,7 +999,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
};
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', undefined, localize('commands', "Commands ({0})", commands.length)),
|
||||
$('summary', { tabindex: '0' }, localize('commands', "Commands ({0})", commands.length)),
|
||||
$('table', undefined,
|
||||
$('tr', undefined,
|
||||
$('th', undefined, localize('command name', "Name")),
|
||||
@@ -1057,7 +1066,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
const details = $('details', { open: true, ontoggle: onDetailsToggle },
|
||||
$('summary', undefined, localize('languages', "Languages ({0})", languages.length)),
|
||||
$('summary', { tabindex: '0' }, localize('languages', "Languages ({0})", languages.length)),
|
||||
$('table', undefined,
|
||||
$('tr', undefined,
|
||||
$('th', undefined, localize('language id', "ID")),
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { isPromiseCanceledError, getErrorMessage } from 'vs/base/common/errors';
|
||||
import { PagedModel, IPagedModel, IPager, DelayedPagedModel } from 'vs/base/common/paging';
|
||||
import { SortBy, SortOrder, IQueryOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementServer, IExtensionManagementServerService, IExtensionTipsService, IExtensionRecommendation } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementServer, IExtensionManagementServerService, IExtensionTipsService, IExtensionRecommendation, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
@@ -44,11 +44,11 @@ import { IAction } from 'vs/base/common/actions';
|
||||
import { ExtensionType, ExtensionIdentifier, IExtensionDescription, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
|
||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
|
||||
import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil';
|
||||
import { IProductService } from 'vs/platform/product/common/product';
|
||||
import { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon';
|
||||
// {{SQL CARBON EDIT}}
|
||||
import product from 'vs/platform/product/node/product';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
import product from 'vs/platform/product/node/product'; // {{SQL CARBON EDIT}}
|
||||
|
||||
|
||||
class ExtensionsViewState extends Disposable implements IExtensionsViewState {
|
||||
@@ -104,8 +104,9 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
|
||||
@IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IProductService protected readonly productService: IProductService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
) {
|
||||
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService);
|
||||
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService);
|
||||
this.server = options.server;
|
||||
}
|
||||
|
||||
@@ -934,9 +935,10 @@ export class ServerExtensionsView extends ExtensionsListView {
|
||||
@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IProductService productService: IProductService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
) {
|
||||
options.server = server;
|
||||
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService);
|
||||
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService, contextKeyService);
|
||||
this._register(onDidChangeTitle(title => this.updateTitle(title)));
|
||||
}
|
||||
|
||||
@@ -1080,10 +1082,14 @@ export class WorkspaceRecommendedExtensionsView extends ExtensionsListView {
|
||||
return this.tipsService.getWorkspaceRecommendations()
|
||||
.then(recommendations => recommendations.filter(({ extensionId }) => {
|
||||
const extension = this.extensionsWorkbenchService.local.filter(i => areSameExtensions({ id: extensionId }, i.identifier))[0];
|
||||
if (!extension || !extension.local || extension.state !== ExtensionState.Installed) {
|
||||
if (!extension
|
||||
|| !extension.local
|
||||
|| extension.state !== ExtensionState.Installed
|
||||
|| extension.enablementState === EnablementState.DisabledByExtensionKind
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return isUIExtension(extension.local.manifest, this.productService, this.configurationService) ? extension.server !== this.extensionManagementServerService.localExtensionManagementServer : extension.server !== this.extensionManagementServerService.remoteExtensionManagementServer;
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,11 +256,8 @@
|
||||
font-weight: bold;
|
||||
font-size: 120%;
|
||||
border-bottom: 1px solid rgba(128, 128, 128, 0.22);
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.extension-editor > .body > .content details > summary:focus {
|
||||
outline: none;
|
||||
padding: 3px 6px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.extension-editor > .body > .content details > summary::-webkit-details-marker {
|
||||
@@ -386,4 +383,4 @@
|
||||
font-size: 90%;
|
||||
font-weight: 600;
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,13 @@ export class Query {
|
||||
}
|
||||
|
||||
static suggestions(query: string): string[] {
|
||||
const commands = ['installed', 'outdated', 'enabled', 'disabled', 'builtin', 'recommended', 'sort', 'category', 'tag', 'ext'];
|
||||
const commands = ['installed', 'outdated', 'enabled', 'disabled', 'builtin', 'recommended', 'sort', 'category', 'tag', 'ext', 'id'];
|
||||
const subcommands = {
|
||||
'sort': ['installs', 'rating', 'name'],
|
||||
'category': ['"programming languages"', 'snippets', 'linters', 'themes', 'debuggers', 'formatters', 'keymaps', '"scm providers"', 'other', '"extension packs"', '"language packs"'],
|
||||
'tag': [''],
|
||||
'ext': ['']
|
||||
'ext': [''],
|
||||
'id': ['']
|
||||
};
|
||||
|
||||
let queryContains = (substr: string) => query.indexOf(substr) > -1;
|
||||
@@ -77,4 +78,4 @@ export class Query {
|
||||
equals(other: Query): boolean {
|
||||
return this.value === other.value && this.sortBy === other.sortBy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { match } from 'vs/base/common/glob';
|
||||
import * as json from 'vs/base/common/json';
|
||||
import { IExtensionManagementService, IExtensionGalleryService, EXTENSION_IDENTIFIER_PATTERN, InstallOperation, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionTipsService, ExtensionRecommendationReason, IExtensionsConfigContent, RecommendationChangeNotification, IExtensionRecommendation, ExtensionRecommendationSource } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionTipsService, ExtensionRecommendationReason, IExtensionsConfigContent, RecommendationChangeNotification, IExtensionRecommendation, ExtensionRecommendationSource, IExtensionEnablementService, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
@@ -101,6 +101,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
@IModelService private readonly _modelService: IModelService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IExtensionManagementService private readonly extensionsService: IExtensionManagementService,
|
||||
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@@ -433,6 +434,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
}
|
||||
|
||||
this.extensionsService.getInstalled(ExtensionType.User).then(local => {
|
||||
local = local.filter(l => this.extensionEnablementService.getEnablementState(l) !== EnablementState.DisabledByExtensionKind); // Filter extensions disabled by kind
|
||||
const recommendations = filteredRecs.filter(({ extensionId }) => local.every(local => !areSameExtensions({ id: extensionId }, local.identifier)));
|
||||
|
||||
if (!recommendations.length) {
|
||||
|
||||
@@ -44,6 +44,8 @@ import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedPr
|
||||
import { ExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService';
|
||||
import { IProductService } from 'vs/platform/product/common/product';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
|
||||
|
||||
|
||||
suite('ExtensionsListView Tests', () => {
|
||||
@@ -93,6 +95,7 @@ suite('ExtensionsListView Tests', () => {
|
||||
instantiationService.stub(IExtensionManagementService, 'onUninstallExtension', uninstallEvent.event);
|
||||
instantiationService.stub(IExtensionManagementService, 'onDidUninstallExtension', didUninstallEvent.event);
|
||||
instantiationService.stub(IRemoteAgentService, RemoteAgentService);
|
||||
instantiationService.stub(IContextKeyService, MockContextKeyService);
|
||||
|
||||
instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService {
|
||||
private _localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' };
|
||||
|
||||
Reference in New Issue
Block a user