hermes-web-angular/src/app/redemptions/redemption-item-edit/redemption-item-edit.component.ts

145 lines
6.1 KiB
TypeScript

import { Component, inject, Input, model, OnInit, signal } from '@angular/core';
import Redemption from '../../shared/models/redemption';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { ActionDropdownComponent } from '../../actions/action-dropdown/action-dropdown.component';
import { TwitchRedemptionDropdownComponent } from '../twitch-redemption-dropdown/twitch-redemption-dropdown.component';
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { HermesClientService } from '../../hermes-client.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import TwitchRedemption from '../../shared/models/twitch-redemption';
import RedeemableAction from '../../shared/models/redeemable_action';
import { integerValidator } from '../../shared/validators/integer';
import { createTypeValidator } from '../../shared/validators/of-type';
import { RedemptionService } from '../../shared/services/redemption.service';
import { Subscription } from 'rxjs';
@Component({
selector: 'redemption-item-edit',
imports: [
ActionDropdownComponent,
MatButtonModule,
MatCardModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
ReactiveFormsModule,
TwitchRedemptionDropdownComponent,
],
templateUrl: './redemption-item-edit.component.html',
styleUrl: './redemption-item-edit.component.scss'
})
export class RedemptionItemEditComponent implements OnInit {
readonly client = inject(HermesClientService);
readonly redemptionService = inject(RedemptionService);
readonly dialogRef = inject(MatDialogRef<RedemptionItemEditComponent>);
readonly data = inject<{ redemption: Redemption, twitchRedemptions: TwitchRedemption[], redeemableActions: RedeemableAction[] }>(MAT_DIALOG_DATA);
redemptionFormControl = new FormControl<TwitchRedemption | string | undefined>(undefined, [Validators.required, createTypeValidator('Object')]);
redemptionErrorMessages: { [errorKey: string]: string } = {
'required': 'This field is required.',
'invalidType': 'Select a value from the dropdown.',
};
actionFormControl = new FormControl<RedeemableAction | string | undefined>(undefined, [Validators.required, createTypeValidator('Object')]);
actionErrorMessages: { [errorKey: string]: string } = {
'required': 'This field is required.',
'invalidType': 'Select a value from the dropdown.',
};
orderFormControl = new FormControl(0, [Validators.required, Validators.min(0), Validators.max(99), integerValidator]);
orderErrorMessages: { [errorKey: string]: string } = {
'required': 'This field is required.',
'min': 'The value must be at least 0.',
'max': 'The value must be at most 99.',
'integer': 'The value must be a whole number.',
};
orderErrorMessageKeys: string[] = [];
formGroups = new FormGroup({
twitchRedemption: this.redemptionFormControl,
redeemableAction: this.actionFormControl,
order: this.orderFormControl,
});
redemption: Redemption = { id: '', user_id: '', redemption_id: '', action_name: '', order: 0, state: true };
twitchRedemptions: TwitchRedemption[] = [];
redeemableActions: RedeemableAction[] = [];
waitForResponse = false;
responseError: string | undefined = undefined;
ngOnInit(): void {
this.redemption = this.data.redemption;
this.orderFormControl.setValue(this.redemption.order);
this.twitchRedemptions = this.data.twitchRedemptions;
this.redeemableActions = this.data.redeemableActions;
this.orderErrorMessageKeys = Object.keys(this.orderErrorMessages);
}
delete() {
const id = this.redemption.id;
this.waitForResponse = true
this.client.first((d: any) => d.op == 4 && d.d.request.type == 'delete_redemption' && d.d.request.data.id == id)
?.subscribe({
next: (d) => {
if (d.d.error) {
this.responseError = d.d.error;
return;
}
this.dialogRef.close(id);
},
error: () => { this.responseError = 'Failed to receive response back from server.'; this.waitForResponse = false; },
complete: () => this.waitForResponse = false,
});
this.client.deleteRedemption(id);
}
save() {
this.responseError = undefined;
const order = this.orderFormControl.value;
if (order == null) {
this.responseError = 'Order must be an integer.';
return;
}
this.waitForResponse = true;
const isNew = !this.redemption.id;
if (isNew) {
this.client.first((d: any) => d.op == 4 && d.d.request.type == 'create_redemption' && d.d.request.data.action == (this.redemption.action_name ?? '') && d.d.request.data.redemption == (this.redemption.redemption_id ?? ''))
?.subscribe({
next: (d) => {
if (d.d.error) {
this.responseError = d.d.error;
return;
}
this.redemption.order = order;
this.dialogRef.close(d.d.data);
},
error: () => { this.responseError = 'Failed to receive response back from server.'; this.waitForResponse = false; },
complete: () => this.waitForResponse = false,
});
this.client.createRedemption(this.redemption.redemption_id, this.redemption.action_name, order);
} else {
this.client.first((d: any) => d.op == 4 && d.d.request.type == 'update_redemption' && d.d.data.id == this.redemption.id)
?.subscribe({
next: (d) => {
if (d.d.error) {
this.responseError = d.d.error;
return;
}
this.redemption.order = order;
this.dialogRef.close(d.d.data);
},
error: () => { this.responseError = 'Failed to receive response back from server.'; this.waitForResponse = false; },
complete: () => this.waitForResponse = false,
});
this.client.updateRedemption(this.redemption.id, this.redemption.redemption_id, this.redemption.action_name, order);
}
}
}