Commit e2713f80 authored by Juraj Fiala's avatar Juraj Fiala
Browse files

feat: Add creating/editing countries

parent a8639a58
...@@ -11,6 +11,7 @@ import { AgentListGuard } from './auth/agent-list.guard'; ...@@ -11,6 +11,7 @@ import { AgentListGuard } from './auth/agent-list.guard';
import { AuthComponent } from './auth/auth.component'; import { AuthComponent } from './auth/auth.component';
import { AuthGuard } from './auth/auth.guard'; import { AuthGuard } from './auth/auth.guard';
import { CountryDetailComponent } from './country/country-detail.component'; import { CountryDetailComponent } from './country/country-detail.component';
import { CountryEditComponent } from './country/country-edit.component';
import { CountryListComponent } from './country/country-list.component'; import { CountryListComponent } from './country/country-list.component';
import { HomeComponent } from './home/home.component'; import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component'; import { LoginComponent } from './login/login.component';
...@@ -45,6 +46,8 @@ const routes: Routes = [ ...@@ -45,6 +46,8 @@ const routes: Routes = [
{ path: 'agents', component: AgentListComponent , { path: 'agents', component: AgentListComponent ,
canActivate: [AgentListGuard], canActivate: [AgentListGuard],
}, },
{ path: 'country/edit/:id', component: CountryEditComponent },
{ path: 'country/create', component: CountryEditComponent },
{ path: 'countries', component: CountryListComponent }, { path: 'countries', component: CountryListComponent },
{ path: 'country/:id', component: CountryDetailComponent }, { path: 'country/:id', component: CountryDetailComponent },
{ path: 'mission/:id', component: MissionDetailComponent }, { path: 'mission/:id', component: MissionDetailComponent },
......
...@@ -27,6 +27,7 @@ import { AssignmentDetailComponent } from './assignment/assignment-detail.compon ...@@ -27,6 +27,7 @@ import { AssignmentDetailComponent } from './assignment/assignment-detail.compon
import { AuthComponent } from './auth/auth.component'; import { AuthComponent } from './auth/auth.component';
import { CountryDetailComponent } from './country/country-detail.component'; import { CountryDetailComponent } from './country/country-detail.component';
import { CountryListComponent } from './country/country-list.component'; import { CountryListComponent } from './country/country-list.component';
import { CountryEditComponent } from './country/country-edit.component';
import { HomeComponent } from './home/home.component'; import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component'; import { LoginComponent } from './login/login.component';
import { MissionDetailComponent } from './mission/mission-detail.component'; import { MissionDetailComponent } from './mission/mission-detail.component';
...@@ -46,6 +47,7 @@ import {AssignmentListComponent} from "./assignment/assignment-list.component"; ...@@ -46,6 +47,7 @@ import {AssignmentListComponent} from "./assignment/assignment-list.component";
EditAgentComponent, EditAgentComponent,
CountryListComponent, CountryListComponent,
CountryDetailComponent, CountryDetailComponent,
CountryEditComponent,
MissionListComponent, MissionListComponent,
MissionDetailComponent, MissionDetailComponent,
HomeComponent, HomeComponent,
......
...@@ -18,8 +18,7 @@ ...@@ -18,8 +18,7 @@
<div *ngIf="state === requestState.ERROR"> <div *ngIf="state === requestState.ERROR">
Error occured: {{ errorMessage }} Error occured: {{ errorMessage }}
</div> </div>
<div *ngIf="country && state === requestState.SUCCESS" class="main-container"> <div *ngIf="country && state === requestState.SUCCESS" class="main-container px-4">
<div *ngIf="!editing"> <div *ngIf="!editing">
<h1>{{ country.name}}</h1> <h1>{{ country.name}}</h1>
...@@ -90,7 +89,7 @@ ...@@ -90,7 +89,7 @@
</mat-form-field> </mat-form-field>
</div> </div>
<button color="accent" *ngIf="!editing" mat-fab (click)="setEditing(true)" class="!fixed right-8 bottom-20" <button color="accent" mat-fab routerLink="../edit/{{ country.id }}" class="!fixed right-8 bottom-20"
aria-label="Example icon button with a delete icon"> aria-label="Example icon button with a delete icon">
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
</button> </button>
......
<mat-toolbar *ngIf="country" color="primary" class="flex flex-row">
<button mat-icon-button [routerLink]="country.id ? ['/auth/country/', country.id] : '/auth/countries'" aria-label="Cancel editing">
<mat-icon>close</mat-icon>
</button>
<span *ngIf="this.creatingNew">Create country</span>
<span *ngIf="!this.creatingNew">Edit country</span>
<span class="flex-1"></span>
<button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Menu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item>Delete</button>
</mat-menu>
</mat-toolbar>
<div *ngIf="country" class="main-container">
<form [formGroup]="edit" class="flex flex-col px-4">
<mat-form-field>
<mat-label>Name</mat-label>
<input matInput formControlName="name" [(ngModel)]="country.name" />
</mat-form-field>
<mat-form-field>
<mat-label>Code</mat-label>
<input matInput formControlName="code" [(ngModel)]="country.code">
</mat-form-field>
<mat-form-field>
<mat-label>Demographics</mat-label>
<textarea matInput formControlName="demographics" [(ngModel)]="country.demographics"></textarea>
</mat-form-field>
<mat-form-field>
<mat-label>Geography</mat-label>
<textarea matInput formControlName="geography" [(ngModel)]="country.geography"></textarea>
</mat-form-field>
<mat-form-field>
<mat-label>Communications</mat-label>
<textarea matInput formControlName="communications" [(ngModel)]="country.communications"></textarea>
</mat-form-field>
<mat-form-field>
<mat-label>Government</mat-label>
<textarea matInput formControlName="government" [(ngModel)]="country.government"></textarea>
</mat-form-field>
<mat-form-field>
<mat-label>Economy</mat-label>
<textarea matInput formControlName="economy" [(ngModel)]="country.economy"></textarea>
</mat-form-field>
<mat-form-field>
<mat-label>Military</mat-label>
<textarea matInput formControlName="military" [(ngModel)]="country.military"></textarea>
</mat-form-field>
<!-- -->
</form>
<mat-divider></mat-divider>
<button color="accent" mat-fab class="!fixed right-8 bottom-20" aria-label="Save country details"
disabled="{{ !edit.valid }}" (click)="save()">
<mat-icon>done</mat-icon>
</button>
</div>
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { firstValueFrom } from 'rxjs';
import { environment } from 'src/environments/environment';
import { RequestState } from '../request-state.enum';
import { Country } from './country.interface';
@Component({
selector: 'country-edit',
templateUrl: 'country-edit.component.html',
})
export class CountryEditComponent implements OnInit {
country: Country = {
id: '',
code: '',
name: '',
demographics: '',
geography: '',
communications: '',
government: '',
economy: '',
military: '',
missionsIds: []
};
state: RequestState = RequestState.SUCCESS;
errorMessage: String = '';
edit = new FormGroup({
name: new FormControl('', [
Validators.pattern(/[a-zA-Z]{3,}/),
Validators.required,
]),
code: new FormControl(''),
demographics: new FormControl(''),
geography: new FormControl(''),
communications: new FormControl(''),
government: new FormControl(''),
economy: new FormControl(''),
military: new FormControl(''),
});
creatingNew = false;
constructor(
private httpClient: HttpClient,
private route: ActivatedRoute,
private router: Router
) {}
async ngOnInit() {
const id = this.route.snapshot.params['id'];
if (id) {
this.creatingNew = false;
try {
this.state = RequestState.PENDING;
this.country = await firstValueFrom(
this.httpClient.get<Country>(`${environment.apiUrl}/countries/${id}`)
);
this.country.id = id
this.edit.patchValue({
name: this.country.name,
code: this.country.code ?? '',
demographics: this.country.demographics ?? '',
geography: this.country.geography ?? '',
communications: this.country.communications ?? '',
government: this.country.government ?? '',
economy: this.country.economy ?? '',
military: this.country.military ?? '',
});
this.state = RequestState.SUCCESS;
} catch (error) {
this.errorMessage = 'Loading agent failed';
this.state = RequestState.ERROR;
}
} else {
this.creatingNew = true;
}
}
async save() {
this.country.name = this.edit.get('name')?.value;
this.country.code = this.edit.get('code')?.value;
this.country.demographics = this.edit.get('demographics')?.value;
this.country.geography = this.edit.get('geography')?.value;
this.country.communications = this.edit.get('communications')?.value;
this.country.government = this.edit.get('government')?.value;
this.country.economy = this.edit.get('economy')?.value;
this.country.military = this.edit.get('military')?.value;
if (this.creatingNew) {
this.country = await firstValueFrom(
this.httpClient.post<Country>(`${environment.apiUrl}/countries`, this.country)
);
this.router.navigate(['auth', 'countries']);
} else {
await firstValueFrom(
this.httpClient.put<Country>(
`${environment.apiUrl}/countries/${this.country.id}`,
this.country
)
);
this.router.navigate(['auth', 'country', this.country.id]);
}
}
}
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
</mat-list-item> </mat-list-item>
</mat-action-list> </mat-action-list>
<button mat-fab color="accent" class="!fixed right-8 bottom-20" aria-label="Example icon button with a delete icon"> <button mat-fab color="accent" class="!fixed right-8 bottom-20" routerLink="../country/create" aria-label="Create new country">
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
</button> </button>
</div> </div>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment