Commit 258c71a3 authored by Juraj Fiala's avatar Juraj Fiala
Browse files

feat: Update agent visuals

parent 09d60769
Pipeline #142524 failed with stage
in 8 seconds
<div *ngIf="state === requestState.ERROR">
Error occured: {{ errorMessage }}
</div>
<div *ngIf="agent && state === requestState.SUCCESS" class="px-4">
<div class="flex">
<span class="text-4xl text-black mb-4">{{ agent.name }}</span>
<button
mat-icon-button
routerLink="../edit/{{ agent.id }}"
class="justify-end"
>
<mat-icon>edit</mat-icon>
</button>
</div>
<mat-toolbar *ngIf="agent" color="primary" class="flex flex-row">
<button mat-icon-button routerLink="/auth/agents" aria-label="Go back">
<mat-icon>arrow_back</mat-icon>
</button>
<br />
<span class="text-md">Training</span>
<p class="mb-4 border-b-[1xp] border-gray-200 text-lg">
{{ agent.training }}
</p>
<span>Agent detail</span>
<table mat-table [dataSource]="agent.codeNames" class="pb-4 w-full">
<ng-container matColumnDef="codename">
<th mat-header-cell *matHeaderCellDef class="text-lg text-black">
Codenames
</th>
<td mat-cell *matCellDef="let codename" class="text-gray-700">
{{ codename.codeName }}
</td>
</ng-container>
<span class="flex-1"></span>
<tr mat-header-row *matHeaderRowDef="codenameColumns"></tr>
<tr mat-row *matRowDef="let row; columns: codenameColumns"></tr>
</table>
<button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Example icon-button with a menu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item>Delete</button>
</mat-menu>
</mat-toolbar>
<table
mat-table
[dataSource]="agent.skills"
class="pb-6 text-gray-700 w-full"
>
<ng-container matColumnDef="skill">
<th mat-header-cell *matHeaderCellDef class="text-lg text-black">
Skills
</th>
<td mat-cell *matCellDef="let skill">{{ skill.name }}</td>
</ng-container>
<div *ngIf="state === requestState.ERROR">
Error occured: {{ errorMessage }}
</div>
<tr mat-header-row *matHeaderRowDef="skillColumns"></tr>
<tr mat-row *matRowDef="let row; columns: skillColumns"></tr>
</table>
<div *ngIf="agent && state === requestState.SUCCESS" class="main-container">
<div class="pl-6 text-lg text-black">Assignments</div>
<table
mat-table
[dataSource]="agent.agentAssignments"
class="pb-6 w-full text-gray-700"
>
<ng-container matColumnDef="missionName">
<th mat-header-cell *matHeaderCellDef class="text-black">Mission</th>
<td mat-cell *matCellDef="let assignment">
{{ assignment.mission.name }}
</td>
</ng-container>
<div class="px-4">
<h1>{{ agent.name }}</h1>
<ng-container matColumnDef="start">
<th mat-header-cell *matHeaderCellDef class="text-black">Start</th>
<td mat-cell *matCellDef="let assignment">{{ assignment.start }}</td>
</ng-container>
<h4 class="!m-0">Training</h4>
<p>{{ agent.training }}</p>
</div>
<tr mat-header-row *matHeaderRowDef="assignmentColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: assignmentColumns"
routerLink="/auth/assignment/{{ row.id }}"
class="hover:bg-gray-200 hover:cursor-pointer"
></tr>
</table>
<mat-list>
<div mat-subheader>Codenames</div>
<mat-list-item *ngFor="let codeName of agent.codeNames">
<mat-icon mat-list-icon>badge</mat-icon>
<h2 mat-line> {{codeName.codeName}} </h2>
</mat-list-item>
<mat-divider></mat-divider>
<div mat-subheader>Skills</div>
<mat-list-item *ngFor="let skill of agent.skills">
<mat-icon mat-list-icon>plumbing</mat-icon>
<h2 mat-line> {{skill.name}} </h2>
</mat-list-item>
<mat-divider></mat-divider>
<div mat-subheader>Assignments</div>
<mat-list-item *ngFor="let assignment of agent.agentAssignments">
<mat-icon mat-list-icon>assignment</mat-icon>
<div mat-line>{{ assignment.mission.name }} </div>
<div mat-line>{{ assignment.start }} ({{ assignment.durationInDays }} days)</div>
</mat-list-item>
</mat-list>
<button color="accent" mat-fab routerLink="../edit/{{ agent.id }}" class="!fixed right-8 bottom-20"
aria-label="Edit country details">
<mat-icon>edit</mat-icon>
</button>
</div>
<div *ngIf="state === requestState.ERROR">
Error occured: {{ errorMessage }}
</div>
<div *ngIf="state === requestState.SUCCESS">
<mat-form-field appearance="fill">
<mat-label>State</mat-label>
<mat-select #filterCountry>
<mat-option *ngFor="let country of countries" [value]="country">{{
country.name
}}</mat-option>
</mat-select>
</mat-form-field>
<div *ngIf="state === requestState.SUCCESS" class="main-container">
<div class="flex flex-col px-4">
<button mat-raised-button routerLink="../agent/create">Create agent</button>
<mat-form-field>
<mat-form-field class="example-chip-list" appearance="fill">
<mat-label>Filter by skills</mat-label>
<mat-chip-list #chipList aria-label="Fruit selection">
<mat-chip *ngFor="let skill of filterSkills" (removed)="remove(skill)">
{{ skill.name }}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
</mat-chip>
<input
placeholder="Skill ..."
#fruitInput
[formControl]="fruitCtrl"
[matAutocomplete]="auto"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
(matChipInputTokenEnd)="add($event)"
/>
</mat-chip-list>
<mat-autocomplete
#auto="matAutocomplete"
(optionSelected)="selected($event)"
>
<mat-option *ngFor="let skill of filteredSkills | async" [value]="skill">
{{ skill.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<mat-label>Filter by state</mat-label>
<mat-select #filterCountry (valueChange)="filter(filterCountry.value)">
<mat-option>Any</mat-option>
<mat-option *ngFor="let country of countries" [value]="country">
{{ country.name }}
</mat-option>
</mat-select>
</mat-form-field>
<button mat-raised-button (click)="filter(filterCountry.value)">
Filter
</button>
<mat-form-field>
<mat-label>Filter by skills</mat-label>
<mat-chip-list #chipList aria-label="Fruit selection">
<mat-chip *ngFor="let skill of filterSkills" (removed)="remove(skill); filter(filterCountry.value)">
{{ skill.name }}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
</mat-chip>
<input placeholder="Skill…" #fruitInput [formControl]="fruitCtrl" [matAutocomplete]="auto"
[matChipInputFor]="chipList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
(matChipInputTokenEnd)="add($event)" />
</mat-chip-list>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let skill of filteredSkills | async" [value]="skill">
{{ skill.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
<mat-divider></mat-divider>
<table mat-table [dataSource]="agents" class="w-full">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let agent">
{{ agent.name }}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="agentColumns"></tr>
<tr
mat-row
class="hover:bg-gray-200"
routerLink="../agent/{{ row.id }}"
*matRowDef="let row; columns: agentColumns"
></tr>
</table>
<mat-action-list>
<mat-list-item *ngFor="let agent of agents" [routerLink]="['/auth/agent/', agent.id]">
<h2 mat-line> {{agent.name}} </h2>
<p mat-line>A.K.A. <span *ngFor="let codeName of agent.codeNames"> {{codeName.codeName}}, </span></p>
<mat-divider></mat-divider>
</mat-list-item>
</mat-action-list>
</div>
<button mat-fab color="accent" class="!fixed right-8 bottom-20" routerLink="../agent/create"
aria-label="Create new agent">
<mat-icon>add</mat-icon>
</button>
import { COMMA, ENTER } from '@angular/cdk/keycodes';
import { HttpClient } from '@angular/common/http';
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { FormControl } from '@angular/forms';
import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
import { MatChipInputEvent } from '@angular/material/chips';
......@@ -26,7 +26,9 @@ interface Country {
selector: 'agent-list',
templateUrl: 'agent-list.component.html',
})
export class AgentListComponent implements OnInit {
export class AgentListComponent implements OnInit, AfterViewInit {
@ViewChild("filterCountry", {read: ElementRef}) filterCountryElem!: ElementRef;
// Big spaghetti, I don't know what I am doing.
requestState = RequestState;
state: RequestState = this.requestState.PENDING;
......@@ -44,6 +46,7 @@ export class AgentListComponent implements OnInit {
filterSkills: Skill[] = [];
allSkills: Skill[] = [];
constructor(private httpClient: HttpClient, private router: Router) {
this.filteredSkills = this.fruitCtrl.valueChanges.pipe(
startWith(null),
......@@ -53,13 +56,19 @@ export class AgentListComponent implements OnInit {
);
}
ngAfterViewInit() {
this.fruitCtrl.valueChanges.subscribe(() => {
this.filter(this.filterCountryElem.nativeElement.value)
});
}
@ViewChild('fruitInput') fruitInput: ElementRef<HTMLInputElement> | undefined;
add(event: MatChipInputEvent): void {
const value = (event.value || '').trim();
const toAdd = this.allSkills.filter((skill) => skill.name === value)[0];
// Add our fruit
// Add our skills
if (toAdd) {
this.filterSkills.push(toAdd);
}
......@@ -68,10 +77,13 @@ export class AgentListComponent implements OnInit {
event.chipInput!.clear();
this.fruitCtrl.setValue(null);
console.log(this.filterCountryElem.nativeElement.value)
console.log("was here")
this.filter(this.filterCountryElem.nativeElement.value)
}
remove(fruit: Skill): void {
const index = this.filterSkills.indexOf(fruit);
remove(skill: Skill): void {
const index = this.filterSkills.indexOf(skill);
if (index >= 0) {
this.filterSkills.splice(index, 1);
......@@ -134,6 +146,10 @@ export class AgentListComponent implements OnInit {
throw err;
}
this.state = this.requestState.SUCCESS;
// this.chipList.nativeElement.valueChanges.subscribe(() => {
// this.filter(this.filterCountryElem.nativeElement.value)
// });
}
async getAgents(query: string) {
......
<div *ngIf="agent">
<form [formGroup]="edit">
<mat-toolbar *ngIf="agent" color="primary" class="flex flex-row">
<button mat-icon-button routerLink="/auth/agents" aria-label="Cancel editing">
<mat-icon>close</mat-icon>
</button>
<span>Edit agent</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="agent" class="main-container">
<form [formGroup]="edit" class="flex flex-col px-4">
<mat-form-field>
<mat-label>Agent name</mat-label>
<input matInput formControlName="name" />
......@@ -7,81 +24,72 @@
</mat-form-field>
<mat-form-field>
<mat-label>Training</mat-label>
<textarea matInput formControlName="training"></textarea>
<mat-label>Role</mat-label>
<mat-select [(value)]="selectedRole">
<mat-option *ngFor="let role of roles" [value]="role">
{{ role }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>Password</mat-label>
<input matInput formControlName="password" />
<input matInput formControlName="password" type="password" />
<mat-error>Must be at least 6 characters long</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>Training</mat-label>
<textarea matInput formControlName="training"></textarea>
</mat-form-field>
</form>
<mat-form-field>
<mat-label>New skill</mat-label>
<input matInput #newSkill />
</mat-form-field>
<button mat-icon-button (click)="addSkill(newSkill.value)">
<mat-icon>add</mat-icon>
</button>
<mat-divider></mat-divider>
<mat-form-field>
<mat-label>New codename</mat-label>
<input matInput #newCodename />
</mat-form-field>
<button mat-icon-button (click)="addCodename(newCodename.value)">
<mat-icon>add</mat-icon>
</button>
<mat-list>
<div mat-subheader>Codenames</div>
<mat-list-item *ngFor="let codeName of agent.codeNames">
<mat-icon mat-list-icon>badge</mat-icon>
<h2 mat-line> {{codeName.codeName}} </h2>
</mat-list-item>
<mat-form-field appearance="fill">
<mat-label>Favorite food</mat-label>
<mat-select [(value)]="selectedRole">
<mat-option *ngFor="let role of roles" [value]="role">
{{ role }}
</mat-option>
</mat-select>
</mat-form-field>
<table mat-table [dataSource]="agent.codeNames" class="pb-4 w-full">
<ng-container matColumnDef="codename">
<th mat-header-cell *matHeaderCellDef class="text-lg text-black">
Codenames
</th>
<td mat-cell *matCellDef="let codename" class="text-gray-700">
{{ codename.codeName }}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="codenameColumns"></tr>
<tr mat-row *matRowDef="let row; columns: codenameColumns"></tr>
</table>
<table
mat-table
[dataSource]="agent.skills"
class="pb-6 text-gray-700 w-full"
>
<ng-container matColumnDef="skill">
<th mat-header-cell *matHeaderCellDef class="text-lg text-black">
Skills
</th>
<td mat-cell *matCellDef="let skill">{{ skill.name }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="skillColumns"></tr>
<tr mat-row *matRowDef="let row; columns: skillColumns"></tr>
</table>
<button class="ml-4" mat-raised-button routerLink="auth/agents">
Cancel
</button>
<button
class="mr-4"
mat-raised-button
disabled="{{ !edit.valid }}"
(click)="saveAgent()"
>
Save
<mat-list-item>
<mat-icon mat-list-icon></mat-icon>
<mat-form-field mat-line>
<mat-label>New codename</mat-label>
<input matInput #newCodename />
</mat-form-field>
<button mat-icon-button (click)="addCodename(newCodename)">
<mat-icon>add</mat-icon>
</button>
</mat-list-item>
<mat-divider></mat-divider>
<div mat-subheader>Skills</div>
<mat-list-item *ngFor="let skill of agent.skills">
<mat-icon mat-list-icon>plumbing</mat-icon>
<h2 mat-line> {{skill.name}} </h2>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon></mat-icon>
<mat-form-field mat-line>
<mat-label>Add skill</mat-label>
<input matInput #newSkill />
</mat-form-field>
<button mat-icon-button (click)="addSkill(newSkill)">
<mat-icon>add</mat-icon>
</button>
</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<button color="accent" mat-fab class="!fixed right-8 bottom-20" aria-label="Save agent details"
disabled="{{ !edit.valid }}" (click)="saveAgent()">
<mat-icon>done</mat-icon>
</button>
</div>
......@@ -70,7 +70,9 @@ export class EditAgentComponent implements OnInit {
}
}
addCodename(newCodename: string) {
addCodename(input: HTMLInputElement) {
const newCodename = input.value
if (!newCodename || newCodename.length === 0) {
return;
}
......@@ -79,9 +81,13 @@ export class EditAgentComponent implements OnInit {
}
this.agent!.codeNames.push({ codeName: newCodename });
this.agent!.codeNames = [...this.agent!.codeNames];
input.value = ""
}
addSkill(newSkill: string) {
addSkill(input: HTMLInputElement) {
const newSkill = input.value
if (!newSkill || newSkill.length === 0) {
return;
}
......@@ -90,6 +96,8 @@ export class EditAgentComponent implements OnInit {
}
this.agent!.skills.push({ name: newSkill });
this.agent!.skills = [...this.agent!.skills];
input.value = ""
}
async saveAgent() {
......
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