diff --git a/src/styles_OLD.css b/src/_styles_OLD.txt similarity index 100% rename from src/styles_OLD.css rename to src/_styles_OLD.txt diff --git a/src/app/features/components/products/product-list/product-list.component.ts b/src/app/features/components/products/product-list/product-list.component.ts index ec73399..cb13706 100644 --- a/src/app/features/components/products/product-list/product-list.component.ts +++ b/src/app/features/components/products/product-list/product-list.component.ts @@ -3,12 +3,18 @@ import { Component, OnInit, inject } from '@angular/core'; import { Router } from '@angular/router'; import { CommonModule, CurrencyPipe, DatePipe } from '@angular/common'; -import { AdminProduct, ProductImage } from '../../../../core/models/product.model'; +import { + AdminProduct, + ProductImage, +} from '../../../../core/models/product.model'; import { ProductService } from '../../../services/product.service'; import { SupplierService } from '../../../services/supplier.service'; import { SnackbarService } from '../../../../shared/services/snackbar.service'; import { StorageService } from '../../../../core/services/storage.service'; -import { GenericTableComponent, ColumnConfig } from '../../../../shared/components/data-display/generic-table/generic-table.component'; +import { + GenericTableComponent, + ColumnConfig, +} from '../../../../shared/components/data-display/generic-table/generic-table.component'; import { SearchBarComponent } from '../../../../shared/components/layout/search-bar/search-bar.component'; import { ButtonComponent } from '../../../../shared/components/ui/button/button.component'; import { IconComponent } from '../../../../shared/components/ui/icon/icon.component'; @@ -16,10 +22,18 @@ import { IconComponent } from '../../../../shared/components/ui/icon/icon.compon @Component({ selector: 'app-product-list', standalone: true, - imports: [CommonModule, CurrencyPipe, DatePipe, GenericTableComponent, SearchBarComponent, ButtonComponent, IconComponent], + imports: [ + CommonModule, + CurrencyPipe, + DatePipe, + GenericTableComponent, + SearchBarComponent, + ButtonComponent, + IconComponent, + ], providers: [DatePipe], templateUrl: './product-list.component.html', - styleUrl: './product-list.component.css' + styleUrl: './product-list.component.css', }) export class ProductListComponent implements OnInit { private productService = inject(ProductService); @@ -28,21 +42,65 @@ export class ProductListComponent implements OnInit { private snackbar = inject(SnackbarService); private storageService = inject(StorageService); private datePipe = inject(DatePipe); - + private readonly TABLE_SETTINGS_KEY = 'product-table-columns'; - allProducts: (AdminProduct & { mainImage?: string; supplierName?: string })[] = []; - filteredProducts: (AdminProduct & { mainImage?: string; supplierName?: string })[] = []; + allProducts: (AdminProduct & { + mainImage?: string; + supplierName?: string; + })[] = []; + filteredProducts: (AdminProduct & { + mainImage?: string; + supplierName?: string; + })[] = []; isColumnFilterVisible = false; readonly allTableColumns: ColumnConfig[] = [ { key: 'mainImage', title: 'Bild', type: 'image' }, { key: 'name', title: 'Name', type: 'text', subKey: 'sku' }, { key: 'price', title: 'Preis', type: 'currency', cssClass: 'text-right' }, - { key: 'stockQuantity', title: 'Lager', type: 'text', cssClass: 'text-right' }, + { + key: 'stockQuantity', + title: 'Lager', + type: 'text', + cssClass: 'text-right', + }, { key: 'supplierName', title: 'Lieferant', type: 'text' }, { key: 'isActive', title: 'Aktiv', type: 'status' }, - { key: 'actions', title: 'Aktionen', type: 'actions', cssClass: 'text-right' } + { key: 'id', title: 'ID', type: 'text' }, + { key: 'description', title: 'Beschreibung', type: 'text' }, + { + key: 'oldPrice', + title: 'Alter Preis', + type: 'currency', + cssClass: 'text-right', + }, + { + key: 'purchasePrice', + title: 'Einkaufspreis', + type: 'currency', + cssClass: 'text-right', + }, + { key: 'isInStock', title: 'Auf Lager', type: 'status' }, + { key: 'weight', title: 'Gewicht', type: 'number', cssClass: 'text-right' }, + { key: 'slug', title: 'Slug', type: 'text' }, + { key: 'createdDate', title: 'Erstellt am', type: 'date' }, + { key: 'lastModifiedDate', title: 'Zuletzt geƤndert', type: 'date' }, + { key: 'supplierId', title: 'Lieferanten-ID', type: 'text' }, + { key: 'categorieIds', title: 'Kategorie-IDs', type: 'text' }, + { key: 'isFeatured', title: 'Hervorgehoben', type: 'status' }, + { + key: 'featuredDisplayOrder', + title: 'Anzeigereihenfolge (hervorgehoben)', + type: 'number', + cssClass: 'text-right', + }, + { + key: 'actions', + title: 'Aktionen', + type: 'actions', + cssClass: 'text-right', + }, ]; visibleTableColumns: ColumnConfig[] = []; @@ -55,15 +113,16 @@ export class ProductListComponent implements OnInit { } loadProducts(): void { - this.productService.getAll().subscribe(products => { - this.supplierService.getAll().subscribe(suppliers => { - this.allProducts = products.map(p => { - const supplier = suppliers.find(s => s.id === p.supplierId); + this.productService.getAll().subscribe((products) => { + this.supplierService.getAll().subscribe((suppliers) => { + this.allProducts = products.map((p) => { + const supplier = suppliers.find((s) => s.id === p.supplierId); return { ...p, mainImage: this.getMainImageUrl(p.images), supplierName: supplier?.name || '-', - createdDate: this.datePipe.transform(p.createdDate, 'dd.MM.yyyy HH:mm') || '-', + createdDate: + this.datePipe.transform(p.createdDate, 'dd.MM.yyyy HH:mm') || '-', }; }); this.onSearch(''); @@ -73,9 +132,10 @@ export class ProductListComponent implements OnInit { onSearch(term: string): void { const lowerTerm = term.toLowerCase(); - this.filteredProducts = this.allProducts.filter(p => - p.name?.toLowerCase().includes(lowerTerm) || - p.sku?.toLowerCase().includes(lowerTerm) + this.filteredProducts = this.allProducts.filter( + (p) => + p.name?.toLowerCase().includes(lowerTerm) || + p.sku?.toLowerCase().includes(lowerTerm) ); } @@ -97,14 +157,26 @@ export class ProductListComponent implements OnInit { } private loadTableSettings(): void { - const savedKeys = this.storageService.getItem(this.TABLE_SETTINGS_KEY); - const defaultKeys = ['mainImage', 'name', 'price', 'stockQuantity', 'isActive', 'actions']; - const keysToUse = (savedKeys && savedKeys.length > 0) ? savedKeys : defaultKeys; - this.visibleTableColumns = this.allTableColumns.filter(c => keysToUse.includes(c.key)); + const savedKeys = this.storageService.getItem( + this.TABLE_SETTINGS_KEY + ); + const defaultKeys = [ + 'mainImage', + 'name', + 'price', + 'stockQuantity', + 'isActive', + 'actions', + ]; + const keysToUse = + savedKeys && savedKeys.length > 0 ? savedKeys : defaultKeys; + this.visibleTableColumns = this.allTableColumns.filter((c) => + keysToUse.includes(c.key) + ); } private saveTableSettings(): void { - const visibleKeys = this.visibleTableColumns.map(c => c.key); + const visibleKeys = this.visibleTableColumns.map((c) => c.key); this.storageService.setItem(this.TABLE_SETTINGS_KEY, visibleKeys); } @@ -113,26 +185,29 @@ export class ProductListComponent implements OnInit { } isColumnVisible(columnKey: string): boolean { - return this.visibleTableColumns.some(c => c.key === columnKey); + return this.visibleTableColumns.some((c) => c.key === columnKey); } onColumnToggle(column: ColumnConfig, event: Event): void { const checkbox = event.target as HTMLInputElement; if (checkbox.checked) { this.visibleTableColumns.push(column); - this.visibleTableColumns.sort((a, b) => - this.allTableColumns.findIndex(c => c.key === a.key) - - this.allTableColumns.findIndex(c => c.key === b.key) + this.visibleTableColumns.sort( + (a, b) => + this.allTableColumns.findIndex((c) => c.key === a.key) - + this.allTableColumns.findIndex((c) => c.key === b.key) ); } else { - this.visibleTableColumns = this.visibleTableColumns.filter(c => c.key !== column.key); + this.visibleTableColumns = this.visibleTableColumns.filter( + (c) => c.key !== column.key + ); } this.saveTableSettings(); } getMainImageUrl(images?: ProductImage[]): string { if (!images || images.length === 0) return 'https://via.placeholder.com/50'; - const mainImage = images.find(img => img.isMainImage); + const mainImage = images.find((img) => img.isMainImage); return mainImage?.url || images[0]?.url || 'https://via.placeholder.com/50'; } -} \ No newline at end of file +} diff --git a/src/app/features/components/products/product-new/product-new.component.css b/src/app/features/components/products/product-new/product-new.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/features/components/products/product-new/product-new.component.html b/src/app/features/components/products/product-new/product-new.component.html new file mode 100644 index 0000000..2ea317e --- /dev/null +++ b/src/app/features/components/products/product-new/product-new.component.html @@ -0,0 +1 @@ +

