feat(dashboard): add contacts and room selector components

This commit is contained in:
KostyaDanovsky 2017-06-27 12:26:09 +03:00
parent d351b3d6ff
commit 61869dad7a
18 changed files with 374 additions and 19 deletions

View file

@ -0,0 +1,27 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UserService } from './users.service';
const SERVICES = [
UserService,
];
@NgModule({
imports: [
CommonModule,
],
providers: [
...SERVICES,
],
})
export class DataModule {
static forRoot(): ModuleWithProviders {
return <ModuleWithProviders>{
ngModule: DataModule,
providers: [
...SERVICES,
],
};
}
}

View file

@ -0,0 +1,35 @@
import { Injectable } from '@angular/core';
let counter = 0;
@Injectable()
export class UserService {
private users = {
nick: { name: 'Nick Jones', picture: 'assets/images/nick.png' },
eva: { name: 'Eva Moor', picture: 'assets/images/eva.png' },
jack: { name: 'Jack Williams', picture: 'assets/images/jack.png' },
lee: { name: 'Lee Wong', picture: 'assets/images/lee.png' },
alan: { name: 'Alan Thompson', picture: 'assets/images/alan.png' },
kate: { name: 'Kate Martinez', picture: 'assets/images/kate.png' },
};
private userArray: any[];
constructor() {
// this.userArray = Object.values(this.users);
}
getUsers() {
return this.users;
}
getUserArray() {
return this.userArray;
}
getUser() {
counter = (counter + 1) % this.userArray.length;
return this.userArray[counter];
}
}

View file

@ -0,0 +1,13 @@
<nga-card size="xmedium">
<nga-tabset fullWidth>
<nga-tab tabTitle="Contacts">
<div class="contact" *ngFor="let c of contacts">
<nga-user [picture]="c.user.picture" [name]="c.user.name" [title]="c.type" size="xmedium"></nga-user>
<i class="ion-ios-telephone-outline"></i>
</div>
</nga-tab>
<nga-tab tabTitle="Recent">
<span>Content #2</span>
</nga-tab>
</nga-tabset>
</nga-card>

View file

@ -0,0 +1,44 @@
@import '../../../@theme/styles/variables';
@import '~@nga/theme/styles/global/bootstrap/hero-buttons';
@include nga-install-component() {
nga-tabset /deep/ ul {
border-bottom: 1px solid nga-theme(separator);
}
nga-tab {
padding: 0;
}
.contact {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem;
border-bottom: 1px solid nga-theme(separator);
}
i {
font-size: 2.5rem;
cursor: pointer;
}
nga-user /deep/ {
.info-container {
margin-left: 0.875rem;
}
.user-name {
font-size: 1.25rem;
font-weight: nga-theme(font-weight-bolder);
color: nga-theme(color-head);
}
.user-title {
font-size: 0.875rem;
text-transform: uppercase;
}
}
}

View file

@ -0,0 +1,25 @@
import { Component } from '@angular/core';
import { UserService } from '../../../@core/data/users.service';
@Component({
selector: 'ngx-contacts',
styleUrls: ['./contacts.component.scss'],
templateUrl: './contacts.component.html',
})
export class ContactsComponent {
contacts: any[];
constructor(private userService: UserService) {
const users = this.userService.getUsers();
this.contacts = [
{ user: users.nick, type: 'mobile' },
{ user: users.eva, type: 'home' },
{ user: users.jack, type: 'mobile' },
{ user: users.lee, type: 'mobile' },
{ user: users.alan, type: 'home' },
{ user: users.kate, type: 'work' },
];
}
}

View file

@ -34,20 +34,12 @@
Room Management
</nga-card-header>
<nga-card-body>
<ngx-room-selector></ngx-room-selector>
</nga-card-body>
</nga-card>
</div>
<div class="col-lg-3">
<nga-card size="xmedium" class="contacts">
<nga-tabset fullWidth>
<nga-tab tabTitle="Contacts">
<span>Content #1</span>
</nga-tab>
<nga-tab tabTitle="Recent">
<span>Content #2</span>
</nga-tab>
</nga-tabset>
</nga-card>
<ngx-contacts></ngx-contacts>
</div>
</div>

View file

@ -1,12 +1,5 @@
@import '../../@theme/styles/variables';
@import '~@akveo/nga-theme/styles/global/bootstrap/hero-buttons';
@include nga-install-component() {
nga-card-header {
}
nga-card.contacts nga-tabset /deep/ ul {
border-bottom: 1px solid nga-theme(separator);
}
}

