Просмотр исходного кода

wip generic table component

master
Daniel 1 год назад
Родитель
Сommit
aa76fe59ad
9 измененных файлов: 269 добавлений и 17 удалений
  1. +7
    -0
      matsen-tool/src/app/_components/list/list-col-definition.ts
  2. +59
    -0
      matsen-tool/src/app/_components/list/list.component.html
  3. +0
    -0
      matsen-tool/src/app/_components/list/list.component.scss
  4. +23
    -0
      matsen-tool/src/app/_components/list/list.component.spec.ts
  5. +128
    -0
      matsen-tool/src/app/_components/list/list.component.ts
  6. +1
    -1
      matsen-tool/src/app/_components/search-select/search-select.component.html
  7. +17
    -1
      matsen-tool/src/app/_views/products/product-list/product-list.component.html
  8. +32
    -15
      matsen-tool/src/app/_views/products/product-list/product-list.component.ts
  9. +2
    -0
      matsen-tool/src/app/app.module.ts

+ 7
- 0
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
}

+ 59
- 0
matsen-tool/src/app/_components/list/list.component.html Просмотреть файл

@@ -0,0 +1,59 @@
<app-paging #pagingComponent
[getDataFunction]="getDataFunction"
[dataSource]="dataSource"
[searchable]="searchable"
[hidePageSize]="hidePageSize"
>
<div *ngIf="listColDefinitions" class="table-responsive">
<table mat-table [dataSource]="dataSource" matSort (matSortChange)="onSortChange($event)" class="mat-elevation-z8">

<!-- Iterate over listColDefinitions to define columns -->
<ng-container *ngFor="let column of listColDefinitions">
<ng-container [matColumnDef]="column.name">
<!-- Header Cell -->
<th mat-header-cell *matHeaderCellDef>
{{ column.text | translate }}
</th>
<!-- Conditional Cells -->
<td mat-cell *matCellDef="let element">
<ng-container [ngSwitch]="column.type">
<!-- Detail Column -->
<ng-container *ngSwitchCase="COLUMN_TYPE_DETAIL" >
<span class="btn btn-primary spt-icon-details"
data-type="user-tool" data-action="edit"
(click)="navigateToDetailsFunction(element, column)">
</span>
</ng-container>
<!-- Position Column -->
<ng-container *ngSwitchCase="COLUMN_TYPE_POSITION">
{{ pagingComponent.getPageSize() * (pagingComponent.getPageIndex() - 1) + dataSource.filteredData.indexOf(element) + 1 }}
</ng-container>
<!-- Image Column -->
<ng-container *ngSwitchCase="COLUMN_TYPE_IMAGE">
<img [src]="getElementImage(element, column)" width="40" height="40"/>
</ng-container>
<!-- Text Column -->
<ng-container *ngSwitchCase="COLUMN_TYPE_TEXT">
{{ getElementValue(element, column) }}
</ng-container>
<!-- Text Linked Column -->
<ng-container *ngSwitchCase="COLUMN_TYPE_TEXT_LINKED">
<span class="btn-link" (click)="navigateToDetailsFunction(element, column)">
{{ getElementValue(element, column) }}
</span>
</ng-container>
</ng-container>
</td>
</ng-container>
</ng-container>

<!-- Header and Row Definitions -->
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns; index as i;"
(click)="onRowSelected(row, i)"
[ngClass]="{'highlighted': selectedRowIndex === i}">
</tr>
</table>
</div>

</app-paging>

+ 0
- 0
matsen-tool/src/app/_components/list/list.component.scss Просмотреть файл


+ 23
- 0
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<ListComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ListComponent]
})
.compileComponents();
fixture = TestBed.createComponent(ListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 128
- 0
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<any>;

@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;
}
}

+ 1
- 1
matsen-tool/src/app/_components/search-select/search-select.component.html Просмотреть файл

@@ -10,7 +10,7 @@
[dataSource]="dataSource"
[searchable]="true"
[hidePageSize]="true"
>
>

<div *ngIf="searchSelectColDefs" class="table-responsive">
<table mat-table [dataSource]="dataSource" matSort (matSortChange)="onSortChange($event)" class="mat-elevation-z8">


+ 17
- 1
matsen-tool/src/app/_views/products/product-list/product-list.component.html Просмотреть файл

@@ -1,3 +1,19 @@
<div class="spt-container">
<div *ngIf="!this.user" class="top-btn">
<button *ngIf="bShowNewProductButton" class="btn btn-primary" (click)="openModalNewProduct()">+ {{ 'basic.new-product' | translate }}</button>
<button *ngIf="!bShowNewProductButton" class="btn btn-primary" (click)="openModalAssignProduct()">+ {{ 'basic.assign-product' | translate }}</button>
</div>
<app-list #listComponent
[dataSource]="getDataSource()"
[getDataFunction]="getData"
[navigateToDetailsFunction]="navigateToProductDetails"
[listColDefinitions]="listColDefinitions"
[searchable]="true"
[hidePageSize]="false"
></app-list>
</div>


<div class="spt-container">
<div *ngIf="!this.user" class="top-btn">
<button *ngIf="bShowNewProductButton" class="btn btn-primary" (click)="openModalNewProduct()">+ {{ 'basic.new-product' | translate }}</button>
@@ -71,4 +87,4 @@
</table>
</div>
</app-paging>
</div>
</div>

+ 32
- 15
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<any>;

@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<ContactPartnerProductJsonld>(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<ProductJsonld>(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<ProductJsonld>(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<PartnerProductJsonld>(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<ContactPartnerProductJsonld>(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'];


+ 2
- 0
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},


Загрузка…
Отмена
Сохранить