Complete incidents functionality #97
5 changed files with 170 additions and 30 deletions
|
@ -0,0 +1,55 @@
|
||||||
|
<h2 mat-dialog-title>Edit Incident</h2>
|
||||||
|
<mat-dialog-content>
|
||||||
|
<div class="incRecord">
|
||||||
|
@let inc = inc$ | async;
|
||||||
|
@if (inc) {
|
||||||
|
<form id="incForm" [formGroup]="form" (ngSubmit)="save()">
|
||||||
|
<div>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Name</mat-label>
|
||||||
|
<input matInput name="name" type="text" formControlName="name" />
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field subscriptSizing="dynamic" class="timeFilterBox">
|
||||||
|
<mat-label>Start</mat-label>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
type="datetime-local"
|
||||||
|
name="start"
|
||||||
|
placeholder="Start time"
|
||||||
|
formControlName="start"
|
||||||
|
/>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field subscriptSizing="dynamic" class="timeFilterBox">
|
||||||
|
<mat-label>End</mat-label>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
type="datetime-local"
|
||||||
|
name="end"
|
||||||
|
placeholder="End time"
|
||||||
|
formControlName="end"
|
||||||
|
/>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field subscriptSizing="dynamic" class="descBox">
|
||||||
|
<mat-label>Description</mat-label>
|
||||||
|
<textarea
|
||||||
|
matInput
|
||||||
|
name="description"
|
||||||
|
placeholder="Description"
|
||||||
|
rows="8"
|
||||||
|
cols="200"
|
||||||
|
>{{ inc.description }}</textarea
|
||||||
|
>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
} @else {
|
||||||
|
<div class="spinner">
|
||||||
|
<mat-spinner></mat-spinner>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</mat-dialog-content>
|
||||||
|
<mat-dialog-actions>
|
||||||
|
<button mat-button type="button" (click)="cancel()">Cancel</button>
|
||||||
|
<button mat-button form="incForm" type="submit" cdkFocusInitial>Save</button>
|
||||||
|
</mat-dialog-actions>
|
|
@ -1,6 +1,9 @@
|
||||||
@let inc = inc$ | async;
|
@let inc = inc$ | async;
|
||||||
<mat-card class="incident" appearance="outlined">
|
<mat-card class="incident" appearance="outlined">
|
||||||
<h1>{{ inc?.name }}</h1>
|
<div class="cardHdr">
|
||||||
|
<h1>{{ inc?.name }}</h1>
|
||||||
|
<a (click)="editIncident(incID)"><mat-icon>edit</mat-icon></a>
|
||||||
|
</div>
|
||||||
<div class="inc-heading">
|
<div class="inc-heading">
|
||||||
<div class="field field-start field-label">Start</div>
|
<div class="field field-start field-label">Start</div>
|
||||||
<div class="field field-data field-start">
|
<div class="field field-data field-start">
|
||||||
|
|
|
@ -8,16 +8,14 @@
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inc-heading,
|
.inc-heading {
|
||||||
.inc-description {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row wrap;
|
margin-bottom: 20px;
|
||||||
flex: 1 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.inc-heading,
|
.cardHdr {
|
||||||
.inc-description {
|
display: flex;
|
||||||
margin-bottom: 30px;
|
flex-flow: row wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.field {
|
.field {
|
||||||
|
@ -30,3 +28,29 @@
|
||||||
.field-label::after {
|
.field-label::after {
|
||||||
content: ":";
|
content: ":";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cardHdr h1 {
|
||||||
|
flex: 1 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardHdr a {
|
||||||
|
flex: 0 0;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
form mat-form-field {
|
||||||
|
width: 60rem;
|
||||||
|
flex: 0 0;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.incRecord {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
|
@ -1,23 +1,7 @@
|
||||||
import { Component, computed, inject, ViewChild } from '@angular/core';
|
import { Component, computed, inject, ViewChild } from '@angular/core';
|
||||||
import { toSignal } from '@angular/core/rxjs-interop';
|
import { map, tap } from 'rxjs/operators';
|
||||||
import { debounceTime } from 'rxjs/operators';
|
|
||||||
import {
|
|
||||||
Talkgroup,
|
|
||||||
TalkgroupUpdate,
|
|
||||||
IconMap,
|
|
||||||
iconMapping,
|
|
||||||
} from '../../talkgroup';
|
|
||||||
import { COMMA, ENTER } from '@angular/cdk/keycodes';
|
|
||||||
import { TalkgroupService } from '../../talkgroups/talkgroups.service';
|
|
||||||
import {
|
|
||||||
MatAutocomplete,
|
|
||||||
MatAutocompleteModule,
|
|
||||||
MatAutocompleteSelectedEvent,
|
|
||||||
MatAutocompleteActivatedEvent,
|
|
||||||
} from '@angular/material/autocomplete';
|
|
||||||
import { CommonModule, DatePipe } from '@angular/common';
|
import { CommonModule, DatePipe } from '@angular/common';
|
||||||
import { BehaviorSubject, catchError, of, Subscription } from 'rxjs';
|
import { Subject, Subscription } from 'rxjs';
|
||||||
import { shareReplay } from 'rxjs/operators';
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import {
|
import {
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
|
@ -25,7 +9,7 @@ import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
} from '@angular/forms';
|
} from '@angular/forms';
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
|
@ -34,6 +18,63 @@ import { IncidentsService } from '../incidents.service';
|
||||||
import { IncidentRecord } from '../../incidents';
|
import { IncidentRecord } from '../../incidents';
|
||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
import { FmtDatePipe } from '../incidents.component';
|
import { FmtDatePipe } from '../incidents.component';
|
||||||
|
import {
|
||||||
|
MAT_DIALOG_DATA,
|
||||||
|
MatDialog,
|
||||||
|
MatDialogActions,
|
||||||
|
MatDialogContent,
|
||||||
|
MatDialogRef,
|
||||||
|
MatDialogTitle,
|
||||||
|
} from '@angular/material/dialog';
|
||||||
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-incident-editor',
|
||||||
|
imports: [
|
||||||
|
MatIconModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
FormsModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatCheckboxModule,
|
||||||
|
CommonModule,
|
||||||
|
MatProgressSpinnerModule,
|
||||||
|
MatDialogTitle,
|
||||||
|
MatDialogActions,
|
||||||
|
MatDialogContent,
|
||||||
|
MatButtonModule,
|
||||||
|
],
|
||||||
|
templateUrl: './incident-editor-dialog.component.html',
|
||||||
|
styleUrl: './incident.component.scss',
|
||||||
|
})
|
||||||
|
export class IncidentEditDialogComponent {
|
||||||
|
dialogRef = inject(MatDialogRef<IncidentEditDialogComponent>);
|
||||||
|
incID = inject<string>(MAT_DIALOG_DATA);
|
||||||
|
inc$!: Observable<IncidentRecord>;
|
||||||
|
form = new FormGroup({
|
||||||
|
name: new FormControl(''),
|
||||||
|
start: new FormControl(),
|
||||||
|
end: new FormControl(),
|
||||||
|
description: new FormControl(''),
|
||||||
|
});
|
||||||
|
|
||||||
|
constructor(private incSvc: IncidentsService) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.inc$ = this.incSvc.getIncident(this.incID).pipe(
|
||||||
|
tap((inc) => {
|
||||||
|
this.form.patchValue(inc);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {}
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-incident',
|
selector: 'app-incident',
|
||||||
|
@ -52,8 +93,11 @@ import { FmtDatePipe } from '../incidents.component';
|
||||||
styleUrl: './incident.component.scss',
|
styleUrl: './incident.component.scss',
|
||||||
})
|
})
|
||||||
export class IncidentComponent {
|
export class IncidentComponent {
|
||||||
|
incPrime = new Subject<IncidentRecord>();
|
||||||
inc$!: Observable<IncidentRecord>;
|
inc$!: Observable<IncidentRecord>;
|
||||||
subscriptions: Subscription = new Subscription();
|
subscriptions: Subscription = new Subscription();
|
||||||
|
dialog = inject(MatDialog);
|
||||||
|
incID!: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
|
@ -63,8 +107,21 @@ export class IncidentComponent {
|
||||||
saveIncName(ev: Event) {}
|
saveIncName(ev: Event) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
const incID = this.route.snapshot.paramMap.get('id')!;
|
this.incID = this.route.snapshot.paramMap.get('id')!;
|
||||||
this.inc$ = this.incSvc.getIncident(incID);
|
this.inc$ = this.incPrime.pipe(map((inc) => inc));
|
||||||
|
this.incSvc.getIncident(this.incID).subscribe(this.incPrime);
|
||||||
|
}
|
||||||
|
|
||||||
|
editIncident(incID: string) {
|
||||||
|
const dialogRef = this.dialog.open(IncidentEditDialogComponent, {
|
||||||
|
data: incID,
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogRef.afterClosed().subscribe((res) => {
|
||||||
|
if (res !== undefined) {
|
||||||
|
this.incPrime.next(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
|
|
@ -222,7 +222,8 @@ body {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input,
|
||||||
|
textarea {
|
||||||
caret-color: var(--color-dark-fg) !important;
|
caret-color: var(--color-dark-fg) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue