Start updating inventory
This commit is contained in:
parent
f564c37b15
commit
a8d13cc1fb
|
@ -9,6 +9,9 @@ import {EditComponent} from './pages/edit/edit.component';
|
||||||
import {RecipesModule} from '../recipes/recipes.module'
|
import {RecipesModule} from '../recipes/recipes.module'
|
||||||
import {MatSortModule} from '@angular/material/sort'
|
import {MatSortModule} from '@angular/material/sort'
|
||||||
import {FormsModule} from '@angular/forms'
|
import {FormsModule} from '@angular/forms'
|
||||||
|
import {CreTablesModule} from '../shared/components/tables/tables.module'
|
||||||
|
import {CreInputsModule} from '../shared/components/inputs/inputs.module'
|
||||||
|
import {CreButtonsModule} from '../shared/components/buttons/buttons.module'
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -19,7 +22,10 @@ import {FormsModule} from '@angular/forms'
|
||||||
SharedModule,
|
SharedModule,
|
||||||
RecipesModule,
|
RecipesModule,
|
||||||
MatSortModule,
|
MatSortModule,
|
||||||
FormsModule
|
FormsModule,
|
||||||
|
CreTablesModule,
|
||||||
|
CreInputsModule,
|
||||||
|
CreButtonsModule
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class MaterialModule {
|
export class MaterialModule {
|
||||||
|
|
|
@ -1,47 +1,34 @@
|
||||||
<div class="action-bar backward">
|
<div class="action-bar backward">
|
||||||
<!-- Left -->
|
<!-- Left -->
|
||||||
<div class="d-flex flex-row">
|
<div class="d-flex flex-row">
|
||||||
<mat-form-field class="mr-4">
|
<cre-input
|
||||||
<mat-label>Recherche par code...</mat-label>
|
class="mr-4"
|
||||||
<input
|
label="Recherche par code..."
|
||||||
matInput
|
[control]="materialNameFilterControl">
|
||||||
type="text"
|
</cre-input>
|
||||||
[(ngModel)]="materialNameFilter"
|
<cre-select
|
||||||
(keyup)="filterDataSource()"/>
|
label="Recherche par type de produit"
|
||||||
</mat-form-field>
|
[control]="materialTypeFilterControl"
|
||||||
<mat-form-field *ngIf="materialTypes$ | async as materialTypes">
|
[entries]="materialTypesEntries$">
|
||||||
<mat-label>Recherche par type de produit</mat-label>
|
</cre-select>
|
||||||
<mat-select
|
|
||||||
[(value)]="materialTypeFilter"
|
|
||||||
(valueChange)="filterDataSource()">
|
|
||||||
<mat-option
|
|
||||||
*ngFor="let materialType of materialTypes"
|
|
||||||
[value]="materialType.id">
|
|
||||||
{{materialType.name}}
|
|
||||||
</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right -->
|
<!-- Right -->
|
||||||
<div class="ml-auto">
|
<div class="ml-auto">
|
||||||
<mat-form-field class="mr-4">
|
<cre-input
|
||||||
<mat-label>Quantité faible</mat-label>
|
class="mr-4"
|
||||||
<input
|
label="Quantité faible"
|
||||||
matInput
|
type="number"
|
||||||
type="number"
|
step="0.01"
|
||||||
step="0.01"
|
[(value)]="lowQuantityThreshold">
|
||||||
[(ngModel)]="lowQuantityThreshold"/>
|
</cre-input>
|
||||||
</mat-form-field>
|
|
||||||
<cre-unit-selector [(unit)]="units"></cre-unit-selector>
|
<cre-unit-selector [(unit)]="units"></cre-unit-selector>
|
||||||
<button
|
<cre-accent-button
|
||||||
*ngIf="canEditMaterial"
|
*ngIf="canEditMaterial"
|
||||||
class="ml-3"
|
class="ml-3"
|
||||||
mat-raised-button
|
|
||||||
color="accent"
|
|
||||||
routerLink="/catalog/material/add">
|
routerLink="/catalog/material/add">
|
||||||
Ajouter
|
Ajouter
|
||||||
</button>
|
</cre-accent-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -51,19 +38,18 @@
|
||||||
</p>
|
</p>
|
||||||
</cre-warning-alert>
|
</cre-warning-alert>
|
||||||
|
|
||||||
<table
|
<cre-table
|
||||||
*ngIf="materials.length > 0"
|
*ngIf="materials.length > 0"
|
||||||
mat-table
|
|
||||||
matSort
|
|
||||||
class="mx-auto"
|
class="mx-auto"
|
||||||
[dataSource]="dataSource">
|
[data]="dataSource"
|
||||||
|
[columns]="columns">
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="name">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Code</th>
|
<th mat-header-cell *matHeaderCellDef>Code</th> <!-- mat-sort-header -->
|
||||||
<td mat-cell *matCellDef="let material">{{material.name}}</td>
|
<td mat-cell *matCellDef="let material">{{material.name}}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="materialType">
|
<ng-container matColumnDef="materialType">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Type de produit</th>
|
<th mat-header-cell *matHeaderCellDef>Type de produit</th> <!-- mat-sort-header -->
|
||||||
<td mat-cell *matCellDef="let material">{{material.materialType.name}}</td>
|
<td mat-cell *matCellDef="let material">{{material.materialType.name}}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
@ -75,9 +61,7 @@
|
||||||
<ng-container matColumnDef="addQuantity">
|
<ng-container matColumnDef="addQuantity">
|
||||||
<th mat-header-cell *matHeaderCellDef></th>
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
<td mat-cell [class.disabled]="!canAddToInventory" *matCellDef="let material; let i = index">
|
<td mat-cell [class.disabled]="!canAddToInventory" *matCellDef="let material; let i = index">
|
||||||
<div
|
<div [creInteractiveCell]="i" class="input-group">
|
||||||
[hidden]="!((!hoveredMaterial && i === 0) || (hoveredMaterial === material) || (selectedMaterial && selectedMaterial === material))"
|
|
||||||
class="input-group">
|
|
||||||
<input
|
<input
|
||||||
#addQuantityInput
|
#addQuantityInput
|
||||||
class="form-control w-50"
|
class="form-control w-50"
|
||||||
|
@ -98,7 +82,7 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="lowQuantityIcon">
|
<ng-container matColumnDef="lowQuantityIcon">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header></th>
|
<th mat-header-cell *matHeaderCellDef></th> <!-- mat-sort-header -->
|
||||||
<td mat-cell *matCellDef="let material" [class.disabled]="!isLowQuantity(material)">
|
<td mat-cell *matCellDef="let material" [class.disabled]="!isLowQuantity(material)">
|
||||||
<mat-icon
|
<mat-icon
|
||||||
svgIcon="format-color-fill"
|
svgIcon="format-color-fill"
|
||||||
|
@ -122,37 +106,23 @@
|
||||||
<ng-container matColumnDef="editButton">
|
<ng-container matColumnDef="editButton">
|
||||||
<th mat-header-cell *matHeaderCellDef></th>
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
<td mat-cell *matCellDef="let material; let i = index" [class.disabled]="!canEditMaterial">
|
<td mat-cell *matCellDef="let material; let i = index" [class.disabled]="!canEditMaterial">
|
||||||
<ng-container *ngIf="(!hoveredMaterial && i === 0) || hoveredMaterial === material">
|
<cre-accent-button
|
||||||
<button
|
[creInteractiveCell]="i"
|
||||||
mat-raised-button
|
routerLink="/catalog/material/edit/{{material.id}}">
|
||||||
color="accent"
|
Modifier
|
||||||
routerLink="/catalog/material/edit/{{material.id}}">
|
</cre-accent-button>
|
||||||
Modifier
|
|
||||||
</button>
|
|
||||||
</ng-container>
|
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="openSimdutButton">
|
<ng-container matColumnDef="openSimdutButton">
|
||||||
<th mat-header-cell *matHeaderCellDef></th>
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
<td mat-cell *matCellDef="let material; let i = index" [class.disabled]="canEditMaterial">
|
<td mat-cell *matCellDef="let material; let i = index" [class.disabled]="canEditMaterial">
|
||||||
<ng-container *ngIf="(!hoveredMaterial && i === 0) || hoveredMaterial === material">
|
<cre-accent-button
|
||||||
<button
|
[creInteractiveCell]="i"
|
||||||
mat-raised-button
|
[disabled]="!materialHasSimdut(material)"
|
||||||
color="accent"
|
(click)="openSimdut(material)">
|
||||||
[disabled]="!materialHasSimdut(material)"
|
Fiche signalitique
|
||||||
(click)="openSimdut(material)">
|
</cre-accent-button>
|
||||||
Fiche signalitique
|
|
||||||
</button>
|
|
||||||
</ng-container>
|
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
</cre-table>
|
||||||
<tr mat-header-row *matHeaderRowDef="columns"></tr>
|
|
||||||
<tr
|
|
||||||
mat-row
|
|
||||||
class="entity-row"
|
|
||||||
*matRowDef="let material; columns: columns"
|
|
||||||
(mouseover)="hoveredMaterial = material">
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
.input-group-append button
|
|
||||||
border-radius: 0 4px 4px 0
|
|
||||||
|
|
||||||
mat-select
|
mat-select
|
||||||
margin-top: 4px
|
margin-top: 4px
|
||||||
|
|
||||||
.form-control
|
.input-group
|
||||||
width: 6rem
|
cre-input
|
||||||
|
width: 6rem
|
||||||
|
|
||||||
|
.input-group-append button
|
||||||
|
border-radius: 0 4px 4px 0
|
||||||
|
|
|
@ -12,6 +12,9 @@ import {MatTableDataSource} from '@angular/material/table'
|
||||||
import {MaterialTypeService} from '../../../material-type/service/material-type.service'
|
import {MaterialTypeService} from '../../../material-type/service/material-type.service'
|
||||||
import {InventoryService} from '../../service/inventory.service'
|
import {InventoryService} from '../../service/inventory.service'
|
||||||
import {AppState} from '../../../shared/app-state'
|
import {AppState} from '../../../shared/app-state'
|
||||||
|
import {FormControl} from '@angular/forms'
|
||||||
|
import {map} from 'rxjs/operators'
|
||||||
|
import {CreInputEntry} from '../../../shared/components/inputs/inputs'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'cre-list',
|
selector: 'cre-list',
|
||||||
|
@ -22,7 +25,9 @@ export class InventoryComponent extends ErrorHandlingComponent {
|
||||||
@ViewChild(MatSort) sort: MatSort
|
@ViewChild(MatSort) sort: MatSort
|
||||||
|
|
||||||
materials: Material[] | null = []
|
materials: Material[] | null = []
|
||||||
materialTypes$ = this.materialTypeService.all
|
materialTypesEntries$ = this.materialTypeService.all.pipe(map(materialTypes => {
|
||||||
|
return materialTypes.map(materialType => new CreInputEntry(materialType.id, materialType.name))
|
||||||
|
}))
|
||||||
dataSource: MatTableDataSource<Material>
|
dataSource: MatTableDataSource<Material>
|
||||||
|
|
||||||
columns = ['name', 'materialType', 'quantity', 'addQuantity', 'lowQuantityIcon', 'simdutIcon', 'editButton', 'openSimdutButton']
|
columns = ['name', 'materialType', 'quantity', 'addQuantity', 'lowQuantityIcon', 'simdutIcon', 'editButton', 'openSimdutButton']
|
||||||
|
@ -31,8 +36,12 @@ export class InventoryComponent extends ErrorHandlingComponent {
|
||||||
|
|
||||||
units = UNIT_MILLILITER
|
units = UNIT_MILLILITER
|
||||||
lowQuantityThreshold = 100 // TEMPORARY will be in the application settings
|
lowQuantityThreshold = 100 // TEMPORARY will be in the application settings
|
||||||
materialTypeFilter = 1
|
|
||||||
materialNameFilter = ''
|
materialTypeFilterControl = new FormControl()
|
||||||
|
materialNameFilterControl = new FormControl()
|
||||||
|
|
||||||
|
private materialTypeFilter = 1
|
||||||
|
private materialNameFilter = ''
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private materialService: MaterialService,
|
private materialService: MaterialService,
|
||||||
|
@ -60,6 +69,16 @@ export class InventoryComponent extends ErrorHandlingComponent {
|
||||||
true,
|
true,
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
this.subscribe(
|
||||||
|
this.materialTypeFilterControl.valueChanges,
|
||||||
|
filter => this.materialTypeFilter = filter
|
||||||
|
)
|
||||||
|
|
||||||
|
this.subscribe(
|
||||||
|
this.materialNameFilterControl.valueChanges,
|
||||||
|
filter => this.materialNameFilter = filter
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
setupDataSource(): MatTableDataSource<Material> {
|
setupDataSource(): MatTableDataSource<Material> {
|
||||||
|
@ -83,10 +102,6 @@ export class InventoryComponent extends ErrorHandlingComponent {
|
||||||
return this.dataSource
|
return this.dataSource
|
||||||
}
|
}
|
||||||
|
|
||||||
filterDataSource() {
|
|
||||||
this.dataSource.filter = 'filter'
|
|
||||||
}
|
|
||||||
|
|
||||||
isLowQuantity(material: Material) {
|
isLowQuantity(material: Material) {
|
||||||
return this.getQuantity(material) < this.lowQuantityThreshold
|
return this.getQuantity(material) < this.lowQuantityThreshold
|
||||||
}
|
}
|
||||||
|
@ -118,6 +133,11 @@ export class InventoryComponent extends ErrorHandlingComponent {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get filter(): string {
|
||||||
|
// Uses private UTF-8 char to separate the two fields, change if a better method is found
|
||||||
|
return `${this.materialTypeFilter}${this.materialNameFilter}`
|
||||||
|
}
|
||||||
|
|
||||||
get canEditMaterial(): boolean {
|
get canEditMaterial(): boolean {
|
||||||
return this.accountService.hasPermission(Permission.EDIT_MATERIALS)
|
return this.accountService.hasPermission(Permission.EDIT_MATERIALS)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ import {
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import {MatColumnDef, MatHeaderRowDef, MatRowDef, MatTable, MatTableDataSource} from '@angular/material/table'
|
import {MatColumnDef, MatHeaderRowDef, MatRowDef, MatTable, MatTableDataSource} from '@angular/material/table'
|
||||||
|
|
||||||
|
type CreTableData<T> = T[] | MatTableDataSource<T>
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[creInteractiveCell]'
|
selector: '[creInteractiveCell]'
|
||||||
})
|
})
|
||||||
|
@ -66,7 +68,7 @@ export class CreTable<T> implements AfterContentInit {
|
||||||
this.dataSource.filter = filter
|
this.dataSource.filter = filter
|
||||||
}
|
}
|
||||||
|
|
||||||
@Input() set data(data: T[]) {
|
@Input() set data(data: CreTableData<T>) {
|
||||||
this.setupDataSource(data)
|
this.setupDataSource(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +82,16 @@ export class CreTable<T> implements AfterContentInit {
|
||||||
this.headerRowDefs.forEach(headerRowDef => this.table.addHeaderRowDef(headerRowDef))
|
this.headerRowDefs.forEach(headerRowDef => this.table.addHeaderRowDef(headerRowDef))
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupDataSource(data: T[]) {
|
private setupDataSource(data: CreTableData<T>) {
|
||||||
this.dataSource = new MatTableDataSource<T>(data)
|
if (data instanceof MatTableDataSource) {
|
||||||
this.dataSource.filterPredicate = (t, filter) => this.filterFn(t, filter)
|
this.dataSource = data
|
||||||
|
} else {
|
||||||
|
this.dataSource = new MatTableDataSource<T>(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.filterFn) {
|
||||||
|
this.dataSource.filterPredicate = (t, filter) => this.filterFn(t, filter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onRowHover(index: number) {
|
onRowHover(index: number) {
|
||||||
|
|
Loading…
Reference in New Issue