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

Use issue reporter for settings search #43274

Merged
merged 7 commits into from
Feb 10, 2018
130 changes: 112 additions & 18 deletions src/vs/code/electron-browser/issue/issueReporterMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { localize } from 'vs/nls';
import { $ } from 'vs/base/browser/dom';
import * as collections from 'vs/base/common/collections';
import * as browser from 'vs/base/browser/browser';
import { escape } from 'vs/base/common/strings';
import product from 'vs/platform/node/product';
import pkg from 'vs/platform/node/package';
import * as os from 'os';
Expand All @@ -30,7 +31,7 @@ import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProper
import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc';
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import { IssueReporterModel } from 'vs/code/electron-browser/issue/issueReporterModel';
import { IssueReporterData, IssueReporterStyles, IssueType } from 'vs/platform/issue/common/issue';
import { IssueReporterData, IssueReporterStyles, IssueType, ISettingsSearchIssueReporterData } from 'vs/platform/issue/common/issue';
import BaseHtml from 'vs/code/electron-browser/issue/issueReporterPage';
import { ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
import { debounce } from 'vs/base/common/decorators';
Expand Down Expand Up @@ -67,7 +68,8 @@ export class IssueReporter extends Disposable {
includeSystemInfo: true,
includeWorkspaceInfo: true,
includeProcessInfo: true,
includeExtensions: true,
includeSearchedExtensions: true,
includeSettingsSearchDetails: true,
versionInfo: {
vscodeVersion: `${pkg.name} ${pkg.version} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'})`,
os: `${os.type()} ${os.arch()} ${os.release()}`
Expand Down Expand Up @@ -101,14 +103,18 @@ export class IssueReporter extends Disposable {
show(document.getElementById('english'));
}

this.setUpTypes();
this.setEventHandlers();
this.applyZoom(configuration.data.zoomLevel);
this.applyStyles(configuration.data.styles);
this.handleExtensionData(configuration.data.enabledExtensions);

if (configuration.data.issueType === IssueType.SettingsSearchIssue) {
this.handleSettingsSearchData(<ISettingsSearchIssueReporterData>configuration.data);
}
}

render(): void {
(<HTMLSelectElement>document.getElementById('issue-type')).value = this.issueReporterModel.getData().issueType.toString();
this.renderBlocks();
}

Expand Down Expand Up @@ -203,6 +209,46 @@ export class IssueReporter extends Disposable {
}
}

private handleSettingsSearchData(data: ISettingsSearchIssueReporterData): void {
this.issueReporterModel.update({
actualSearchResults: data.actualSearchResults,
query: data.query,
filterResultCount: data.filterResultCount
});
this.updateSearchedExtensionTable(data.enabledExtensions);
this.updateSettingsSearchDetails(data);
}

private updateSettingsSearchDetails(data: ISettingsSearchIssueReporterData): void {
const target = document.querySelector('.block-settingsSearchResults .block-info');

const details = `
<div class='block-settingsSearchResults-details'>
<div>Query: "${data.query}"</div>
<div>Literal match count: ${data.filterResultCount}</div>
</div>
`;

let table = `
<tr>
<th>Setting</th>
<th>Extension</th>
<th>Score</th>
</tr>`;

data.actualSearchResults
.forEach(setting => {
table += `
<tr>
<td>${setting.key}</td>
<td>${setting.extensionId}</td>
<td>${String(setting.score).slice(0, 5)}</td>
</tr>`;
});

target.innerHTML = `${details}<table>${table}</table>`;
}

private initServices(configuration: IWindowConfiguration): void {
const serviceCollection = new ServiceCollection();
const mainProcessClient = new ElectronIPCClient(String(`window${configuration.windowId}`));
Expand Down Expand Up @@ -238,7 +284,7 @@ export class IssueReporter extends Disposable {
this.render();
});

['includeSystemInfo', 'includeProcessInfo', 'includeWorkspaceInfo', 'includeExtensions'].forEach(elementId => {
['includeSystemInfo', 'includeProcessInfo', 'includeWorkspaceInfo', 'includeExtensions', 'includeSearchedExtensions', 'includeSettingsSearchDetails'].forEach(elementId => {
document.getElementById(elementId).addEventListener('click', (event: Event) => {
event.stopPropagation();
this.issueReporterModel.update({ [elementId]: !this.issueReporterModel.getData()[elementId] });
Expand Down Expand Up @@ -351,6 +397,10 @@ export class IssueReporter extends Disposable {
return true;
}

if (issueType === IssueType.SettingsSearchIssue) {
return true;
}

return false;
}

Expand Down Expand Up @@ -425,23 +475,50 @@ export class IssueReporter extends Disposable {
this.telemetryService.publicLog('issueReporterSearchError', { message: error.message });
}

private setUpTypes(): void {
const makeOption = (issueType: IssueType, description: string) => `<option value="${issueType.valueOf()}">${escape(description)}</option>`;

const typeSelect = (<HTMLSelectElement>document.getElementById('issue-type'));
const { issueType } = this.issueReporterModel.getData();
if (issueType === IssueType.SettingsSearchIssue) {
typeSelect.innerHTML = makeOption(IssueType.SettingsSearchIssue, localize('settingsSearchIssue', "Settings Search Issue"));
typeSelect.disabled = true;
} else {
typeSelect.innerHTML = [
makeOption(IssueType.Bug, localize('bugReporter', "Bug Report")),
makeOption(IssueType.PerformanceIssue, localize('performanceIssue', "Performance Issue")),
makeOption(IssueType.FeatureRequest, localize('featureRequest', "Feature Request"))
].join('\n');
}

typeSelect.value = issueType.toString();
}

private renderBlocks(): void {
// Depending on Issue Type, we render different blocks and text
const { issueType } = this.issueReporterModel.getData();
const systemBlock = document.querySelector('.block-system');
const processBlock = document.querySelector('.block-process');
const workspaceBlock = document.querySelector('.block-workspace');
const extensionsBlock = document.querySelector('.block-extensions');
const disabledExtensions = document.getElementById('disabledExtensions');
const searchedExtensionsBlock = document.querySelector('.block-searchedExtensions');
const settingsSearchResultsBlock = document.querySelector('.block-settingsSearchResults');

const disabledExtensions = document.getElementById('disabledExtensions');
const descriptionTitle = document.getElementById('issue-description-label');
const descriptionSubtitle = document.getElementById('issue-description-subtitle');

// Hide all by default
hide(systemBlock);
hide(processBlock);
hide(workspaceBlock);
hide(extensionsBlock);
hide(searchedExtensionsBlock);
hide(settingsSearchResultsBlock);
hide(disabledExtensions);

if (issueType === IssueType.Bug) {
show(systemBlock);
hide(processBlock);
hide(workspaceBlock);
show(extensionsBlock);
show(disabledExtensions);

Expand All @@ -456,15 +533,15 @@ export class IssueReporter extends Disposable {

descriptionTitle.innerHTML = `${localize('stepsToReproduce', "Steps to Reproduce")} <span class="required-input">*</span>`;
descriptionSubtitle.innerHTML = localize('performanceIssueDesciption', "When did this performance issue happen? Does it occur on startup or after a specific series of actions? We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
} else {
hide(systemBlock);
hide(processBlock);
hide(workspaceBlock);
hide(extensionsBlock);
hide(disabledExtensions);

} else if (issueType === IssueType.FeatureRequest) {
descriptionTitle.innerHTML = `${localize('description', "Description")} <span class="required-input">*</span>`;
descriptionSubtitle.innerHTML = localize('featureRequestDescription', "Please describe the feature you would like to see. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
} else if (issueType === IssueType.SettingsSearchIssue) {
show(searchedExtensionsBlock);
show(settingsSearchResultsBlock);

descriptionTitle.innerHTML = `${localize('expectedResults', "Expected Results")} <span class="required-input">*</span>`;
descriptionSubtitle.innerHTML = localize('settingsSearchResultsDescription', "Please list the results that you were expecting to see when you searched with this query. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
}
}

Expand Down Expand Up @@ -591,23 +668,40 @@ export class IssueReporter extends Disposable {
return;
}

const table = this.getExtensionTableHtml(extensions);
target.innerHTML = `<table>${table}</table>${themeExclusionStr}`;
}

private updateSearchedExtensionTable(extensions: ILocalExtension[]): void {
const target = document.querySelector('.block-searchedExtensions .block-info');

if (!extensions.length) {
target.innerHTML = 'Extensions: none';
return;
}

const table = this.getExtensionTableHtml(extensions);
target.innerHTML = `<table>${table}</table>`;
}

private getExtensionTableHtml(extensions: ILocalExtension[]): string {
let table = `
<tr>
<th>Extension</th>
<th>Author (truncated)</th>
<th>Version</th>
</tr>`;

extensions.forEach(extension => {
table += `
table += extensions.map(extension => {
return `
<tr>
<td>${extension.manifest.name}</td>
<td>${extension.manifest.publisher.substr(0, 3)}</td>
<td>${extension.manifest.version}</td>
</tr>`;
});
}).join('');

target.innerHTML = `<table>${table}</table>${themeExclusionStr}`;
return table;
}
}

Expand Down
47 changes: 46 additions & 1 deletion src/vs/code/electron-browser/issue/issueReporterModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { assign } from 'vs/base/common/objects';
import { ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IssueType } from 'vs/platform/issue/common/issue';
import { IssueType, ISettingSearchResult } from 'vs/platform/issue/common/issue';

export interface IssueReporterData {
issueType?: IssueType;
Expand All @@ -22,11 +22,16 @@ export interface IssueReporterData {
includeWorkspaceInfo?: boolean;
includeProcessInfo?: boolean;
includeExtensions?: boolean;
includeSearchedExtensions?: boolean;
includeSettingsSearchDetails?: boolean;

numberOfThemeExtesions?: number;
enabledNonThemeExtesions?: ILocalExtension[];
extensionsDisabled?: boolean;
reprosWithoutExtensions?: boolean;
actualSearchResults?: ISettingSearchResult[];
query?: string;
filterResultCount?: number;
}

export class IssueReporterModel {
Expand Down Expand Up @@ -99,6 +104,17 @@ ${this.getInfos()}`;
info += this._data.reprosWithoutExtensions ? '\nReproduces without extensions' : '\nReproduces only with extensions';
}

if (this._data.issueType === IssueType.SettingsSearchIssue) {
if (this._data.includeSearchedExtensions) {
info += this.generateExtensionsMd();
}

if (this._data.includeSettingsSearchDetails) {
info += this.generateSettingSearchResultsMd();
info += '\n' + this.generateSettingsSearchResultDetailsMd();
}
}

return info;
}

Expand Down Expand Up @@ -171,6 +187,35 @@ ${tableHeader}
${table}
${themeExclusionStr}

</details>`;
}

private generateSettingsSearchResultDetailsMd(): string {
return `
Query: ${this._data.query}
Literal matches: ${this._data.filterResultCount}`;
}

private generateSettingSearchResultsMd(): string {
if (!this._data.actualSearchResults) {
return '';
}

if (!this._data.actualSearchResults.length) {
return `No fuzzy results`;
}

let tableHeader = `Setting|Extension|Score
---|---|---`;
const table = this._data.actualSearchResults.map(setting => {
return `${setting.key}|${setting.extensionId}|${String(setting.score).slice(0, 5)}`;
}).join('\n');

return `<details><summary>Results</summary>

${tableHeader}
${table}

</details>`;
}
}
30 changes: 27 additions & 3 deletions src/vs/code/electron-browser/issue/issueReporterPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ export default (): string => `
<div class="input-group">
<label id="issue-type-label" class="inline-form-control" for="issue-type">${escape(localize('issueTypeLabel', "This is a"))}</label>
<select id="issue-type" class="inline-form-control">
<option value="0">${escape(localize('bugReporter', "Bug Report"))}</option>
<option value="1">${escape(localize('performanceIssue', "Performance Issue"))}</option>
<option value="2">${escape(localize('featureRequest', "Feature Request"))}</option>
<!-- To be dynamically filled -->
</select>
</div>

Expand Down Expand Up @@ -86,6 +84,32 @@ export default (): string => `
</div>
</details>
</div>
<div class="block block-searchedExtensions">
<details>
<summary>${escape(localize('searchedExtensions', "Searched Extensions"))}
<div class="include-data">
<input class="sendData" type="checkbox" id="includeSearchedExtensions" checked/>
<label class="caption" for="includeSearchedExtensions">${escape(localize('sendData', "Send my data"))}</label>
</div>
</summary>
<div class="block-info">
<!-- To be dynamically filled -->
</div>
</details>
</div>
<div class="block block-settingsSearchResults">
<details>
<summary>${escape(localize('settingsSearchDetails', "Settings Search Details"))}
<div class="include-data">
<input class="sendData" type="checkbox" id="includeSettingsSearchDetails" checked/>
<label class="caption" for="includeSettingsSearchDetails">${escape(localize('sendData', "Send my data"))}</label>
</div>
</summary>
<div class="block-info">
<!-- To be dynamically filled -->
</div>
</details>
</div>
</div>
</div>

Expand Down
8 changes: 8 additions & 0 deletions src/vs/code/electron-browser/issue/media/issueReporter.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ td {
border-top: 1px solid #e9ecef;
}

.block-settingsSearchResults-details {
padding-bottom: .5rem;
}

.block-settingsSearchResults-details > div {
padding: .5rem .75rem;
}

.section {
margin-bottom: 1.5em;
}
Expand Down