Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to ignore recommendations both globally and at a per-workspace level #51941

Merged

Conversation

JacksonKearl
Copy link
Contributor

@JacksonKearl JacksonKearl commented Jun 14, 2018

Resolves #48743.

Copy link
Contributor

@ramya-rao-a ramya-rao-a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Phase 1 is done. I'll get back to this in an hr.

@@ -74,6 +74,7 @@ export const IExtensionsWorkbenchService = createDecorator<IExtensionsWorkbenchS
export interface IExtensionsWorkbenchService {
_serviceBrand: any;
onChange: Event<void>;
onRecommendationChange: Event<void>;

This comment was marked as resolved.

data.root.setAttribute('aria-label', extension.displayName + '. ' + extRecommendations[extension.id]);
data.root.title = extRecommendations[extension.id.toLowerCase()].reasonText;
addClass(data.root, 'recommended');
}

This comment was marked as resolved.

@@ -16,7 +16,16 @@ export const ExtensionsConfigurationSchema: IJSONSchema = {
properties: {
recommendations: {
type: 'array',
description: localize('app.extensions.json.recommendations', "List of extensions recommendations. The identifier of an extension is always '${publisher}.${name}'. For example: 'vscode.csharp'."),
description: localize('app.extensions.json.recommendations', "List of extensions which should be recommended for users of this repository. The identifier of an extension is always '${publisher}.${name}'. For example: 'vscode.csharp'."),

This comment was marked as resolved.

},
unwantedRecommendations: {
type: 'array',
description: localize('app.extensions.json.unwantedRecommendations', "List of extensions which are irrelevant, redundant, or otherwise unwanted, and should not be recommended for users of this repository. The identifier of an extension is always '${publisher}.${name}'. For example: 'vscode.csharp'."),

This comment was marked as resolved.

@@ -544,6 +544,37 @@ export class EnableGloballyAction extends Action implements IExtensionAction {
}
}

export class IgnoreAction extends Action {

This comment was marked as resolved.

@@ -369,6 +392,22 @@ export class ExtensionEditor extends BaseEditor {
this.extensionActionBar.push([disabledStatusAction, reloadAction, updateAction, enableAction, disableAction, installAction, maliciousStatusAction], { icon: true, label: true });
this.transientDisposables.push(enableAction, updateAction, reloadAction, disableAction, installAction, maliciousStatusAction, disabledStatusAction);

const ignoreAction = this.instantiationService.createInstance(IgnoreAction);
ignoreAction.extension = extension;
ignoreAction.onIgnored = () => {

This comment was marked as resolved.

this.recommendationText.textContent = localize('recommendationHasBeenIgnoredGlobal', "You have chosen not to receive recommendations for this extension.");
}
if (ignoredRecommendations.workspace.indexOf(extension.id.toLowerCase()) !== -1) {
this.recommendationText.textContent = localize('recommendationHasBeenIgnoredWorkspace', "This extension has been marked as redundant or irrelevant by users of the current workspace.");

This comment was marked as resolved.

This comment was marked as resolved.

recommendations: string[];
unwantedRecommendations: string[];
}

This comment was marked as resolved.

@@ -374,6 +384,8 @@ export interface IExtensionTipsService {
getKeymapRecommendations(): string[];
getKeywordsForExtension(extension: string): string[];
getRecommendationsForExtension(extension: string): string[];
refreshAllIgnoredRecommendations(): TPromise<void>;
getAllIgnoredRecommendations(): IIgnoredRecommendations;

This comment was marked as resolved.

const ignoredRecommendations = this.extensionTipsService.getAllIgnoredRecommendations();

toggleClass(this.header, 'ignored', this.recentlyIgnored.indexOf(extension.id.toLowerCase()) !== -1 || ignoredRecommendations.workspace.indexOf(extension.id.toLowerCase()) !== -1);
if (this.recentlyIgnored.indexOf(extension.id.toLowerCase()) !== -1) {

This comment was marked as resolved.

*/
this.telemetryService.publicLog('extensionGallery:openExtension', assign(extension.telemetryData, recommendationsData));

const ignoredRecommendations = this.extensionTipsService.getAllIgnoredRecommendations();

toggleClass(this.header, 'ignored', this.recentlyIgnored.indexOf(extension.id.toLowerCase()) !== -1 || ignoredRecommendations.workspace.indexOf(extension.id.toLowerCase()) !== -1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to add the ignored class?
From what I can see in the css file, its used in the same situation where the recommended label is used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It stylizes the text differently and removes the ignore button

return cleansedIDs;
}

refreshAllIgnoredRecommendations(): TPromise<void> {

This comment was marked as resolved.

});

this._exeBasedRecommendations = filteredExeBased;
this._fileBasedRecommendations = filteredFileBased;

This comment was marked as resolved.

'\t\t',
'\t],',
'\t"unwantedRecommendations": [',
'\t\t// List of extensions which should not be recommended for users of this workspace. These extensions may be irrelevant, redundant, or otherwise unwanted.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A literal translation of this would mean that we are asking users to list ALL the extensions that they would consider irrelevant/redundant etc.

How about..

List of extensions that will be skipped from the recommendations that VS Code makes for the users of this workspace... ?

@@ -295,24 +306,25 @@ export class ExtensionEditor extends BaseEditor {
this.publisher.textContent = extension.publisherDisplayName;
this.description.textContent = extension.description;

removeClass(this.header, 'ignored');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignored can be recommendationIgnored?

.then(contents => this.processConfigContent(this.mergeExtensionRecommendationConfigs(flatten(contents))));
}

private resolveWorkspaceExtensionConfig(workspace: IWorkspace): TPromise<IExtensionsConfigContent[]> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are both resolveWorkspaceExtensionConfig and resolveWorkspaceFolderExtensionConfig returning array of IExtensionsConfigContent? They both work on individual files... and so wouldn't the output be just `TPromise< IExtensionsConfigContent>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it back to maybe being represented by empty array or array of one rather than merging all over the place. what do you think?

private fetchCombinedExtensionRecommendationConfig(): TPromise<IExtensionsConfigContent> {
const workspace = this.contextService.getWorkspace();
return TPromise.join([this.resolveWorkspaceExtensionConfig(workspace), ...workspace.folders.map(workspaceFolder => this.resolveWorkspaceFolderExtensionConfig(workspaceFolder))])
.then(contents => this.processConfigContent(this.mergeExtensionRecommendationConfigs(flatten(contents))));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like now, this is the only place from where we call mergeExtensionRecommendationConfigs, in which case, how about merging its code into processConfigContent?

@@ -555,86 +636,84 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
});
}

private _suggestWorkspaceRecommendations(): TPromise<any> {
private _suggestWorkspaceRecommendations(allRecommendations: string[]): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this parameter need to be passed in? Can we not use this._allWorkspaceRecommendedExtensions directly?

@ramya-rao-a ramya-rao-a merged commit 442e5e2 into microsoft:master Jun 19, 2018
@github-actions github-actions bot locked and limited conversation to collaborators Mar 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow hiding some recommended extensions
3 participants