From a6cc8faec6290563f421e9c8bf562cd8cb97a3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87etin?= <69278826+cetincakiroglu@users.noreply.github.com> Date: Mon, 6 Jan 2025 17:11:34 +0300 Subject: [PATCH] Fix crud --- src/views/pages/crud.ts | 641 +++++++++++++++++++++------------------- 1 file changed, 329 insertions(+), 312 deletions(-) diff --git a/src/views/pages/crud.ts b/src/views/pages/crud.ts index 7f3dd73..c8350ac 100644 --- a/src/views/pages/crud.ts +++ b/src/views/pages/crud.ts @@ -1,5 +1,5 @@ -import {Component, inject, OnInit} from '@angular/core'; -import { MessageService } from 'primeng/api'; +import { ChangeDetectorRef, Component, OnInit, signal, ViewChild } from '@angular/core'; +import { ConfirmationService, MessageService } from 'primeng/api'; import {Table, TableModule} from 'primeng/table'; import {CommonModule} from '@angular/common'; import {FileUploadModule} from 'primeng/fileupload'; @@ -16,357 +16,374 @@ import {RadioButtonModule} from 'primeng/radiobutton'; import {InputNumberModule} from 'primeng/inputnumber'; import {DialogModule} from 'primeng/dialog'; import { Product, ProductService } from '@/src/service/product.service'; +import { TagModule } from 'primeng/tag'; +import { InputIconModule } from 'primeng/inputicon'; +import { IconFieldModule } from 'primeng/iconfield'; +import { ConfirmDialogModule } from 'primeng/confirmdialog'; +interface Column { + field: string; + header: string; + customExportHeader?: string; +} + +interface ExportColumn { + title: string; + dataKey: string; +} @Component({ standalone: true, - imports: [ - CommonModule, - TableModule, - FileUploadModule, - FormsModule, - ButtonModule, - RippleModule, - ToastModule, - ToolbarModule, - RatingModule, - InputTextModule, - TextareaModule, - SelectModule, - RadioButtonModule, - InputNumberModule, - DialogModule - ], + imports: [ + CommonModule, + TableModule, + FormsModule, + ButtonModule, + RippleModule, + ToastModule, + ToolbarModule, + RatingModule, + InputTextModule, + TextareaModule, + SelectModule, + RadioButtonModule, + InputNumberModule, + DialogModule, + TagModule, + InputIconModule, + IconFieldModule, + ConfirmDialogModule + ], template: ` -
-
- - - -
- - -
-
+ + + + + - - - - - - - -
-
Manage Products
- - - - -
-
- - - - - - Code - Name - Image - Price - Category - Reviews - Status - - - - - - - - - Code - {{product.code || product.id}} - - - Name - {{product.name}} - - Image - - - - Price - {{product.price | currency:'USD'}} - - - Category - {{product.category}} - - Reviews - - - Status - {{product.inventoryStatus}} - - -
- - -
- - -
-
-
+ + + + - - - -
- - - Name is required. + + +
+
Manage Products
+ + + + +
+
+ + + + + + Code + + Name + + + Image + + Price + + + + Category + + + + Reviews + + + + Status + + + + + + + + + + + {{ product.code }} + {{ product.name }} + + + + {{ product.price | currency: 'USD' }} + {{ product.category }} + + + + + + + + + + + + +
+ + + +
+ +
+ + + Name is required.
-
- - -
-
- - - - {{product.inventoryStatus}} - - - {{option.label}} - - +
+ +
-
- -
-
- +
+ + +
+ +
+ Category +
+
+
-
- +
+
-
- +
+
-
- +
+
-
-
- - +
+
+ +
-
- - +
+ +
- - - - - - - - - -
- - Are you sure you want to delete {{product.name}}?
- - - - -
+ - -
- - Are you sure you want to delete selected products? -
- - - - -
-
+ + + + + + + `, - providers: [MessageService, ProductService], + providers: [MessageService, ProductService, ConfirmationService], }) export class Crud implements OnInit { + productDialog: boolean = false; - productDialog: boolean = false; + products = signal([]) - deleteProductDialog: boolean = false; + product!: Product; - deleteProductsDialog: boolean = false; + selectedProducts!: Product[] | null; - products: Product[] = []; + submitted: boolean = false; - product: Product = {}; + statuses!: any[]; - selectedProducts: Product[] = []; + @ViewChild('dt') dt!: Table; - submitted: boolean = false; + exportColumns!: ExportColumn[]; - cols: any[] = []; + cols!: Column[]; - statuses: any[] = []; + constructor( + private productService: ProductService, + private messageService: MessageService, + private confirmationService: ConfirmationService, + ) {} - private messageService = inject(MessageService); - - private productService = inject(ProductService); - - ngOnInit() { - this.productService.getProducts().then(data => this.products = data); - - this.cols = [ - { field: 'product', header: 'Product' }, - { field: 'price', header: 'Price' }, - { field: 'category', header: 'Category' }, - { field: 'rating', header: 'Reviews' }, - { field: 'inventoryStatus', header: 'Status' } - ]; - - this.statuses = [ - { label: 'INSTOCK', value: 'instock' }, - { label: 'LOWSTOCK', value: 'lowstock' }, - { label: 'OUTOFSTOCK', value: 'outofstock' } - ]; - } - - openNew() { - this.product = {}; - this.submitted = false; - this.productDialog = true; - } - - deleteSelectedProducts() { - this.deleteProductsDialog = true; - } - - editProduct(product: Product) { - this.product = { ...product }; - this.productDialog = true; - } - - deleteProduct(product: Product) { - this.deleteProductDialog = true; - this.product = { ...product }; - } - - confirmDeleteSelected() { - this.deleteProductsDialog = false; - this.products = this.products.filter(val => !this.selectedProducts.includes(val)); - this.messageService.add({ severity: 'success', summary: 'Successful', detail: 'Products Deleted', life: 3000 }); - this.selectedProducts = []; - } - - confirmDelete() { - this.deleteProductDialog = false; - this.products = this.products.filter(val => val.id !== this.product.id); - this.messageService.add({ severity: 'success', summary: 'Successful', detail: 'Product Deleted', life: 3000 }); - this.product = {}; - } - - hideDialog() { - this.productDialog = false; - this.submitted = false; - } - - saveProduct() { - this.submitted = true; - - if (this.product.name?.trim()) { - if (this.product.id) { - // @ts-ignore - this.product.inventoryStatus = this.product.inventoryStatus.value ? this.product.inventoryStatus.value : this.product.inventoryStatus; - this.products[this.findIndexById(this.product.id)] = this.product; - this.messageService.add({ severity: 'success', summary: 'Successful', detail: 'Product Updated', life: 3000 }); - } else { - this.product.id = this.createId(); - this.product.code = this.createId(); - this.product.image = 'product-placeholder.svg'; - // @ts-ignore - this.product.inventoryStatus = this.product.inventoryStatus ? this.product.inventoryStatus.value : 'INSTOCK'; - this.products.push(this.product); - this.messageService.add({ severity: 'success', summary: 'Successful', detail: 'Product Created', life: 3000 }); - } - - this.products = [...this.products]; - this.productDialog = false; - this.product = {}; - } - } - - findIndexById(id: string): number { - let index = -1; - for (let i = 0; i < this.products.length; i++) { - if (this.products[i].id === id) { - index = i; - break; - } + exportCSV() { + this.dt.exportCSV(); } - return index; - } - - createId(): string { - let id = ''; - const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - for (let i = 0; i < 5; i++) { - id += chars.charAt(Math.floor(Math.random() * chars.length)); + ngOnInit() { + this.loadDemoData(); } - return id; - } - onGlobalFilter(table: Table, event: Event) { - table.filterGlobal((event.target as HTMLInputElement).value, 'contains'); - } + loadDemoData() { + this.productService.getProducts().then((data) => { + this.products.set(data); + }); + + this.statuses = [ + { label: 'INSTOCK', value: 'instock' }, + { label: 'LOWSTOCK', value: 'lowstock' }, + { label: 'OUTOFSTOCK', value: 'outofstock' } + ]; + + this.cols = [ + { field: 'code', header: 'Code', customExportHeader: 'Product Code' }, + { field: 'name', header: 'Name' }, + { field: 'image', header: 'Image' }, + { field: 'price', header: 'Price' }, + { field: 'category', header: 'Category' } + ]; + + this.exportColumns = this.cols.map((col) => ({ title: col.header, dataKey: col.field })); + } + + onGlobalFilter(table: Table, event: Event) { + table.filterGlobal((event.target as HTMLInputElement).value, 'contains'); + } + + openNew() { + this.product = {}; + this.submitted = false; + this.productDialog = true; + } + + editProduct(product: Product) { + this.product = { ...product }; + this.productDialog = true; + } + + deleteSelectedProducts() { + this.confirmationService.confirm({ + message: 'Are you sure you want to delete the selected products?', + header: 'Confirm', + icon: 'pi pi-exclamation-triangle', + accept: () => { + this.products.set(this.products().filter((val) => !this.selectedProducts?.includes(val))); + this.selectedProducts = null; + this.messageService.add({ + severity: 'success', + summary: 'Successful', + detail: 'Products Deleted', + life: 3000 + }); + + + } + }); + } + + hideDialog() { + this.productDialog = false; + this.submitted = false; + } + + deleteProduct(product: Product) { + this.confirmationService.confirm({ + message: 'Are you sure you want to delete ' + product.name + '?', + header: 'Confirm', + icon: 'pi pi-exclamation-triangle', + accept: () => { + this.products.set(this.products().filter((val) => val.id !== product.id)); + this.product = {}; + this.messageService.add({ + severity: 'success', + summary: 'Successful', + detail: 'Product Deleted', + life: 3000 + }); + } + }); + } + + findIndexById(id: string): number { + let index = -1; + for (let i = 0; i < this.products().length; i++) { + if (this.products()[i].id === id) { + index = i; + break; + } + } + + return index; + } + + createId(): string { + let id = ''; + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (var i = 0; i < 5; i++) { + id += chars.charAt(Math.floor(Math.random() * chars.length)); + } + return id; + } + + getSeverity(status: string) { + switch (status) { + case 'INSTOCK': + return 'success'; + case 'LOWSTOCK': + return 'warn'; + case 'OUTOFSTOCK': + return 'danger'; + default: + return 'info'; + } + } + + saveProduct() { + this.submitted = true; + let _products = this.products(); + if (this.product.name?.trim()) { + if (this.product.id) { + _products[this.findIndexById(this.product.id)] = this.product; + this.products.set([..._products]); + this.messageService.add({ + severity: 'success', + summary: 'Successful', + detail: 'Product Updated', + life: 3000 + }); + } else { + this.product.id = this.createId(); + this.product.image = 'product-placeholder.svg'; + this.messageService.add({ + severity: 'success', + summary: 'Successful', + detail: 'Product Created', + life: 3000 + }); + this.products.set([..._products, this.product]); + } + + this.productDialog = false; + this.product = {}; + } + } }