github.com/in4it/ecs-deploy@v0.0.42-0.20240508120354-ed77ff16df25/webapp/src/app/service-detail/service-detail.component.html (about)

     1  <div class="service-detail-container">
     2    <div class="offset-md-2 col-md-8">
     3      <h1>{{service.serviceName}}</h1>
     4      <ul class="nav nav-tabs">
     5        <li class="nav-item">
     6          <a class="nav-link" [class.active]="tab == 'service'" [routerLink]="" (click)="onClickService()">Service</a>
     7        </li>
     8        <li class="nav-item">
     9          <a class="nav-link" [class.active]="tab == 'versions'" [routerLink]="" (click)="onClickVersions()">Versions</a>
    10        </li>
    11        <li class="nav-item">
    12          <a class="nav-link" [class.active]="tab == 'events'" [routerLink]="" (click)="onClickEvents()">Event Logs</a>
    13        </li>
    14        <li class="nav-item">
    15          <a class="nav-link" [class.active]="tab == 'logs'" [routerLink]="" (click)="onClickLogs(true)">App Logs</a>
    16        </li>
    17        <li class="nav-item">
    18          <a class="nav-link" [class.active]="tab == 'parameters'" [routerLink]="" (click)="onClickParameters()">Parameters</a>
    19        </li>
    20        <li class="nav-item">
    21          <a class="nav-link" [class.active]="tab == 'scaling'" [routerLink]="" (click)="onClickScaling()">Scaling</a>
    22        </li>
    23        <li class="nav-item">
    24          <a class="nav-link" [class.active]="tab == 'runTask'" [routerLink]="" (click)="onClickRunTask()">Run Task</a>
    25        </li>
    26      </ul>
    27    </div>
    28    <div class="offset-md-2 col-md-8" *ngIf="tab == 'service'">
    29      <i *ngIf="loading" class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
    30      <span *ngIf="loading" class="sr-only">Loading...</span>
    31      <div *ngIf="!loading">
    32        <div class="row">
    33          <div class="col-md-4 cluster-info">
    34            <ul class="list-group list-group-horizontal">
    35              <li class="list-group-item list-group-item-success" *ngIf="service.status == 'ACTIVE'">Service Status: {{service.status}}</li>
    36              <li class="list-group-item list-group-item-warning" *ngIf="service.status != 'ACTIVE'">Service Status: {{service.status}}</li>
    37            </ul>
    38          </div>
    39          <div class="col-md-8 cluster-info right-buttons">
    40              <ul class="list-inline">
    41                <li class="list-inline-item"><button [disabled]="loading" class="btn btn-primary" (click)="refresh()"><i class="fa fa-refresh" aria-hidden="true"></i> Refresh</button></li>
    42              </ul>
    43          </div>
    44        </div>
    45        <div *ngIf="service['deploymentMap']['ACTIVE']">
    46          <div class="alert alert-primary" role="alert" >
    47            Deployment in progress...
    48          </div>
    49          <table class="table center-table">
    50            <thead class="thead-default">
    51              <tr>
    52                <th class="w-40">Deployed at</th>
    53                <th class="w-20">Services</th>
    54                <th class="w-15"></th>
    55                <th class="w-25"></th>
    56              </tr>
    57            </thead>
    58            <tbody>
    59              <tr>
    60                <td>{{service["deploymentMap"]["ACTIVE"]["lastDeploy"]}}</td>
    61                <td>
    62                  <strong>{{service["deploymentMap"]["ACTIVE"]["desiredCount"]}} / {{service["deploymentMap"]["ACTIVE"]["runningCount"]}}</strong> running
    63                  <span *ngIf="service['deploymentMap']['ACTIVE']['pendingCount'] &gt; 0"> ({{service['deploymentMap']['ACTIVE']['pendingCount']}} pending)</span>
    64                </td>
    65              </tr>
    66          </table>
    67          <p class="deploy-arrow text-center"><i class="fa fa-arrow-down fa-3x" aria-hidden="true"></i></p>
    68        </div>
    69        <table class="table center-table">
    70          <thead class="thead-default">
    71            <tr>
    72              <th>Deployed at</th>
    73              <th>Services</th>
    74              <th>Tasks</th>
    75              <th>Containers</th>
    76            </tr>
    77          </thead>
    78          <tbody>
    79          <tr>
    80            <td>{{service["deploymentMap"]["PRIMARY"]["lastDeploy"]}}</td>
    81            <td>
    82              <strong>{{service["deploymentMap"]["PRIMARY"]["desiredCount"]}} / {{service["deploymentMap"]["PRIMARY"]["runningCount"]}}</strong> running
    83              <span *ngIf="service['deploymentMap']['PRIMARY']['pendingCount'] &gt; 0"> ({{service['deploymentMap']['PRIMARY']['pendingCount']}} pending)</span>
    84            </td>
    85            <td>
    86              <strong>{{service["taskStatus"]["RUNNING"] || 0 }} / {{service["taskTotal"]}}</strong> running
    87              <span *ngIf="service['taskStatus']['STOPPED'] &gt; 0"> ({{service['taskStatus']['STOPPED']}} stopped)</span>
    88              <span *ngIf="service['taskStatus']['PENDING'] &gt; 0"> ({{service['taskStatus']['PENDING']}} stopped)</span>
    89            </td>
    90            <td>
    91              <strong>{{service["containerStatus"]["RUNNING"] || 0 }} / {{service["containerTotal"]}}</strong> running
    92              <span *ngIf="service['containerStatus']['STOPPED'] &gt; 0"> ({{service['containerStatus']['STOPPED']}} stopped)</span>
    93              <span *ngIf="service['containerStatus']['PENDING'] &gt; 0"> ({{service['containerStatus']['PENDING']}} stopped)</span>
    94            </td>
    95          </tr>
    96        </table>
    97      </div>
    98    </div>
    99    <div class="offset-md-2 col-md-8 cluster-info" *ngIf="tab == 'versions'">
   100      <i *ngIf="loading" class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
   101      <span *ngIf="loading" class="sr-only">Loading...</span>
   102      <div class="right-buttons" *ngIf="!loading">
   103        <ul class="list-inline">
   104          <li class="list-inline-item"><a class="btn btn-primary" (click)="inspectChild.open(service.serviceName, selectedVersion)">Inspect</a></li>
   105          <li class="list-inline-item"><a class="btn btn-primary" (click)="deployChild.open(service.serviceName, selectedVersion)">Deploy</a></li>
   106        </ul>
   107      </div>
   108      <table class="table center-table" *ngIf="!loading">
   109        <thead class="thead-default">
   110          <tr>
   111            <th>&nbsp;</th>
   112            <th>image</th>
   113            <th>tag</th>
   114            <th>Last Deployed</th>
   115          </tr>
   116        </thead>
   117        <tbody>
   118        <tr *ngFor="let version of versions">
   119          <td class="text-center"><input type="radio" class="form-check-input" name="selectedVersion" [(ngModel)]="selectedVersion" [value]="version.lastDeploy" class="text-center" /></td>
   120          <td>{{version.imageName}}</td>
   121          <td>{{version.tag}}</td>
   122          <td>{{version.lastDeployMoment}}</td>
   123        </tr>
   124      </table>
   125    </div>
   126    <div class="offset-md-2 col-md-8 cluster-info" *ngIf="tab == 'events'">
   127      <i *ngIf="loading" class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
   128      <span *ngIf="loading" class="sr-only">Loading...</span>
   129      <div *ngIf="!loading">
   130        <div class="right-buttons">
   131          <ul class="list-inline">
   132            <li class="list-inline-item"><button [disabled]="loading" class="btn btn-primary" (click)="refresh()"><i class="fa fa-refresh" aria-hidden="true"></i> Refresh</button></li>
   133          </ul>
   134        </div>
   135        <table class="table center-table">
   136          <thead class="thead-default">
   137            <tr>
   138              <th class="w-25">Timestamp</th>
   139              <th class="w-75">Message</th>
   140            </tr>
   141          </thead>
   142          <tbody>
   143          <tr *ngFor="let event of service.events">
   144            <td>{{event.createdAtFormatted}}</td>
   145            <td>{{event.message}}</td>
   146          </tr>
   147        </table>
   148      </div>
   149    </div>
   150    <div class="offset-md-2 col-md-8 cluster-info" *ngIf="tab == 'parameters'">
   151      <i *ngIf="loading" class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
   152      <span *ngIf="loading" class="sr-only">Loading...</span>
   153      <div *ngIf="!loading">
   154        <div class="right-buttons">
   155          <ul class="list-inline">
   156            <li class="list-inline-item"><button [disabled]="loading" class="btn btn-primary" (click)="showNewParameter()"><i class="fa fa-file-text-o" aria-hidden="true"></i> New Parameter</button></li>
   157          </ul>
   158        </div>
   159        <table class="table center-table">
   160          <thead class="thead-default">
   161            <tr>
   162              <th class="w-25">Parameter Name</th>
   163              <th class="w-75">Parameter Value</th>
   164            </tr>
   165          </thead>
   166          <tbody>
   167          <tr *ngIf="newParameter">
   168            <td class="align-middle">
   169              <input type="text" class="form-control" placeholder="Name..." name="parameterName" [(ngModel)]="newParameterInput.name" />
   170            </td>
   171            <td class="align-middle">
   172              <div class="row align-middle">
   173                <div class="col-md-7 mx-auto h-100">
   174                  <input type="text" class="form-control" placeholder="Value..." name="parameterValue" [(ngModel)]="newParameterInput.value" />
   175                </div>
   176                <div class="col-md-2">
   177                  <label class="checkbox-label">
   178                    <input type="checkbox" [(ngModel)]="newParameterInput.encrypted" value="true" >&nbsp;Encrypt
   179                  </label>
   180                </div>
   181                <div class="col-md-2">
   182                  <button [disabled]="saving" class="btn btn-primary" (click)="saveNewParameter()"><i class="fa fa-file-text-o" aria-hidden="true"></i>&nbsp;&nbsp;Save</button>
   183                  <i *ngIf="saving" class="fa fa-spinner" aria-hidden="true"></i>
   184                </div>
   185              </div>
   186            </td>
   187          </tr>
   188          <tr *ngFor="let parameter of parameters.keys">
   189            <td class="align-middle">{{parameter}}</td>
   190            <td class="align-middle" *ngIf="selectedParameter == parameter">
   191              <div class="row align-middle">
   192                <div class="col-9">
   193                  <input type="text" class="form-control" *ngIf="parameters.map[parameter]['value'] != '***'" name="parameterValue" [(ngModel)]="parameterInput.value" />
   194                  <input type="text" class="form-control" placeholder="new value..." *ngIf="parameters.map[parameter]['value'] == '***'" name="parameterValue" [(ngModel)]="parameterInput.value" />
   195                </div>
   196                <div class="col-2">
   197                  <button [disabled]="saving" class="btn btn-primary" (click)="saveParameter(parameter)"><i class="fa fa-file-text-o" aria-hidden="true"></i>&nbsp;&nbsp;Save</button>
   198                  <i *ngIf="saving" class="fa fa-spinner" aria-hidden="true"></i>
   199                </div>
   200              </div>
   201            </td>
   202            <td *ngIf="selectedParameter != parameter">
   203              {{parameters.map[parameter]["value"]}}&nbsp;<button class="btn" (click)="editParameter(parameter)"><i class="fa fa-pencil align-baseline" aria-hidden="true"></i></button>
   204              <button class="btn float-right" (click)="confirmChild.open('deleteParameter', 'parameter', service.serviceName, parameter)"><i class="fa fa-trash" aria-hidden="true"></i></button>
   205            </td>
   206          </tr>
   207        </table>
   208      </div>
   209    </div>
   210    <div class="offset-md-2 col-md-8 cluster-info" *ngIf="tab == 'scaling'">
   211      <i *ngIf="loading" class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
   212      <span *ngIf="loading" class="sr-only">Loading...</span>
   213      <div *ngIf="!loading">
   214        <div class="row">
   215          <div class="col-md-4">
   216            <h2>Manual Scaling</h2>
   217          </div>
   218          <div class="col-md-8 right-buttons">
   219            <ul class="list-inline">
   220              <li class="list-inline-item" *ngIf="scalingInput.autoscaling"><button [disabled]="loading" class="btn btn-primary" (click)="confirmChild.open('disableAutoscaling', 'autoscaling', service.serviceName, 'for '+service.serviceName)"><i class="fa fa-unlink" aria-hidden="true"></i> Disable Auto Scaling</button></li>
   221              <li class="list-inline-item"><button [disabled]="loading" class="btn btn-primary" (click)="refresh()"><i class="fa fa-refresh" aria-hidden="true"></i> Refresh</button></li>
   222            </ul>
   223          </div>
   224        </div>
   225        <table class="table center-table">
   226          <thead class="thead-default">
   227            <tr>
   228              <th class="w-25"><strong>Manual Scaling</strong></th>
   229              <th class="w-25">Running Count</th>
   230              <th class="w-25">Desired Count</th>
   231              <th class="w-25">&nbsp;</th>
   232            </tr>
   233          </thead>
   234          <tbody>
   235              <td>{{service["serviceName"]}}</td>
   236              <td>{{service["runningCount"]}} ({{service["pendingCount"]}} pending)</td>
   237              <td *ngIf="editManualScaling">
   238                <div class="row align-middle">
   239                  <div class="col-6">
   240                    <input type="text" class="form-control" name="desiredCount" [(ngModel)]="scalingInput.desiredCount" />
   241                  </div>
   242                  <div class="col-2">
   243                    <button [disabled]="saving" class="btn btn-primary" (click)="saveDesiredCount()"><i class="fa fa-file-text-o" aria-hidden="true"></i>&nbsp;&nbsp;Save</button>
   244                    <i *ngIf="saving" class="fa fa-spinner" aria-hidden="true"></i>
   245                  </div>
   246                </div>
   247              </td>
   248              <td *ngIf="!editManualScaling">
   249                {{service["desiredCount"]}}&nbsp;<button class="btn" (click)="editDesiredCount()"><i class="fa fa-pencil align-baseline" aria-hidden="true"></i></button>
   250              </td>
   251          <tbody>
   252        </table>
   253        <h2>Auto Scaling</h2>
   254        <div class="row" *ngIf="!scalingInput.autoscaling">
   255          <div class="col-6">
   256            <button [disabled]="saving" class="btn btn-primary" (click)="enableAutoscaling()"><i class="fa fa-balance-scale" aria-hidden="true"></i>&nbsp;&nbsp;Enable Auto Scaling</button>
   257          </div>
   258        </div>
   259        <div *ngIf="scalingInput.autoscaling">
   260          <table class="table center-table">
   261            <tbody>
   262              <tr>
   263                <td class="w-25">Minimum number of tasks</td>
   264                <td>
   265                  <div class="row">
   266                    <div class="col-6">
   267                      <input type="text" class="form-control" name="minimumCount" [(ngModel)]="scalingInput.minimumCount" />
   268                    </div>
   269                  </div>
   270                </td>
   271              </tr>
   272              <tr>
   273                <td>Desired number of tasks</td>
   274                <td>
   275                  <div class="row">
   276                    <div class="col-6">
   277                      <input type="text" class="form-control" name="desiredCount" [(ngModel)]="scalingInput.desiredCount" />
   278                    </div>
   279                  </div>
   280                </td>
   281              </tr>
   282              <tr>
   283                <td>Maximum number of tasks</td>
   284                <td>
   285                  <div class="row">
   286                    <div class="col-6">
   287                      <input type="text" class="form-control" name="maximumCount" [(ngModel)]="scalingInput.maximumCount" />
   288                    </div>
   289                  </div>
   290                </td>
   291              </tr>
   292                <td>&nbsp;</td>
   293                <td>
   294                  <button [disabled]="saving" class="btn btn-primary" (click)="saveAutoscalingPolicy()"><i class="fa fa-file-text-o" aria-hidden="true"></i>&nbsp;&nbsp;Save</button>
   295                </td>
   296              <tr>
   297              </tr>
   298            </tbody>
   299          </table>
   300          <h2>Auto Scaling Policies</h2>
   301          <table class="table center-table" *ngIf="scalingInput.policyCount &gt; 0">
   302            <thead class="thead-default">
   303              <tr>
   304                <th>Name</th>
   305                <th>Policy</th>
   306                <th>Action</th>
   307                <th>&nbsp;</th>
   308              </tr>
   309            </thead>
   310            <tbody>
   311              <tr *ngFor="let policy of scalingInput.policies">
   312                <td>{{policy.policyName}}</td>
   313                <td>{{policy.metric}} {{policy.comparisonOperator}} {{policy.threshold}}% for {{policy.evaluationPeriods}} times in {{policy.period/60}} minute(s) ({{policy.thresholdStatistic}})</td>
   314                <td>{{policy.scalingAdjustment}}</td>
   315                <td class="button">
   316                  <button class="btn btn-middle" (click)="confirmChild.open('deleteAutoscalingPolicy', 'autoscaling policy', service.serviceName, policy.policyName)"><i class="fa fa-trash" aria-hidden="true"></i></button>
   317                </td>
   318              </tr>
   319            </tbody>
   320          </table>
   321          <div *ngIf="!scalingInput.newAutoscalingPolicy">
   322            <div class="row">
   323              <div class="col-6">
   324                <button [disabled]="saving" class="btn btn-primary" (click)="newAutoscalingPolicy()"><i class="fa fa-balance-scale" aria-hidden="true"></i>&nbsp;&nbsp;New Scaling policy</button>
   325              </div>
   326            </div>
   327          </div>
   328          <div *ngIf="scalingInput.newAutoscalingPolicy">
   329            <h3>New Auto Scaling policy</h3>
   330            <table class="table center-table">
   331              <tbody>
   332                <tr>
   333                  <td class="w-25">Metric</td>
   334                  <td>
   335                    <div class="row">
   336                      <div class="col-8">
   337                        <select class="form-control" [(ngModel)]="scalingInputPolicy.metric">
   338                          <option value="cpu">CPU in use (percentage)</option>
   339                          <option value="memory">Memory in use (percentage)</option>
   340                        </select>
   341                      </div>
   342                    </div>
   343                  </td>
   344                </tr>
   345                <tr>
   346                  <td>Threshold</td>
   347                  <td>
   348                    <div class="row">
   349                      <div class="col-4">
   350                        <select class="form-control" [(ngModel)]="scalingInputPolicy.thresholdStatistic">
   351                          <option value="average">Average</option>
   352                          <option value="minimum">Minimum</option>
   353                          <option value="maximum">Maximum</option>
   354                          <option value="sum">Sum</option>
   355                          <option value="sampleCount">Data samples</option>
   356                        </select>
   357                      </div>
   358                      <div class="col-2">
   359                        <select class="form-control" [(ngModel)]="scalingInputPolicy.comparisonOperator">
   360                          <option value="greaterThanOrEqualToThreshold">&gt;=</option>
   361                          <option value="lessThanOrEqualToThreshold">&lt;=</option>
   362                          <option value="greaterThanThreshold">&gt;</option>
   363                          <option value="lessThanThreshold">&lt;</option>
   364                        </select>
   365                      </div>
   366                      <div class="col-2">
   367                        <input type="text" class="form-control" name="threshold" [(ngModel)]="scalingInputPolicy.threshold" />
   368                      </div>
   369                    </div>
   370                  </td>
   371                </tr>
   372                <tr>
   373                  <td>Threshold period</td>
   374                  <td>
   375                    <div class="row">
   376                      <div class="col-1">
   377                        <span class="middle">for</span>
   378                      </div>
   379                      <div class="col-2">
   380                        <input type="text" class="form-control" name="datapointsToAlarm" [(ngModel)]="scalingInputPolicy.datapointsToAlarm" />
   381                      </div>
   382                      <div class="col-2">
   383                        <span class="middle">periods of</span>
   384                      </div>
   385                      <div class="col-3">
   386                        <select class="form-control" [(ngModel)]="scalingInputPolicy.period">
   387                          <option value="60">1 minute</option>
   388                          <option value="300">5 minutes</option>
   389                          <option value="900">15 minutes</option>
   390                          <option value="1800">30 minutes</option>
   391                          <option value="3600">60 minutes</option>
   392                        </select>
   393                      </div>
   394                    </div>
   395                  </td>
   396                </tr>
   397                <tr>
   398                  <td>Scaling adjustment</td>
   399                  <td>
   400                    <div class="row">
   401                      <div class="col-2">
   402                        <select class="form-control" [(ngModel)]="scalingInputPolicy.scalingAdjustment">
   403                          <option value="1">Up (+1)</option>
   404                          <option value="2">Up (+2)</option>
   405                          <option value="3">Up (+3)</option>
   406                          <option value="-1">Down (-1)</option>
   407                          <option value="-2">Down (-2)</option>
   408                          <option value="-3">Down (-3)</option>
   409                        </select>
   410                      </div>
   411                    </div>
   412                  </td>
   413                </tr>
   414              </tbody>
   415            </table>
   416            <div class="row">
   417              <div class="col-6">
   418                <button [disabled]="saving" class="btn btn-primary" (click)="addAutoscalingPolicy()"><i class="fa fa-balance-scale" aria-hidden="true"></i>&nbsp;&nbsp;Add policy</button>
   419              </div>
   420            </div>
   421          </div>
   422        </div>
   423      </div>
   424    </div>
   425    <div class="offset-md-2 col-md-8 cluster-info" *ngIf="tab == 'runTask'">
   426      <i *ngIf="loading" class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
   427      <span *ngIf="loading" class="sr-only">Loading...</span>
   428      <div *ngIf="!loading">
   429        <h3>General configuration</h3>
   430        <table class="table center-table run-task">
   431          <thead class="thead-default">
   432            <tr>
   433              <th class="w-25">Property</th>
   434              <th class="w-75">Value</th>
   435            </tr>
   436          </thead>
   437          <tbody>
   438            <tr>
   439              <td>Max. execution time (sec.)</td>
   440              <td>
   441                <div class="row">
   442                  <div class="col-2">
   443                    <input type="text" class="form-control" name="maxExecutionTime" [(ngModel)]="runTaskConfig.maxExecutionTime" />
   444                  </div>
   445                </div>
   446              </td>
   447            </tr>
   448          </tbody>
   449        </table>
   450        <div *ngFor="let container of service['taskDefinition']['containerDefinitions']">
   451          <h3>{{container.name}}</h3>
   452          <table class="table center-table run-task" *ngIf="runTaskInput[container.name].enabled">
   453            <thead class="thead-default">
   454              <tr>
   455                <th class="w-25">Property</th>
   456                <th class="w-75">Value</th>
   457              </tr>
   458            </thead>
   459            <tbody>
   460              <tr>
   461                <td>Configuration</td>
   462                <td>
   463                  <div class="row">
   464                    <div class="col-6">
   465                      <label class="checkbox-label">
   466                        <input type="checkbox" [(ngModel)]="runTaskInput[container.name].enabled" value="true"/>&nbsp;Enabled
   467                      </label>
   468                    </div>
   469                  </div>
   470                  <div class="row">
   471                    <div class="col-6">
   472                      <label class="checkbox-label">
   473                        <input type="checkbox" [(ngModel)]="runTaskInput[container.name].environmentVariables" value="true" checked="true"/>&nbsp;Load environment variables
   474                      </label>
   475                    </div>
   476                  </div>
   477                </td>
   478              </tr>
   479              <tr>
   480                <td>Command</td>
   481                <td>
   482                  <div class="row">
   483                    <div class="col-12">
   484                      <input type="text" class="form-control" name="containerCommand" [(ngModel)]="runTaskInput[container.name].containerCommand" placeHolder="echo &quot;this is a command&quot;" />
   485                    </div>
   486                  </div>
   487                </td>
   488              </tr>
   489            <tbody>
   490          </table>
   491          <label class="checkbox-label" *ngIf="!runTaskInput[container.name].enabled">
   492            <input type="checkbox" [(ngModel)]="runTaskInput[container.name].enabled" value="true"/>&nbsp;Enable <br />
   493          </label>
   494        </div>
   495        <div class="bottom-buttons">
   496          <button [disabled]="saving" class="btn btn-primary" (click)="runTask()"><i class="fa fa-play" aria-hidden="true"></i>&nbsp;&nbsp;Run Task</button>
   497          <i *ngIf="saving" class="fa fa-spinner" aria-hidden="true"></i>
   498        </div>
   499      </div>
   500    </div>
   501    <div class="offset-md-2 col-md-8 cluster-info" *ngIf="tab == 'logs'">
   502      <i *ngIf="loading" class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
   503      <span *ngIf="loading" class="sr-only">Loading...</span>
   504      <div *ngIf="!loading">
   505        <div class="form-group row">
   506          <div class="col-md-8">
   507            <select class="form-control" [(ngModel)]="logsInput.selectedTaskArn" (ngModelChange)="updateLogs()" [compareWith]="compareByID">
   508              <option *ngFor="let t of logsInput['taskArns']" [ngValue]="t">{{t.name}}</option>
   509            </select>
   510          </div>
   511          <div class="col-md-4">
   512            <select class="form-control" [(ngModel)]="logsInput.selectedContainer" (ngModelChange)="updateLogs()" [compareWith]="compareByID">
   513              <option *ngFor="let c of logsInput['containers']" [ngValue]="c">{{c.name}}</option>
   514            </select>
   515          </div>
   516        </div>
   517        <div class="form-group row">
   518          <div class="offset-md-8 col-md-4">
   519            <select class="form-control" [(ngModel)]="logsInput.selectedTimerange" (ngModelChange)="updateLogs()">
   520              <option *ngFor="let t of logsInput['timerange']" [ngValue]="t">{{t.name}}</option>
   521            </select>
   522          </div>
   523        </div>
   524        <div class="right-buttons">
   525          <ul class="list-inline">
   526            <li class="list-inline-item"><button [disabled]="loading" class="btn btn-primary" (click)="refreshLogs()"><i class="fa fa-refresh" aria-hidden="true"></i> Refresh</button></li>
   527          </ul>
   528        </div>
   529        <i *ngIf="loadingLogs" class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
   530        <span *ngIf="loadingLogs" class="sr-only">Loading...</span>
   531        <div class="table-responsive logs">
   532          <table class="table center-table" *ngIf="service['logs']">
   533            <thead class="thead-default">
   534              <tr>
   535                <th class="w-30">Timestamp</th>
   536                <th class="w-70">Message</th>
   537              </tr>
   538            </thead>
   539            <tbody>
   540              <tr *ngFor="let e of service.logs.logEvents">
   541                <td>{{e.timestamp}}</td>
   542                <td>{{e.message}}</td>
   543              </tr>
   544              <tr *ngIf="service.logs.count == 0">
   545                <td>&nbsp;</td>
   546                <td>No messages to show</td>
   547              </tr>
   548            </tbody>
   549          </table>
   550        </div>
   551        <div class="right-buttons" *ngIf="service['logs'] &amp;&amp; service.logs.count > 10">
   552          <ul class="list-inline">
   553            <li class="list-inline-item"><button [disabled]="loading" class="btn btn-primary" (click)="refreshLogs()"><i class="fa fa-refresh" aria-hidden="true"></i> Refresh</button></li>
   554          </ul>
   555        </div>
   556      </div>
   557    </div>
   558  </div>
   559  <app-service-detail-confirm (deletedItem)="deletedItem($event)" (deletingItem)="deletingItem($event)"></app-service-detail-confirm>
   560  <app-service-detail-inspect></app-service-detail-inspect>
   561  <app-service-detail-deploy (deployed)="deployed($event)" (deploying)="deploying($event)"></app-service-detail-deploy>