Skip to content
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Component, EventEmitter, Input, Output, booleanAttribute } from '@angular/core';
import { first, timer } from 'rxjs';

import { Component, EventEmitter, Input, OnInit, Output, booleanAttribute } from '@angular/core';
import { MatFormFieldAppearance } from '@angular/material/form-field';

import { FormControlSuperclass, createControlProviders } from '../../../utils';
Expand All @@ -13,7 +15,10 @@ import { getHintText } from '../utils/get-hint-text';
providers: createControlProviders(() => SelectFieldComponent),
standalone: false,
})
export class SelectFieldComponent<T = unknown> extends FormControlSuperclass<T[]> {
export class SelectFieldComponent<T = unknown>
extends FormControlSuperclass<T[]>
implements OnInit
{
@Input() options: Option<T>[] = [];
@Output() searchChange = new EventEmitter<string>();

Expand All @@ -32,6 +37,17 @@ export class SelectFieldComponent<T = unknown> extends FormControlSuperclass<T[]

searchStr: string = '';

override ngOnInit() {
super.ngOnInit();
if (this.externalSearch) {
timer(0)
.pipe(first())
.subscribe(() => {
this.searchChange.emit(String(this.control.value));
});
}
}

get hintText() {
return getHintText(
this.options,
Expand Down
28 changes: 28 additions & 0 deletions projects/matez/src/lib/services/app-mode/app-mode.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Injectable, computed, effect, signal } from '@angular/core';

type AppMode = 'simple' | 'advanced';

@Injectable({
providedIn: 'root',
})
export class AppModeService {
mode = signal<AppMode>(this.getInitialMode());

isSimple = computed(() => this.mode() === 'simple');
isAdvanced = computed(() => this.mode() === 'advanced');

constructor() {
effect(() => {
localStorage.setItem('app-mode', this.mode());
});
}

private getInitialMode(): AppMode {
const stored = localStorage.getItem('app-mode');
return (stored as AppMode) || 'simple';
}

setMode(mode: AppMode): void {
this.mode.set(mode);
}
}
1 change: 1 addition & 0 deletions projects/matez/src/lib/services/app-mode/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './app-mode.service';
1 change: 1 addition & 0 deletions projects/matez/src/lib/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './query-params';
export * from './url.service';
export * from './toast';
export * from './theme';
export * from './app-mode';
33 changes: 26 additions & 7 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,22 @@
>
{{ username().slice(0, 2).toUpperCase() }}
</button>
<button
[matMenuTriggerFor]="themeMenu"
[matTooltip]="(themeService.theme() | titlecase) + ' theme'"
mat-icon-button
>
<mat-icon>{{ getThemeIcon() }}</mat-icon>
</button>
<div class="flex items-center">
<button
[matMenuTriggerFor]="themeMenu"
[matTooltip]="(themeService.theme() | titlecase) + ' theme'"
mat-icon-button
>
<mat-icon>{{ getThemeIcon() }}</mat-icon>
</button>
<button
[matMenuTriggerFor]="modeMenu"
[matTooltip]="(modeService.mode() | titlecase) + ' mode'"
mat-icon-button
>
<mat-icon>{{ getModeIcon() }}</mat-icon>
</button>
</div>
<mat-menu #themeMenu="matMenu">
<button mat-menu-item (click)="themeService.setTheme('light')">
<mat-icon>{{ getThemeIcon('light') }}</mat-icon>
Expand All @@ -58,6 +67,16 @@
<span>Logout</span>
</button>
</mat-menu>
<mat-menu #modeMenu="matMenu">
<button mat-menu-item (click)="modeService.setMode('simple')">
<mat-icon>{{ getModeIcon('simple') }}</mat-icon>
<span>Simple</span>
</button>
<button mat-menu-item (click)="modeService.setMode('advanced')">
<mat-icon>{{ getModeIcon('advanced') }}</mat-icon>
<span>Advanced</span>
</button>
</mat-menu>
</div>
</div>
</mat-sidenav>
Expand Down
6 changes: 6 additions & 0 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { Router, RouterOutlet } from '@angular/router';

import {
AppModeService,
BaseLink,
CmdkModule,
CmdkOption,
Expand Down Expand Up @@ -228,6 +229,7 @@ export class AppComponent {

sidenavInfoService = inject(SidenavInfoService);
themeService = inject(ThemeService);
protected modeService = inject(AppModeService);

links = createNavLinks();
username = this.keycloakUserService.username;
Expand Down Expand Up @@ -282,6 +284,10 @@ export class AppComponent {
}
}

getModeIcon(mode = this.modeService.mode()): string {
return mode === 'advanced' ? 'school' : 'wand_stars';
}

private registerConsoleUtils() {
Object.assign(window as never as object, {
ccSwitchLogging: () => {
Expand Down
8 changes: 4 additions & 4 deletions src/app/deposits/deposits.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
import { getUnionKey } from '@vality/ng-thrift';

import { QueryDsl } from '~/api/fistful-stat';
import { createCurrencyColumn } from '~/utils';
import { createCurrencyColumn, createDomainObjectColumn } from '~/utils';

import { DATE_RANGE_DAYS, DEBOUNCE_TIME_MS } from '../tokens';

Expand Down Expand Up @@ -89,9 +89,9 @@ export class DepositsComponent implements OnInit {
field: 'created_at',
cell: { type: 'datetime' },
},
{
field: 'destination_id',
},
createDomainObjectColumn((d) => ({ ref: { wallet_config: { id: d.destination_id } } }), {
header: 'Destination',
}),
{
field: 'identity_id',
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<cc-page-layout
[id]="(ruleset$ | async)?.ref?.id"
[title]="((routingRulesType$ | async) === 'payment' ? 'Shop' : 'Wallet') + ' Routing Rules'"
[upLink]="[
'/parties/' +
(partyID$ | async) +
'/routing-rules/' +
(routingRulesType$ | async) +
'/' +
(partyRulesetRefID$ | async),
]"
fullHeight
(idLinkClick)="openRefId()"
>
<cc-page-layout-actions>
<button mat-flat-button (click)="addRule()">Add</button>
</cc-page-layout-actions>
@if (appMode.isAdvanced()) {
<v-table
[(sort)]="sort"
[columns]="columns"
[data]="(candidates$ | async) || []"
[progress]="isLoading$ | async"
[rowDragDrop]="['priority']"
standaloneFilter
(rowDropped)="drop($any($event))"
></v-table>
} @else {
@if (candidateGroups$ | async; as groups) {
<cc-dnd-cards [rows]="groups" (dropped)="cardDrop($event)">
<ng-template #card let-item>
@if (!!item?.terminal) {
<div
class="flex flex-col gap-2 items-start w-full min-w-0 h-full justify-between"
>
<div class="flex gap-2 w-full justify-between">
<div
[matTooltip]="
'#' +
item.candidate.terminal.id +
': ' +
item.terminal?.object?.terminal?.data?.name
"
class="min-w-0 truncate"
>
{{ item.terminal?.object?.terminal?.data?.name }}
</div>
<div
[matTooltip]="'Weight: ' + item.candidate.weight"
class="text-foreground-muted"
>
{{ item.weightPercent }}%
</div>
</div>
@if (!!item?.fullAllowedStr) {
<div
[matTooltip]="item.fullAllowedStr"
class="truncate text-foreground-muted w-full min-w-0"
>
{{ item.fullAllowedStr }}
</div>
}
<div class="flex items-center justify-between w-full gap-2">
<mat-slide-toggle
[checked]="item.allowed"
[matTooltip]="item.fullAllowedStr"
class="min-w-0"
(change)="toggleAllow(item.idx)"
></mat-slide-toggle>
<div class="flex">
<button mat-icon-button (click)="edit(item.idx)">
<mat-icon>edit</mat-icon>
</button>
<button [matMenuTriggerFor]="menu" mat-icon-button>
<mat-icon>more_vert</mat-icon>
</button>
</div>
<mat-menu #menu="matMenu">
<button mat-menu-item (click)="editRule(item.idx)">
<mat-icon>edit</mat-icon>
<span>Advanced edit</span>
</button>
<button mat-menu-item (click)="duplicateRule(item.idx)">
<mat-icon>content_copy</mat-icon>
<span>Duplicate</span>
</button>
<button mat-menu-item (click)="removeRule(item.idx)">
<mat-icon>delete</mat-icon>
<span>Remove</span>
</button>
</mat-menu>
</div>
</div>
} @else {
Loading...
}
</ng-template>
</cc-dnd-cards>
}
}
</cc-page-layout>
Loading
Loading