mirror of
				https://github.com/avatao-content/frontend-tutorial-framework
				synced 2025-11-04 05:32:55 +00:00 
			
		
		
		
	Merge pull request #54 from avatao-content/message-buttons
Message button support in bot messages
This commit is contained in:
		@@ -28,6 +28,7 @@ import {
 | 
				
			|||||||
} from './services/config.service';
 | 
					} from './services/config.service';
 | 
				
			||||||
import { FSMUpdateService } from './services/fsmupdate.service';
 | 
					import { FSMUpdateService } from './services/fsmupdate.service';
 | 
				
			||||||
import { LoaderComponent } from './loader/loader.component';
 | 
					import { LoaderComponent } from './loader/loader.component';
 | 
				
			||||||
 | 
					import {CapitalizePipe} from './pipes/capitalize.pipe';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@NgModule({
 | 
					@NgModule({
 | 
				
			||||||
@@ -42,6 +43,7 @@ import { LoaderComponent } from './loader/loader.component';
 | 
				
			|||||||
    TestmessengerComponent,
 | 
					    TestmessengerComponent,
 | 
				
			||||||
    SafePipe,
 | 
					    SafePipe,
 | 
				
			||||||
    SafeHtmlPipe,
 | 
					    SafeHtmlPipe,
 | 
				
			||||||
 | 
					    CapitalizePipe,
 | 
				
			||||||
    ConsoleComponent,
 | 
					    ConsoleComponent,
 | 
				
			||||||
    LoaderComponent
 | 
					    LoaderComponent
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,9 @@
 | 
				
			|||||||
<div [attr.class]="layout | async">
 | 
					<div [attr.class]="layout | async">
 | 
				
			||||||
  <div class="tfw-grid-main-components">
 | 
					  <div class="tfw-grid-main-components">
 | 
				
			||||||
    <div class="tfw-header"><app-header></app-header></div>
 | 
					 | 
				
			||||||
    <div [ngClass]="{'hide-attribute': hideMessages | async}" class="tfw-messages">
 | 
					    <div [ngClass]="{'hide-attribute': hideMessages | async}" class="tfw-messages">
 | 
				
			||||||
      <app-messages></app-messages>
 | 
					      <app-messages></app-messages>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="tfw-header"><app-header></app-header></div>
 | 
				
			||||||
    <div class="tfw-web tao-grid-top-left"
 | 
					    <div class="tfw-web tao-grid-top-left"
 | 
				
			||||||
         [ngClass]="{'deploy-blur': deploying || (iframeReloadPoller.isPolling | async)}">
 | 
					         [ngClass]="{'deploy-blur': deploying || (iframeReloadPoller.isPolling | async)}">
 | 
				
			||||||
        <div *ngIf="iframeUrl | async" class="iframe-container">
 | 
					        <div *ngIf="iframeUrl | async" class="iframe-container">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,7 +57,7 @@
 | 
				
			|||||||
  .tfw-messages {
 | 
					  .tfw-messages {
 | 
				
			||||||
    // Check whether the layout contains a web component
 | 
					    // Check whether the layout contains a web component
 | 
				
			||||||
    div[class*="web"] & {
 | 
					    div[class*="web"] & {
 | 
				
			||||||
      border: 2px solid $tao-gray-100;
 | 
					      border: 2px solid $tao-base-color;
 | 
				
			||||||
      border-top: 0;
 | 
					      border-top: 0;
 | 
				
			||||||
      border-left: 0;
 | 
					      border-left: 0;
 | 
				
			||||||
      border-bottom: 0;
 | 
					      border-bottom: 0;
 | 
				
			||||||
@@ -65,17 +65,16 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .tfw-header {
 | 
					  .tfw-header {
 | 
				
			||||||
    padding: $small;
 | 
					    padding: $tiny;
 | 
				
			||||||
    padding-top: $tiny;
 | 
					    padding-top: $hair;
 | 
				
			||||||
    background-color: $tao-gray-50;
 | 
					    background-color: $tao-base-color;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @include set-scrollbar-style('dark', '.tfw-messages');
 | 
					  @include set-scrollbar-style('dark', '.tfw-messages');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .tfw-messages {
 | 
					  .tfw-messages {
 | 
				
			||||||
    padding: $space;
 | 
					    padding: $tiny;
 | 
				
			||||||
    padding-top: $hair;
 | 
					    background-color: $tao-base-color;
 | 
				
			||||||
    background-color: $tao-gray-50;
 | 
					 | 
				
			||||||
    overflow-y: scroll;
 | 
					    overflow-y: scroll;
 | 
				
			||||||
    max-height: 95vmin;
 | 
					    max-height: 95vmin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,3 @@
 | 
				
			|||||||
<div class="tfw-grid-navbar tao-grid-center-center">
 | 
					<div>
 | 
				
			||||||
  <img src="images/avatao_logo.svg" routerLink="/" class="tao-grid-center-left tfw-company-logo" alt="">
 | 
					  <img src="images/avatao-tutorial-framework-logo.svg" routerLink="/" class="tao-grid-center-left tfw-company-logo" alt="">
 | 
				
			||||||
  <span class="tfw-header-title">Tutorials</span>
 | 
					 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,19 +1,8 @@
 | 
				
			|||||||
@import "../../assets/scss/variables.scss";
 | 
					@import "../../assets/scss/variables.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.tfw-header-title {
 | 
					 | 
				
			||||||
  color: $tao-blue-500;
 | 
					 | 
				
			||||||
  font-size: $font-size-h3;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.tfw-grid-navbar {
 | 
					 | 
				
			||||||
  display: grid;
 | 
					 | 
				
			||||||
  grid-template-columns: $company-logo-width 1fr;
 | 
					 | 
				
			||||||
  grid-column-gap: 8px;
 | 
					 | 
				
			||||||
  width: 100%;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.tfw-company-logo {
 | 
					.tfw-company-logo {
 | 
				
			||||||
  display: block;
 | 
					  display: block;
 | 
				
			||||||
  width: $company-logo-width;
 | 
					  padding: $tiny;
 | 
				
			||||||
 | 
					  width: 80%;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,13 @@
 | 
				
			|||||||
import { WebSocketMessage } from './websocket-message';
 | 
					import { WebSocketMessage } from './websocket-message';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type MessageButton = 'yes' | 'no' | 'fix' | 'hint' | 'solution' | 'next';
 | 
				
			||||||
 | 
					export type MessageButtonMap = Record<MessageButton, {caption: string}>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface MessageData {
 | 
					export interface MessageData {
 | 
				
			||||||
  originator?: string;
 | 
					  originator?: string;
 | 
				
			||||||
  timestamp?: Date;
 | 
					  timestamp?: Date;
 | 
				
			||||||
  typing?: boolean;
 | 
					  typing?: boolean;
 | 
				
			||||||
 | 
					  buttons?: MessageButton[];
 | 
				
			||||||
  command?: any;
 | 
					  command?: any;
 | 
				
			||||||
  message: string;
 | 
					  message: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,11 +4,21 @@
 | 
				
			|||||||
       [class.highlighted-message]="last"
 | 
					       [class.highlighted-message]="last"
 | 
				
			||||||
       (click)="sendMessageCommand(message)">
 | 
					       (click)="sendMessageCommand(message)">
 | 
				
			||||||
    <div class="tfw-grid-message-header">
 | 
					    <div class="tfw-grid-message-header">
 | 
				
			||||||
      <img class="tao-grid-center-left" src="images/avataobot.svg"/>
 | 
					 | 
				
			||||||
      <div class="tao-grid-center-left originator">{{message.originator}}</div>
 | 
					      <div class="tao-grid-center-left originator">{{message.originator}}</div>
 | 
				
			||||||
      <div class="timestamp tao-grid-center-right">{{message.timestamp | date:'HH:mm:ss'}}</div>
 | 
					      <div class="timestamp tao-grid-center-right">{{message.timestamp | date:'HH:mm:ss'}}</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="tfw-grid-message-body" [innerHtml]="message.message | safeHtml"></div>
 | 
					    <div class="tfw-grid-message-body" [innerHtml]="message.message | safeHtml"></div>
 | 
				
			||||||
 | 
					    <div *ngIf="message.buttons !== undefined">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <div class="tfw-message-btn-divider"></div>
 | 
				
			||||||
 | 
					      <div class="tfw-message-btn">
 | 
				
			||||||
 | 
					        <button *ngFor="let messageButton of message.buttons"
 | 
				
			||||||
 | 
					             class="{{messageButton}}"
 | 
				
			||||||
 | 
					             (click)="sendButtonCommand(messageButton)">
 | 
				
			||||||
 | 
					          {{buttonMap[messageButton].caption}}
 | 
				
			||||||
 | 
					        </button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <div *ngIf="showTypingIndicator"
 | 
					  <div *ngIf="showTypingIndicator"
 | 
				
			||||||
        class="tfw-grid-message jumping-circle-container"
 | 
					        class="tfw-grid-message jumping-circle-container"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,25 +1,67 @@
 | 
				
			|||||||
@import "../../assets/scss/variables.scss";
 | 
					@import "../../assets/scss/variables.scss";
 | 
				
			||||||
@import "../../assets/scss/mixins/layout";
 | 
					@import "../../assets/scss/mixins/layout";
 | 
				
			||||||
 | 
					@import "../../assets/scss/mixins/button";
 | 
				
			||||||
.tfw-next-button {
 | 
					 | 
				
			||||||
  text-align: center;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
.tfw-grid-message {
 | 
					.tfw-grid-message {
 | 
				
			||||||
 | 
					  font-family: "Roboto";
 | 
				
			||||||
 | 
					  font-style: normal;
 | 
				
			||||||
  display: grid;
 | 
					  display: grid;
 | 
				
			||||||
  grid-template-rows: 1fr auto;
 | 
					  grid-template-rows: 1fr auto;
 | 
				
			||||||
  grid-row-gap: $hair;
 | 
					  grid-row-gap: $nano;
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  padding: $hair;
 | 
				
			||||||
  background-color: $tao-gray-100;
 | 
					 | 
				
			||||||
  border-radius: $tao-panel-border-radius-sm;
 | 
					  border-radius: $tao-panel-border-radius-sm;
 | 
				
			||||||
  padding: $tiny;
 | 
					 | 
				
			||||||
  font-size: $font-size-base;
 | 
					  font-size: $font-size-base;
 | 
				
			||||||
  margin-bottom: $hair;
 | 
					  margin-bottom: $hair;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  animation-name: inflate;
 | 
					  animation-name: inflate;
 | 
				
			||||||
  animation-duration: 0.5s;
 | 
					  animation-duration: 0.5s;
 | 
				
			||||||
  animation-timing-function: cubic-bezier(0.01, 0.1, 0, 1);
 | 
					  animation-timing-function: cubic-bezier(0.01, 0.1, 0, 1);
 | 
				
			||||||
 | 
					  color: white;
 | 
				
			||||||
 | 
					  background-color: $tao-card-color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .tfw-message-btn-divider {
 | 
				
			||||||
 | 
					    opacity: 0.25;
 | 
				
			||||||
 | 
					    border: 1px solid $tao-gray-color;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  .tfw-message-btn {
 | 
				
			||||||
 | 
					    color: $tao-btn-font-color;
 | 
				
			||||||
 | 
					    padding-top: $tiny;
 | 
				
			||||||
 | 
					    padding-bottom: $hair;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .no {
 | 
				
			||||||
 | 
					      @include set-button-style($tao-red-color);
 | 
				
			||||||
 | 
					      width: $xlarge;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .yes {
 | 
				
			||||||
 | 
					      @include set-button-style($tao-green-color);
 | 
				
			||||||
 | 
					      width: $xlarge;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .solution {
 | 
				
			||||||
 | 
					      @include set-button-style($tao-blue-color);
 | 
				
			||||||
 | 
					      width: $xlarge + $medium + $tiny;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .hint {
 | 
				
			||||||
 | 
					      @include set-button-style($tao-yellow-color);
 | 
				
			||||||
 | 
					      width: $xlarge + $medium + $tiny;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .fix {
 | 
				
			||||||
 | 
					      @include set-button-style($tao-yellow-color);
 | 
				
			||||||
 | 
					      width: $xlarge + $medium + $tiny;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .next {
 | 
				
			||||||
 | 
					      @include set-button-style($tao-blue-color);
 | 
				
			||||||
 | 
					      width: $xlarge;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.highlighted-message {
 | 
					.highlighted-message {
 | 
				
			||||||
@@ -65,24 +107,33 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.tfw-grid-message-header {
 | 
					.tfw-grid-message-header {
 | 
				
			||||||
  display: grid;
 | 
					  display: grid;
 | 
				
			||||||
  grid-template-columns: 1fr 5fr 8fr;
 | 
					  grid-template-columns: 5fr 8fr;
 | 
				
			||||||
  grid-column-gap: 4px;
 | 
					  grid-column-gap: 4px;
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  img {
 | 
					 | 
				
			||||||
    width: 12px;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  .originator {
 | 
					  .originator {
 | 
				
			||||||
    font-weight: 500;
 | 
					    font-style: normal;
 | 
				
			||||||
 | 
					    font-weight: bold;
 | 
				
			||||||
 | 
					    font-size: $font-size-base;
 | 
				
			||||||
 | 
					    line-height: 26px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    color: $tao-message-originator-color;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .timestamp {
 | 
					  .timestamp {
 | 
				
			||||||
    font-size: $font-size-tiny;
 | 
					    font-size: $font-size-base;
 | 
				
			||||||
 | 
					    color: $tao-gray-color;
 | 
				
			||||||
    opacity: 0.37;
 | 
					    opacity: 0.37;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.tfw-grid-message-body {
 | 
					.tfw-grid-message-body {
 | 
				
			||||||
  @include word-break()
 | 
					  @include word-break();
 | 
				
			||||||
 | 
					  line-height: 26px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  & p {
 | 
				
			||||||
 | 
					    margin-bottom: $tiny !important;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
import { ChangeDetectorRef, Component, OnInit, EventEmitter, Output, ElementRef } from '@angular/core';
 | 
					import { ChangeDetectorRef, Component, OnInit, EventEmitter, Output, ElementRef } from '@angular/core';
 | 
				
			||||||
import { MessageData, Message } from '../message-types/bot-messages';
 | 
					import {MessageData, Message, MessageButton, MessageButtonMap} from '../message-types/bot-messages';
 | 
				
			||||||
import { MarkdownService } from '../services/markdown.service';
 | 
					import { MarkdownService } from '../services/markdown.service';
 | 
				
			||||||
import { WebSocketService } from '../services/websocket.service';
 | 
					import { WebSocketService } from '../services/websocket.service';
 | 
				
			||||||
import { Subject } from 'rxjs';
 | 
					import { Subject } from 'rxjs';
 | 
				
			||||||
@@ -13,8 +13,15 @@ export class MessagesComponent implements OnInit {
 | 
				
			|||||||
  @Output() newMessageEvent: EventEmitter<any> = new EventEmitter();
 | 
					  @Output() newMessageEvent: EventEmitter<any> = new EventEmitter();
 | 
				
			||||||
  newMessage: Subject<MessageData> = new Subject<MessageData>();
 | 
					  newMessage: Subject<MessageData> = new Subject<MessageData>();
 | 
				
			||||||
  showTypingIndicator = false;
 | 
					  showTypingIndicator = false;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  messages: MessageData[] = [];
 | 
					  messages: MessageData[] = [];
 | 
				
			||||||
 | 
					  buttonMap: MessageButtonMap = {
 | 
				
			||||||
 | 
					    fix: {caption: 'Ready to fix'},
 | 
				
			||||||
 | 
					    solution: {caption: 'Show solution'},
 | 
				
			||||||
 | 
					    hint: {caption: 'Hint'},
 | 
				
			||||||
 | 
					    next: {caption: 'Next'},
 | 
				
			||||||
 | 
					    yes: {caption: 'Yes'},
 | 
				
			||||||
 | 
					    no: {caption: 'No'},
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private markdownService: MarkdownService,
 | 
					    private markdownService: MarkdownService,
 | 
				
			||||||
@@ -71,4 +78,11 @@ export class MessagesComponent implements OnInit {
 | 
				
			|||||||
      this.websocketService.send(message.command);
 | 
					      this.websocketService.send(message.command);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sendButtonCommand(messageButton: MessageButton) {
 | 
				
			||||||
 | 
					    this.websocketService.send({
 | 
				
			||||||
 | 
					      'key': 'message.button.click',
 | 
				
			||||||
 | 
					      'value': messageButton
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								src/app/pipes/capitalize.pipe.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/app/pipes/capitalize.pipe.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import { Pipe, PipeTransform } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Pipe({
 | 
				
			||||||
 | 
					  name: 'capitalize',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CapitalizePipe implements PipeTransform {
 | 
				
			||||||
 | 
					  transform(value: string): string {
 | 
				
			||||||
 | 
					    if (!value) {
 | 
				
			||||||
 | 
					      return '';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return value[0].toLocaleUpperCase() + value.toLocaleLowerCase().slice(1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										9
									
								
								src/assets/images/avatao-tutorial-framework-logo.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/assets/images/avatao-tutorial-framework-logo.svg
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
		 After Width: | Height: | Size: 17 KiB  | 
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
		 Before Width: | Height: | Size: 7.0 KiB  | 
@@ -1 +0,0 @@
 | 
				
			|||||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11.98 16.98"><defs><style>.cls-1{fill:none;stroke:#277eec;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style></defs><title>avataobot</title><rect class="cls-1" x="2.46" y="7.47" width="7.05" height="7.05" transform="translate(9.53 -1.01) rotate(45)"/><polyline class="cls-1" points="10.98 1 5.99 5.99 1 1"/></svg>
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 417 B  | 
@@ -3,6 +3,7 @@
 | 
				
			|||||||
  'grid';
 | 
					  'grid';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@import
 | 
					@import
 | 
				
			||||||
 | 
					  'mixins/button',
 | 
				
			||||||
  'mixins/scrollbar';
 | 
					  'mixins/scrollbar';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@import
 | 
					@import
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
// Spaces
 | 
					// Spaces
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$space: 24px;
 | 
					$space: 32px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$sxlarge: 9 * $space;
 | 
					$sxlarge: 9 * $space;
 | 
				
			||||||
$xxxlarge: 6 * $space;
 | 
					$xxxlarge: 6 * $space;
 | 
				
			||||||
@@ -30,30 +30,6 @@ $tao-blue-700: #195684;
 | 
				
			|||||||
$tao-blue-800: #103B5B;
 | 
					$tao-blue-800: #103B5B;
 | 
				
			||||||
$tao-blue-900: #081A2B;
 | 
					$tao-blue-900: #081A2B;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tao sky palette
 | 
					 | 
				
			||||||
$tao-sky-50:  #F1FAFD;
 | 
					 | 
				
			||||||
$tao-sky-100: #C5E9F5;
 | 
					 | 
				
			||||||
$tao-sky-200: #9AD8EE;
 | 
					 | 
				
			||||||
$tao-sky-300: #6EC7E6;
 | 
					 | 
				
			||||||
$tao-sky-400: #42B7DF;
 | 
					 | 
				
			||||||
$tao-sky-500: #19A7D8;
 | 
					 | 
				
			||||||
$tao-sky-600: #0E8BA8;
 | 
					 | 
				
			||||||
$tao-sky-700: #04647A;
 | 
					 | 
				
			||||||
$tao-sky-800: #004251;
 | 
					 | 
				
			||||||
$tao-sky-900: #002028;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Tao phtalo palette
 | 
					 | 
				
			||||||
$tao-phtalo-50:  #F2FBFC;
 | 
					 | 
				
			||||||
$tao-phtalo-100: #C8EDF1;
 | 
					 | 
				
			||||||
$tao-phtalo-200: #9FDFE6;
 | 
					 | 
				
			||||||
$tao-phtalo-300: #75D1DB;
 | 
					 | 
				
			||||||
$tao-phtalo-400: #4CC3D0;
 | 
					 | 
				
			||||||
$tao-phtalo-500: #24B6C6;
 | 
					 | 
				
			||||||
$tao-phtalo-600: #16989E;
 | 
					 | 
				
			||||||
$tao-phtalo-700: #0C7575;
 | 
					 | 
				
			||||||
$tao-phtalo-800: #034C4F;
 | 
					 | 
				
			||||||
$tao-phtalo-900: #002426;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Tao turqoise palette
 | 
					// Tao turqoise palette
 | 
				
			||||||
$tao-turqoise-50:  #F1FBFB;
 | 
					$tao-turqoise-50:  #F1FBFB;
 | 
				
			||||||
$tao-turqoise-100: #C3EFEF;
 | 
					$tao-turqoise-100: #C3EFEF;
 | 
				
			||||||
@@ -90,29 +66,6 @@ $tao-warm-yellow-700: #CC8B36;
 | 
				
			|||||||
$tao-warm-yellow-800: #B2762F;
 | 
					$tao-warm-yellow-800: #B2762F;
 | 
				
			||||||
$tao-warm-yellow-900: #996526;
 | 
					$tao-warm-yellow-900: #996526;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tao plum palette
 | 
					 | 
				
			||||||
$tao-plum-50:  #F6F8FD;
 | 
					 | 
				
			||||||
$tao-plum-100: #DADFF8;
 | 
					 | 
				
			||||||
$tao-plum-200: #BEC7F3;
 | 
					 | 
				
			||||||
$tao-plum-300: #A2AFED;
 | 
					 | 
				
			||||||
$tao-plum-400: #8797E8;
 | 
					 | 
				
			||||||
$tao-plum-500: #6C80E3;
 | 
					 | 
				
			||||||
$tao-plum-600: #5E77BF;
 | 
					 | 
				
			||||||
$tao-plum-700: #4B5E99;
 | 
					 | 
				
			||||||
$tao-plum-800: #384672;
 | 
					 | 
				
			||||||
$tao-plum-900: #272F4C;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Tao pink palette
 | 
					 | 
				
			||||||
$tao-pink-50:  #FFF0F7;
 | 
					 | 
				
			||||||
$tao-pink-100: #FFBFDF;
 | 
					 | 
				
			||||||
$tao-pink-200: #FF8FC6;
 | 
					 | 
				
			||||||
$tao-pink-300: #FF5EAE;
 | 
					 | 
				
			||||||
$tao-pink-400: #FF2E95;
 | 
					 | 
				
			||||||
$tao-pink-500: #FF007E;
 | 
					 | 
				
			||||||
$tao-pink-600: #D8007C;
 | 
					 | 
				
			||||||
$tao-pink-700: #B20066;
 | 
					 | 
				
			||||||
$tao-pink-800: #8C0050;
 | 
					 | 
				
			||||||
$tao-pink-900: #66003A;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tao red palette
 | 
					// Tao red palette
 | 
				
			||||||
$tao-red-50:  #FFF5F5;
 | 
					$tao-red-50:  #FFF5F5;
 | 
				
			||||||
@@ -138,6 +91,19 @@ $tao-gray-700: #232323;
 | 
				
			|||||||
$tao-gray-800: #0C0C0C;
 | 
					$tao-gray-800: #0C0C0C;
 | 
				
			||||||
$tao-gray-900: #000000;
 | 
					$tao-gray-900: #000000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Tao messages
 | 
				
			||||||
 | 
					$tao-base-color: #2A324C;
 | 
				
			||||||
 | 
					$tao-btn-font-color: #1F2836;
 | 
				
			||||||
 | 
					$tao-card-color: #363E56;
 | 
				
			||||||
 | 
					$tao-message-originator-color: #6697FF;
 | 
				
			||||||
 | 
					$tao-copy-color: #FFFFFF;
 | 
				
			||||||
 | 
					$tao-timestamp-color: #94A6B9;
 | 
				
			||||||
 | 
					$tao-gray-color: #94A6B9; // @25% opacity
 | 
				
			||||||
 | 
					$tao-yellow-color: #FFD68F;
 | 
				
			||||||
 | 
					$tao-blue-color: #6697FF;
 | 
				
			||||||
 | 
					$tao-green-color: #48BEB0;
 | 
				
			||||||
 | 
					$tao-red-color: #FF4583;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Panel border radius
 | 
					// Panel border radius
 | 
				
			||||||
$tao-panel-border-radius:	     14px;
 | 
					$tao-panel-border-radius:	     14px;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										25
									
								
								src/assets/scss/mixins/_button.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/assets/scss/mixins/_button.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					@import "../variables.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@mixin set-button-style($color) {
 | 
				
			||||||
 | 
					  box-sizing: border-box;
 | 
				
			||||||
 | 
					  border-radius: 10px;
 | 
				
			||||||
 | 
					  background: $color;
 | 
				
			||||||
 | 
					  border: 1.5px solid $color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  font-style: normal;
 | 
				
			||||||
 | 
					  font-weight: bold;
 | 
				
			||||||
 | 
					  font-size: 14px;
 | 
				
			||||||
 | 
					  line-height: 26px;
 | 
				
			||||||
 | 
					  height: $space;
 | 
				
			||||||
 | 
					  margin-right: $tiny;
 | 
				
			||||||
 | 
					  color: $tao-btn-font-color;
 | 
				
			||||||
 | 
					  outline: none;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &:active {
 | 
				
			||||||
 | 
					    background: $tao-btn-font-color;
 | 
				
			||||||
 | 
					    border: $tao-btn-font-color;
 | 
				
			||||||
 | 
					    color: $color;
 | 
				
			||||||
 | 
					    border-radius: 10px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2,8 +2,8 @@ $grid-columns-count: 100;
 | 
				
			|||||||
$grid-rows-count: 30;
 | 
					$grid-rows-count: 30;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$terminal-ide-web-layout: (
 | 
					$terminal-ide-web-layout: (
 | 
				
			||||||
  'header': (0, 20, 0, 8),
 | 
					  'messages': (0, 20, 0, 52),
 | 
				
			||||||
  'messages': (0, 20, 8, 60),
 | 
					  'header': (0, 20, 52, 60),
 | 
				
			||||||
  'ide': (56, 96, 0, 100),
 | 
					  'ide': (56, 96, 0, 100),
 | 
				
			||||||
  'terminal': (0, 56, 60, 100),
 | 
					  'terminal': (0, 56, 60, 100),
 | 
				
			||||||
  'web': (20, 56, 0, 60),
 | 
					  'web': (20, 56, 0, 60),
 | 
				
			||||||
@@ -11,8 +11,8 @@ $terminal-ide-web-layout: (
 | 
				
			|||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$terminal-web-layout: (
 | 
					$terminal-web-layout: (
 | 
				
			||||||
  'header': (0, 20, 0, 8),
 | 
					  'messages': (0, 20, 0, 92),
 | 
				
			||||||
  'messages': (0, 20, 8, 100),
 | 
					  'header': (0, 20, 92, 100),
 | 
				
			||||||
  'ide': (),
 | 
					  'ide': (),
 | 
				
			||||||
  'terminal': (56, 96, 0, 100),
 | 
					  'terminal': (56, 96, 0, 100),
 | 
				
			||||||
  'web': (20, 56, 0, 100),
 | 
					  'web': (20, 56, 0, 100),
 | 
				
			||||||
@@ -20,8 +20,8 @@ $terminal-web-layout: (
 | 
				
			|||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$terminal-ide-vertical-layout: (
 | 
					$terminal-ide-vertical-layout: (
 | 
				
			||||||
  'header': (0, 20, 0, 8),
 | 
					  'messages': (0, 20, 0, 92),
 | 
				
			||||||
  'messages': (0, 20, 8, 100),
 | 
					  'header': (0, 20, 92, 100),
 | 
				
			||||||
  'ide': (56, 96, 0, 100),
 | 
					  'ide': (56, 96, 0, 100),
 | 
				
			||||||
  'terminal': (20, 56, 0, 100),
 | 
					  'terminal': (20, 56, 0, 100),
 | 
				
			||||||
  'web': (),
 | 
					  'web': (),
 | 
				
			||||||
@@ -29,8 +29,8 @@ $terminal-ide-vertical-layout: (
 | 
				
			|||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$terminal-ide-horizontal-layout: (
 | 
					$terminal-ide-horizontal-layout: (
 | 
				
			||||||
  'header': (0, 20, 0, 8),
 | 
					  'messages': (0, 20, 0, 92),
 | 
				
			||||||
  'messages': (0, 20, 8, 100),
 | 
					  'header': (0, 20, 92, 100),
 | 
				
			||||||
  'ide': (20, 96, 0, 60),
 | 
					  'ide': (20, 96, 0, 60),
 | 
				
			||||||
  'terminal': (20, 96, 60, 100),
 | 
					  'terminal': (20, 96, 60, 100),
 | 
				
			||||||
  'web': (),
 | 
					  'web': (),
 | 
				
			||||||
@@ -38,8 +38,8 @@ $terminal-ide-horizontal-layout: (
 | 
				
			|||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$ide-web-vertical-layout: (
 | 
					$ide-web-vertical-layout: (
 | 
				
			||||||
  'header': (0, 20, 0, 8),
 | 
					  'messages': (0, 20, 0, 92),
 | 
				
			||||||
  'messages': (0, 20, 8, 100),
 | 
					  'header': (0, 20, 92, 100),
 | 
				
			||||||
  'ide': (56, 96, 0, 100),
 | 
					  'ide': (56, 96, 0, 100),
 | 
				
			||||||
  'terminal': (),
 | 
					  'terminal': (),
 | 
				
			||||||
  'web': (20, 56, 0, 100),
 | 
					  'web': (20, 56, 0, 100),
 | 
				
			||||||
@@ -47,8 +47,8 @@ $ide-web-vertical-layout: (
 | 
				
			|||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$terminal-only-layout: (
 | 
					$terminal-only-layout: (
 | 
				
			||||||
  'header': (0, 20, 0, 8),
 | 
					  'messages': (0, 20, 0, 92),
 | 
				
			||||||
  'messages': (0, 20, 8, 100),
 | 
					  'header': (0, 20, 92, 100),
 | 
				
			||||||
  'ide': (),
 | 
					  'ide': (),
 | 
				
			||||||
  'terminal': (20, 96, 0, 100),
 | 
					  'terminal': (20, 96, 0, 100),
 | 
				
			||||||
  'web': (),
 | 
					  'web': (),
 | 
				
			||||||
@@ -56,8 +56,8 @@ $terminal-only-layout: (
 | 
				
			|||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$ide-only-layout: (
 | 
					$ide-only-layout: (
 | 
				
			||||||
  'header': (0, 20, 0, 8),
 | 
					  'messages': (0, 20, 0, 92),
 | 
				
			||||||
  'messages': (0, 20, 8, 100),
 | 
					  'header': (0, 20, 92, 100),
 | 
				
			||||||
  'ide': (20, 96, 0, 100),
 | 
					  'ide': (20, 96, 0, 100),
 | 
				
			||||||
  'terminal': (),
 | 
					  'terminal': (),
 | 
				
			||||||
  'web': (),
 | 
					  'web': (),
 | 
				
			||||||
@@ -65,8 +65,8 @@ $ide-only-layout: (
 | 
				
			|||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$web-only-layout: (
 | 
					$web-only-layout: (
 | 
				
			||||||
  'header': (0, 20, 0, 8),
 | 
					  'messages': (0, 20, 0, 92),
 | 
				
			||||||
  'messages': (0, 20, 8, 100),
 | 
					  'header': (0, 20, 92, 100),
 | 
				
			||||||
  'ide': (),
 | 
					  'ide': (),
 | 
				
			||||||
  'terminal': (),
 | 
					  'terminal': (),
 | 
				
			||||||
  'web': (20, 96, 0, 100),
 | 
					  'web': (20, 96, 0, 100),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
@mixin set-scrollbar-style($style, $selctor) {
 | 
					@mixin set-scrollbar-style($style, $selector) {
 | 
				
			||||||
  ::-webkit-scrollbar {
 | 
					  ::-webkit-scrollbar {
 | 
				
			||||||
    width: 3px !important;
 | 
					    width: 3px !important;
 | 
				
			||||||
    height: 3px !important;
 | 
					    height: 3px !important;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #{$selctor}::-webkit-scrollbar-track {
 | 
					  #{$selector}::-webkit-scrollbar-track {
 | 
				
			||||||
    border-radius: 10px !important;
 | 
					    border-radius: 10px !important;
 | 
				
			||||||
    width: 3px !important;
 | 
					    width: 3px !important;
 | 
				
			||||||
    @if ($style == 'light') {
 | 
					    @if ($style == 'light') {
 | 
				
			||||||
@@ -15,7 +15,7 @@
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #{$selctor}::-webkit-scrollbar-thumb {
 | 
					  #{$selector}::-webkit-scrollbar-thumb {
 | 
				
			||||||
    @if ($style == 'dark') {
 | 
					    @if ($style == 'dark') {
 | 
				
			||||||
      background: #8a8a8a !important;
 | 
					      background: #8a8a8a !important;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -25,7 +25,7 @@
 | 
				
			|||||||
    border-radius: 10px !important;
 | 
					    border-radius: 10px !important;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #{$selctor}::-webkit-scrollbar-thumb:hover {
 | 
					  #{$selector}::-webkit-scrollbar-thumb:hover {
 | 
				
			||||||
    @if ($style == 'dark') {
 | 
					    @if ($style == 'dark') {
 | 
				
			||||||
      background: #424242 !important;
 | 
					      background: #424242 !important;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,3 +35,4 @@
 | 
				
			|||||||
    cursor: pointer !important;
 | 
					    cursor: pointer !important;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@
 | 
				
			|||||||
  <base href="/">
 | 
					  <base href="/">
 | 
				
			||||||
  <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
					  <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
				
			||||||
  <link rel="icon" type="image/x-icon" href="images/favicon.ico">
 | 
					  <link rel="icon" type="image/x-icon" href="images/favicon.ico">
 | 
				
			||||||
 | 
					  <link href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap" rel="stylesheet" type="text/css">
 | 
				
			||||||
</head>
 | 
					</head>
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
  <app-root></app-root>
 | 
					  <app-root></app-root>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,5 +8,6 @@ body, html {
 | 
				
			|||||||
  height: 100vh;
 | 
					  height: 100vh;
 | 
				
			||||||
  width: 100vw;
 | 
					  width: 100vw;
 | 
				
			||||||
  overflow: hidden;
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @include set-scrollbar-style('light', '');
 | 
					  @include set-scrollbar-style('light', '');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user