update pos consumer
This commit is contained in:
@@ -5,16 +5,21 @@ import { Component, EventEmitter, Input, Output, signal } from '@angular/core';
|
||||
template: '',
|
||||
})
|
||||
export abstract class AbstractDialog {
|
||||
@Input()
|
||||
@Input({ required: true })
|
||||
set visible(v: boolean) {
|
||||
this.visibleSignal.set(!!v);
|
||||
this.visibleChange.emit(!!v);
|
||||
if (!v) {
|
||||
this.onClose.emit();
|
||||
}
|
||||
}
|
||||
get visible() {
|
||||
return this.visibleSignal();
|
||||
}
|
||||
private visibleSignal = signal(false);
|
||||
|
||||
@Output() onClose = new EventEmitter<void>();
|
||||
|
||||
close() {
|
||||
this.visible = false;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { TEnumApi } from '../models';
|
||||
|
||||
export const apiEnumTranslates = {
|
||||
goldKarat: '',
|
||||
goldKarat: 'عیار',
|
||||
userStatus: 'وضعیت کاربر',
|
||||
accountRole: 'نقش',
|
||||
accountStatus: 'وضعیت',
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
[class]="` w-full ${size === 'large' ? 'p-inputtext-lg' : size === 'small' ? 'p-inputtext-sm' : ''}`"
|
||||
[required]="isRequired"
|
||||
[invalid]="control.invalid && (control.touched || control.dirty)"
|
||||
(onInput)="onPriceInput($event)"
|
||||
(onBlur)="blur.emit()"
|
||||
/>
|
||||
<!-- (input)="onInput($event)" -->
|
||||
@@ -39,7 +40,9 @@
|
||||
(input)="onInput($event)"
|
||||
/>
|
||||
}
|
||||
@if (preparedSuffix()) {
|
||||
@if (suffixTemp) {
|
||||
<ng-container [ngTemplateOutlet]="suffixTemp" />
|
||||
} @else if (preparedSuffix()) {
|
||||
<p-inputgroup-addon>{{ preparedSuffix() }}</p-inputgroup-addon>
|
||||
}
|
||||
</p-inputgroup>
|
||||
|
||||
@@ -2,12 +2,21 @@ import { Maybe } from '@/core';
|
||||
import { ToastService } from '@/core/services/toast.service';
|
||||
import { UikitFieldComponent } from '@/uikit/uikit-field.component';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, computed, EventEmitter, inject, Input, Output } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
computed,
|
||||
ContentChild,
|
||||
EventEmitter,
|
||||
inject,
|
||||
Input,
|
||||
Output,
|
||||
TemplateRef,
|
||||
} from '@angular/core';
|
||||
import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { InputGroupModule } from 'primeng/inputgroup';
|
||||
import { InputGroupAddon } from 'primeng/inputgroupaddon';
|
||||
import { InputMaskModule } from 'primeng/inputmask';
|
||||
import { InputNumberModule } from 'primeng/inputnumber';
|
||||
import { InputNumberInputEvent, InputNumberModule } from 'primeng/inputnumber';
|
||||
import { InputTextModule } from 'primeng/inputtext';
|
||||
import { KeyFilterModule } from 'primeng/keyfilter';
|
||||
import { ToggleSwitch } from 'primeng/toggleswitch';
|
||||
@@ -33,6 +42,7 @@ export class InputComponent {
|
||||
@Input() type:
|
||||
| 'simple'
|
||||
| 'postalCode'
|
||||
| 'nationalId'
|
||||
| 'mobile'
|
||||
| 'phone'
|
||||
| 'email'
|
||||
@@ -58,6 +68,8 @@ export class InputComponent {
|
||||
@Output() valueChange = new EventEmitter<string | number>();
|
||||
@Output() blur = new EventEmitter<void>();
|
||||
|
||||
@ContentChild('suffixTemp', { static: true }) suffixTemp!: TemplateRef<any> | null;
|
||||
|
||||
private readonly toastService = inject(ToastService);
|
||||
|
||||
// onInput(ev: Event) {
|
||||
@@ -80,6 +92,8 @@ export class InputComponent {
|
||||
return '09xxxxxxxx';
|
||||
case 'postalCode':
|
||||
return 'کد پستی (۱۰ رقم)';
|
||||
case 'nationalId':
|
||||
return 'کد ملی (۱۰ رقم)';
|
||||
case 'phone':
|
||||
return 'شماره تلفن';
|
||||
case 'email':
|
||||
@@ -96,6 +110,7 @@ export class InputComponent {
|
||||
case 'mobile':
|
||||
case 'phone':
|
||||
case 'postalCode':
|
||||
case 'nationalId':
|
||||
case 'price':
|
||||
case 'number':
|
||||
return 'numeric';
|
||||
@@ -113,6 +128,7 @@ export class InputComponent {
|
||||
case 'mobile':
|
||||
return 11;
|
||||
case 'postalCode':
|
||||
case 'nationalId':
|
||||
return 10;
|
||||
case 'phone':
|
||||
return 11;
|
||||
@@ -132,6 +148,7 @@ export class InputComponent {
|
||||
break;
|
||||
case 'email':
|
||||
case 'postalCode':
|
||||
case 'nationalId':
|
||||
inputClass.push('ltrInput', 'rtlPlaceholder');
|
||||
break;
|
||||
}
|
||||
@@ -150,6 +167,7 @@ export class InputComponent {
|
||||
case 'phone':
|
||||
case 'price':
|
||||
case 'postalCode':
|
||||
case 'nationalId':
|
||||
case 'number':
|
||||
return 'number';
|
||||
case 'checkbox':
|
||||
@@ -165,11 +183,22 @@ export class InputComponent {
|
||||
return this.required || this.control.hasValidator(Validators.required);
|
||||
}
|
||||
|
||||
onInput($event: Event) {
|
||||
onPriceInput($event: InputNumberInputEvent) {
|
||||
console.log($event);
|
||||
|
||||
this.onInput($event.originalEvent, true);
|
||||
}
|
||||
onInput($event: Event, isPriceFormat?: boolean) {
|
||||
// @ts-ignore
|
||||
const value = $event.target.value as string;
|
||||
if (this.type === 'number') {
|
||||
let value = $event.target.value as string;
|
||||
|
||||
if (isPriceFormat) {
|
||||
value = value.replace(/,/g, '');
|
||||
}
|
||||
|
||||
if (this.inputMode === 'numeric') {
|
||||
let newValue = parseFloat(value);
|
||||
// console.log(value, newValue);
|
||||
|
||||
const minValidator = (this.min || this.min === 0) && parseFloat(value) < this.min!;
|
||||
const maxValidator = (this.max || this.max === 0) && parseFloat(value) > this.max;
|
||||
@@ -187,10 +216,20 @@ export class InputComponent {
|
||||
}
|
||||
|
||||
newValue = parseFloat(value.slice(0, value.length - 1));
|
||||
// @ts-ignore
|
||||
$event.target.value = newValue;
|
||||
if (newValue < 0 || isNaN(newValue)) {
|
||||
newValue = 0;
|
||||
}
|
||||
|
||||
if (isPriceFormat) {
|
||||
// @ts-ignore
|
||||
$event.target.value = newValue.toLocaleString('en-US');
|
||||
} else {
|
||||
// @ts-ignore
|
||||
$event.target.value = newValue;
|
||||
}
|
||||
|
||||
this.control.setValue(newValue);
|
||||
}
|
||||
this.control.setValue(newValue);
|
||||
}
|
||||
|
||||
if (this.preparedMaxLength && this.preparedMaxLength < value.length) {
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
<div class="inline-flex gap-2 items-center w-full">
|
||||
<span class="text-muted-color text-base font-normal shrink-0">{{ label }}:</span>
|
||||
<ng-content>
|
||||
<span class="text-text-color text-base font-bold grow">{{ value || "-" }}</span>
|
||||
</ng-content>
|
||||
<div class="inline-flex flex-col gap-1 w-full">
|
||||
<div class="inline-flex gap-2 items-center w-full">
|
||||
<span class="text-muted-color text-base font-normal flex-auto grow-0">{{ label }}:</span>
|
||||
<div class="shrink-0 grow">
|
||||
<ng-content>
|
||||
@if (valueType() === "badge") {
|
||||
<p-badge [value]="valueToShow()?.toString()" [severity]="value ? 'success' : 'danger'" />
|
||||
} @else {
|
||||
<span class="text-text-color text-base font-bold grow"> {{ valueToShow() }}</span>
|
||||
}
|
||||
</ng-content>
|
||||
</div>
|
||||
</div>
|
||||
@if (hint) {
|
||||
<span class="text-muted-color text-sm font-normal">{{ hint }}</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { formatDurationToText, formatJalali, JALALI_DATE_FORMATS } from '@/utils';
|
||||
import priceMaskUtils from '@/utils/price-mask.utils';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Component, computed, Input, signal } from '@angular/core';
|
||||
import { Badge } from 'primeng/badge';
|
||||
|
||||
@Component({
|
||||
selector: 'app-key-value',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
imports: [CommonModule, Badge],
|
||||
templateUrl: './key-value.component.html',
|
||||
host: {
|
||||
class: 'w-full block',
|
||||
@@ -12,5 +15,86 @@ import { Component, Input } from '@angular/core';
|
||||
})
|
||||
export class KeyValueComponent {
|
||||
@Input() label!: string;
|
||||
@Input() value?: string = '-';
|
||||
@Input() value?: string | boolean | number;
|
||||
@Input() hint?: string;
|
||||
@Input() type:
|
||||
| 'price'
|
||||
| 'active'
|
||||
| 'boolean'
|
||||
| 'has'
|
||||
| 'date'
|
||||
| 'dateTime'
|
||||
| 'duration'
|
||||
| 'simple' = 'simple';
|
||||
@Input() trueValueToShow?: string;
|
||||
@Input() falseValueToShow?: string;
|
||||
@Input() variant?: 'badge' | 'text';
|
||||
|
||||
valueToShow = signal(this.setValueToShow());
|
||||
|
||||
ngOnChanges() {
|
||||
this.valueToShow.set(this.setValueToShow());
|
||||
}
|
||||
|
||||
setValueToShow() {
|
||||
let value = this.value;
|
||||
if (this.type !== 'simple') {
|
||||
if (this.value) {
|
||||
if (this.trueValueToShow) {
|
||||
value = this.trueValueToShow;
|
||||
} else {
|
||||
switch (this.type) {
|
||||
case 'date':
|
||||
if (typeof this.value === 'boolean') return '-';
|
||||
|
||||
// @ts-ignore
|
||||
return formatJalali(this.value);
|
||||
case 'dateTime':
|
||||
if (typeof this.value === 'boolean') return '-';
|
||||
// @ts-ignore
|
||||
|
||||
return formatJalali(this.value, JALALI_DATE_FORMATS.NUMERIC_WITH_TIME);
|
||||
case 'duration':
|
||||
return formatDurationToText(this.value as string);
|
||||
case 'price':
|
||||
return priceMaskUtils.formatWithCurrency(this.value as number);
|
||||
case 'active':
|
||||
value = 'فعال';
|
||||
break;
|
||||
case 'boolean':
|
||||
value = 'بله';
|
||||
break;
|
||||
case 'has':
|
||||
value = 'دارد';
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.falseValueToShow) {
|
||||
value = this.falseValueToShow;
|
||||
} else {
|
||||
switch (this.type) {
|
||||
case 'active':
|
||||
value = 'غیر فعال';
|
||||
break;
|
||||
case 'boolean':
|
||||
value = 'خیر';
|
||||
break;
|
||||
case 'has':
|
||||
value = 'ندارد';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (this.type) {
|
||||
case 'simple':
|
||||
return this.value || '';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
valueType = computed(() =>
|
||||
this.variant || ['boolean', 'has', 'active'].includes(this.type) ? 'badge' : 'text',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export const CustomerType = {
|
||||
INDIVIDUAL: 'INDIVIDUAL',
|
||||
LEGAL: 'LEGAL',
|
||||
UNKNOWN: 'UNKNOWN',
|
||||
} as const;
|
||||
|
||||
export type CustomerType = (typeof CustomerType)[keyof typeof CustomerType];
|
||||
@@ -0,0 +1,21 @@
|
||||
import { ISelectItem } from '@/shared/abstractClasses';
|
||||
|
||||
export const goldKarat = {
|
||||
KARAT_18: 'KARAT_18',
|
||||
KARAT_21: 'KARAT_21',
|
||||
KARAT_24: 'KARAT_24',
|
||||
} as const;
|
||||
export type TGoldKarat = (typeof goldKarat)[keyof typeof goldKarat];
|
||||
|
||||
const translates: Record<string, string> = {
|
||||
KARAT_18: '18',
|
||||
KARAT_21: '21',
|
||||
KARAT_24: '24',
|
||||
};
|
||||
|
||||
export const goldKaratSelect: ISelectItem[] = Object.keys(goldKarat).map((key) => ({
|
||||
id: key,
|
||||
name: translates[key],
|
||||
}));
|
||||
|
||||
export const goldKaratLabel = 'عیار';
|
||||
@@ -0,0 +1,8 @@
|
||||
import { goldKaratLabel, goldKaratSelect } from './goldKarat';
|
||||
|
||||
export const LOCAL_ENUMS = {
|
||||
gold: {
|
||||
label: goldKaratLabel,
|
||||
items: goldKaratSelect,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './io';
|
||||
export * from './types';
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
export interface IEnumResponse {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { LOCAL_ENUMS } from '../constants';
|
||||
|
||||
export type TLocalEnum = keyof typeof LOCAL_ENUMS;
|
||||
@@ -0,0 +1,12 @@
|
||||
<uikit-field [label]="label()" [control]="control" [showLabel]="showLabel" [showErrors]="showErrors">
|
||||
<p-select
|
||||
[loading]="loading()"
|
||||
[options]="items()"
|
||||
optionLabel="name"
|
||||
optionValue="value"
|
||||
[formControl]="control"
|
||||
[showClear]="showClear"
|
||||
[filter]="true"
|
||||
appendTo="body"
|
||||
/>
|
||||
</uikit-field>
|
||||
@@ -0,0 +1,30 @@
|
||||
import { UikitFieldComponent } from '@/uikit';
|
||||
import { Component, computed, Input } from '@angular/core';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { Select } from 'primeng/select';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AbstractSelectComponent, ISelectItem } from '../abstractClasses';
|
||||
import { LOCAL_ENUMS } from './constants';
|
||||
import { TLocalEnum } from './models';
|
||||
|
||||
@Component({
|
||||
selector: 'app-enum-select',
|
||||
templateUrl: './select.component.html',
|
||||
imports: [UikitFieldComponent, Select, ReactiveFormsModule],
|
||||
})
|
||||
export class EnumSelectComponent extends AbstractSelectComponent<ISelectItem, ISelectItem[]> {
|
||||
@Input() type!: TLocalEnum;
|
||||
@Input() customLabel?: string;
|
||||
|
||||
label = computed(() => this.customLabel ?? LOCAL_ENUMS[this.type].label);
|
||||
|
||||
override getDataService() {
|
||||
return new Observable<ISelectItem[]>((observer) => {
|
||||
return observer.next(LOCAL_ENUMS[this.type].items);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.getData();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user