Allow user to add a comment to a request for movies/tv shows then display this in requests table.

This commit is contained in:
Ryan Castles 2023-04-23 16:40:39 +10:00
commit 165920291f
22 changed files with 133 additions and 92 deletions

View file

@ -145,7 +145,8 @@ namespace Ombi.Core.Engine
QualityOverride = model.QualityPathOverride.GetValueOrDefault(), QualityOverride = model.QualityPathOverride.GetValueOrDefault(),
RequestedDate4k = model.Is4kRequest ? DateTime.UtcNow : DateTime.MinValue, RequestedDate4k = model.Is4kRequest ? DateTime.UtcNow : DateTime.MinValue,
Is4kRequest = model.Is4kRequest, Is4kRequest = model.Is4kRequest,
Source = model.Source Source = model.Source,
Comment = model.Comment
}; };
} }

View file

@ -35,5 +35,7 @@ namespace Ombi.Core.Models.Requests
public string RequestOnBehalf { get; set; } public string RequestOnBehalf { get; set; }
public int? RootFolderOverride { get; set; } public int? RootFolderOverride { get; set; }
public int? QualityPathOverride { get; set; } public int? QualityPathOverride { get; set; }
public string Comment { get; set; }
} }
} }

View file

@ -23,6 +23,7 @@ namespace Ombi.Store.Entities.Requests
public OmbiUser RequestedUser { get; set; } public OmbiUser RequestedUser { get; set; }
public RequestSource Source { get; set; } = RequestSource.Ombi; public RequestSource Source { get; set; } = RequestSource.Ombi;
public string Comment { get; set; }
[NotMapped] [NotMapped]

View file

@ -27,5 +27,7 @@ namespace Ombi.Store.Entities.Requests
public int TotalSeasons { get; set; } public int TotalSeasons { get; set; }
public List<ChildRequests> ChildRequests { get; set; } public List<ChildRequests> ChildRequests { get; set; }
public string Comment { get; set; }
} }
} }

View file

@ -126,7 +126,7 @@ export class DiscoverCardComponent implements OnInit {
return ""; return "";
} }
public request(event: any, is4k: boolean) { public request(event: any, is4k: boolean, comment: string) {
event.preventDefault(); event.preventDefault();
this.loading = true; this.loading = true;
switch (this.result.type) { switch (this.result.type) {
@ -146,6 +146,7 @@ export class DiscoverCardComponent implements OnInit {
qualityPathOverride: null, qualityPathOverride: null,
rootFolderOverride: null, rootFolderOverride: null,
is4KRequest: is4k, is4KRequest: is4k,
comment: comment
}; };
if (!this.isAdmin) { if (!this.isAdmin) {
@ -157,7 +158,7 @@ export class DiscoverCardComponent implements OnInit {
AdminRequestDialogComponent, AdminRequestDialogComponent,
{ {
width: "700px", width: "700px",
data: { type: RequestType.movie, id: this.result.id, is4k: is4k }, data: { type: RequestType.movie, id: this.result.id, is4k: is4k, comment: comment },
panelClass: "modal-panel", panelClass: "modal-panel",
} }
); );
@ -170,6 +171,8 @@ export class DiscoverCardComponent implements OnInit {
movieRequest.requestOnBehalf = result.username?.id; movieRequest.requestOnBehalf = result.username?.id;
movieRequest.qualityPathOverride = result.radarrPathId; movieRequest.qualityPathOverride = result.radarrPathId;
movieRequest.rootFolderOverride = result.radarrFolderId; movieRequest.rootFolderOverride = result.radarrFolderId;
movieRequest.comment = result.comment;
this.requestMovie(movieRequest); this.requestMovie(movieRequest);
}); });
break; break;

View file

@ -212,4 +212,5 @@ export class BaseRequestOptions {
requestOnBehalf: string | undefined; requestOnBehalf: string | undefined;
rootFolderOverride: number | undefined; rootFolderOverride: number | undefined;
qualityPathOverride: number | undefined; qualityPathOverride: number | undefined;
comment: string | undefined;
} }

View file

