| @@ -12,6 +12,7 @@ | |||
| (page)="handlePageEvent($event)" | |||
| [pageSize]="pageSize" | |||
| [pageIndex]="pageIndex" | |||
| [hidePageSize]="hidePageSize" | |||
| showFirstLastButtons> | |||
| </mat-paginator> | |||
| </div> | |||
| @@ -24,6 +25,7 @@ | |||
| (page)="handlePageEvent($event)" | |||
| [pageSize]="pageSize" | |||
| [pageIndex]="pageIndex" | |||
| [hidePageSize]="hidePageSize" | |||
| showFirstLastButtons> | |||
| </mat-paginator> | |||
| </div> | |||
| @@ -17,6 +17,7 @@ export class PagingComponent implements OnInit, AfterViewInit { | |||
| @Input() public pageSize!: number; | |||
| @Input() public pageSizeOptions!: number[]; | |||
| @Input() public searchable: boolean; | |||
| @Input() public hidePageSize: boolean; | |||
| @ViewChild(MatPaginator) public paginator!: MatPaginator; | |||
| @@ -41,6 +42,7 @@ export class PagingComponent implements OnInit, AfterViewInit { | |||
| this.pageEvent = new PageEvent(); | |||
| this.pageIndex = 0; | |||
| this.searchable = false; | |||
| this.hidePageSize = false; | |||
| this.loadingSub = new Subscription(); | |||
| } | |||
| @@ -1,41 +1,51 @@ | |||
| <app-paging #pagingComponent | |||
| [getDataFunction]="getDataFunction" | |||
| [dataSource]="dataSource" | |||
| [searchable]="true" | |||
| > | |||
| <div class="search-select"> | |||
| <div class="show-name"> | |||
| <p #paragraphRef (click)="openSearchBox()"></p> | |||
| <span class="spt-clear" *ngIf="searchBoxFilled" (click)="clearSearch()"></span> | |||
| </div> | |||
| <!-- <p>NAME {{documentForm.get(formId)}}<span>X</span></p>--> | |||
| <div class="search-toggle" [class.search-box-open]="searchBoxOpen"> | |||
| <app-paging #pagingComponent | |||
| [getDataFunction]="getDataFunction" | |||
| [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"> | |||
| <div *ngIf="searchSelectColDefs" class="table-responsive"> | |||
| <table mat-table [dataSource]="dataSource" matSort (matSortChange)="onSortChange($event)" class="mat-elevation-z8"> | |||
| <ng-container *ngFor="let column of searchSelectColDefs" [matColumnDef]="column.column"> | |||
| <th mat-header-cell *matHeaderCellDef> | |||
| {{ column.columnHeader | translate }} | |||
| </th> | |||
| <ng-container *ngIf="column.columnType == COLUMN_TYPE_POSITION"> | |||
| <td mat-cell *matCellDef="let element"> | |||
| {{ pagingComponent.getPageSize() * (pagingComponent.getPageIndex()-1) + dataSource.filteredData.indexOf(element) + 1 }} | |||
| </td> | |||
| </ng-container> | |||
| <ng-container *ngIf="column.columnType == COLUMN_TYPE_IMAGE"> | |||
| <td mat-cell *matCellDef="let element"> | |||
| <img src="{{ getElementValue(element, column) }}" width="40" height="40"/> | |||
| </td> | |||
| </ng-container> | |||
| <ng-container *ngIf="column.columnType == COLUMN_TYPE_TEXT"> | |||
| <td mat-cell *matCellDef="let element"> | |||
| {{ getElementValue(element, column) }} | |||
| </td> | |||
| </ng-container> | |||
| <ng-container *ngFor="let column of searchSelectColDefs" [matColumnDef]="column.column"> | |||
| <th mat-header-cell *matHeaderCellDef> | |||
| {{ column.columnHeader | translate }} | |||
| </th> | |||
| <ng-container *ngIf="column.columnType == COLUMN_TYPE_POSITION"> | |||
| <td mat-cell *matCellDef="let element"> | |||
| {{ pagingComponent.getPageSize() * (pagingComponent.getPageIndex()-1) + dataSource.filteredData.indexOf(element) + 1 }} | |||
| </td> | |||
| </ng-container> | |||
| <ng-container *ngIf="column.columnType == COLUMN_TYPE_IMAGE"> | |||
| <td mat-cell *matCellDef="let element"> | |||
| <img src="{{ getElementValue(element, column) }}" width="40" height="40"/> | |||
| </td> | |||
| </ng-container> | |||
| <ng-container *ngIf="column.columnType == COLUMN_TYPE_TEXT"> | |||
| <td mat-cell *matCellDef="let element"> | |||
| {{ getElementValue(element, column) }} | |||
| </td> | |||
| </ng-container> | |||
| </ng-container> | |||
| </ng-container> | |||
| <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> | |||
| <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> | |||
| </table> | |||
| </div> | |||
| </app-paging> | |||
| </div> | |||
| </app-paging> | |||
| </div> | |||
| @@ -1,4 +1,4 @@ | |||
| import {AfterViewInit, Component, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core'; | |||
| import {AfterViewInit, Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core'; | |||
| import {PagingComponent} from "@app/_components/paging/paging.component"; | |||
| import {FormGroup} from "@angular/forms"; | |||
| import {SearchInputColDef} from "@app/_components/search-input/search-input-col-def"; | |||
| @@ -12,15 +12,6 @@ import {OrderFilter} from "@app/_models/orderFilter"; | |||
| }) | |||
| export class SearchSelectComponent implements OnInit, AfterViewInit { | |||
| static COLUMN_TYPE_POSITION: string = 'position'; | |||
| static COLUMN_TYPE_TEXT: string = 'text'; | |||
| static COLUMN_TYPE_IMAGE: string = 'image'; | |||
| static validColumnTypes: string[] = [ | |||
| SearchSelectComponent.COLUMN_TYPE_POSITION, | |||
| SearchSelectComponent.COLUMN_TYPE_TEXT, | |||
| SearchSelectComponent.COLUMN_TYPE_IMAGE | |||
| ]; | |||
| @Input() public formId!: string; | |||
| @Input() public formLabelLangKey!: string; | |||
| @Input() public documentForm!: FormGroup; | |||
| @@ -28,15 +19,33 @@ export class SearchSelectComponent implements OnInit, AfterViewInit { | |||
| @Input() public getDataFunction!: Function; | |||
| @Input() public dataSource: any; | |||
| @Input() public searchSelectColDefs!: SearchInputColDef[]; | |||
| @Output() rowSelected = new EventEmitter<any>(); | |||
| @ViewChild('paragraphRef', { static: false }) paragraphRef!: ElementRef; | |||
| @ViewChild("pagingComponent", { static: false }) pagingComponent!: PagingComponent | |||
| @ViewChild(MatSort) sort; | |||
| static COLUMN_TYPE_POSITION: string = 'position'; | |||
| static COLUMN_TYPE_TEXT: string = 'text'; | |||
| static COLUMN_TYPE_IMAGE: string = 'image'; | |||
| static validColumnTypes: string[] = [ | |||
| SearchSelectComponent.COLUMN_TYPE_POSITION, | |||
| SearchSelectComponent.COLUMN_TYPE_TEXT, | |||
| SearchSelectComponent.COLUMN_TYPE_IMAGE | |||
| ]; | |||
| protected displayedColumns!: string[]; | |||
| protected selectedRowIndex: number | null = null; | |||
| protected searchBoxOpen: boolean; | |||
| protected searchBoxInitialized: boolean; | |||
| protected searchBoxFilled: boolean; | |||
| constructor() { | |||
| this.sort = new MatSort(); | |||
| this.searchBoxOpen = false; | |||
| this.searchBoxInitialized = false; | |||
| this.searchBoxFilled = false; | |||
| } | |||
| ngOnInit(): void { | |||
| @@ -47,11 +56,11 @@ export class SearchSelectComponent implements OnInit, AfterViewInit { | |||
| } | |||
| ngAfterViewInit(): void { | |||
| // this.searchBoxOpen = false; | |||
| } | |||
| getData(): void { | |||
| this.pagingComponent.getData(); | |||
| } | |||
| setData(dataSource: any, data: any[], dataLength: number): void { | |||
| @@ -81,6 +90,9 @@ export class SearchSelectComponent implements OnInit, AfterViewInit { | |||
| console.log(row, index); | |||
| this.selectedRowIndex = index; | |||
| this.documentForm.get(this.formId)?.setValue(row.id); | |||
| this.paragraphRef.nativeElement.textContent = row.fullName; | |||
| this.searchBoxFilled = true; | |||
| this.searchBoxOpen = false; | |||
| } | |||
| get COLUMN_TYPE_POSITION(): string { | |||
| @@ -120,4 +132,21 @@ export class SearchSelectComponent implements OnInit, AfterViewInit { | |||
| res.subResource = subResource | |||
| return res; | |||
| } | |||
| openSearchBox() { | |||
| // if (this.paragraphRef.nativeElement.textContent !== '') { | |||
| this.searchBoxOpen = !this.searchBoxOpen; | |||
| if (this.searchBoxOpen && !this.searchBoxInitialized) { | |||
| this.pagingComponent.getData(); | |||
| this.searchBoxInitialized = true; | |||
| } | |||
| // } | |||
| } | |||
| clearSearch() { | |||
| this.paragraphRef.nativeElement.textContent = ''; | |||
| this.searchBoxFilled = false; | |||
| this.documentForm.get(this.formId)?.setValue(undefined); | |||
| // this.searchBoxOpen = true; | |||
| } | |||
| } | |||
| @@ -33,7 +33,7 @@ | |||
| <th mat-header-cell *matHeaderCellDef> | |||
| {{ 'overview.logo' | translate }} | |||
| </th> | |||
| <td mat-cell *matCellDef="let element"> | |||
| <td mat-cell *matCellDef="let element" class="btn-link" (click)="navigateToPartnerDetails(element)"> | |||
| <img *ngIf="element.logoUrl !== null && element.logoUrl !== undefined" | |||
| src="{{ element.logoUrl }}" alt="" width="40" height="40" /> | |||
| <img *ngIf="element.logoUrl === null || element.logoUrl === undefined" | |||
| @@ -47,7 +47,7 @@ | |||
| {{ partnerColumnHeadline }} | |||
| </th> | |||
| <td mat-cell *matCellDef="let element"> | |||
| {{ element.name }} | |||
| <span class="btn-link" (click)="navigateToPartnerDetails(element)">{{ element.name }}</span> | |||
| </td> | |||
| </ng-container> | |||
| @@ -35,7 +35,7 @@ | |||
| <th mat-header-cell *matHeaderCellDef> | |||
| {{ 'overview.image' | translate }} | |||
| </th> | |||
| <td mat-cell *matCellDef="let element"> | |||
| <td mat-cell *matCellDef="let element" class="btn-link" (click)="navigateToProductDetails(element)"> | |||
| <img *ngIf="element.imageUrl !== null && element.imageUrl !== undefined" | |||
| src="{{element.imageUrl}}" width="40" height="40"/> | |||
| <img *ngIf="element.imageUrl === null || element.imageUrl === undefined" | |||
| @@ -49,7 +49,7 @@ | |||
| {{ 'overview.productname' | translate }} | |||
| </th> | |||
| <td mat-cell *matCellDef="let element"> | |||
| {{ element.name }} | |||
| <span class="btn-link" (click)="navigateToProductDetails(element)">{{ element.name }}</span> | |||
| </td> | |||
| </ng-container> | |||
| @@ -11,6 +11,7 @@ | |||
| </div> | |||
| <div class="mb-3"> | |||
| <label for="d" class="form-label">{{ 'form.contact' | translate }}:</label> | |||
| <app-search-select #contactSearchSelect | |||
| [formId]="'contactIri'" | |||
| [formLabelLangKey]="'form.product'" | |||
| @@ -19,8 +20,8 @@ | |||
| [dataSource]="dataSourceContacts" | |||
| [searchSelectColDefs]="colDefContacts" | |||
| > | |||
| <input type="hidden" formControlName="contactIri" value="{{taskNote.contactIri}}"/> | |||
| </app-search-select> | |||
| <input type="hidden" formControlName="contactIri" value="{{taskNote.contactIri}}"/> | |||
| </div> | |||
| <p class="form-label">{{ 'form.contact-type' | translate }}:</p> | |||
| @@ -61,7 +61,7 @@ export class NewTaskNoteComponent implements OnInit, AfterViewInit { | |||
| } | |||
| ngAfterViewInit(): void { | |||
| this.contactSearchSelect.getData(); | |||
| } | |||
| getContacts = (term?: string): void => { | |||
| @@ -104,7 +104,11 @@ | |||
| <div class="card spt-comments" *ngFor="let taskNote of taskNotes.get(task.id)"> | |||
| <div class="card-body"> | |||
| <div class="d-flex justify-content-between align-items-center"> | |||
| <p>{{ taskNote.owner?.firstName }} {{ taskNote.owner?.lastName }} - {{ getTranslationKey(taskNote.contactType) | translate }}</p> | |||
| <p>{{ taskNote.owner?.firstName }} {{ taskNote.owner?.lastName }} - {{ getTranslationKey(taskNote.contactType) | translate }} | |||
| <ng-container *ngIf="taskNote.contact"> | |||
| mit {{ taskNote.contact?.firstName }} {{ taskNote.contact?.lastName }} | |||
| </ng-container> | |||
| </p> | |||
| <p>{{ taskNote.createdAt | date:'dd.MM.YYYY - HH:mm':'GMT+0000' }} Uhr</p> | |||
| </div> | |||
| <div> | |||
| @@ -340,3 +340,55 @@ img { | |||
| box-shadow: 4px -100px rgba(255, 255, 255, 0), 8px -90px rgba(255, 255, 255, 0), 10px -120px rgba(255, 255, 255, 0), 15px -45px rgba(255, 255, 255, 0); | |||
| } | |||
| } | |||
| .search-select { | |||
| table { | |||
| thead { | |||
| display: none; | |||
| } | |||
| img { | |||
| width: 30px; | |||
| } | |||
| } | |||
| .mat-mdc-paginator-range-actions { | |||
| justify-content: flex-end; | |||
| flex-wrap: wrap; | |||
| margin-right: -15px; | |||
| } | |||
| .mat-mdc-paginator-range-label { | |||
| text-align: right; | |||
| flex-basis: 100%; | |||
| flex-grow: 0; | |||
| margin: 0 7px 0 0; | |||
| } | |||
| .mat-mdc-icon-button.mat-mdc-button-base { | |||
| width: 30px; | |||
| height: 30px; | |||
| padding: 0px; | |||
| } | |||
| .mat-mdc-table .mdc-data-table__cell, | |||
| .mat-mdc-table .mdc-data-table__header-cell { | |||
| padding-top: 4px; | |||
| padding-bottom: 4px; | |||
| } | |||
| .spt-tools.single { | |||
| display: none; | |||
| } | |||
| .show-name { | |||
| position: relative; | |||
| p { | |||
| border: 1px solid #dee2e6; | |||
| padding: 6px 12px; | |||
| font-size: 16px; | |||
| line-height: 24px; | |||
| min-height: 38px; | |||
| cursor: text; | |||
| } | |||
| } | |||
| .search-toggle { | |||
| display: none; | |||
| } | |||
| .search-box-open { | |||
| display: block; | |||
| } | |||
| } | |||
| @@ -95,6 +95,7 @@ dl, | |||
| } | |||
| .btn-link { | |||
| color: $color-matsen; | |||
| cursor: pointer; | |||
| @include transition(); | |||
| &:hover { | |||
| color: $color-matsen-dark; | |||