Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #514 from safing/feature/support-form
Browse files Browse the repository at this point in the history
Improve UX for support form. Show full country name on hover
  • Loading branch information
dhaavi authored Mar 15, 2024
2 parents c6cf99e + fb0732d commit 0ff05f3
Show file tree
Hide file tree
Showing 10 changed files with 417 additions and 87 deletions.
4 changes: 3 additions & 1 deletion modules/portmaster/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import { PlaceholderComponent } from './shared/text-placeholder';
import { DashboardWidgetComponent } from './pages/dashboard/dashboard-widget/dashboard-widget.component';
import { MergeProfileDialogComponent } from './pages/app-view/merge-profile-dialog/merge-profile-dialog.component';
import { INTEGRATION_SERVICE, integrationServiceFactory } from './integration';
import { SupportProgressDialogComponent } from './pages/support/progress-dialog';

function loadAndSetLocaleInitializer(configService: ConfigService) {
return async function () {
Expand Down Expand Up @@ -158,7 +159,8 @@ const localeConfig = {
DashboardPageComponent,
DashboardWidgetComponent,
FeatureCardComponent,
MergeProfileDialogComponent
MergeProfileDialogComponent,
SupportProgressDialogComponent
],
imports: [
BrowserModule,
Expand Down
125 changes: 44 additions & 81 deletions modules/portmaster/src/app/pages/support/form/support-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { fadeInAnimation, fadeInListAnimation, moveInOutAnimation } from 'src/ap
import { FuzzySearchService } from 'src/app/shared/fuzzySearch';
import { SupportPage, supportTypes } from '../pages';
import { INTEGRATION_SERVICE } from 'src/app/integration';
import { SupportProgressDialogComponent, TicketData, TicketInfo } from '../progress-dialog';

@Component({
templateUrl: './support-form.html',
Expand Down Expand Up @@ -156,6 +157,46 @@ export class SupportFormComponent implements OnInit {
return valid;
}

createIssue(type: 'github' | 'private', genUrl?: boolean, email?: string) {
const ticketData: TicketData = {
repo: this.selectedRepo || '',
title: this.title,
debugInfo: this.debugData,
sections: this.page?.sections.map(section => ({
title: section.title,
body: this.form[section.title],
})) || [],
}

let issue: TicketInfo;

switch (type) {
case 'github':
issue = {
type: 'github',
generateUrl: genUrl || false,
preset: this.page!.ghIssuePreset || '',
...ticketData
};

break;

case 'private':
issue = {
type: 'private',
email: email,
...ticketData
}

break;
}

SupportProgressDialogComponent.open(this.dialog, issue)
.subscribe(() => {
this.sessionService.delete(this.page?.id || '');
});
}

createOnGithub(genUrl?: boolean) {
if (!this.validate()) {
return;
Expand All @@ -177,61 +218,13 @@ export class SupportFormComponent implements OnInit {
]
})
.onAction('openGithub', () => {
this.createOnGithub(true);
this.createIssue('github', true)
})
.onAction('createWithout', () => {
this.createOnGithub(false);
this.createIssue('github', false)
})
return;
}

let debugInfo: Observable<string> = this.supporthub.uploadText('debug-info', this.debugData);
if (!this.page?.includeDebugData) {
debugInfo = of('');
}

debugInfo
.pipe(
mergeMap(url => this.supporthub.createIssue(
this.selectedRepo,
this.page?.ghIssuePreset || '',
this.title,
this.page!.sections.map(section => ({
title: section.title,
body: this.form[section.title],
})),
url,
{ generateUrl: genUrl || false }
))
)
.subscribe({
next: url => {
this.sessionService.delete(this.page?.id || '');
const openUrl = () => {
this.integration.openExternal(url);
}

if (genUrl === true) {
openUrl();
return;
}

const opts: ConfirmDialogConfig = {
canCancel: false,
buttons: [{ id: '', text: 'Close', class: 'outline' }, { id: 'open', text: 'Open Issue' }],
caption: 'Info',
header: 'Issue Created!',
message: 'We successfully created the issue on Github for you. Use the following link to check for updates: ' + url,
}
this.dialog.confirm(opts)
.onAction('open', () => {
openUrl();
})
},
error: err => {
this.uai.error('Failed to create issue', this.uai.getErrorMessgae(err))
}
})
}

openIssue(issue: Issue) {
Expand All @@ -258,37 +251,7 @@ export class SupportFormComponent implements OnInit {
}
this.dialog.confirm(opts)
.onAction('create', () => {
let debugInfo: Observable<string> = this.supporthub.uploadText('debug-info', this.debugData);
if (!this.page?.includeDebugData) {
debugInfo = of('');
}

debugInfo
.pipe(
mergeMap(url => this.supporthub.createTicket(
this.selectedRepo,
this.title,
opts.inputModel || '',
this.page!.sections.map(section => ({
title: section.title,
body: this.form[section.title],
})),
url,
))
)
.subscribe({
next: () => {
let msg = '';
if (!!opts.inputModel) {
msg = 'You will be contacted as soon as possible';
}
this.uai.success('Ticket created successfully', msg)
this.sessionService.delete(this.page?.id || '');
},
error: err => {
this.uai.error('Failed to create ticket', this.uai.getErrorMessgae(err))
}
})
this.createIssue('private', undefined, opts.inputModel);
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './progress-dialog';
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<!-- Progress Indicator -->
<div *ngIf="state !== 'error' && state !== 'done'">

<caption class="text-xxs text-secondary">Status</caption>

<div class="flex flex-row gap-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
class="w-5 h-5 animate animate-spin">
<path stroke-linecap="round" stroke-linejoin="round"
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
</svg>

<div [ngSwitch]="state">
<!-- Uploading debug data -->
<ng-template ngSwitchCase="debug-info">
<span>Uploading debug data ....</span>
</ng-template>

<!-- Github Issue -->
<ng-template ngSwitchCase="create-issue">
<span>Creating GitHub issue ...</span>
</ng-template>

<!-- Private ticket -->
<ng-template ngSwitchCase="create-ticket">
<span>Creating private support ticket ...</span>
</ng-template>
</div>
</div>
</div>


<!-- Issue/ticket creation successfull -->
<ng-template [ngIf]="state === 'done'">
<span class="flex flex-row gap-2 items-center justify-start">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="0.75" stroke="currentColor"
class="text-green-300 w-10 h-10">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>

<span class="text-base text-primary">
<ng-template [ngIf]="dialogRef.data.type === 'github' && dialogRef.data.generateUrl">
Ticket prepared successfully
</ng-template>

<ng-template [ngIf]="dialogRef.data.type !== 'github' || !dialogRef.data.generateUrl">
Ticket created successfully!
</ng-template>
</span>
</span>

<div *ngIf="dialogRef.data.type === 'github' && dialogRef.data.generateUrl">
<span>Use the following button to open the pre-filled GitHub issue form:</span>

<br />

<div class="flex flex-row items-center justify-center p-4">
<button class="bg-blue" (click)="integration.openExternal(url)">Create Issue</button>
</div>
</div>

<div *ngIf="dialogRef.data.type === 'github' && !dialogRef.data.generateUrl" class="flex flex-col">
<span>
We successfully create the issue on GitHub for you.
<br />
Use the following link to check for updates:
</span>

<span class="inline-block w-full text-center mt-4 underline text-secondary"
(click)="integration.openExternal(url)">{{ url }}</span>
</div>

<span *ngIf="dialogRef.data.type === 'private' && dialogRef.data.email">
We will contact you as soon as possbile.
</span>
</ng-template>

<!-- An error occured -->
<div *ngIf="state === 'error'" class="flex flex-col gap-2">

<span class="flex flex-row gap-2 items-center justify-start">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="0.75" stroke="currentColor"
class="text-red-300 w-10 h-10">
<path stroke-linecap="round" stroke-linejoin="round"
d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>

<span class="text-base text-primary">
Failed to create Support Ticket
</span>
</span>


<span>
An error occured while creating your support ticket:
</span>

<span class="text-red block w-full text-center">
{{ error || 'Unknown Error' }}
</span>
</div>


<div class="flex flex-row justify-center items-center gap-2">

<button *ngIf="state === 'done' && !!url && dialogRef.data.type === 'github' && !dialogRef.data.generateUrl "
class="bg-blue" (click)="integration.openExternal(url)">Open Issue</button>

<button *ngIf="state === 'done' && !!url && dialogRef.data.type === 'github' && !dialogRef.data.generateUrl "
(click)="copyUrl()">Copy URL</button>

<button (click)="dialogRef.close()" class="btn">Close</button>
</div>
Loading

0 comments on commit 0ff05f3

Please sign in to comment.