develop #5
|
@ -8,12 +8,12 @@ services:
|
|||
MYSQL_ROOT_PASSWORD: "pass"
|
||||
MYSQL_DATABASE: "cre"
|
||||
ports:
|
||||
- "3306:3306"
|
||||
- "3307:3306"
|
||||
backend:
|
||||
image: registry.fyloz.dev:5443/colorrecipesexplorer/backend:latest
|
||||
environment:
|
||||
spring_profiles_active: "mysql,debug"
|
||||
cre_database_url: "mysql://database:3306/cre"
|
||||
cre_database_url: "mysql://database:3307/cre"
|
||||
cre_database_username: "root"
|
||||
cre_database_password: "pass"
|
||||
CRE_ENABLE_DB_UPDATE: 1
|
||||
|
|
|
@ -1 +1,10 @@
|
|||
<recipe-form (submitForm)="submit($event)"></recipe-form>
|
||||
<cre-action-bar>
|
||||
<cre-action-group>
|
||||
<cre-primary-button routerLink="/color/list">Retour</cre-primary-button>
|
||||
</cre-action-group>
|
||||
<cre-action-group>
|
||||
<cre-submit-button [form]="recipeForm.creForm" (submit)="recipeForm.submit()"></cre-submit-button>
|
||||
</cre-action-group>
|
||||
</cre-action-bar>
|
||||
|
||||
<recipe-form #recipeForm (submitForm)="submit($event)"></recipe-form>
|
||||
|
|
|
@ -1,132 +1,122 @@
|
|||
<mat-card *ngIf="recipe && (!editionMode || mix)" class="x-centered mt-5">
|
||||
<mat-card-header>
|
||||
<mat-card-title *ngIf="!editionMode">Création d'un mélange pour la recette {{recipe.company.name}}
|
||||
- {{recipe.name}}</mat-card-title>
|
||||
<mat-card-title *ngIf="editionMode">Modification du mélange {{mix.mixType.name}} de la
|
||||
recette {{recipe.company.name}} - {{recipe.name}}</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<mat-form-field>
|
||||
<mat-label>Nom</mat-label>
|
||||
<input matInput type="text" [formControl]="nameControl"/>
|
||||
<mat-icon svgIcon="form-textbox" matSuffix></mat-icon>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-label>Type de produit</mat-label>
|
||||
<mat-select [formControl]="materialTypeControl">
|
||||
<mat-option
|
||||
*ngFor="let materialType of (materialTypes$ | async)"
|
||||
[value]="materialType.id">
|
||||
{{materialType.name}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<ng-container *ngIf="recipe && materials && (!editionMode || mix)">
|
||||
<cre-action-bar>
|
||||
<cre-action-group>
|
||||
<cre-primary-button routerLink="/color/edit/{{recipeId}}">Retour</cre-primary-button>
|
||||
</cre-action-group>
|
||||
<cre-action-group>
|
||||
<cre-warn-button *ngIf="editionMode" (click)="deleteConfirmBox.show()">Supprimer</cre-warn-button>
|
||||
<cre-submit-button [form]="creForm" (submit)="submit()">Enregistrer</cre-submit-button>
|
||||
</cre-action-group>
|
||||
</cre-action-bar>
|
||||
|
||||
<div class="mix-materials-wrapper">
|
||||
<ng-container *ngTemplateOutlet="mixEditor"></ng-container>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-raised-button color="primary" routerLink="/color/edit/{{recipeId}}">Retour</button>
|
||||
<button *ngIf="editionMode" mat-raised-button color="warn" (click)="deleteConfirmBox.show()">
|
||||
Supprimer
|
||||
</button>
|
||||
<button mat-raised-button color="accent" [disabled]="!form.valid" (click)="submit()">Enregistrer</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
<cre-form #creForm [formControls]="controls" class="mx-auto">
|
||||
<cre-form-title *ngIf="!editionMode">Ajouter un mélange à la couleur {{recipe.company.name}}
|
||||
- {{recipe.name}}</cre-form-title>
|
||||
<cre-form-title *ngIf="editionMode">Modification du mélange {{mix.mixType.name}} de la
|
||||
couleur {{recipe.company.name}}
|
||||
- {{recipe.name}}</cre-form-title>
|
||||
|
||||
<ng-template #mixEditor>
|
||||
<table #matTable mat-table [dataSource]="mixMaterials">
|
||||
<ng-container matColumnDef="position">
|
||||
<th mat-header-cell *matHeaderCellDef>Position</th>
|
||||
<td mat-cell *matCellDef="let mixMaterial">
|
||||
{{mixMaterial.position}}
|
||||
</td>
|
||||
</ng-container>
|
||||
<cre-form-content>
|
||||
<cre-input [control]="controls.name" label="name" icon="form-textbox"></cre-input>
|
||||
<cre-select [control]="controls.materialType" label="Type de produit"
|
||||
[entries]="materialTypeEntries$"></cre-select>
|
||||
</cre-form-content>
|
||||
</cre-form>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="buttonsPosition">
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let mixMaterial; let i = index">
|
||||
<ng-container *ngIf="(!hoveredMixMaterial && i === 0) || hoveredMixMaterial === mixMaterial">
|
||||
<button
|
||||
mat-mini-fab
|
||||
color="primary"
|
||||
class="mr-1"
|
||||
[disabled]="mixMaterial.position <= 1"
|
||||
(click)="decreasePosition(mixMaterial, matTable)">
|
||||
<mat-icon svgIcon="arrow-up"></mat-icon>
|
||||
</button>
|
||||
<button
|
||||
mat-mini-fab
|
||||
color="primary"
|
||||
[disabled]="mixMaterial.position >= mixMaterials.length"
|
||||
(click)="increasePosition(mixMaterial, matTable)">
|
||||
<mat-icon svgIcon="arrow-down"></mat-icon>
|
||||
</button>
|
||||
<table #matTable mat-table [dataSource]="mixMaterials" class="mx-auto mt-5">
|
||||
<ng-container matColumnDef="position">
|
||||
<th mat-header-cell *matHeaderCellDef>Position</th>
|
||||
<td mat-cell *matCellDef="let mixMaterial">
|
||||
{{mixMaterial.position}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="buttonsPosition">
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let mixMaterial; let i = index">
|
||||
<ng-container *ngIf="(!hoveredMixMaterial && i === 0) || hoveredMixMaterial === mixMaterial">
|
||||
<button
|
||||
mat-mini-fab
|
||||
color="primary"
|
||||
class="mr-1"
|
||||
[disabled]="mixMaterial.position <= 1"
|
||||
(click)="decreasePosition(mixMaterial, matTable)">
|
||||
<mat-icon svgIcon="arrow-up"></mat-icon>
|
||||
</button>
|
||||
<button
|
||||
mat-mini-fab
|
||||
color="primary"
|
||||
[disabled]="mixMaterial.position >= mixMaterials.length"
|
||||
(click)="increasePosition(mixMaterial, matTable)">
|
||||
<mat-icon svgIcon="arrow-down"></mat-icon>
|
||||
</button>
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="material">
|
||||
<th mat-header-cell *matHeaderCellDef>Produit</th>
|
||||
<td mat-cell *matCellDef="let mixMaterial">
|
||||
<!-- <mat-form-field *ngIf="materials">-->
|
||||
<!-- <mat-select-->
|
||||
<!-- [value]="mixMaterial.materialId"-->
|
||||
<!-- (valueChange)="setMixMaterialMaterial(mixMaterial, $event)">-->
|
||||
<!-- <mat-option-->
|
||||
<!-- *ngFor="let material of sortedMaterials(getAvailableMaterials(mixMaterial))"-->
|
||||
<!-- [value]="material.id">-->
|
||||
<!-- {{materialDisplayName(material)}}-->
|
||||
<!-- </mat-option>-->
|
||||
<!-- </mat-select>-->
|
||||
<!-- </mat-form-field>-->
|
||||
|
||||
|
||||
<cre-select [entries]="getAvailableMaterials(mixMaterial)"></cre-select>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="quantity">
|
||||
<th mat-header-cell *matHeaderCellDef>Quantité</th>
|
||||
<td mat-cell *matCellDef="let mixMaterial">
|
||||
<mat-form-field>
|
||||
<input matInput type="number" step="0.001" [(ngModel)]="mixMaterial.quantity"/>
|
||||
</mat-form-field>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="units">
|
||||
<th mat-header-cell *matHeaderCellDef>Unités</th>
|
||||
<td mat-cell *matCellDef="let mixMaterial" class="units-wrapper">
|
||||
<ng-container *ngIf="materials">
|
||||
<ng-container *ngIf="mixMaterial.isPercents">
|
||||
<p>%</p>
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="material">
|
||||
<th mat-header-cell *matHeaderCellDef>Produit</th>
|
||||
<td mat-cell *matCellDef="let mixMaterial">
|
||||
<mat-form-field *ngIf="materials">
|
||||
<mat-select
|
||||
[value]="mixMaterial.materialId"
|
||||
(valueChange)="setMixMaterialMaterial(mixMaterial, $event)">
|
||||
<mat-option
|
||||
*ngFor="let material of sortedMaterials(getAvailableMaterials(mixMaterial))"
|
||||
[value]="material.id">
|
||||
{{materialDisplayName(material)}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="quantity">
|
||||
<th mat-header-cell *matHeaderCellDef>Quantité</th>
|
||||
<td mat-cell *matCellDef="let mixMaterial">
|
||||
<mat-form-field>
|
||||
<input matInput type="number" step="0.001" [(ngModel)]="mixMaterial.quantity"/>
|
||||
</mat-form-field>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="units">
|
||||
<th mat-header-cell *matHeaderCellDef>Unités</th>
|
||||
<td mat-cell *matCellDef="let mixMaterial" class="units-wrapper">
|
||||
<ng-container *ngIf="materials">
|
||||
<ng-container *ngIf="mixMaterial.isPercents">
|
||||
<p>%</p>
|
||||
<ng-container *ngIf="!mixMaterial.isPercents">
|
||||
<ng-container *ngIf="!hoveredMixMaterial || hoveredMixMaterial != mixMaterial">
|
||||
<span>{{units}}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!mixMaterial.isPercents">
|
||||
<ng-container *ngIf="!hoveredMixMaterial || hoveredMixMaterial != mixMaterial">
|
||||
<span>{{units}}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="hoveredMixMaterial && hoveredMixMaterial == mixMaterial">
|
||||
<cre-unit-selector [(unit)]="units" [showLabel]="false" [short]="true"></cre-unit-selector>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="hoveredMixMaterial && hoveredMixMaterial == mixMaterial">
|
||||
<cre-unit-selector [(unit)]="units" [showLabel]="false" [short]="true"></cre-unit-selector>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="buttonRemove">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<button mat-raised-button color="accent" (click)="addRow()">Ajouter</button>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let mixMaterial; let i = index">
|
||||
<ng-container *ngIf="hoveredMixMaterial && hoveredMixMaterial == mixMaterial">
|
||||
<button mat-raised-button color="warn" (click)="removeRow(i)">Retirer</button>
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="buttonRemove">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<button mat-raised-button color="accent" (click)="addRow()">Ajouter</button>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let mixMaterial; let i = index">
|
||||
<ng-container *ngIf="hoveredMixMaterial && hoveredMixMaterial == mixMaterial">
|
||||
<button mat-raised-button color="warn" (click)="removeRow(i)">Retirer</button>
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="columns"></tr>
|
||||
<tr mat-row *matRowDef="let mixMaterial; columns: columns" (mouseover)="hoveredMixMaterial = mixMaterial"></tr>
|
||||
</table>
|
||||
</ng-template>
|
||||
<tr mat-header-row *matHeaderRowDef="tableColumns"></tr>
|
||||
<tr mat-row *matRowDef="let mixMaterial; columns: tableColumns" (mouseover)="hoveredMixMaterial = mixMaterial"></tr>
|
||||
</table>
|
||||
|
||||
<cre-confirm-box
|
||||
*ngIf="editionMode && mix"
|
||||
|
|
|
@ -10,16 +10,19 @@ import {
|
|||
import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component'
|
||||
import {MixService} from '../../services/mix.service'
|
||||
import {RecipeService} from '../../services/recipe.service'
|
||||
import {Material} from '../../../shared/model/material.model'
|
||||
import {Material, materialComparator} from '../../../shared/model/material.model'
|
||||
import {MaterialService} from '../../../material/service/material.service'
|
||||
import {MaterialTypeService} from '../../../material-type/service/material-type.service'
|
||||
import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms'
|
||||
import {FormBuilder, FormControl, Validators} from '@angular/forms'
|
||||
import {UNIT_MILLILITER} from '../../../shared/units'
|
||||
import {MatTable} from '@angular/material/table'
|
||||
import {ActivatedRoute, Router} from '@angular/router'
|
||||
import {ConfirmBoxComponent} from '../../../shared/components/confirm-box/confirm-box.component'
|
||||
import {AccountService} from '../../../accounts/services/account.service'
|
||||
import {ErrorService} from '../../../shared/service/error.service'
|
||||
import {map, tap} from 'rxjs/operators';
|
||||
import {CreInputEntry} from '../../../shared/components/inputs/inputs';
|
||||
import {CreForm, ICreForm} from '../../../shared/components/forms/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'cre-mix-editor',
|
||||
|
@ -29,6 +32,7 @@ import {ErrorService} from '../../../shared/service/error.service'
|
|||
export class MixEditorComponent extends ErrorHandlingComponent {
|
||||
@ViewChild('matTable') mixTable: MatTable<MixMaterial>
|
||||
@ViewChild('deleteConfirmBox') deleteConfirmBox: ConfirmBoxComponent
|
||||
@ViewChild(CreForm) creForm: ICreForm
|
||||
|
||||
@Input() mixId: number | null
|
||||
@Input() recipeId: number | null
|
||||
|
@ -36,35 +40,36 @@ export class MixEditorComponent extends ErrorHandlingComponent {
|
|||
|
||||
@Output() save = new EventEmitter<any>()
|
||||
|
||||
recipe: Recipe
|
||||
mix: Mix | null
|
||||
recipe: Recipe | null
|
||||
materialTypes$ = this.materialTypeService.all
|
||||
|
||||
form: FormGroup
|
||||
nameControl: FormControl
|
||||
materialTypeControl: FormControl
|
||||
|
||||
mixMaterials: MixMaterialDto[] = []
|
||||
editionMode = false
|
||||
units = UNIT_MILLILITER
|
||||
hoveredMixMaterial: MixMaterial | null
|
||||
columns = ['position', 'buttonsPosition', 'material', 'quantity', 'units', 'buttonRemove']
|
||||
tableColumns = ['position', 'buttonsPosition', 'material', 'quantity', 'units', 'buttonRemove']
|
||||
|
||||
deleting = false
|
||||
errorHandlers = [{
|
||||
filter: error => error.type === 'notfound-mix-id',
|
||||
consumer: error => this.urlUtils.navigateTo('/color/list')
|
||||
consumer: _ => this.urlUtils.navigateTo('/color/list')
|
||||
}, {
|
||||
filter: error => error.type === 'exists-material-name',
|
||||
messageProducer: error => `Un produit avec le nom '${error.name}' existe déjà`
|
||||
}, {
|
||||
filter: error => error.type === 'cannotdelete-mix',
|
||||
messageProducer: error => 'Ce mélange est utilisé par un ou plusieurs autres mélanges'
|
||||
messageProducer: _ => 'Ce mélange est utilisé par un ou plusieurs autres mélanges'
|
||||
}, {
|
||||
filter: error => error.type === 'invalid-mixmaterial-first',
|
||||
messageProducer: error => 'La quantité du premier ingrédient du mélange ne peut pas être exprimée en pourcentage'
|
||||
messageProducer: _ => 'La quantité du premier ingrédient du mélange ne peut pas être exprimée en pourcentage'
|
||||
}]
|
||||
|
||||
controls: any
|
||||
materialTypeEntries$ = this.materialTypeService.all.pipe(
|
||||
map(materialTypes => materialTypes.map(materialType => new CreInputEntry(materialType.id, materialType.name))),
|
||||
)
|
||||
|
||||
private _mixMaterials: MixMaterialDto[] = []
|
||||
|
||||
constructor(
|
||||
private mixService: MixService,
|
||||
private recipeService: RecipeService,
|
||||
|
@ -87,22 +92,42 @@ export class MixEditorComponent extends ErrorHandlingComponent {
|
|||
this.editionMode = true
|
||||
}
|
||||
|
||||
this.subscribeEntityById(
|
||||
this.recipeService,
|
||||
this.recipeId,
|
||||
r => {
|
||||
this.recipe = r
|
||||
this.fetchRecipe()
|
||||
this.fetchMaterials()
|
||||
}
|
||||
|
||||
private fetchRecipe() {
|
||||
this.subscribe(
|
||||
this.recipeService.getById(this.recipeId),
|
||||
recipe => {
|
||||
this.recipe = recipe
|
||||
|
||||
if (this.editionMode) {
|
||||
this.mix = this.recipe.mixes.find(m => m.id === this.mixId)
|
||||
this.mix = this.recipe.mixes.find(mix => mix.id === this.mixId)
|
||||
this.mixMaterials = mixMaterialsAsMixMaterialsDto(this.mix)
|
||||
} else {
|
||||
this.addBlankMixMaterial()
|
||||
}
|
||||
this.generateForm()
|
||||
|
||||
this.createControls()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fetchMaterials() {
|
||||
this.subscribe(
|
||||
this.materialService.all,
|
||||
materials => this.materials = materials
|
||||
)
|
||||
}
|
||||
|
||||
private createControls() {
|
||||
this.controls = {
|
||||
name: new FormControl(this.mix?.mixType.name, Validators.required),
|
||||
materialType: new FormControl(this.mix?.mixType.material.materialType.id, Validators.required)
|
||||
}
|
||||
}
|
||||
|
||||
addRow() {
|
||||
this.addBlankMixMaterial()
|
||||
this.mixTable.renderRows()
|
||||
|
@ -141,9 +166,9 @@ export class MixEditorComponent extends ErrorHandlingComponent {
|
|||
|
||||
submit() {
|
||||
this.save.emit({
|
||||
name: this.nameControl.value,
|
||||
name: this.controls.name.value,
|
||||
recipeId: this.recipeId,
|
||||
materialTypeId: this.materialTypeControl.value,
|
||||
materialTypeId: this.controls.materialType.value,
|
||||
mixMaterials: this.mixMaterials,
|
||||
units: this.units
|
||||
})
|
||||
|
@ -154,8 +179,21 @@ export class MixEditorComponent extends ErrorHandlingComponent {
|
|||
this.subscribeAndNavigate(this.mixService.delete(this.mixId), `/color/edit/${this.recipeId}`)
|
||||
}
|
||||
|
||||
getAvailableMaterials(mixMaterial: MixMaterialDto): Material[] {
|
||||
return this.materials.filter(m => mixMaterial.materialId === m.id || this.mixMaterials.filter(mm => mm.materialId === m.id).length === 0)
|
||||
getAvailableMaterials(mixMaterial: MixMaterialDto): CreInputEntry[] {
|
||||
// return this.materialService.all.pipe(
|
||||
// map(materials => materials.filter(material => {
|
||||
// return mixMaterial.materialId === material.id || this.mixMaterials.filter(mm => mm.materialId === material.id).length === 0
|
||||
// })),
|
||||
// map(materials => this.sortedMaterials(materials)),
|
||||
// map(materials => materials.map(material => new CreInputEntry(material.id, material.name)))
|
||||
// )
|
||||
console.log(this.materials.map(material => new CreInputEntry(material.id, material.name)))
|
||||
return []
|
||||
// return this.materials.map(material => new CreInputEntry(material.id, material.name))
|
||||
// return this.materials
|
||||
// .filter(m => mixMaterial.materialId === m.id || this.mixMaterials.filter(mm => mm.materialId === m.id).length === 0)
|
||||
// .sort(materialComparator)
|
||||
// .map(material => new CreInputEntry(material.id, material.name))
|
||||
}
|
||||
|
||||
materialDisplayName(material: Material): string {
|
||||
|
@ -165,43 +203,18 @@ export class MixEditorComponent extends ErrorHandlingComponent {
|
|||
return material.name
|
||||
}
|
||||
|
||||
sortedMaterials(materials: Material[]): Material[] {
|
||||
return materials.sort((a, b) => {
|
||||
const aPrefixName = a.materialType.prefix.toLowerCase()
|
||||
const bPrefixName = b.materialType.prefix.toLowerCase()
|
||||
|
||||
if (aPrefixName < bPrefixName) {
|
||||
return -1
|
||||
} else if (aPrefixName > bPrefixName) {
|
||||
return 1
|
||||
} else {
|
||||
const aName = a.name.toLowerCase()
|
||||
const bName = b.name.toLowerCase()
|
||||
|
||||
if (aName < bName) {
|
||||
return -1
|
||||
} else if (aName > bName) {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
})
|
||||
get mixMaterials(): MixMaterialDto[] {
|
||||
return this._mixMaterials
|
||||
}
|
||||
|
||||
private generateForm() {
|
||||
this.nameControl = new FormControl(this.mix ? this.mix.mixType.name : null, Validators.required)
|
||||
this.materialTypeControl = new FormControl(this.mix ? this.mix.mixType.material.materialType.id : null, Validators.required)
|
||||
this.form = this.formBuilder.group({
|
||||
name: this.nameControl,
|
||||
materialType: this.materialTypeControl
|
||||
})
|
||||
set mixMaterials(mixMaterials: MixMaterialDto[]) {
|
||||
this._mixMaterials = mixMaterials
|
||||
this.mixTable.renderRows()
|
||||
}
|
||||
|
||||
private addBlankMixMaterial() {
|
||||
this.mixMaterials.push(
|
||||
new MixMaterialDto(null, 0, false, this.mixMaterials.length + 1)
|
||||
)
|
||||
const mixMaterial = new MixMaterialDto(null, 0, false, this.mixMaterials.length + 1)
|
||||
this.mixMaterials = [...this.mixMaterials, mixMaterial]
|
||||
}
|
||||
|
||||
private updateMixMaterialPosition(mixMaterial: MixMaterialDto, updatedPosition: number) {
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
import {Component} from '@angular/core'
|
||||
import {RecipeService} from '../../services/recipe.service'
|
||||
import {RecipeService} from './services/recipe.service'
|
||||
import {ActivatedRoute, Router} from '@angular/router'
|
||||
import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component'
|
||||
import {ErrorHandlingComponent} from '../shared/components/subscribing.component'
|
||||
import {
|
||||
MixMaterialDto,
|
||||
Recipe,
|
||||
recipeMixCount,
|
||||
recipeNoteForGroupId,
|
||||
recipeStepCount
|
||||
} from '../../../shared/model/recipe.model'
|
||||
} from '../shared/model/recipe.model'
|
||||
import {Observable, Subject} from 'rxjs'
|
||||
import {ErrorHandler, ErrorService} from '../../../shared/service/error.service'
|
||||
import {AlertService} from '../../../shared/service/alert.service'
|
||||
import {GlobalAlertHandlerComponent} from '../../../shared/components/global-alert-handler/global-alert-handler.component'
|
||||
import {InventoryService} from '../../../material/service/inventory.service'
|
||||
import {ConfirmBoxComponent} from '../../../shared/components/confirm-box/confirm-box.component'
|
||||
import {GroupService} from '../../../groups/services/group.service'
|
||||
import {AppState} from '../../../shared/app-state'
|
||||
import {AccountService} from '../../../accounts/services/account.service'
|
||||
import {Permission} from '../../../shared/model/user'
|
||||
import {ErrorHandler, ErrorService} from '../shared/service/error.service'
|
||||
import {AlertService} from '../shared/service/alert.service'
|
||||
import {GlobalAlertHandlerComponent} from '../shared/components/global-alert-handler/global-alert-handler.component'
|
||||
import {InventoryService} from '../material/service/inventory.service'
|
||||
import {ConfirmBoxComponent} from '../shared/components/confirm-box/confirm-box.component'
|
||||
import {GroupService} from '../groups/services/group.service'
|
||||
import {AppState} from '../shared/app-state'
|
||||
import {AccountService} from '../accounts/services/account.service'
|
||||
import {Permission} from '../shared/model/user'
|
||||
import {FormControl} from '@angular/forms';
|
||||
import {map, tap} from 'rxjs/operators';
|
||||
import {CreInputEntry} from '../../../shared/components/inputs/inputs';
|
||||
import {map} from 'rxjs/operators';
|
||||
import {CreInputEntry} from '../shared/components/inputs/inputs';
|
||||
|
||||
@Component({
|
||||
selector: 'cre-explore',
|
||||
templateUrl: './explore.component.html',
|
||||
styleUrls: ['./explore.component.sass']
|
||||
selector: 'cre-recipe-explore',
|
||||
templateUrl: './explore.html',
|
||||
styleUrls: ['./recipes.sass']
|
||||
})
|
||||
export class ExploreComponent extends ErrorHandlingComponent {
|
||||
export class CreRecipeExplore extends ErrorHandlingComponent {
|
||||
deductErrorBody = {}
|
||||
units$ = new Subject<string>()
|
||||
selectedGroupId: number | null
|
|
@ -5,7 +5,7 @@
|
|||
</cre-warning-alert>
|
||||
</div>
|
||||
|
||||
<cre-form *ngIf="hasCompanies" #form [formControls]="controls" class="mx-auto">
|
||||
<cre-form *ngIf="hasCompanies" [formControls]="controls" class="mx-auto">
|
||||
<cre-form-title *ngIf="!recipe">Ajouter une couleur</cre-form-title>
|
||||
<cre-form-title *ngIf="recipe">Modifier la couleur {{recipe.name}}</cre-form-title>
|
||||
<cre-form-content>
|
||||
|
@ -18,8 +18,4 @@
|
|||
<cre-input [control]="controls.remark" label="Remarque" icon="text"></cre-input>
|
||||
<cre-combo-box [control]="controls.company" label="Bannière" [entries]="companyEntries$"></cre-combo-box>
|
||||
</cre-form-content>
|
||||
<cre-form-actions *ngIf="!recipe">
|
||||
<cre-primary-button routerLink="/color/list">Retour</cre-primary-button>
|
||||
<cre-accent-button [disabled]="form.invalid" (click)="submit()">Enregistrer</cre-accent-button>
|
||||
</cre-form-actions>
|
||||
</cre-form>
|
||||
|
|
|
@ -1,31 +1,19 @@
|
|||
<div class="action-bar">
|
||||
<mat-form-field>
|
||||
<mat-label>Recherche</mat-label>
|
||||
<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>
|
||||
<div class="button-add">
|
||||
<button *ngIf="hasEditPermission" mat-raised-button color="accent" routerLink="/color/add">Ajouter</button>
|
||||
</div>
|
||||
</div>
|
||||
<cre-action-bar>
|
||||
<cre-action-group>
|
||||
<cre-input label="Recherche" [control]="searchControl"></cre-input>
|
||||
</cre-action-group>
|
||||
<cre-action-group>
|
||||
<cre-accent-button *ngIf="hasEditPermission" routerLink="/color/add">Ajouter</cre-accent-button>
|
||||
</cre-action-group>
|
||||
</cre-action-bar>
|
||||
|
||||
<div *ngIf="!loading">
|
||||
<cre-warning-alert *ngIf="companies.length === 0">
|
||||
<p>Il n'y a actuellement aucune bannière enregistrée dans le système.</p>
|
||||
<p *ngIf="hasCompanyEditPermission">Vous pouvez en créer une <b><a routerLink="/catalog/company/add">ici</a></b>.</p>
|
||||
<p *ngIf="hasCompanyEditPermission">Vous pouvez en créer une <b><a routerLink="/catalog/company/add">ici</a></b>.
|
||||
</p>
|
||||
</cre-warning-alert>
|
||||
<cre-warning-alert *ngIf="recipes.size === 0">
|
||||
<cre-warning-alert *ngIf="companies.length > 0 && recipes.size === 0">
|
||||
<p>Il n'y a actuellement aucune recette enregistrée dans le système.</p>
|
||||
<p *ngIf="hasEditPermission">Vous pouvez en créer une <b><a routerLink="/color/add">ici</a></b>.</p>
|
||||
</cre-warning-alert>
|
|
@ -1,23 +1,24 @@
|
|||
import {ChangeDetectorRef, Component} from '@angular/core'
|
||||
import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component'
|
||||
import {RecipeService} from '../../services/recipe.service'
|
||||
import {Permission} from '../../../shared/model/user'
|
||||
import {AccountService} from '../../../accounts/services/account.service'
|
||||
import {getRecipeLuma, Recipe} from '../../../shared/model/recipe.model'
|
||||
import {ActivatedRoute, Router} from '@angular/router'
|
||||
import {ErrorService} from '../../../shared/service/error.service'
|
||||
import {AppState} from '../../../shared/app-state'
|
||||
import {ConfigService} from '../../../shared/service/config.service'
|
||||
import {Company} from '../../../shared/model/company.model';
|
||||
import {CompanyService} from '../../../company/service/company.service';
|
||||
import {Config} from '../../../shared/model/config.model';
|
||||
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';
|
||||
|
||||
@Component({
|
||||
selector: 'cre-list',
|
||||
templateUrl: './list.component.html',
|
||||
styleUrls: ['./list.component.sass']
|
||||
selector: 'cre-recipe-list',
|
||||
templateUrl: 'list.html',
|
||||
styleUrls: ['recipes.sass']
|
||||
})
|
||||
export class ListComponent extends ErrorHandlingComponent {
|
||||
export class RecipeList extends ErrorHandlingComponent {
|
||||
companies: Company[] = []
|
||||
recipes: Map<number, Recipe[]> = new Map<number, Recipe[]>()
|
||||
tableCols = ['name', 'description', 'color', 'sample', 'iconNotApproved', 'buttonView', 'buttonEdit']
|
||||
|
@ -25,6 +26,8 @@ export class ListComponent extends ErrorHandlingComponent {
|
|||
panelForcedExpanded = false
|
||||
hiddenRecipes = []
|
||||
|
||||
searchControl: FormControl
|
||||
|
||||
constructor(
|
||||
private companyService: CompanyService,
|
||||
private recipeService: RecipeService,
|
||||
|
@ -47,7 +50,7 @@ export class ListComponent extends ErrorHandlingComponent {
|
|||
this.subscribe(
|
||||
this.configService.get(Config.EMERGENCY_MODE),
|
||||
config => {
|
||||
if (config.content == "true") {
|
||||
if (config.content == 'true') {
|
||||
this.urlUtils.navigateTo('/admin/config/')
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +58,12 @@ export class ListComponent extends ErrorHandlingComponent {
|
|||
|
||||
this.fetchCompanies()
|
||||
this.fetchRecipes()
|
||||
|
||||
this.searchControl = new FormControl('')
|
||||
this.subscribe(
|
||||
this.searchControl.valueChanges,
|
||||
value => this.searchRecipes(value)
|
||||
)
|
||||
}
|
||||
|
||||
private fetchCompanies() {
|
||||
|
@ -72,7 +81,8 @@ export class ListComponent extends ErrorHandlingComponent {
|
|||
)
|
||||
}
|
||||
|
||||
searchRecipes() {
|
||||
searchRecipes(searchQuery) {
|
||||
this.searchQuery = searchQuery
|
||||
if (this.searchQuery.length > 0 && !this.panelForcedExpanded) {
|
||||
this.panelForcedExpanded = true
|
||||
this.cdRef.detectChanges()
|
|
@ -1,2 +0,0 @@
|
|||
.recipe-content > div
|
||||
margin: 0 3rem 3rem
|
|
@ -1,9 +0,0 @@
|
|||
mat-expansion-panel
|
||||
width: 60rem
|
||||
margin: 20px auto
|
||||
|
||||
.button-add
|
||||
margin-top: .8rem
|
||||
|
||||
.recipe-color-circle
|
||||
box-shadow: 0 2px 1px -1px rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 3px 0 rgba(0, 0, 0, 0.12)
|
|
@ -1,14 +1,14 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {ListComponent} from './pages/list/list.component';
|
||||
import {ExploreComponent} from './pages/explore/explore.component';
|
||||
import {CreRecipeExplore} from './explore';
|
||||
import {MixEditComponent} from './pages/mix/mix-edit/mix-edit.component';
|
||||
import {MixAddComponent} from './pages/mix/mix-add/mix-add.component';
|
||||
import {RecipeAdd, RecipeEdit} from './recipes';
|
||||
import {RecipeList} from './list';
|
||||
|
||||
const routes: Routes = [{
|
||||
path: 'list',
|
||||
component: ListComponent
|
||||
component: RecipeList
|
||||
}, {
|
||||
path: 'add',
|
||||
component: RecipeAdd
|
||||
|
@ -23,7 +23,7 @@ const routes: Routes = [{
|
|||
component: MixEditComponent
|
||||
}, {
|
||||
path: 'explore/:id',
|
||||
component: ExploreComponent
|
||||
component: CreRecipeExplore
|
||||
}, {
|
||||
path: '',
|
||||
pathMatch: 'full',
|
||||
|
|
|
@ -2,10 +2,9 @@ import {NgModule} from '@angular/core'
|
|||
|
||||
import {RecipesRoutingModule} from './recipes-routing.module'
|
||||
import {SharedModule} from '../shared/shared.module'
|
||||
import {ListComponent} from './pages/list/list.component'
|
||||
import {MatExpansionModule} from '@angular/material/expansion'
|
||||
import {FormsModule} from '@angular/forms'
|
||||
import {ExploreComponent} from './pages/explore/explore.component'
|
||||
import {CreRecipeExplore} from './explore'
|
||||
import {RecipeInfoComponent} from './components/recipe-info/recipe-info.component'
|
||||
import {MixTableComponent} from './components/mix-table/mix-table.component'
|
||||
import {StepListComponent} from './components/step-list/step-list.component'
|
||||
|
@ -21,12 +20,11 @@ import {CreInputsModule} from '../shared/components/inputs/inputs.module';
|
|||
import {CreButtonsModule} from '../shared/components/buttons/buttons.module';
|
||||
import {RecipeAdd, RecipeEdit, RecipeForm} from './recipes';
|
||||
import {CreActionBarModule} from '../shared/components/action-bar/action-bar.module';
|
||||
|
||||
import {RecipeList} from './list';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
ListComponent,
|
||||
ExploreComponent,
|
||||
CreRecipeExplore,
|
||||
RecipeInfoComponent,
|
||||
MixTableComponent,
|
||||
StepListComponent,
|
||||
|
@ -39,7 +37,8 @@ import {CreActionBarModule} from '../shared/components/action-bar/action-bar.mod
|
|||
MixesCardComponent,
|
||||
RecipeForm,
|
||||
RecipeAdd,
|
||||
RecipeEdit
|
||||
RecipeEdit,
|
||||
RecipeList
|
||||
],
|
||||
exports: [
|
||||
UnitSelectorComponent
|
||||
|
|
|
@ -4,3 +4,15 @@
|
|||
cre-form
|
||||
margin-top: 0 !important
|
||||
|
||||
mat-expansion-panel
|
||||
width: 60rem
|
||||
margin: 20px auto
|
||||
|
||||
.button-add
|
||||
margin-top: .8rem
|
||||
|
||||
.recipe-color-circle
|
||||
box-shadow: 0 2px 1px -1px rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 3px 0 rgba(0, 0, 0, 0.12)
|
||||
|
||||
.recipe-content > div
|
||||
margin: 0 3rem 3rem
|
||||
|
|
|
@ -16,6 +16,7 @@ import {AlertService} from '../shared/service/alert.service';
|
|||
import {GroupService} from '../groups/services/group.service';
|
||||
import {StepTableComponent} from './components/step-table/step-table.component';
|
||||
import {anyMap} from '../shared/utils/map.utils';
|
||||
import {CreForm, ICreForm} from '../shared/components/forms/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'recipe-form',
|
||||
|
@ -26,6 +27,8 @@ import {anyMap} from '../shared/utils/map.utils';
|
|||
export class RecipeForm extends SubscribingComponent {
|
||||
@Input() recipe: Recipe | null
|
||||
|
||||
@ViewChild(CreForm) creForm: ICreForm
|
||||
|
||||
@Output() submitForm = new EventEmitter<Recipe>();
|
||||
|
||||
controls: any
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<div class="d-flex flex-row justify-content-between px-5 py-4">
|
||||
<div class="d-flex flex-row justify-content-between px-5 py-4" [class.flex-row-reverse]="reverse">
|
||||
<ng-content select="cre-action-group"></ng-content>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Component} from '@angular/core'
|
||||
import {Component, Input} from '@angular/core'
|
||||
|
||||
@Component({
|
||||
selector: 'cre-action-group',
|
||||
|
@ -11,4 +11,6 @@ export class CreActionGroup {}
|
|||
selector: 'cre-action-bar',
|
||||
templateUrl: 'action-bar.html'
|
||||
})
|
||||
export class CreActionBar {}
|
||||
export class CreActionBar {
|
||||
@Input() reverse = false
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||
import {ICreForm} from './forms';
|
||||
|
||||
@Component({
|
||||
selector: 'cre-submit-button',
|
||||
templateUrl: 'submit-button.html'
|
||||
})
|
||||
export class CreSubmitButton {
|
||||
@Input() form: ICreForm
|
||||
@Input() valid: boolean | null
|
||||
|
||||
@Output() submit = new EventEmitter<void>()
|
||||
|
||||
get disableButton(): boolean {
|
||||
return !this.form || !(this.valid ?? this.form.valid)
|
||||
}
|
||||
}
|
|
@ -1,28 +1,34 @@
|
|||
import {NgModule} from '@angular/core'
|
||||
import {CreFormActions, CreFormComponent, CreFormContent, CreFormTitle} from './forms'
|
||||
import {CreFormActions, CreForm, CreFormContent, CreFormTitle} from './forms'
|
||||
import {MatCardModule} from '@angular/material/card'
|
||||
import {CommonModule} from '@angular/common'
|
||||
import {MatButtonModule} from '@angular/material/button'
|
||||
import {ReactiveFormsModule} from '@angular/forms'
|
||||
import {CreSubmitButton} from './buttons';
|
||||
import {CreButtonsModule} from '../buttons/buttons.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
CreFormComponent,
|
||||
CreForm,
|
||||
CreFormTitle,
|
||||
CreFormContent,
|
||||
CreFormActions
|
||||
CreFormActions,
|
||||
CreSubmitButton
|
||||
],
|
||||
exports: [
|
||||
CreFormComponent,
|
||||
CreForm,
|
||||
CreFormTitle,
|
||||
CreFormContent,
|
||||
CreFormActions
|
||||
CreFormActions,
|
||||
CreSubmitButton
|
||||
],
|
||||
imports: [
|
||||
MatCardModule,
|
||||
CommonModule,
|
||||
MatButtonModule,
|
||||
ReactiveFormsModule
|
||||
]
|
||||
imports: [
|
||||
MatCardModule,
|
||||
CommonModule,
|
||||
MatButtonModule,
|
||||
ReactiveFormsModule,
|
||||
CreButtonsModule
|
||||
]
|
||||
})
|
||||
export class CreFormsModule {}
|
||||
export class CreFormsModule {
|
||||
}
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
import {Component, ContentChild, Directive, Input, OnInit, ViewEncapsulation} from '@angular/core'
|
||||
import {FormBuilder, FormGroup} from '@angular/forms'
|
||||
|
||||
export interface ICreForm {
|
||||
form: FormGroup
|
||||
valid: boolean
|
||||
invalid: boolean
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: 'cre-form-title'
|
||||
})
|
||||
|
@ -17,7 +23,6 @@ export class CreFormContent {
|
|||
selector: 'cre-form-actions'
|
||||
})
|
||||
export class CreFormActions {
|
||||
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
@ -26,7 +31,7 @@ export class CreFormActions {
|
|||
styleUrls: ['forms.sass'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class CreFormComponent implements OnInit {
|
||||
export class CreForm implements ICreForm, OnInit {
|
||||
@ContentChild(CreFormActions) formActions: CreFormActions
|
||||
@Input() formControls: { [key: string]: any }
|
||||
|
||||
|
@ -45,6 +50,10 @@ export class CreFormComponent implements OnInit {
|
|||
return !!this.formActions
|
||||
}
|
||||
|
||||
get valid(): boolean {
|
||||
return this.form && this.form.valid
|
||||
}
|
||||
|
||||
get invalid(): boolean {
|
||||
return !this.form || this.form.invalid
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<cre-accent-button [disabled]="disableButton" (click)="submit.emit()">Enregistrer</cre-accent-button>
|
|
@ -5,7 +5,7 @@
|
|||
<input
|
||||
#input
|
||||
matInput
|
||||
[required]="isFieldRequired"
|
||||
[required]="fieldRequired"
|
||||
[disabled]="disabled"
|
||||
[(ngModel)]="value"
|
||||
(change)="valueChange.emit(value)"/>
|
||||
|
@ -14,7 +14,7 @@
|
|||
<input
|
||||
#input
|
||||
matInput
|
||||
[required]="isFieldRequired"
|
||||
[required]="fieldRequired"
|
||||
[formControl]="control">
|
||||
</ng-container>
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
} from '@angular/core'
|
||||
import {AbstractControl, FormControl, ValidationErrors, ValidatorFn, Validators} from '@angular/forms'
|
||||
import {COMMA, ENTER} from '@angular/cdk/keycodes'
|
||||
import {Observable, Subject} from 'rxjs'
|
||||
import {isObservable, Observable, Subject} from 'rxjs'
|
||||
import {map, takeUntil} from 'rxjs/operators'
|
||||
import {MatChipInputEvent} from '@angular/material/chips'
|
||||
import {MatAutocomplete, MatAutocompleteSelectedEvent} from '@angular/material/autocomplete'
|
||||
|
@ -50,16 +50,16 @@ export class CreInputComponent extends _CreInputBase implements AfterViewInit {
|
|||
@ViewChild('input') input: any
|
||||
@ContentChild(TemplateRef) errors: TemplateRef<any>
|
||||
|
||||
fieldRequired = true
|
||||
|
||||
ngAfterViewInit() {
|
||||
const element = this.input.nativeElement
|
||||
element.type = this.type
|
||||
element.step = this.step.toString()
|
||||
element.placeholder = this.placeholder
|
||||
element.autocomplete = this.autocomplete ? 'on' : 'off'
|
||||
}
|
||||
|
||||
get isFieldRequired(): boolean {
|
||||
return this.control ? this.control.validator && this.control.validator({} as AbstractControl)?.required : this.required
|
||||
this.fieldRequired = this.control ? this.control.validator && this.control.validator({} as AbstractControl)?.required : this.required
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,7 +400,19 @@ export class CreSliderInputComponent {
|
|||
templateUrl: 'select.html'
|
||||
})
|
||||
export class CreSelectComponent extends _CreInputBase {
|
||||
@Input() entries: Observable<CreInputEntry[]>
|
||||
@Input() entries: Observable<CreInputEntry[]> | CreInputEntry[]
|
||||
|
||||
get entriesAreObservable(): boolean {
|
||||
return isObservable(this.entries)
|
||||
}
|
||||
|
||||
get arrayEntries(): CreInputEntry[] {
|
||||
return this.entries as CreInputEntry[]
|
||||
}
|
||||
|
||||
get observableEntries(): Observable<CreInputEntry[]> {
|
||||
return this.entries as Observable<CreInputEntry[]>
|
||||
}
|
||||
}
|
||||
|
||||
export class CreInputEntry {
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
<mat-form-field>
|
||||
<mat-label>{{label}}</mat-label>
|
||||
<mat-select [formControl]="control">
|
||||
<mat-option *ngFor="let entry of entries | async" [value]="entry.key">
|
||||
{{entry.display || entry.value}}
|
||||
</mat-option>
|
||||
<mat-select [attr.formControl]="control ? control : null">
|
||||
<ng-container *ngIf="entriesAreObservable">
|
||||
<ng-container
|
||||
*ngFor="let entry of (observableEntries | async)">
|
||||
<mat-option [value]="entry.key">{{entry.display || entry.value}}</mat-option>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<ng-container
|
||||
*ngIf="!entriesAreObservable">
|
||||
<mat-option *ngFor="let entry of arrayEntries" [value]="entry.key">
|
||||
{{entry.display || entry.value}}
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {MaterialType} from "./materialtype.model";
|
||||
import {MaterialType} from './materialtype.model';
|
||||
import {openPdf} from '../utils/utils'
|
||||
|
||||
export class Material {
|
||||
|
@ -15,3 +15,25 @@ export class Material {
|
|||
export function openSimdut(material: Material) {
|
||||
openPdf(material.simdutUrl)
|
||||
}
|
||||
|
||||
export const materialComparator = (a: Material, b: Material): number => {
|
||||
const aPrefixName = a.materialType.prefix.toLowerCase()
|
||||
const bPrefixName = b.materialType.prefix.toLowerCase()
|
||||
|
||||
if (aPrefixName < bPrefixName) {
|
||||
return -1
|
||||
} else if (aPrefixName > bPrefixName) {
|
||||
return 1
|
||||
} else {
|
||||
const aName = a.name.toLowerCase()
|
||||
const bName = b.name.toLowerCase()
|
||||
|
||||
if (aName < bName) {
|
||||
return -1
|
||||
} else if (aName > bName) {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'
|
||||
import {chipListRequired, CreInputEntry, CreChipComboBoxComponent} from '../../shared/components/inputs/inputs'
|
||||
import {CreFormComponent} from '../../shared/components/forms/forms'
|
||||
import {CreForm} from '../../shared/components/forms/forms'
|
||||
import {TouchUpKitProductEditor} from './product-editor'
|
||||
import {FormControl, Validators} from '@angular/forms'
|
||||
import {RecipeService} from '../../recipes/services/recipe.service'
|
||||
|
@ -18,7 +18,7 @@ import {map} from 'rxjs/operators'
|
|||
export class TouchUpKitForm extends SubscribingComponent {
|
||||
@ViewChild('finishInput') finishInput: CreChipComboBoxComponent
|
||||
@ViewChild('materialInput') materialInput: CreChipComboBoxComponent
|
||||
@ViewChild(CreFormComponent) form: CreFormComponent
|
||||
@ViewChild(CreForm) form: CreForm
|
||||
@ViewChild(TouchUpKitProductEditor) contentEditor: TouchUpKitProductEditor
|
||||
|
||||
@Input() touchUpKit: TouchUpKit | null
|
||||
|
|
Loading…
Reference in New Issue