mirror of
https://github.com/Microsoft/vscode
synced 2024-08-24 11:36:01 +00:00
put new profiles UI behind flag (#214586)
This commit is contained in:
parent
af5696c630
commit
9548a679f5
|
@ -31,10 +31,17 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
|||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IUserDataProfilesEditor } from 'vs/workbench/contrib/userDataProfile/common/userDataProfile';
|
||||
import { ConfigurationScope, Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
|
||||
type IProfileTemplateQuickPickItem = IQuickPickItem & IProfileTemplateInfo;
|
||||
|
||||
export const OpenProfileMenu = new MenuId('OpenProfile');
|
||||
const CONFIG_ENABLE_NEW_PROFILES_UI = 'workbench.experimental.enableNewProfilesUI';
|
||||
const CONTEXT_ENABLE_NEW_PROFILES_UI = ContextKeyExpr.equals('config.workbench.experimental.enableNewProfilesUI', true);
|
||||
|
||||
export class UserDataProfilesWorkbenchContribution extends Disposable implements IWorkbenchContribution {
|
||||
|
||||
|
@ -54,6 +61,10 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
|
||||
@IWorkspaceTagsService private readonly workspaceTagsService: IWorkspaceTagsService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@ILifecycleService private readonly lifecycleService: ILifecycleService,
|
||||
) {
|
||||
super();
|
||||
|
@ -73,6 +84,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
this.hasProfilesContext.set(this.userDataProfilesService.profiles.length > 1);
|
||||
this._register(this.userDataProfilesService.onDidChangeProfiles(e => this.hasProfilesContext.set(this.userDataProfilesService.profiles.length > 1)));
|
||||
|
||||
this.registerConfiguration();
|
||||
this.registerEditor();
|
||||
this.registerActions();
|
||||
|
||||
|
@ -83,6 +95,29 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
this.reportWorkspaceProfileInfo();
|
||||
}
|
||||
|
||||
private openProfilesEditor(): Promise<IUserDataProfilesEditor | undefined> {
|
||||
return this.editorGroupsService.activeGroup.openEditor(new UserDataProfilesEditorInput(this.instantiationService));
|
||||
}
|
||||
|
||||
private isNewProfilesUIEnabled(): boolean {
|
||||
return this.configurationService.getValue(CONFIG_ENABLE_NEW_PROFILES_UI) === true;
|
||||
}
|
||||
|
||||
private registerConfiguration(): void {
|
||||
Registry.as<IConfigurationRegistry>(Extensions.Configuration)
|
||||
.registerConfiguration({
|
||||
...workbenchConfigurationNodeBase,
|
||||
properties: {
|
||||
[CONFIG_ENABLE_NEW_PROFILES_UI]: {
|
||||
type: 'boolean',
|
||||
description: localize('enable new profiles UI', "Enables the new profiles UI."),
|
||||
default: this.productService.quality !== 'stable',
|
||||
scope: ConfigurationScope.APPLICATION,
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private registerEditor(): void {
|
||||
Registry.as<IEditorPaneRegistry>(EditorExtensions.EditorPane).registerEditorPane(
|
||||
EditorPaneDescriptor.create(
|
||||
|
@ -120,6 +155,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
const getProfilesTitle = () => {
|
||||
return localize('profiles', "Profile ({0})", this.userDataProfileService.currentProfile.name);
|
||||
};
|
||||
const when = ContextKeyExpr.or(CONTEXT_ENABLE_NEW_PROFILES_UI.negate(), HAS_PROFILES_CONTEXT);
|
||||
MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
|
||||
get title() {
|
||||
return getProfilesTitle();
|
||||
|
@ -127,7 +163,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
submenu: ProfilesMenu,
|
||||
group: '2_configuration',
|
||||
order: 1,
|
||||
when: HAS_PROFILES_CONTEXT,
|
||||
when,
|
||||
});
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, {
|
||||
get title() {
|
||||
|
@ -136,7 +172,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
submenu: ProfilesMenu,
|
||||
group: '2_configuration',
|
||||
order: 1,
|
||||
when: HAS_PROFILES_CONTEXT,
|
||||
when,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -269,6 +305,8 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
private readonly currentprofileActionsDisposable = this._register(new MutableDisposable<DisposableStore>());
|
||||
private registerCurrentProfilesActions(): void {
|
||||
this.currentprofileActionsDisposable.value = new DisposableStore();
|
||||
this.currentprofileActionsDisposable.value.add(this.registerEditCurrentProfileAction());
|
||||
this.currentprofileActionsDisposable.value.add(this.registerShowCurrentProfileContentsAction());
|
||||
this.currentprofileActionsDisposable.value.add(this.registerExportCurrentProfileAction());
|
||||
this.currentprofileActionsDisposable.value.add(this.registerImportProfileAction());
|
||||
}
|
||||
|
@ -287,12 +325,14 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
{
|
||||
id: MenuId.GlobalActivity,
|
||||
group: '2_configuration',
|
||||
order: 1
|
||||
order: 1,
|
||||
when: CONTEXT_ENABLE_NEW_PROFILES_UI,
|
||||
},
|
||||
{
|
||||
id: MenuId.MenubarPreferencesMenu,
|
||||
group: '2_configuration',
|
||||
order: 1
|
||||
order: 1,
|
||||
when: CONTEXT_ENABLE_NEW_PROFILES_UI,
|
||||
},
|
||||
]
|
||||
});
|
||||
|
@ -308,12 +348,69 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
id: 'workbench.profiles.actions.manageProfiles',
|
||||
category: Categories.Preferences,
|
||||
title: localize2('open profiles', "Open Profiles (UI)"),
|
||||
precondition: CONTEXT_ENABLE_NEW_PROFILES_UI,
|
||||
},
|
||||
}));
|
||||
|
||||
return disposables;
|
||||
}
|
||||
|
||||
private registerEditCurrentProfileAction(): IDisposable {
|
||||
const that = this;
|
||||
return registerAction2(class RenameCurrentProfileAction extends Action2 {
|
||||
constructor() {
|
||||
const precondition = ContextKeyExpr.and(ContextKeyExpr.notEquals(CURRENT_PROFILE_CONTEXT.key, that.userDataProfilesService.defaultProfile.id), IS_CURRENT_PROFILE_TRANSIENT_CONTEXT.toNegated());
|
||||
super({
|
||||
id: `workbench.profiles.actions.editCurrentProfile`,
|
||||
title: localize2('edit profile', "Edit Profile..."),
|
||||
precondition,
|
||||
f1: true,
|
||||
menu: [
|
||||
{
|
||||
id: ProfilesMenu,
|
||||
group: '2_manage_current',
|
||||
when: ContextKeyExpr.and(precondition, CONTEXT_ENABLE_NEW_PROFILES_UI.negate()),
|
||||
order: 2
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
run(accessor: ServicesAccessor) {
|
||||
if (that.isNewProfilesUIEnabled()) {
|
||||
return that.openProfilesEditor();
|
||||
} else {
|
||||
return that.userDataProfileImportExportService.editProfile(that.userDataProfileService.currentProfile);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private registerShowCurrentProfileContentsAction(): IDisposable {
|
||||
const id = 'workbench.profiles.actions.showProfileContents';
|
||||
return registerAction2(class ShowProfileContentsAction extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id,
|
||||
title: localize2('show profile contents', "Show Profile Contents"),
|
||||
category: PROFILES_CATEGORY,
|
||||
menu: [
|
||||
{
|
||||
id: ProfilesMenu,
|
||||
group: '2_manage_current',
|
||||
order: 3,
|
||||
when: CONTEXT_ENABLE_NEW_PROFILES_UI.negate()
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
async run(accessor: ServicesAccessor) {
|
||||
const userDataProfileImportExportService = accessor.get(IUserDataProfileImportExportService);
|
||||
return userDataProfileImportExportService.showProfileContents();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private registerExportCurrentProfileAction(): IDisposable {
|
||||
const that = this;
|
||||
const disposables = new DisposableStore();
|
||||
|
@ -322,22 +419,37 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
constructor() {
|
||||
super({
|
||||
id,
|
||||
title: localize2('export profile', "Export Profile ({0})...", that.userDataProfileService.currentProfile.name),
|
||||
title: localize2('export profile', "Export Profile..."),
|
||||
category: PROFILES_CATEGORY,
|
||||
precondition: IS_PROFILE_EXPORT_IN_PROGRESS_CONTEXT.toNegated(),
|
||||
f1: true,
|
||||
menu: {
|
||||
id: MenuId.MenubarShare
|
||||
}
|
||||
menu: [
|
||||
{
|
||||
id: ProfilesMenu,
|
||||
group: '4_import_export_profiles',
|
||||
order: 1,
|
||||
when: CONTEXT_ENABLE_NEW_PROFILES_UI.negate(),
|
||||
}, {
|
||||
id: MenuId.CommandPalette
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
async run(accessor: ServicesAccessor) {
|
||||
const editorGroupsService = accessor.get(IEditorGroupsService);
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
return editorGroupsService.activeGroup.openEditor(new UserDataProfilesEditorInput(instantiationService));
|
||||
if (that.isNewProfilesUIEnabled()) {
|
||||
return that.openProfilesEditor();
|
||||
} else {
|
||||
return that.userDataProfileImportExportService.exportProfile2();
|
||||
}
|
||||
}
|
||||
}));
|
||||
disposables.add(MenuRegistry.appendMenuItem(MenuId.MenubarShare, {
|
||||
command: {
|
||||
id,
|
||||
title: localize2('export profile in share', "Export Profile ({0})...", that.userDataProfileService.currentProfile.name),
|
||||
precondition: PROFILES_ENABLEMENT_CONTEXT,
|
||||
},
|
||||
}));
|
||||
return disposables;
|
||||
}
|
||||
|
||||
|
@ -352,7 +464,17 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
title: localize2('import profile', "Import Profile..."),
|
||||
category: PROFILES_CATEGORY,
|
||||
precondition: IS_PROFILE_IMPORT_IN_PROGRESS_CONTEXT.toNegated(),
|
||||
f1: true,
|
||||
menu: [
|
||||
{
|
||||
id: ProfilesMenu,
|
||||
group: '4_import_export_profiles',
|
||||
when: ContextKeyExpr.and(PROFILES_ENABLEMENT_CONTEXT, CONTEXT_ENABLE_NEW_PROFILES_UI.negate()),
|
||||
order: 2
|
||||
}, {
|
||||
id: MenuId.CommandPalette,
|
||||
when: PROFILES_ENABLEMENT_CONTEXT,
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -454,6 +576,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
}
|
||||
|
||||
private registerCreateProfileAction(): void {
|
||||
const that = this;
|
||||
this._register(registerAction2(class CreateProfileAction extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
|
@ -462,13 +585,23 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
category: PROFILES_CATEGORY,
|
||||
precondition: PROFILES_ENABLEMENT_CONTEXT,
|
||||
f1: true,
|
||||
menu: [
|
||||
{
|
||||
id: ProfilesMenu,
|
||||
group: '3_manage_profiles',
|
||||
when: ContextKeyExpr.and(PROFILES_ENABLEMENT_CONTEXT, CONTEXT_ENABLE_NEW_PROFILES_UI.negate()),
|
||||
order: 1
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
async run(accessor: ServicesAccessor) {
|
||||
const editorGroupsService = accessor.get(IEditorGroupsService);
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
return editorGroupsService.activeGroup.openEditor(new UserDataProfilesEditorInput(instantiationService));
|
||||
if (that.isNewProfilesUIEnabled()) {
|
||||
return that.openProfilesEditor();
|
||||
} else {
|
||||
return that.userDataProfileImportExportService.createProfile();
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@ -482,6 +615,14 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
|||
category: PROFILES_CATEGORY,
|
||||
f1: true,
|
||||
precondition: ContextKeyExpr.and(PROFILES_ENABLEMENT_CONTEXT, HAS_PROFILES_CONTEXT),
|
||||
menu: [
|
||||
{
|
||||
id: ProfilesMenu,
|
||||
group: '3_manage_profiles',
|
||||
when: ContextKeyExpr.and(PROFILES_ENABLEMENT_CONTEXT, CONTEXT_ENABLE_NEW_PROFILES_UI.negate()),
|
||||
order: 2
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
|||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import type { IHoverWidget } from 'vs/base/browser/ui/hover/hover';
|
||||
import { IAccessibleViewInformationService } from 'vs/workbench/services/accessibility/common/accessibleViewInformationService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
interface IUserDataProfileTemplate {
|
||||
readonly name: string;
|
||||
|
@ -103,6 +104,7 @@ function isUserDataProfileTemplate(thing: unknown): thing is IUserDataProfileTem
|
|||
&& (isUndefined(candidate.extensions) || typeof candidate.extensions === 'string'));
|
||||
}
|
||||
|
||||
const EXPORT_PROFILE_PREVIEW_VIEW = 'workbench.views.profiles.export.preview';
|
||||
const IMPORT_PROFILE_PREVIEW_VIEW = 'workbench.views.profiles.import.preview';
|
||||
|
||||
export class UserDataProfileImportExportService extends Disposable implements IUserDataProfileImportExportService, IURLHandler {
|
||||
|
@ -141,6 +143,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU
|
|||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IContextViewService private readonly contextViewService: IContextViewService,
|
||||
@IHoverService private readonly hoverService: IHoverService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
) {
|
||||
super();
|
||||
this.registerProfileContentHandler(Schemas.file, this.fileUserDataProfileContentHandler = instantiationService.createInstance(FileUserDataProfileContentHandler));
|
||||
|
@ -190,6 +193,15 @@ export class UserDataProfileImportExportService extends Disposable implements IU
|
|||
this.profileContentHandlers.delete(id);
|
||||
}
|
||||
|
||||
async exportProfile2(): Promise<void> {
|
||||
if (this.isProfileExportInProgressContextKey.get()) {
|
||||
this.logService.warn('Profile export already in progress.');
|
||||
return;
|
||||
}
|
||||
|
||||
return this.showProfileContents();
|
||||
}
|
||||
|
||||
async importProfile(uri: URI, options?: IProfileImportOptions): Promise<void> {
|
||||
if (this.isProfileImportInProgressContextKey.get()) {
|
||||
this.notificationService.warn('Profile import already in progress.');
|
||||
|
@ -226,6 +238,10 @@ export class UserDataProfileImportExportService extends Disposable implements IU
|
|||
return this.saveProfile(undefined, from);
|
||||
}
|
||||
|
||||
editProfile(profile: IUserDataProfile): Promise<void> {
|
||||
return this.saveProfile(profile);
|
||||
}
|
||||
|
||||
async createFromProfile(from: IUserDataProfile, options: IUserDataProfileCreateOptions, token: CancellationToken): Promise<IUserDataProfile | undefined> {
|
||||
const disposables = new DisposableStore();
|
||||
let creationPromise: CancelablePromise<void>;
|
||||
|
@ -643,6 +659,36 @@ export class UserDataProfileImportExportService extends Disposable implements IU
|
|||
}
|
||||
}
|
||||
|
||||
async showProfileContents(): Promise<void> {
|
||||
const view = this.viewsService.getViewWithId(EXPORT_PROFILE_PREVIEW_VIEW);
|
||||
if (view) {
|
||||
this.viewsService.openView(view.id, true);
|
||||
return;
|
||||
}
|
||||
const disposables = new DisposableStore();
|
||||
try {
|
||||
const userDataProfilesExportState = disposables.add(this.instantiationService.createInstance(UserDataProfileExportState, this.userDataProfileService.currentProfile, undefined));
|
||||
const barrier = new Barrier();
|
||||
const exportAction = new BarrierAction(barrier, new Action('export', localize('export', "Export"), undefined, true, async () => {
|
||||
exportAction.enabled = false;
|
||||
try {
|
||||
await this.doExportProfile(userDataProfilesExportState, EXPORT_PROFILE_PREVIEW_VIEW);
|
||||
} catch (error) {
|
||||
exportAction.enabled = true;
|
||||
this.notificationService.error(error);
|
||||
throw error;
|
||||
}
|
||||
}), this.notificationService);
|
||||
const closeAction = new BarrierAction(barrier, new Action('close', localize('close', "Close")), this.notificationService);
|
||||
await this.showProfilePreviewView(EXPORT_PROFILE_PREVIEW_VIEW, userDataProfilesExportState.profile.name, exportAction, closeAction, true, userDataProfilesExportState);
|
||||
disposables.add(this.userDataProfileService.onDidChangeCurrentProfile(e => barrier.open()));
|
||||
await barrier.wait();
|
||||
await this.hideProfilePreviewView(EXPORT_PROFILE_PREVIEW_VIEW);
|
||||
} finally {
|
||||
disposables.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
async exportProfile(profile: IUserDataProfile): Promise<void> {
|
||||
const disposables = new DisposableStore();
|
||||
try {
|
||||
|
|
|
@ -101,8 +101,11 @@ export interface IUserDataProfileImportExportService {
|
|||
|
||||
resolveProfileTemplate(uri: URI): Promise<IUserDataProfileTemplate | null>;
|
||||
exportProfile(profile: IUserDataProfile): Promise<void>;
|
||||
exportProfile2(): Promise<void>;
|
||||
importProfile(uri: URI, options?: IProfileImportOptions): Promise<void>;
|
||||
showProfileContents(): Promise<void>;
|
||||
createProfile(from?: IUserDataProfile | URI): Promise<void>;
|
||||
editProfile(profile: IUserDataProfile): Promise<void>;
|
||||
createFromProfile(from: IUserDataProfile, options: IUserDataProfileCreateOptions, token: CancellationToken): Promise<IUserDataProfile | undefined>;
|
||||
createProfileFromTemplate(profileTemplate: IUserDataProfileTemplate, options: IUserDataProfileCreateOptions, token: CancellationToken): Promise<IUserDataProfile | undefined>;
|
||||
createTroubleshootProfile(): Promise<void>;
|
||||
|
|
Loading…
Reference in a new issue