mirror of
https://github.com/akveo/ngx-admin.git
synced 2025-12-18 08:20:13 +01:00
refactor(iot): security camera widget
This commit is contained in:
parent
c1d2ebbbd2
commit
39272ba2ce
3 changed files with 130 additions and 161 deletions
|
|
@ -1,43 +1,58 @@
|
|||
<nb-card size="xlarge">
|
||||
<nb-card size="giant">
|
||||
|
||||
<nb-card-header>
|
||||
<div class="cameras-card-header">
|
||||
<span class="cameras-card-title">Security Cameras</span>
|
||||
<span class="cameras-filter">
|
||||
<a [class.active]="isSingleView" (click)="isSingleView = true">
|
||||
Security Cameras
|
||||
|
||||
<button class="single-view-button"
|
||||
nbButton
|
||||
[appearance]="isSingleView ? 'filled' : 'outline'"
|
||||
(click)="isSingleView = true">
|
||||
<i class="nb-square"></i>
|
||||
</a>
|
||||
<a [class.active]="!isSingleView" (click)="isSingleView = false">
|
||||
<i class="nb-grid-a"></i>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
<button class="grid-view-button"
|
||||
nbButton
|
||||
[appearance]="isSingleView ? 'outline' : 'filled'"
|
||||
(click)="isSingleView = false">
|
||||
<nb-icon icon="grid" pack="eva"></nb-icon>
|
||||
</button>
|
||||
</nb-card-header>
|
||||
<nb-card-body>
|
||||
<div class="cameras single-view" *ngIf="isSingleView">
|
||||
|
||||
<div class="grid-container">
|
||||
|
||||
<div class="single-view" *ngIf="isSingleView">
|
||||
<div class="camera" [style.background-image]="'url(' + selectedCamera.source + ')'">
|
||||
<span>{{ selectedCamera.title }}</span>
|
||||
<span class="camera-name">{{ selectedCamera.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cameras" *ngIf="!isSingleView">
|
||||
<div class="camera col-sm-6" *ngFor="let camera of cameras" [style.background-image]="'url(' + camera.source + ')'"
|
||||
|
||||
<div class="grid-view" *ngIf="!isSingleView">
|
||||
<div class="camera"
|
||||
*ngFor="let camera of cameras"
|
||||
[style.background-image]="'url(' + camera.source + ')'"
|
||||
(click)="selectCamera(camera)">
|
||||
<span>{{ camera.title }}</span>
|
||||
<span class="camera-name">{{ camera.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</nb-card-body>
|
||||
|
||||
</div>
|
||||
|
||||
<nb-card-footer>
|
||||
<nb-actions size="medium" fullWidth>
|
||||
<nb-actions [size]="actionSize" fullWidth>
|
||||
<nb-action>
|
||||
<i class="nb-pause-outline"></i><span>Pause</span>
|
||||
<nb-icon icon="pause-circle-outline" pack="eva"></nb-icon>
|
||||
Pause
|
||||
</nb-action>
|
||||
<nb-action>
|
||||
<i class="nb-list"></i><span>Logs</span>
|
||||
<nb-icon icon="list-outline" pack="eva"></nb-icon>
|
||||
Logs
|
||||
</nb-action>
|
||||
<nb-action>
|
||||
<i class="nb-search"></i><span>Search</span>
|
||||
<nb-icon icon="search-outline" pack="eva"></nb-icon>
|
||||
Search
|
||||
</nb-action>
|
||||
<nb-action>
|
||||
<i class="nb-gear"></i><span>Setup</span>
|
||||
<nb-icon icon="settings-2-outline" pack="eva"></nb-icon>
|
||||
Setup
|
||||
</nb-action>
|
||||
</nb-actions>
|
||||
</nb-card-footer>
|
||||
|
|
|
|||
|
|
@ -3,96 +3,72 @@
|
|||
@import '~bootstrap/scss/mixins/breakpoints';
|
||||
|
||||
@include nb-install-component() {
|
||||
|
||||
nb-card-header {
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
nb-card-body {
|
||||
padding: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
nb-card-footer {
|
||||
padding: 1rem 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.cameras-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cameras-card-title {
|
||||
flex: 1;
|
||||
padding: 1.25rem;
|
||||
.single-view-button {
|
||||
.nb-square {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
@include nb-ltr {
|
||||
margin-left: auto;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
@include nb-rtl {
|
||||
margin-right: auto;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cameras-filter {
|
||||
.grid-view-button {
|
||||
::ng-deep svg {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
@include nb-ltr {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
@include nb-rtl {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
||||
a {
|
||||
font-size: 2.5rem;
|
||||
padding: 0 0.75rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
color: nb-theme(color-fg);
|
||||
}
|
||||
|
||||
a:first-child {
|
||||
@include nb-ltr(border-left, 1px solid nb-theme(separator));
|
||||
@include nb-rtl(border-right, 1px solid nb-theme(separator));
|
||||
.single-view,
|
||||
.grid-view {
|
||||
flex: 1 0 100%;
|
||||
}
|
||||
|
||||
a:last-child {
|
||||
@include nb-ltr(border-top-right-radius, nb-theme(card-border-radius));
|
||||
@include nb-rtl(border-top-left-radius, nb-theme(card-border-radius));
|
||||
}
|
||||
|
||||
a.active {
|
||||
background-color: nb-theme(color-bg-active);
|
||||
color: nb-theme(color-fg-heading);
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.cameras {
|
||||
position: absolute;
|
||||
.grid-view {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.camera {
|
||||
flex: 1 0 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.single-view .camera {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.cameras.single-view {
|
||||
.camera {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
&::before {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.camera {
|
||||
position: relative;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
height: 50%;
|
||||
padding: 0;
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
color: white;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
font-family: nb-theme(font-secondary);
|
||||
font-weight: nb-theme(font-weight-bolder);
|
||||
font-size: 1.25rem;
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
|
|
@ -108,69 +84,29 @@
|
|||
}
|
||||
}
|
||||
|
||||
.camera-name {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
color: white;
|
||||
background: nb-theme(overlay-backdrop-background-color);
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
nb-action {
|
||||
padding: 0 0.5rem 0 0;
|
||||
nb-icon {
|
||||
@include nb-ltr(margin-right, 0.5rem);
|
||||
@include nb-rtl(margin-left, 0.5rem);
|
||||
}
|
||||
|
||||
i {
|
||||
color: nb-theme(color-fg);
|
||||
font-size: 3rem;
|
||||
margin-right: 0.5rem;
|
||||
|
||||
@include nb-for-theme(corporate) {
|
||||
color: nb-theme(actions-fg);
|
||||
::ng-deep svg {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-family: nb-theme(font-secondary);
|
||||
font-weight: nb-theme(font-weight-bold);
|
||||
color: nb-theme(color-fg-heading);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
@include nb-for-theme(cosmic) {
|
||||
.cameras-filter a.active {
|
||||
color: nb-theme(color-fg-highlight);
|
||||
}
|
||||
|
||||
.camera {
|
||||
span {
|
||||
background: rgba(88, 73, 184, 0.5);
|
||||
}
|
||||
|
||||
&::before {
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
nb-action span {
|
||||
font-weight: nb-theme(font-weight-bolder);
|
||||
}
|
||||
}
|
||||
|
||||
@include nb-for-theme(corporate) {
|
||||
.cameras-filter a {
|
||||
&.active {
|
||||
color: nb-theme(color-primary);
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
@include nb-ltr(border-left, 1px solid nb-theme(border-color));
|
||||
@include nb-rtl(border-right, 1px solid nb-theme(border-color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(lg) {
|
||||
@include media-breakpoint-down(xl) {
|
||||
nb-action {
|
||||
padding: 0;
|
||||
i {
|
||||
margin: 0;
|
||||
}
|
||||
span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,53 @@
|
|||
import { Component, OnDestroy } from '@angular/core';
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { NbComponentSize, NbMediaBreakpointsService, NbThemeService } from '@nebular/theme';
|
||||
|
||||
import { Camera, SecurityCamerasData } from '../../../@core/data/security-cameras';
|
||||
import { takeWhile } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-security-cameras',
|
||||
styleUrls: ['./security-cameras.component.scss'],
|
||||
templateUrl: './security-cameras.component.html',
|
||||
})
|
||||
export class SecurityCamerasComponent implements OnDestroy {
|
||||
export class SecurityCamerasComponent implements OnInit, OnDestroy {
|
||||
|
||||
private alive = true;
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
cameras: Camera[];
|
||||
selectedCamera: Camera;
|
||||
isSingleView = false;
|
||||
actionSize: NbComponentSize = 'medium';
|
||||
|
||||
constructor(private securityCamerasService: SecurityCamerasData) {
|
||||
constructor(
|
||||
private themeService: NbThemeService,
|
||||
private breakpointService: NbMediaBreakpointsService,
|
||||
private securityCamerasService: SecurityCamerasData,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.securityCamerasService.getCamerasData()
|
||||
.pipe(takeWhile(() => this.alive))
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((cameras: Camera[]) => {
|
||||
this.cameras = cameras;
|
||||
this.selectedCamera = this.cameras[0];
|
||||
});
|
||||
|
||||
const breakpoints = this.breakpointService.getBreakpointsMap();
|
||||
this.themeService.onMediaQueryChange()
|
||||
.pipe(map(([, breakpoint]) => breakpoint.width))
|
||||
.subscribe((width: number) => {
|
||||
this.actionSize = width > breakpoints.md ? 'medium' : 'small';
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
selectCamera(camera: any) {
|
||||
this.selectedCamera = camera;
|
||||
this.isSingleView = true;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.alive = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue