Merge pull request #17 from avatao-content/cssdesign

Cssdesign
This commit is contained in:
therealkrispet 2018-03-14 16:58:00 +01:00 committed by GitHub
commit 3b7b597b3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 272 additions and 173 deletions

View File

@ -9,7 +9,7 @@ import { AceEditorModule } from 'ng2-ace-editor';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard/dashboard.component'; import { DashboardComponent } from './dashboard/dashboard.component';
import { HeaderComponent } from './header/header.component'; import { HeaderComponent } from './header/header.component';
import { LoginComponent } from './login/login.component'; import { LoginComponent } from './web/web.component';
import { MarkdownService } from './services/markdown.service'; import { MarkdownService } from './services/markdown.service';
import { TerminadoService } from './services/terminado.service'; import { TerminadoService } from './services/terminado.service';
import { WebideComponent } from './webide/webide.component'; import { WebideComponent } from './webide/webide.component';
@ -20,6 +20,7 @@ import { FSMUpdateService } from './services/fsmupdate.service';
import { ProcessManagerService } from './services/processmanager.service'; import { ProcessManagerService } from './services/processmanager.service';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { TestmessengerComponent } from './testmessenger/testmessenger.component'; import { TestmessengerComponent } from './testmessenger/testmessenger.component';
import { DeploymentNotificationService } from './services/deployment-notification.service';
@NgModule({ @NgModule({
@ -46,7 +47,8 @@ import { TestmessengerComponent } from './testmessenger/testmessenger.component'
WebSocketService, WebSocketService,
TerminadoService, TerminadoService,
FSMUpdateService, FSMUpdateService,
ProcessManagerService ProcessManagerService,
DeploymentNotificationService
], ],
bootstrap: [ bootstrap: [
AppComponent AppComponent

View File

@ -1,7 +1,17 @@
<app-header></app-header>
<div class="tfw-grid-main-components"> <div class="tfw-grid-main-components">
<div class="tfw-header"><app-header></app-header></div>
<div class="tfw-messages"><app-messages></app-messages></div> <div class="tfw-messages"><app-messages></app-messages></div>
<div class="tfw-web tao-grid-top-left"><app-login></app-login></div> <div class="tfw-web tao-grid-top-left"
[ngClass]="{ 'deploy-blur': deploying }">
<div class="iframe-container">
<iframe class="iframe"
scrolling="yes" frameborder="0"
src="about:blank"></iframe>
</div>
</div>
<div class="tfw-webide"><app-webide></app-webide></div> <div class="tfw-webide"><app-webide></app-webide></div>
<div class="tfw-terminal"><app-terminal></app-terminal></div> <div class="tfw-terminal">
<app-terminal></app-terminal>
</div>
<div class="tfw-terminal-footer"></div>
</div> </div>

View File

@ -1,72 +1,60 @@
$space: 24px; @import "../../assets/scss/variables.scss";
@import "../../assets/scss/mixins/layout.scss";
$tao-plum-900: #272F4C;
$tao-gray-50: #FAFAFA;
$tao-navbar-height: 67px;
$layout-template: "default"; // Change this to switch template
$default-layout: (
'messages': (1, 2, 1, 4),
'webide': (4, -1, 1, -1),
'terminal': (1, 4, 4, -1),
'web': (2, 4, 1, 4)
);
$raw-layout: (
'messages': (1, 2, 1, -1),
'webide': (4, -1, 1, -1),
'terminal': (2, 4, 1, -1),
'web': (),
);
$layout: (
"default": $default-layout,
"raw": $raw-layout
);
@mixin position-grid-items($map, $sel) {
$sel: if($sel == '' and &, &, $sel);
@debug $sel;
#{$sel} {
@each $k, $v in $map {
@at-root #{$sel}#{$k} {
@if (length($v) == 0) {
display: none
}
@else {
grid-column-start: nth($v, 1);
grid-column-end: nth($v, 2);
grid-row-start: nth($v, 3);
grid-row-end: nth($v, 4);
}
}
}
}
}
.tfw-grid-main-components { .tfw-grid-main-components {
overflow-y: hidden;
display: grid; display: grid;
padding-top: $tao-navbar-height;
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
justify-content: center; justify-content: center;
align-content: center; align-content: center;
grid-template-columns: repeat(5, 1fr); grid-template-columns: repeat($grid-columns-count, 1fr);
grid-template-rows: repeat(5, 1fr); grid-template-rows: repeat($grid-rows-count, 1fr);
@include position-grid-items(map_get($layout,$layout-template),'.tfw-'); @include position-grid-items(map_get($layout,$layout-template),'.tfw-');
.tfw-web { .tfw-header,
padding: $space; .tfw-messages {
@if ($layout-template == 'default') {
border: 2px solid $tao-gray-100;
border-top: 0;
border-left: 0;
border-bottom: 0;
}
}
.tfw-header {
padding: $small;
background-color: $tao-gray-50;
} }
.tfw-messages { .tfw-messages {
padding: $space; padding: $space;
padding-top: $hair;
background-color: $tao-gray-50; background-color: $tao-gray-50;
overflow-y: scroll;
@if ($layout-template != 'default') {
max-height: 95vmin;
}
@else {
max-height: 55vmin;
}
}
.tfw-web {
.iframe-container {
display: flex;
overflow: hidden;
@include set-component-size('web');
}
.iframe {
flex-grow: 1;
border: none;
margin: 0;
padding: $small;
}
} }
.tfw-webide { .tfw-webide {
@ -74,6 +62,18 @@ $layout: (
} }
.tfw-terminal { .tfw-terminal {
} overflow-y: hidden;
border: 1px solid $tao-plum-100;
border-bottom: 0;
background-color: $tao-gray-800;
@if ($layout-template != 'vraw') {
border-left: 0;
}
}
} }
.deploy-blur {
filter: blur(3px);
}

View File

@ -1,10 +1,28 @@
import { Component } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { DeploymentNotificationService } from '../services/deployment-notification.service';
import { Subscription } from 'rxjs/Subscription';
@Component({ @Component({
selector: 'app-dashboard', selector: 'app-dashboard',
templateUrl: './dashboard.component.html', templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss'] styleUrls: ['./dashboard.component.scss']
}) })
export class DashboardComponent { export class DashboardComponent implements OnInit, OnDestroy {
constructor() {}
deploying = false;
deploymentNotificationSubscription: Subscription;
constructor(private deploymentNotificationService: DeploymentNotificationService) {}
ngOnInit() {
this.deploymentNotificationSubscription = this.deploymentNotificationService.deploying.subscribe(
(deploying) => this.deploying = deploying
);
}
ngOnDestroy() {
if (this.deploymentNotificationSubscription) {
this.deploymentNotificationSubscription.unsubscribe();
}
}
} }

View File

@ -1,11 +1,4 @@
<nav class="navbar navbar-default navbar-expand-md navbar-light tfw-navbar fixed-top"> <div class="tfw-grid-navbar tao-grid-center-center">
<div class="tfw-grid-navbar">
<!-- <ul class="navbar-nav tao-grid-center-right">
<li class="nav-item tao-header-title">an</li>
</ul>-->
<img src="images/avatao_logo.svg" routerLink="/" class="tao-grid-center-left tfw-company-logo" alt=""> <img src="images/avatao_logo.svg" routerLink="/" class="tao-grid-center-left tfw-company-logo" alt="">
<ul class="navbar-nav"> <span class="tfw-header-title">Tutorials</span>
<li class="nav-item tfw-header-title">Tutorials</li> </div>
</ul>
</div>
</nav>

View File

@ -1,24 +1,10 @@
$tao-blue-500: #277EEC; @import "../../assets/scss/variables.scss";
$font-size-base: 14px;
$font-size-h3: floor(($font-size-base * 1.3));
$tao-navbar-height: 67px;
$company-logo-width: 130px;
.tfw-header-title { .tfw-header-title {
color: $tao-blue-500; color: $tao-blue-500;
font-size: $font-size-h3; font-size: $font-size-h3;
} }
.tfw-navbar {
background-color: rgba(255, 255, 255, 0.96);
min-height: $tao-navbar-height;
box-shadow: 0px 1px 6px 0px #888;
margin-bottom: 12px;
border: 1px solid #e7e7e7;
}
.tfw-grid-navbar { .tfw-grid-navbar {
display: grid; display: grid;
grid-template-columns: $company-logo-width 1fr; grid-template-columns: $company-logo-width 1fr;
@ -31,29 +17,3 @@ $company-logo-width: 130px;
width: $company-logo-width; width: $company-logo-width;
} }
.tfw-company-logo-mobile {
display: none;
width: 130px;
}
@media (max-width: 767px) {
.tfw-grid-navbar {
grid-template-columns: 1fr;
}
.tfw-company-logo {
display: none;
}
.tfw-company-logo-mobile {
display: block;
}
.tfw-navbar-links {
justify-self: left !important;
}
}
.jumbotron {
padding: 2vh;
}

View File

@ -1,5 +1,8 @@
<div class="tfw-messages-main"> <div class="tfw-messages-main">
<h5>Instructions</h5> <div class="tfw-grid-messages-header">
<div class="tao-grid-top-left"><span>Instructions</span></div>
<div class="tao-grid-center-right"><button class="tao-btn-rainbow">Next</button></div>
</div>
<div class="tfw-grid-message" *ngFor="let message of messages.slice().reverse()"> <div class="tfw-grid-message" *ngFor="let message of messages.slice().reverse()">
<div class="tfw-grid-message-header"> <div class="tfw-grid-message-header">
<img class="tao-grid-center-left" src="images/avataobot.svg"/> <img class="tao-grid-center-left" src="images/avataobot.svg"/>
@ -9,3 +12,4 @@
<div [innerHtml]="message.message"></div> <div [innerHtml]="message.message"></div>
</div> </div>
</div> </div>

View File

@ -1,28 +1,21 @@
$space: 24px; @import "../../assets/scss/variables.scss";
$small: 0.75 * $space;
$tiny: 0.5 * $space;
$hair: 0.25 * $space;
$tao-blue-500: #277EEC;
$tao-gray-100: #F2F2F2;
$tao-panel-border-radius-sm: 8px;
$font-size-tiny: 12px;
$font-size-base: 14px;
.tfw-messages-main { .tfw-messages-main {
max-height: 50vmin;
overflow-y: scroll;
h5 {
.tfw-grid-messages-header {
display: grid;
grid-template-columns: 1fr 1fr;
margin-bottom: $small; margin-bottom: $small;
span {
color: $tao-blue-500; color: $tao-blue-500;
font-weight: 500; font-weight: 500;
font-size: $font-size-h3;
} }
}
} }
.tfw-grid-message { .tfw-grid-message {

View File

@ -0,0 +1,11 @@
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class DeploymentNotificationService {
deploying: Subject<boolean> = new Subject<boolean>();
constructor() { }
}

View File

@ -11,7 +11,32 @@ export class TerminadoService {
constructor() { constructor() {
Terminal.applyAddon(fit); Terminal.applyAddon(fit);
Terminal.applyAddon(terminado); Terminal.applyAddon(terminado);
this.xterm = new Terminal(); this.xterm = new Terminal({
theme: {
foreground: '#ffffff',
background: '#0C0C0C', // $tao-gray-800
cursor: '#ffffff',
selection: 'rgba(255, 255, 255, 0.3)',
black: '#000000',
red: '#FF5252', // $tao-red-500
brightRed: '#FF7171', // $tao-red-400
green: '#2fd19f', // $tao-bright-green-500
brightGreen: '#2fd19f', // $tao-bright-green-500
brightYellow: '#FFD283', // $tao-warm-yellow-300
yellow: '#FFB83B', // $tao-warm-yellow-500
magenta: '#FF8FC6', // $tao-pink-200
brightMagenta: '#FF8FC6', // $tao-pink-200
cyan: '#277EEC', // $tao-blue-500
blue: '#277EEC', // $tao-blue-500
brightCyan: '#42B7DF', // $tao-sky-400
brightBlue: '#19A7D8', // $tao-sky-500
white: '#FAFAFA', // $tao-gray-50
brightBlack: '#808080',
brightWhite: '#ffffff'
},
fontSize: 14
});
const wsproto = (location.protocol === 'https:') ? 'wss://' : 'ws://'; const wsproto = (location.protocol === 'https:') ? 'wss://' : 'ws://';
this.ws = new WebSocket(wsproto + window.location.host + '/terminal'); this.ws = new WebSocket(wsproto + window.location.host + '/terminal');
} }

View File

@ -1 +1 @@
<div #xterm class="tfw-xterm mt-3 mb-3" (window:resize)="fit()"></div> <div #xterm class="tfw-xterm" (window:resize)="fit()"></div>

View File

@ -0,0 +1,14 @@
@import "../../assets/scss/mixins/layout.scss";
@import "../../app/dashboard/dashboard.component.scss";
.tfw-xterm {
max-height: 100%;
height: 100%;
min-height: 100%;
}

View File

@ -1,3 +1,4 @@
<!--
<div> <div>
<h1>Login page</h1> <h1>Login page</h1>
<form #loginForm="ngForm" (submit)="onSubmit()" [hidden]="submitted"> <form #loginForm="ngForm" (submit)="onSubmit()" [hidden]="submitted">
@ -23,7 +24,7 @@
[(ngModel)]="model.password" [(ngModel)]="model.password"
> >
</div> </div>
<button type="submit" class="btn btn-primary">Submit</button> <button type="submit" class="btn tao-btn-primary">Submit</button>
</form> </form>
<div [hidden]="!submitted"> <div [hidden]="!submitted">
<p> <p>
@ -31,6 +32,8 @@
You <em><span *ngIf="!is_admin">don't </span>have</em> admin privileges. You <em><span *ngIf="!is_admin">don't </span>have</em> admin privileges.
</p> </p>
</div> </div>
</div>
-->
<div class="iframe-container">
</div> </div>

View File

@ -1,21 +1,25 @@
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { Login } from './login'; import { Login } from './web';
import { DeploymentNotificationService } from '../services/deployment-notification.service';
import { Subscription } from 'rxjs/Subscription';
@Component({ @Component({
selector: 'app-login', selector: 'app-web',
templateUrl: './login.component.html', templateUrl: './web.component.html',
styleUrls: ['./login.component.scss'] styleUrls: ['./web.component.scss']
}) })
export class LoginComponent implements OnInit { export class LoginComponent {
model = new Login('', ''); model = new Login('', '');
submitted = false; submitted = false;
is_admin: boolean; is_admin: boolean;
logged_in_email: string; logged_in_email: string;
constructor( constructor(
private http: HttpClient private http: HttpClient
) {} ) {}
onSubmit() { onSubmit() {
this.postLogin(this.model).subscribe( this.postLogin(this.model).subscribe(
res => { res => {
@ -27,8 +31,6 @@ export class LoginComponent implements OnInit {
} }
postLogin(login: Login): Observable<any> { postLogin(login: Login): Observable<any> {
return this.http.post<Login>('/login', login); return this.http.post<Login>('/web', login);
} }
ngOnInit() {}
} }

View File

@ -1,4 +1,4 @@
<div class="tfw-grid-container"> <div class="tfw-grid-webide-statusbar">
<div class="btn-group btn-group-sm flex-wrap tao-grid-center-left"> <div class="btn-group btn-group-sm flex-wrap tao-grid-center-left">
<button *ngFor="let file of files" <button *ngFor="let file of files"
class="btn tfw-tab-btn" class="btn tfw-tab-btn"

View File

@ -1,24 +1,12 @@
$space: 24px; @import "../../assets/scss/variables.scss";
$small: 0.75 * $space; .tfw-grid-webide-statusbar {
$tao-bright-green-100: #c5f2e4;
$tao-bright-green-200: #a0ead3;
$tao-warm-yellow-200: #FFE0A9;
$tao-warm-yellow-600: #E59C3C;
$tao-plum-200: #BEC7F3;
$tao-plum-900: #272F4C;
$tao-red-500: #FF5252;
.tfw-grid-container {
display: grid; display: grid;
height: $tao-navbar-height;
grid-template-columns: 8fr 1fr; grid-template-columns: 8fr 1fr;
} }
.tfw-ace-editor { .tfw-ace-editor {
height: 100%; height: calc(100% - 67px);
width: 100%; width: 100%;
} }
@ -40,12 +28,15 @@ $tao-red-500: #FF5252;
.disabled, .disabled,
&:disabled { &:disabled {
background-color: $tao-plum-200; background-color: $tao-plum-200;
font-weight: 500;
font-style: italic;
color: black; color: black;
border: 0;
} }
} }
.tfw-deploy-btn-group { .tfw-deploy-btn-group {
margin: $small; margin: auto $tiny;
.tfw-deploy-btn { .tfw-deploy-btn {
background: $tao-bright-green-200; background: $tao-bright-green-200;
@ -97,4 +88,3 @@ $tao-red-500: #FF5252;
} }
} }

View File

@ -15,6 +15,7 @@ import 'brace/theme/cobalt';
import { SourceCode } from './source-code'; import { SourceCode } from './source-code';
import { WebSocketService } from '../services/websocket.service'; import { WebSocketService } from '../services/websocket.service';
import { ProcessManagerService } from '../services/processmanager.service'; import { ProcessManagerService } from '../services/processmanager.service';
import { DeploymentNotificationService } from '../services/deployment-notification.service';
const modelist = brace.acequire('ace/ext/modelist'); const modelist = brace.acequire('ace/ext/modelist');
@ -45,7 +46,8 @@ export class WebideComponent implements OnInit {
constructor(private webSocketService: WebSocketService, constructor(private webSocketService: WebSocketService,
private changeDetectorRef: ChangeDetectorRef, private changeDetectorRef: ChangeDetectorRef,
private processManagerService: ProcessManagerService) { } private processManagerService: ProcessManagerService,
private deploymentNotificationService: DeploymentNotificationService) { }
ngOnInit() { ngOnInit() {
this.webSocketService.connect(); this.webSocketService.connect();
@ -116,11 +118,12 @@ export class WebideComponent implements OnInit {
setDeployButtonState(state: string) { setDeployButtonState(state: string) {
this.deployButtonState = state; this.deployButtonState = state;
this.deploymentNotificationService.deploying.next(state === 'DEPLOYING' ? true : false);
} }
deployCode() { deployCode() {
this.processManagerService.restartProcess('login'); this.processManagerService.restartProcess('login');
this.deployButtonState = 'DEPLOYING'; this.setDeployButtonState('DEPLOYING');
} }
sendCodeIfDirty() { sendCodeIfDirty() {

View File

@ -1,5 +1,3 @@
@import @import
'variables', 'variables',
'grid'; 'grid';

View File

@ -156,5 +156,9 @@ $font-size-h4: floor(($font-size-base * 1.2));
$font-size-h5: floor(($font-size-base * 1.1)); $font-size-h5: floor(($font-size-base * 1.1));
$tao-navbar-height: 67px; $tao-navbar-height: 67px;
$company-logo-width: 130px;
// Change this to switch template. Options: 'default', 'vraw', 'hraw'
$layout-template: 'default';

View File

@ -0,0 +1,62 @@
$grid-columns-count: 5;
$grid-rows-count: 15;
$default-layout: (
'header': (1, 2, 1, 2),
'messages': (1, 2, 2, 10),
'webide': (4,$grid-rows-count+1, 1, $grid-rows-count+1),
'terminal': (1, 4, 10, $grid-rows-count+1),
'web': (2, 4, 1, 10)
);
$vraw-layout: (
'header': (1, 2, 1, 2),
'messages': (1, 2, 2,$grid-rows-count+1),
'webide': (4,$grid-rows-count+1, 1,$grid-rows-count+1),
'terminal': (2, 4, 1,$grid-rows-count+1),
'web': (),
);
$hraw-layout: (
'header': (1, 2, 1,$grid-rows-count+1),
'messages': (1, 2, 2,$grid-rows-count+1),
'webide': (2,$grid-rows-count+1, 1, 10),
'terminal': (2, $grid-rows-count+1, 10, $grid-rows-count+1),
'web': (),
);
$layout: (
'default': $default-layout,
'vraw': $vraw-layout,
'hraw': $hraw-layout
);
@mixin position-grid-items($map, $sel) {
$sel: if($sel == '' and &, &, $sel);
@debug $sel;
#{$sel} {
@each $k, $v in $map {
@at-root #{$sel}#{$k} {
@if (length($v) == 0) {
display: none
}
@else {
grid-column-start: nth($v, 1);
grid-column-end: nth($v, 2);
grid-row-start: nth($v, 3);
grid-row-end: nth($v, 4);
}
}
}
}
}
@mixin set-component-size($key) {
$columns-count: nth(map_get($default-layout, $key),2) - nth(map_get($default-layout, $key),1);
$rows-count: nth(map_get($default-layout, $key),4) - nth(map_get($default-layout, $key),3);
min-width: #{$columns-count / $grid-columns-count * 100}vw;
min-height: #{$rows-count / $grid-rows-count * 100}vh;
}

View File

@ -24,11 +24,18 @@
padding: 8px 24px; padding: 8px 24px;
} }
&:hover { &:hover
{
background: initial;
background-color: transparent; background-color: transparent;
color: $tao-blue-500; color: $tao-blue-500;
box-shadow: inset 0 0 0 1px $tao-blue-500; box-shadow: inset 0 0 0 1px $tao-blue-500;
} }
&:active {
}
} }
.tao-btn-rainbow { .tao-btn-rainbow {