Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 59 additions & 40 deletions src/vs/workbench/contrib/issue/browser/baseIssueReporterService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ export class BaseIssueReporterService extends Disposable {
public selectedExtension = '';
public delayedSubmit = new Delayer<void>(300);
public publicGithubButton!: Button | ButtonWithDropdown;
public internalGithubButton!: Button | ButtonWithDropdown;
private publicGithubSingle?: Button; // simple button reused for ack/create/preview
private publicGithubDropdown?: ButtonWithDropdown; // dropdown variant (create + preview)
private publicGithubSingleClickDisposable?: { dispose(): void };
public internalGithubButton!: Button;
public nonGitHubIssueUrl = false;
public needsUpdate = false;
public acknowledged = false;
Expand Down Expand Up @@ -218,7 +221,6 @@ export class BaseIssueReporterService extends Disposable {
return;
}


// public elements section
let publicElements = this.getElementById('public-elements');
if (!publicElements) {
Expand Down Expand Up @@ -270,48 +272,66 @@ export class BaseIssueReporterService extends Disposable {
return;
}

// Dispose of the existing button
if (this.publicGithubButton) {
this.publicGithubButton.dispose();
}
// Desired logical variant
const needsAck = !this.acknowledged && this.needsUpdate;
const wantDropdown = !!this.data.githubAccessToken && this.isPreviewEnabled();
const wanted: 'ack' | 'dropdown' | 'create' | 'preview' = needsAck ? 'ack' : (wantDropdown ? 'dropdown' : (this.data.githubAccessToken ? 'create' : 'preview'));

// setup button + dropdown if applicable
if (!this.acknowledged && this.needsUpdate) { // * old version and hasn't ack'd
this.publicGithubButton = this._register(new Button(container, unthemedButtonStyles));
this.publicGithubButton.label = localize('acknowledge', "Confirm Version Acknowledgement");
this.publicGithubButton.enabled = false;
} else if (this.data.githubAccessToken && this.isPreviewEnabled()) { // * has access token, create by default, preview dropdown
this.publicGithubButton = this._register(new ButtonWithDropdown(container, {
// Lazy instantiate both physical controls once and reuse
if (!this.publicGithubSingle) {
this.publicGithubSingle = this._register(new Button(container, unthemedButtonStyles));
}
if (!this.publicGithubDropdown) {
this.publicGithubDropdown = this._register(new ButtonWithDropdown(container, {
contextMenuProvider: this.contextMenuService,
actions: [this.previewAction],
addPrimaryActionToDropdown: false,
...unthemedButtonStyles
}));
this._register(this.publicGithubButton.onDidClick(() => {
this.createAction.run();
}));
this.publicGithubButton.label = localize('createOnGitHub', "Create on GitHub");
this.publicGithubButton.enabled = true;
} else if (this.data.githubAccessToken && !this.isPreviewEnabled()) { // * Access token but invalid preview state: simple Button (create only)
this.publicGithubButton = this._register(new Button(container, unthemedButtonStyles));
this._register(this.publicGithubButton.onDidClick(() => {
this.createAction.run();
}));
this.publicGithubButton.label = localize('createOnGitHub', "Create on GitHub");
this.publicGithubButton.enabled = true;
} else { // * No access token: simple Button (preview only)
this.publicGithubButton = this._register(new Button(container, unthemedButtonStyles));
this._register(this.publicGithubButton.onDidClick(() => {
this.previewAction.run();
}));
this.publicGithubButton.label = localize('previewOnGitHub', "Preview on GitHub");
this.publicGithubButton.enabled = true;
this._register(this.publicGithubDropdown.onDidClick(() => this.createAction.run()));
}

// make sure that the repo link is after the button
// Maintain ordering before repo link if present
const repoLink = this.getElementById('show-repo-name');
if (repoLink) {
container.insertBefore(this.publicGithubButton.element, repoLink);
if (this.publicGithubDropdown.element.compareDocumentPosition(repoLink) & Node.DOCUMENT_POSITION_FOLLOWING) {
container.insertBefore(this.publicGithubDropdown.element, repoLink);
}
if (this.publicGithubSingle.element.compareDocumentPosition(repoLink) & Node.DOCUMENT_POSITION_FOLLOWING) {
container.insertBefore(this.publicGithubSingle.element, repoLink);
}
}

// Hide both then show target
this.publicGithubSingle.element.style.display = 'none';
this.publicGithubDropdown.element.style.display = 'none';

if (wanted === 'dropdown') {
this.publicGithubDropdown.label = localize('createOnGitHub', "Create on GitHub");
this.publicGithubDropdown.enabled = true;
this.publicGithubDropdown.element.style.display = '';
this.publicGithubButton = this.publicGithubDropdown;
} else {
// Rebind single button click as needed
if (this.publicGithubSingleClickDisposable) {
this.publicGithubSingleClickDisposable.dispose();
this.publicGithubSingleClickDisposable = undefined;
}

if (wanted === 'ack') {
this.publicGithubSingle.label = localize('acknowledge', "Confirm Version Acknowledgement");
this.publicGithubSingle.enabled = false;
} else if (wanted === 'create') {
this.publicGithubSingle.label = localize('createOnGitHub', "Create on GitHub");
this.publicGithubSingle.enabled = true;
this.publicGithubSingleClickDisposable = this._register(this.publicGithubSingle.onDidClick(() => this.createAction.run()));
} else { // preview
this.publicGithubSingle.label = localize('previewOnGitHub', "Preview on GitHub");
this.publicGithubSingle.enabled = true;
this.publicGithubSingleClickDisposable = this._register(this.publicGithubSingle.onDidClick(() => this.previewAction.run()));
}
this.publicGithubSingle.element.style.display = '';
this.publicGithubButton = this.publicGithubSingle;
}
}

Expand Down Expand Up @@ -355,12 +375,8 @@ export class BaseIssueReporterService extends Disposable {
return;
}

// Dispose of the existing button
if (this.internalGithubButton) {
this.internalGithubButton.dispose();
}

if (this.data.githubAccessToken && this.data.privateUri) {
// create button if not already created.
if (!this.internalGithubButton) {
this.internalGithubButton = this._register(new Button(container, unthemedButtonStyles));
this._register(this.internalGithubButton.onDidClick(() => {
this.privateAction.run();
Expand All @@ -369,6 +385,9 @@ export class BaseIssueReporterService extends Disposable {
this.internalGithubButton.element.id = 'internal-create-btn';
this.internalGithubButton.element.classList.add('internal-create-subtle');
this.internalGithubButton.label = localize('createInternally', "Create Internally");
}

if (this.data.githubAccessToken && this.data.privateUri) {
this.internalGithubButton.enabled = true;
this.internalGithubButton.setTitle(this.data.privateUri.path!.slice(1));
}
Expand Down
72 changes: 72 additions & 0 deletions src/vs/workbench/contrib/issue/browser/issue.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,24 @@ import { CommandsRegistry } from '../../../../platform/commands/common/commands.
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from '../../../../platform/configuration/common/configurationRegistry.js';
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { IProductService } from '../../../../platform/product/common/productService.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
import { EditorPaneDescriptor, IEditorPaneRegistry } from '../../../browser/editor.js';
import { Extensions, IWorkbenchContributionsRegistry } from '../../../common/contributions.js';
import { EditorExtensions, IEditorSerializer, IEditorFactoryRegistry } from '../../../common/editor.js';
import { EditorInput } from '../../../common/editor/editorInput.js';
import { IEditorResolverService, RegisteredEditorPriority } from '../../../services/editor/common/editorResolverService.js';
import { IssueFormService } from './issueFormService.js';
import { BrowserIssueService } from './issueService.js';
import './issueTroubleshoot.js';
import { IIssueFormService, IWorkbenchIssueService } from '../common/issue.js';
import { BaseIssueContribution } from '../common/issue.contribution.js';
import { LifecyclePhase } from '../../../services/lifecycle/common/lifecycle.js';
import { IssueReporterEditorInput } from './issueReporterEditorInput.js';
import { IssueReporterEditor } from './issueReporterEditor.js';
import { localize } from '../../../../nls.js';


class WebIssueContribution extends BaseIssueContribution {
Expand All @@ -39,6 +48,69 @@ Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench).registerWorkb
registerSingleton(IWorkbenchIssueService, BrowserIssueService, InstantiationType.Delayed);
registerSingleton(IIssueFormService, IssueFormService, InstantiationType.Delayed);

//#region --- issue reporter editor

class IssueReporterEditorContribution {

static readonly ID = 'workbench.contrib.issueReporterEditor';

constructor(
@IEditorResolverService editorResolverService: IEditorResolverService,
@IInstantiationService instantiationService: IInstantiationService
) {
editorResolverService.registerEditor(
`${IssueReporterEditorInput.RESOURCE.scheme}:**/**`,
{
id: IssueReporterEditorInput.ID,
label: localize('promptOpenWith.issueReporter.displayName', "Issue Reporter"),
priority: RegisteredEditorPriority.exclusive
},
{
singlePerResource: true,
canSupportResource: resource => resource.scheme === IssueReporterEditorInput.RESOURCE.scheme
},
{
createEditorInput: () => {
return {
editor: IssueReporterEditorInput.instance,
options: {
pinned: true
}
};
}
}
);
}
}

Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench).registerWorkbenchContribution(IssueReporterEditorContribution, LifecyclePhase.Restored);

// Register the editor pane
Registry.as<IEditorPaneRegistry>(EditorExtensions.EditorPane).registerEditorPane(
EditorPaneDescriptor.create(IssueReporterEditor, IssueReporterEditor.ID, localize('issueReporter', "Issue Reporter")),
[new SyncDescriptor(IssueReporterEditorInput)]
);

// Register editor serializer
class IssueReporterEditorInputSerializer implements IEditorSerializer {

canSerialize(editorInput: EditorInput): boolean {
return true;
}

serialize(editorInput: EditorInput): string {
return '';
}

deserialize(instantiationService: IInstantiationService): EditorInput {
return IssueReporterEditorInput.instance;
}
}

Registry.as<IEditorFactoryRegistry>(EditorExtensions.EditorFactory).registerEditorSerializer(IssueReporterEditorInput.ID, IssueReporterEditorInputSerializer);

//#endregion

CommandsRegistry.registerCommand('_issues.getSystemStatus', (accessor) => {
return nls.localize('statusUnsupported', "The --status argument is not yet supported in browsers.");
});
Loading
Loading