This commit is contained in:
parent
d2225ad6b0
commit
0a78aeece3
4 changed files with 256 additions and 3 deletions
|
@ -1,4 +1,10 @@
|
||||||
import {Routes} from '@angular/router';
|
import { Routes } from '@angular/router';
|
||||||
import {DashboardComponent} from '@app/views/dashboard/dashboard.component';
|
import { DashboardComponent } from '@app/views/dashboard/dashboard.component';
|
||||||
|
|
||||||
export const routes: Routes = [{path: '', component: DashboardComponent, title: 'Home'}];
|
import { EmployeeDetailComponent } from './views/employee-detail/employee-detail.component';
|
||||||
|
|
||||||
|
export const routes: Routes = [
|
||||||
|
{ path: '', component: DashboardComponent, title: 'Home' },
|
||||||
|
{ path: 'employee/new', component: EmployeeDetailComponent, title: 'New Employee' },
|
||||||
|
{ path: 'employee/:id', component: EmployeeDetailComponent, title: 'Edit Employee' }
|
||||||
|
];
|
||||||
|
|
82
src/app/views/employee-detail/employee-detail.component.html
Normal file
82
src/app/views/employee-detail/employee-detail.component.html
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
<form class="employee-detail" [formGroup]="employeeForm" appearance="outline">
|
||||||
|
<div class="employee-detail__info-view">
|
||||||
|
<div class="employee-detail__info-view__base">
|
||||||
|
<h2>Info</h2>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>First Name</mat-label>
|
||||||
|
<input matInput formControlName="firstName">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Last Name</mat-label>
|
||||||
|
<input matInput formControlName="lastName">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Postcode</mat-label>
|
||||||
|
<mat-icon matSuffix>money</mat-icon>
|
||||||
|
<input matInput formControlName="postcode">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>City</mat-label>
|
||||||
|
<mat-icon matSuffix>location_city</mat-icon>
|
||||||
|
<input matInput formControlName="city">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Street</mat-label>
|
||||||
|
<mat-icon matSuffix>house</mat-icon>
|
||||||
|
<input matInput formControlName="street">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Phone</mat-label>
|
||||||
|
<mat-icon matSuffix>phone</mat-icon>
|
||||||
|
<input matInput formControlName="phone">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="employee-detail__info-view__skills">
|
||||||
|
<h2>Skills</h2>
|
||||||
|
<div class="employee-detail__info-view__skills__action-row">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Skill</mat-label>
|
||||||
|
<mat-select [disabled]="!($unusedSkills | async)?.length">
|
||||||
|
@for (skill of ($unusedSkills|async); track skill) {
|
||||||
|
<mat-option [value]="skill.skill">{{skill.skill}}</mat-option>
|
||||||
|
}
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
<button mat-fab class="shadowless">
|
||||||
|
<mat-icon>add</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<mat-table [dataSource]="skillsDataSource">
|
||||||
|
<ng-container matColumnDef="id">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Id</th>
|
||||||
|
<td mat-cell *matCellDef="let skill">{{skill.id}}</td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="skill">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Skill</th>
|
||||||
|
<td mat-cell *matCellDef="let skill">
|
||||||
|
<p>{{skill.skill}}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="action">
|
||||||
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
|
<td mat-cell *matCellDef="let row">
|
||||||
|
<button mat-mini-fab class="warn shadowless">
|
||||||
|
<mat-icon>delete</mat-icon>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: skillsDisplayedColumns;"></tr>
|
||||||
|
</mat-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="employee-detail__action-row">
|
||||||
|
<a mat-flat-button class="abort" routerLink="/">Abort</a>
|
||||||
|
@if (isNewEmployee) {
|
||||||
|
<button mat-flat-button (click)="onCreate()">Create</button>
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
<button mat-flat-button (click)="onSave()">Save</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
82
src/app/views/employee-detail/employee-detail.component.scss
Normal file
82
src/app/views/employee-detail/employee-detail.component.scss
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
@use '@angular/material' as mat;
|
||||||
|
|
||||||
|
.employee-detail {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
&__info-view {
|
||||||
|
display: flex;
|
||||||
|
gap: 2rem;
|
||||||
|
|
||||||
|
>* {
|
||||||
|
min-width: 0;
|
||||||
|
flex-basis: 0;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__base {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-size: var(--mat-sys-body-large-size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__skills {
|
||||||
|
height: fit-content;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&__action-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
mat-form-field:first-of-type {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: var(--mat-sys-body-large-size);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr {
|
||||||
|
height: 76px;
|
||||||
|
|
||||||
|
td.mat-column-skill {
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 28px;
|
||||||
|
padding-bottom: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.mat-column-action {
|
||||||
|
width: 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
padding-left: 24px;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-of-type {
|
||||||
|
height: 66px;
|
||||||
|
|
||||||
|
td.mat-column-skill {
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.mat-column-action {
|
||||||
|
padding-top: 10px;
|
||||||
|
vertical-align: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__action-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
83
src/app/views/employee-detail/employee-detail.component.ts
Normal file
83
src/app/views/employee-detail/employee-detail.component.ts
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import { AsyncPipe } from '@angular/common';
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { MatIcon } from '@angular/material/icon';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
|
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
||||||
|
import { ActivatedRoute, RouterLink } from '@angular/router';
|
||||||
|
import { Employee, EmployeeService, Qualification, QualificationService } from '@core/ems';
|
||||||
|
import { map, Observable } from 'rxjs';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-employee-detail',
|
||||||
|
imports: [
|
||||||
|
AsyncPipe,
|
||||||
|
MatIcon,
|
||||||
|
RouterLink,
|
||||||
|
MatButtonModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatSelectModule,
|
||||||
|
MatTableModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
],
|
||||||
|
templateUrl: './employee-detail.component.html',
|
||||||
|
styleUrl: './employee-detail.component.scss'
|
||||||
|
})
|
||||||
|
export class EmployeeDetailComponent {
|
||||||
|
isNewEmployee: boolean;
|
||||||
|
employeeForm: FormGroup;
|
||||||
|
skillsDataSource: MatTableDataSource<Qualification> = new MatTableDataSource<Qualification>([]);
|
||||||
|
skillsDisplayedColumns = ['skill', 'action'];
|
||||||
|
$unusedSkills: Observable<Array<Qualification> | undefined>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private employeeService: EmployeeService,
|
||||||
|
private qualificationService: QualificationService,
|
||||||
|
private formBuilder: FormBuilder
|
||||||
|
) {
|
||||||
|
const idParam = this.route.snapshot.paramMap.get('id');
|
||||||
|
this.isNewEmployee = idParam == null;
|
||||||
|
|
||||||
|
this.employeeForm = this.formBuilder.group<Employee>({
|
||||||
|
id: 0,
|
||||||
|
firstName: '',
|
||||||
|
lastName: '',
|
||||||
|
postcode: '',
|
||||||
|
city: '',
|
||||||
|
street: '',
|
||||||
|
phone: '',
|
||||||
|
skillSet: []
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$unusedSkills = this.qualificationService.getAllQualifications();
|
||||||
|
|
||||||
|
if (this.isNewEmployee) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = parseInt(idParam as string);
|
||||||
|
this.employeeService.getEmployee({ id }).subscribe((employee) => {
|
||||||
|
this.employeeForm = this.formBuilder.group<Employee>(employee);
|
||||||
|
this.skillsDataSource = new MatTableDataSource<Qualification>(employee.skillSet);
|
||||||
|
this.$unusedSkills = this.qualificationService.getAllQualifications().pipe(
|
||||||
|
map((allSkills: Array<Qualification>) => {
|
||||||
|
const usedSkillIds = new Set(employee.skillSet.map(skill => skill.id));
|
||||||
|
return allSkills?.filter(skill => !usedSkillIds.has(skill.id));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onCreate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onSave() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue