diff --git a/matsen-tool/src/app/_components/list/list-col-definition.ts b/matsen-tool/src/app/_components/list/list-col-definition.ts new file mode 100644 index 0000000..12190ef --- /dev/null +++ b/matsen-tool/src/app/_components/list/list-col-definition.ts @@ -0,0 +1,7 @@ +export interface ListColDefinition { + name: string, + text: string, + type: string, + field?: string + subResource?: string +} \ No newline at end of file diff --git a/matsen-tool/src/app/_components/list/list.component.html b/matsen-tool/src/app/_components/list/list.component.html new file mode 100644 index 0000000..761b384 --- /dev/null +++ b/matsen-tool/src/app/_components/list/list.component.html @@ -0,0 +1,59 @@ + +
+ + + + + + + + + + + + + + + + +
+ {{ column.text | translate }} + + + + + + + + + + {{ pagingComponent.getPageSize() * (pagingComponent.getPageIndex() - 1) + dataSource.filteredData.indexOf(element) + 1 }} + + + + + + + + {{ getElementValue(element, column) }} + + + + + {{ getElementValue(element, column) }} + + + +
+
+ +
\ No newline at end of file diff --git a/matsen-tool/src/app/_components/list/list.component.scss b/matsen-tool/src/app/_components/list/list.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/matsen-tool/src/app/_components/list/list.component.spec.ts b/matsen-tool/src/app/_components/list/list.component.spec.ts new file mode 100644 index 0000000..a82ee22 --- /dev/null +++ b/matsen-tool/src/app/_components/list/list.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ListComponent } from './list.component'; + +describe('ListComponent', () => { + let component: ListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ListComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/matsen-tool/src/app/_components/list/list.component.ts b/matsen-tool/src/app/_components/list/list.component.ts new file mode 100644 index 0000000..6c2a446 --- /dev/null +++ b/matsen-tool/src/app/_components/list/list.component.ts @@ -0,0 +1,128 @@ +import {AfterViewInit, Component, Input, OnInit, ViewChild} from '@angular/core'; +import {MatSort, Sort} from "@angular/material/sort"; +import {PagingComponent} from "@app/_components/paging/paging.component"; +import {MatTableDataSource} from "@angular/material/table"; +import {ListColDefinition} from "@app/_components/list/list-col-definition"; +import {OrderFilter} from "@app/_models/orderFilter"; + +type GeneralDataSource = MatTableDataSource; + +@Component({ + selector: 'app-list', + templateUrl: './list.component.html', + styleUrl: './list.component.scss' +}) +export class ListComponent implements OnInit, AfterViewInit { + + @Input() public dataSource!: GeneralDataSource; + @Input() public getDataFunction!: Function; + @Input() public navigateToDetailsFunction!: Function; + @Input() public searchable: boolean; + @Input() public listColDefinitions!: ListColDefinition[]; + @Input() public hidePageSize: boolean; + @ViewChild(MatSort) sort; + @ViewChild("pagingComponent", { static: false }) pagingComponent!: PagingComponent; + + public static COLUMN_TYPE_DETAIL: string = 'detail'; + public static COLUMN_TYPE_POSITION: string = 'position'; + public static COLUMN_TYPE_TEXT: string = 'text'; + public static COLUMN_TYPE_TEXT_LINKED: string = 'text_linked'; + public static COLUMN_TYPE_IMAGE: string = 'image'; + public static validColumnTypes: string[] = [ + ListComponent.COLUMN_TYPE_DETAIL, + ListComponent.COLUMN_TYPE_POSITION, + ListComponent.COLUMN_TYPE_TEXT, + ListComponent.COLUMN_TYPE_TEXT_LINKED, + ListComponent.COLUMN_TYPE_IMAGE + ]; + + + protected displayedColumns!: string[]; + protected selectedRowIndex: number | null = null; + + + constructor() { + this.searchable = true; + this.sort = new MatSort(); + this.hidePageSize = false; + } + + ngOnInit(): void { + this.displayedColumns = []; + this.listColDefinitions.forEach((value, index) => { + this.displayedColumns.push(value.name); + }); + } + + ngAfterViewInit(): void { + // this.searchBoxOpen = false; + } + + getData(): void { + this.getDataFunction() + } + + setData(dataSource: any, dataLength: number): void { + this.dataSource = dataSource; + this.pagingComponent.dataSource = dataSource; + this.pagingComponent.setDataLength(dataLength); + } + + onSortChange = (sortState: Sort) => { + this.pagingComponent.resetPageIndex() + + let order: OrderFilter; + if (sortState.direction === "") { + order = OrderFilter.Undefined; + } else { + order = sortState.direction; + } + this.pagingComponent.getData(); + } + + onRowSelected(row: any, index: number) { + console.log('row selected'); + console.log(row, index); + this.selectedRowIndex = index; + } + + getElementValue(element: any, column: ListColDefinition): any { + if (column.field) { + return column.subResource ? element[column.subResource][column.field] : element[column.field]; + } + } + + getElementImage(element: any, column: ListColDefinition): any { + let elementValue = this.getElementValue(element, column); + if (elementValue !== undefined && elementValue !== null) { + return elementValue; + } + return "/assets/images/icons/dummy-product.png" + } + + get COLUMN_TYPE_DETAIL(): string { return ListComponent.COLUMN_TYPE_DETAIL; } + get COLUMN_TYPE_POSITION(): string { return ListComponent.COLUMN_TYPE_POSITION; } + get COLUMN_TYPE_IMAGE(): string { return ListComponent.COLUMN_TYPE_IMAGE; } + get COLUMN_TYPE_TEXT(): string { return ListComponent.COLUMN_TYPE_TEXT; } + get COLUMN_TYPE_TEXT_LINKED(): string { return ListComponent.COLUMN_TYPE_TEXT_LINKED; } + + public static createColDefinition( + name: string, + text: string, + type: string, + field?: string, + subResource?: string + ): ListColDefinition { + if (!this.validColumnTypes.includes(type)) { + throw Error('invalid column type'); + } + + let res: ListColDefinition = {} as ListColDefinition; + res.name = name; + res.text = text; + res.type = type; + res.field = field; + res.subResource = subResource + return res; + } +} diff --git a/matsen-tool/src/app/_components/search-select/search-select.component.html b/matsen-tool/src/app/_components/search-select/search-select.component.html index 0ebf8bd..5ae07c4 100644 --- a/matsen-tool/src/app/_components/search-select/search-select.component.html +++ b/matsen-tool/src/app/_components/search-select/search-select.component.html @@ -10,7 +10,7 @@ [dataSource]="dataSource" [searchable]="true" [hidePageSize]="true" - > + >
diff --git a/matsen-tool/src/app/_views/products/product-list/product-list.component.html b/matsen-tool/src/app/_views/products/product-list/product-list.component.html index c9bb532..9254981 100644 --- a/matsen-tool/src/app/_views/products/product-list/product-list.component.html +++ b/matsen-tool/src/app/_views/products/product-list/product-list.component.html @@ -1,3 +1,19 @@ +
+
+ + +
+ +
+ +
@@ -71,4 +87,4 @@
- + \ No newline at end of file diff --git a/matsen-tool/src/app/_views/products/product-list/product-list.component.ts b/matsen-tool/src/app/_views/products/product-list/product-list.component.ts index b097c13..f1b0955 100644 --- a/matsen-tool/src/app/_views/products/product-list/product-list.component.ts +++ b/matsen-tool/src/app/_views/products/product-list/product-list.component.ts @@ -18,6 +18,8 @@ import {OrderFilter} from "@app/_models/orderFilter"; import {NewProductComponent} from "@app/_views/products/new-product/new-product.component"; import {AssignProductComponent} from "@app/_views/products/assign-product/assign-product.component"; import {TranslateService} from "@ngx-translate/core"; +import {ListColDefinition} from "@app/_components/list/list-col-definition"; +import {ListComponent} from "@app/_components/list/list.component"; type GeneralDataSource = MatTableDataSource; @Component({ @@ -32,6 +34,7 @@ export class ProductListComponent implements OnInit, AfterViewInit { @Input() public contact!: ContactJsonld; @ViewChild(MatSort) sort; @ViewChild("pagingComponent", { static: false }) pagingComponent!: PagingComponent; + @ViewChild("listComponent", { static: false }) listComponent!: ListComponent; protected displayedColumns: string[]; @@ -48,6 +51,8 @@ export class ProductListComponent implements OnInit, AfterViewInit { protected bShowNewProductButton: boolean; protected nameOrderAsc: OrderFilter; + public listColDefinitions!: ListColDefinition[]; + constructor( private router: Router, private productService: ProductService, @@ -71,6 +76,13 @@ export class ProductListComponent implements OnInit, AfterViewInit { this.dataSourceContactPartnerProducts = new MatTableDataSource(this.contactPartnerProducts); this.bShowNewProductButton = true; this.nameOrderAsc = OrderFilter.Asc; + + this.listColDefinitions = [ + ListComponent.createColDefinition('detail', 'overview.details', ListComponent.COLUMN_TYPE_DETAIL), + ListComponent.createColDefinition('pos', 'overview.number', ListComponent.COLUMN_TYPE_POSITION), + ListComponent.createColDefinition('img', 'overview.image', ListComponent.COLUMN_TYPE_IMAGE, 'imageUrl'), + ListComponent.createColDefinition('name', 'form.product', ListComponent.COLUMN_TYPE_TEXT_LINKED, 'name'), + ]; } ngOnInit(){ @@ -83,8 +95,9 @@ export class ProductListComponent implements OnInit, AfterViewInit { ngAfterViewInit() { this.dataSourceProducts.sort = this.sort; - this.dataSourceProducts.paginator = this.pagingComponent.paginator; - this.pagingComponent.getData(); + //this.dataSourceProducts.paginator = this.pagingComponent.paginator; + //this.pagingComponent.getData(); + this.listComponent.getData(); } getDataSource(): GeneralDataSource { @@ -113,24 +126,28 @@ export class ProductListComponent implements OnInit, AfterViewInit { getProducts = (searchValue = undefined) => { this.productsSub = this.productService.productsGetCollection( - this.pagingComponent.getPageIndex(), - this.pagingComponent.getPageSize(), + this.listComponent.pagingComponent.getPageIndex(), + this.listComponent.pagingComponent.getPageSize(), searchValue, undefined, this.nameOrderAsc, ).subscribe( data => { this.products = data["hydra:member"]; - this.pagingComponent.setDataLength(Number(data["hydra:totalItems"])); + this.listComponent.pagingComponent.setDataLength(Number(data["hydra:totalItems"])); this.dataSourceProducts = new MatTableDataSource(this.products); + + this.listComponent.setData(this.dataSourceProducts, Number(data["hydra:totalItems"])); + + } ); } getUserProducts = (searchValue = undefined) => { this.productsSub = this.userProductService.userProductsGetCollection( - this.pagingComponent.getPageIndex(), - this.pagingComponent.getPageSize(), + this.listComponent.pagingComponent.getPageIndex(), + this.listComponent.pagingComponent.getPageSize(), this.user.id, undefined, undefined, @@ -146,7 +163,7 @@ export class ProductListComponent implements OnInit, AfterViewInit { } }) - this.pagingComponent.setDataLength(Number(data["hydra:totalItems"])); + this.listComponent.pagingComponent.setDataLength(Number(data["hydra:totalItems"])); this.dataSourceProducts = new MatTableDataSource(this.products); } ); @@ -154,8 +171,8 @@ export class ProductListComponent implements OnInit, AfterViewInit { getPartnerProducts = (searchValue= undefined) => { this.productsSub = this.partnerProductService.partnerProductsGetCollection( - this.pagingComponent.getPageIndex(), - this.pagingComponent.getPageSize(), + this.listComponent.pagingComponent.getPageIndex(), + this.listComponent.pagingComponent.getPageSize(), this.partner.id, undefined, undefined, @@ -165,7 +182,7 @@ export class ProductListComponent implements OnInit, AfterViewInit { ).subscribe( data => { this.partnerProducts = data["hydra:member"]; - this.pagingComponent.setDataLength(Number(data["hydra:totalItems"])); + this.listComponent.pagingComponent.setDataLength(Number(data["hydra:totalItems"])); this.dataSourcePartnerProducts = new MatTableDataSource(this.partnerProducts); } ); @@ -173,15 +190,15 @@ export class ProductListComponent implements OnInit, AfterViewInit { getContactPartnerProduct = (searchValue = undefined) => { this.productsSub = this.contactPartnerProductService.contactPartnerProductsGetCollection( - this.pagingComponent.getPageIndex(), - this.pagingComponent.getPageSize(), + this.listComponent.pagingComponent.getPageIndex(), + this.listComponent.pagingComponent.getPageSize(), this.contact.id, undefined, searchValue ).subscribe( data => { this.contactPartnerProducts = data["hydra:member"]; - this.pagingComponent.setDataLength(Number(data["hydra:totalItems"])); + this.listComponent.pagingComponent.setDataLength(Number(data["hydra:totalItems"])); this.dataSourceContactPartnerProducts = new MatTableDataSource(this.contactPartnerProducts); } ); @@ -224,7 +241,7 @@ export class ProductListComponent implements OnInit, AfterViewInit { this.pagingComponent.getData(); } - navigateToProductDetails(element: any) { + navigateToProductDetails = (element: any, column?: any)=> { let product: ProductJsonld; if (this.user !== undefined) { product = element['partner']; diff --git a/matsen-tool/src/app/app.module.ts b/matsen-tool/src/app/app.module.ts index c1245d9..414700d 100644 --- a/matsen-tool/src/app/app.module.ts +++ b/matsen-tool/src/app/app.module.ts @@ -65,6 +65,7 @@ import { AssignProductComponent } from './_views/products/assign-product/assign- import { LinkedLabelComponent } from './_components/linked-label/linked-label.component'; import {LoadingInterceptor} from "@app/_helpers/loading-interceptor.service"; import { SearchSelectComponent } from './_components/search-select/search-select.component'; +import { ListComponent } from './_components/list/list.component'; export function apiConfigFactory(): Configuration { @@ -152,6 +153,7 @@ export function HttpLoaderFactory(http: HttpClient) { AssignProductComponent, LinkedLabelComponent, SearchSelectComponent, + ListComponent, ], providers: [ {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true},