feat: update app version in ngsw-config.json; refactor input component for leading zero normalization and improve payment dialog handling
This commit is contained in:
+5
-13
@@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
|
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
|
||||||
"appData": {
|
"appData": {
|
||||||
"appVersion": "0.0.14",
|
"appVersion": "0.0.17",
|
||||||
"buildDate": "2026-05-16T13:47:08.720Z",
|
"buildDate": "2026-05-16T16:43:54.103Z",
|
||||||
"buildNumber": 14
|
"buildNumber": 17
|
||||||
},
|
},
|
||||||
"assetGroups": [
|
"assetGroups": [
|
||||||
{
|
{
|
||||||
@@ -12,9 +12,7 @@
|
|||||||
"resources": {
|
"resources": {
|
||||||
"files": [
|
"files": [
|
||||||
"/favicon.ico",
|
"/favicon.ico",
|
||||||
"/index.html",
|
"/index.html"
|
||||||
"/*.css",
|
|
||||||
"/*.js"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"updateMode": "prefetch"
|
"updateMode": "prefetch"
|
||||||
@@ -42,11 +40,5 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dataGroups": [],
|
"dataGroups": [],
|
||||||
"index": "/index.html",
|
"index": "/index.html"
|
||||||
"navigationUrls": [
|
|
||||||
"/**",
|
|
||||||
"!/**/*.*",
|
|
||||||
"!/**/*__*",
|
|
||||||
"!/**/*__*/**"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,6 +119,15 @@ export class PosPagesLayoutComponent {
|
|||||||
this.layoutService.setTopbarEndSlot(this.topbarEnd);
|
this.layoutService.setTopbarEndSlot(this.topbarEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ngAfterViewInit() {
|
||||||
|
// // @ts-ignore
|
||||||
|
// window.WebV = {
|
||||||
|
// onPaymentResult: (payload: unknown) => {
|
||||||
|
// console.log('payload', payload);
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.layoutService.changeIsFullPage(false);
|
this.layoutService.changeIsFullPage(false);
|
||||||
this.layoutService.setTopbarStartSlot(null);
|
this.layoutService.setTopbarStartSlot(null);
|
||||||
|
|||||||
@@ -31,16 +31,16 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
|
|||||||
IPosOrderItem<IGoldPayload>,
|
IPosOrderItem<IGoldPayload>,
|
||||||
IPosOrderItem<IGoldPayload>
|
IPosOrderItem<IGoldPayload>
|
||||||
> {
|
> {
|
||||||
// override defaultValues: Partial<IPosOrderItem<IGoldPayload>> = {
|
override defaultValues: Partial<IPosOrderItem<IGoldPayload>> = {
|
||||||
// unit_price: 200_000_000,
|
unit_price: 200_000_000,
|
||||||
// quantity: 2,
|
quantity: 2,
|
||||||
// payload: {
|
payload: {
|
||||||
// commission: 10_000,
|
// commission: 10_000,
|
||||||
// wages: 10_000,
|
// wages: 10_000,
|
||||||
// profit: 10_000,
|
// profit: 10_000,
|
||||||
// karat: '18' as TGoldKarat,
|
karat: 'KARAT_18' as TGoldKarat,
|
||||||
// } as any,
|
} as any,
|
||||||
// };
|
};
|
||||||
|
|
||||||
@Output() onSubmitForm = new EventEmitter<IGoldPayload>();
|
@Output() onSubmitForm = new EventEmitter<IGoldPayload>();
|
||||||
@Output() onChangeTotalAmount = new EventEmitter<number>();
|
@Output() onChangeTotalAmount = new EventEmitter<number>();
|
||||||
|
|||||||
+1
-1
@@ -27,6 +27,6 @@
|
|||||||
[discountAmount]="discountAmount()"
|
[discountAmount]="discountAmount()"
|
||||||
[taxAmount]="taxAmount()"
|
[taxAmount]="taxAmount()"
|
||||||
/>
|
/>
|
||||||
<p-button class="sm:w-auto w-full" (onClick)="submit()"> {{ preparedCTAText() }} </p-button>
|
<button pButton class="sm:w-auto w-full" (onClick)="submit()">{{ preparedCTAText() }}</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { formatWithCurrency } from '@/utils';
|
|||||||
import { Component, computed, EventEmitter, Input, Output, signal } from '@angular/core';
|
import { Component, computed, EventEmitter, Input, Output, signal } from '@angular/core';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { Button } from 'primeng/button';
|
import { ButtonDirective } from 'primeng/button';
|
||||||
import { IPosOrderItem, IStandardPayload } from '../../../models';
|
import { IPosOrderItem, IStandardPayload } from '../../../models';
|
||||||
import { PosFormDialogAmountCardTemplateComponent } from '../form-dialog-amount-card-template.component';
|
import { PosFormDialogAmountCardTemplateComponent } from '../form-dialog-amount-card-template.component';
|
||||||
|
|
||||||
@@ -16,9 +16,9 @@ import { PosFormDialogAmountCardTemplateComponent } from '../form-dialog-amount-
|
|||||||
imports: [
|
imports: [
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
InputComponent,
|
InputComponent,
|
||||||
Button,
|
|
||||||
PosFormDialogAmountCardTemplateComponent,
|
PosFormDialogAmountCardTemplateComponent,
|
||||||
AmountPercentageInputComponent,
|
AmountPercentageInputComponent,
|
||||||
|
ButtonDirective,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class PosStandardPayloadFormComponent extends AbstractForm<
|
export class PosStandardPayloadFormComponent extends AbstractForm<
|
||||||
|
|||||||
@@ -57,12 +57,16 @@ export class PosPaymentFormDialogComponent extends AbstractFormDialog<IPayment,
|
|||||||
payedInTerminal = signal<Array<number>>([]);
|
payedInTerminal = signal<Array<number>>([]);
|
||||||
|
|
||||||
private restorePaymentCallback: Maybe<() => void> = null;
|
private restorePaymentCallback: Maybe<() => void> = null;
|
||||||
|
|
||||||
private readonly injectedPaymentResultHandler = (payload: unknown) => {
|
private readonly injectedPaymentResultHandler = (payload: unknown) => {
|
||||||
|
alert('پرداخت با موفقیت انجام شد');
|
||||||
this.toastServices.success({ text: 'شد شد شد شد شد' });
|
this.toastServices.success({ text: 'شد شد شد شد شد' });
|
||||||
// this.handlePaymentResult(payload);
|
// this.handlePaymentResult(payload);
|
||||||
};
|
};
|
||||||
|
|
||||||
ngOnViewInit() {
|
ngAfterViewInit() {
|
||||||
|
console.log('ngOnViewInit');
|
||||||
|
|
||||||
this.restorePaymentCallback = this.paymentBridge.registerPaymentResultListener(
|
this.restorePaymentCallback = this.paymentBridge.registerPaymentResultListener(
|
||||||
this.injectedPaymentResultHandler,
|
this.injectedPaymentResultHandler,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,36 +1,33 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { ToastService } from '@/core/services/toast.service';
|
||||||
|
import { inject, Injectable } from '@angular/core';
|
||||||
import { PosPaymentBridgeAbstract } from './payment-bridge.abstract';
|
import { PosPaymentBridgeAbstract } from './payment-bridge.abstract';
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class PosPaymentBridgeService extends PosPaymentBridgeAbstract {
|
export class PosPaymentBridgeService extends PosPaymentBridgeAbstract {
|
||||||
|
private readonly toastServices = inject(ToastService);
|
||||||
registerPaymentResultListener(handler: (payload: unknown) => void): () => void {
|
registerPaymentResultListener(handler: (payload: unknown) => void): () => void {
|
||||||
const w = window as unknown as {
|
// const w = window as unknown as {
|
||||||
WebV: {
|
// WebV?: {
|
||||||
onPaymentResult?: (payload: unknown) => void;
|
// onPaymentResult?: (payload: unknown) => void;
|
||||||
AndroidBridge?: {
|
// AndroidBridge?: {
|
||||||
onPaymentResult?: (payload: unknown) => void;
|
// onPaymentResult?: (payload: unknown) => void;
|
||||||
};
|
// };
|
||||||
};
|
// };
|
||||||
|
// };
|
||||||
|
this.toastServices.error({ text: '@@@@@@@@@@@@@' });
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
window.webV = {
|
||||||
|
onPaymentResult: () => {
|
||||||
|
this.toastServices.error({ text: 'asdasdsadassadasdas' });
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const previousGlobal = w.WebV.onPaymentResult;
|
return () => {};
|
||||||
const previousBridge = w.WebV.AndroidBridge?.onPaymentResult;
|
|
||||||
|
|
||||||
w.WebV.onPaymentResult = handler;
|
|
||||||
if (w.WebV.AndroidBridge) {
|
|
||||||
w.WebV.AndroidBridge.onPaymentResult = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
w.WebV.onPaymentResult = previousGlobal;
|
|
||||||
if (w.WebV.AndroidBridge) {
|
|
||||||
w.WebV.AndroidBridge.onPaymentResult = previousBridge;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emitPaymentResultForTest(payload: unknown): void {
|
emitPaymentResultForTest(payload: unknown): void {
|
||||||
const w = window as unknown as { WebV: { onPaymentResult?: (payload: unknown) => void } };
|
const w = window as unknown as { WebV?: { onPaymentResult?: (payload: unknown) => void } };
|
||||||
w.WebV.onPaymentResult?.(payload);
|
w.WebV?.onPaymentResult?.(payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import { ToggleSwitch } from 'primeng/toggleswitch';
|
|||||||
templateUrl: './input.component.html',
|
templateUrl: './input.component.html',
|
||||||
})
|
})
|
||||||
export class InputComponent {
|
export class InputComponent {
|
||||||
|
private lastValidNumericValue = '';
|
||||||
@Input() type:
|
@Input() type:
|
||||||
| 'simple'
|
| 'simple'
|
||||||
| 'postalCode'
|
| 'postalCode'
|
||||||
@@ -226,6 +227,21 @@ export class InputComponent {
|
|||||||
return `${normalizedInteger}.${fixedDecimal}`;
|
return `${normalizedInteger}.${fixedDecimal}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private normalizeLeadingZeros(value: string, allowDecimal: boolean): string {
|
||||||
|
if (!value) return value;
|
||||||
|
if (!allowDecimal) {
|
||||||
|
return value.replace(/^0+(?=\d)/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.includes('.')) {
|
||||||
|
const [integerPart = '0', decimalPart = ''] = value.split('.');
|
||||||
|
const normalizedInteger = integerPart.replace(/^0+(?=\d)/, '') || '0';
|
||||||
|
return `${normalizedInteger}.${decimalPart}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.replace(/^0+(?=\d)/, '');
|
||||||
|
}
|
||||||
|
|
||||||
onInput($event: Event, isPriceFormat?: boolean) {
|
onInput($event: Event, isPriceFormat?: boolean) {
|
||||||
const target = $event.target as HTMLInputElement | null;
|
const target = $event.target as HTMLInputElement | null;
|
||||||
if (!target) return;
|
if (!target) return;
|
||||||
@@ -236,6 +252,7 @@ export class InputComponent {
|
|||||||
if (this.inputMode === 'numeric' || this.inputMode === 'decimal' || isPriceFormat) {
|
if (this.inputMode === 'numeric' || this.inputMode === 'decimal' || isPriceFormat) {
|
||||||
value = this.sanitizeNumericValue(value, allowDecimal);
|
value = this.sanitizeNumericValue(value, allowDecimal);
|
||||||
value = this.applyFixed(value);
|
value = this.applyFixed(value);
|
||||||
|
value = this.normalizeLeadingZeros(value, allowDecimal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.preparedMaxLength && value.length > this.preparedMaxLength) {
|
if (this.preparedMaxLength && value.length > this.preparedMaxLength) {
|
||||||
@@ -260,12 +277,23 @@ export class InputComponent {
|
|||||||
text: `مقدار ${this.label} نمیتواند کمتر از ${this.min} باشد.`,
|
text: `مقدار ${this.label} نمیتواند کمتر از ${this.min} باشد.`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
value = value.slice(0, -1);
|
value = this.lastValidNumericValue;
|
||||||
numericValue = Number.isNaN(parseFloat(value)) ? 0 : parseFloat(value);
|
numericValue = Number.isNaN(parseFloat(value)) ? 0 : parseFloat(value);
|
||||||
|
|
||||||
|
const isIdentifierField = ['mobile', 'phone', 'postalCode', 'nationalId'].includes(this.type);
|
||||||
|
const restoredControlValue = isIdentifierField ? value : value === '' ? '' : numericValue;
|
||||||
|
|
||||||
|
this.control.setValue(restoredControlValue);
|
||||||
|
target.value = isPriceFormat && value !== '' ? numericValue.toLocaleString('en-US') : value;
|
||||||
|
return;
|
||||||
|
} else if (this.inputMode === 'numeric' || this.inputMode === 'decimal') {
|
||||||
|
this.lastValidNumericValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isIdentifierField = !this.numericValue;
|
const isIdentifierField = ['mobile', 'phone', 'postalCode', 'nationalId'].includes(this.type);
|
||||||
this.control.setValue(isIdentifierField ? value : value === '' ? '' : numericValue);
|
const controlValue = isIdentifierField ? value : value === '' ? '' : numericValue;
|
||||||
|
|
||||||
|
this.control.setValue(controlValue);
|
||||||
|
|
||||||
const viewValue = isPriceFormat && value !== '' ? numericValue.toLocaleString('en-US') : value;
|
const viewValue = isPriceFormat && value !== '' ? numericValue.toLocaleString('en-US') : value;
|
||||||
|
|
||||||
@@ -277,4 +305,10 @@ export class InputComponent {
|
|||||||
this.valueChange.emit(isIdentifierField ? value : numericValue);
|
this.valueChange.emit(isIdentifierField ? value : numericValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
const allowDecimal = this.type === 'price' || this.type === 'number';
|
||||||
|
const initial = this.sanitizeNumericValue(`${this.control?.value ?? ''}`, allowDecimal);
|
||||||
|
this.lastValidNumericValue = initial;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user