@ -106,7 +106,7 @@ export class MovieDetailsComponent implements OnInit{
} }
} }
public async request(is4K: boolean, userId?: string) { public async request(is4K: boolean, userId?: string, comment?: string) {
if (!this.is4KEnabled) { if (!this.is4KEnabled) {
is4K = false; is4K = false;
} }
@ -119,7 +119,8 @@ export class MovieDetailsComponent implements OnInit{
qualityPathOverride: result.radarrPathId, qualityPathOverride: result.radarrPathId,
requestOnBehalf: result.username?.id, requestOnBehalf: result.username?.id,
rootFolderOverride: result.radarrFolderId, rootFolderOverride: result.radarrFolderId,
is4KRequest: is4K })); is4KRequest: is4K,
comment: result.comment }));
if (requestResult.result) { if (requestResult.result) {
if (is4K) { if (is4K) {
this.movie.has4KRequest = true; this.movie.has4KRequest = true;
@ -135,7 +136,7 @@ export class MovieDetailsComponent implements OnInit{
} }
}); });
} else { } else {
const result = await firstValueFrom(this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId, languageCode: this.translate.currentLang, requestOnBehalf: userId, qualityPathOverride: undefined, rootFolderOverride: undefined, is4KRequest: is4K })); const result = await firstValueFrom(this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId, languageCode: this.translate.currentLang, requestOnBehalf: userId, qualityPathOverride: undefined, rootFolderOverride: undefined, is4KRequest: is4K, comment: comment }));
if (result.result) { if (result.result) {
if (is4K) { if (is4K) {
this.movie.has4KRequest = true; this.movie.has4KRequest = true;

View file

@ -25,7 +25,7 @@ export class TvRequestGridComponent {
return this.tv?.seasonRequests?.length > 0 return this.tv?.seasonRequests?.length > 0
} }
public displayedColumns: string[] = ['select', 'number', 'title', 'airDate', 'status']; public displayedColumns: string[] = ['select', 'number', 'title', 'airDate','status'];
constructor(private requestService: RequestService, private requestServiceV2: RequestServiceV2, private notificationService: MessageService, constructor(private requestService: RequestService, private requestServiceV2: RequestServiceV2, private notificationService: MessageService,
private dialog: MatDialog, private translate: TranslateService) { private dialog: MatDialog, private translate: TranslateService) {
@ -69,6 +69,7 @@ export class TvRequestGridComponent {
viewModel.qualityPathOverride = result?.sonarrPathId; viewModel.qualityPathOverride = result?.sonarrPathId;
viewModel.rootFolderOverride = result?.sonarrFolderId; viewModel.rootFolderOverride = result?.sonarrFolderId;
viewModel.languageProfile = result?.sonarrLanguageId; viewModel.languageProfile = result?.sonarrLanguageId;
//viewModel.comment = result?.comment;
const requestResult = await this.requestServiceV2.requestTv(viewModel).toPromise(); const requestResult = await this.requestServiceV2.requestTv(viewModel).toPromise();
this.postRequest(requestResult); this.postRequest(requestResult);

View file

@ -66,6 +66,11 @@
<td mat-cell id="status{{element.id}}" *matCellDef="let element"> {{element.status |translateStatus }} </td> <td mat-cell id="status{{element.id}}" *matCellDef="let element"> {{element.status |translateStatus }} </td>
</ng-container> </ng-container>
<ng-container matColumnDef="comment">
<th mat-header-cell *matHeaderCellDef> {{'Requests.Comment' | translate}} </th>
<td mat-cell id="requestedBy{{element.id}}" *matCellDef="let element"> {{element.comment}} </td>
</ng-container>
<ng-container matColumnDef="has4kRequest"> <ng-container matColumnDef="has4kRequest">
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Requests.Has4KRequest' | translate}} </th> <th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Requests.Has4KRequest' | translate}} </th>
<td mat-cell id="has4kRequest{{element.id}}" *matCellDef="let element"> <td mat-cell id="has4kRequest{{element.id}}" *matCellDef="let element">

View file

@ -24,7 +24,7 @@ export class MoviesGridComponent implements OnInit, AfterViewInit {
public dataSource: MatTableDataSource<IMovieRequests>; public dataSource: MatTableDataSource<IMovieRequests>;
public resultsLength: number; public resultsLength: number;
public isLoadingResults = true; public isLoadingResults = true;
public displayedColumns: string[] = ['title', 'requestedUser.requestedBy', 'status', 'requestStatus','requestedDate', 'actions']; public displayedColumns: string[] = ['title', 'requestedUser.requestedBy', 'status', 'requestStatus','requestedDate', 'comment', 'actions' ];
public gridCount: string = "15"; public gridCount: string = "15";
public isAdmin: boolean; public isAdmin: boolean;
public is4kEnabled = false; public is4kEnabled = false;

View file

@ -60,6 +60,11 @@
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="comment">
<th mat-header-cell *matHeaderCellDef> {{'Requests.Comment' | translate}} </th>
<td mat-cell id="requestedBy{{element.id}}" *matCellDef="let element"> {{element.parentRequest.comment}} </td>
</ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef> </th> <th mat-header-cell *matHeaderCellDef> </th>
<td mat-cell *matCellDef="let element"> <td mat-cell *matCellDef="let element">

View file

@ -19,7 +19,7 @@ export class TvGridComponent implements OnInit, AfterViewInit {
public dataSource: IChildRequests[] = []; public dataSource: IChildRequests[] = [];
public resultsLength: number; public resultsLength: number;
public isLoadingResults = true; public isLoadingResults = true;
public displayedColumns: string[] = ['series', 'requestedBy', 'status', 'requestStatus', 'requestedDate','actions']; public displayedColumns: string[] = ['series', 'requestedBy', 'status', 'requestStatus', 'requestedDate', 'comment','actions'];
public gridCount: string = "15"; public gridCount: string = "15";
public isAdmin: boolean; public isAdmin: boolean;
public defaultSort: string = "requestedDate"; public defaultSort: string = "requestedDate";

View file

@ -28,6 +28,10 @@
</mat-option> </mat-option>
</mat-autocomplete> </mat-autocomplete>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline">
<mat-label>{{ 'MediaDetails.AddComment' | translate}}</mat-label>
<textarea matInput class="comment-box" formControlName="comment"></textarea>
</mat-form-field>
<!-- End User area --> <!-- End User area -->

View file

@ -6,3 +6,7 @@
border-color: $ombi-background-primary; border-color: $ombi-background-primary;
color:white; color:white;
} }
.comment-box {
resize: none;
}

View file

@ -20,6 +20,7 @@ export interface IAdminRequestDialogData {
type: RequestType; type: RequestType;
id: number; id: number;
is4k: boolean | null; is4k: boolean | null;
comment: string | null;
} }
@Component({ @Component({
@ -59,6 +60,7 @@ export class AdminRequestDialogComponent implements OnInit {
public async ngOnInit() { public async ngOnInit() {
this.form = this.fb.group({ this.form = this.fb.group({
username: [null], username: [null],
comment: [null],
sonarrPathId: [null], sonarrPathId: [null],
sonarrFolderId: [null], sonarrFolderId: [null],
sonarrLanguageId: [null], sonarrLanguageId: [null],

View file

@ -12,6 +12,7 @@ export interface EpisodeRequestData {
series: ISearchTvResultV2; series: ISearchTvResultV2;
isAdmin: boolean; isAdmin: boolean;
requestOnBehalf: string | undefined; requestOnBehalf: string | undefined;
comment: string | undefined;
} }
@Component({ @Component({
selector: "episode-request", selector: "episode-request",
@ -69,6 +70,7 @@ export class EpisodeRequestComponent {
viewModel.qualityPathOverride = result?.sonarrPathId; viewModel.qualityPathOverride = result?.sonarrPathId;
viewModel.rootFolderOverride = result?.sonarrFolderId; viewModel.rootFolderOverride = result?.sonarrFolderId;
viewModel.languageProfile = result?.sonarrLanguageId; viewModel.languageProfile = result?.sonarrLanguageId;
viewModel.comment = result?.comment;
const requestResult = await this.requestService.requestTv(viewModel).toPromise(); const requestResult = await this.requestService.requestTv(viewModel).toPromise();
this.postRequest(requestResult); this.postRequest(requestResult);

View file

@ -378,6 +378,7 @@
"RadarrConfiguration": "Конфигурация на Radarr", "RadarrConfiguration": "Конфигурация на Radarr",
"RequestOnBehalf": "Заявете от името на", "RequestOnBehalf": "Заявете от името на",
"PleaseSelectUser": "Моля, изберете потребител", "PleaseSelectUser": "Моля, изберете потребител",
"AddComment": "Добавить комментарий",
"StreamingOn": "Поточното изпълнение е включено:", "StreamingOn": "Поточното изпълнение е включено:",
"RequestedBy": "Заявено от:", "RequestedBy": "Заявено от:",
"OnDate": "On:", "OnDate": "On:",

View file

@ -378,6 +378,7 @@
"RadarrConfiguration": "Radarr Configuration", "RadarrConfiguration": "Radarr Configuration",
"RequestOnBehalf": "Request on behalf of", "RequestOnBehalf": "Request on behalf of",
"PleaseSelectUser": "Please select a user", "PleaseSelectUser": "Please select a user",
"AddComment": "Add a comment",
"StreamingOn": "Streamuje na:", "StreamingOn": "Streamuje na:",
"RequestedBy": "Požadováno od:", "RequestedBy": "Požadováno od:",
"OnDate": "On:", "OnDate": "On:",

View file

@ -165,6 +165,7 @@
"TheatricalReleaseSort": "Theatrical Release", "TheatricalReleaseSort": "Theatrical Release",
"DigitalRelease": "Digital Release: {{date}}", "DigitalRelease": "Digital Release: {{date}}",
"RequestDate": "Request Date", "RequestDate": "Request Date",
"Comment": "Comment",
"QualityOverride": "Quality Override:", "QualityOverride": "Quality Override:",
"RootFolderOverride": "Root Folder Override:", "RootFolderOverride": "Root Folder Override:",
"ChangeRootFolder": "Root Folder", "ChangeRootFolder": "Root Folder",
@ -379,6 +380,7 @@
"RadarrConfiguration": "Radarr Configuration", "RadarrConfiguration": "Radarr Configuration",
"RequestOnBehalf": "Request on behalf of", "RequestOnBehalf": "Request on behalf of",
"PleaseSelectUser": "Please select a user", "PleaseSelectUser": "Please select a user",
"AddComment": "Add a comment",
"StreamingOn": "Streaming On:", "StreamingOn": "Streaming On:",
"RequestedBy": "Requested By:", "RequestedBy": "Requested By:",
"OnDate": "On:", "OnDate": "On:",

View file

@ -378,6 +378,7 @@
"RadarrConfiguration": "Radarr Configuration", "RadarrConfiguration": "Radarr Configuration",
"RequestOnBehalf": "Request on behalf of", "RequestOnBehalf": "Request on behalf of",
"PleaseSelectUser": "Please select a user", "PleaseSelectUser": "Please select a user",
"AddComment": "Add a comment",
"StreamingOn": "Streaming On:", "StreamingOn": "Streaming On:",
"RequestedBy": "Etterspurt av:", "RequestedBy": "Etterspurt av:",
"OnDate": "On:", "OnDate": "On:",

View file

@ -378,6 +378,7 @@
"RadarrConfiguration": "Radarr Configuration", "RadarrConfiguration": "Radarr Configuration",
"RequestOnBehalf": "Request on behalf of", "RequestOnBehalf": "Request on behalf of",
"PleaseSelectUser": "Please select a user", "PleaseSelectUser": "Please select a user",
"AddComment": "Add a comment",
"StreamingOn": "Streaming On:", "StreamingOn": "Streaming On:",
"RequestedBy": "Requested By:", "RequestedBy": "Requested By:",
"OnDate": "On:", "OnDate": "On:",

View file

@ -378,6 +378,7 @@
"RadarrConfiguration": "Radarr Configuration", "RadarrConfiguration": "Radarr Configuration",
"RequestOnBehalf": "Request on behalf of", "RequestOnBehalf": "Request on behalf of",
"PleaseSelectUser": "Please select a user", "PleaseSelectUser": "Please select a user",
"AddComment": "Add a comment",
"StreamingOn": "Streaming On:", "StreamingOn": "Streaming On:",
"RequestedBy": "Автор запроса:", "RequestedBy": "Автор запроса:",
"OnDate": "On:", "OnDate": "On:",