Cleaned up code for redeemable actions.
This commit is contained in:
@ -28,10 +28,12 @@ import { MatIconModule } from '@angular/material/icon';
|
|||||||
})
|
})
|
||||||
export class ActionItemEditComponent implements OnInit {
|
export class ActionItemEditComponent implements OnInit {
|
||||||
private readonly client = inject(HermesClientService);
|
private readonly client = inject(HermesClientService);
|
||||||
readonly dialogRef = inject(MatDialogRef<ActionItemEditComponent>);
|
|
||||||
private readonly data = inject<{ action: RedeemableAction, actions: RedeemableAction[] }>(MAT_DIALOG_DATA);
|
private readonly data = inject<{ action: RedeemableAction, actions: RedeemableAction[] }>(MAT_DIALOG_DATA);
|
||||||
|
readonly dialogRef = inject(MatDialogRef<ActionItemEditComponent>);
|
||||||
|
|
||||||
action = this.data.action;
|
action = this.data.action;
|
||||||
actions = this.data.actions;
|
actions = this.data.actions;
|
||||||
|
|
||||||
readonly actionEntries: ({ [key: string]: any[] }) = {
|
readonly actionEntries: ({ [key: string]: any[] }) = {
|
||||||
'SLEEP': [
|
'SLEEP': [
|
||||||
{
|
{
|
||||||
@ -272,18 +274,18 @@ export class ActionItemEditComponent implements OnInit {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.action.name = this.formGroup.get('name')!.value!;
|
|
||||||
this.action.type = this.formGroup.get('type')!.value!;
|
|
||||||
this.action.data = {}
|
|
||||||
for (const entry of this.actionEntries[this.action.type]) {
|
|
||||||
this.action.data[entry.key] = entry.control.value!.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(this.action.type in this.actionEntries)) {
|
if (!(this.action.type in this.actionEntries)) {
|
||||||
this.waitForResponse = false;
|
this.waitForResponse = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.action.name = this.formGroup.get('name')!.value!;
|
||||||
|
this.action.type = this.formGroup.get('type')!.value!;
|
||||||
|
this.action.data = {};
|
||||||
|
for (const entry of this.actionEntries[this.action.type]) {
|
||||||
|
this.action.data[entry.key] = entry.control.value!.toString();
|
||||||
|
}
|
||||||
|
|
||||||
const isNewAction = !this.action.user_id;
|
const isNewAction = !this.action.user_id;
|
||||||
const requestType = isNewAction ? 'create_redeemable_action' : 'update_redeemable_action';
|
const requestType = isNewAction ? 'create_redeemable_action' : 'update_redeemable_action';
|
||||||
this.client.first((d: any) => d.op == 4 && d.d.request.type == requestType && d.d.data.name == this.action.name)
|
this.client.first((d: any) => d.op == 4 && d.d.request.type == requestType && d.d.data.name == this.action.name)
|
||||||
@ -299,8 +301,8 @@ export class ActionItemEditComponent implements OnInit {
|
|||||||
complete: () => this.waitForResponse = false,
|
complete: () => this.waitForResponse = false,
|
||||||
});
|
});
|
||||||
if (isNewAction)
|
if (isNewAction)
|
||||||
this.client.createRedeemableAction(this.action.name, this.action.type, this.action.data);
|
this.client.createRedeemableAction(this.action.name, this.action.type, false, this.action.data);
|
||||||
else
|
else
|
||||||
this.client.updateRedeemableAction(this.action.name, this.action.type, this.action.data);
|
this.client.updateRedeemableAction(this.action.name, this.action.type, false, this.action.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<main>
|
<main>
|
||||||
@for (action of actions; track action.name) {
|
@for (action of actions(); track action.name) {
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="container"
|
class="container"
|
||||||
(click)="modify(action)">
|
(click)="modify(action)">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
|
import { Component, inject, input } from '@angular/core';
|
||||||
import { MatListModule } from '@angular/material/list';
|
import { MatListModule } from '@angular/material/list';
|
||||||
import RedeemableAction from '../../shared/models/redeemable-action';
|
import RedeemableAction from '../../shared/models/redeemable-action';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
@ -23,16 +23,14 @@ import { MatSelectModule } from '@angular/material/select';
|
|||||||
styleUrl: './action-list.component.scss'
|
styleUrl: './action-list.component.scss'
|
||||||
})
|
})
|
||||||
export class ActionListComponent {
|
export class ActionListComponent {
|
||||||
@Input() actions: RedeemableAction[] = []
|
actions = input.required<RedeemableAction[]>({ alias: 'actions' });
|
||||||
@Output() actionsChange = new EventEmitter<RedeemableAction>();
|
|
||||||
|
|
||||||
readonly dialog = inject(MatDialog);
|
readonly dialog = inject(MatDialog);
|
||||||
readonly client = inject(HermesClientService);
|
readonly client = inject(HermesClientService);
|
||||||
|
|
||||||
opened = false;
|
|
||||||
|
|
||||||
create(): void {
|
create(): void {
|
||||||
this.openDialog({ user_id: '', name: '', type: '', data: {} });
|
this.openDialog({ user_id: '', name: '', type: '', has_message: false, data: {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
modify(action: RedeemableAction): void {
|
modify(action: RedeemableAction): void {
|
||||||
@ -40,27 +38,8 @@ export class ActionListComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private openDialog(action: RedeemableAction): void {
|
private openDialog(action: RedeemableAction): void {
|
||||||
if (this.opened)
|
this.dialog.open(ActionItemEditComponent, {
|
||||||
return;
|
data: { action: { user_id: action.user_id, name: action.name, type: action.type, data: action.data }, actions: this.actions() },
|
||||||
|
|
||||||
this.opened = true;
|
|
||||||
|
|
||||||
const dialogRef = this.dialog.open(ActionItemEditComponent, {
|
|
||||||
data: { action: { user_id: action.user_id, name: action.name, type: action.type, data: action.data }, actions: this.actions },
|
|
||||||
});
|
|
||||||
|
|
||||||
const isNewAction = action.name.length <= 0;
|
|
||||||
dialogRef.afterClosed().subscribe((result: RedeemableAction | undefined) => {
|
|
||||||
this.opened = false;
|
|
||||||
if (!result)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (isNewAction) {
|
|
||||||
this.actionsChange.emit(result);
|
|
||||||
} else {
|
|
||||||
action.type = result.type;
|
|
||||||
action.data = result.data;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<mat-form-field subscriptSizing="dynamic">
|
<mat-form-field subscriptSizing="dynamic">
|
||||||
<mat-label>Filter by type</mat-label>
|
<mat-label>Filter by type</mat-label>
|
||||||
<mat-select value="0"
|
<mat-select value="0"
|
||||||
(selectionChange)="onFilterChange($event.value)">
|
(selectionChange)="filter = filters[$event.value]">
|
||||||
<mat-select-trigger>
|
<mat-select-trigger>
|
||||||
<mat-icon matPrefix>filter_list</mat-icon> {{filter.name}}
|
<mat-icon matPrefix>filter_list</mat-icon> {{filter.name}}
|
||||||
</mat-select-trigger>
|
</mat-select-trigger>
|
||||||
@ -22,13 +22,11 @@
|
|||||||
<input matInput
|
<input matInput
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Name of action"
|
placeholder="Name of action"
|
||||||
[formControl]="searchControl"
|
[formControl]="searchControl" />
|
||||||
[(ngModel)]="search">
|
|
||||||
<mat-icon matPrefix>search</mat-icon>
|
<mat-icon matPrefix>search</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
<action-list class="list center"
|
<action-list class="list center"
|
||||||
[actions]="actions"
|
[actions]="actions" />
|
||||||
(actionsChange)="items.push($event)" />
|
|
||||||
</content>
|
</content>
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, Inject, inject, OnInit } from '@angular/core';
|
import { Component, inject, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { ActionListComponent } from "../action-list/action-list.component";
|
import { ActionListComponent } from "../action-list/action-list.component";
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
@ -10,7 +10,8 @@ import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
|||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import RedeemableActionService from '../../shared/services/redeemable-action.service';
|
import RedeemableActionService from '../../shared/services/redeemable-action.service';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { DOCUMENT } from '@angular/common';
|
import { containsLettersInOrder } from '../../shared/utils/string-compare';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
interface IActionFilter {
|
interface IActionFilter {
|
||||||
name: string
|
name: string
|
||||||
@ -32,7 +33,7 @@ interface IActionFilter {
|
|||||||
templateUrl: './actions.component.html',
|
templateUrl: './actions.component.html',
|
||||||
styleUrl: './actions.component.scss'
|
styleUrl: './actions.component.scss'
|
||||||
})
|
})
|
||||||
export class ActionsComponent implements OnInit {
|
export class ActionsComponent implements OnInit, OnDestroy {
|
||||||
filters: IActionFilter[] = [
|
filters: IActionFilter[] = [
|
||||||
{ name: 'All', filter: _ => true },
|
{ name: 'All', filter: _ => true },
|
||||||
{ name: 'Local File', filter: data => data.type.includes('_FILE') },
|
{ name: 'Local File', filter: data => data.type.includes('_FILE') },
|
||||||
@ -47,58 +48,28 @@ export class ActionsComponent implements OnInit {
|
|||||||
private readonly redeemableActionService = inject(RedeemableActionService);
|
private readonly redeemableActionService = inject(RedeemableActionService);
|
||||||
private readonly route = inject(ActivatedRoute);
|
private readonly route = inject(ActivatedRoute);
|
||||||
|
|
||||||
filter = this.filters[0];
|
private readonly subscriptions: (Subscription | undefined)[] = [];
|
||||||
searchControl = new FormControl('');
|
|
||||||
search = '';
|
|
||||||
items: RedeemableAction[] = [];
|
|
||||||
|
|
||||||
constructor(@Inject(DOCUMENT) private document: Document) { }
|
filter = this.filters[0];
|
||||||
|
searchControl = new FormControl<string>('');
|
||||||
|
_actions: RedeemableAction[] = [];
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.route.data.subscribe(data => {
|
this.route.data.subscribe(data => this._actions = data['redeemableActions'] || []);
|
||||||
if (!data['redeemableActions'])
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.actions = [...data['redeemableActions']];
|
this.subscriptions.push(this.redeemableActionService.delete$?.subscribe(_ => this.redeemableActionService.fetch().subscribe(a => this._actions = a)));
|
||||||
});
|
|
||||||
this.redeemableActionService.create$?.subscribe(d => {
|
|
||||||
if (d.error || d.request.nounce != null && d.request.nounce.startsWith(this.client.session_id))
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.actions.push(d.data);
|
|
||||||
});
|
|
||||||
this.redeemableActionService.update$?.subscribe(d => {
|
|
||||||
if (d.error || d.request.nounce != null && d.request.nounce.startsWith(this.client.session_id))
|
|
||||||
return;
|
|
||||||
|
|
||||||
const action = this.actions.find(a => a.name == d.data.name);
|
|
||||||
if (action) {
|
|
||||||
action.type = d.data.type;
|
|
||||||
action.data = d.data.data;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.redeemableActionService.delete$?.subscribe(d => {
|
|
||||||
if (d.error)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.items = this.actions.filter(a => a.name != d.request.data.name);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.client.fetchRedeemableActions();
|
this.client.fetchRedeemableActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.subscriptions.filter(s => s).forEach(s => s?.unsubscribe());
|
||||||
|
}
|
||||||
|
|
||||||
get actions(): RedeemableAction[] {
|
get actions(): RedeemableAction[] {
|
||||||
const searchLower = this.search.toLowerCase();
|
const searchLower = this.searchControl.value!.toLowerCase();
|
||||||
return this.items.filter(this.filter.filter)
|
return this._actions.filter(this.filter.filter)
|
||||||
.filter((action) => action.name.toLowerCase().includes(searchLower));
|
.filter((action) => containsLettersInOrder(action.name.toLowerCase(), searchLower));
|
||||||
}
|
|
||||||
|
|
||||||
set actions(value) {
|
|
||||||
this.items = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
onFilterChange(event: any): void {
|
|
||||||
this.filter = this.filters[event];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
@use '@angular/material' as mat;
|
@use '@angular/material' as mat;
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
background-color: rgb(202, 68, 255);
|
||||||
|
border-radius: 15px;
|
||||||
|
margin: 0 0;
|
||||||
|
padding: 0;
|
||||||
|
max-width: 500px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
@include mat.all-component-densities(-5);
|
@include mat.all-component-densities(-5);
|
||||||
|
|
||||||
@include mat.form-field-overrides((
|
@include mat.form-field-overrides((
|
||||||
@ -8,13 +15,6 @@ ul {
|
|||||||
outlined-focus-label-text-color: rgb(155, 57, 194),
|
outlined-focus-label-text-color: rgb(155, 57, 194),
|
||||||
outlined-focus-outline-color: rgb(155, 57, 194),
|
outlined-focus-outline-color: rgb(155, 57, 194),
|
||||||
));
|
));
|
||||||
|
|
||||||
background-color: rgb(202, 68, 255);
|
|
||||||
border-radius: 15px;
|
|
||||||
margin: 0 0;
|
|
||||||
padding: 0;
|
|
||||||
max-width: 500px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ul li {
|
ul li {
|
||||||
|
@ -156,14 +156,14 @@ export class HermesClientService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public createRedeemableAction(name: string, type: string, d: { [key: string]: any }) {
|
public createRedeemableAction(name: string, type: string, has_message: boolean, d: { [key: string]: any }) {
|
||||||
if (!this.logged_in)
|
if (!this.logged_in)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.send(3, {
|
this.send(3, {
|
||||||
request_id: null,
|
request_id: null,
|
||||||
type: "create_redeemable_action",
|
type: "create_redeemable_action",
|
||||||
data: { name, type, data: d },
|
data: { name, type, has_message, data: d },
|
||||||
nounce: this.session_id,
|
nounce: this.session_id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -439,14 +439,14 @@ export class HermesClientService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateRedeemableAction(name: string, type: string, d: { [key: string]: any }) {
|
public updateRedeemableAction(name: string, type: string, has_message: boolean, d: { [key: string]: any }) {
|
||||||
if (!this.logged_in)
|
if (!this.logged_in)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.send(3, {
|
this.send(3, {
|
||||||
request_id: null,
|
request_id: null,
|
||||||
type: "update_redeemable_action",
|
type: "update_redeemable_action",
|
||||||
data: { name, type, data: d },
|
data: { name, type, has_message, data: d },
|
||||||
nounce: this.session_id,
|
nounce: this.session_id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
@use '@angular/material' as mat;
|
@use '@angular/material' as mat;
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
background-color: rgb(202, 68, 255);
|
||||||
|
border-radius: 15px;
|
||||||
|
margin: 0 0;
|
||||||
|
padding: 0;
|
||||||
|
max-width: 600px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
@include mat.all-component-densities(-5);
|
@include mat.all-component-densities(-5);
|
||||||
|
|
||||||
@include mat.form-field-overrides((
|
@include mat.form-field-overrides((
|
||||||
@ -8,13 +15,6 @@ ul {
|
|||||||
outlined-focus-label-text-color: rgb(155, 57, 194),
|
outlined-focus-label-text-color: rgb(155, 57, 194),
|
||||||
outlined-focus-outline-color: rgb(155, 57, 194),
|
outlined-focus-outline-color: rgb(155, 57, 194),
|
||||||
));
|
));
|
||||||
|
|
||||||
background-color: rgb(202, 68, 255);
|
|
||||||
border-radius: 15px;
|
|
||||||
margin: 0 0;
|
|
||||||
padding: 0;
|
|
||||||
max-width: 600px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ul li {
|
ul li {
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
@use '@angular/material' as mat;
|
@use '@angular/material' as mat;
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
background-color: rgb(202, 68, 255);
|
||||||
|
border-radius: 15px;
|
||||||
|
margin: 0 0;
|
||||||
|
padding: 0;
|
||||||
|
max-width: 500px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
@include mat.all-component-densities(-5);
|
@include mat.all-component-densities(-5);
|
||||||
|
|
||||||
@include mat.form-field-overrides((
|
@include mat.form-field-overrides((
|
||||||
@ -8,13 +15,6 @@ ul {
|
|||||||
outlined-focus-label-text-color: rgb(155, 57, 194),
|
outlined-focus-label-text-color: rgb(155, 57, 194),
|
||||||
outlined-focus-outline-color: rgb(155, 57, 194),
|
outlined-focus-outline-color: rgb(155, 57, 194),
|
||||||
));
|
));
|
||||||
|
|
||||||
background-color: rgb(202, 68, 255);
|
|
||||||
border-radius: 15px;
|
|
||||||
margin: 0 0;
|
|
||||||
padding: 0;
|
|
||||||
max-width: 500px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ul li {
|
ul li {
|
||||||
|
@ -2,5 +2,6 @@ export default interface RedeemableAction {
|
|||||||
user_id: string;
|
user_id: string;
|
||||||
name: string;
|
name: string;
|
||||||
type: string;
|
type: string;
|
||||||
|
has_message: boolean;
|
||||||
data: any;
|
data: any;
|
||||||
}
|
}
|
@ -22,7 +22,7 @@ export default class RedeemableActionService {
|
|||||||
this.update$ = this.client.filterByRequestType('update_redeemable_action');
|
this.update$ = this.client.filterByRequestType('update_redeemable_action');
|
||||||
this.delete$ = this.client.filterByRequestType('delete_redeemable_action');
|
this.delete$ = this.client.filterByRequestType('delete_redeemable_action');
|
||||||
|
|
||||||
this.create$?.subscribe(d => this.data.push(d.data));
|
this.create$?.subscribe(d => {this.data.push(d.data); console.log('action service add:', d.data) });
|
||||||
this.update$?.subscribe(d => {
|
this.update$?.subscribe(d => {
|
||||||
const action = this.data.find(r => r.name == d.data.name);
|
const action = this.data.find(r => r.name == d.data.name);
|
||||||
if (action) {
|
if (action) {
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
@use '@angular/material' as mat;
|
@use '@angular/material' as mat;
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
background-color: rgb(202, 68, 255);
|
||||||
|
border-radius: 15px;
|
||||||
|
margin: 0 0;
|
||||||
|
padding: 0;
|
||||||
|
max-width: 500px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
@include mat.all-component-densities(-5);
|
@include mat.all-component-densities(-5);
|
||||||
|
|
||||||
@include mat.form-field-overrides((
|
@include mat.form-field-overrides((
|
||||||
@ -8,13 +15,6 @@ ul {
|
|||||||
outlined-focus-label-text-color: rgb(155, 57, 194),
|
outlined-focus-label-text-color: rgb(155, 57, 194),
|
||||||
outlined-focus-outline-color: rgb(155, 57, 194),
|
outlined-focus-outline-color: rgb(155, 57, 194),
|
||||||
));
|
));
|
||||||
|
|
||||||
background-color: rgb(202, 68, 255);
|
|
||||||
border-radius: 15px;
|
|
||||||
margin: 0 0;
|
|
||||||
padding: 0;
|
|
||||||
max-width: 500px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ul li {
|
ul li {
|
||||||
|
Reference in New Issue
Block a user