View file

@ -1,20 +1,25 @@
import { NgModule } from '@angular/core';
import { NgaTabsetModule } from '@akveo/nga-theme';
import { NgaTabsetModule, NgaUserModule } from '@akveo/nga-theme';
import { SharedModule } from '../../shared.module';
import { DashboardComponent } from './dashboard.component';
import { StatusCardsComponent } from './status-cards/status-cards.component';
import { TemperatureDraggerComponent } from './temperature-dragger/temperature-dragger.component';
import { ContactsComponent } from './contacts/contacts.component';
import { RoomSelectorComponent } from './room-selector/room-selector.component';
@NgModule({
imports: [
SharedModule,
NgaTabsetModule,
NgaUserModule,
SharedModule,
],
declarations: [
DashboardComponent,
StatusCardsComponent,
TemperatureDraggerComponent,
ContactsComponent,
RoomSelectorComponent,
],
})
export class DashboardModule { }

View file

@ -0,0 +1,82 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" [attr.viewBox]="viewBox"
preserveAspectRatio="xMidYMid">
<defs>
<filter id="f2" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur result="blurOut" in="StrokePaint" stdDeviation="10" />
</filter>
<pattern id="New_Pattern_Swatch_1" data-name="New Pattern Swatch 1" width="60" height="60"
patternUnits="userSpaceOnUse" viewBox="0 0 60 60">
<line class="stroke-pattern" x1="-113.26" y1="123.26" x2="3.26" y2="6.74"/>
<line class="stroke-pattern" x1="-103.26" y1="133.26" x2="13.26" y2="16.74"/>
<line class="stroke-pattern" x1="-93.26" y1="143.26" x2="23.26" y2="26.74"/>
<line class="stroke-pattern" x1="-83.26" y1="153.26" x2="33.26" y2="36.74"/>
<line class="stroke-pattern" x1="-73.26" y1="163.26" x2="43.26" y2="46.74"/>
<line class="stroke-pattern" x1="-63.26" y1="173.26" x2="53.26" y2="56.74"/>
<line class="stroke-pattern" x1="-53.26" y1="123.26" x2="63.26" y2="6.74"/>
<line class="stroke-pattern" x1="-43.26" y1="133.26" x2="73.26" y2="16.74"/>
<line class="stroke-pattern" x1="-33.26" y1="143.26" x2="83.26" y2="26.74"/>
<line class="stroke-pattern" x1="-23.26" y1="153.26" x2="93.26" y2="36.74"/>
<line class="stroke-pattern" x1="-13.26" y1="163.26" x2="103.26" y2="46.74"/>
<line class="stroke-pattern" x1="-3.26" y1="173.26" x2="113.26" y2="56.74"/>
<line class="stroke-pattern" x1="6.74" y1="123.26" x2="123.26" y2="6.74"/>
<line class="stroke-pattern" x1="16.74" y1="133.26" x2="133.26" y2="16.74"/>
<line class="stroke-pattern" x1="26.74" y1="143.26" x2="143.26" y2="26.74"/>
<line class="stroke-pattern" x1="36.74" y1="153.26" x2="153.26" y2="36.74"/>
<line class="stroke-pattern" x1="46.74" y1="163.26" x2="163.26" y2="46.74"/>
<line class="stroke-pattern" x1="56.74" y1="173.26" x2="173.26" y2="56.74"/>
<line class="stroke-pattern" x1="-113.26" y1="63.26" x2="3.26" y2="-53.26"/>
<line class="stroke-pattern" x1="-103.26" y1="73.26" x2="13.26" y2="-43.26"/>
<line class="stroke-pattern" x1="-93.26" y1="83.26" x2="23.26" y2="-33.26"/>
<line class="stroke-pattern" x1="-83.26" y1="93.26" x2="33.26" y2="-23.26"/>
<line class="stroke-pattern" x1="-73.26" y1="103.26" x2="43.26" y2="-13.26"/>
<line class="stroke-pattern" x1="-63.26" y1="113.26" x2="53.26" y2="-3.26"/>
<line class="stroke-pattern" x1="-53.26" y1="63.26" x2="63.26" y2="-53.26"/>
<line class="stroke-pattern" x1="-43.26" y1="73.26" x2="73.26" y2="-43.26"/>
<line class="stroke-pattern" x1="-33.26" y1="83.26" x2="83.26" y2="-33.26"/>
<line class="stroke-pattern" x1="-23.26" y1="93.26" x2="93.26" y2="-23.26"/>
<line class="stroke-pattern" x1="-13.26" y1="103.26" x2="103.26" y2="-13.26"/>
<line class="stroke-pattern" x1="-3.26" y1="113.26" x2="113.26" y2="-3.26"/>
<line class="stroke-pattern" x1="6.74" y1="63.26" x2="123.26" y2="-53.26"/>
<line class="stroke-pattern" x1="16.74" y1="73.26" x2="133.26" y2="-43.26"/>
<line class="stroke-pattern" x1="26.74" y1="83.26" x2="143.26" y2="-33.26"/>
<line class="stroke-pattern" x1="36.74" y1="93.26" x2="153.26" y2="-23.26"/>
<line class="stroke-pattern" x1="46.74" y1="103.26" x2="163.26" y2="-13.26"/>
<line class="stroke-pattern" x1="56.74" y1="113.26" x2="173.26" y2="-3.26"/>
<line class="stroke-pattern" x1="-113.26" y1="3.26" x2="3.26" y2="-113.26"/>
<line class="stroke-pattern" x1="-103.26" y1="13.26" x2="13.26" y2="-103.26"/>
<line class="stroke-pattern" x1="-93.26" y1="23.26" x2="23.26" y2="-93.26"/>
<line class="stroke-pattern" x1="-83.26" y1="33.26" x2="33.26" y2="-83.26"/>
<line class="stroke-pattern" x1="-73.26" y1="43.26" x2="43.26" y2="-73.26"/>
<line class="stroke-pattern" x1="-63.26" y1="53.26" x2="53.26" y2="-63.26"/>
<line class="stroke-pattern" x1="-53.26" y1="3.26" x2="63.26" y2="-113.26"/>
<line class="stroke-pattern" x1="-43.26" y1="13.26" x2="73.26" y2="-103.26"/>
<line class="stroke-pattern" x1="-33.26" y1="23.26" x2="83.26" y2="-93.26"/>
<line class="stroke-pattern" x1="-23.26" y1="33.26" x2="93.26" y2="-83.26"/>
<line class="stroke-pattern" x1="-13.26" y1="43.26" x2="103.26" y2="-73.26"/>
<line class="stroke-pattern" x1="-3.26" y1="53.26" x2="113.26" y2="-63.26"/>
<line class="stroke-pattern" x1="6.74" y1="3.26" x2="123.26" y2="-113.26"/>
<line class="stroke-pattern" x1="16.74" y1="13.26" x2="133.26" y2="-103.26"/>
<line class="stroke-pattern" x1="26.74" y1="23.26" x2="143.26" y2="-93.26"/>
<line class="stroke-pattern" x1="36.74" y1="33.26" x2="153.26" y2="-83.26"/>
<line class="stroke-pattern" x1="46.74" y1="43.26" x2="163.26" y2="-73.26"/>
<line class="stroke-pattern" x1="56.74" y1="53.26" x2="173.26" y2="-63.26"/>
</pattern>
</defs>
<g>
<path class="room-border" [attr.d]="border.d" *ngFor="let border of roomSvg.borders" />
</g>
<g>
<path class="stroked-element" [attr.d]="strokedArea.d" *ngFor="let strokedArea of roomSvg.stokedAreas"/>
</g>
<g [attr.id]="room.id" [class.selected-room]="selectedRoom == room.id" *ngFor="let room of sortedRooms">
<path class="room-bg" (click)="roomSelected(room.id)" [attr.d]="room.area.d" />
<path class="room-border" [attr.d]="room.border.d" />
<text class="room-text" (click)="roomSelected(room.id)" text-anchor="middle"
[attr.x]="room.name.x" [attr.y]="room.name.y">{{room.name.text}}</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View file

