Fix manual and instumented layout changes (force event 'resize')
| @@ -1,13 +1,16 @@ | |||||||
| export const config = { | export const config = { | ||||||
|   dashboard: { |   dashboard: { | ||||||
|     route: 'dashboard', |     route: 'dashboard', | ||||||
|     currentLayout: 'terminal-web', |     currentLayout: 'terminal-ide-web', | ||||||
|     enabledLayouts:  new Set([ |     enabledLayouts:  new Set([ | ||||||
|       'terminal-ide-web', |       'terminal-ide-web', | ||||||
|       'terminal-web', |       'terminal-ide-vertical', | ||||||
|  |       'terminal-ide-horizontal', | ||||||
|       'terminal-only', |       'terminal-only', | ||||||
|       'web-only', |       'terminal-web', | ||||||
|       'ide-only' |       'ide-web-vertical', | ||||||
|  |       'ide-only', | ||||||
|  |       'web-only' | ||||||
|       ]), |       ]), | ||||||
|     allLayouts:  new Set([ |     allLayouts:  new Set([ | ||||||
|       'terminal-ide-web', |       'terminal-ide-web', | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ | |||||||
|         <app-terminal></app-terminal> |         <app-terminal></app-terminal> | ||||||
|     </div> |     </div> | ||||||
|     <div class="tfw-sidebar"> |     <div class="tfw-sidebar"> | ||||||
|       <app-sidebar [layout]="layout"></app-sidebar> |       <app-sidebar (layoutChanged)="setLayout($event)" [layout]="layout"></app-sidebar> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <div class="tfw-terminal-footer"></div> |     <div class="tfw-terminal-footer"></div> | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { Component, OnDestroy, OnInit, ChangeDetectorRef, ViewChild, AfterViewInit } from '@angular/core'; | import { Component, OnDestroy, OnInit, ChangeDetectorRef } from '@angular/core'; | ||||||
| import { DeploymentNotificationService } from '../services/deployment-notification.service'; | import { DeploymentNotificationService } from '../services/deployment-notification.service'; | ||||||
| import { Subscription } from 'rxjs/Subscription'; | import { Subscription } from 'rxjs/Subscription'; | ||||||
| import { WebSocketService } from '../services/websocket.service'; | import { WebSocketService } from '../services/websocket.service'; | ||||||
| @@ -11,16 +11,13 @@ import { SidebarComponent } from '../sidebar/sidebar.component'; | |||||||
|   templateUrl: './dashboard.component.html', |   templateUrl: './dashboard.component.html', | ||||||
|   styleUrls: ['./dashboard.component.scss'] |   styleUrls: ['./dashboard.component.scss'] | ||||||
| }) | }) | ||||||
| export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { | export class DashboardComponent implements OnInit, OnDestroy { | ||||||
|   deploying = false; |   deploying = false; | ||||||
|   deploymentNotificationSubscription: Subscription; |   deploymentNotificationSubscription: Subscription; | ||||||
|   enabledLayouts: Set<string> = config.dashboard.enabledLayouts; |   enabledLayouts: Set<string> = config.dashboard.enabledLayouts; | ||||||
|   layout: string = config.dashboard.currentLayout ; |   layout: string = config.dashboard.currentLayout; | ||||||
|   command_handlers = {'layout': this.layoutHandler.bind(this)}; |   command_handlers = {'layout': this.layoutHandler.bind(this)}; | ||||||
|  |  | ||||||
|   @ViewChild(SidebarComponent) |  | ||||||
|   private sidebarComponent: SidebarComponent; |  | ||||||
|  |  | ||||||
|   constructor(private deploymentNotificationService: DeploymentNotificationService, |   constructor(private deploymentNotificationService: DeploymentNotificationService, | ||||||
|               private webSocketService: WebSocketService, |               private webSocketService: WebSocketService, | ||||||
|               private changeDetectorRef: ChangeDetectorRef) {} |               private changeDetectorRef: ChangeDetectorRef) {} | ||||||
| @@ -36,19 +33,22 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngAfterViewInit() { |  | ||||||
|     this.layout = this.sidebarComponent.layout; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   layoutHandler(data: LayoutCommand) { |   layoutHandler(data: LayoutCommand) { | ||||||
|     if (this.enabledLayouts.has(data.layout)) { |     if (this.enabledLayouts.has(data.layout)) { | ||||||
|       this.layout = data.layout; |       this.setLayout(data.layout); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       console.log('Invalid ide layout "' + data.layout + '" received!'); |       console.log('Invalid ide layout "' + data.layout + '" received!'); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   setLayout(layout: string) { | ||||||
|  |     this.layout = layout; | ||||||
|  |     // We need to trigger a 'resize' event manually, otherwise ace editor stays collapsed | ||||||
|  |     // Ace editors 'resize' event listener requires a parameter of force=true | ||||||
|  |     setTimeout(() => window.dispatchEvent(new Event('resize', {force: true} as any)), 0); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   ngOnDestroy() { |   ngOnDestroy() { | ||||||
|     if (this.deploymentNotificationSubscription) { |     if (this.deploymentNotificationSubscription) { | ||||||
|       this.deploymentNotificationSubscription.unsubscribe(); |       this.deploymentNotificationSubscription.unsubscribe(); | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ 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'; | import { DeploymentNotificationService } from '../services/deployment-notification.service'; | ||||||
| import { config } from '../config'; | import { config } from '../config'; | ||||||
|  | import { element } from 'protractor'; | ||||||
|  |  | ||||||
| const modelist = brace.acequire('ace/ext/modelist'); | const modelist = brace.acequire('ace/ext/modelist'); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { Component, Input, Output, OnInit } from '@angular/core'; | import { Component, Input, Output, EventEmitter } from '@angular/core'; | ||||||
| import { config } from '../config'; | import { config } from '../config'; | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
| @@ -7,14 +7,15 @@ import { config } from '../config'; | |||||||
|   styleUrls: ['./sidebar.component.scss'] |   styleUrls: ['./sidebar.component.scss'] | ||||||
| }) | }) | ||||||
|  |  | ||||||
| export class SidebarComponent implements OnInit { | export class SidebarComponent { | ||||||
|   @Input() @Output() layout: string; |   @Input() layout: string; | ||||||
|  |   @Output() layoutChanged = new EventEmitter<string>(); | ||||||
|   enabledLayouts: Set<string> = config.dashboard.enabledLayouts; |   enabledLayouts: Set<string> = config.dashboard.enabledLayouts; | ||||||
|  |  | ||||||
|   constructor() {} |   constructor() {} | ||||||
|   ngOnInit() { |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   setLayout(layout: string) { |   setLayout(layout: string) { | ||||||
|     this.layout = layout; |     this.layout = layout; | ||||||
|  |     this.layoutChanged.emit(this.layout); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +0,0 @@ | |||||||
| export interface SourceCode { |  | ||||||
|   filename: string; |  | ||||||
|   content?: string; |  | ||||||
|   files: string[]; |  | ||||||
|   directory: string; |  | ||||||
|   command: string; |  | ||||||
| } |  | ||||||
| @@ -1,44 +0,0 @@ | |||||||
| <div class="tfw-grid-webide-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> |  | ||||||
| @@ -1,95 +0,0 @@ | |||||||
| @import "../../assets/scss/variables.scss"; |  | ||||||
|  |  | ||||||
| .tfw-grid-webide-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); } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,154 +0,0 @@ | |||||||
| 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-webide', |  | ||||||
|   templateUrl: './webide.component.html', |  | ||||||
|   styleUrls: ['./webide.component.scss'] |  | ||||||
| }) |  | ||||||
| export class WebideComponent implements OnInit { |  | ||||||
|   key_id = 'webide'; |  | ||||||
|   filename = ''; |  | ||||||
|   code: string = config.webide.defaultCode; |  | ||||||
|   language: string = config.webide.defaultLanguage; |  | ||||||
|   theme = 'cobalt'; |  | ||||||
|   directory = ''; |  | ||||||
|   files: string[]; |  | ||||||
|   codeState = 'SAVED'; |  | ||||||
|   deployButtonState = 'DEPLOYED'; |  | ||||||
|   showDeployButton: boolean = config.webide.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.webide.deployProcessName, (event) => { this.setDeployButtonState('DEPLOYED'); }); |  | ||||||
|     this.processManagerService.subscribeErrorCallback(config.webide.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.webide.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 |  | ||||||
|     }); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| Before Width: | Height: | Size: 6.4 KiB | 
| Before Width: | Height: | Size: 6.8 KiB | 
| Before Width: | Height: | Size: 7.0 KiB | 
| Before Width: | Height: | Size: 12 KiB | 
| Before Width: | Height: | Size: 7.9 KiB | 
| Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB | 
| Before Width: | Height: | Size: 7.8 KiB | 
| Before Width: | Height: | Size: 13 KiB | 
| @@ -1 +0,0 @@ | |||||||
| <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 59"><defs><style>.cls-1{fill:#277eec;}</style></defs><title>terminalonly_active</title><path class="cls-1" d="M65.06,59H2.94C1.32,59,0,57.35,0,55.31V3.69C0,1.65,1.32,0,2.94,0H65.06C66.68,0,68,1.65,68,3.69V55.31C68,57.35,66.68,59,65.06,59ZM2.94,1.05A2.42,2.42,0,0,0,.84,3.69V55.31A2.42,2.42,0,0,0,2.94,58H65.06a2.42,2.42,0,0,0,2.1-2.64V3.69a2.42,2.42,0,0,0-2.1-2.64Z"/><path class="cls-1" d="M18.82,12.75a.16.16,0,0,1,.13.06l12,13.47a1.13,1.13,0,0,1,0,1.58L19,41.33a.18.18,0,0,1-.22,0,.1.1,0,0,1-.05-.17l12-13.47a.93.93,0,0,0,0-1.31L18.68,13a.1.1,0,0,1,.05-.17A.14.14,0,0,1,18.82,12.75Z"/><path class="cls-1" d="M18.82,41.76a.52.52,0,0,1-.27-.07.49.49,0,0,1-.26-.35l0-.18.15-.22,12-13.46a.57.57,0,0,0,0-.82L18.28,13.06v-.27a.53.53,0,0,1,.26-.35l.09,0,.18,0a.56.56,0,0,1,.41.18L31.22,26a1.52,1.52,0,0,1,0,2.08l-12,13.47A.54.54,0,0,1,18.82,41.76Zm-.15-.68h0Zm0-28Z"/><path class="cls-1" d="M18.82,41.63a.54.54,0,0,1-.21-.05.38.38,0,0,1-.19-.26.32.32,0,0,1,.09-.29l12-13.47a.71.71,0,0,0,0-1l-12-13.46a.34.34,0,0,1-.08-.29.38.38,0,0,1,.19-.26.44.44,0,0,1,.52.09l12,13.47a1.37,1.37,0,0,1,0,1.9l-12,13.47A.41.41,0,0,1,18.82,41.63Zm.05-.28h0Zm-.1-.18Zm.09-28.39h0Z"/><path class="cls-1" d="M18.82,42a.79.79,0,0,1-.38-.09.73.73,0,0,1-.39-.52.72.72,0,0,1,.18-.61l12-13.46a.33.33,0,0,0,0-.5l-12-13.47a.68.68,0,0,1-.18-.59.73.73,0,0,1,.39-.53.8.8,0,0,1,1,.17l12,13.47a1.76,1.76,0,0,1,0,2.4l-12,13.47A.77.77,0,0,1,18.82,42Zm0-29.1L30.77,26.33a1.06,1.06,0,0,1,0,1.48l-12,13.47,0,0h0l12-13.46a1,1,0,0,0,0-1.42Z"/><path class="cls-1" d="M44.35,41.93H30.14a.75.75,0,1,1,0-1.5H44.35a.75.75,0,0,1,0,1.5Z"/></svg> |  | ||||||
| Before Width: | Height: | Size: 1.6 KiB | 
| Before Width: | Height: | Size: 6.8 KiB | 
| Before Width: | Height: | Size: 5.7 KiB | 
| @@ -46,7 +46,6 @@ $ide-web-vertical-layout: ( | |||||||
|   '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) | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
| $terminal-only-layout: ( | $terminal-only-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), | ||||||
| @@ -74,7 +73,6 @@ $web-only-layout: ( | |||||||
|   '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) | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
| $layouts: ( | $layouts: ( | ||||||
|   'terminal-ide-web': $terminal-ide-web-layout, |   'terminal-ide-web': $terminal-ide-web-layout, | ||||||
|   'terminal-web': $terminal-web-layout, |   'terminal-web': $terminal-web-layout, | ||||||
| @@ -131,5 +129,3 @@ $layouts: ( | |||||||
|     min-height: #{$rows-count / $grid-rows-count * 100}vh; |     min-height: #{$rows-count / $grid-rows-count * 100}vh; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||