develop #5
|
@ -9,7 +9,7 @@
|
|||
<p *ngIf="hasEditPermission">Vous pouvez en créer une <b><a routerLink="/catalog/company/add">ici</a></b>.</p>
|
||||
</cre-warning-alert>
|
||||
|
||||
<cre-table *ngIf="!companiesEmpty" class="mx-auto" [dataSource]="companies$ | async" [columns]="columns">
|
||||
<cre-table *ngIf="!companiesEmpty" class="mx-auto" [data]="companies$ | async" [columns]="columns">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>Nom</th>
|
||||
<td mat-cell *matCellDef="let company">{{company.name}}</td>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<cre-table
|
||||
*ngIf="!materialTypesEmpty"
|
||||
class="mx-auto"
|
||||
[dataSource]="materialTypes$ | async"
|
||||
[data]="materialTypes$ | async"
|
||||
[columns]="columns">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>Nom</th>
|
||||
|
|
|
@ -36,7 +36,12 @@
|
|||
<ng-template
|
||||
#recipeTableTemplate
|
||||
let-recipes="recipes">
|
||||
<table class="mx-auto" mat-table [dataSource]="recipes">
|
||||
<cre-table
|
||||
class="w-100"
|
||||
[columns]="columns"
|
||||
[data]="recipes"
|
||||
[filter]="searchQuery"
|
||||
[filterFn]="recipeFilterPredicate">
|
||||
<!-- Recipe's info -->
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>Nom</th>
|
||||
|
@ -84,19 +89,16 @@
|
|||
<!-- Buttons -->
|
||||
<ng-container matColumnDef="buttonView">
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let recipe">
|
||||
<button mat-flat-button color="accent" routerLink="/color/explore/{{recipe.id}}">Voir</button>
|
||||
<td mat-cell *matCellDef="let recipe; let i = index">
|
||||
<cre-accent-button [creInteractiveCell]="i" routerLink="/color/explore/{{recipe.id}}">Voir</cre-accent-button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="buttonEdit">
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let recipe" [class.disabled]="!hasEditPermission">
|
||||
<button mat-flat-button color="accent" routerLink="/color/edit/{{recipe.id}}">Modifier</button>
|
||||
<td mat-cell *matCellDef="let recipe; let i = index" [class.disabled]="!hasEditPermission">
|
||||
<cre-accent-button [creInteractiveCell]="i" routerLink="/color/edit/{{recipe.id}}">Modifier</cre-accent-button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="tableCols"></tr>
|
||||
<tr mat-row *matRowDef="let recipe; columns: tableCols" [hidden]="hiddenRecipes[recipe.id]"></tr>
|
||||
</table>
|
||||
</cre-table>
|
||||
</ng-template>
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import {ChangeDetectorRef, Component} from '@angular/core';
|
||||
import {ErrorHandlingComponent} from '../shared/components/subscribing.component';
|
||||
import {Company} from '../shared/model/company.model';
|
||||
import {getRecipeLuma, Recipe} from '../shared/model/recipe.model';
|
||||
import {CompanyService} from '../company/service/company.service';
|
||||
import {RecipeService} from './services/recipe.service';
|
||||
import {AccountService} from '../accounts/services/account.service';
|
||||
import {ConfigService} from '../shared/service/config.service';
|
||||
import {AppState} from '../shared/app-state';
|
||||
import {ErrorService} from '../shared/service/error.service';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {Config} from '../shared/model/config.model';
|
||||
import {Permission} from '../shared/model/user';
|
||||
import {FormControl} from '@angular/forms';
|
||||
import {ChangeDetectorRef, Component} from '@angular/core'
|
||||
import {ErrorHandlingComponent} from '../shared/components/subscribing.component'
|
||||
import {Company} from '../shared/model/company.model'
|
||||
import {getRecipeLuma, Recipe, recipeMatchesFilter} from '../shared/model/recipe.model'
|
||||
import {CompanyService} from '../company/service/company.service'
|
||||
import {RecipeService} from './services/recipe.service'
|
||||
import {AccountService} from '../accounts/services/account.service'
|
||||
import {ConfigService} from '../shared/service/config.service'
|
||||
import {AppState} from '../shared/app-state'
|
||||
import {ErrorService} from '../shared/service/error.service'
|
||||
import {ActivatedRoute, Router} from '@angular/router'
|
||||
import {Config} from '../shared/model/config.model'
|
||||
import {Permission} from '../shared/model/user'
|
||||
import {FormControl} from '@angular/forms'
|
||||
|
||||
@Component({
|
||||
selector: 'cre-recipe-list',
|
||||
|
@ -21,12 +21,13 @@ import {FormControl} from '@angular/forms';
|
|||
export class RecipeList extends ErrorHandlingComponent {
|
||||
companies: Company[] = []
|
||||
recipes: Map<number, Recipe[]> = new Map<number, Recipe[]>()
|
||||
tableCols = ['name', 'description', 'color', 'sample', 'iconNotApproved', 'buttonView', 'buttonEdit']
|
||||
searchQuery = ''
|
||||
columns = ['name', 'description', 'color', 'sample', 'iconNotApproved', 'buttonView', 'buttonEdit']
|
||||
panelForcedExpanded = false
|
||||
hiddenRecipes = []
|
||||
|
||||
searchControl: FormControl
|
||||
searchQuery = ''
|
||||
|
||||
recipeFilterPredicate = recipeMatchesFilter
|
||||
|
||||
constructor(
|
||||
private companyService: CompanyService,
|
||||
|
@ -62,7 +63,13 @@ export class RecipeList extends ErrorHandlingComponent {
|
|||
this.searchControl = new FormControl('')
|
||||
this.subscribe(
|
||||
this.searchControl.valueChanges,
|
||||
value => this.searchRecipes(value)
|
||||
value => {
|
||||
this.searchQuery = value
|
||||
if (value.length > 0 && !this.panelForcedExpanded) {
|
||||
this.panelForcedExpanded = true
|
||||
this.cdRef.detectChanges()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -81,25 +88,14 @@ export class RecipeList extends ErrorHandlingComponent {
|
|||
)
|
||||
}
|
||||
|
||||
searchRecipes(searchQuery) {
|
||||
this.searchQuery = searchQuery
|
||||
if (this.searchQuery.length > 0 && !this.panelForcedExpanded) {
|
||||
this.panelForcedExpanded = true
|
||||
this.cdRef.detectChanges()
|
||||
}
|
||||
|
||||
for (let recipeArray of this.recipes.values()) {
|
||||
recipeArray.forEach(recipe => this.recipeMatchesSearchQuery(recipe))
|
||||
}
|
||||
}
|
||||
|
||||
isCompanyHidden(company: Company): boolean {
|
||||
const companyRecipes = this.recipes.get(company.id);
|
||||
const companyRecipes = this.recipes.get(company.id)
|
||||
return !(companyRecipes && companyRecipes.length >= 0) ||
|
||||
this.searchQuery && this.searchQuery.length > 0 &&
|
||||
companyRecipes.map(r => this.hiddenRecipes[r.id]).filter(r => !r).length <= 0
|
||||
!companyRecipes.some(recipe => this.recipeFilterPredicate(recipe, this.searchQuery))
|
||||
}
|
||||
|
||||
|
||||
isLight(recipe: Recipe): boolean {
|
||||
return getRecipeLuma(recipe) > 200
|
||||
}
|
||||
|
@ -111,16 +107,4 @@ export class RecipeList extends ErrorHandlingComponent {
|
|||
get hasCompanyEditPermission(): boolean {
|
||||
return this.accountService.hasPermission(Permission.EDIT_COMPANIES)
|
||||
}
|
||||
|
||||
private recipeMatchesSearchQuery(recipe: Recipe) {
|
||||
const matches = this.searchString(recipe.company.name) ||
|
||||
this.searchString(recipe.name) ||
|
||||
this.searchString(recipe.description) ||
|
||||
(recipe.sample && this.searchString(recipe.sample.toString()))
|
||||
this.hiddenRecipes[recipe.id] = !matches
|
||||
}
|
||||
|
||||
private searchString(value: string): boolean {
|
||||
return value.toLowerCase().indexOf(this.searchQuery.toLowerCase()) >= 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</p>
|
||||
</cre-warning-alert>
|
||||
|
||||
<cre-table [hidden]="materialCount <= 0" class="mx-auto" [dataSource]="mixMaterials" [columns]="columns">
|
||||
<cre-table [hidden]="materialCount <= 0" class="mx-auto" [data]="mixMaterials" [columns]="columns">
|
||||
<ng-container matColumnDef="position">
|
||||
<th mat-header-cell *matHeaderCellDef>Position</th>
|
||||
<td mat-cell *matCellDef="let mixMaterial">{{mixMaterial.position}}</td>
|
||||
|
|
|
@ -16,3 +16,15 @@ mat-expansion-panel
|
|||
|
||||
.recipe-content > div
|
||||
margin: 0 3rem 3rem
|
||||
|
||||
cre-table
|
||||
.mat-column-name,
|
||||
.mat-column-color,
|
||||
.mat-column-iconNotApproved
|
||||
width: 5em
|
||||
|
||||
.mat-column-description
|
||||
width: 50em
|
||||
|
||||
.mat-column-sample
|
||||
width: 10em
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<table mat-table [dataSource]="dataSource">
|
||||
<table
|
||||
mat-table
|
||||
[dataSource]="dataSource">
|
||||
<ng-content></ng-content>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="columns"></tr>
|
||||
|
|
|
@ -4,6 +4,7 @@ import {CommonModule} from '@angular/common'
|
|||
import {CreInteractiveCell, CrePositionButtons, CreTable} from './tables'
|
||||
import {MatButtonModule} from "@angular/material/button";
|
||||
import {MatIconModule} from "@angular/material/icon";
|
||||
import {MatSortModule} from '@angular/material/sort'
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -11,12 +12,13 @@ import {MatIconModule} from "@angular/material/icon";
|
|||
CreInteractiveCell,
|
||||
CrePositionButtons
|
||||
],
|
||||
imports: [
|
||||
MatTableModule,
|
||||
CommonModule,
|
||||
MatButtonModule,
|
||||
MatIconModule
|
||||
],
|
||||
imports: [
|
||||
MatTableModule,
|
||||
CommonModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatSortModule
|
||||
],
|
||||
exports: [
|
||||
CreTable,
|
||||
CreInteractiveCell,
|
||||
|
|
|
@ -2,14 +2,16 @@ import {
|
|||
AfterContentInit,
|
||||
Component,
|
||||
ContentChildren,
|
||||
Directive, EventEmitter,
|
||||
Directive,
|
||||
EventEmitter,
|
||||
HostBinding,
|
||||
Input, Output,
|
||||
Input,
|
||||
Output,
|
||||
QueryList,
|
||||
ViewChild,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core'
|
||||
import {MatColumnDef, MatHeaderRowDef, MatRowDef, MatTable} from '@angular/material/table'
|
||||
import {MatColumnDef, MatHeaderRowDef, MatRowDef, MatTable, MatTableDataSource} from '@angular/material/table'
|
||||
|
||||
@Directive({
|
||||
selector: '[creInteractiveCell]'
|
||||
|
@ -57,17 +59,32 @@ export class CreTable<T> implements AfterContentInit {
|
|||
@ViewChild(MatTable, {static: true}) table: MatTable<T>
|
||||
|
||||
@Input() columns: string[]
|
||||
@Input() dataSource: T[]
|
||||
@Input() interactive = true
|
||||
@Input() filterFn: (t: T, string: string) => boolean = () => true
|
||||
|
||||
@Input() set filter(filter: string) {
|
||||
this.dataSource.filter = filter
|
||||
}
|
||||
|
||||
@Input() set data(data: T[]) {
|
||||
this.setupDataSource(data)
|
||||
}
|
||||
|
||||
selectedIndex = 0
|
||||
|
||||
dataSource: MatTableDataSource<T>
|
||||
|
||||
ngAfterContentInit(): void {
|
||||
this.columnDefs.forEach(columnDef => this.table.addColumnDef(columnDef))
|
||||
this.rowDefs.forEach(rowDef => this.table.addRowDef(rowDef))
|
||||
this.headerRowDefs.forEach(headerRowDef => this.table.addHeaderRowDef(headerRowDef))
|
||||
}
|
||||
|
||||
private setupDataSource(data: T[]) {
|
||||
this.dataSource = new MatTableDataSource<T>(data)
|
||||
this.dataSource.filterPredicate = (t, filter) => this.filterFn(t, filter)
|
||||
}
|
||||
|
||||
onRowHover(index: number) {
|
||||
if (this.interactive) {
|
||||
this.interactiveCells.forEach(cell => cell.hoverIndex = index)
|
||||
|
@ -98,15 +115,15 @@ export class CrePositionButtons {
|
|||
@Input() disableDecreaseButton = false
|
||||
@Input() disableIncreaseButton = false
|
||||
|
||||
@Output() positionChange = new EventEmitter<number>();
|
||||
@Output() positionChange = new EventEmitter<number>()
|
||||
|
||||
increasePosition() {
|
||||
this.position += 1;
|
||||
this.position += 1
|
||||
this.positionChange.emit(this.position)
|
||||
}
|
||||
|
||||
decreasePosition() {
|
||||
this.position -= 1;
|
||||
this.position -= 1
|
||||
this.positionChange.emit(this.position)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,3 +124,8 @@ export function getRecipeLuma(recipe: Recipe): number {
|
|||
|
||||
return 0.2126 * r + 0.7152 * g + 0.0722 * b // per ITU-R BT.709
|
||||
}
|
||||
|
||||
export function recipeMatchesFilter(recipe: Recipe, filter: string): boolean {
|
||||
const recipeStr = recipe.company.name + recipe.name + recipe.description + recipe.sample
|
||||
return recipeStr.toLowerCase().indexOf(filter.toLowerCase()) >= 0
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</cre-action-group>
|
||||
</cre-action-bar>
|
||||
|
||||
<cre-table class="mx-auto" [dataSource]="touchUpKit.content" [columns]="contentTableCols" [interactive]="false">
|
||||
<cre-table class="mx-auto" [data]="touchUpKit.content" [columns]="contentTableCols" [interactive]="false">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>Nom</th>
|
||||
<td mat-cell *matCellDef="let product">{{product.name}}</td>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</cre-action-group>
|
||||
</cre-action-bar>
|
||||
|
||||
<cre-table class="mx-auto" [dataSource]="uncompletedTouchUpKits$ | async" [columns]="columns">
|
||||
<cre-table class="mx-auto" [data]="uncompletedTouchUpKits$ | async" [columns]="columns">
|
||||
<ng-container matColumnDef="project">
|
||||
<th mat-header-cell *matHeaderCellDef>Project</th>
|
||||
<td mat-cell *matCellDef="let touchUpKit">{{touchUpKit.project}}</td>
|
||||
|
@ -57,7 +57,7 @@
|
|||
<mat-card-title>Kits de retouche complétés</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<cre-table [dataSource]="completedTouchUpKits$ | async" [columns]="completedColumns">
|
||||
<cre-table [data]="completedTouchUpKits$ | async" [columns]="completedColumns">
|
||||
<ng-container matColumnDef="project">
|
||||
<th mat-header-cell *matHeaderCellDef>Project</th>
|
||||
<td mat-cell *matCellDef="let touchUpKit">{{touchUpKit.project}}</td>
|
||||
|
|
Loading…
Reference in New Issue