Added redemptions page. Fixed some issues. Removed some instances of console.log().
This commit is contained in:
@ -0,0 +1,24 @@
|
||||
<mat-form-field>
|
||||
<mat-label>Redeemable Action</mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
placeholder="Pick a Redeemable Action"
|
||||
aria-label="redeemable action"
|
||||
[formControl]="formControl"
|
||||
[matAutocomplete]="auto"
|
||||
(blur)="blur()"
|
||||
(input)="input()">
|
||||
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn" (optionSelected)="select($event.option.value)">
|
||||
@for (action of filteredActions; track action.name) {
|
||||
<mat-option [value]="action">{{action.name}}</mat-option>
|
||||
}
|
||||
</mat-autocomplete>
|
||||
@if (!search && formControl.invalid && (formControl.dirty || formControl.touched)) {
|
||||
@for (error of errorMessageKeys; track $index) {
|
||||
@if (formControl.hasError(error)) {
|
||||
<small class="error">{{errorMessages[error]}}</small>
|
||||
}
|
||||
}
|
||||
}
|
||||
</mat-form-field>
|
@ -0,0 +1,4 @@
|
||||
.error {
|
||||
display: block;
|
||||
color: #ba1a1a;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ActionDropdownComponent } from './action-dropdown.component';
|
||||
|
||||
describe('ActionDropdownComponent', () => {
|
||||
let component: ActionDropdownComponent;
|
||||
let fixture: ComponentFixture<ActionDropdownComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ActionDropdownComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ActionDropdownComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
90
src/app/actions/action-dropdown/action-dropdown.component.ts
Normal file
90
src/app/actions/action-dropdown/action-dropdown.component.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import { Component, EventEmitter, inject, input, Input, OnInit, Output } from '@angular/core';
|
||||
import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import RedeemableAction from '../../shared/models/redeemable_action';
|
||||
|
||||
@Component({
|
||||
selector: 'action-dropdown',
|
||||
imports: [MatAutocompleteModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule],
|
||||
templateUrl: './action-dropdown.component.html',
|
||||
styleUrl: './action-dropdown.component.scss'
|
||||
})
|
||||
export class ActionDropdownComponent implements OnInit {
|
||||
@Input() formControl = new FormControl<RedeemableAction | string | undefined>(undefined);
|
||||
@Input() errorMessages: { [errorKey: string]: string } = {}
|
||||
|
||||
@Input() search: boolean = false;
|
||||
@Input() actions: RedeemableAction[] = [];
|
||||
@Input() action: string | undefined;
|
||||
@Output() readonly actionChange = new EventEmitter<string>();
|
||||
|
||||
private readonly route = inject(ActivatedRoute);
|
||||
|
||||
errorMessageKeys: string[] = []
|
||||
|
||||
|
||||
constructor() {
|
||||
this.route.data.subscribe(data => {
|
||||
if (!data['redeemableActions'])
|
||||
return;
|
||||
|
||||
this.actions = data['redeemableActions'];
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.errorMessageKeys = Object.keys(this.errorMessages);
|
||||
|
||||
if (!this.action)
|
||||
return;
|
||||
|
||||
const action = this.actions.find(r => r.name == this.action);
|
||||
this.formControl.setValue(action);
|
||||
}
|
||||
|
||||
get filteredActions() {
|
||||
const value = this.formControl.value;
|
||||
if (typeof value == 'string') {
|
||||
return this.actions.filter(r => r.name.toLowerCase().includes(value.toLowerCase()));
|
||||
}
|
||||
return this.actions;
|
||||
}
|
||||
|
||||
select(event: RedeemableAction) {
|
||||
this.actionChange.emit(event.name);
|
||||
}
|
||||
|
||||
input() {
|
||||
if (this.search && typeof this.formControl.value == 'string') {
|
||||
this.actionChange.emit(this.formControl.value);
|
||||
}
|
||||
}
|
||||
|
||||
blur() {
|
||||
if (!this.search && typeof this.formControl.value == 'string') {
|
||||
const name = this.formControl.value;
|
||||
const nameLower = name.toLowerCase();
|
||||
let newValue: RedeemableAction | undefined = undefined;
|
||||
const insenstiveActions = this.filteredActions.filter(a => a.name.toLowerCase() == nameLower);
|
||||
if (insenstiveActions.length > 1) {
|
||||
const sensitiveAction = insenstiveActions.find(a => a.name == name);
|
||||
newValue = sensitiveAction ?? undefined;
|
||||
} else if (insenstiveActions.length == 1) {
|
||||
newValue = insenstiveActions[0];
|
||||
}
|
||||
|
||||
if (newValue && newValue.name != this.formControl.value) {
|
||||
this.formControl.setValue(newValue);
|
||||
this.actionChange.emit(newValue.name);
|
||||
} else if (!newValue)
|
||||
this.actionChange.emit(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
displayFn(value: any) {
|
||||
return value?.name;
|
||||
}
|
||||
}
|
@ -67,10 +67,6 @@ export class ActionsComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
this.client.subscribeToRequests('delete_redeemable_action', d => {
|
||||
// if (d.request.nounce != null && d.request.nounce.startsWith(this.client.session_id)) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
this.items = this.actions.filter(a => a.name != d.request.data.name);
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user