mirror of
https://github.com/avatao-content/frontend-tutorial-framework
synced 2025-01-15 23:41:55 +00:00
Use fix sidebar to instrument and control layout changes
This commit is contained in:
parent
b460c429e6
commit
959a0df3d6
@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
|
|||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
import { DashboardComponent } from './dashboard/dashboard.component';
|
import { DashboardComponent } from './dashboard/dashboard.component';
|
||||||
import { WebideComponent } from './webide/webide.component';
|
import { IdeComponent } from './ide/ide.component';
|
||||||
import { TerminalComponent } from './terminal/terminal.component';
|
import { TerminalComponent } from './terminal/terminal.component';
|
||||||
import { MessagesComponent } from './messages/messages.component';
|
import { MessagesComponent } from './messages/messages.component';
|
||||||
import { TestmessengerComponent } from './testmessenger/testmessenger.component';
|
import { TestmessengerComponent } from './testmessenger/testmessenger.component';
|
||||||
@ -11,7 +11,7 @@ import { config } from './config';
|
|||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: '', redirectTo: '/dashboard', pathMatch: 'full'},
|
{ path: '', redirectTo: '/dashboard', pathMatch: 'full'},
|
||||||
{ path: config.dashboard.route, component: DashboardComponent},
|
{ path: config.dashboard.route, component: DashboardComponent},
|
||||||
{ path: config.webide.route, component: WebideComponent },
|
{ path: config.ide.route, component: IdeComponent },
|
||||||
{ path: config.terminal.route, component: TerminalComponent },
|
{ path: config.terminal.route, component: TerminalComponent },
|
||||||
{ path: config.messages.route, component: MessagesComponent },
|
{ path: config.messages.route, component: MessagesComponent },
|
||||||
{ path: config.testmessenger.route, component: TestmessengerComponent }
|
{ path: config.testmessenger.route, component: TestmessengerComponent }
|
||||||
|
@ -13,7 +13,7 @@ import { SidebarComponent } from './sidebar/sidebar.component';
|
|||||||
import { LoginComponent } from './web/web.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 { IdeComponent } from './ide/ide.component';
|
||||||
import { MessagesComponent } from './messages/messages.component';
|
import { MessagesComponent } from './messages/messages.component';
|
||||||
import { WebSocketService } from './services/websocket.service';
|
import { WebSocketService } from './services/websocket.service';
|
||||||
import { TerminalComponent } from './terminal/terminal.component';
|
import { TerminalComponent } from './terminal/terminal.component';
|
||||||
@ -30,7 +30,7 @@ import { DeploymentNotificationService } from './services/deployment-notificatio
|
|||||||
HeaderComponent,
|
HeaderComponent,
|
||||||
SidebarComponent,
|
SidebarComponent,
|
||||||
LoginComponent,
|
LoginComponent,
|
||||||
WebideComponent,
|
IdeComponent,
|
||||||
MessagesComponent,
|
MessagesComponent,
|
||||||
TerminalComponent,
|
TerminalComponent,
|
||||||
DashboardComponent,
|
DashboardComponent,
|
||||||
|
@ -1,24 +1,31 @@
|
|||||||
export const config = {
|
export const config = {
|
||||||
dashboard: {
|
dashboard: {
|
||||||
'route': 'dashboard',
|
route: 'dashboard',
|
||||||
'defaultLayout': 'vraw-open'
|
defaultLayout: 'terminal-ide-vertical',
|
||||||
|
enabledLayouts: [
|
||||||
|
'terminal-ide-vertical',
|
||||||
|
'terminal-ide-horizontal',
|
||||||
|
'terminal-only',
|
||||||
|
'ide-only'
|
||||||
|
]
|
||||||
|
|
||||||
},
|
},
|
||||||
webide: {
|
ide: {
|
||||||
'route': 'webide',
|
route: 'ide',
|
||||||
'autoSaveInterval': 444,
|
autoSaveInterval: 444,
|
||||||
'defaultCode': 'Loading your file...',
|
defaultCode: 'Loading your file...',
|
||||||
'defaultLanguage': 'text',
|
defaultLanguage: 'text',
|
||||||
'deployProcessName': 'login',
|
deployProcessName: 'login',
|
||||||
'showDeployButton': true
|
showDeployButton: true
|
||||||
},
|
},
|
||||||
terminal: {
|
terminal: {
|
||||||
'route': 'shell'
|
route: 'shell'
|
||||||
},
|
},
|
||||||
messages: {
|
messages: {
|
||||||
'route': 'messages',
|
route: 'messages',
|
||||||
'showNextButton': false
|
showNextButton: false
|
||||||
},
|
},
|
||||||
testmessenger: {
|
testmessenger: {
|
||||||
'route': 'testmessenger'
|
route: 'testmessenger'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div [attr.tfw-layout]="layout">
|
<div [attr.class]="layout">
|
||||||
<div class="tfw-grid-main-components">
|
<div class="tfw-grid-main-components">
|
||||||
<div class="tfw-header"><app-header></app-header></div>
|
<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>
|
||||||
@ -10,7 +10,9 @@
|
|||||||
src="about:blank"></iframe>
|
src="about:blank"></iframe>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tfw-webide"><app-webide></app-webide></div>
|
<div class="tfw-ide">
|
||||||
|
<app-ide></app-ide>
|
||||||
|
</div>
|
||||||
<div class="tfw-terminal">
|
<div class="tfw-terminal">
|
||||||
<app-terminal></app-terminal>
|
<app-terminal></app-terminal>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,6 +2,24 @@
|
|||||||
@import "../../assets/scss/mixins/layout.scss";
|
@import "../../assets/scss/mixins/layout.scss";
|
||||||
|
|
||||||
|
|
||||||
|
@mixin set-tfw-web($layouts-key) {
|
||||||
|
|
||||||
|
.tfw-web {
|
||||||
|
.iframe-container {
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
@include set-component-size($layouts-key, 'web');
|
||||||
|
}
|
||||||
|
|
||||||
|
.iframe {
|
||||||
|
flex-grow: 1;
|
||||||
|
border: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: $small;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tfw-grid-main-components {
|
.tfw-grid-main-components {
|
||||||
display: grid;
|
display: grid;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
@ -13,7 +31,9 @@
|
|||||||
|
|
||||||
.tfw-header,
|
.tfw-header,
|
||||||
.tfw-messages {
|
.tfw-messages {
|
||||||
@if (str_slice($layout-key, 0, str_length('default')) == 'default') {
|
|
||||||
|
// Check whether the layout contains a web component
|
||||||
|
div[class*="web"] & {
|
||||||
border: 2px solid $tao-gray-100;
|
border: 2px solid $tao-gray-100;
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
@ -31,51 +51,34 @@
|
|||||||
padding-top: $hair;
|
padding-top: $hair;
|
||||||
background-color: $tao-gray-50;
|
background-color: $tao-gray-50;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
max-height: 55vmin;
|
||||||
|
|
||||||
@if (str_slice($layout-key, 0, str_length('default')) != 'default') {
|
div[class*="web"] & {
|
||||||
max-height: 95vmin;
|
max-height: 95vmin;
|
||||||
}
|
}
|
||||||
@else {
|
|
||||||
max-height: 55vmin;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tfw-web {
|
.tfw-ide {
|
||||||
.iframe-container {
|
|
||||||
display: flex;
|
|
||||||
overflow: hidden;
|
|
||||||
@include set-component-size('web');
|
|
||||||
}
|
|
||||||
|
|
||||||
.iframe {
|
|
||||||
flex-grow: 1;
|
|
||||||
border: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: $small;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tfw-webide {
|
|
||||||
background-color: $tao-plum-900;
|
background-color: $tao-plum-900;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tfw-sidebar {
|
.tfw-sidebar {
|
||||||
background-color: $tao-turqoise-800;
|
background-color: $tao-turqoise-300;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
padding-top: 75px;
|
||||||
|
border-left: 1px solid $tao-plum-500;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tfw-terminal {
|
.tfw-terminal {
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
border: 1px solid $tao-plum-100;
|
|
||||||
border-bottom: 0;
|
|
||||||
background-color: $tao-gray-800;
|
background-color: $tao-gray-800;
|
||||||
@if (str_slice($layout-key, 0, str_length('vraw')) == 'vraw') {
|
|
||||||
border-left: 0;
|
div[class*="web"] & {
|
||||||
border-top: 0;
|
border-top: 1px solid $tao-plum-100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,3 +86,39 @@
|
|||||||
.deploy-blur {
|
.deploy-blur {
|
||||||
filter: blur(3px);
|
filter: blur(3px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.terminal-ide-web {
|
||||||
|
@include set-tfw-web('terminal-ide-web');
|
||||||
|
@include position-grid-items(map_get($layouts, 'terminal-ide-web'),'.tfw-');
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-web{
|
||||||
|
@include set-tfw-web('terminal-web');
|
||||||
|
@include position-grid-items(map_get($layouts,'terminal-web'),'.tfw-');
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-ide-vertical {
|
||||||
|
@include position-grid-items(map_get($layouts,'terminal-ide-vertical'),'.tfw-');
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-ide-horizontal {
|
||||||
|
@include position-grid-items(map_get($layouts,'terminal-ide-horizontal'),'.tfw-');
|
||||||
|
}
|
||||||
|
|
||||||
|
.ide-web-vertical {
|
||||||
|
@include set-tfw-web('ide-web-vertical');
|
||||||
|
@include position-grid-items(map_get($layouts,'ide-web-vertical'),'.tfw-');
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-only {
|
||||||
|
@include position-grid-items(map_get($layouts,'terminal-only'),'.tfw-');
|
||||||
|
}
|
||||||
|
|
||||||
|
.ide-only {
|
||||||
|
@include position-grid-items(map_get($layouts,'ide-only'),'.tfw-');
|
||||||
|
}
|
||||||
|
|
||||||
|
.web-only {
|
||||||
|
@include set-tfw-web('web-only');
|
||||||
|
@include position-grid-items(map_get($layouts,'web-only'),'.tfw-');
|
||||||
|
}
|
||||||
|
@ -13,8 +13,7 @@ import { config } from '../config';
|
|||||||
export class DashboardComponent implements OnInit, OnDestroy {
|
export class DashboardComponent implements OnInit, OnDestroy {
|
||||||
deploying = false;
|
deploying = false;
|
||||||
deploymentNotificationSubscription: Subscription;
|
deploymentNotificationSubscription: Subscription;
|
||||||
layout: string = config.dashboard.defaultLayout;
|
layout: string = config.dashboard.defaultLayout ;
|
||||||
layout = 'vraw-closed';
|
|
||||||
command_handlers = {'layout': this.layoutHandler.bind(this)};
|
command_handlers = {'layout': this.layoutHandler.bind(this)};
|
||||||
|
|
||||||
constructor(private deploymentNotificationService: DeploymentNotificationService,
|
constructor(private deploymentNotificationService: DeploymentNotificationService,
|
||||||
@ -33,11 +32,11 @@ export class DashboardComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
layoutHandler(data: LayoutCommand) {
|
layoutHandler(data: LayoutCommand) {
|
||||||
if (data.layout.match('vraw-open|vraw-closed|hraw|default-open|default-closed')) {
|
if (data.layout.match('terminal-ide-vertical|terminal-only|hraw|default-open|default-closed')) {
|
||||||
this.layout = data.layout;
|
this.layout = data.layout;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log('Invalid webide layout "' + data.layout + '" received!');
|
console.log('Invalid ide layout "' + data.layout + '" received!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
src/app/ide/ide.component.html
Normal file
44
src/app/ide/ide.component.html
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<div class="tfw-grid-ide-statusbar">
|
||||||
|
<div class="btn-group btn-group-sm flex-wrap tao-grid-center-left">
|
||||||
|
<button *ngFor="let file of files"
|
||||||
|
class="btn tfw-tab-btn"
|
||||||
|
(click)="tabSwitchButtonHandler(file)"
|
||||||
|
[class.active]="filename === file"
|
||||||
|
[class.disabled]="filename === file"
|
||||||
|
[disabled]="filename === file"
|
||||||
|
[class.tao-tab-btn-saved]="filename === file && codeState === 'SAVED'">
|
||||||
|
<span *ngIf="filename !== file">{{file}}</span>
|
||||||
|
<span *ngIf="filename === file"
|
||||||
|
[class.underline]="codeState === 'DIRTY'">{{file}}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group-sm tfw-deploy-btn-group">
|
||||||
|
<button *ngIf="showDeployButton"
|
||||||
|
type="submit"
|
||||||
|
class="btn tfw-deploy-btn tao-grid-top-center"
|
||||||
|
(click)="sendCodeIfDirty(); deployCode()"
|
||||||
|
[disabled]="deployButtonState === 'DEPLOYING' || deployButtonState === 'DEPLOYED'"
|
||||||
|
[class.deployed]="deployButtonState === 'DEPLOYED'"
|
||||||
|
[class.deploy]="deployButtonState === 'DEPLOYING'"
|
||||||
|
[class.disabled]="deployButtonState === 'DEPLOYING' || deployButtonState === 'DEPLOYED'"
|
||||||
|
[class.failed]="deployButtonState === 'FAILED'"
|
||||||
|
>
|
||||||
|
<span *ngIf="deployButtonState === 'TODEPLOY'">Deploy</span>
|
||||||
|
<span *ngIf="deployButtonState === 'DEPLOYED'">
|
||||||
|
<img src="images/greentick_icon.svg"/>
|
||||||
|
<span>Deployed</span>
|
||||||
|
</span>
|
||||||
|
<span *ngIf="deployButtonState === 'DEPLOYING'"><div class="loader"></div>Reloading app...</span>
|
||||||
|
<span *ngIf="deployButtonState === 'FAILED'">Deployment failed. Retry</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div (keyup)="setCodeState('DIRTY'); setDeployButtonState('TODEPLOY'); resetAutoSaveCountdown()"
|
||||||
|
ace-editor
|
||||||
|
[(text)]="code"
|
||||||
|
[mode]="language"
|
||||||
|
[theme]="theme"
|
||||||
|
class="tfw-ace-editor"
|
||||||
|
>
|
||||||
|
</div>
|
95
src/app/ide/ide.component.scss
Normal file
95
src/app/ide/ide.component.scss
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
@import "../../assets/scss/variables.scss";
|
||||||
|
|
||||||
|
.tfw-grid-ide-statusbar {
|
||||||
|
display: grid;
|
||||||
|
height: $tao-navbar-height;
|
||||||
|
grid-template-columns: 8fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tfw-ace-editor {
|
||||||
|
height: calc(100% - 67px);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group {
|
||||||
|
padding-left: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.underline {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tfw-tab-btn {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid $tao-plum-900;
|
||||||
|
border-left: 0;
|
||||||
|
border-right: 0;
|
||||||
|
border-radius: 100px;
|
||||||
|
padding: 5px 19px;
|
||||||
|
z-index: 200;
|
||||||
|
|
||||||
|
.tfw-tab-btn-saved,
|
||||||
|
.active,
|
||||||
|
.disabled,
|
||||||
|
&:disabled {
|
||||||
|
background-color: $tao-plum-200;
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: italic;
|
||||||
|
color: black;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tfw-deploy-btn-group {
|
||||||
|
margin: auto $tiny;
|
||||||
|
|
||||||
|
.tfw-deploy-btn {
|
||||||
|
background: $tao-bright-green-200;
|
||||||
|
border-radius: 100px;
|
||||||
|
padding: 6px 19px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
position: relative;
|
||||||
|
bottom: 1px;
|
||||||
|
height: $small;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.failed {
|
||||||
|
background-color: $tao-red-500;
|
||||||
|
color:white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled,
|
||||||
|
&.disabled,
|
||||||
|
&.deployed,
|
||||||
|
&.deploy
|
||||||
|
{
|
||||||
|
background-color: $tao-bright-green-100;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.deploy {
|
||||||
|
background-color: $tao-warm-yellow-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
border: 2px solid $tao-warm-yellow-600;
|
||||||
|
border-radius: 50%;
|
||||||
|
border-top: 2px solid $tao-warm-yellow-200;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
animation: spin 2s linear infinite;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 5px;
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
154
src/app/ide/ide.component.ts
Normal file
154
src/app/ide/ide.component.ts
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
import * as brace from 'brace';
|
||||||
|
import 'brace/ext/modelist';
|
||||||
|
|
||||||
|
import 'brace/mode/c_cpp';
|
||||||
|
import 'brace/mode/csharp';
|
||||||
|
import 'brace/mode/java';
|
||||||
|
import 'brace/mode/javascript';
|
||||||
|
import 'brace/mode/json';
|
||||||
|
import 'brace/mode/python';
|
||||||
|
import 'brace/mode/sql';
|
||||||
|
|
||||||
|
import 'brace/theme/cobalt';
|
||||||
|
import { SourceCode } from './source-code';
|
||||||
|
import { WebSocketService } from '../services/websocket.service';
|
||||||
|
import { ProcessManagerService } from '../services/processmanager.service';
|
||||||
|
import { DeploymentNotificationService } from '../services/deployment-notification.service';
|
||||||
|
import { config } from '../config';
|
||||||
|
|
||||||
|
const modelist = brace.acequire('ace/ext/modelist');
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-ide',
|
||||||
|
templateUrl: './ide.component.html',
|
||||||
|
styleUrls: ['./ide.component.scss']
|
||||||
|
})
|
||||||
|
export class IdeComponent implements OnInit {
|
||||||
|
key_id = 'webide';
|
||||||
|
filename = '';
|
||||||
|
code: string = config.ide.defaultCode;
|
||||||
|
language: string = config.ide.defaultLanguage;
|
||||||
|
theme = 'cobalt';
|
||||||
|
directory = '';
|
||||||
|
files: string[];
|
||||||
|
codeState = 'SAVED';
|
||||||
|
deployButtonState = 'DEPLOYED';
|
||||||
|
showDeployButton: boolean = config.ide.showDeployButton;
|
||||||
|
autosave = null;
|
||||||
|
command_handlers = {'reload': this.reloadHandler.bind(this),
|
||||||
|
'read': this.readHandler.bind(this),
|
||||||
|
'select': this.selectHandler.bind(this),
|
||||||
|
'write': this.writeHandler.bind(this),
|
||||||
|
'selectdir': this.selectdirHandler.bind(this)};
|
||||||
|
|
||||||
|
constructor(private webSocketService: WebSocketService,
|
||||||
|
private changeDetectorRef: ChangeDetectorRef,
|
||||||
|
private processManagerService: ProcessManagerService,
|
||||||
|
private deploymentNotificationService: DeploymentNotificationService) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.webSocketService.connect();
|
||||||
|
this.subscribeWS();
|
||||||
|
this.requestCode();
|
||||||
|
this.processManagerService.init();
|
||||||
|
this.processManagerService.subscribeCallback(config.ide.deployProcessName, (event) => { this.setDeployButtonState('DEPLOYED'); });
|
||||||
|
this.processManagerService.subscribeErrorCallback(config.ide.deployProcessName, (event) => { this.setDeployButtonState('FAILED'); });
|
||||||
|
this.resetAutoSaveCountdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribeWS() {
|
||||||
|
this.webSocketService.observeKey<SourceCode>(this.key_id).subscribe((event) => {
|
||||||
|
this.command_handlers[event.data.command](event.data);
|
||||||
|
this.changeDetectorRef.detectChanges();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFileData(data: SourceCode) {
|
||||||
|
this.filename = data.filename;
|
||||||
|
this.directory = data.directory;
|
||||||
|
this.code = (data.content != null) ? data.content : this.code;
|
||||||
|
this.language = modelist.getModeForPath(this.filename).name;
|
||||||
|
this.files = data.files;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectHandler(data: SourceCode) {
|
||||||
|
this.updateFileData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
reloadHandler(data: SourceCode) {
|
||||||
|
this.requestCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
readHandler(data: SourceCode) {
|
||||||
|
if (this.codeState === 'SAVED') {
|
||||||
|
this.updateFileData(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeHandler() {
|
||||||
|
this.setCodeState('SAVED');
|
||||||
|
}
|
||||||
|
|
||||||
|
selectdirHandler(data: SourceCode) {
|
||||||
|
this.updateFileData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
resetAutoSaveCountdown() {
|
||||||
|
if (this.autosave) {
|
||||||
|
clearInterval(this.autosave);
|
||||||
|
}
|
||||||
|
this.autosave = setInterval(() => { this.sendCodeIfDirty(); }, config.ide.autoSaveInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
tabSwitchButtonHandler(file) {
|
||||||
|
if (this.codeState === 'DIRTY') {
|
||||||
|
this.sendCodeContents();
|
||||||
|
}
|
||||||
|
this.selectCode(file);
|
||||||
|
this.requestCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
setCodeState(state: string) {
|
||||||
|
if (state.match('SAVED|DIRTY')) {
|
||||||
|
this.codeState = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setDeployButtonState(state: string) {
|
||||||
|
this.deployButtonState = state;
|
||||||
|
this.deploymentNotificationService.deploying.next(state === 'DEPLOYING' ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
deployCode() {
|
||||||
|
this.processManagerService.restartProcess('login');
|
||||||
|
this.setDeployButtonState('DEPLOYING');
|
||||||
|
}
|
||||||
|
|
||||||
|
sendCodeIfDirty() {
|
||||||
|
if (this.codeState === 'DIRTY') {
|
||||||
|
this.sendCodeContents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendCodeContents() {
|
||||||
|
this.webSocketService.send(this.key_id, {
|
||||||
|
'command': 'write',
|
||||||
|
'content': this.code
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
requestCode() {
|
||||||
|
this.webSocketService.send(this.key_id, {
|
||||||
|
'command': 'read'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
selectCode(filename: string) {
|
||||||
|
this.webSocketService.send(this.key_id, {
|
||||||
|
'command': 'select',
|
||||||
|
'filename': filename
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
7
src/app/ide/source-code.ts
Normal file
7
src/app/ide/source-code.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export interface SourceCode {
|
||||||
|
filename: string;
|
||||||
|
content?: string;
|
||||||
|
files: string[];
|
||||||
|
directory: string;
|
||||||
|
command: string;
|
||||||
|
}
|
@ -1 +1,4 @@
|
|||||||
<div> IDE </div>
|
<div class="tfw-ide-pin">
|
||||||
|
<img src="images/IDE.svg">
|
||||||
|
<img class="active" src="images/IDE_active.svg">
|
||||||
|
</div>
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
@import "../../assets/scss/variables.scss";
|
@import "../../assets/scss/variables.scss";
|
||||||
|
@import "../../assets/scss/mixins/layout.scss";
|
||||||
|
|
||||||
.tfw-webide-pin{
|
img {
|
||||||
|
width: 50px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tfw-ide-pin {
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
& .active {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
1
src/assets/images/IDE.svg
Normal file
1
src/assets/images/IDE.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 6.4 KiB |
1
src/assets/images/IDE_active.svg
Normal file
1
src/assets/images/IDE_active.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 6.8 KiB |
@ -158,3 +158,6 @@ $font-size-h5: floor(($font-size-base * 1.1));
|
|||||||
|
|
||||||
$tao-navbar-height: 67px;
|
$tao-navbar-height: 67px;
|
||||||
$company-logo-width: 130px;
|
$company-logo-width: 130px;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,72 +1,102 @@
|
|||||||
$grid-columns-count: 25;
|
$grid-columns-count: 25;
|
||||||
$grid-rows-count: 25;
|
$grid-rows-count: 25;
|
||||||
|
|
||||||
$layout-key: 'vraw-open';
|
$terminal-ide-web-layout: (
|
||||||
|
|
||||||
$default-open-layout: (
|
|
||||||
'header': (1, 6, 1, 2),
|
'header': (1, 6, 1, 2),
|
||||||
'messages': (1, 6, 2, 10),
|
'messages': (1, 6, 2, 16),
|
||||||
'webide': (15,$grid-columns-count+1, 1, $grid-rows-count+1),
|
'ide': (15,$grid-columns-count, 1, $grid-rows-count+1),
|
||||||
'terminal': (1, 15, 10, $grid-rows-count+1),
|
'terminal': (1, 15, 16, $grid-rows-count+1),
|
||||||
'web': (6, 15, 1, 10),
|
'web': (6, 15, 1, 16),
|
||||||
'sidebar': ()
|
'sidebar': ($grid-columns-count,$grid-columns-count+1, 1,$grid-rows-count+1)
|
||||||
);
|
);
|
||||||
|
|
||||||
$default-closed-layout: (
|
$terminal-web-layout: (
|
||||||
'header': (1, 6, 1, 2),
|
'header': (1, 6, 1, 2),
|
||||||
'messages': (1, 6, 2, 10),
|
'messages': (1, 6, 2, 10),
|
||||||
'webide': (16,$grid-columns-count+1, 1, $grid-rows-count+1),
|
'ide': (),
|
||||||
'terminal': (1, 16, 10, $grid-rows-count+1),
|
'terminal': (15, $grid-columns-count, 10, $grid-rows-count+1),
|
||||||
'web': (6, 15, 1, 10),
|
'web': (6, 15, 1, 10),
|
||||||
'sidebar': ()
|
'sidebar': ($grid-columns-count,$grid-columns-count+1, 1,$grid-rows-count+1)
|
||||||
);
|
);
|
||||||
|
|
||||||
$vraw-open-layout: (
|
$terminal-ide-vertical-layout: (
|
||||||
'header': (1, 6, 1, 2),
|
'header': (1, 6, 1, 2),
|
||||||
'messages': (1, 6, 2,$grid-rows-count+1),
|
'messages': (1, 6, 2,$grid-rows-count+1),
|
||||||
'webide': (16, $grid-columns-count+1, 1,$grid-rows-count+1),
|
'ide': (15, $grid-columns-count, 1,$grid-rows-count+1),
|
||||||
'terminal': (6, 16, 1, $grid-rows-count+1),
|
'terminal': (6, 15, 1, $grid-rows-count+1),
|
||||||
'web': (),
|
'web': (),
|
||||||
'sidebar': (),
|
'sidebar': ($grid-columns-count,$grid-columns-count+1, 1,$grid-rows-count+1)
|
||||||
);
|
);
|
||||||
|
|
||||||
$vraw-closed-layout: (
|
$terminal-ide-horizontal-layout: (
|
||||||
'header': (1, 6, 1, 2),
|
'header': (1, 6, 1, 2),
|
||||||
'messages': (1, 6, 2,$grid-rows-count+1),
|
'messages': (1, 6, 2,$grid-rows-count+1),
|
||||||
'webide': (),
|
'ide': (6,$grid-columns-count, 1, 16),
|
||||||
|
'terminal': (6, $grid-columns-count, 16, $grid-rows-count+1),
|
||||||
|
'web': (),
|
||||||
|
'sidebar': ($grid-columns-count,$grid-columns-count+1, 1,$grid-rows-count+1),
|
||||||
|
);
|
||||||
|
|
||||||
|
$ide-web-vertical-layout: (
|
||||||
|
'header': (1, 6, 1, 2),
|
||||||
|
'messages': (1, 6, 2, $grid-rows-count+1),
|
||||||
|
'ide': (15, $grid-columns-count, 1,$grid-rows-count+1),
|
||||||
|
'terminal': (),
|
||||||
|
'web': (6, 15, 10, $grid-rows-count+1),
|
||||||
|
'sidebar': ($grid-columns-count,$grid-columns-count+1, 1,$grid-rows-count+1)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
$terminal-only-layout: (
|
||||||
|
'header': (1, 6, 1, 2),
|
||||||
|
'messages': (1, 6, 2,$grid-rows-count+1),
|
||||||
|
'ide': (),
|
||||||
'terminal': (6, $grid-columns-count, 1,$grid-rows-count+1),
|
'terminal': (6, $grid-columns-count, 1,$grid-rows-count+1),
|
||||||
'web': (),
|
'web': (),
|
||||||
'sidebar': ($grid-columns-count,$grid-columns-count+1, 1,$grid-rows-count+1)
|
'sidebar': ($grid-columns-count,$grid-columns-count+1, 1,$grid-rows-count+1)
|
||||||
);
|
);
|
||||||
|
|
||||||
$hraw-layout: (
|
$ide-only-layout: (
|
||||||
'header': (1, 4, 1,$grid-rows-count+1),
|
'header': (1, 6, 1, 2),
|
||||||
'messages': (1, 4, 2,$grid-rows-count+1),
|
'messages': (1, 6, 2,$grid-rows-count+1),
|
||||||
'webide': (4,$grid-columns-count+1, 1, 10),
|
'ide': (6, $grid-columns-count, 1,$grid-rows-count+1),
|
||||||
'terminal': (4, $grid-columns-count+1, 10, $grid-rows-count+1),
|
'terminal': (),
|
||||||
'web': (),
|
'web': (),
|
||||||
'sidebar': (),
|
'sidebar': ($grid-columns-count,$grid-columns-count+1, 1,$grid-rows-count+1)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$web-only-layout: (
|
||||||
|
'header': (1, 6, 1, 2),
|
||||||
|
'messages': (1, 6, 2,$grid-rows-count+1),
|
||||||
|
'ide': (),
|
||||||
|
'terminal': (),
|
||||||
|
'web': (6, $grid-columns-count, 1,$grid-rows-count+1),
|
||||||
|
'sidebar': ($grid-columns-count,$grid-columns-count+1, 1,$grid-rows-count+1)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
$layouts: (
|
$layouts: (
|
||||||
'default-open': $default-open-layout,
|
'terminal-ide-web': $terminal-ide-web-layout,
|
||||||
'default-closed': $default-closed-layout,
|
'terminal-web': $terminal-web-layout,
|
||||||
'vraw-open': $vraw-open-layout,
|
'terminal-ide-vertical': $terminal-ide-vertical-layout,
|
||||||
'vraw-closed': $vraw-closed-layout,
|
'terminal-ide-horizontal': $terminal-ide-horizontal-layout,
|
||||||
'hraw': $hraw-layout
|
'ide-web-vertical': $ide-web-vertical-layout,
|
||||||
|
'terminal-only': $terminal-only-layout,
|
||||||
|
'ide-only': $ide-only-layout,
|
||||||
|
'web-only': $web-only-layout
|
||||||
);
|
);
|
||||||
|
|
||||||
@mixin set-layout($layout_key) {
|
@mixin set-layout($layouts-key) {
|
||||||
@if(index(map_keys($layouts), $layout_key)) {
|
@if(index(map_keys($layouts), $layouts-key)) {
|
||||||
$layout: map_get($layouts, $layout_key)
|
$layout: map_get($layouts, $layouts-key)
|
||||||
}
|
}
|
||||||
@else {
|
@else {
|
||||||
@error 'Invalid layout value: "#{$layout_key}"'
|
@error 'Invalid layout value: "#{$layouts-key}"'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@function get-layout(){
|
@function get-layout($layouts-key){
|
||||||
@return map_get($layouts, $layout_key);
|
@return map_get($layouts, $layouts-key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin position-grid-items($map, $sel) {
|
@mixin position-grid-items($map, $sel) {
|
||||||
@ -87,8 +117,8 @@ $layouts: (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin set-component-size($key) {
|
@mixin set-component-size($layouts-key, $layout-key) {
|
||||||
$tfw-component: map_get(get-layout(), $key);
|
$tfw-component: map_get(get-layout($layouts-key), $layout-key);
|
||||||
|
|
||||||
@if (length($tfw-component) > 0) {
|
@if (length($tfw-component) > 0) {
|
||||||
$columns-count: nth($tfw-component,2) - nth($tfw-component,1);
|
$columns-count: nth($tfw-component,2) - nth($tfw-component,1);
|
||||||
@ -100,22 +130,3 @@ $layouts: (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[tfw-layout='vraw-open'] {
|
|
||||||
@include position-grid-items(map_get($layouts,'vraw-open'),'.tfw-');
|
|
||||||
}
|
|
||||||
|
|
||||||
[tfw-layout='vraw-closed'] {
|
|
||||||
@include position-grid-items(map_get($layouts,'vraw-closed'),'.tfw-');
|
|
||||||
}
|
|
||||||
|
|
||||||
[tfw-layout='hraw'] {
|
|
||||||
@include position-grid-items(map_get($layouts,'hraw'),'.tfw-');
|
|
||||||
}
|
|
||||||
|
|
||||||
[tfw-layout='default-open'] {
|
|
||||||
@include position-grid-items(map_get($layouts, 'default-open'),'.tfw-');
|
|
||||||
}
|
|
||||||
|
|
||||||
[tfw-layout='default-closed'] {
|
|
||||||
@include position-grid-items(map_get($layouts,'default-closed'),'.tfw-');
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user