Changeset 16723


Ignore:
Timestamp:
Aug 31, 2017, 11:55:56 AM (3 years ago)
Author:
dramos
Message:

front-end updates

Location:
internals/2017/ScheduleOptimizer
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • internals/2017/ScheduleOptimizer/README

    r16708 r16723  
     1STEPS:
     2
     3Backend:
    14./backend/WSListener/WSSolarScheduler/Web.config file is empty, replace it.
     5process table needs a new column (alter table process add column FlexTime int;)
     6
     7
     8Frontend:
     9npm install
     10ng serve (to run a development server)
     11ng build (to compile)
  • internals/2017/ScheduleOptimizer/frontend/src/app/app.component.ts

    r16708 r16723  
    1313
    1414
    15 
    16 
    1715}
  • internals/2017/ScheduleOptimizer/frontend/src/app/app.module.ts

    r16708 r16723  
    1414import { FormComponent } from './form/form.component';
    1515import { ReportComponent } from './report/report.component';
    16 
    1716
    1817
     
    3938    HttpModule,
    4039    RouterModule.forRoot(appRoutes),
    41     FormsModule
     40    FormsModule,
     41
    4242  ],
    4343  providers: [OptimizeService],
  • internals/2017/ScheduleOptimizer/frontend/src/app/form/form.component.css

    r16708 r16723  
     1.loading {
     2  position: absolute;
     3  top:0;
     4  margin :0;
     5  padding: 0;
     6  height: 100%;
     7  width: 100%;
     8  background: rgba(0,0,0,0.8);
     9  z-index: 2;
     10  display: flex;
     11  justify-content: center;
     12  align-items: center;
     13}
     14
     15.loader {
     16  margin:0;
     17  padding:0;
     18  border: 16px solid #f3f3f3; /* Light grey */
     19  border-top: 16px solid #e81e1e; /* Blue */
     20  border-radius: 50%;
     21  width: 120px;
     22  height: 120px;
     23  animation: spin 1s linear infinite;
     24}
     25
     26@keyframes spin {
     27  0% { transform: rotate(0deg); }
     28  100% { transform: rotate(360deg); }
     29}
  • internals/2017/ScheduleOptimizer/frontend/src/app/form/form.component.html

    r16708 r16723  
     1<div *ngIf="loading" class="loading">
     2  <div style="color: #ffffff; top: -20px; left: -20px">
     3      <div class="loader"></div>
     4  </div>
     5</div>
    16<div class="container">
    27  <div class="row">
    3     <div class="col-md-3"></div>
     8    <div class="col-md-3">
     9    </div>
    410    <div class="col-md-6">
    511      <form>
    612          <h3>Optimizar planeamento semanal</h3>
    713          <hr>
    8           <div class="form-group">
    9             <label>Data <small>(primeiro dia da semana)</small></label>
    10             <input [ngModel] ="date | date:'yyyy-MM-dd'" (ngModelChange)="date = $event" name="date" type="date" class="form-control"/>
     14          <div id="dateInput" class="form-group">
     15            <label>Data <small>(primeiro dia da semana: segunda-feira)</small></label>
     16            <input [ngModel] ="date | date:'yyyy-MM-dd'" (ngModelChange)="change($event)" name="date" type="date" class="form-control"/>
    1117          </div>
    1218          <div class="form-group">
    13               <label>Iterações  <small>(valor superior a 500, para obter soluções razoáveis)</small></label>
     19              <label>Iterações  <small>(utilizar valor superior a 500 para obter bons planeamentos)</small></label>
    1420              <input [(ngModel)]="iterations" name="iterations" type="number" class="form-control"/>
    1521          </div>
     
    2834              <label><input [(ngModel)]="ignorePriority" name="ignorePriority" type="checkbox" value="">Ignorar prioridades</label>
    2935          </div>
    30           <input (click)="onClickSubmit()" type="submit" class="btn btn-primary" value="Submeter">
     36          <input [disabled]="error" (click)="onClickSubmit()" type="submit" class="btn btn-primary" value="Submeter">
    3137      </form>
    3238    </div>
  • internals/2017/ScheduleOptimizer/frontend/src/app/form/form.component.ts

    r16708 r16723  
    1 import { Component, OnInit, Input } from '@angular/core';
     1import { Component, OnInit, Input, ViewChild } from '@angular/core';
    22import { OptimizeService } from './../optimizer.service';
    33import { ReportComponent } from './../report/report.component';
    44import { Router} from '@angular/router';
     5
     6
    57@Component({
    68  selector: 'app-form',
     
    1618  options: Array<string>;
    1719  ignorePriority: boolean;
     20  error: boolean;
     21  loading: boolean;
    1822
    1923  constructor(private service: OptimizeService, private router: Router) {
    20     this.date = new Date().getFullYear() + '-' + new Date().getMonth() + '-' + new Date().getDay();
     24    this.date = new Date().toString();
    2125    this.iterations = 1000;
    2226    this.ignore = false;
    23     this.options = ['Geral (minimizar tempo de viagem, equipas, tempo perdido)',
    24                     'Tempos de viagem'];
     27    this.options = ['Reduzir equipas',
     28                    'Reduzir tempos de viagem'];
    2529    this.parameter = this.options[0];
    2630    this.ignorePriority = false;
     31    this.error = false;
     32    this.loading = false;
    2733  }
    2834
    2935  ngOnInit() {
     36    if ( new Date(this.date).getDay() !== 1) {
     37      document.getElementById('dateInput').classList.add('text-danger');
     38      document.getElementById('dateInput').classList.add('has-error');
     39      this.error = true;
     40    } else {
     41      document.getElementById('dateInput').classList.remove('text-danger');
     42      document.getElementById('dateInput').classList.remove('has-error');
     43      this.error = false;
     44    }
    3045  }
    3146
    3247  onClickSubmit() {
     48    this.loading = true;
    3349    let selected = 0;
    3450    if (this.ignorePriority) {
     
    5167        case this.options[1]:
    5268          selected = 3;
    53           this.service.setFn(this.options[1] + ' ' + 'cm prioridades.');
     69          this.service.setFn(this.options[1] + ' ' + 'com prioridades.');
    5470          break;
    5571      }
    5672    }
    57     this.service.webService(this.date, this.iterations, this.ignore, selected, (result) => {
     73
     74
     75    this.service.optimizeWeek(this.date, this.iterations, this.ignore, selected, (result) => {
    5876      this.router.navigate(['report']);
     77      this.loading = false;
    5978    });
     79
     80  }
     81
     82  change(event) {
     83    this.date = event;
     84    if ( new Date(this.date).getDay() !== 1) {
     85      document.getElementById('dateInput').classList.add('text-danger');
     86      document.getElementById('dateInput').classList.add('has-error');
     87      this.error = true;
     88    } else {
     89      document.getElementById('dateInput').classList.remove('text-danger');
     90      document.getElementById('dateInput').classList.remove('has-error');
     91      this.error = false;
     92    }
    6093  }
    6194}
  • internals/2017/ScheduleOptimizer/frontend/src/app/nav-bar/nav-bar.component.css

    r16708 r16723  
    1414  justify-content: center;
    1515}
     16
     17a {
     18  cursor: pointer;
     19}
  • internals/2017/ScheduleOptimizer/frontend/src/app/nav-bar/nav-bar.component.html

    r16708 r16723  
    33    <div class="navbar-header">
    44      <a class="navbar-brand navbar-left" >
    5         <img src="assets/logotipo.png"/>
     5        <img (click)="home()" src="assets/logotipo.png"/>
    66      </a>
    77      <p class="navbar-text">Schedule Optimizer</p>
  • internals/2017/ScheduleOptimizer/frontend/src/app/nav-bar/nav-bar.component.ts

    r16708 r16723  
    11import { Component, OnInit } from '@angular/core';
     2import { Router } from '@angular/router';
    23
    34@Component({
     
    89export class NavBarComponent implements OnInit {
    910
    10   constructor() { }
     11  constructor(private router: Router) { }
    1112
    1213  ngOnInit() {
    1314  }
    1415
     16  home() {
     17    this.router.navigate(['/']);
     18  }
     19
    1520}
  • internals/2017/ScheduleOptimizer/frontend/src/app/optimizer.service.ts

    r16708 r16723  
    2525  }
    2626
    27   webService(date, iterations, ignore, costFunction, callback) {
     27  optimizeWeek(date, iterations, ignore, costFunction, callback) {
    2828    const dateParams = date.split('-');
    2929    const xmlhttp = new XMLHttpRequest();
     
    4545    '   </soapenv:Body>' +
    4646    '</soapenv:Envelope>';
    47     const sup = this;
    48     xmlhttp.onreadystatechange = function () {
     47    xmlhttp.onreadystatechange = () => {
    4948        if (xmlhttp.readyState === 4) {
    5049            if (xmlhttp.status === 200) {
    5150              const parser = new xml2js.Parser();
    5251              parser.parseString(xmlhttp.responseText.split(':').join(''), (err, result) => {
    53               const data = result.sEnvelope.sBody[0].OptimizeWeekResponse[0].OptimizeWeekResult[0];
     52              this.data = result.sEnvelope.sBody[0].OptimizeWeekResponse[0].OptimizeWeekResult[0];
    5453              callback();
    55               sup.data = data;
    5654              });
    5755
     
    6664    xmlhttp.send(sr);
    6765  }
     66
     67
     68  rescheduleWeek(callback) {
     69    const xmlhttp = new XMLHttpRequest();
     70    xmlhttp.open('POST', 'http://localhost:52830/SolarSchedulerService.svc?wsdl', true);
     71    const sr = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">' +
     72    '   <soapenv:Header/>' +
     73    '   <soapenv:Body>' +
     74    '      <ReScheduleWeek/>' +
     75    '   </soapenv:Body>' +
     76    '   </soapenv:Envelope>';
     77
     78    xmlhttp.onreadystatechange = () => {
     79        if (xmlhttp.readyState === 4) {
     80            if (xmlhttp.status === 200) {
     81              callback();
     82            }
     83        }
     84    };
     85
     86    xmlhttp.setRequestHeader ('SOAPAction', 'urn:ISolarSchedulerService/RescheduleWeek');
     87    xmlhttp.setRequestHeader('Content-Type', 'text/xml; charset=UTF-8');
     88    xmlhttp.setRequestHeader('Access-Control-Allow-Origin', '*');
     89
     90    xmlhttp.send(sr);
     91  }
    6892}
  • internals/2017/ScheduleOptimizer/frontend/src/app/report/report.component.css

    r16708 r16723  
     1.equal {
     2  display: flex;
     3  display: -webkit-flex;
     4  flex-wrap: wrap;
     5}
  • internals/2017/ScheduleOptimizer/frontend/src/app/report/report.component.html

    r16708 r16723  
    11<div class="container">
    2     <div class="row">
    3       <div class="col-md-12">
    4         <h2>Optimização - Relatório semanal</h2>
    5         <hr>
    6       </div>
    7       <div class="col-md-8">
    8         <ul>
    9           <li>
    10             O início dos agendamentos pode variar <b>{{ conditions[0] }} hora(s)</b>;
    11           </li>
    12           <li>
    13             Tempos entre agendamentos que sejam inferiores a <b>{{ conditions[1] }} horas </b> são considerados perdidos;
    14           </li>
    15           <li>
    16             As restrições de área <b>{{ conditions[2] }} foram</b> ignoradas.
    17           </li>
    18           <li>
    19             <b>Parâmetro(s) a optimizar: </b>{{ this.service.getFn() }}
    20           </li>
    21         </ul>
    22       </div>
    23       <br>
    24       <div class="col-md-12">
    25         <hr>
    26       </div>
     2  <div class="row">
     3    <div class="col-md-12">
     4      <h2>Proposta de optimização para o planeamento semanal</h2>
     5      <hr>
    276    </div>
    287  </div>
    29   <app-teams-used></app-teams-used>
    30   <app-work-hours></app-work-hours>
    31   <app-travel-hours></app-travel-hours>
    32   <app-appointments></app-appointments>
     8  <div class="row equal">
     9    <div class="col-md-8">
     10      <ul>
     11        <li>
     12          O início dos agendamentos pode variar <b>{{ conditions[0] }} hora(s)</b>;
     13        </li>
     14        <li>
     15          Tempos entre agendamentos que sejam inferiores a <b>{{ conditions[1] }} horas </b> são considerados perdidos;
     16        </li>
     17        <li>
     18          As restrições de área <b>{{ conditions[2] }} foram</b> ignoradas.
     19        </li>
     20        <li>
     21          <b>Parâmetro(s) a optimizar: </b>{{ this.service.getFn() }}
     22        </li>
     23      </ul>
     24    </div>
     25    <div style="margin: auto; text-align: center" class="col-md-4">
     26      <button (click)="rescheduleWeek()" class="btn btn-danger">Efetivar o planeamento</button>
     27    </div>
     28    <br>
     29  </div>
     30  <div class="row">
     31    <div class="col-md-12">
     32      <hr>
     33    </div>
     34  </div>
     35</div>
     36<app-teams-used></app-teams-used>
     37<app-work-hours></app-work-hours>
     38<app-travel-hours></app-travel-hours>
     39<app-appointments></app-appointments>
  • internals/2017/ScheduleOptimizer/frontend/src/app/report/report.component.ts

    r16708 r16723  
    55import { TravelHoursComponent } from './travel-hours/travel-hours.component';
    66import { AppointmentsComponent } from './appointments/appointments.component';
     7import { Router} from '@angular/router';
    78
    89@Component({
     
    2021  conditions = ['2', '3', 'não'];
    2122
    22   constructor(public service: OptimizeService) {
     23  constructor(public service: OptimizeService, public router: Router) {
    2324  }
    2425
     
    3940  }
    4041
    41 
    42 
     42  rescheduleWeek() {
     43    this.service.rescheduleWeek( () => {
     44      this.router.navigate(['/']);
     45    });
     46  }
    4347}
Note: See TracChangeset for help on using the changeset viewer.