@ -0,0 +1,59 @@
:host {
display: block;
align-items: center;
width: 100%;
height: 100%;
}
svg {
display:block;
width: 100%;
height: 100%;
}
.stroke-pattern {
fill: none;
stroke: #a1a1e5;
stroke-miterlimit: 10;
opacity: 0.1;
stroke-width: 1px;
}
.stroked-element {
stroke-width: 4px;
stroke: #a1a1e5;
stroke-miterlimit: 10;
fill: url('#New_Pattern_Swatch_1');
}
.room-border {
stroke-width: 4px;
stroke: #a1a1e5;
stroke-miterlimit: 10;
fill: none;
transition: stroke 0.4s ease-out;
}
.room-bg {
fill: transparent;
stroke: transparent;
cursor: pointer;
transition: fill 0.4s ease-out;
}
.room-text {
cursor: pointer;
user-select: none;
}
.selected-room {
z-index: 40;
.room-bg {
stroke: rgba(0, 255, 170, 0.5);
fill: rgba(0, 255, 170, 0.5);
filter: url('#f2');
}
.room-border {
stroke: #00f9a6;
}
}

View file

@ -0,0 +1,78 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-room-selector',
templateUrl: './room-selector.component.html',
styleUrls: ['./room-selector.component.scss'],
})
export class RoomSelectorComponent {
selectedRoom: null;
sortedRooms = [];
viewBox = '-20 -20 608.88 407.99';
roomSvg = {
borders: [{
d: 'M186.21,130.05H216.37V160H186.21Z',
}],
stokedAreas: [
{ d: 'M562.71,225V354h-290V319H418.37a6.09,6.09,0,0,0,6.09-6.09V225Z' },
{ d: 'M8.09,130V347.91A6.09,6.09,0,0,0,14.18,354h54V130Z' },
{ d: 'M216.37,49.82H358.8V92.5H216.37Z' },
],
rooms: [
{
id: '0',
name: { text: 'Kitchen', x: 142, y: 240.8 },
area: { d: 'M68.18,130V359.9A6.09,6.09,0,0,0,74.27,366h136a6.09,6.09,0,0,0,6.09-6.09V160H186.21V130Z' },
border: { d: 'M96,130H68.18V359.9A6.09,6.09,0,0,0,74.27,366h136a6.09,6.09,0,0,0,6.09-6.09V225 M152.71,' +
'130H186.21V160H216.21' },
},
{
id: '1',
name: { text: 'Bedroom', x: 109, y: 66 },
area: { d: 'M152.71,130h63.66V8.09A6.09,6.09,0,0,0,210.27,2H8.09A6.09,6.09,0,0,0,2,8.09V123.95A6.09,' +
'6.09,0,0,0,8.09,130H96Z' },
border: { d: 'M152.71,130h63.66V8.09A6.09,6.09,0,0,0,210.27,2H8.09A6.09,6.09,0,0,0,2,8.09V123.95A6.09' +
',6.09,0,0,0,8.09,130H96' },
},
{
id: '2',
name: { text: 'Living Room', x: 468, y: 134 },
area: { d: 'M358.8,160V49.82a6.09,6.09,0,0,1,6.09-6.09H570.78a6.09,6.09,0,0,1,6.09,6.09V218.9a6.09' +
',6.09,0,0,1-6.09,6.09h-212Z' },
border: { d: 'M358.8,160V49.82a6.09,6.09,0,0,1,6.09-6.09H570.78a6.09,6.09,0,0,1,6.09,6.09V218.9a6.09' +
',6.09,0,0,1-6.09,6.09h-212' },
},
{
id: '3',
name: { text: 'Hallway', x: 320, y: 273 },
area: { d: 'M216.37,354V92.5H358.8V225H424.39V319H272.71V354Z' },
border: { d: 'M216.37,225V354 M216.21,160V92.5H358.8V160 M358.8,225H424.39V312.91a6.09,' +
'6.09,0,0,1,-6.09,6.09H272.71V354' },
},
],
};
constructor() {
this.sortRooms();
}
private sortRooms() {
this.sortedRooms = this.roomSvg.rooms.slice(0).sort((a, b) => {
if (a.id === this.selectedRoom) {
return 1;
}
if (b.id === this.selectedRoom) {
return -1;
}
return 0;
});
}
roomSelected(roomNumber) {
this.selectedRoom = roomNumber;
this.sortRooms();
}
}

View file

@ -8,6 +8,7 @@ import { PagesComponent } from './pages.component';
import { DashboardModule } from './dashboard/dashboard.module';
import { PagesRoutingModule } from './pages-routing.module';
import { ThemeModule } from '../@theme/theme.module';
import { DataModule } from '../@core/data/data.module';
const PAGES_COMPONENTS = [
PagesComponent,
@ -21,6 +22,7 @@ const PAGES_COMPONENTS = [
NgaMenuModule.forRoot({ items: menuItems }),
PagesRoutingModule,
ThemeModule,
DataModule.forRoot(),
DashboardModule,
],
declarations: [

BIN
src/assets/images/alan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

BIN
src/assets/images/eva.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

BIN
src/assets/images/jack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

BIN
src/assets/images/kate.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

BIN
src/assets/images/lee.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

BIN
src/assets/images/nick.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB