Skip to content

Commit

Permalink
#10 indicator tooltip and visibility (#23)
Browse files Browse the repository at this point in the history
* #10: sets indicator tooltip

* #10: improves indicator visibility

* #10: moves update timer to service

---------

Co-authored-by: Dirk Peter <[email protected]>
  • Loading branch information
dirk-peter-c8y and Dirk Peter authored Jun 12, 2024
1 parent 99f2747 commit a227aea
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 49 deletions.
22 changes: 0 additions & 22 deletions plugin/components/reminder-drawer/reminder-drawer.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Component, OnDestroy } from '@angular/core';
import { AlertService, HeaderService } from '@c8y/ngx-components';
import { filter, sortBy } from 'lodash';
import moment from 'moment';
import { BsModalService } from 'ngx-bootstrap/modal';
import { BehaviorSubject, Subscription } from 'rxjs';
import {
Expand Down Expand Up @@ -119,25 +117,5 @@ export class ReminderDrawerComponent implements OnDestroy {
this.reminders = reminders;
this.reminderGroups = this.reminderService.groupReminders(reminders);
this.lastUpdate = new Date();
this.setUpdateTimer();
}

private setUpdateTimer(): void {
// TODO update indicator
// - move update timer to service?
const now = moment();

clearTimeout(this.updateTimer);

if (!this.reminders.length) return;

const closestReminder = sortBy(
filter(this.reminders, (r) => r.status !== ReminderStatus.cleared && moment(r.time) > now),
'time'
)[0];

if (!closestReminder) return;

this.updateTimer = setTimeout(() => this.digestReminders(this.reminders), moment(closestReminder.time).diff(now));
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<button type="button" class="{{ status }}" [class.open]="open" (click)="toggleDrawer()">
<button type="button" class="{{ status }}" [tooltip]="tooltipText" [class.open]="open"
(click)="toggleDrawer()">
<em>
<ng-container *ngIf="open; else showText">
<i [c8yIcon]="'close'"></i>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ em {
font-size: 16px;
border-radius: 8px;
background-color: var(--c8y-palette-status-success-light);
border: 0 solid var(--c8y-palette-status-success-light);
border: 1px solid var(--c8y-palette-status-success);
transition: all .3s ease-in-out;
}

Expand All @@ -35,13 +35,13 @@ button {
background: none;

&.status-warning em {
border-color: var(--c8y-palette-status-warning-high);
background-color: var(--c8y-palette-status-warning-high);
border-color: var(--c8y-palette-status-warning);
}

&.status-danger em {
border-color: var(--c8y-palette-status-danger-light);
background-color: var(--c8y-palette-status-danger-light);
border-color: var(--c8y-palette-status-danger);
}

&.open em {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,29 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { REMINDER_MAX_COUNTER } from '../../reminder.model';
import { ReminderService } from '../../services/reminder.service';
import { Subscription } from 'rxjs';
import { TranslateService } from '@ngx-translate/core';

const ReminderStatus = {
default: '',
warning: 'status-warning',
danger: 'status-danger',
danger: 'status-danger'
};

@Component({
selector: 'c8y-reminder-indicator',
templateUrl: './reminder-indicator.component.html',
styleUrls: ['./reminder-indicator.component.less'],
styleUrls: ['./reminder-indicator.component.less']
})
export class ReminderIndicatorComponent implements OnInit, OnDestroy {
open = false;
counter = 0;
status = ReminderStatus.default;
maxCounter = REMINDER_MAX_COUNTER;
tooltipText!: string;

private subscription = new Subscription();

constructor(private reminderService: ReminderService) { }
constructor(private reminderService: ReminderService, private translateService: TranslateService) {}

ngOnInit(): void {
// open status
Expand All @@ -34,7 +36,10 @@ export class ReminderIndicatorComponent implements OnInit, OnDestroy {

// reminder counter
this.subscription.add(
this.reminderService.reminderCounter$.subscribe((counter) => this.setCounterStatus(counter))
this.reminderService.reminderCounter$.subscribe((counter) => {
this.setCounterStatus(counter);
this.setCounterText();
})
);
}

Expand All @@ -46,11 +51,28 @@ export class ReminderIndicatorComponent implements OnInit, OnDestroy {
this.reminderService.toggleDrawer();
}

private setCounterStatus(counter: number) {
private setCounterStatus(counter: number): void {
this.counter = counter;

if (counter >= this.maxCounter) this.status = ReminderStatus.danger;
else if (counter >= 1) this.status = ReminderStatus.warning;
else this.status = ReminderStatus.default;
}

private setCounterText(counter = this.counter): void {
let txt: string;

switch (counter) {
case 0:
txt = 'No reminder is due';
break;
case 1:
txt = 'One reminder is due';
break;
default:
txt = '{{ counter }} reminders are due';
}

this.tooltipText = this.translateService.instant(txt, { counter });
}
}
21 changes: 13 additions & 8 deletions plugin/components/reminder-modal/reminder-modal.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@ <h3 translate>Create a Reminder</h3>

<form [formGroup]="form" (submit)="submit()">
<div class="modal-body">
<c8y-asset-selector-miller class="m-b-24" [label]="'Assign to'" [selectedDevice]="asset" [isLoading]="isLoading"
(onSelected)="assetSelected($event.items)" [config]="{
groupsSelectable: true,
singleColumn: true,
columnHeaders: true,
showFilter: true,
search: true
}"></c8y-asset-selector-miller>
<c8y-asset-selector-miller class="m-b-24"
[label]="'Assign to'"
[selectedDevice]="asset"
[isLoading]="isLoading"
[config]="{
groupsSelectable: true,
singleColumn: true,
columnHeaders: true,
showFilter: true,
search: true
}"
(onSelected)="assetSelected($event.items)"
></c8y-asset-selector-miller>

<formly-form [form]="form" [fields]="fields" [model]="reminder"></formly-form>
</div>
Expand Down
13 changes: 6 additions & 7 deletions plugin/components/reminder-modal/reminder-modal.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,15 @@ import { Reminder, ReminderStatus, REMINDER_TEXT_LENGTH, REMINDER_TYPE } from '.
styleUrls: ['./reminder-modal.component.less']
})
export class ReminderModalComponent implements OnInit {
// TODO selectable context
isLoading = false;
asset!: Partial<IManagedObject>;
form = new FormGroup({});

reminder: Partial<Reminder> = {
// source: {
// id: undefined,
// name: undefined
// },
source: {
id: undefined,
name: undefined
},
text: undefined,
time: undefined,
type: REMINDER_TYPE
Expand Down Expand Up @@ -75,15 +74,15 @@ export class ReminderModalComponent implements OnInit {

ngOnInit(): void {
this.asset = this.getAssetFromRoute(this.activatedRoute.snapshot);
// this.reminder.source.id = this.asset.id;
// this.reminder.source.name = String(this.asset.name) || '';
}

close() {
this.bsModalRef.hide();
}

assetSelected(asset: Partial<IManagedObject>): void {
if (!asset || !asset.id) return;

this.asset = {
id: asset.id,
name: asset.name
Expand Down
4 changes: 3 additions & 1 deletion plugin/reminder-plugin.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { RouterModule } from '@angular/router';
import { CoreModule, EventRealtimeService, hookAction } from '@c8y/ngx-components';
import { AssetSelectorModule } from '@c8y/ngx-components/assets-navigator';
import { FormlyModule } from '@ngx-formly/core';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { MomentModule } from 'ngx-moment';
import { ReminderDrawerComponent } from './components/reminder-drawer/reminder-drawer.component';
import { ReminderIndicatorComponent } from './components/reminder-indicator/reminder-indicator.component';
Expand All @@ -21,7 +22,8 @@ import { ReminderService } from './services/reminder.service';
MomentModule,
FormlyModule.forChild({
types: [{ name: 'time', component: TimeFieldType }]
})
}),
TooltipModule
],
declarations: [ReminderDrawerComponent, ReminderIndicatorComponent, ReminderModalComponent, TimeFieldType],
providers: [
Expand Down
38 changes: 36 additions & 2 deletions plugin/services/reminder.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ComponentRef, Injectable } from '@angular/core';
import { EventService, IEvent, IResult } from '@c8y/client';
import { EventRealtimeService, RealtimeMessage } from '@c8y/ngx-components';
import { cloneDeep, has, sortBy } from 'lodash';
import { cloneDeep, filter as _filter, has, sortBy } from 'lodash';
import moment from 'moment';
import { BehaviorSubject, Subscription } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { map, filter } from 'rxjs/operators';
import { ReminderDrawerComponent } from '../components/reminder-drawer/reminder-drawer.component';
import {
Reminder,
Expand All @@ -25,6 +25,7 @@ export class ReminderService {
private drawerRef: ComponentRef<unknown>;
private drawer: ReminderDrawerComponent;
private subscription = new Subscription();
private updateTimer: NodeJS.Timeout;
private _reminderCounter = 0;
private _reminders: Reminder[] = [];

Expand All @@ -34,6 +35,8 @@ export class ReminderService {
private set reminders(reminders: Reminder[]) {
this._reminders = reminders;
this.reminders$.next(this._reminders);
this.updateCounter();
this.setUpdateTimer();
}

private get reminderCounter(): number {
Expand Down Expand Up @@ -250,4 +253,35 @@ export class ReminderService {
return reminder;
});
}

private updateCounter(): void {
const now = new Date().getTime();
let count = 0;
let dueDate: number;

this.reminders.forEach((reminder) => {
dueDate = new Date(reminder.time).getTime();
if (dueDate <= now && reminder.status === ReminderStatus.active) count++;
});

this.reminderCounter = count;
}

private setUpdateTimer(): void {
const now = moment();

clearTimeout(this.updateTimer);

if (!this.reminders || !this.reminders.length) return;

const dueReminders = _filter(this.reminders, (r) => r.status !== ReminderStatus.cleared && moment(r.time) > now);
const closestReminder: Reminder = sortBy(dueReminders, 'time')[0];

if (!closestReminder) return;

this.updateTimer = setTimeout(
() => (this.reminders = this.digestReminders(this.reminders)),
moment(closestReminder.time).diff(now)
);
}
}

0 comments on commit a227aea

Please sign in to comment.