Merge branch 'bug-solving' into 'master'
Corrections de la recherche dans la liste des recettes Closes #17 See merge request color-recipes-explorer/frontend!13
This commit is contained in:
commit
88184c884e
|
@ -3,7 +3,7 @@
|
|||
<h3>{{recipe.company.name}} - {{recipe.name}}</h3>
|
||||
<div
|
||||
class="recipe-color-circle"
|
||||
[class.dark-mode]="darkColor"
|
||||
[class.dark-mode]="isDarkColor"
|
||||
[style.backgroundColor]="recipe.color">
|
||||
<div>{{recipe.gloss}}%</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {AfterViewInit, Component, Input} from '@angular/core'
|
||||
import {Recipe} from '../../../shared/model/recipe.model'
|
||||
import {getRecipeLuma, Recipe} from '../../../shared/model/recipe.model'
|
||||
|
||||
@Component({
|
||||
selector: 'cre-recipe-info',
|
||||
|
@ -17,15 +17,7 @@ export class RecipeInfoComponent implements AfterViewInit {
|
|||
this.isBPacExtensionInstalled = document.querySelectorAll('.bpac-extension-installed').length > 0
|
||||
}
|
||||
|
||||
get darkColor(): boolean {
|
||||
// https://stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black
|
||||
const c = this.recipe.color.substring(1) // strip #
|
||||
const rgb = parseInt(c, 16) // convert rrggbb to decimal
|
||||
const r = (rgb >> 16) & 0xff // extract red
|
||||
const g = (rgb >> 8) & 0xff // extract green
|
||||
const b = (rgb >> 0) & 0xff // extract blue
|
||||
|
||||
const luma = 0.2126 * r + 0.7152 * g + 0.0722 * b // per ITU-R BT.709
|
||||
return luma < 100
|
||||
get isDarkColor(): boolean {
|
||||
return getRecipeLuma(this.recipe) < 100
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ export class AddComponent extends ErrorHandlingComponent {
|
|||
type: 'slider',
|
||||
min: 0,
|
||||
max: 100,
|
||||
defaultValue: 10,
|
||||
defaultValue: 0,
|
||||
required: true,
|
||||
errorMessages: [
|
||||
{conditionFn: errors => errors.required, message: 'Le lustre de la couleur est requis'}
|
||||
|
|
|
@ -3,10 +3,20 @@
|
|||
<div class="d-flex flex-column">
|
||||
<div class="mt-1 pb-2">
|
||||
<button mat-raised-button color="primary" routerLink="/color/list">Retour</button>
|
||||
<button mat-raised-button color="accent" (click)="submit(editComponent, stepTable)"
|
||||
[disabled]="editComponent.form && editComponent.form.invalid">Enregistrer
|
||||
<button
|
||||
mat-raised-button
|
||||
color="accent"
|
||||
[disabled]="editComponent.form && editComponent.form.invalid"
|
||||
(click)="submit(editComponent, stepTable)">
|
||||
Enregistrer
|
||||
</button>
|
||||
<button
|
||||
*ngIf="hasDeletePermission"
|
||||
mat-raised-button
|
||||
color="warn"
|
||||
(click)="confirmBoxComponent.show()">
|
||||
Supprimer
|
||||
</button>
|
||||
<button mat-raised-button color="warn" *ngIf="hasDeletePermission" (click)="confirmBoxComponent.show()">Supprimer</button>
|
||||
</div>
|
||||
<mat-form-field>
|
||||
<mat-label>Unités</mat-label>
|
||||
|
@ -52,4 +62,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<cre-confirm-box #confirmBoxComponent message="Voulez-vous vraiment supprimer la couleur {{recipe.name}}?" (confirm)="delete()"></cre-confirm-box>
|
||||
<cre-confirm-box
|
||||
#confirmBoxComponent
|
||||
message="Voulez-vous vraiment supprimer la couleur {{recipe?.name}}?"
|
||||
(confirm)="delete()">
|
||||
</cre-confirm-box>
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
<div class="action-bar">
|
||||
<mat-form-field>
|
||||
<mat-label>Recherche</mat-label>
|
||||
<input matInput type="text" [(ngModel)]="searchQuery"/>
|
||||
<button mat-button *ngIf="searchQuery" matSuffix mat-icon-button (click)="searchQuery=''">
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
[(ngModel)]="searchQuery"
|
||||
(keyup)="searchRecipes()"/>
|
||||
<button
|
||||
mat-button
|
||||
*ngIf="searchQuery"
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
(click)="searchQuery=''">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
|
@ -11,8 +20,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<mat-expansion-panel class="table-title" *ngFor="let companyRecipes of (recipes$ | async)"
|
||||
[hidden]="isCompanyHidden(companyRecipes.recipes)" [expanded]="panelForcedExpanded">
|
||||
<mat-expansion-panel
|
||||
class="table-title"
|
||||
*ngFor="let companyRecipes of recipes"
|
||||
[hidden]="isCompanyHidden(companyRecipes.recipes)"
|
||||
[expanded]="panelForcedExpanded">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
{{companyRecipes.company}}
|
||||
|
@ -40,7 +52,8 @@
|
|||
<ng-container matColumnDef="color">
|
||||
<th mat-header-cell *matHeaderCellDef>Couleur</th>
|
||||
<td mat-cell *matCellDef="let recipe">
|
||||
<div class="recipe-color-circle" [class.light-mode]="isLightColor(recipe)" [style.backgroundColor]="recipe.color"></div>
|
||||
<div class="recipe-color-circle" [class.light-mode]="isLight(recipe)"
|
||||
[style.backgroundColor]="recipe.color"></div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
@ -80,6 +93,6 @@
|
|||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="tableCols"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: tableCols" [hidden]="!searchRecipe(row)"></tr>
|
||||
<tr mat-row *matRowDef="let recipe; columns: tableCols" [hidden]="hiddenRecipes[recipe.id]"></tr>
|
||||
</table>
|
||||
</ng-template>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {Component} from '@angular/core'
|
||||
import {ChangeDetectorRef, Component} from '@angular/core'
|
||||
import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component'
|
||||
import {RecipeService} from '../../services/recipe.service'
|
||||
import {EmployeePermission} from '../../../shared/model/employee'
|
||||
import {AccountService} from '../../../accounts/services/account.service'
|
||||
import {Recipe} from '../../../shared/model/recipe.model'
|
||||
import {getRecipeLuma, Recipe} from '../../../shared/model/recipe.model'
|
||||
import {ActivatedRoute, Router} from '@angular/router'
|
||||
import {ErrorModel, ErrorService} from '../../../shared/service/error.service'
|
||||
|
||||
|
@ -13,17 +13,18 @@ import {ErrorModel, ErrorService} from '../../../shared/service/error.service'
|
|||
styleUrls: ['./list.component.sass']
|
||||
})
|
||||
export class ListComponent extends ErrorHandlingComponent {
|
||||
recipes$ = this.recipeService.allSortedByCompany
|
||||
recipes: { company: string, recipes: Recipe[] }[] = []
|
||||
tableCols = ['name', 'description', 'color', 'gloss', 'sample', 'iconNotApproved', 'buttonView', 'buttonEdit']
|
||||
searchQuery = ""
|
||||
searchQuery = ''
|
||||
panelForcedExpanded = false
|
||||
recipesHidden = []
|
||||
hiddenRecipes = []
|
||||
|
||||
handledErrorModels: ErrorModel[]
|
||||
|
||||
constructor(
|
||||
private recipeService: RecipeService,
|
||||
private accountService: AccountService,
|
||||
private cdRef: ChangeDetectorRef,
|
||||
errorService: ErrorService,
|
||||
router: Router,
|
||||
activatedRoute: ActivatedRoute
|
||||
|
@ -32,40 +33,44 @@ export class ListComponent extends ErrorHandlingComponent {
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
super.ngOnInit()
|
||||
|
||||
this.subscribe(
|
||||
this.recipeService.allSortedByCompany,
|
||||
recipes => this.recipes = recipes
|
||||
)
|
||||
}
|
||||
|
||||
searchRecipe(recipe: Recipe) {
|
||||
if (this.searchQuery.length > 0) {
|
||||
searchRecipes() {
|
||||
if (this.searchQuery.length > 0 && !this.panelForcedExpanded) {
|
||||
this.panelForcedExpanded = true
|
||||
this.cdRef.detectChanges()
|
||||
}
|
||||
const positive = this.searchString(recipe.name) ||
|
||||
this.searchString(recipe.description) ||
|
||||
this.searchString(recipe.sample.toString())
|
||||
this.recipesHidden[recipe.id] = !positive
|
||||
return positive
|
||||
|
||||
this.recipes
|
||||
.flatMap(r => r.recipes)
|
||||
.forEach(r => this.recipeMatchesSearchQuery(r))
|
||||
}
|
||||
|
||||
isCompanyHidden(companyRecipes: Recipe[]): boolean {
|
||||
return (this.searchQuery && this.searchQuery.length > 0) && companyRecipes.map(r => this.recipesHidden[r.id]).filter(r => !r).length <= 0
|
||||
return (this.searchQuery && this.searchQuery.length > 0) && companyRecipes.map(r => this.hiddenRecipes[r.id]).filter(r => !r).length <= 0
|
||||
}
|
||||
|
||||
isLightColor(recipe: Recipe): boolean {
|
||||
// https://stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black
|
||||
const c = recipe.color.substring(1) // strip #
|
||||
const rgb = parseInt(c, 16) // convert rrggbb to decimal
|
||||
const r = (rgb >> 16) & 0xff // extract red
|
||||
const g = (rgb >> 8) & 0xff // extract green
|
||||
const b = (rgb >> 0) & 0xff // extract blue
|
||||
|
||||
const luma = 0.2126 * r + 0.7152 * g + 0.0722 * b // per ITU-R BT.709
|
||||
return luma > 200
|
||||
isLight(recipe: Recipe): boolean {
|
||||
return getRecipeLuma(recipe) > 200
|
||||
}
|
||||
|
||||
get hasEditPermission(): boolean {
|
||||
return this.accountService.hasPermission(EmployeePermission.EDIT_RECIPE)
|
||||
}
|
||||
|
||||
private recipeMatchesSearchQuery(recipe: Recipe) {
|
||||
const matches = 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
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Component, EventEmitter, Input, Output} from '@angular/core'
|
||||
import {ChangeDetectorRef, Component, EventEmitter, Input, Output} from '@angular/core'
|
||||
import {FormBuilder, FormControl, FormGroup} from '@angular/forms'
|
||||
import {FormField} from '../entity-add/entity-add.component'
|
||||
import {EmployeePermission} from '../../model/employee'
|
||||
|
|
|
@ -113,3 +113,14 @@ export function sortMixMaterialsDto(mixMaterials: MixMaterialDto[]): MixMaterial
|
|||
return mixMaterials.sort((a, b) => a.position - b.position)
|
||||
}
|
||||
|
||||
export function getRecipeLuma(recipe: Recipe): number {
|
||||
// https://stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black
|
||||
const c = recipe.color.substring(1) // strip #
|
||||
const rgb = parseInt(c, 16) // convert rrggbb to decimal
|
||||
const r = (rgb >> 16) & 0xff // extract red
|
||||
const g = (rgb >> 8) & 0xff // extract green
|
||||
const b = (rgb >> 0) & 0xff // extract blue
|
||||
|
||||
return 0.2126 * r + 0.7152 * g + 0.0722 * b // per ITU-R BT.709
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue