Skip to content

Commit

Permalink
feat: dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
VilemRaska committed Feb 18, 2025
1 parent 8f005ed commit 598e0e7
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ClassRangeDirective, ClassRangeOptions } from '@/utils/class-range.directive';
import { timeDifference } from '@/utils/time-difference';
import { AsyncPipe } from '@angular/common';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { TimeAgoComponent } from '@gapp/ui/time-ago';
import { interval, map, merge } from 'rxjs';

@Component({
selector: 'time-ago-badge',
template: `
<span [class-range]="options" [value]="secondsAgo$ | async" class="badge badge-outline">
<time-ago [date]="date()"></time-ago>
</span>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TimeAgoComponent, AsyncPipe, ClassRangeDirective],
})
export class TimeAgoBadgeComponent {
public date = input<string>('');

public options: ClassRangeOptions = {
180: 'badge-success',
360: 'badge-warning',
3600: 'badge-error',
100_000: 'badge-ghost',
};

public secondsAgo$ = merge(interval(1000), toObservable(this.date)).pipe(map(() => timeDifference(this.date())));
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
<div class="flex flex-row justify-between py-2">
<span class="font-bold">
{{ car()?.callsign }}
</span>
<div tabindex="0" class="collapse collapse-arrow bg-base-200">
<input type="checkbox" />
<div class="collapse-title flex flex-row justify-between">
<div>
@if(telemetry(); as telemetry) {
<time-ago-badge [date]="telemetry._time"></time-ago-badge>
} @else {
<span class="badge badge-ghost badge-outline">Not connected</span>
}
</div>
<div class="font-bold">
{{ car()?.callsign }}
</div>
</div>

<span>
@if(telemetry(); as telemetry) {
<span [class-range]="options" [value]="secondsAgo$ | async" class="badge badge-outline">
<time-ago [date]="telemetry._time"></time-ago>
</span>
} @else {
<span class="badge badge-ghost badge-outline">Not connected</span>
}
</span>
<div class="collapse-content">
<div class="flex flex-col gap-2 border-l-2 border-neutral pl-2">
<span>{{ car()?.description }}</span>
<!-- <button class="btn btn-sm btn-info">Detail</button> -->
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,29 +1,15 @@
import { Car } from '@/services/cars.service';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { TelemetryStatus } from './dashboard.service';
import { TimeAgoComponent } from '@gapp/ui/time-ago';
import { ClassRangeDirective, ClassRangeOptions } from '@/utils/class-range.directive';
import { interval, map, merge } from 'rxjs';
import { timeDifference } from '@/utils/time-difference';
import { AsyncPipe } from '@angular/common';
import { toObservable } from '@angular/core/rxjs-interop';
import { TimeAgoBadgeComponent } from '@/components/time-ago-badge/time-ago-badge.component';

@Component({
selector: 'car-status-card',
templateUrl: './car-status-card.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TimeAgoComponent, ClassRangeDirective, AsyncPipe],
imports: [TimeAgoBadgeComponent],
})
export class CarStatusCardComponent {
public car = input<Car>();
public telemetry = input<TelemetryStatus>();

public options: ClassRangeOptions = {
180: 'badge-success',
360: 'badge-warning',
3600: 'badge-error',
100_000: 'badge-ghost',
};

public secondsAgo$ = merge(interval(1000), toObservable(this.telemetry)).pipe(map(() => timeDifference(this.telemetry()?._time)));
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
<div class="flex flex-row justify-between py-2">
<span class="font-bold">
{{ vessel()?.callsign }}
</span>
<span>
@if(lastContact(); as lastContact) {
<span [class-range]="options" [value]="secondsAgo$ | async" class="badge badge-outline">
<time-ago [date]="lastContact._time"></time-ago>
</span>
} @else {
<span class="badge badge-ghost badge-outline">Not connected</span>
}
</span>
<div tabindex="0" class="collapse collapse-arrow bg-base-200">
<input type="checkbox" />
<div class="collapse-title flex flex-row justify-between">
<div class="font-bold">
{{ vessel()?.callsign }}
</div>
<div>
@if(lastContact(); as lastContact) {
<time-ago-badge [date]="lastContact._time"></time-ago-badge>
} @else {
<span class="badge badge-ghost badge-outline">Not connected</span>
}
</div>
</div>

<div class="collapse-content">
<div class="flex flex-col gap-2 border-l-2 border-neutral pl-2">
<ul class="flex flex-col gap-1">
@for(transmitter of vessel()?.transmitters; track $index) {
<li class="flex flex-row justify-start gap-2">
<div>{{ transmitter }}</div>
<div>
@if(getTransmitterTelemetry(transmitter)()?._time; as time) {
<time-ago-badge [date]="time"></time-ago-badge>
}
</div>
</li>
}
</ul>

<!-- <a class="btn btn-sm btn-info" href="https://amateur.sondehub.org/{{ vessel()?.callsign }}" target="_blank">Open in SondeHub</a> -->
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
import { TelemetryStatus } from './dashboard.service';
import { Vessel } from '@/services/vessels.service';
import { TimeAgoComponent } from '@gapp/ui/time-ago';
import { ClassRangeDirective, ClassRangeOptions } from '@/utils/class-range.directive';
import { AsyncPipe } from '@angular/common';
import { timeDifference } from '@/utils/time-difference';
import { interval, map, merge } from 'rxjs';
import { toObservable } from '@angular/core/rxjs-interop';
import { TimeAgoBadgeComponent } from '@/components/time-ago-badge/time-ago-badge.component';

@Component({
selector: 'vessel-status-card',
templateUrl: './vessel-status-card.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TimeAgoComponent, ClassRangeDirective, AsyncPipe],
imports: [TimeAgoBadgeComponent],
})
export class VesselStatusCardComponent {
public vessel = input<Vessel>();
Expand All @@ -23,12 +18,7 @@ export class VesselStatusCardComponent {
return telemetry?.sort((a, b) => Date.parse(b._time) - Date.parse(a._time))?.[0];
});

public options: ClassRangeOptions = {
180: 'badge-success',
360: 'badge-warning',
3600: 'badge-error',
100_000: 'badge-ghost',
};

public secondsAgo$ = merge(interval(1000), toObservable(this.lastContact)).pipe(map(() => timeDifference(this.lastContact()?._time)));
public getTransmitterTelemetry(transmitter: string) {
return computed(() => this.telemetry()?.find((t) => t.callsign === transmitter));
}
}

0 comments on commit 598e0e7

Please sign in to comment.