feat: refactor dialog components to use light-bottomsheet for improved UX
- Replaced SharedDialogComponent with SharedLightBottomsheetComponent in customer-dialog, order-submitted-dialog, payment form-dialog, and pre-invoice-dialog components. - Updated styles and properties for light-bottomsheet to enhance responsiveness and usability. - Modified payload form components to use measure units instead of unit types for better clarity. - Adjusted form controls to use consistent naming conventions for amounts and percentages. - Enhanced support for overlay options in select components to manage z-index dynamically. - Improved support for RTL layouts in input groups and other components.
This commit is contained in:
+3
-3
@@ -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.9",
|
"appVersion": "0.0.10",
|
||||||
"buildDate": "2026-05-13T06:42:17.700Z",
|
"buildDate": "2026-05-13T09:21:01.165Z",
|
||||||
"buildNumber": 9
|
"buildNumber": 10
|
||||||
},
|
},
|
||||||
"assetGroups": [
|
"assetGroups": [
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-3
@@ -1,6 +1,5 @@
|
|||||||
import ISummary from '@/core/models/summary';
|
import ISummary from '@/core/models/summary';
|
||||||
import { TCustomerInfo, TPosOrderGoodPayload } from '@/domains/pos/modules/landing/models';
|
import { TCustomerInfo, TPosOrderGoodPayload } from '@/domains/pos/modules/landing/models';
|
||||||
import { UnitType } from '@/utils';
|
|
||||||
|
|
||||||
export interface ISalesInvoicesRawResponse {
|
export interface ISalesInvoicesRawResponse {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -29,7 +28,7 @@ interface Payment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Item {
|
interface Item {
|
||||||
unit_type: UnitType;
|
measure_unit: ISummary;
|
||||||
discount: string;
|
discount: string;
|
||||||
quantity: string;
|
quantity: string;
|
||||||
total_amount: string;
|
total_amount: string;
|
||||||
@@ -46,6 +45,6 @@ interface Good {
|
|||||||
barcode: null;
|
barcode: null;
|
||||||
local_sku: null;
|
local_sku: null;
|
||||||
pricing_model: string;
|
pricing_model: string;
|
||||||
unit_type: string;
|
measure_unit: ISummary;
|
||||||
category: ISummary;
|
category: ISummary;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,14 +31,14 @@
|
|||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@if (isPwaBuild) {
|
||||||
<div class="mt-auto">
|
<div class="mt-auto">
|
||||||
<hr class="mb-4 mx-4 border-t border-0 border-surface" />
|
<hr class="mb-4 mx-4 border-t border-0 border-surface" />
|
||||||
@if (isPwaBuild) {
|
|
||||||
<div class="px-6 pb-6 text-sm text-muted-color">
|
<div class="px-6 pb-6 text-sm text-muted-color">
|
||||||
نسخه برنامه : <span class="font-semibold">{{ appVersion }}</span>
|
نسخه برنامه : <span class="font-semibold">{{ appVersion }}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</p-drawer>
|
</p-drawer>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export class PosMainMenuSidebarComponent extends AbstractDialog {
|
|||||||
icon: 'pi pi-fw pi-cog',
|
icon: 'pi pi-fw pi-cog',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'درباره ما',
|
label: 'درباره نرمافزار',
|
||||||
routerLink: posAboutNamedRoutes.about.meta.pagePath!(),
|
routerLink: posAboutNamedRoutes.about.meta.pagePath!(),
|
||||||
icon: 'pi pi-fw pi-info-circle',
|
icon: 'pi pi-fw pi-info-circle',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,15 +2,7 @@ import { AuthService } from '@/core';
|
|||||||
import { LayoutService } from '@/layout/service/layout.service';
|
import { LayoutService } from '@/layout/service/layout.service';
|
||||||
import { PageLoadingComponent } from '@/shared/components/page-loading.component';
|
import { PageLoadingComponent } from '@/shared/components/page-loading.component';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import {
|
import { Component, TemplateRef, ViewChild, computed, inject, signal } from '@angular/core';
|
||||||
AfterViewInit,
|
|
||||||
Component,
|
|
||||||
TemplateRef,
|
|
||||||
ViewChild,
|
|
||||||
computed,
|
|
||||||
inject,
|
|
||||||
signal,
|
|
||||||
} from '@angular/core';
|
|
||||||
import { RouterLinkWithHref, RouterOutlet } from '@angular/router';
|
import { RouterLinkWithHref, RouterOutlet } from '@angular/router';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from 'primeng/api';
|
||||||
import { Button, ButtonDirective } from 'primeng/button';
|
import { Button, ButtonDirective } from 'primeng/button';
|
||||||
@@ -38,7 +30,7 @@ import { PosChooseCardsComponent } from './choose-pos.component';
|
|||||||
RouterOutlet,
|
RouterOutlet,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class PosPagesLayoutComponent implements AfterViewInit {
|
export class PosPagesLayoutComponent {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
// private readonly nativeBridgeService = inject(NativeBridgeService);
|
// private readonly nativeBridgeService = inject(NativeBridgeService);
|
||||||
@@ -118,9 +110,6 @@ export class PosPagesLayoutComponent implements AfterViewInit {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.layoutService.changeIsFullPage(true);
|
this.layoutService.changeIsFullPage(true);
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewInit() {
|
|
||||||
this.layoutService.setTopbarStartSlot(this.topbarStart);
|
this.layoutService.setTopbarStartSlot(this.topbarStart);
|
||||||
this.layoutService.setTopbarCenterSlot(this.topbarCenter);
|
this.layoutService.setTopbarCenterSlot(this.topbarCenter);
|
||||||
this.layoutService.setTopbarEndSlot(this.topbarEnd);
|
this.layoutService.setTopbarEndSlot(this.topbarEnd);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import ISummary from '@/core/models/summary';
|
import ISummary from '@/core/models/summary';
|
||||||
import { UnitType } from '@/utils';
|
|
||||||
|
|
||||||
export interface IGoodRawResponse {
|
export interface IGoodRawResponse {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -10,7 +9,7 @@ export interface IGoodRawResponse {
|
|||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
category: ISummary;
|
category: ISummary;
|
||||||
unit_type: UnitType;
|
measure_unit: ISummary;
|
||||||
pricing_model: string;
|
pricing_model: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
image_url: string;
|
image_url: string;
|
||||||
|
|||||||
@@ -1,6 +1,55 @@
|
|||||||
<div class="w-full h-full min-h-[60svh] flex items-center justify-center p-4">
|
<div class="w-full min-h-[60svh] p-4 md:p-6">
|
||||||
<div class="text-center">
|
<section class="mx-auto max-w-3xl overflow-hidden rounded-2xl border border-surface-200 bg-white">
|
||||||
<h2 class="text-xl font-semibold mb-2">درباره سیستم</h2>
|
<div class="bg-gradient-to-l from-emerald-50 via-teal-50 to-cyan-50 p-5 md:p-7">
|
||||||
<p class="text-muted-color">این صفحه به زودی تکمیل می شود.</p>
|
<p class="mb-2 inline-flex items-center rounded-full bg-white px-3 py-1 text-xs font-semibold text-emerald-700">
|
||||||
|
{{ brandingInfo.appTitle }}
|
||||||
|
</p>
|
||||||
|
<span class="block mb-4 text-xl font-bold text-surface-900 md:text-3xl">درباره نسخه تیس</span>
|
||||||
|
<p class="mt-3 max-w-2xl text-sm leading-7 text-surface-700 md:text-base">
|
||||||
|
این نسخه برای استفاده روزانه روی دستگاه های PSP بهینه شده است تا عملیات ثبت و صدور صورتحسابهای مالیاتی با سرعت
|
||||||
|
بالاتر، پایداری بیشتر و تجربه کاربری ساده تر انجام شود.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid gap-3 p-4 md:grid-cols-3 md:gap-4 md:p-6">
|
||||||
|
<!-- <article class="rounded-xl border border-surface-200 bg-surface-50 p-4">
|
||||||
|
<h2 class="mb-2 text-sm font-bold text-surface-900">پایداری در وب ویو</h2>
|
||||||
|
<p class="text-sm leading-6 text-surface-700">
|
||||||
|
رفتار رابط کاربری برای محیط WebView تنظیم شده تا روی سخت افزارهای ضعیف تر هم اجرای روان تری داشته باشد.
|
||||||
|
</p>
|
||||||
|
</article> -->
|
||||||
|
|
||||||
|
<article class="rounded-xl border border-surface-200 bg-surface-50 p-4">
|
||||||
|
<span class="block mb-4 text-xl font-bold text-surface-900">تمرکز بر سرعت عملیات</span>
|
||||||
|
<p class="text-sm leading-6 text-surface-700">
|
||||||
|
مسیرهای کلیدی مانند انتخاب کالا، ورود مقادیر و ثبت نهایی برای کاهش تاخیر و افزایش سرعت کاربر بهینه شده اند.
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="rounded-xl border border-surface-200 bg-surface-50 p-4">
|
||||||
|
<span class="block mb-4 text-xl font-bold text-surface-900">سازگار با سناریوهای فروش</span>
|
||||||
|
<p class="text-sm leading-6 text-surface-700">
|
||||||
|
طراحی این نسخه بر مبنای سناریوهای واقعی فروشگاه انجام شده تا اپراتور با کمترین کلیک فرآیند را تکمیل کند.
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mx-4 mb-4 rounded-xl border border-surface-200 bg-surface-50 p-4 md:mx-6">
|
||||||
|
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||||
|
<div class="text-sm text-surface-700">
|
||||||
|
نسخه برنامه:
|
||||||
|
<span class="font-semibold text-surface-900">{{ appVersion() }}</span>
|
||||||
|
</div>
|
||||||
|
<button pButton type="button" [outlined]="!hasUpdate()" [disabled]="isCheckingUpdate()" (click)="onUpdateCtaClick()">
|
||||||
|
{{ updateCtaLabel() }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="border-t border-surface-200 bg-surface-50 px-4 py-4 md:px-6">
|
||||||
|
<p class="text-xs leading-6 text-surface-600 md:text-sm">
|
||||||
|
در صورت نیاز به راهنمایی بیشتر، به صفحهی راهنمای استفاده مراجعه کنید یا با پشتیبانی تماس بگیرید.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,87 @@
|
|||||||
import { Component } from '@angular/core';
|
import { brandingConfig } from '@/branding/branding.config';
|
||||||
|
import { Component, computed, inject, signal } from '@angular/core';
|
||||||
|
import { SwUpdate, VersionReadyEvent } from '@angular/service-worker';
|
||||||
|
import { ButtonDirective } from 'primeng/button';
|
||||||
|
import { filter } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pos-about-page',
|
selector: 'pos-about-page',
|
||||||
templateUrl: './root.component.html',
|
templateUrl: './root.component.html',
|
||||||
|
imports: [ButtonDirective],
|
||||||
})
|
})
|
||||||
export class PosAboutPageComponent {}
|
export class PosAboutPageComponent {
|
||||||
|
private readonly swUpdate = inject(SwUpdate);
|
||||||
|
|
||||||
|
brandingInfo = brandingConfig;
|
||||||
|
appVersion = signal('0.0.0');
|
||||||
|
isPwaBuild = this.swUpdate.isEnabled;
|
||||||
|
isCheckingUpdate = signal(false);
|
||||||
|
hasUpdate = signal(false);
|
||||||
|
isUpdated = signal(false);
|
||||||
|
|
||||||
|
updateCtaLabel = computed(() => {
|
||||||
|
if (!this.isPwaBuild) return 'به روزرسانی فقط در نسخه PWA';
|
||||||
|
if (this.isUpdated()) return 'به روز است';
|
||||||
|
if (this.hasUpdate()) return 'به روزرسانی برنامه';
|
||||||
|
if (this.isCheckingUpdate()) return 'در حال بررسی...';
|
||||||
|
return 'بررسی به روزرسانی';
|
||||||
|
});
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
if (!this.isPwaBuild) return;
|
||||||
|
|
||||||
|
this.loadVersion();
|
||||||
|
this.swUpdate.versionUpdates
|
||||||
|
.pipe(filter((event): event is VersionReadyEvent => event.type === 'VERSION_READY'))
|
||||||
|
.subscribe((event) => {
|
||||||
|
const appData = event.latestVersion.appData as { appVersion?: string } | undefined;
|
||||||
|
this.appVersion.set(appData?.appVersion || this.appVersion());
|
||||||
|
this.hasUpdate.set(true);
|
||||||
|
this.isUpdated.set(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async onUpdateCtaClick() {
|
||||||
|
if (!this.isPwaBuild || this.isCheckingUpdate()) return;
|
||||||
|
|
||||||
|
if (this.hasUpdate()) {
|
||||||
|
await this.applyUpdate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.checkForUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async checkForUpdate() {
|
||||||
|
this.isCheckingUpdate.set(true);
|
||||||
|
this.isUpdated.set(false);
|
||||||
|
try {
|
||||||
|
const hasUpdate = await this.swUpdate.checkForUpdate();
|
||||||
|
this.hasUpdate.set(hasUpdate);
|
||||||
|
this.isUpdated.set(!hasUpdate);
|
||||||
|
} finally {
|
||||||
|
this.isCheckingUpdate.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async applyUpdate() {
|
||||||
|
this.isCheckingUpdate.set(true);
|
||||||
|
try {
|
||||||
|
await this.swUpdate.activateUpdate();
|
||||||
|
this.isUpdated.set(true);
|
||||||
|
this.hasUpdate.set(false);
|
||||||
|
window.location.reload();
|
||||||
|
} finally {
|
||||||
|
this.isCheckingUpdate.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadVersion() {
|
||||||
|
fetch('/ngsw.json')
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data: { appData?: { appVersion?: string } }) => {
|
||||||
|
this.appVersion.set(data?.appData?.appVersion || this.appVersion());
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+7
-2
@@ -1,4 +1,9 @@
|
|||||||
<shared-dialog [(visible)]="visible" header="اطلاعات مشتری" [modal]="true" [style]="{ width: '560px' }">
|
<shared-light-bottomsheet
|
||||||
|
[(visible)]="visible"
|
||||||
|
header="اطلاعات مشتری"
|
||||||
|
[modal]="true"
|
||||||
|
[style]="{ 'max-height': '90svh', height: 'auto' }"
|
||||||
|
>
|
||||||
<div class="card p-2! flex justify-center">
|
<div class="card p-2! flex justify-center">
|
||||||
<p-selectbutton [options]="customerTypes" [(ngModel)]="selectedCustomerType" optionValue="value">
|
<p-selectbutton [options]="customerTypes" [(ngModel)]="selectedCustomerType" optionValue="value">
|
||||||
<ng-template #item let-item>
|
<ng-template #item let-item>
|
||||||
@@ -13,4 +18,4 @@
|
|||||||
} @else if (selectedCustomerType() === "LEGAL") {
|
} @else if (selectedCustomerType() === "LEGAL") {
|
||||||
<pos-customer-legal-form (onSubmit)="onSubmitCustomer()" (onClose)="close()" />
|
<pos-customer-legal-form (onSubmit)="onSubmitCustomer()" (onClose)="close()" />
|
||||||
}
|
}
|
||||||
</shared-dialog>
|
</shared-light-bottomsheet>
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
||||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
import { SharedLightBottomsheetComponent } from '@/shared/components/dialog/light-bottomsheet.component';
|
||||||
import { CustomerType } from '@/shared/localEnum/constants/customerTypes';
|
import { CustomerType } from '@/shared/localEnum/constants/customerTypes';
|
||||||
import { Component, EventEmitter, inject, Output, signal } from '@angular/core';
|
import { Component, EventEmitter, inject, Output, signal } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
@@ -13,7 +13,7 @@ import { CustomerUnknownFormComponent } from './unknown/form.component';
|
|||||||
selector: 'pos-order-customer-dialog',
|
selector: 'pos-order-customer-dialog',
|
||||||
templateUrl: './customer-dialog.component.html',
|
templateUrl: './customer-dialog.component.html',
|
||||||
imports: [
|
imports: [
|
||||||
SharedDialogComponent,
|
SharedLightBottomsheetComponent,
|
||||||
CustomerIndividualFormComponent,
|
CustomerIndividualFormComponent,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
CustomerLegalFormComponent,
|
CustomerLegalFormComponent,
|
||||||
|
|||||||
+3
-1
@@ -16,7 +16,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-sm text-ellipsis text-nowrap overflow-hidden">
|
<span class="text-sm text-ellipsis text-nowrap overflow-hidden">
|
||||||
{{ inOrderGood.quantity }} {{ enumTranslator(inOrderGood.good.unit_type) }}
|
{{ inOrderGood.quantity }} {{ inOrderGood.good.measure_unit.name }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@if (!inOrderGood.discount_amount) {
|
@if (!inOrderGood.discount_amount) {
|
||||||
@@ -53,9 +53,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if (visible()) {
|
||||||
<pos-payload-form-dialog
|
<pos-payload-form-dialog
|
||||||
[(visible)]="visible"
|
[(visible)]="visible"
|
||||||
[good]="inOrderGood.good"
|
[good]="inOrderGood.good"
|
||||||
[initialValues]="inOrderGood"
|
[initialValues]="inOrderGood"
|
||||||
[orderItemId]="inOrderGood.id"
|
[orderItemId]="inOrderGood.id"
|
||||||
/>
|
/>
|
||||||
|
}
|
||||||
|
|||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
<shared-dialog
|
<shared-light-bottomsheet
|
||||||
[(visible)]="visible"
|
[(visible)]="visible"
|
||||||
header="ثبت موفقیتآمیز"
|
header="ثبت موفقیتآمیز"
|
||||||
[modal]="true"
|
[modal]="true"
|
||||||
[style]="{ width: '420px' }"
|
[style]="{ 'max-height': '90svh', height: 'auto' }"
|
||||||
[closable]="true"
|
[closable]="true"
|
||||||
(onHide)="close()"
|
(onHide)="close()"
|
||||||
>
|
>
|
||||||
@@ -15,4 +15,4 @@
|
|||||||
<button pButton type="button" outlined (click)="sendInvoice()">ارسال به سامانه مودیان</button>
|
<button pButton type="button" outlined (click)="sendInvoice()">ارسال به سامانه مودیان</button>
|
||||||
<button pButton type="button" outlined (click)="openOrderDetails()">جزئیات</button>
|
<button pButton type="button" outlined (click)="openOrderDetails()">جزئیات</button>
|
||||||
</div>
|
</div>
|
||||||
</shared-dialog>
|
</shared-light-bottomsheet>
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ import { NativeBridgeService } from '@/core/services';
|
|||||||
import { ToastService } from '@/core/services/toast.service';
|
import { ToastService } from '@/core/services/toast.service';
|
||||||
import { PosInfoStore } from '@/domains/pos/store';
|
import { PosInfoStore } from '@/domains/pos/store';
|
||||||
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
||||||
import { SharedDialogComponent } from '@/shared/components';
|
import { SharedLightBottomsheetComponent } from '@/shared/components/dialog/light-bottomsheet.component';
|
||||||
import { formatJalali } from '@/utils';
|
import { formatJalali } from '@/utils';
|
||||||
import { Component, computed, inject, Input, signal } from '@angular/core';
|
import { Component, computed, inject, Input, signal } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
@@ -15,7 +15,7 @@ import { IPosOrderResponse } from '../../models';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'pos-order-submitted-dialog',
|
selector: 'pos-order-submitted-dialog',
|
||||||
templateUrl: 'order-submitted-dialog.component.html',
|
templateUrl: 'order-submitted-dialog.component.html',
|
||||||
imports: [SharedDialogComponent, ButtonDirective],
|
imports: [SharedLightBottomsheetComponent, ButtonDirective],
|
||||||
})
|
})
|
||||||
export class PosOrderSubmittedDialogComponent extends AbstractDialog {
|
export class PosOrderSubmittedDialogComponent extends AbstractDialog {
|
||||||
@Input({ required: true }) invoice!: IPosOrderResponse;
|
@Input({ required: true }) invoice!: IPosOrderResponse;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
} @else if (isStandardMode()) {
|
} @else if (isStandardMode()) {
|
||||||
<pos-standard-payload-form
|
<pos-standard-payload-form
|
||||||
[initialValues]="standardPayload()"
|
[initialValues]="standardPayload()"
|
||||||
[unitType]="good.unit_type"
|
[measureUnit]="good.measure_unit"
|
||||||
[editMode]="editMode()"
|
[editMode]="editMode()"
|
||||||
(onSubmit)="submit($event)"
|
(onSubmit)="submit($event)"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<app-amount-percentage-input
|
<app-amount-percentage-input
|
||||||
[percentageControl]="form.controls.payload.controls.wages_percentage"
|
[percentageControl]="form.controls.payload.controls.wages_percentage"
|
||||||
[amountControl]="form.controls.payload.controls.wages_amount"
|
[amountControl]="form.controls.payload.controls.wages"
|
||||||
[baseAmount]="unitWithQuantity()"
|
[baseAmount]="unitWithQuantity()"
|
||||||
[minAmount]="0"
|
[minAmount]="0"
|
||||||
[maxAmount]="unitWithQuantity()"
|
[maxAmount]="unitWithQuantity()"
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
/>
|
/>
|
||||||
<app-amount-percentage-input
|
<app-amount-percentage-input
|
||||||
[percentageControl]="form.controls.payload.controls.commission_percentage"
|
[percentageControl]="form.controls.payload.controls.commission_percentage"
|
||||||
[amountControl]="form.controls.payload.controls.commission_amount"
|
[amountControl]="form.controls.payload.controls.commission"
|
||||||
[baseAmount]="unitWithQuantity()"
|
[baseAmount]="unitWithQuantity()"
|
||||||
[minAmount]="0"
|
[minAmount]="0"
|
||||||
[maxAmount]="unitWithQuantity()"
|
[maxAmount]="unitWithQuantity()"
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
/>
|
/>
|
||||||
<app-amount-percentage-input
|
<app-amount-percentage-input
|
||||||
[percentageControl]="form.controls.payload.controls.profit_percentage"
|
[percentageControl]="form.controls.payload.controls.profit_percentage"
|
||||||
[amountControl]="form.controls.payload.controls.profit_amount"
|
[amountControl]="form.controls.payload.controls.profit"
|
||||||
[baseAmount]="totalAmountBeforeProfit()"
|
[baseAmount]="totalAmountBeforeProfit()"
|
||||||
[minAmount]="0"
|
[minAmount]="0"
|
||||||
[maxAmount]="totalAmountBeforeProfit()"
|
[maxAmount]="totalAmountBeforeProfit()"
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
<app-amount-percentage-input
|
<app-amount-percentage-input
|
||||||
[percentageControl]="form.controls.discount_percentage"
|
[percentageControl]="form.controls.discount_percentage"
|
||||||
[amountControl]="form.controls.discount_amount"
|
[amountControl]="form.controls.discount"
|
||||||
[baseAmount]="baseAmountForDiscountCalculation()"
|
[baseAmount]="baseAmountForDiscountCalculation()"
|
||||||
[minAmount]="0"
|
[minAmount]="0"
|
||||||
[maxAmount]="baseAmountForDiscountCalculation()"
|
[maxAmount]="baseAmountForDiscountCalculation()"
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
<pos-form-dialog-amount-card-template
|
<pos-form-dialog-amount-card-template
|
||||||
[totalAmount]="totalAmount()"
|
[totalAmount]="totalAmount()"
|
||||||
[baseTotalAmount]="baseTotalAmount()"
|
[baseTotalAmount]="baseTotalAmount()"
|
||||||
[discountAmount]="form.controls.discount_amount.value || 0"
|
[discountAmount]="form.controls.discount.value || 0"
|
||||||
[taxAmount]="taxAmount()"
|
[taxAmount]="taxAmount()"
|
||||||
/>
|
/>
|
||||||
<button pButton class="sm:w-auto w-full" (click)="submit()">{{ preparedCTAText() }}</button>
|
<button pButton class="sm:w-auto w-full" (click)="submit()">{{ preparedCTAText() }}</button>
|
||||||
|
|||||||
@@ -31,6 +31,17 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
|
|||||||
IPosOrderItem<IGoldPayload>,
|
IPosOrderItem<IGoldPayload>,
|
||||||
IPosOrderItem<IGoldPayload>
|
IPosOrderItem<IGoldPayload>
|
||||||
> {
|
> {
|
||||||
|
override defaultValues: Partial<IPosOrderItem<IGoldPayload>> = {
|
||||||
|
unit_price: 200_000_000,
|
||||||
|
quantity: 2,
|
||||||
|
payload: {
|
||||||
|
commission: 10_000,
|
||||||
|
wages: 10_000,
|
||||||
|
profit: 10_000,
|
||||||
|
karat: '18' as TGoldKarat,
|
||||||
|
} as any,
|
||||||
|
};
|
||||||
|
|
||||||
@Output() onSubmitForm = new EventEmitter<IGoldPayload>();
|
@Output() onSubmitForm = new EventEmitter<IGoldPayload>();
|
||||||
@Output() onChangeTotalAmount = new EventEmitter<number>();
|
@Output() onChangeTotalAmount = new EventEmitter<number>();
|
||||||
|
|
||||||
@@ -59,14 +70,14 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
|
|||||||
const form = this.fb.group({
|
const form = this.fb.group({
|
||||||
unit_price: [this.initialValues?.unit_price || 0, [Validators.required]],
|
unit_price: [this.initialValues?.unit_price || 0, [Validators.required]],
|
||||||
quantity: [this.initialValues?.quantity || 0, [Validators.required, greaterThanValidator(0)]],
|
quantity: [this.initialValues?.quantity || 0, [Validators.required, greaterThanValidator(0)]],
|
||||||
discount_amount: [this.initialValues?.discount || 0],
|
discount: [this.initialValues?.discount || 0],
|
||||||
discount_percentage: [0, [Validators.max(100), Validators.min(0)]],
|
discount_percentage: [0, [Validators.max(100), Validators.min(0)]],
|
||||||
payload: this.fb.group({
|
payload: this.fb.group({
|
||||||
commission_amount: [this.initialValues?.payload?.commission || 0, [Validators.required]],
|
commission: [this.initialValues?.payload?.commission || 0, [Validators.required]],
|
||||||
commission_percentage: [0, [Validators.required, Validators.max(100), Validators.min(0)]],
|
commission_percentage: [0, [Validators.required, Validators.max(100), Validators.min(0)]],
|
||||||
wages_amount: [this.initialValues?.payload?.wages || 0, [Validators.required]],
|
wages: [this.initialValues?.payload?.wages || 0, [Validators.required]],
|
||||||
wages_percentage: [0, [Validators.required, Validators.max(100), Validators.min(0)]],
|
wages_percentage: [0, [Validators.required, Validators.max(100), Validators.min(0)]],
|
||||||
profit_amount: [this.initialValues?.payload?.profit || 0, [Validators.required]],
|
profit: [this.initialValues?.payload?.profit || 0, [Validators.required]],
|
||||||
profit_percentage: [0, [Validators.required, Validators.max(100), Validators.min(0)]],
|
profit_percentage: [0, [Validators.required, Validators.max(100), Validators.min(0)]],
|
||||||
karat: [this.initialValues?.payload?.karat || '', [Validators.required]],
|
karat: [this.initialValues?.payload?.karat || '', [Validators.required]],
|
||||||
}),
|
}),
|
||||||
@@ -76,17 +87,15 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
|
|||||||
this.updateCalculateAmount(value as any);
|
this.updateCalculateAmount(value as any);
|
||||||
});
|
});
|
||||||
|
|
||||||
form.controls.payload.controls.profit_amount.valueChanges
|
form.controls.payload.controls.profit.valueChanges.pipe(takeUntilDestroyed()).subscribe(() => {
|
||||||
.pipe(takeUntilDestroyed())
|
|
||||||
.subscribe(() => {
|
|
||||||
// if ((form.controls.discount_amount.value || 0) > (value || 0)) {
|
// if ((form.controls.discount_amount.value || 0) > (value || 0)) {
|
||||||
form.controls.discount_amount.setValue(0, { emitEvent: false });
|
form.controls.discount.setValue(0, { emitEvent: false });
|
||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
form.controls.payload.controls.profit_percentage.valueChanges
|
form.controls.payload.controls.profit_percentage.valueChanges
|
||||||
.pipe(takeUntilDestroyed())
|
.pipe(takeUntilDestroyed())
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
form.controls.discount_amount.setValue(0, { emitEvent: false });
|
form.controls.discount.setValue(0, { emitEvent: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
return form;
|
return form;
|
||||||
@@ -101,19 +110,19 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
|
|||||||
base_total_amount: this.baseTotalAmount(),
|
base_total_amount: this.baseTotalAmount(),
|
||||||
tax_amount: this.taxAmount(),
|
tax_amount: this.taxAmount(),
|
||||||
payload: {
|
payload: {
|
||||||
commission: this.form.controls.payload.controls.commission_amount.value || 0,
|
commission: this.form.controls.payload.controls.commission.value || 0,
|
||||||
karat: this.form.controls.payload.controls.karat.value as TGoldKarat,
|
karat: this.form.controls.payload.controls.karat.value as TGoldKarat,
|
||||||
profit: this.form.controls.payload.controls.profit_amount.value || 0,
|
profit: this.form.controls.payload.controls.profit.value || 0,
|
||||||
wages: this.form.controls.payload.controls.wages_amount.value || 0,
|
wages: this.form.controls.payload.controls.wages.value || 0,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCalculateAmount(payload: Partial<IPosOrderItem<any>>) {
|
updateCalculateAmount(payload: Partial<IPosOrderItem<any>>) {
|
||||||
const commissionAmount = Number(payload.payload?.commission_amount ?? '0');
|
const commissionAmount = Number(payload.payload?.commission ?? '0');
|
||||||
const wageAmount = Number(payload.payload?.wages_amount ?? '0');
|
const wageAmount = Number(payload.payload?.wages ?? '0');
|
||||||
const discountAmount = Number(payload.discount_amount ?? '0');
|
const discountAmount = Number(payload.discount ?? '0');
|
||||||
const profitAmount = Number(payload.payload?.profit_amount ?? '0');
|
const profitAmount = Number(payload.payload?.profit ?? '0');
|
||||||
const unitPrice = Number(payload.unit_price ?? '0');
|
const unitPrice = Number(payload.unit_price ?? '0');
|
||||||
const quantity = Number(payload.quantity ?? '0');
|
const quantity = Number(payload.quantity ?? '0');
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -3,9 +3,9 @@
|
|||||||
<app-input
|
<app-input
|
||||||
[control]="form.controls.quantity"
|
[control]="form.controls.quantity"
|
||||||
name="quantity"
|
name="quantity"
|
||||||
[label]="preparedFormVisuals().quantityLabel"
|
[label]="measureUnit.name"
|
||||||
type="number"
|
type="number"
|
||||||
[suffix]="preparedFormVisuals().quantitySymbolText"
|
[suffix]="measureUnit.name"
|
||||||
[min]="0"
|
[min]="0"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import ISummary from '@/core/models/summary';
|
||||||
import { AbstractForm } from '@/shared/abstractClasses';
|
import { AbstractForm } from '@/shared/abstractClasses';
|
||||||
import { InputComponent } from '@/shared/components';
|
import { InputComponent } from '@/shared/components';
|
||||||
import { AmountPercentageInputComponent } from '@/shared/components/amountPercentageInput/amount-percentage-input.component';
|
import { AmountPercentageInputComponent } from '@/shared/components/amountPercentageInput/amount-percentage-input.component';
|
||||||
import { formatWithCurrency, getGoodUnitTypeProperties, UnitType } from '@/utils';
|
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';
|
||||||
@@ -24,7 +25,7 @@ export class PosStandardPayloadFormComponent extends AbstractForm<
|
|||||||
IPosOrderItem<IStandardPayload>,
|
IPosOrderItem<IStandardPayload>,
|
||||||
IPosOrderItem<IStandardPayload>
|
IPosOrderItem<IStandardPayload>
|
||||||
> {
|
> {
|
||||||
@Input({ required: true }) unitType!: UnitType;
|
@Input({ required: true }) measureUnit!: ISummary;
|
||||||
@Output() onChangeTotalAmount = new EventEmitter<number>();
|
@Output() onChangeTotalAmount = new EventEmitter<number>();
|
||||||
|
|
||||||
private readonly initialForm = () => {
|
private readonly initialForm = () => {
|
||||||
@@ -53,8 +54,6 @@ export class PosStandardPayloadFormComponent extends AbstractForm<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
preparedFormVisuals = computed(() => getGoodUnitTypeProperties(this.unitType));
|
|
||||||
|
|
||||||
baseTotalAmount = signal<number>(0);
|
baseTotalAmount = signal<number>(0);
|
||||||
totalAmount = signal<number>(0);
|
totalAmount = signal<number>(0);
|
||||||
discountAmount = signal<number>(0);
|
discountAmount = signal<number>(0);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<shared-dialog
|
<shared-light-bottomsheet
|
||||||
[(visible)]="visible"
|
[(visible)]="visible"
|
||||||
header="اطلاعات پرداخت"
|
header="اطلاعات پرداخت"
|
||||||
[modal]="true"
|
[modal]="true"
|
||||||
[style]="{ width: '500px' }"
|
[style]="{ 'max-height': '90svh', height: 'auto' }"
|
||||||
[closable]="true"
|
[closable]="true"
|
||||||
(onHide)="close()"
|
(onHide)="close()"
|
||||||
>
|
>
|
||||||
@@ -71,4 +71,4 @@
|
|||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</shared-dialog>
|
</shared-light-bottomsheet>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { NativeBridgeService } from '@/core/services';
|
|||||||
import { ToastService } from '@/core/services/toast.service';
|
import { ToastService } from '@/core/services/toast.service';
|
||||||
import { AbstractFormDialog } from '@/shared/abstractClasses';
|
import { AbstractFormDialog } from '@/shared/abstractClasses';
|
||||||
import { InputComponent, KeyValueComponent } from '@/shared/components';
|
import { InputComponent, KeyValueComponent } from '@/shared/components';
|
||||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
import { SharedLightBottomsheetComponent } from '@/shared/components/dialog/light-bottomsheet.component';
|
||||||
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||||
import { UikitFieldComponent } from '@/uikit';
|
import { UikitFieldComponent } from '@/uikit';
|
||||||
import { Component, computed, inject, signal } from '@angular/core';
|
import { Component, computed, inject, signal } from '@angular/core';
|
||||||
@@ -27,7 +27,7 @@ import { PosLandingStore } from '../../store/main.store';
|
|||||||
FormFooterActionsComponent,
|
FormFooterActionsComponent,
|
||||||
KeyValueComponent,
|
KeyValueComponent,
|
||||||
ButtonDirective,
|
ButtonDirective,
|
||||||
SharedDialogComponent,
|
SharedLightBottomsheetComponent,
|
||||||
Select,
|
Select,
|
||||||
UikitFieldComponent,
|
UikitFieldComponent,
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<shared-dialog
|
<shared-light-bottomsheet
|
||||||
[(visible)]="visible"
|
[(visible)]="visible"
|
||||||
header="پیش فاکتور"
|
header="پیش فاکتور"
|
||||||
[modal]="true"
|
[modal]="true"
|
||||||
[style]="{ width: '500px' }"
|
[style]="{ 'max-height': '90svh', height: 'auto' }"
|
||||||
[closable]="true"
|
[closable]="true"
|
||||||
(onHide)="close()"
|
(onHide)="close()"
|
||||||
>
|
>
|
||||||
<form [formGroup]="form"></form>
|
<form [formGroup]="form"></form>
|
||||||
<uikit-datepicker [control]="form.controls.invoiceDate" label="تاریخ فاکتور" />
|
<uikit-datepicker [control]="form.controls.invoiceDate" label="تاریخ فاکتور" />
|
||||||
</shared-dialog>
|
</shared-light-bottomsheet>
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
||||||
|
import { SharedLightBottomsheetComponent } from '@/shared/components/dialog/light-bottomsheet.component';
|
||||||
import { UikitFlatpickrJalaliComponent } from '@/uikit';
|
import { UikitFlatpickrJalaliComponent } from '@/uikit';
|
||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { PosLandingStore } from '../store/main.store';
|
import { PosLandingStore } from '../store/main.store';
|
||||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pos-pre-invoice-dialog',
|
selector: 'pos-pre-invoice-dialog',
|
||||||
templateUrl: './pre-invoice-dialog.component.html',
|
templateUrl: './pre-invoice-dialog.component.html',
|
||||||
imports: [SharedDialogComponent, UikitFlatpickrJalaliComponent, ReactiveFormsModule],
|
imports: [SharedLightBottomsheetComponent, UikitFlatpickrJalaliComponent, ReactiveFormsModule],
|
||||||
})
|
})
|
||||||
export class PosPreInvoiceDialogComponent extends AbstractDialog {
|
export class PosPreInvoiceDialogComponent extends AbstractDialog {
|
||||||
private readonly store = inject(PosLandingStore);
|
private readonly store = inject(PosLandingStore);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
import ISummary from '@/core/models/summary';
|
||||||
import { IGoodResponse } from '@/domains/pos/models/good.io';
|
import { IGoodResponse } from '@/domains/pos/models/good.io';
|
||||||
import { UnitType } from '@/utils';
|
|
||||||
import { TPosOrderGoodPayload } from './payload';
|
import { TPosOrderGoodPayload } from './payload';
|
||||||
|
|
||||||
export interface IPosOrderItem<T = TPosOrderGoodPayload> {
|
export interface IPosOrderItem<T = TPosOrderGoodPayload> {
|
||||||
@@ -7,7 +7,7 @@ export interface IPosOrderItem<T = TPosOrderGoodPayload> {
|
|||||||
quantity: number;
|
quantity: number;
|
||||||
total_amount: number;
|
total_amount: number;
|
||||||
discount_amount: number;
|
discount_amount: number;
|
||||||
unit_type: UnitType;
|
measure_unit: ISummary;
|
||||||
good_id?: string;
|
good_id?: string;
|
||||||
service_id?: string;
|
service_id?: string;
|
||||||
notes?: string;
|
notes?: string;
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ export class PosLandingStore {
|
|||||||
items: this.inOrderGoods().map(({ good, ...rest }) => ({
|
items: this.inOrderGoods().map(({ good, ...rest }) => ({
|
||||||
...rest,
|
...rest,
|
||||||
good_id: good.id,
|
good_id: good.id,
|
||||||
unit_type: good.unit_type,
|
measure_unit: good.measure_unit,
|
||||||
})),
|
})),
|
||||||
invoice_date: new Date().toISOString(),
|
invoice_date: new Date().toISOString(),
|
||||||
payments: this.payments(),
|
payments: this.payments(),
|
||||||
|
|||||||
@@ -34,17 +34,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
<shared-dialog
|
<shared-light-bottomsheet [(visible)]="showInvoiceBottomSheet" [modal]="true" [closable]="true" header="فاکتور">
|
||||||
[(visible)]="showInvoiceBottomSheet"
|
|
||||||
position="bottom"
|
|
||||||
[modal]="true"
|
|
||||||
[closable]="true"
|
|
||||||
header="فاکتور"
|
|
||||||
>
|
|
||||||
@if (showInvoiceBottomSheet()) {
|
@if (showInvoiceBottomSheet()) {
|
||||||
<pos-order-section (onAddMoreGoods)="closeInvoiceBottomSheet()" (onSuccess)="onSuccessSubmit($event)" />
|
<pos-order-section (onAddMoreGoods)="closeInvoiceBottomSheet()" (onSuccess)="onSuccessSubmit($event)" />
|
||||||
}
|
}
|
||||||
</shared-dialog>
|
</shared-light-bottomsheet>
|
||||||
|
|
||||||
@if (responseInvoice()) {
|
@if (responseInvoice()) {
|
||||||
<pos-order-submitted-dialog [(visible)]="isVisibleSuccessDialog" [invoice]="responseInvoice()!" />
|
<pos-order-submitted-dialog [(visible)]="isVisibleSuccessDialog" [invoice]="responseInvoice()!" />
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { Maybe } from '@/core';
|
import { Maybe } from '@/core';
|
||||||
import { PosInfoStore } from '@/domains/pos/store/pos.store';
|
import { PosInfoStore } from '@/domains/pos/store/pos.store';
|
||||||
import { AbstractIsMobileComponent } from '@/shared/abstractClasses/abstract-is-mobile';
|
import { AbstractIsMobileComponent } from '@/shared/abstractClasses/abstract-is-mobile';
|
||||||
import { SharedDialogComponent } from '@/shared/components';
|
import { SharedLightBottomsheetComponent } from '@/shared/components/dialog/light-bottomsheet.component';
|
||||||
import { PageLoadingComponent } from '@/shared/components/page-loading.component';
|
import { PageLoadingComponent } from '@/shared/components/page-loading.component';
|
||||||
import { PriceMaskDirective } from '@/shared/directives';
|
import { PriceMaskDirective } from '@/shared/directives';
|
||||||
import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';
|
||||||
@@ -24,7 +24,7 @@ import { PosLandingStore } from '../store/main.store';
|
|||||||
PosOrderSectionComponent,
|
PosOrderSectionComponent,
|
||||||
PageLoadingComponent,
|
PageLoadingComponent,
|
||||||
PriceMaskDirective,
|
PriceMaskDirective,
|
||||||
SharedDialogComponent,
|
SharedLightBottomsheetComponent,
|
||||||
ButtonDirective,
|
ButtonDirective,
|
||||||
PosOrderSubmittedDialogComponent,
|
PosOrderSubmittedDialogComponent,
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,6 +1,47 @@
|
|||||||
<div class="w-full h-full min-h-[60svh] flex items-center justify-center p-4">
|
<div class="w-full min-h-[60svh] p-4 md:p-6">
|
||||||
<div class="text-center">
|
<section class="mx-auto max-w-3xl overflow-hidden rounded-2xl border border-surface-200 bg-white">
|
||||||
<h2 class="text-xl font-semibold mb-2">پشتیبانی</h2>
|
<div class="bg-gradient-to-l from-sky-50 via-cyan-50 to-teal-50 p-5 md:p-7">
|
||||||
<p class="text-muted-color">این صفحه به زودی تکمیل می شود.</p>
|
<h1 class="text-2xl font-bold text-surface-900 md:text-3xl">پشتیبانی تیس</h1>
|
||||||
|
<p class="mt-3 max-w-2xl text-sm leading-7 text-surface-700 md:text-base">
|
||||||
|
در صورت بروز مشکل در ثبت سفارش، صدور صورتحساب یا تنظیمات دستگاه، تیم پشتیبانی آماده پاسخگویی است. لطفا هنگام
|
||||||
|
تماس، نام پایانه و شماره سریال دستگاه را همراه داشته باشید.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="grid gap-3 p-4 md:grid-cols-2 md:gap-4 md:p-6">
|
||||||
|
<article class="rounded-xl border border-surface-200 bg-surface-50 p-4">
|
||||||
|
<h2 class="mb-3 text-sm font-bold text-surface-900">شماره های تماس مستقیم</h2>
|
||||||
|
<ul class="space-y-2 text-sm text-surface-700">
|
||||||
|
<li class="flex items-center justify-between gap-2">
|
||||||
|
<span>واحد پشتیبانی 1</span>
|
||||||
|
<a class="font-semibold text-primary" href="tel:02191012345" dir="ltr">021-91012345</a>
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center justify-between gap-2">
|
||||||
|
<span>واحد پشتیبانی 2</span>
|
||||||
|
<a class="font-semibold text-primary" href="tel:02191012346" dir="ltr">021-91012346</a>
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center justify-between gap-2">
|
||||||
|
<span>پاسخگویی اضطراری</span>
|
||||||
|
<a class="font-semibold text-primary" href="tel:09121234567" dir="ltr">0912-123-4567</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="rounded-xl border border-surface-200 bg-surface-50 p-4">
|
||||||
|
<h2 class="mb-3 text-sm font-bold text-surface-900">راهنمای سریع قبل از تماس</h2>
|
||||||
|
<ul class="space-y-2 text-sm leading-6 text-surface-700">
|
||||||
|
<li>اتصال اینترنت دستگاه را بررسی کنید.</li>
|
||||||
|
<li>یک بار برنامه را ببندید و دوباره اجرا کنید.</li>
|
||||||
|
<li>در صفحه درباره نرم افزار، نسخه برنامه را اعلام کنید.</li>
|
||||||
|
<li>در صورت خطا، متن خطا یا تصویر آن را برای پشتیبانی ارسال کنید.</li>
|
||||||
|
</ul>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="border-t border-surface-200 bg-surface-50 px-4 py-4 md:px-6">
|
||||||
|
<p class="text-xs leading-6 text-surface-600 md:text-sm">
|
||||||
|
ساعات پاسخگویی: شنبه تا چهارشنبه 8:30 تا 17:30 و پنجشنبه 8:30 تا 13:00
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ export class AppLayout {
|
|||||||
public renderer: Renderer2,
|
public renderer: Renderer2,
|
||||||
public router: Router,
|
public router: Router,
|
||||||
) {
|
) {
|
||||||
|
this.layoutService.headerSlot$.subscribe((tpl) => (this.topBarMoreAction = tpl));
|
||||||
|
this.layoutService.topbarStartSlot$.subscribe((tpl) => (this.topBarStartAction = tpl));
|
||||||
|
this.layoutService.topbarCenterSlot$.subscribe((tpl) => (this.topBarCenterAction = tpl));
|
||||||
|
this.layoutService.topbarEndSlot$.subscribe((tpl) => (this.topBarEndAction = tpl));
|
||||||
|
|
||||||
this.overlayMenuOpenSubscription = this.layoutService.overlayOpen$.subscribe(() => {
|
this.overlayMenuOpenSubscription = this.layoutService.overlayOpen$.subscribe(() => {
|
||||||
if (!this.menuOutsideClickListener) {
|
if (!this.menuOutsideClickListener) {
|
||||||
this.menuOutsideClickListener = this.renderer.listen('document', 'click', (event) => {
|
this.menuOutsideClickListener = this.renderer.listen('document', 'click', (event) => {
|
||||||
@@ -133,11 +138,6 @@ export class AppLayout {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.layoutService.headerSlot$.subscribe((tpl) => (this.topBarMoreAction = tpl));
|
|
||||||
this.layoutService.topbarStartSlot$.subscribe((tpl) => (this.topBarStartAction = tpl));
|
|
||||||
this.layoutService.topbarCenterSlot$.subscribe((tpl) => (this.topBarCenterAction = tpl));
|
|
||||||
this.layoutService.topbarEndSlot$.subscribe((tpl) => (this.topBarEndAction = tpl));
|
|
||||||
|
|
||||||
if (window.location.pathname === '/') {
|
if (window.location.pathname === '/') {
|
||||||
if (!this.authService.currentAccount()) {
|
if (!this.authService.currentAccount()) {
|
||||||
this.router.navigateByUrl('auth');
|
this.router.navigateByUrl('auth');
|
||||||
|
|||||||
@@ -37,14 +37,14 @@ export abstract class AbstractForm<
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.form.reset(this.initialValues ?? this.defaultValues);
|
this.form.patchValue(this.initialValues ?? this.defaultValues);
|
||||||
// Object.entries(this.form.controls).forEach(([key, control]) => {
|
// Object.entries(this.form.controls).forEach(([key, control]) => {
|
||||||
// console.log(key, control);
|
// console.log(key, control);
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
this.form.reset(this.initialValues ?? this.defaultValues);
|
this.form.patchValue(this.initialValues ?? this.defaultValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSuccess(response: Response): void {}
|
onSuccess(response: Response): void {}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
[formControl]="control"
|
[formControl]="control"
|
||||||
[showClear]="showClear"
|
[showClear]="showClear"
|
||||||
[name]="name || type"
|
[name]="name || type"
|
||||||
|
[overlayOptions]="overlayOptions()"
|
||||||
appendTo="body"
|
appendTo="body"
|
||||||
/>
|
/>
|
||||||
</uikit-field>
|
</uikit-field>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { UikitFieldComponent } from '@/uikit';
|
import { UikitFieldComponent } from '@/uikit';
|
||||||
import { Component, computed, inject, Input } from '@angular/core';
|
import { DOCUMENT } from '@angular/common';
|
||||||
|
import { Component, Inject, computed, inject, Input } from '@angular/core';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { Select } from 'primeng/select';
|
import { Select } from 'primeng/select';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
@@ -19,6 +20,9 @@ export class EnumSelectComponent extends AbstractSelectComponent<string, IApiEnu
|
|||||||
@Input() customLabel?: string;
|
@Input() customLabel?: string;
|
||||||
|
|
||||||
private readonly service = inject(EnumsService);
|
private readonly service = inject(EnumsService);
|
||||||
|
constructor(@Inject(DOCUMENT) private readonly document: Document) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
label = computed(() => this.customLabel ?? apiEnumTranslates[this.type]);
|
label = computed(() => this.customLabel ?? apiEnumTranslates[this.type]);
|
||||||
|
|
||||||
@@ -29,4 +33,20 @@ export class EnumSelectComponent extends AbstractSelectComponent<string, IApiEnu
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.getData();
|
this.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlayOptions() {
|
||||||
|
return {
|
||||||
|
autoZIndex: true,
|
||||||
|
baseZIndex: this.overlayBaseZIndex(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
overlayBaseZIndex() {
|
||||||
|
const drawers = Array.from(this.document.body.querySelectorAll('.p-drawer,[data-pc-name="drawer"]')) as HTMLElement[];
|
||||||
|
const zIndexes = drawers
|
||||||
|
.map((drawer) => Number.parseInt(drawer.style.zIndex || '0', 10))
|
||||||
|
.filter((zIndex) => Number.isFinite(zIndex) && zIndex > 0);
|
||||||
|
|
||||||
|
return zIndexes.length ? Math.max(...zIndexes) + 2 : 1000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -24,8 +24,8 @@
|
|||||||
[attr.name]="name"
|
[attr.name]="name"
|
||||||
[attr.placeholder]="placeholder"
|
[attr.placeholder]="placeholder"
|
||||||
[attr.autocomplete]="autocomplete"
|
[attr.autocomplete]="autocomplete"
|
||||||
[class]="` w-full hasSuffix text-left ${size === 'large' ? 'p-inputtext-lg' : size === 'small' ? 'p-inputtext-sm' : ''}`"
|
[inputStyle]="{ direction: 'ltr' }"
|
||||||
dir="ltr"
|
[inputStyleClass]="` w-full hasSuffix text-left ${size === 'large' ? 'p-inputtext-lg' : size === 'small' ? 'p-inputtext-sm' : ''}`"
|
||||||
[required]="required"
|
[required]="required"
|
||||||
[invalid]="amountControl.invalid && (amountControl.touched || amountControl.dirty)"
|
[invalid]="amountControl.invalid && (amountControl.touched || amountControl.dirty)"
|
||||||
(onInput)="onPriceInput($event)"
|
(onInput)="onPriceInput($event)"
|
||||||
@@ -58,9 +58,10 @@
|
|||||||
<p-select
|
<p-select
|
||||||
[formControl]="selectedType"
|
[formControl]="selectedType"
|
||||||
[options]="typeSelectOptions"
|
[options]="typeSelectOptions"
|
||||||
|
tabindex="-1"
|
||||||
optionValue="value"
|
optionValue="value"
|
||||||
size="small"
|
size="small"
|
||||||
class="border-0!"
|
class="border-none! shadow-none! w-full!"
|
||||||
/>
|
/>
|
||||||
</p-inputgroup-addon>
|
</p-inputgroup-addon>
|
||||||
</p-inputgroup>
|
</p-inputgroup>
|
||||||
|
|||||||
@@ -180,11 +180,16 @@ export class AmountPercentageInputComponent {
|
|||||||
const amountValue = Number(this.amountControl.value || 0);
|
const amountValue = Number(this.amountControl.value || 0);
|
||||||
const percentageValue = Number(this.percentageControl.value || 0);
|
const percentageValue = Number(this.percentageControl.value || 0);
|
||||||
const isPercentageType = percentageValue > 0 && amountValue <= 0;
|
const isPercentageType = percentageValue > 0 && amountValue <= 0;
|
||||||
|
|
||||||
|
console.log(amountValue, percentageValue, isPercentageType);
|
||||||
|
|
||||||
this.preparedLabel.set(this.prepareLabel(isPercentageType));
|
this.preparedLabel.set(this.prepareLabel(isPercentageType));
|
||||||
|
|
||||||
this.selectedType.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value) => {
|
this.selectedType.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value) => {
|
||||||
this.preparedLabel.set(this.prepareLabel(value === 'percentage'));
|
this.preparedLabel.set(this.prepareLabel(value === 'percentage'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.selectedType.setValue(isPercentageType ? 'percentage' : 'amount');
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<p-checkBox [formControl]="control" [name]="name" [id]="name" binary class="shrink-0"> </p-checkBox>
|
<p-checkBox [formControl]="control" [name]="name" [inputId]="name" binary class="shrink-0"> </p-checkBox>
|
||||||
<uikit-label [name]="name"> {{ label }} </uikit-label>
|
<uikit-label [name]="name"> {{ label }} </uikit-label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
<div class="light-bottomsheet-mask" (click)="onMaskClick()"></div>
|
<div class="light-bottomsheet-mask" (click)="onMaskClick()"></div>
|
||||||
|
|
||||||
<section
|
<section class="light-bottomsheet-panel" [ngStyle]="style || { 'max-height': mobileDrawerHeight, height: 'auto' }">
|
||||||
class="light-bottomsheet-panel"
|
|
||||||
role="dialog"
|
|
||||||
aria-modal="true"
|
|
||||||
[attr.aria-hidden]="!visible"
|
|
||||||
[ngStyle]="style || { 'max-height': mobileDrawerHeight, height: 'auto' }"
|
|
||||||
>
|
|
||||||
<div class="light-bottomsheet-content">
|
<div class="light-bottomsheet-content">
|
||||||
@if (header || closable) {
|
@if (header || closable) {
|
||||||
<header class="light-bottomsheet-header">
|
<header class="light-bottomsheet-header">
|
||||||
<h3 class="light-bottomsheet-title">{{ header }}</h3>
|
<span class="text-xl font-bold">{{ header }}</span>
|
||||||
@if (closable) {
|
@if (closable) {
|
||||||
<button type="button" class="light-bottomsheet-close" (click)="onVisibilityChange(false)" aria-label="Close">
|
<p-button
|
||||||
×
|
type="button"
|
||||||
</button>
|
icon="pi pi-times"
|
||||||
|
text
|
||||||
|
size="small"
|
||||||
|
class="light-bottomsheet-close"
|
||||||
|
(click)="onVisibilityChange(false)"
|
||||||
|
aria-label="Close"
|
||||||
|
>
|
||||||
|
</p-button>
|
||||||
}
|
}
|
||||||
</header>
|
</header>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,29 @@
|
|||||||
import { NgStyle } from '@angular/common';
|
import { DOCUMENT, NgStyle } from '@angular/common';
|
||||||
import { DOCUMENT } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
Inject,
|
Inject,
|
||||||
Input,
|
Input,
|
||||||
|
OnChanges,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
Output,
|
Output,
|
||||||
Renderer2,
|
Renderer2,
|
||||||
|
SimpleChanges,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { Button } from 'primeng/button';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'shared-light-bottomsheet',
|
selector: 'shared-light-bottomsheet',
|
||||||
templateUrl: './light-bottomsheet.component.html',
|
templateUrl: './light-bottomsheet.component.html',
|
||||||
imports: [NgStyle],
|
imports: [NgStyle, Button],
|
||||||
styles: [
|
styles: [
|
||||||
`
|
`
|
||||||
:host {
|
:host {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 11020;
|
z-index: 1210;
|
||||||
}
|
}
|
||||||
|
|
||||||
.light-bottomsheet-mask {
|
.light-bottomsheet-mask {
|
||||||
@@ -66,8 +68,6 @@ import {
|
|||||||
|
|
||||||
.light-bottomsheet-title {
|
.light-bottomsheet-title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 0.95rem;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.light-bottomsheet-close {
|
.light-bottomsheet-close {
|
||||||
@@ -98,11 +98,17 @@ import {
|
|||||||
`,
|
`,
|
||||||
],
|
],
|
||||||
host: {
|
host: {
|
||||||
|
'[attr.role]': '"complementary"',
|
||||||
|
'[attr.aria-modal]': 'true',
|
||||||
|
'[attr.pfocustrap]': 'true',
|
||||||
|
'[attr.data-pc-name]': "'drawer'",
|
||||||
|
'[attr.data-pc-section]': "'root'",
|
||||||
|
'[attr.aria-hidden]': '!visible',
|
||||||
'[style.display]': 'visible ? "block" : "none"',
|
'[style.display]': 'visible ? "block" : "none"',
|
||||||
'[style.--sheet-transition]': 'transitionOptions',
|
'[style.--sheet-transition]': 'transitionOptions',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export class SharedLightBottomsheetComponent implements OnInit, OnDestroy {
|
export class SharedLightBottomsheetComponent implements OnInit, OnDestroy, OnChanges {
|
||||||
@Input() header = '';
|
@Input() header = '';
|
||||||
@Input() visible = false;
|
@Input() visible = false;
|
||||||
@Output() visibleChange = new EventEmitter<boolean>();
|
@Output() visibleChange = new EventEmitter<boolean>();
|
||||||
@@ -116,6 +122,7 @@ export class SharedLightBottomsheetComponent implements OnInit, OnDestroy {
|
|||||||
@Output() onHide = new EventEmitter<any>();
|
@Output() onHide = new EventEmitter<any>();
|
||||||
|
|
||||||
private originalParent: Node | null = null;
|
private originalParent: Node | null = null;
|
||||||
|
private readonly defaultDrawerZIndex = 1102;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly elementRef: ElementRef<HTMLElement>,
|
private readonly elementRef: ElementRef<HTMLElement>,
|
||||||
@@ -127,9 +134,20 @@ export class SharedLightBottomsheetComponent implements OnInit, OnDestroy {
|
|||||||
const host = this.elementRef.nativeElement;
|
const host = this.elementRef.nativeElement;
|
||||||
this.originalParent = host.parentNode;
|
this.originalParent = host.parentNode;
|
||||||
this.renderer.appendChild(this.document.body, host);
|
this.renderer.appendChild(this.document.body, host);
|
||||||
|
this.syncZIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
if (changes['visible'] && this.visible) {
|
||||||
|
this.syncZIndex();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
this.removeDrawer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private removeDrawer() {
|
||||||
const host = this.elementRef.nativeElement;
|
const host = this.elementRef.nativeElement;
|
||||||
if (this.originalParent) {
|
if (this.originalParent) {
|
||||||
this.renderer.appendChild(this.originalParent, host);
|
this.renderer.appendChild(this.originalParent, host);
|
||||||
@@ -139,6 +157,9 @@ export class SharedLightBottomsheetComponent implements OnInit, OnDestroy {
|
|||||||
onVisibilityChange(nextValue: boolean) {
|
onVisibilityChange(nextValue: boolean) {
|
||||||
this.visible = nextValue;
|
this.visible = nextValue;
|
||||||
this.visibleChange.emit(nextValue);
|
this.visibleChange.emit(nextValue);
|
||||||
|
if (nextValue) {
|
||||||
|
this.syncZIndex();
|
||||||
|
}
|
||||||
if (!nextValue) {
|
if (!nextValue) {
|
||||||
this.onHide.emit();
|
this.onHide.emit();
|
||||||
}
|
}
|
||||||
@@ -149,4 +170,19 @@ export class SharedLightBottomsheetComponent implements OnInit, OnDestroy {
|
|||||||
this.onVisibilityChange(false);
|
this.onVisibilityChange(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private syncZIndex() {
|
||||||
|
const host = this.elementRef.nativeElement;
|
||||||
|
const siblingDrawers = Array.from(
|
||||||
|
this.document.body.querySelectorAll('.p-drawer'),
|
||||||
|
) as HTMLElement[];
|
||||||
|
const drawerZIndexes = siblingDrawers
|
||||||
|
.map((drawer) => Number.parseInt(drawer.style.zIndex || '0', 10))
|
||||||
|
.filter((zIndex) => Number.isFinite(zIndex) && zIndex > 0);
|
||||||
|
|
||||||
|
const maxDrawerZIndex = drawerZIndexes.length
|
||||||
|
? Math.max(...drawerZIndexes)
|
||||||
|
: this.defaultDrawerZIndex;
|
||||||
|
this.renderer.setStyle(host, 'z-index', `${maxDrawerZIndex + 1}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
[formControl]="control"
|
[formControl]="control"
|
||||||
[showClear]="showClear"
|
[showClear]="showClear"
|
||||||
[filter]="true"
|
[filter]="true"
|
||||||
|
[overlayOptions]="overlayOptions()"
|
||||||
appendTo="body"
|
appendTo="body"
|
||||||
/>
|
/>
|
||||||
</uikit-field>
|
</uikit-field>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { UikitFieldComponent } from '@/uikit';
|
import { UikitFieldComponent } from '@/uikit';
|
||||||
import { Component, computed, Input } from '@angular/core';
|
import { DOCUMENT } from '@angular/common';
|
||||||
|
import { Component, Inject, computed, Input } from '@angular/core';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { Select } from 'primeng/select';
|
import { Select } from 'primeng/select';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
@@ -16,6 +17,10 @@ export class EnumSelectComponent extends AbstractSelectComponent<ISelectItem, IS
|
|||||||
@Input() type!: TLocalEnum;
|
@Input() type!: TLocalEnum;
|
||||||
@Input() customLabel?: string;
|
@Input() customLabel?: string;
|
||||||
|
|
||||||
|
constructor(@Inject(DOCUMENT) private readonly document: Document) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
label = computed(() => this.customLabel ?? LOCAL_ENUMS[this.type].label);
|
label = computed(() => this.customLabel ?? LOCAL_ENUMS[this.type].label);
|
||||||
|
|
||||||
override getDataService() {
|
override getDataService() {
|
||||||
@@ -27,4 +32,20 @@ export class EnumSelectComponent extends AbstractSelectComponent<ISelectItem, IS
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.getData();
|
this.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlayOptions() {
|
||||||
|
return {
|
||||||
|
autoZIndex: true,
|
||||||
|
baseZIndex: this.overlayBaseZIndex(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
overlayBaseZIndex() {
|
||||||
|
const drawers = Array.from(this.document.body.querySelectorAll('.p-drawer,[data-pc-name="drawer"]')) as HTMLElement[];
|
||||||
|
const zIndexes = drawers
|
||||||
|
.map((drawer) => Number.parseInt(drawer.style.zIndex || '0', 10))
|
||||||
|
.filter((zIndex) => Number.isFinite(zIndex) && zIndex > 0);
|
||||||
|
|
||||||
|
return zIndexes.length ? Math.max(...zIndexes) + 2 : 1000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,11 +48,12 @@ input.p-inputtext {
|
|||||||
margin-inline-end: 0.5rem;
|
margin-inline-end: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-inputgroup > .p-component.hasSuffix:first-child {
|
.p-inputgroup > .p-component.hasSuffix:first-child,
|
||||||
|
.p-inputgroup > .p-component > .hasSuffix {
|
||||||
border-start-start-radius: 0 !important;
|
border-start-start-radius: 0 !important;
|
||||||
border-end-start-radius: 0 !important;
|
border-end-start-radius: 0 !important;
|
||||||
border-end-end-radius: var(--p-inputgroup-addon-border-radius);
|
border-end-end-radius: var(--p-inputgroup-addon-border-radius) !important;
|
||||||
border-start-end-radius: var(--p-inputgroup-addon-border-radius);
|
border-start-end-radius: var(--p-inputgroup-addon-border-radius) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-tablist {
|
.p-tablist {
|
||||||
|
|||||||
Reference in New Issue
Block a user