Works kind of, wip
This commit is contained in:
parent
1c0734f19d
commit
8a223b8897
9 changed files with 135 additions and 136 deletions
|
@ -27,8 +27,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"navigationUrls":
|
"navigationUrls": [
|
||||||
[
|
|
||||||
"/**",
|
"/**",
|
||||||
"!/**/*.*",
|
"!/**/*.*",
|
||||||
"!/**/****",
|
"!/**/****",
|
||||||
|
|
|
@ -1,10 +1,4 @@
|
||||||
import {
|
import { Component, inject, ViewChild } from '@angular/core';
|
||||||
Component,
|
|
||||||
inject,
|
|
||||||
Pipe,
|
|
||||||
PipeTransform,
|
|
||||||
ViewChild,
|
|
||||||
} from '@angular/core';
|
|
||||||
import { CommonModule, AsyncPipe } from '@angular/common';
|
import { CommonModule, AsyncPipe } from '@angular/common';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatTableModule } from '@angular/material/table';
|
import { MatTableModule } from '@angular/material/table';
|
||||||
|
@ -17,13 +11,20 @@ import { PrefsService } from '../prefs/prefs.service';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { SelectionModel } from '@angular/cdk/collections';
|
import { SelectionModel } from '@angular/cdk/collections';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
|
import { BehaviorSubject, Subscription } from 'rxjs';
|
||||||
import { map, switchMap } from 'rxjs/operators';
|
import { switchMap } from 'rxjs/operators';
|
||||||
import { CallsListParams, CallsService } from './calls.service';
|
import {
|
||||||
|
CallsListParams,
|
||||||
|
CallsService,
|
||||||
|
DatePipe,
|
||||||
|
DownloadURLPipe,
|
||||||
|
FixedPointPipe,
|
||||||
|
TalkgroupPipe,
|
||||||
|
TimePipe,
|
||||||
|
} from './calls.service';
|
||||||
import { CallRecord } from '../calls';
|
import { CallRecord } from '../calls';
|
||||||
|
|
||||||
import { TalkgroupService } from '../talkgroups/talkgroups.service';
|
import { TalkgroupService } from '../talkgroups/talkgroups.service';
|
||||||
import { Talkgroup } from '../talkgroup';
|
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
|
@ -49,94 +50,6 @@ import {
|
||||||
import { IncidentRecord } from '../incidents';
|
import { IncidentRecord } from '../incidents';
|
||||||
import { SelectIncidentDialogComponent } from '../incidents/select-incident-dialog/select-incident-dialog.component';
|
import { SelectIncidentDialogComponent } from '../incidents/select-incident-dialog/select-incident-dialog.component';
|
||||||
|
|
||||||
@Pipe({
|
|
||||||
name: 'grabDate',
|
|
||||||
standalone: true,
|
|
||||||
pure: true,
|
|
||||||
})
|
|
||||||
export class DatePipe implements PipeTransform {
|
|
||||||
transform(ts: string, args?: any): string {
|
|
||||||
const timestamp = new Date(ts);
|
|
||||||
return timestamp.getMonth() + 1 + '/' + timestamp.getDate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Pipe({
|
|
||||||
name: 'time',
|
|
||||||
standalone: true,
|
|
||||||
pure: true,
|
|
||||||
})
|
|
||||||
export class TimePipe implements PipeTransform {
|
|
||||||
transform(ts: string, args?: any): string {
|
|
||||||
const timestamp = new Date(ts);
|
|
||||||
return timestamp.toLocaleTimeString(navigator.language, {
|
|
||||||
hour: '2-digit',
|
|
||||||
minute: '2-digit',
|
|
||||||
hourCycle: 'h23',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Pipe({
|
|
||||||
name: 'talkgroup',
|
|
||||||
standalone: true,
|
|
||||||
pure: true,
|
|
||||||
})
|
|
||||||
export class TalkgroupPipe implements PipeTransform {
|
|
||||||
constructor(private tgService: TalkgroupService) {}
|
|
||||||
|
|
||||||
transform(call: CallRecord, field: string): Observable<string> {
|
|
||||||
return this.tgService.getTalkgroup(call.system_id, call.tgid).pipe(
|
|
||||||
map((tg: Talkgroup) => {
|
|
||||||
switch (field) {
|
|
||||||
case 'alpha': {
|
|
||||||
return tg.alpha_tag ?? call.tgid;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'group': {
|
|
||||||
return tg.tg_group ?? '\u2014';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'system': {
|
|
||||||
return tg.system?.name ?? tg.system_id.toString();
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return tg.name ?? '\u2014';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Pipe({
|
|
||||||
name: 'fixedPoint',
|
|
||||||
standalone: true,
|
|
||||||
pure: true,
|
|
||||||
})
|
|
||||||
export class FixedPointPipe implements PipeTransform {
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
transform(quant: number, divisor: number, places: number): string {
|
|
||||||
const seconds = quant / divisor;
|
|
||||||
return seconds.toFixed(places);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Pipe({
|
|
||||||
name: 'audioDownloadURL',
|
|
||||||
standalone: true,
|
|
||||||
pure: true,
|
|
||||||
})
|
|
||||||
export class DownloadURLPipe implements PipeTransform {
|
|
||||||
constructor(private callsSvc: CallsService) {}
|
|
||||||
|
|
||||||
transform(call: CallRecord, args?: any): string {
|
|
||||||
return this.callsSvc.callAudioDownloadURL(call.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const reqPageSize = 200;
|
const reqPageSize = 200;
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-calls',
|
selector: 'app-calls',
|
||||||
|
@ -144,8 +57,8 @@ const reqPageSize = 200;
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
FixedPointPipe,
|
FixedPointPipe,
|
||||||
TalkgroupPipe,
|
TalkgroupPipe,
|
||||||
DatePipe,
|
|
||||||
TimePipe,
|
TimePipe,
|
||||||
|
DatePipe,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
AsyncPipe,
|
AsyncPipe,
|
||||||
|
|
|
@ -1,8 +1,98 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Pipe, PipeTransform } from '@angular/core';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Observable } from 'rxjs';
|
import { map, Observable } from 'rxjs';
|
||||||
import { CallRecord } from '../calls';
|
import { CallRecord } from '../calls';
|
||||||
import { environment } from '.././../environments/environment';
|
import { environment } from '.././../environments/environment';
|
||||||
|
import { TalkgroupService } from '../talkgroups/talkgroups.service';
|
||||||
|
import { Talkgroup } from '../talkgroup';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'grabDate',
|
||||||
|
standalone: true,
|
||||||
|
pure: true,
|
||||||
|
})
|
||||||
|
export class DatePipe implements PipeTransform {
|
||||||
|
transform(ts: string, args?: any): string {
|
||||||
|
const timestamp = new Date(ts);
|
||||||
|
return timestamp.getMonth() + 1 + '/' + timestamp.getDate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'time',
|
||||||
|
standalone: true,
|
||||||
|
pure: true,
|
||||||
|
})
|
||||||
|
export class TimePipe implements PipeTransform {
|
||||||
|
transform(ts: string, args?: any): string {
|
||||||
|
const timestamp = new Date(ts);
|
||||||
|
return timestamp.toLocaleTimeString(navigator.language, {
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
hourCycle: 'h23',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'talkgroup',
|
||||||
|
standalone: true,
|
||||||
|
pure: true,
|
||||||
|
})
|
||||||
|
export class TalkgroupPipe implements PipeTransform {
|
||||||
|
constructor(private tgService: TalkgroupService) {}
|
||||||
|
|
||||||
|
transform(call: CallRecord, field: string): Observable<string> {
|
||||||
|
return this.tgService.getTalkgroup(call.system_id, call.tgid).pipe(
|
||||||
|
map((tg: Talkgroup) => {
|
||||||
|
switch (field) {
|
||||||
|
case 'alpha': {
|
||||||
|
return tg.alpha_tag ?? call.tgid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'group': {
|
||||||
|
return tg.tg_group ?? '\u2014';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'system': {
|
||||||
|
return tg.system?.name ?? tg.system_id.toString();
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return tg.name ?? '\u2014';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'fixedPoint',
|
||||||
|
standalone: true,
|
||||||
|
pure: true,
|
||||||
|
})
|
||||||
|
export class FixedPointPipe implements PipeTransform {
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
transform(quant: number, divisor: number, places: number): string {
|
||||||
|
const seconds = quant / divisor;
|
||||||
|
return seconds.toFixed(places);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'audioDownloadURL',
|
||||||
|
standalone: true,
|
||||||
|
pure: true,
|
||||||
|
})
|
||||||
|
export class DownloadURLPipe implements PipeTransform {
|
||||||
|
constructor(private callsSvc: CallsService) {}
|
||||||
|
|
||||||
|
transform(call: CallRecord, args?: any): string {
|
||||||
|
return this.callsSvc.callAudioDownloadURL(call.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface CallsListParams {
|
export interface CallsListParams {
|
||||||
start: Date | null;
|
start: Date | null;
|
||||||
|
|
|
@ -35,7 +35,7 @@ import {
|
||||||
TimePipe,
|
TimePipe,
|
||||||
DatePipe,
|
DatePipe,
|
||||||
DownloadURLPipe,
|
DownloadURLPipe,
|
||||||
} from '../../calls/calls.component';
|
} from '../../calls/calls.service';
|
||||||
import { CallPlayerComponent } from '../../calls/player/call-player/call-player.component';
|
import { CallPlayerComponent } from '../../calls/player/call-player/call-player.component';
|
||||||
import { FmtDatePipe } from '../incidents.component';
|
import { FmtDatePipe } from '../incidents.component';
|
||||||
import { MatMenuModule } from '@angular/material/menu';
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
|
@ -183,7 +183,8 @@ export class IncidentComponent {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
let incOb: Observable<IncidentRecord>;
|
let incOb: Observable<IncidentRecord>;
|
||||||
if (this.route.component === this.constructor) { // loaded by route
|
if (this.route.component === this.constructor) {
|
||||||
|
// loaded by route
|
||||||
this.incID = this.route.snapshot.paramMap.get('id')!;
|
this.incID = this.route.snapshot.paramMap.get('id')!;
|
||||||
incOb = this.incSvc.getIncident(this.incID);
|
incOb = this.incSvc.getIncident(this.incID);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
@let sh = share | async;
|
@let sh = share | async;
|
||||||
@if (sh == null) {
|
@if (sh == null) {
|
||||||
|
} @else if (sh.shareType == "incident") {
|
||||||
} @else if (sh.shareType == 'incident') {
|
|
||||||
<app-incident [incident]="sh"></app-incident>
|
<app-incident [incident]="sh"></app-incident>
|
||||||
} @else if (sh.shareType == 'call') {
|
} @else if (sh.shareType == "call") {
|
||||||
|
} @else {}
|
||||||
} @else {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,9 +8,8 @@ describe('ShareComponent', () => {
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [ShareComponent]
|
imports: [ShareComponent],
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ShareComponent);
|
fixture = TestBed.createComponent(ShareComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
|
|
|
@ -5,15 +5,11 @@ import { Observable, Subscription, switchMap } from 'rxjs';
|
||||||
import { IncidentComponent } from '../incidents/incident/incident.component';
|
import { IncidentComponent } from '../incidents/incident/incident.component';
|
||||||
import { AsyncPipe } from '@angular/common';
|
import { AsyncPipe } from '@angular/common';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-share',
|
selector: 'app-share',
|
||||||
imports: [
|
imports: [AsyncPipe, IncidentComponent],
|
||||||
AsyncPipe,
|
|
||||||
IncidentComponent,
|
|
||||||
],
|
|
||||||
templateUrl: './share.component.html',
|
templateUrl: './share.component.html',
|
||||||
styleUrl: './share.component.scss'
|
styleUrl: './share.component.scss',
|
||||||
})
|
})
|
||||||
export class ShareComponent {
|
export class ShareComponent {
|
||||||
shareID!: string;
|
shareID!: string;
|
||||||
|
|
|
@ -9,26 +9,28 @@ export interface Share {
|
||||||
share: ShareType;
|
share: ShareType;
|
||||||
}
|
}
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class ShareService {
|
export class ShareService {
|
||||||
|
constructor(private http: HttpClient) {}
|
||||||
constructor(
|
|
||||||
private http: HttpClient,
|
|
||||||
) { }
|
|
||||||
|
|
||||||
getShare(id: string): Observable<Share | null> {
|
getShare(id: string): Observable<Share | null> {
|
||||||
return this.http.get<ShareType>(`/share/${id}`, {observe: 'response'}).pipe(
|
return this.http
|
||||||
|
.get<ShareType>(`/share/${id}`, { observe: 'response' })
|
||||||
|
.pipe(
|
||||||
map((res) => {
|
map((res) => {
|
||||||
let typ = res.headers.get('X-Share-Type');
|
let typ = res.headers.get('X-Share-Type');
|
||||||
switch (typ) {
|
switch (typ) {
|
||||||
case 'call':
|
case 'call':
|
||||||
return <Share>{shareType: typ, share: (res.body as ArrayBuffer)};
|
return <Share>{ shareType: typ, share: res.body as ArrayBuffer };
|
||||||
case 'incident':
|
case 'incident':
|
||||||
return <Share>{shareType: typ, share: (res.body as IncidentRecord)};
|
return <Share>{
|
||||||
|
shareType: typ,
|
||||||
|
share: res.body as IncidentRecord,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,10 @@ export class TalkgroupService {
|
||||||
private subscriptions = new Subscription();
|
private subscriptions = new Subscription();
|
||||||
constructor(private http: HttpClient) {
|
constructor(private http: HttpClient) {
|
||||||
this.tgs$ = this.fetchAll.pipe(switchMap(() => this.getTalkgroups()));
|
this.tgs$ = this.fetchAll.pipe(switchMap(() => this.getTalkgroups()));
|
||||||
this.tags$ = this.fetchAll.pipe(switchMap(() => this.getAllTags()), shareReplay());
|
this.tags$ = this.fetchAll.pipe(
|
||||||
|
switchMap(() => this.getAllTags()),
|
||||||
|
shareReplay(),
|
||||||
|
);
|
||||||
this.fillTgMap();
|
this.fillTgMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue