Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

Commit

Permalink
Finish dashboard implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ppacher committed Aug 8, 2023
1 parent 0cf1475 commit 6bed9ce
Show file tree
Hide file tree
Showing 26 changed files with 414 additions and 263 deletions.
33 changes: 10 additions & 23 deletions modules/portmaster/src/app/layout/navigation/navigation.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="flex flex-col items-center gap-1">
<div class="relative w-16 h-16">

<app-security-lock [@fadeIn] [@fadeOut] mode="small" class="absolute w-16 h-16"
<app-security-lock [@fadeIn] [@fadeOut] mode="small" class="absolute w-16 h-16" routerLink="dashboard"
*ngIf="sideDashStatus === 'collapsed'">
</app-security-lock>

Expand Down Expand Up @@ -56,24 +56,15 @@

<div class="pt-1 border-t border-gray-400 nav-list">
<!-- The notification drop-down -->
<div
sfngTipUpTrigger="navNotifications" sfngTipUpPassive
class="relative link" cdkOverlayOrigin #notifOrigin="cdkOverlayOrigin"
(click)="notificationDropDown.toggle(notifOrigin)" [class.active]="notificationDropDown.isOpen">
<div sfngTipUpTrigger="navNotifications" sfngTipUpPassive class="relative " (click)="toggleSideDash($event)"
*ngIf="sideDashStatus !== 'expanded'">

<span *ngIf="hasNewNotifications"
class="absolute w-1.5 h-1.5 {{ notificationColor }} rounded-full top-1.5 right-1.5"></span>

<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"
stroke-width="2">
<svg class="w-4 h-4 {{ hasNewNotifications ? notificationColor : '' }}" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</div>
<sfng-dropdown [positions]="dropDownPositions" externalTrigger="true" #notificationDropDown offsetY="0" offsetX="10"
overlayClass="rounded-t">
<app-notification-list></app-notification-list>
</sfng-dropdown>

<!-- The prompt list drop-down -->
<div class="relative link" cdkOverlayOrigin #promptOrigin="cdkOverlayOrigin"
Expand Down Expand Up @@ -162,11 +153,9 @@
</div>
</div>
<div class="nav-lower-list">
<div class="relative link"
sfngTipUpTrigger="navTools" sfngTipUpPassive
tooltip="Version and Tools" sfngTooltipDelay="1000" snfgTooltipPosition="right"
(click)="settingsMenu.dropdown.toggle(settingsMenuTrigger)" cdkOverlayOrigin
#settingsMenuTrigger="cdkOverlayOrigin" [class.active]="settingsMenu.dropdown.isOpen">
<div class="relative link" sfngTipUpTrigger="navTools" sfngTipUpPassive tooltip="Version and Tools"
sfngTooltipDelay="1000" snfgTooltipPosition="right" (click)="settingsMenu.dropdown.toggle(settingsMenuTrigger)"
cdkOverlayOrigin #settingsMenuTrigger="cdkOverlayOrigin" [class.active]="settingsMenu.dropdown.isOpen">

<span *ngIf="versions?.Channel !== 'stable'"
class="absolute w-1.5 h-1.5 bg-yellow-300 rounded-full top-1.5 right-1.5"></span>
Expand Down Expand Up @@ -213,10 +202,8 @@
</app-menu>

<!-- Power Menu -->
<div
sfngTipUpTrigger="navPower" sfngTipUpPassive
tooltip="Shutdown and Restart" sfngTooltipDelay="1000" snfgTooltipPosition="right"
class="link" (click)="powerMenu.dropdown.toggle(powerMenuTrigger)" cdkOverlayOrigin
<div sfngTipUpTrigger="navPower" sfngTipUpPassive tooltip="Shutdown and Restart" sfngTooltipDelay="1000"
snfgTooltipPosition="right" class="link" (click)="powerMenu.dropdown.toggle(powerMenuTrigger)" cdkOverlayOrigin
#powerMenuTrigger="cdkOverlayOrigin" [class.active]="powerMenu.dropdown.isOpen">

