From 1b4ac0789cc006772bc75cf794dfe8055c27eb43 Mon Sep 17 00:00:00 2001 From: ahasani194 Date: Wed, 20 May 2026 20:22:38 +0330 Subject: [PATCH] feat: implement pos goods management module; add create, update, and list components with API integration --- .prettierrc.json | 12 ++-- package.json | 10 ---- .../components/goods/form.component.html | 5 +- .../components/goods/form.component.ts | 5 +- .../main-menu-sidebar.component.ts | 6 ++ .../goodsManagement/components/index.ts | 1 + .../components/list.component.html | 46 ++++++++++++++ .../components/list.component.ts | 56 +++++++++++++++++ .../constants/apiRoutes/index.ts | 8 +++ .../goodsManagement/constants/index.ts | 2 + .../goodsManagement/constants/routes/index.ts | 43 +++++++++++++ .../modules/goodsManagement/models/index.ts | 1 + .../modules/goodsManagement/models/io.d.ts | 7 +++ .../goodsManagement/services/main.service.ts | 29 +++++++++ .../views/create.component.html | 7 +++ .../goodsManagement/views/create.component.ts | 36 +++++++++++ .../modules/goodsManagement/views/index.ts | 3 + .../goodsManagement/views/list.component.html | 1 + .../goodsManagement/views/list.component.ts | 9 +++ .../views/update.component.html | 16 +++++ .../goodsManagement/views/update.component.ts | 60 +++++++++++++++++++ .../components/list-view.component.html | 17 +++--- .../payment/form-dialog.component.ts | 16 ++--- src/app/domains/pos/routes.ts | 2 + .../good/form-dialog.component.html | 18 ++++++ .../components/good/form-dialog.component.ts | 30 ++++++++++ .../components/good/form.component.html | 39 ++++++------ .../shared/components/good/form.component.ts | 17 ++---- 28 files changed, 437 insertions(+), 65 deletions(-) create mode 100644 src/app/domains/pos/modules/goodsManagement/components/index.ts create mode 100644 src/app/domains/pos/modules/goodsManagement/components/list.component.html create mode 100644 src/app/domains/pos/modules/goodsManagement/components/list.component.ts create mode 100644 src/app/domains/pos/modules/goodsManagement/constants/apiRoutes/index.ts create mode 100644 src/app/domains/pos/modules/goodsManagement/constants/index.ts create mode 100644 src/app/domains/pos/modules/goodsManagement/constants/routes/index.ts create mode 100644 src/app/domains/pos/modules/goodsManagement/models/index.ts create mode 100644 src/app/domains/pos/modules/goodsManagement/models/io.d.ts create mode 100644 src/app/domains/pos/modules/goodsManagement/services/main.service.ts create mode 100644 src/app/domains/pos/modules/goodsManagement/views/create.component.html create mode 100644 src/app/domains/pos/modules/goodsManagement/views/create.component.ts create mode 100644 src/app/domains/pos/modules/goodsManagement/views/index.ts create mode 100644 src/app/domains/pos/modules/goodsManagement/views/list.component.html create mode 100644 src/app/domains/pos/modules/goodsManagement/views/list.component.ts create mode 100644 src/app/domains/pos/modules/goodsManagement/views/update.component.html create mode 100644 src/app/domains/pos/modules/goodsManagement/views/update.component.ts create mode 100644 src/app/shared/components/good/form-dialog.component.html create mode 100644 src/app/shared/components/good/form-dialog.component.ts diff --git a/.prettierrc.json b/.prettierrc.json index 4e6fc5a..74ca6df 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -5,28 +5,28 @@ "endOfLine": "lf", "overrides": [ { - "files": "*.html", + "files": "**/*.html", "options": { "bracketSameLine": true, "printWidth": 120 } }, { - "files": "*.scss", + "files": "**/*.scss", "options": { "printWidth": 120, "singleQuote": false } }, { - "files": "*.less", + "files": "**/*.less", "options": { "printWidth": 120, "singleQuote": false } }, { - "files": "*.json", + "files": "**/*.json", "options": { "printWidth": 100 } @@ -40,6 +40,10 @@ "semi": true, "singleQuote": true, "tabWidth": 2, + "tailwindAttributes": [ + "class", + "ngClass" + ], "trailingComma": "es5", "useTabs": false } diff --git a/package.json b/package.json index 8b0ddf7..5698beb 100644 --- a/package.json +++ b/package.json @@ -55,16 +55,6 @@ "typescript": "~5.8.3" }, "name": "psp_panel", - "prettier": { - "overrides": [ - { - "files": "*.html", - "options": { - "parser": "angular" - } - } - ] - }, "private": true, "scripts": { "build": "ng build", diff --git a/src/app/domains/consumer/modules/businessActivities/components/goods/form.component.html b/src/app/domains/consumer/modules/businessActivities/components/goods/form.component.html index e2cd491..a10ea3e 100644 --- a/src/app/domains/consumer/modules/businessActivities/components/goods/form.component.html +++ b/src/app/domains/consumer/modules/businessActivities/components/goods/form.component.html @@ -1,4 +1,4 @@ - + (onClose)="onClose.emit()" /> diff --git a/src/app/domains/consumer/modules/businessActivities/components/goods/form.component.ts b/src/app/domains/consumer/modules/businessActivities/components/goods/form.component.ts index 8f97191..42cac42 100644 --- a/src/app/domains/consumer/modules/businessActivities/components/goods/form.component.ts +++ b/src/app/domains/consumer/modules/businessActivities/components/goods/form.component.ts @@ -1,14 +1,15 @@ import { Component, EventEmitter, Input, Output, inject } from '@angular/core'; import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog'; -import { IGoodResponse, SharedGoodFormComponent } from '@/shared/components/good'; +import { IGoodResponse } from '@/shared/components/good'; +import { ConsumerUserFormDialogComponent } from '@/shared/components/good/form-dialog.component'; import { IConsumerBusinessActivityGoodResponse } from '../../models/goods_io'; import { BusinessActivityGoodsService } from '../../services/goods.service'; @Component({ selector: 'consumer-businessActivity-good-form', templateUrl: './form.component.html', - imports: [SharedGoodFormComponent], + imports: [ConsumerUserFormDialogComponent], }) export class ConsumerBusinessActivityGoodFormComponent extends AbstractDialog { @Input({ required: true }) businessId!: string; diff --git a/src/app/domains/pos/layouts/mainMenuSidebar/main-menu-sidebar.component.ts b/src/app/domains/pos/layouts/mainMenuSidebar/main-menu-sidebar.component.ts index a4637b9..317c9d7 100644 --- a/src/app/domains/pos/layouts/mainMenuSidebar/main-menu-sidebar.component.ts +++ b/src/app/domains/pos/layouts/mainMenuSidebar/main-menu-sidebar.component.ts @@ -8,6 +8,7 @@ import { Ripple } from 'primeng/ripple'; import config from 'src/config'; import { posAboutNamedRoutes } from '../../modules/about/constants'; import { posConfigNamedRoutes } from '../../modules/configs/constants'; +import { PosGoodsManagementRoutes } from '../../modules/goodsManagement/constants'; import { posSaleInvoicesNamedRoutes } from '../../modules/saleInvoices/constants'; import { posSupportNamedRoutes } from '../../modules/support/constants'; import { PosInfoStore } from '../../store'; @@ -45,6 +46,11 @@ export class PosMainMenuSidebarComponent extends AbstractDialog { routerLink: posSaleInvoicesNamedRoutes.saleInvoices.meta.pagePath!(), icon: 'pi pi-fw pi-receipt', }, + { + label: 'کالاها', + routerLink: PosGoodsManagementRoutes.goods.meta.pagePath!(), + icon: 'pi pi-fw pi-objects-column', + }, { label: 'تنظیمات', routerLink: posConfigNamedRoutes.config.meta.pagePath!(), diff --git a/src/app/domains/pos/modules/goodsManagement/components/index.ts b/src/app/domains/pos/modules/goodsManagement/components/index.ts new file mode 100644 index 0000000..576a89e --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/components/index.ts @@ -0,0 +1 @@ +export * from './list.component'; diff --git a/src/app/domains/pos/modules/goodsManagement/components/list.component.html b/src/app/domains/pos/modules/goodsManagement/components/list.component.html new file mode 100644 index 0000000..6bf2250 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/components/list.component.html @@ -0,0 +1,46 @@ +
+ + + + + +
+
+
+ @if (loading()) { + @for (_ of [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15]; track $index) { +
+ +
+ } + } @else { + @for (good of items(); track good.id) { +
+
+ +
+ + {{ good.name }} + + + {{ good.sku.code }} + +
+
+
+ +
+
+ } + } +
diff --git a/src/app/domains/pos/modules/goodsManagement/components/list.component.ts b/src/app/domains/pos/modules/goodsManagement/components/list.component.ts new file mode 100644 index 0000000..76ae498 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/components/list.component.ts @@ -0,0 +1,56 @@ +import { POS_ROUTES } from '@/domains/pos/routes'; +import { PosInfoStore } from '@/domains/pos/store'; +import { InnerPagesHeaderComponent } from '@/shared/components/innerPagesHeader/inner-pages-header.component'; +import { Component, computed, inject, signal } from '@angular/core'; +import { Router, RouterLink } from '@angular/router'; +import { Button, ButtonDirective } from 'primeng/button'; +import { Skeleton } from 'primeng/skeleton'; +import { finalize } from 'rxjs'; +import images from 'src/assets/images'; + +import { PosGoodsManagementRoutes } from '../constants'; +import { IPosGoodsManagementResponse } from '../models'; +import { PosOwnedGoodsService } from '../services/main.service'; + +@Component({ + selector: 'pos-ownedGoods-list', + templateUrl: './list.component.html', + imports: [InnerPagesHeaderComponent, ButtonDirective, Skeleton, Button, RouterLink], +}) +export class PosOwnedGoodsListComponent { + private readonly service = inject(PosOwnedGoodsService); + private readonly infoStore = inject(PosInfoStore); + private readonly router = inject(Router); + + goodPlaceholder = images.placeholders.default; + + loading = signal(true); + items = signal([]); + backRoute = POS_ROUTES.path || '/'; + + preparedPageTitle = computed( + () => `لیست کالاهای ${this.infoStore.entity()?.businessActivity.name}` + ); + + ngOnInit() { + this.getData(); + } + + getData() { + this.loading.set(true); + this.service + .getAll() + .pipe(finalize(() => this.loading.set(false))) + .subscribe((res) => { + this.items.set(res.data ?? []); + }); + } + + refresh() { + this.getData(); + } + + editPageRoute(goodId: string) { + return PosGoodsManagementRoutes.update.meta.pagePath!(goodId); + } +} diff --git a/src/app/domains/pos/modules/goodsManagement/constants/apiRoutes/index.ts b/src/app/domains/pos/modules/goodsManagement/constants/apiRoutes/index.ts new file mode 100644 index 0000000..5e498ae --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/constants/apiRoutes/index.ts @@ -0,0 +1,8 @@ +const baseUrl = () => `/api/v1/pos/owned-goods`; + +export const POS_OWNED_GOODS_API_ROUTES = { + getAll: () => `${baseUrl()}`, + get: (good_id: string) => `${baseUrl()}/${good_id}`, + create: () => `${baseUrl()}`, + update: (good_id: string) => `${baseUrl()}/${good_id}`, +}; diff --git a/src/app/domains/pos/modules/goodsManagement/constants/index.ts b/src/app/domains/pos/modules/goodsManagement/constants/index.ts new file mode 100644 index 0000000..8d8c878 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/constants/index.ts @@ -0,0 +1,2 @@ +export * from './apiRoutes/index'; +export * from './routes/index'; diff --git a/src/app/domains/pos/modules/goodsManagement/constants/routes/index.ts b/src/app/domains/pos/modules/goodsManagement/constants/routes/index.ts new file mode 100644 index 0000000..cb87905 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/constants/routes/index.ts @@ -0,0 +1,43 @@ +import { NamedRoutes } from '@/core'; +import { Routes } from '@angular/router'; +import config from 'src/config'; + +export type TPosGoodsManagementRouteNames = 'goods' | 'update' | 'create'; + +const baseRoute = `${config.isPosApplication ? '' : '/pos'}/goods`; + +export const PosGoodsManagementRoutes: NamedRoutes = { + goods: { + path: 'goods', + loadComponent: () => + import('../../views/list.component').then((m) => m.PosGoodsManagementListComponent), + meta: { + title: 'مدیریت کالاها', + pagePath: () => baseRoute, + }, + }, + update: { + path: 'goods/:goodId', + loadComponent: () => + import('../../views/update.component').then((m) => m.PosGoodsUpdateComponent), + meta: { + title: 'ویرایش کالا', + pagePath: (goodId: string) => `${baseRoute}/${goodId}`, + }, + }, + create: { + path: 'goods/create', + loadComponent: () => + import('../../views/create.component').then((m) => m.PosGoodsCreateComponent), + meta: { + title: 'ایجاد کالا', + pagePath: () => baseRoute, + }, + }, +}; + +export const POS_GOODS_MANAGEMENT_ROUTES: Routes = [ + PosGoodsManagementRoutes.goods, + PosGoodsManagementRoutes.create, + PosGoodsManagementRoutes.update, +]; diff --git a/src/app/domains/pos/modules/goodsManagement/models/index.ts b/src/app/domains/pos/modules/goodsManagement/models/index.ts new file mode 100644 index 0000000..61a518a --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/models/index.ts @@ -0,0 +1 @@ +export * from './io'; diff --git a/src/app/domains/pos/modules/goodsManagement/models/io.d.ts b/src/app/domains/pos/modules/goodsManagement/models/io.d.ts new file mode 100644 index 0000000..aad6b77 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/models/io.d.ts @@ -0,0 +1,7 @@ +import { IGoodResponse } from '@/domains/pos/models'; +import { IGoodRequestPayload } from '@/shared/components/good'; + +export interface IPosGoodsManagementRawResponse extends IGoodResponse {} +export interface IPosGoodsManagementResponse extends IPosGoodsManagementRawResponse {} + +export interface IPosGoodsManagementRequestPayload extends IGoodRequestPayload {} diff --git a/src/app/domains/pos/modules/goodsManagement/services/main.service.ts b/src/app/domains/pos/modules/goodsManagement/services/main.service.ts new file mode 100644 index 0000000..b6c8968 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/services/main.service.ts @@ -0,0 +1,29 @@ +import { IListingResponse } from '@/core/models/service.model'; +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { POS_OWNED_GOODS_API_ROUTES } from '../constants'; +import { IPosGoodsManagementRawResponse, IPosGoodsManagementResponse } from '../models'; + +@Injectable({ providedIn: 'root' }) +export class PosOwnedGoodsService { + constructor(private http: HttpClient) {} + + private apiRoutes = POS_OWNED_GOODS_API_ROUTES; + + getAll(): Observable> { + return this.http.get>(this.apiRoutes.getAll()); + } + + get(goodId: string): Observable { + return this.http.get(this.apiRoutes.get(goodId)); + } + + create(data: FormData): Observable { + return this.http.post(this.apiRoutes.create(), data); + } + + update(goodId: string, payload: FormData): Observable { + return this.http.patch(this.apiRoutes.update(goodId), payload); + } +} diff --git a/src/app/domains/pos/modules/goodsManagement/views/create.component.html b/src/app/domains/pos/modules/goodsManagement/views/create.component.html new file mode 100644 index 0000000..942b293 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/views/create.component.html @@ -0,0 +1,7 @@ +
+ +
+
+ +
+
diff --git a/src/app/domains/pos/modules/goodsManagement/views/create.component.ts b/src/app/domains/pos/modules/goodsManagement/views/create.component.ts new file mode 100644 index 0000000..d559733 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/views/create.component.ts @@ -0,0 +1,36 @@ +import { PosInfoStore } from '@/domains/pos/store'; +import { SharedGoodFormComponent } from '@/shared/components/good'; +import { InnerPagesHeaderComponent } from '@/shared/components/innerPagesHeader/inner-pages-header.component'; +import { Component, computed, inject } from '@angular/core'; +import { Router } from '@angular/router'; +import config from 'src/config'; +import { PosOwnedGoodsService } from '../services/main.service'; + +@Component({ + selector: 'pos-good-create', + templateUrl: './create.component.html', + imports: [SharedGoodFormComponent, InnerPagesHeaderComponent], +}) +export class PosGoodsCreateComponent { + private readonly router = inject(Router); + private readonly store = inject(PosInfoStore); + private readonly service = inject(PosOwnedGoodsService); + + readonly guildId = computed(() => this.store.entity()?.guild.id || ''); + + readonly backRoute = config.isPosApplication ? '/' : '/pos'; + + preparedPageTitle = computed( + () => `ایجاد کالا برای ${this.store.entity()?.businessActivity.name}` + ); + + onSubmit() { + this.onPrev(); + } + + onPrev() { + this.router.navigateByUrl(this.backRoute); + } + + createFn = (payload: FormData) => this.service.create(payload); +} diff --git a/src/app/domains/pos/modules/goodsManagement/views/index.ts b/src/app/domains/pos/modules/goodsManagement/views/index.ts new file mode 100644 index 0000000..07b20d2 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/views/index.ts @@ -0,0 +1,3 @@ +export * from './create.component'; +export * from './list.component'; +export * from './update.component'; diff --git a/src/app/domains/pos/modules/goodsManagement/views/list.component.html b/src/app/domains/pos/modules/goodsManagement/views/list.component.html new file mode 100644 index 0000000..9c37e31 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/views/list.component.html @@ -0,0 +1 @@ + diff --git a/src/app/domains/pos/modules/goodsManagement/views/list.component.ts b/src/app/domains/pos/modules/goodsManagement/views/list.component.ts new file mode 100644 index 0000000..2a05504 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/views/list.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; +import { PosOwnedGoodsListComponent } from '../components'; + +@Component({ + selector: 'pos-goodsManagement-list', + templateUrl: './list.component.html', + imports: [PosOwnedGoodsListComponent], +}) +export class PosGoodsManagementListComponent {} diff --git a/src/app/domains/pos/modules/goodsManagement/views/update.component.html b/src/app/domains/pos/modules/goodsManagement/views/update.component.html new file mode 100644 index 0000000..eadbb2d --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/views/update.component.html @@ -0,0 +1,16 @@ +
+ +
+
+ @if (loading()) { + } @else if (item()) { + + } +
+
diff --git a/src/app/domains/pos/modules/goodsManagement/views/update.component.ts b/src/app/domains/pos/modules/goodsManagement/views/update.component.ts new file mode 100644 index 0000000..698b693 --- /dev/null +++ b/src/app/domains/pos/modules/goodsManagement/views/update.component.ts @@ -0,0 +1,60 @@ +import { Maybe } from '@/core'; +import { PosInfoStore } from '@/domains/pos/store'; +import { SharedGoodFormComponent } from '@/shared/components/good'; +import { InnerPagesHeaderComponent } from '@/shared/components/innerPagesHeader/inner-pages-header.component'; +import pageParamsUtils from '@/utils/page-params.utils'; +import { Component, computed, inject, signal } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { finalize } from 'rxjs'; +import { PosGoodsManagementRoutes } from '../constants'; +import { IPosGoodsManagementResponse } from '../models'; +import { PosOwnedGoodsService } from '../services/main.service'; + +@Component({ + selector: 'pos-good-update', + templateUrl: './update.component.html', + imports: [SharedGoodFormComponent, InnerPagesHeaderComponent], +}) +export class PosGoodsUpdateComponent { + private readonly route = inject(ActivatedRoute); + private readonly router = inject(Router); + private readonly store = inject(PosInfoStore); + private readonly service = inject(PosOwnedGoodsService); + + loading = signal(true); + item = signal>(null); + + pageParams = computed(() => pageParamsUtils(this.route)); + goodId = signal(this.pageParams()['goodId']); + + readonly backRoute = PosGoodsManagementRoutes.goods.meta.pagePath!(); + + preparedPageTitle = computed(() => `ویرایش ${this.item()?.name || ''}`); + readonly guildId = computed(() => this.store.entity()?.guild.id || ''); + + ngOnInit() { + this.loading.set(true); + this.service + .get(this.goodId()) + .pipe( + finalize(() => { + this.loading.set(false); + }) + ) + .subscribe((res) => { + this.item.set(res); + }); + } + + onSubmit() { + this.onPrev(); + } + + onPrev() { + this.router.navigateByUrl(PosGoodsManagementRoutes.goods.meta.pagePath!()); + } + + updateFn = (payload: FormData) => { + return this.service.update(this.goodId(), payload); + }; +} diff --git a/src/app/domains/pos/modules/landing/components/list-view.component.html b/src/app/domains/pos/modules/landing/components/list-view.component.html index dc390f0..90e41d1 100644 --- a/src/app/domains/pos/modules/landing/components/list-view.component.html +++ b/src/app/domains/pos/modules/landing/components/list-view.component.html @@ -1,33 +1,32 @@ -
+
@if (loading()) { @for (_ of [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15]; track $index) { -
+
} } @else { @for (good of visibleGoods(); track good.id) { -
-
+
+
+ class="h-12 w-12 rounded-md object-cover" />
{{ good.name }} @if (!good.is_default_guild_good) { - * + * } - + {{ good.sku.code }}
-
+
diff --git a/src/app/domains/pos/modules/landing/components/payment/form-dialog.component.ts b/src/app/domains/pos/modules/landing/components/payment/form-dialog.component.ts index c86e5c0..5d6f746 100644 --- a/src/app/domains/pos/modules/landing/components/payment/form-dialog.component.ts +++ b/src/app/domains/pos/modules/landing/components/payment/form-dialog.component.ts @@ -61,7 +61,7 @@ export class PosPaymentFormDialogComponent extends AbstractFormDialog { return throwError(() => err); - }), + }) ) .subscribe((res) => { this.close(); diff --git a/src/app/domains/pos/routes.ts b/src/app/domains/pos/routes.ts index 9246ee9..e2ab395 100644 --- a/src/app/domains/pos/routes.ts +++ b/src/app/domains/pos/routes.ts @@ -1,6 +1,7 @@ import { Route } from '@angular/router'; import { POS_ABOUT_ROUTES } from './modules/about/constants'; import { POS_CONFIG_ROUTES } from './modules/configs/constants'; +import { POS_GOODS_MANAGEMENT_ROUTES } from './modules/goodsManagement/constants'; import { POS_SALE_INVOICES_ROUTES } from './modules/saleInvoices/constants'; import { POS_SUPPORT_ROUTES } from './modules/support/constants'; @@ -17,5 +18,6 @@ export const POS_ROUTES = { ...POS_ABOUT_ROUTES, ...POS_SUPPORT_ROUTES, ...POS_CONFIG_ROUTES, + ...POS_GOODS_MANAGEMENT_ROUTES, ], } as Route; diff --git a/src/app/shared/components/good/form-dialog.component.html b/src/app/shared/components/good/form-dialog.component.html new file mode 100644 index 0000000..f99c631 --- /dev/null +++ b/src/app/shared/components/good/form-dialog.component.html @@ -0,0 +1,18 @@ + + @if (visible) { + + } + diff --git a/src/app/shared/components/good/form-dialog.component.ts b/src/app/shared/components/good/form-dialog.component.ts new file mode 100644 index 0000000..6c5af74 --- /dev/null +++ b/src/app/shared/components/good/form-dialog.component.ts @@ -0,0 +1,30 @@ +import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog'; +import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Observable } from 'rxjs'; +import { SharedGoodFormComponent } from './form.component'; +import { IGoodResponse } from './types'; + +@Component({ + selector: 'shared-good-form-dialog', + templateUrl: './form-dialog.component.html', + imports: [SharedDialogComponent, SharedGoodFormComponent], +}) +export class ConsumerUserFormDialogComponent extends AbstractDialog { + @Output() onSubmit = new EventEmitter(); + @Input() initialValues?: IGoodResponse; + @Input() editMode?: boolean; + @Input({ required: true }) guildId!: string; + + @Input() createFn?: (payload: FormData) => Observable; + @Input() updateFn?: (payload: FormData) => Observable; + + get preparedTitle() { + return `${this.editMode ? 'ویرایش' : 'افزودن'} کالا`; + } + + onFormSubmit(response: IGoodResponse) { + this.onSubmit.emit(response); + this.close(); + } +} diff --git a/src/app/shared/components/good/form.component.html b/src/app/shared/components/good/form.component.html index 057ee98..cf54073 100644 --- a/src/app/shared/components/good/form.component.html +++ b/src/app/shared/components/good/form.component.html @@ -1,19 +1,22 @@ - -
- @if (visible) { - - } - - - - - - + + + + + + + + - - -
+ + diff --git a/src/app/shared/components/good/form.component.ts b/src/app/shared/components/good/form.component.ts index 4480615..197e5c3 100644 --- a/src/app/shared/components/good/form.component.ts +++ b/src/app/shared/components/good/form.component.ts @@ -1,4 +1,4 @@ -import { AbstractFormDialog } from '@/shared/abstractClasses'; +import { AbstractForm } from '@/shared/abstractClasses'; import { DescriptionComponent, NameComponent, SkuComponent } from '@/shared/components'; import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component'; import { Component, Input, signal } from '@angular/core'; @@ -8,7 +8,6 @@ import { Maybe } from '@/core'; import { EnumSelectComponent } from '@/shared/apiEnum/select.component'; import { CatalogGuildGoodCategoriesSelectComponent } from '@/shared/catalog/guildGoodCategories'; import { CatalogMeasureUnitsSelectComponent } from '@/shared/catalog/measureUnits'; -import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component'; import { onSelectFileArgs } from '@/shared/components/uploadFile/model'; import { fieldControl } from '@/shared/constants'; import { buildFormData } from '@/utils'; @@ -21,7 +20,6 @@ import { IGoodRequestPayload, IGoodResponse } from './types'; templateUrl: './form.component.html', imports: [ ReactiveFormsModule, - SharedDialogComponent, FormFooterActionsComponent, EnumSelectComponent, SkuComponent, @@ -32,13 +30,10 @@ import { IGoodRequestPayload, IGoodResponse } from './types'; CatalogGuildGoodCategoriesSelectComponent, ], }) -export class SharedGoodFormComponent extends AbstractFormDialog< - IGoodRequestPayload, - IGoodResponse -> { +export class SharedGoodFormComponent extends AbstractForm { @Input({ required: true }) guildId!: string; - @Input({ required: true }) createFn!: (payload: FormData) => Observable; - @Input({ required: true }) updateFn!: (payload: FormData) => Observable; + @Input() createFn?: (payload: FormData) => Observable; + @Input() updateFn?: (payload: FormData) => Observable; goodImage = signal>(null); @@ -69,8 +64,8 @@ export class SharedGoodFormComponent extends AbstractFormDialog< override submitForm() { const formData = buildFormData(this.form, { image: this.goodImage() }); if (this.editMode) { - return this.updateFn(formData); + return this.updateFn?.(formData); } - return this.createFn(formData); + return this.createFn?.(formData); } }