product-new works!

diff --git a/src/app/features/components/products/product-new/product-new.component.ts b/src/app/features/components/products/product-new/product-new.component.ts new file mode 100644 index 0000000..ce59b77 --- /dev/null +++ b/src/app/features/components/products/product-new/product-new.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-product-new', + imports: [], + templateUrl: './product-new.component.html', + styleUrl: './product-new.component.css' +}) +export class ProductNewComponent { + +} diff --git a/src/app/shared/components/data-display/generic-table/generic-table.component.ts b/src/app/shared/components/data-display/generic-table/generic-table.component.ts index f0876f0..98b3ce0 100644 --- a/src/app/shared/components/data-display/generic-table/generic-table.component.ts +++ b/src/app/shared/components/data-display/generic-table/generic-table.component.ts @@ -6,7 +6,7 @@ import { StatusPillComponent } from '../../ui/status-pill/status-pill.component' import { ButtonComponent } from '../../ui/button/button.component'; import { PaginatorComponent } from '../paginator/paginator.component'; -export type ColumnType = 'text' | 'currency' | 'status' | 'image-text' | 'image' | 'actions'; +export type ColumnType = 'text' | 'currency' | 'status' | 'image-text' | 'image' | 'actions' | 'date' | 'number'; export interface ColumnConfig { key: string;