-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(post): Add support for CS ticket ID field in post editor
- Added a new property `supportTicketStatus` to the `PlayerPostEditorDto` interface and implemented it in the `PostEditorComponent` - Created a new component `CsTicketIdHelpComponent` to display information about Customer Support tickets - Added a new HTML template file for the `CsTicketIdHelpComponent` - Updated the HTML template of the `PostEditorComponent` to include a CS ticket ID field when certain conditions are met - Updated the CSS styles of the `SeedTokenChangeComponent` (removed) - Updated the TypeScript code of the `SeedTokenChangeComponent` (removed) - Updated the HTML template of the `PostComponent` to display CS ticket related icons and tooltips Implements frontend requirements for #165.
- Loading branch information
1 parent
495032c
commit 2d228ab
Showing
8 changed files
with
234 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
wowskarma.app/src/app/shared/modals/cs-ticket-id-help/cs-ticket-id-help.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<div class="modal-header"> | ||
<h4 class="modal-title">Customer Support Tickets</h4> | ||
|
||
<div> | ||
<button type="button" class="btn-close mx-2" aria-label="Close" (click)="this.modal.close()"></button> | ||
</div> | ||
</div> | ||
|
||
<div class="modal-body d-flex flex-column gap-3"> | ||
<div> | ||
<h4>What is a Customer Support Ticket ?</h4> | ||
|
||
<p class="text-body"> | ||
Wargaming's Customer Support (aka CS or Player Support) helps players with any issue related to the game. | ||
Submitting a ticket to CS is the best way to get help with your issue, may it be a bug, a technical problem, or a report. | ||
</p> | ||
</div> | ||
|
||
<div> | ||
<h4>How is this related to WOWS Karma ?</h4> | ||
|
||
<p class="text-body"> | ||
WOWS Karma is a community-based platform that is separate from the Customer Support system. | ||
While endorsed, we are not affiliated to Wargaming. This means that our posts aren't systematically sent to WG for reporting. | ||
</p> | ||
|
||
<p class="text-body"> | ||
While CS does occasionally receive some of our posts through tickets, | ||
insight from Wargaming shows that this is only a minuscule percentage of the posts currently on our platform. | ||
</p> | ||
</div> | ||
|
||
<div> | ||
<h4>Why should I submit a ticket to Customer Support ?</h4> | ||
|
||
<p class="text-body"> | ||
WOWS Karma has no power whatsoever on negative events, and <b>our staff is unable to take action on players</b>. | ||
The only party able to effectively take action on players is Wargaming's Customer Support. | ||
</p> | ||
|
||
<p class="text-body"> | ||
If you encounter a player that is acting negatively, submitting a ticket to CS is the best way to get them sanctioned. | ||
This is why, <strong>if you feel that the player you're posting on has broken the rules, we <u>strongly</u> encourage you to submit a ticket right away</strong>. | ||
</p> | ||
</div> | ||
|
||
<div> | ||
<h4>How do I submit a ticket to Customer Support ?</h4> | ||
<p class="text-body"> | ||
To submit a ticket to WG's {{ region() }} Customer Support, you can follow these links depending on your issue : | ||
</p> | ||
|
||
<ul> | ||
<li><a [href]="csLinks()[0]" rel="external" target="_blank">Report : Gameplay Violation / Collusions</a></li> | ||
<li><a [href]="csLinks()[1]" rel="external" target="_blank">Report : Chat Issues / Inappropriate Behaviour</a></li> | ||
</ul> | ||
|
||
<p> | ||
Once reported, then come back here with your Ticket ID. | ||
This will help us, Wargaming, and others know that the affected user has already been reported for a given issue. | ||
</p> | ||
</div> | ||
</div> |
56 changes: 56 additions & 0 deletions
56
wowskarma.app/src/app/shared/modals/cs-ticket-id-help/cs-ticket-id-help.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { ChangeDetectionStrategy, Component, computed, inject, Input } from '@angular/core'; | ||
import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap"; | ||
import { AuthService } from "../../../services/api/services/auth.service"; | ||
import { AppConfigService } from "../../../services/app-config.service"; | ||
|
||
@Component({ | ||
selector: 'app-cs-ticket-id', | ||
standalone: true, | ||
imports: [], | ||
templateUrl: './cs-ticket-id-help.component.html', | ||
changeDetection: ChangeDetectionStrategy.OnPush | ||
}) | ||
export class CsTicketIdHelpComponent { | ||
@Input() modal!: NgbModalRef; | ||
|
||
appConfig = inject(AppConfigService); | ||
|
||
region = computed(() => this.appConfig.currentRegion); | ||
|
||
csLinks = computed<[string, string]>(() => { | ||
/* | ||
* In order: | ||
* - Gameplay / Collusions | ||
* - Chat Issues | ||
* | ||
* See: https://github.com/SakuraIsayeki/WOWS-Karma/issues/165 | ||
*/ | ||
|
||
if (this.region() === 'EU') { | ||
return [ | ||
'https://eu.wargaming.net/support/en/products/wows/help/29948/29949/29955/29957/', | ||
'https://eu.wargaming.net/support/en/products/wows/help/29948/29949/29951/29952/' | ||
]; | ||
} else if (this.region() === 'NA') { | ||
return [ | ||
'https://na.wargaming.net/support/en/products/wows/help/31336/31337/31338/31339/', | ||
'https://na.wargaming.net/support/en/products/wows/help/31336/31337/31345/' | ||
]; | ||
} else if (this.region() === 'SEA') { | ||
return [ | ||
"https://asia.wargaming.net/support/en/products/wows/help/28687/28688/28689/", | ||
"https://asia.wargaming.net/support/en/products/wows/help/28687/28688/28694/" | ||
]; | ||
} | ||
|
||
return ['', '']; | ||
}) | ||
|
||
constructor() { | ||
} | ||
|
||
static OpenModal(modalService: NgbModal) { | ||
const modalRef = modalService.open(CsTicketIdHelpComponent, { size: "lg" }); | ||
modalRef.componentInstance.modal = modalRef; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,84 @@ | ||
<div *ngIf="post() as p" class="m-2 vstack" [id]="p.id"> | ||
<p *ngIf="postDisplayType() === 'neutral'" class="text-body"> | ||
<player-namelink [player]="p.author" [displayClan]="true" /> | ||
> | ||
<player-namelink [player]="p.player" [displayClan]="true" /> | ||
</p> | ||
<p *ngIf="postDisplayType() === 'neutral'" class="text-body"> | ||
<player-namelink [player]="p.author" [displayClan]="true" /> | ||
> | ||
<player-namelink [player]="p.player" [displayClan]="true" /> | ||
</p> | ||
|
||
<div class="card post-card border-{{p.flairs! | postBorderColor}}"> | ||
<div class="card-header"> | ||
<h5 class="my-2">{{ p.title }}</h5> | ||
</div> | ||
|
||
<div class="card-body"> | ||
<markdown class="card-text markdown" [data]="p.content" /> | ||
</div> | ||
<div class="card post-card border-{{p.flairs! | postBorderColor}}"> | ||
<div class="card-header"> | ||
<h5 class="my-2">{{ p.title }}</h5> | ||
</div> | ||
|
||
<div class="card-body py-0 my-1" style="line-height: normal;"> | ||
<div class="row justify-content-between align-items-end"> | ||
<div class="col-auto"> | ||
<flairs-markup [flairsEnum]="p.flairs" /> | ||
</div> | ||
<div class="card-body"> | ||
<markdown class="card-text markdown" [data]="p.content" /> | ||
</div> | ||
|
||
<div class="col-auto px-1"> | ||
<i *ngIf="p.readOnly" class="bi bi-asterisk text-warning lead mx-1"></i> | ||
<i *ngIf="p.modLocked" class="bi bi-x-circle text-danger lead mx-1"></i> | ||
<div class="card-body py-0 my-1" style="line-height: normal;"> | ||
<div class="row justify-content-between align-items-end"> | ||
<div class="col-auto"> | ||
<flairs-markup [flairsEnum]="p.flairs" /> | ||
</div> | ||
|
||
@switch (p.replayState) { | ||
@case (2) { | ||
<a class="text-body" [routerLink]="['/posts', 'view', p.id]"> | ||
<i class="bi bi-camera-video text-success lead mx-1"></i> | ||
</a> | ||
} | ||
<div class="col-auto px-1"> | ||
<i *ngIf="p.readOnly" class="bi bi-asterisk text-warning lead mx-1"></i> | ||
<i *ngIf="p.modLocked" class="bi bi-x-circle text-danger lead mx-1"></i> | ||
|
||
@case (1) { | ||
<a class="text-body" [routerLink]="['/posts', 'view', p.id]" title="Replay minimap is being processed."> | ||
<i class="bi bi-camera-video text-warning lead mx-1"></i> | ||
</a> | ||
} | ||
@switch (p.replayState) { | ||
@case (2) { | ||
<a class="text-body" [routerLink]="['/posts', 'view', p.id]"> | ||
<i class="bi bi-camera-video text-success lead mx-1"></i> | ||
</a> | ||
} | ||
@case (1) { | ||
<a class="text-body" [routerLink]="['/posts', 'view', p.id]" title="Replay minimap is being processed."> | ||
<i class="bi bi-camera-video text-warning lead mx-1"></i> | ||
</a> | ||
} | ||
@case (0) { | ||
<i class="bi bi-camera-video-off text-danger lead mx-1"></i> | ||
} | ||
} | ||
|
||
@case (0) { | ||
<i class="bi bi-camera-video-off text-danger lead mx-1"></i> | ||
} | ||
} | ||
@if (p.supportTicketStatus?.hasTicket) { | ||
@if (p.supportTicketStatus?.ticketId) { | ||
<i class="bi bi-flag text-success lead mx-1" ngbTooltip="CS Ticket ID : {{ p.supportTicketStatus!.ticketId }}"></i> | ||
} @else { | ||
<i class="bi bi-flag text-success lead mx-1" ngbTooltip="Reported to CS"></i> | ||
} | ||
} | ||
|
||
<a class="text-body" [routerLink]="['/posts', 'view', p.id]"> | ||
<i class="bi bi-link-45deg lead"></i> | ||
</a> | ||
</div> | ||
</div> | ||
<a class="text-body" [routerLink]="['/posts', 'view', p.id]"> | ||
<i class="bi bi-link-45deg lead"></i> | ||
</a> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="card-footer"> | ||
<p class="blockquote-footer my-1"> | ||
<ng-container *ngIf="postDisplayType() === 'received'"> | ||
From | ||
<player-namelink [player]="p.author" [displayClan]="true" /> | ||
</ng-container> | ||
<div class="card-footer"> | ||
<p class="blockquote-footer my-1 d-inline-flex gap-1"> | ||
@if (postDisplayType() === 'received') { | ||
<span>From <player-namelink [player]="p.author" [displayClan]="true" /></span> | ||
} | ||
|
||
<ng-container *ngIf="postDisplayType() === 'sent'"> | ||
To | ||
<player-namelink [player]="p.player" [displayClan]="true" /> | ||
</ng-container> | ||
@if (postDisplayType() === 'sent') { | ||
<span>To <player-namelink [player]="p.player" [displayClan]="true" /></span> | ||
} | ||
|
||
{{ p.createdAt | date:'medium' }} | ||
</p> | ||
<span>{{ p.createdAt | date:'medium' }}</span> | ||
</p> | ||
|
||
<div class="d-flex flex-row my-1 gap-2"> | ||
<button *ngIf="canEdit" class="btn btn-warning btn-sm" (click)="openEditor()">Edit</button> | ||
<button *ngIf="canDelete" class="btn btn-danger btn-sm" (click)="openDeleteModal()">Delete</button> | ||
<div class="d-flex flex-row my-1 gap-2"> | ||
<div class="d-flex flex-row gap-1"> | ||
<button *ngIf="canEdit" class="btn btn-warning btn-sm" (click)="openEditor()">Edit</button> | ||
<button *ngIf="canDelete" class="btn btn-danger btn-sm" (click)="openDeleteModal()">Delete</button> | ||
</div> | ||
|
||
<div class="d-flex flex-row gap-1" *ngIf="this.authService.isInRole('mod')"> | ||
<button class="btn btn-outline-warning btn-sm" (click)="openModEditor()">Mod Edit</button> | ||
<button class="btn btn-outline-danger btn-sm" (click)="openModDeleteModal()">Mod Delete</button> | ||
</div> | ||
</div> | ||
<div class="d-flex flex-row gap-1" *ngIf="this.authService.isInRole('mod')"> | ||
<button class="btn btn-outline-warning btn-sm" (click)="openModEditor()">Mod Edit</button> | ||
<button class="btn btn-outline-danger btn-sm" (click)="openModDeleteModal()">Mod Delete</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> |