Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Jan Smejkal
Pa165 Secret Archive
Commits
258c71a3
Commit
258c71a3
authored
May 25, 2022
by
Juraj Fiala
Browse files
feat: Update agent visuals
parent
09d60769
Pipeline
#142524
failed with stage
in 8 seconds
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
frontend/src/app/agent/agent-detail.component.html
View file @
258c71a3
<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>
frontend/src/app/agent/agent-list.component.html
View file @
258c71a3
<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>
frontend/src/app/agent/agent-list.component.ts
View file @
258c71a3
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
)
{
...
...
frontend/src/app/agent/edit-agent.component.html
View file @
258c71a3
<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>
frontend/src/app/agent/edit-agent.component.ts
View file @
258c71a3
...
...
@@ -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
()
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment