Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#10 indicator tooltip and visibility #23

Merged
merged 3 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
);
}
}
Loading