<svg version="1.1" viewBox="0 0 24 24" class="help" xmlns="http://www.w3.org/2000/svg"
Expand Down
8 changes: 4 additions & 4 deletions modules/portmaster/src/app/layout/navigation/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class NavigationComponent implements OnInit {
hasNewNotifications = false;

/** The color to use for the notifcation-available hint (dot) */
notificationColor: string = 'bg-green-300';
notificationColor: string = 'text-green-300';

/** Whether or not we have new, unseen prompts */
hasNewPrompts = false;
Expand Down Expand Up @@ -110,12 +110,12 @@ export class NavigationComponent implements OnInit {
}

if (notif.some(n => n.Type === NotificationType.Error)) {
this.notificationColor = 'bg-red-300';
this.notificationColor = 'text-red-300';
} else
if (notif.some(n => n.Type === NotificationType.Warning)) {
this.notificationColor = 'bg-yellow-300';
this.notificationColor = 'text-yellow-300';
} else {
this.notificationColor = 'bg-green-300';
this.notificationColor = 'text-green-300';
}

this.cdr.markForCheck();
Expand Down
15 changes: 2 additions & 13 deletions modules/portmaster/src/app/layout/side-dash/side-dash.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
<div class="relative flex flex-row w-full gap-2 px-2 pb-8 justify-evenly">
<app-status-pilot class="block w-32"></app-status-pilot>
<div class="h-full border-l-2 border-gray-300"></div>
<app-spn-status class="block w-64"></app-spn-status>

<div class="absolute top-0 right-0 flex flex-row gap-2 pr-4">
<span (click)="openAccountDetails()"
class="block p-1.5 bg-gray-400 rounded cursor-pointer text-primary hover:bg-gray-300 hover:text-primary">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round"
d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z" />
</svg>
</span>
</div>
</div>

<app-notification-list></app-notification-list>

<app-spn-login *ngIf="spnLoginRequired"></app-spn-login>
<app-network-scout *ngIf="!spnLoginRequired" class="flex-grow overflow-auto"></app-network-scout>
12 changes: 0 additions & 12 deletions modules/portmaster/src/app/layout/side-dash/side-dash.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { SfngDialogService } from '@safing/ui';
import { SPNAccountDetailsComponent } from 'src/app/shared/spn-account-details';

@Component({
selector: 'app-side-dash',
Expand All @@ -12,14 +10,4 @@ export class SideDashComponent {
/** Whether or not a SPN account login is required */
spnLoginRequired = false;

constructor(
private dialog: SfngDialogService,
) { }

openAccountDetails() {
this.dialog.create(SPNAccountDetailsComponent, {
autoclose: true,
backdrop: 'light'
})
}
}
4 changes: 2 additions & 2 deletions modules/portmaster/src/app/pages/app-view/app-view.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ <h1 class="flex flex-row items-center mb-0 text-2xl text-primary whitespace-nowr
<span class="text-opacity-75 text-primary"
sfng-tooltip="Support for connection history requires a subscription">None</span>
<ng-container *ngIf="(canUseHistory | async) === false">
<a class="text-xs underline cursor-pointer text-opacity-75" href="https://safing.io/pricing/?source=Portmaster">Available in Portmaster Plus</a>
<a class="text-xs text-opacity-75 underline cursor-pointer"
href="https://safing.io/pricing/?source=Portmaster">Available in Portmaster Plus</a>
</ng-container>
</ng-container>
</div>
Expand Down Expand Up @@ -138,7 +139,6 @@ <h2 class="p-0 m-0 text-lg sfng-lg:text-xl text-primary">{{ (100 / stats!.size)
</sfng-netquery-viewer>
</div>
</sfng-tab>

<!-- App Settings -->
<sfng-tab id="settings" title="Settings">
<div *sfngTabContent class="py-4 overflow-auto" cdkScrollable>
Expand Down
2 changes: 0 additions & 2 deletions modules/portmaster/src/app/pages/app-view/app-view.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
:host {
@apply flex flex-col h-screen max-h-screen;
}

// p-4 px-12
6 changes: 4 additions & 2 deletions modules/portmaster/src/app/pages/app-view/app-view.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild, inject } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AppProfile, AppProfileService, ChartResult, Condition, ConfigService, Database, DebugAPI, ExpertiseLevel, FlatConfigObject, IProfileStats, LayeredProfile, Netquery, Setting, flattenProfileConfig, setAppSetting, Feature, SPNService } from '@safing/portmaster-api';
import { AppProfile, AppProfileService, ChartResult, Condition, ConfigService, Database, DebugAPI, ExpertiseLevel, FeatureID, FlatConfigObject, IProfileStats, LayeredProfile, Netquery, SPNService, Setting, flattenProfileConfig, setAppSetting } from '@safing/portmaster-api';
import { SfngDialogService } from '@safing/ui';
import { BehaviorSubject, Observable, Subscription, combineLatest, interval, of } from 'rxjs';
import { distinctUntilChanged, map, mergeMap, startWith, switchMap } from 'rxjs/operators';
Expand All @@ -24,6 +24,7 @@ export class AppViewComponent implements OnInit, OnDestroy {
@ViewChild(SfngNetqueryViewer)
netqueryViewer?: SfngNetqueryViewer;


/** subscription to our update-process observable */
private subscription = Subscription.EMPTY;

Expand All @@ -50,7 +51,7 @@ export class AppViewComponent implements OnInit, OnDestroy {
canUseHistory = inject(SPNService).profile$
.pipe(
map(profile => {
return profile?.current_plan?.feature_ids?.includes(Feature.History) || false;
return profile?.current_plan?.feature_ids?.includes(FeatureID.History) || false;
})
);

Expand Down Expand Up @@ -469,6 +470,7 @@ export class AppViewComponent implements OnInit, OnDestroy {

this.cdr.markForCheck();
});

}

/**
Expand Down
85 changes: 52 additions & 33 deletions modules/portmaster/src/app/pages/dashboard/dashboard.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
<h1 class="flex flex-col flex-grow text-lg font-light text-white">
Dashboard
<span class="text-sm font-normal text-secondary">Welcome back
<ng-container *ngIf="!!profile">
, <span class="text-primary">{{ profile.username }}</span>!
<ng-container *ngIf="!!profile && profile.state !== ''">
, <span class="text-primary">{{ profile.username }}</span>
</ng-container>
!
</span>
</h1>

Expand All @@ -14,10 +15,17 @@ <h1 class="flex flex-col flex-grow text-lg font-light text-white">
<div class="flex flex-col text-xs leading-4">
<span class="font-light text-secondary">Your current plan is <span
class="font-normal text-green-300">{{ profile.current_plan?.name || 'N/A' }}</span></span>
<span class="font-light text-secondary">and ends {{ profile.subscription ? ' in ': ''}} <span
class="font-normal text-primary">

<span class="font-light text-secondary" *ngIf="!profile.subscription?.next_billing_date">
and ends {{ profile.subscription ? ' in ': ''}} <span class="font-normal text-primary">
{{ profile.subscription ? (profile.subscription.ends_at | timeAgo) : 'never'}}
</span></span>
</span>
</span>
<span class="font-light text-secondary" *ngIf="!!profile.subscription?.next_billing_date">
and re-news in <span class="font-normal text-primary">
{{ profile.subscription!.next_billing_date | timeAgo }}
</span>
</span>
</div>

<button *ngIf="profile.subscription" (click)="openAccountDetails()"
Expand All @@ -27,7 +35,7 @@ <h1 class="flex flex-col flex-grow text-lg font-light text-white">

<button *ngIf="!profile.subscription" (click)="openAccountDetails()"
class="text-xs font-normal text-white cursor-pointer btn bg-blue bg-opacity-80 hover:bg-opacity-100 hover:bg-blue">
Subscribe
Login / Subscribe
</button>

</ng-container>
Expand All @@ -44,68 +52,79 @@ <h1 class="flex flex-col flex-grow text-lg font-light text-white">
<app-feature-card *ngFor="let feature of (features$ | async)" [feature]="feature" [disabled]="!feature.enabled">
</app-feature-card>
</div>

<span class="font-light text-xxs text-primary">
Want more features?
<a href="https://safing.io/pricing/?source=portmaster" class="font-normal underline text-primary">Upgrade your
plan now! 🚀</a>
or
<a href="https://safing.io/pricing/#comparison?source=portmaster" class="font-normal underline text-primary">find
out more</a>
</span>
</div>


<div class="feature-card-container" id="stats">
<label>
Statistics
Statistics <span class="text-xxs">(last 10 minutes)</span>
</label>

<!-- Mini Stats -->
<div class="mini-stats-list">
<div class="mini-stat">
<label>Trackers Blocked</label>
<span>1.2k</span>
<div class="mini-stat" routerLink="/monitor" [queryParams]="{q: 'verdict:3 verdict:4'}">
<label>Connections Blocked</label>
<span>{{ blockedConnections }}</span>
</div>

<div class="mini-stat">
<div class="mini-stat" routerLink="/monitor" [queryParams]="{q: 'active:true'}">
<label>Active Connections</label>
<span>{{ activeConnections }}</span>
</div>

<div class="mini-stat">
<div class="mini-stat" routerLink="/monitor" [queryParams]="{q: 'active:true groupby:profile'}">
<label>Active Apps</label>
<span>{{ activeProfiles }}</span>
</div>

<div class="mini-stat">
<label>Data Sent</label>
<span>
{{ featureBw ? (dataOutgoing | bytes) : 'N/A'}}
<span *ngIf="featureBw">
{{ dataOutgoing | bytes }}
</span>

<span *ngIf="!featureBw" class="!text-xxs !text-secondary w-full text-center !leading-3">
Available in <br />Portmaster Plus
</span>
</div>

<div class="mini-stat">
<label>Data Received</label>
<span>
{{ featureBw ? (dataIncoming | bytes) : 'N/A'}}
<span *ngIf="featureBw">
{{ dataIncoming | bytes }}
</span>
<span *ngIf="!featureBw" class="!text-xxs !text-secondary w-full text-center !leading-3">
Available in <br />Portmaster Plus
</span>
</div>

<div class="mini-stat">
<div class="mini-stat" routerLink="/monitor" [queryParams]="{q: 'tunneled:true groupby:exit_node'}">
<label>SPN Identities</label>
<span>{{ featureSPN ? activeIdentities : 'N/A' }}</span>
<span *ngIf="featureSPN">{{ activeIdentities }}</span>
<span *ngIf="!featureSPN" class="!text-xxs !text-secondary w-full text-center !leading-3">
Available in <br />Portmaster Pro
</span>
</div>
</div>
</div>

<div class="feature-card-container" id="charts">
<label>
Active/Blocked Connections
</label>
<div class="mini-stats-list">
<div class="mini-stat">
<sfng-netquery-line-chart class="w-full h-36" [data]="connectionChart"></sfng-netquery-line-chart>
<label routerLink="/monitor">
Active/Blocked Connections
</label>
<sfng-netquery-line-chart activeConnectionColor="text-green-300 text-opacity-70" class="w-full h-36"
[data]="connectionChart"></sfng-netquery-line-chart>
</div>
<div class="mini-stat" *ngIf="featureSPN">
<label routerLink="/monitor" [queryParams]="{q: 'tunneled:true'}">
Connections Tunneled through SPN
</label>
<sfng-netquery-line-chart activeConnectionColor="text-blue"
activeConnectionAreaColor="text-blue text-opacity-25" hideBlocked="true" class="w-full h-36"
[data]="tunneldConnectionChart">
</sfng-netquery-line-chart>
</div>
</div>
</div>
Expand Down Expand Up @@ -135,8 +154,8 @@ <h1 class="flex flex-col flex-grow text-lg font-light text-white">
<label>
Recently Blocked Applications
</label>
<div class="block w-full">
<span *ngIf="!(blockedProfiles |keyvalue)?.length" class="flex flex-row items-center justify-center gap-2">
<div class="block w-full h-full">
<span *ngIf="!(blockedProfiles |keyvalue)?.length" class="flex flex-row items-center justify-center h-full gap-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,23 @@
"header header header header"
"feature feature feature feature"
"stats stats stats stats"
"stats stats stats stats"
"charts charts charts charts"
"charts charts charts charts"
"countries countries map map"
"blocked blocked map map";
"blocked blocked countries countries"
"map map map map";
}

:host-context(.min-width-1024px) {
.dashboard-grid {
grid-template-areas:
"header header header header"
"feature feature feature feature"
"stats stats stats stats"
"charts charts charts charts"
"countries countries map map"
"blocked blocked map map";
}
}

#header {
Expand Down Expand Up @@ -47,12 +61,12 @@

.auto-grid-3 {
@apply grid gap-4;
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.auto-grid-4 {
@apply grid gap-4;
grid-template-columns: repeat(4, minmax(0, 1fr));
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.feature-card-container {
Expand Down
Loading

0 comments on commit 6bed9ce

Please sign in to comment.