Auto stash before merge of "master" and "origin/master"

This commit is contained in:
Dragos 2021-04-28 18:59:19 +03:00
parent 017c90ab02
commit ead7c9188b
14 changed files with 230 additions and 163 deletions

View File

@ -31,7 +31,7 @@
</ng-container> </ng-container>
<li class="dropdown-header">Deletion protection</li> <li class="dropdown-header">Deletion protection</li>
<li class="list-group-item ps-0 pb-0"> <li class="list-group-item ps-0 pb-0 mt-2 ms-2">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input mt-0" type="checkbox" id="dp{{ instance.id }}" [(ngModel)]="instance.deletion_protection" <input class="form-check-input mt-0" type="checkbox" id="dp{{ instance.id }}" [(ngModel)]="instance.deletion_protection"
(change)="toggleDeletionProtection($event, instance)"> (change)="toggleDeletionProtection($event, instance)">

View File

@ -21,7 +21,7 @@
</ul> </ul>
</div> </div>
<div class="form-check form-switch"> <div class="form-check form-switch mb-0">
<input class="form-check-input mt-0" type="checkbox" id="fw{{ instance.id }}" [(ngModel)]="instance.firewall_enabled" <input class="form-check-input mt-0" type="checkbox" id="fw{{ instance.id }}" [(ngModel)]="instance.firewall_enabled"
(change)="toggleCloudFirewall($event, instance)"> (change)="toggleCloudFirewall($event, instance)">
<label class="form-check-label" for="fw{{ instance.id }}">Toggle cloud firewall</label> <label class="form-check-label" for="fw{{ instance.id }}">Toggle cloud firewall</label>

View File

@ -43,3 +43,8 @@
{ {
font-size: 1rem; font-size: 1rem;
} }
.dropdown-menu b
{
font-weight: 400;
}

View File

@ -33,7 +33,7 @@
*ngIf="snapshot.state === 'created' && !snapshot.working"> *ngIf="snapshot.state === 'created' && !snapshot.working">
<button class="btn btn-link text-success" tooltip="Start machine from this snapshot" container="body" placement="top" [adaptivePosition]="false" <button class="btn btn-link text-success" tooltip="Start machine from this snapshot" container="body" placement="top" [adaptivePosition]="false"
(click)="restoreSnapshot(snapshot)"> (click)="restoreSnapshot(snapshot)">
<fa-icon icon="history" [fixedWidth]="true" size="sm"></fa-icon> <fa-icon icon="undo" [fixedWidth]="true" size="sm"></fa-icon>
</button> </button>
<button class="btn btn-link text-info" dropdownToggle <button class="btn btn-link text-info" dropdownToggle

View File

@ -49,7 +49,7 @@
{ {
position: absolute; position: absolute;
left: .5rem; left: .5rem;
top: 50%; top: 51%;
transform: translateY(-50%); transform: translateY(-50%);
z-index: 1; z-index: 1;
pointer-events: none; pointer-events: none;

View File

@ -180,6 +180,7 @@ p
padding: .75rem .25rem; padding: .75rem .25rem;
color: #5a8cd8; color: #5a8cd8;
font-family: "Mukta", sans-serif; font-family: "Mukta", sans-serif;
font-size: 1.1rem;
text-transform: none; text-transform: none;
} }
} }

View File

@ -12,18 +12,18 @@
<ng-container *ngIf="instances && instances.length"> <ng-container *ngIf="instances && instances.length">
<div class="input-group input-group-pill me-lg-3 mb-3 mb-lg-0 w-lg-auto w-100"> <div class="input-group input-group-pill me-lg-3 mb-3 mb-lg-0 w-lg-auto w-100">
<input type="text" class="form-control" placeholder="Search..." formControlName="searchTerm" <input type="text" class="form-control" placeholder="Search..." formControlName="searchTerm"
appAlphaOnly="^[A-Za-z0-9_-]+$" tooltip="Search by name, tag, metadata, operating system or brand" appAlphaOnly="^[A-Za-z0-9_-]+$" tooltip="Search by name, tag, metadata, operating system or brand"
placement="top" container="body" [adaptivePosition]="false"> placement="top" container="body" [adaptivePosition]="false">
<button class="btn btn-outline-info" type="button" (click)="clearSearch()" <button class="btn btn-outline-info" type="button" (click)="clearSearch()"
[disabled]="!editorForm.get('searchTerm').value" tooltip="Clear search" container="body" placement="top" [disabled]="!editorForm.get('searchTerm').value" tooltip="Clear search" container="body" placement="top"
[adaptivePosition]="false"> [adaptivePosition]="false">
<fa-icon icon="times" size="sm" [fixedWidth]="true"></fa-icon> <fa-icon icon="times" size="sm" [fixedWidth]="true"></fa-icon>
</button> </button>
</div> </div>
<div class="btn-group me-lg-3 mb-3 mb-lg-0 w-lg-auto w-100"> <div class="btn-group me-lg-3 mb-3 mb-lg-0 w-lg-auto w-100">
<button class="btn btn-outline-info dropdown-toggle" [disabled]="loadingIndicator" [popover]="filtersTemplate" <button class="btn btn-outline-info dropdown-toggle" [disabled]="loadingIndicator" [popover]="filtersTemplate"
[outsideClick]="true" container="body" placement="bottom right" containerClass="menu-popover"> [outsideClick]="true" container="body" placement="bottom right" containerClass="menu-popover">
Showing {{ listItems.length }} / {{ instances.length }} Showing {{ listItems.length }} / {{ instances.length }}
<ng-container *ngIf="runningInstanceCount && stoppedInstanceCount"> <ng-container *ngIf="runningInstanceCount && stoppedInstanceCount">
<span class="badge rounded-pill bg-success text-dark">{{ runningInstanceCount }} running</span> <span class="badge rounded-pill bg-success text-dark">{{ runningInstanceCount }} running</span>
@ -45,31 +45,31 @@
<ul *dropdownMenu class="dropdown-menu dropdown-menu-right" role="menu"> <ul *dropdownMenu class="dropdown-menu dropdown-menu-right" role="menu">
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'name'" <button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'name'"
(click)="setSortProperty('name')"> (click)="setSortProperty('name')">
Name Name
</button> </button>
</li> </li>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'os'" <button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'os'"
(click)="setSortProperty('os')"> (click)="setSortProperty('os')">
Operating system Operating system
</button> </button>
</li> </li>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'brand'" <button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'brand'"
(click)="setSortProperty('brand')"> (click)="setSortProperty('brand')">
Brand Brand
</button> </button>
</li> </li>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'image'" <button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'image'"
(click)="setSortProperty('image')"> (click)="setSortProperty('image')">
Image Image
</button> </button>
</li> </li>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'state'" <button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'state'"
(click)="setSortProperty('state')"> (click)="setSortProperty('state')">
State State
</button> </button>
</li> </li>
@ -90,32 +90,32 @@
</h2> </h2>
<virtual-scroller #scroller [items]="listItems" bufferAmount="2" class="instances" <virtual-scroller #scroller [items]="listItems" bufferAmount="2" class="instances"
[parentScroll]="scroller.window.document.getElementById('scrollingBlock')" [scrollThrottlingTime]="250"> [parentScroll]="scroller.window.document.getElementById('scrollingBlock')" [scrollThrottlingTime]="250">
<div *ngFor="let instance of scroller.viewPortItems; trackBy: trackByFunction; let index = index" <div *ngFor="let instance of scroller.viewPortItems; trackBy: trackByFunction; let index = index"
[ngClass]="showMachineDetails ? 'col-12 full-details' : 'col-xl-2 col-lg-3 col-md-4 col-sm-6 col-12'" [ngClass]="showMachineDetails ? 'col-12 full-details' : 'col-xl-2 col-lg-3 col-md-4 col-sm-6 col-12'"
[class.col-lg-6]="editorForm.get('fullDetailsTwoColumns').value" lazyLoad [lazyLoadDelay]="lazyLoadDelay" [class.col-lg-6]="showMachineDetails && editorForm.get('fullDetailsTwoColumns').value" lazyLoad [lazyLoadDelay]="lazyLoadDelay"
[container]="scroller.element.nativeElement.getElementsByClassName('scrollable-content')[0]" [container]="scroller.element.nativeElement.getElementsByClassName('scrollable-content')[0]"
(canLoad)="instance.loading = false" (unload)="instance.loading = true" (canLoad)="instance.loading = false" (unload)="instance.loading = true"
(load)="loadInstanceDetails(instance)"> (load)="loadInstanceDetails(instance)">
<fieldset class="card" [disabled]="instance.working"> <fieldset class="card" [disabled]="instance.working">
<div class="row g-0"> <div class="row g-0">
<div class="card-info" [ngClass]="showMachineDetails ? 'col-lg-4' : 'col'"> <div class="card-info" [ngClass]="showMachineDetails ? 'col-lg-4' : 'col'">
<div> <div>
<h5 class="card-title text-truncate" [tooltip]="instance.name" container="body" placement="top" <h5 class="card-title text-truncate" [tooltip]="instance.name" container="body" placement="top"
[adaptivePosition]="false"> [adaptivePosition]="false">
{{ instance.name }} {{ instance.name }}
</h5> </h5>
<div *ngIf="!instance.loading && instance.imageDetails" <div *ngIf="!instance.loading && instance.imageDetails"
class="text-truncate small text-info text-faded mb-1" [tooltip]="instance.imageDetails.description" class="text-truncate small text-info text-faded mb-1" [tooltip]="instance.imageDetails.description"
container="body" placement="top" [adaptivePosition]="false"> container="body" placement="top" [adaptivePosition]="false">
{{ instance.imageDetails.name }}, v{{ instance.imageDetails.version }} {{ instance.imageDetails.name }}, v{{ instance.imageDetails.version }}
</div> </div>
<button *ngIf="!instance.loading" <button *ngIf="!instance.loading"
class="btn btn-outline-info w-100 d-flex justify-content-around align-items-center text-truncate" class="btn btn-outline-info w-100 d-flex justify-content-around align-items-center text-truncate"
tooltip="Change specifications" container="body" placement="top" [adaptivePosition]="false" tooltip="Change specifications" container="body" placement="top" [adaptivePosition]="false"
(click)="resizeMachine(instance)" [disabled]="instance.brand === 'kvm'"> (click)="resizeMachine(instance)" [disabled]="instance.brand === 'kvm'">
<!--<span class="text-uppercase text-truncate">{{ instance.packageDetails.name }}</span>--> <!--<span class="text-uppercase text-truncate">{{ instance.packageDetails.name }}</span>-->
<span class="px-1"> <span class="px-1">
@ -150,29 +150,30 @@
<div class="d-flex flex-nowrap justify-content-between align-items-center"> <div class="d-flex flex-nowrap justify-content-between align-items-center">
<a href="javascript:void(0)" class="badge text-uppercase" <a href="javascript:void(0)" class="badge text-uppercase"
[class.bg-light]="instance.state !== 'running' && instance.state !== 'stopped'" [class.bg-light]="instance.state !== 'running' && instance.state !== 'stopped'"
[class.bg-danger]="instance.state === 'stopped'" [class.bg-success]="instance.state === 'running'" [class.bg-danger]="instance.state === 'stopped'" [class.bg-success]="instance.state === 'running'"
(click)="showMachineHistory(instance)" tooltip="{{ 'dashboard.listItem.history' | translate }}" (click)="showMachineHistory(instance)" tooltip="{{ 'dashboard.listItem.history' | translate }}"
container="body" placement="top" [adaptivePosition]="false"> container="body" placement="top" [adaptivePosition]="false">
<fa-icon icon="history" [fixedWidth]="true"></fa-icon>
{{ instance.state }} {{ instance.state }}
</a> </a>
<div class="btn-group btn-group-sm" dropdown placement="bottom right" *ngIf="!instance.loading"> <div class="btn-group btn-group-sm" dropdown placement="bottom right" *ngIf="!instance.loading">
<button class="btn btn-link text-warning" (click)="restartMachine(instance)" <button class="btn btn-link text-warning" (click)="restartMachine(instance)"
*ngIf="instance.state === 'running'"> *ngIf="instance.state === 'running'">
<fa-icon icon="power-off" [fixedWidth]="true" size="sm" tooltip="Restart this machine" <fa-icon icon="power-off" [fixedWidth]="true" size="sm" tooltip="Restart this machine"
container="body" placement="top" [adaptivePosition]="false"></fa-icon> container="body" placement="top" [adaptivePosition]="false"></fa-icon>
</button> </button>
<button class="btn btn-link text-success" (click)="startMachine(instance)" <button class="btn btn-link text-success" (click)="startMachine(instance)"
*ngIf="instance.state === 'stopped'"> *ngIf="instance.state === 'stopped'">
<fa-icon icon="play" [fixedWidth]="true" size="sm" tooltip="Start this machine" container="body" <fa-icon icon="play" [fixedWidth]="true" size="sm" tooltip="Start this machine" container="body"
placement="top" [adaptivePosition]="false"></fa-icon> placement="top" [adaptivePosition]="false"></fa-icon>
</button> </button>
<button class="btn btn-link text-info" [popover]="instanceContextMenu" <button class="btn btn-link text-info" [popover]="instanceContextMenu"
[popoverContext]="{ instance: instance }" placement="bottom left" containerClass="menu-dropdown" [popoverContext]="{ instance: instance }" placement="bottom left" containerClass="menu-dropdown"
[outsideClick]="true"> [outsideClick]="true">
<fa-icon icon="ellipsis-v" [fixedWidth]="true" size="sm"></fa-icon> <fa-icon icon="ellipsis-v" [fixedWidth]="true" size="sm"></fa-icon>
</button> </button>
</div> </div>
@ -184,49 +185,49 @@
<div class="card-header p-0 h-100"> <div class="card-header p-0 h-100">
<tabset class="dashboard-tabs" *ngIf="!instance.loading"> <tabset class="dashboard-tabs" *ngIf="!instance.loading">
<tab customClass="dashboard-tab" (selectTab)="tabChanged($event, instance)" <tab customClass="dashboard-tab" (selectTab)="tabChanged($event, instance)"
id="{{ instance.id }}-info"> id="{{ instance.id }}-info">
<ng-template tabHeading> <ng-template tabHeading>
<fa-icon icon="info-circle" class="d-sm-none"></fa-icon> <fa-icon icon="info-circle" class="d-sm-none"></fa-icon>
<span class="d-none d-sm-inline-block ms-1">Info</span> <span class="d-none d-sm-inline-block ms-1">Info</span>
</ng-template> </ng-template>
<div class="card-body p-2 h-100"> <div class="card-body p-2 h-100">
<app-instance-info [instance]="instance" [loadInfo]="instance.shouldLoadInfo" <app-instance-info [instance]="instance" [loadInfo]="instance.shouldLoadInfo"
(load)="setInstanceInfo(instance, $event)" (processing)="instance.working = true" (load)="setInstanceInfo(instance, $event)" (processing)="instance.working = true"
(finishedProcessing)="instance.working = false"> (finishedProcessing)="instance.working = false">
</app-instance-info> </app-instance-info>
</div> </div>
</tab> </tab>
<tab customClass="dashboard-tab" (selectTab)="tabChanged($event, instance)" <tab customClass="dashboard-tab" (selectTab)="tabChanged($event, instance)"
id="{{ instance.id }}-networks"> id="{{ instance.id }}-networks">
<ng-template tabHeading> <ng-template tabHeading>
<fa-icon icon="network-wired" class="d-sm-none"></fa-icon> <fa-icon icon="network-wired" class="d-sm-none"></fa-icon>
<span class="d-none d-sm-inline-block ms-1">Network</span> <span class="d-none d-sm-inline-block ms-1">Network</span>
</ng-template> </ng-template>
<div class="card-body p-2 h-100"> <div class="card-body p-2 h-100">
<app-instance-networks [instance]="instance" [loadNetworks]="instance.shouldLoadNetworks" <app-instance-networks [instance]="instance" [loadNetworks]="instance.shouldLoadNetworks"
(load)="setInstanceNetworks(instance, $event)" (processing)="instance.working = true" (load)="setInstanceNetworks(instance, $event)" (processing)="instance.working = true"
(finishedProcessing)="instance.working = false" (finishedProcessing)="instance.working = false"
(instanceReboot)="watchInstanceState(instance)" (instanceReboot)="watchInstanceState(instance)"
(instanceStateUpdate)="updateInstance(instance, $event)"> (instanceStateUpdate)="updateInstance(instance, $event)">
</app-instance-networks> </app-instance-networks>
</div> </div>
</tab> </tab>
<tab customClass="dashboard-tab" (selectTab)="tabChanged($event, instance)" <tab customClass="dashboard-tab" (selectTab)="tabChanged($event, instance)"
id="{{ instance.id }}-snapshots" *ngIf="instance.brand !== 'kvm'"> id="{{ instance.id }}-snapshots" *ngIf="instance.brand !== 'kvm'">
<ng-template tabHeading> <ng-template tabHeading>
<fa-icon icon="history" class="d-sm-none"></fa-icon> <fa-icon icon="history" class="d-sm-none"></fa-icon>
<span class="d-none d-sm-inline-block ms-1">Snapshots</span> <span class="d-none d-sm-inline-block ms-1">Snapshots</span>
</ng-template> </ng-template>
<div class="card-body p-2 h-100"> <div class="card-body p-2 h-100">
<app-instance-snapshots [instance]="instance" [loadSnapshots]="instance.shouldLoadSnapshots" <app-instance-snapshots [instance]="instance" [loadSnapshots]="instance.shouldLoadSnapshots"
(load)="setInstanceSnapshots(instance, $event)" (processing)="instance.working = true" (load)="setInstanceSnapshots(instance, $event)" (processing)="instance.working = true"
(finishedProcessing)="instance.working = false" (finishedProcessing)="instance.working = false"
(instanceStateUpdate)="updateInstance(instance, $event)"> (instanceStateUpdate)="updateInstance(instance, $event)">
</app-instance-snapshots> </app-instance-snapshots>
</div> </div>
</tab> </tab>
<tab *ngIf="false" customClass="dashboard-tab" (selectTab)="tabChanged($event, instance)" <tab *ngIf="false" customClass="dashboard-tab" (selectTab)="tabChanged($event, instance)"
id="{{ instance.id }}-migrations"> id="{{ instance.id }}-migrations">
<ng-template tabHeading> <ng-template tabHeading>
<fa-icon icon="coins" class="d-sm-none"></fa-icon> <fa-icon icon="coins" class="d-sm-none"></fa-icon>
<span class="d-none d-sm-inline-block ms-1">Migrations</span> <span class="d-none d-sm-inline-block ms-1">Migrations</span>
@ -236,16 +237,15 @@
</div> </div>
</tab> </tab>
<tab customClass="dashboard-tab" (selectTab)="tabChanged($event, instance)" <tab customClass="dashboard-tab" (selectTab)="tabChanged($event, instance)"
id="{{ instance.id }}-volumes" *ngIf="instance.volumes && instance.volumes.length"> id="{{ instance.id }}-volumes" *ngIf="instance.volumes && instance.volumes.length">
<ng-template tabHeading> <ng-template tabHeading>
<fa-icon icon="database" class="d-sm-none"></fa-icon> <fa-icon icon="database" class="d-sm-none"></fa-icon>
<span class="d-none d-sm-inline-block ms-1">Volumes</span> <span class="d-none d-sm-inline-block ms-1">Volumes</span>
</ng-template> </ng-template>
<div class="card-body p-2 h-100"> <div class="card-body p-2 h-100">
<ul class="list-group list-group-flush list-info"> <ul class="list-group list-group-flush list-info">
<li <li class="list-group-item text-uppercase px-0 dns d-flex justify-content-between align-items-center"
class="list-group-item text-uppercase px-0 dns d-flex justify-content-between align-items-center" *ngFor="let volume of instance.volumes">
*ngFor="let volume of instance.volumes">
<div class="text-truncate"> <div class="text-truncate">
<fa-icon icon="database" [fixedWidth]="true" size="sm"></fa-icon> <fa-icon icon="database" [fixedWidth]="true" size="sm"></fa-icon>
<span class="ms-1"> <span class="ms-1">
@ -275,32 +275,35 @@
<div class="dropdown-header">{{ 'dashboard.list.filterByState' | translate }}</div> <div class="dropdown-header">{{ 'dashboard.list.filterByState' | translate }}</div>
<div class="btn-group w-100 mb-3" dropdown> <div class="btn-group w-100 mb-3" dropdown>
<button class="btn btn-state-filter dropdown-toggle d-flex justify-content-between align-items-center" <button class="btn btn-state-filter dropdown-toggle d-flex justify-content-between align-items-center"
dropdownToggle> dropdownToggle>
<span *ngIf="!editorForm.get(['filters', 'stateFilter']).value">{{ 'dashboard.list.anyState' | translate <span *ngIf="!editorForm.get(['filters', 'stateFilter']).value">
}}</span> {{ 'dashboard.list.anyState' | translate }}
<span *ngIf="editorForm.get(['filters', 'stateFilter']).value === 'running'">{{ </span>
'dashboard.listItem.stateRunning' | translate }}</span> <span *ngIf="editorForm.get(['filters', 'stateFilter']).value === 'running'">
<span *ngIf="editorForm.get(['filters', 'stateFilter']).value === 'stopped'">{{ {{ 'dashboard.listItem.stateRunning' | translate }}
'dashboard.listItem.stateStopped' | translate }}</span> </span>
<span *ngIf="editorForm.get(['filters', 'stateFilter']).value === 'stopped'">
{{ 'dashboard.listItem.stateStopped' | translate }}
</span>
</button> </button>
<ul *dropdownMenu class="dropdown-menu dropdown-menu-state-filter" role="menu"> <ul *dropdownMenu class="dropdown-menu dropdown-menu-state-filter" role="menu">
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" [class.active]="!editorForm.get(['filters', 'stateFilter']).value" <button class="dropdown-item" [class.active]="!editorForm.get(['filters', 'stateFilter']).value"
(click)="setStateFilter()"> (click)="setStateFilter()">
{{ 'dashboard.list.anyState' | translate }} {{ 'dashboard.list.anyState' | translate }}
</button> </button>
</li> </li>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" <button class="dropdown-item"
[class.active]="editorForm.get(['filters', 'stateFilter']).value === 'running'" [class.active]="editorForm.get(['filters', 'stateFilter']).value === 'running'"
(click)="setStateFilter('running')"> (click)="setStateFilter('running')">
{{ 'dashboard.listItem.stateRunning' | translate }} {{ 'dashboard.listItem.stateRunning' | translate }}
</button> </button>
</li> </li>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" <button class="dropdown-item"
[class.active]="editorForm.get(['filters', 'stateFilter']).value === 'stopped'" [class.active]="editorForm.get(['filters', 'stateFilter']).value === 'stopped'"
(click)="setStateFilter('stopped')"> (click)="setStateFilter('stopped')">
{{ 'dashboard.listItem.stateStopped' | translate }} {{ 'dashboard.listItem.stateStopped' | translate }}
</button> </button>
</li> </li>
@ -313,8 +316,9 @@
<div class="dropdown-header">{{ 'dashboard.list.filterByDisk' | translate }}</div> <div class="dropdown-header">{{ 'dashboard.list.filterByDisk' | translate }}</div>
<ngx-slider class="mb-3" formControlName="diskFilter" [options]="diskFilterOptions"></ngx-slider> <ngx-slider class="mb-3" formControlName="diskFilter" [options]="diskFilterOptions"></ngx-slider>
<button class="btn btn-outline-dark w-100 mt-3" (click)="clearFilters()">{{ 'dashboard.list.resetFilters' | <button class="btn btn-outline-dark w-100 mt-3" (click)="clearFilters()">
translate }}</button> {{ 'dashboard.list.resetFilters' | translate }}
</button>
</ng-container> </ng-container>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
@ -323,14 +327,14 @@
<label class="form-check-label" for="showMachineDetails"> <label class="form-check-label" for="showMachineDetails">
{{ 'dashboard.list.showDetails' | translate }} {{ 'dashboard.list.showDetails' | translate }}
<fa-icon icon="spinner" [pulse]="true" size="sm" class="me-1" <fa-icon icon="spinner" [pulse]="true" size="sm" class="me-1"
*ngIf="editorForm.get('showMachineDetails').disabled"></fa-icon> *ngIf="editorForm.get('showMachineDetails').disabled"></fa-icon>
</label> </label>
</div> </div>
<div [collapse]="!editorForm.get('showMachineDetails').value" [isAnimated]="true"> <div [collapse]="!editorForm.get('showMachineDetails').value" [isAnimated]="true">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input mt-0" type="checkbox" id="fullDetailsTwoColumns" <input class="form-check-input mt-0" type="checkbox" id="fullDetailsTwoColumns"
formControlName="fullDetailsTwoColumns"> formControlName="fullDetailsTwoColumns">
<label class="form-check-label" for="fullDetailsTwoColumns"> <label class="form-check-label" for="fullDetailsTwoColumns">
{{ 'dashboard.list.dualColumns' | translate }} {{ 'dashboard.list.dualColumns' | translate }}
</label> </label>
@ -343,40 +347,46 @@
<ul class="list-group list-group-flush" role="menu"> <ul class="list-group list-group-flush" role="menu">
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" (click)="renameMachine(instance)"> <button class="dropdown-item" (click)="renameMachine(instance)">
<fa-icon icon="pen" [fixedWidth]="true"></fa-icon> <fa-icon icon="pen" [fixedWidth]="true" size="sm"></fa-icon>
{{ 'dashboard.listItem.rename' | translate }} {{ 'dashboard.listItem.rename' | translate }}
</button> </button>
</li> </li>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" (click)="showTagEditor(instance)"> <button class="dropdown-item" (click)="showTagEditor(instance)">
<fa-icon icon="tags" [fixedWidth]="true"></fa-icon> <fa-icon icon="tags" [fixedWidth]="true" size="sm"></fa-icon>
{{ 'dashboard.listItem.editTags' | translate }} {{ 'dashboard.listItem.editTags' | translate }}
</button> </button>
</li> </li>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" (click)="showTagEditor(instance, true)"> <button class="dropdown-item" (click)="showTagEditor(instance, true)">
<fa-icon icon="tags" [fixedWidth]="true"></fa-icon> <fa-icon icon="tags" [fixedWidth]="true" size="sm"></fa-icon>
{{ 'dashboard.listItem.editMetadata' | translate }} {{ 'dashboard.listItem.editMetadata' | translate }}
</button> </button>
</li> </li>
<li class="dropdown-divider"></li> <li class="dropdown-divider"></li>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" (click)="createMachine(instance)"> <button class="dropdown-item" (click)="createMachine(instance)">
<fa-icon icon="clone" [fixedWidth]="true"></fa-icon> <fa-icon icon="clone" [fixedWidth]="true" size="sm"></fa-icon>
{{ 'dashboard.listItem.clone' | translate }} {{ 'dashboard.listItem.clone' | translate }}
</button> </button>
</li> </li>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" (click)="createImageFromMachine(instance)"> <button class="dropdown-item" (click)="createImageFromMachine(instance)">
<fa-icon icon="layer-group" [fixedWidth]="true"></fa-icon> <fa-icon icon="layer-group" [fixedWidth]="true" size="sm"></fa-icon>
{{ 'dashboard.listItem.createImage' | translate }} {{ 'dashboard.listItem.createImage' | translate }}
</button> </button>
</li> </li>
<li class="dropdown-divider"></li> <li class="dropdown-divider"></li>
<ng-container *ngIf="instance.state === 'running'"> <ng-container *ngIf="instance.state === 'running'">
<li role="menuitem">
<button class="dropdown-item" (click)="restartMachine(instance)">
<fa-icon icon="undo" [fixedWidth]="true" size="sm"></fa-icon>
{{ 'dashboard.listItem.restart' | translate }}
</button>
</li>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" (click)="stopMachine(instance)"> <button class="dropdown-item" (click)="stopMachine(instance)">
<fa-icon icon="stop" [fixedWidth]="true"></fa-icon> <fa-icon icon="stop" [fixedWidth]="true" size="sm"></fa-icon>
{{ 'dashboard.listItem.stop' | translate }} {{ 'dashboard.listItem.stop' | translate }}
</button> </button>
</li> </li>
@ -384,9 +394,9 @@
</ng-container> </ng-container>
<li role="menuitem"> <li role="menuitem">
<button class="dropdown-item" (click)="deleteMachine(instance)"> <button class="dropdown-item" (click)="deleteMachine(instance)">
<fa-icon icon="trash" [fixedWidth]="true"></fa-icon> <fa-icon icon="trash" [fixedWidth]="true" size="sm"></fa-icon>
{{ 'dashboard.listItem.delete' | translate }} {{ 'dashboard.listItem.delete' | translate }}
</button> </button>
</li> </li>
</ul> </ul>
</ng-template> </ng-template>

View File

@ -1,162 +1,197 @@
:host { :host
{
flex-direction: column; flex-direction: column;
overflow : hidden; overflow: hidden;
} }
.ips { .ips
+.ips { {
margin-left : .5rem; + .ips
{
margin-left: .5rem;
padding-left: .5rem; padding-left: .5rem;
border-left : 2px solid #2b3540; border-left: 2px solid #2b3540;
} }
} }
.card { .card
border : 1px solid rgba(0, 0, 0, .5); {
border: 1px solid rgba(0, 0, 0, .5);
background-color: rgba(16, 21, 39, .5); background-color: rgba(16, 21, 39, .5);
box-shadow : 0 0 0 2px #0b2b51, 0 0 2px 4px #0b284b, 0 0 10px 3px #0e162a; box-shadow: 0 0 0 2px #0b2b51, 0 0 2px 4px #0b284b, 0 0 10px 3px #0e162a;
transition : box-shadow .15s ease-out; transition: box-shadow .15s ease-out;
&:hover { &:hover
{
box-shadow: 0 0 0 2px #0b2b51, 0 0 2px 4px rgba(18, 203, 240, .4), 0 0 10px 3px #0e162a; box-shadow: 0 0 0 2px #0b2b51, 0 0 2px 4px rgba(18, 203, 240, .4), 0 0 10px 3px #0e162a;
} }
.card-title { .card-title
color : #ff9c07; {
color: #ff9c07;
margin-bottom: 0; margin-bottom: 0;
font-weight : bold; font-weight: bold;
} }
.card-body { .card-body
{
background-color: rgba(16, 21, 39, .5); background-color: rgba(16, 21, 39, .5);
max-height : 205px; max-height: 205px;
overflow : auto; overflow: auto;
padding-top : .7rem !important; padding-top: .7rem !important;
} }
.list-group-item { .list-group-item
{
background: none; background: none;
span { span
{
color: #8881ff; color: #8881ff;
} }
b, b,
.strong { .strong
color : #ff9c07; {
color: #ff9c07;
font-weight: bold; font-weight: bold;
} }
} }
.btn-info, .btn-info,
.btn-outline-info { .btn-outline-info
font-size : 1rem; {
font-size: 1rem;
line-height: 1; line-height: 1;
} }
} }
.card-info { .card-info
{
background-color: rgba(16, 21, 39, .75); background-color: rgba(16, 21, 39, .75);
display : flex; display: flex;
flex-direction : column; flex-direction: column;
justify-content : space-between; justify-content: space-between;
padding : .25rem .5rem .5rem; padding: .25rem .5rem .5rem;
height : 170px; height: 170px;
} }
.full-details .card-info { .full-details .card-info
{
height: 240px; height: 240px;
} }
@media (max-width: 576px) { @media (max-width: 576px)
.card-info { {
.card-info
{
height: auto; height: auto;
} }
} }
.no-overflow-sm { .no-overflow-sm
{
overflow: hidden; overflow: hidden;
} }
@media (max-width: 992px) { @media (max-width: 992px)
.no-overflow-sm { {
.no-overflow-sm
{
overflow: visible; overflow: visible;
} }
} }
.open .dropdown-toggle {} .open .dropdown-toggle
{
}
.filters { .filters
{
width: 240px; width: 240px;
} }
.form-check-label { .form-check-label
{
color: inherit; color: inherit;
} }
.btn-toolbar .btn { .btn-toolbar .btn
.badge { {
padding : 0.1rem 0.35rem 0; .badge
border : 1px solid transparent; {
text-shadow: 0 0 3px rgb(255 255 255 / 25%); padding: .1rem .35rem 0;
border: 1px solid transparent;
font-weight: 400;
font-size: 1.25rem;
&:first-letter { &:first-letter
{
font-size: 1.2rem; font-size: 1.2rem;
} }
} }
&:hover { &:hover
.badge { {
border-color: #000; .badge
{
border-color: rgba(0,0,0,.25);
} }
} }
} }
@keyframes flash { @keyframes flash
{
from, from, 50%, to
50%, {
to {
opacity: 1; opacity: 1;
} }
25%, 25%, 75%
75% { {
opacity: 0; opacity: 0;
} }
} }
.flash { .flash
animation-name : flash; {
animation-duration : calc(.9s * 1.3); animation-name: flash;
animation-duration: calc(.9s * 1.3);
animation-timing-function: ease-in-out; animation-timing-function: ease-in-out;
} }
.btn-state-filter:not(.btn-lg):not(.btn-sm) { .btn-state-filter:not(.btn-lg):not(.btn-sm)
{
background-color: #11182b; background-color: #11182b;
color : #ff9c07; color: #ff9c07;
padding : .5rem 1rem; padding: .5rem 1rem;
} }
.open.show .btn-state-filter { .open.show .btn-state-filter
{
border-radius: 1.25rem 1.25rem 0 0; border-radius: 1.25rem 1.25rem 0 0;
} }
.dropdown-menu.dropdown-menu-state-filter { .dropdown-menu.dropdown-menu-state-filter
background : #11182b; {
color : #ff9c07; background: #11182b;
width : 100%; color: #ff9c07;
padding : 0; width: 100%;
padding: 0;
border-radius: 0 0 .25rem .25rem; border-radius: 0 0 .25rem .25rem;
.dropdown-item { .dropdown-item
{
color: inherit; color: inherit;
&.active { &.active
{
color: #0dcaf0; color: #0dcaf0;
} }
&:hover { &:hover
{
background-color: rgba(11, 172, 204, .2); background-color: rgba(11, 172, 204, .2);
} }
} }
@ -164,6 +199,17 @@
.form-switch, .form-switch,
.form-switch input, .form-switch input,
.form-switch label { .form-switch label
{
cursor: pointer; cursor: pointer;
} }
.dropdown-toggle b
{
font-weight: 400;
}
a.badge
{
text-decoration: none;
}

View File

@ -774,7 +774,7 @@ export class InstancesComponent implements OnInit, OnDestroy
instance.working = false; instance.working = false;
}); });
instance.shouldLoadInfo = this.editorForm.get('showMachineDetails').value; instance.shouldLoadInfo = true;
} }
// ---------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------

View File

@ -32,7 +32,8 @@ import
faTimes, faTrash, faUser, faUserTag, faTag, faUserLock, faLock, faPen, faCheckCircle, faPenNib, faPlus, faMinus, faAngleRight, faHandPointer, faTimes, faTrash, faUser, faUserTag, faTag, faUserLock, faLock, faPen, faCheckCircle, faPenNib, faPlus, faMinus, faAngleRight, faHandPointer,
faArrowsAlt, faTags, faEllipsisV, faHatWizard, faUserCog, faCircle, faAngleLeft, faExternalLinkAlt, faCheck, faPowerOff, faBars, faSpinner, faArrowsAlt, faTags, faEllipsisV, faHatWizard, faUserCog, faCircle, faAngleLeft, faExternalLinkAlt, faCheck, faPowerOff, faBars, faSpinner,
faStop, faPlay, faRedo, faMicrochip, faDesktop, faCopy, faSquare, faCheckSquare, faSave, faDatabase, faClone, faSearch, faHistory, faMask, faStop, faPlay, faRedo, faMicrochip, faDesktop, faCopy, faSquare, faCheckSquare, faSave, faDatabase, faClone, faSearch, faHistory, faMask,
faCloud, faCloudUploadAlt, faEye, faFingerprint, faLink, faClipboard, faCoins, faArrowRight, faEllipsisH, faStar, faCommentAlt, faOutdent faCloud, faCloudUploadAlt, faEye, faFingerprint, faLink, faClipboard, faCoins, faArrowRight, faEllipsisH, faStar, faCommentAlt, faOutdent,
faUndo
} from '@fortawesome/free-solid-svg-icons'; } from '@fortawesome/free-solid-svg-icons';
import { faDocker } from '@fortawesome/free-brands-svg-icons'; import { faDocker } from '@fortawesome/free-brands-svg-icons';
@ -147,7 +148,8 @@ export class SharedModule
faTimes, faTrash, faUser, faUserTag, faTag, faUserLock, faLock, faPen, faCheckCircle, faPenNib, faPlus, faMinus, faAngleRight, faHandPointer, faTimes, faTrash, faUser, faUserTag, faTag, faUserLock, faLock, faPen, faCheckCircle, faPenNib, faPlus, faMinus, faAngleRight, faHandPointer,
faArrowsAlt, faTags, faEllipsisV, faHatWizard, faUserCog, faCircle, faAngleLeft, faExternalLinkAlt, faCheck, faPowerOff, faBars, faSpinner, faArrowsAlt, faTags, faEllipsisV, faHatWizard, faUserCog, faCircle, faAngleLeft, faExternalLinkAlt, faCheck, faPowerOff, faBars, faSpinner,
faStop, faPlay, faRedo, faMicrochip, faDesktop, faCopy, faSquare, faCheckSquare, faSave, faDatabase, faClone, faSearch, faHistory, faMask, faStop, faPlay, faRedo, faMicrochip, faDesktop, faCopy, faSquare, faCheckSquare, faSave, faDatabase, faClone, faSearch, faHistory, faMask,
faCloud, faCloudUploadAlt, faEye, faFingerprint, faLink, faClipboard, faCoins, faArrowRight, faEllipsisH, faStar, faCommentAlt, faOutdent faCloud, faCloudUploadAlt, faEye, faFingerprint, faLink, faClipboard, faCoins, faArrowRight, faEllipsisH, faStar, faCommentAlt, faOutdent,
faUndo
); );
} }
} }

View File

@ -2,7 +2,7 @@
{ {
border-radius: 2rem; border-radius: 2rem;
line-height: 1.2; line-height: 1.2;
font-family: "Mukta", sans-serif; font-family: "Bebas Neue", sans-serif;
text-transform: uppercase; text-transform: uppercase;
font-weight: 400; font-weight: 400;
@ -18,7 +18,7 @@
.btn:not(.btn-lg):not(.btn-sm) .btn:not(.btn-lg):not(.btn-sm)
{ {
font-size: 1.15rem; font-size: 1.25rem;
padding: .375rem .5rem .3rem; padding: .375rem .5rem .3rem;
} }
@ -34,10 +34,10 @@
.btn.btn-lg .btn.btn-lg
{ {
font-size: 1.15rem; font-size: 1.5rem;
padding-bottom: .35rem; padding-bottom: .35rem;
line-height: 1; line-height: 1;
font-weight: 600; font-weight: 400;
} }
.btn-primary .btn-primary

View File

@ -2,8 +2,8 @@
{ {
text-transform: uppercase; text-transform: uppercase;
color: #0dcaf0; color: #0dcaf0;
font-family: "Varta", sans-serif; font-family: "Bebas Neue", sans-serif;
font-size: 1.2rem; font-size: 1.25rem;
vertical-align: middle; vertical-align: middle;
} }

View File

@ -29,7 +29,7 @@
h4 h4
{ {
color: #3d5e8e; color: #3d5e8e;
font-family: "Varta", sans-serif; font-family: "Bebas Neue", sans-serif;
} }
} }
} }

View File

@ -116,7 +116,8 @@ body, div, virtual-scroller
background: none; background: none;
border-radius: 0; border-radius: 0;
border: none; border: none;
font-family: "Varta", sans-serif; font-family: "Bebas Neue", sans-serif;
text-transform: uppercase;
text-align: center; text-align: center;
color: #0dcaf0; color: #0dcaf0;
width: 100%; width: 100%;
@ -138,6 +139,7 @@ body, div, virtual-scroller
.nav-tabs .nav-tabs
{ {
border: none; border: none;
flex-wrap: nowrap;
} }
.tab-content .tab-content
@ -266,10 +268,11 @@ accordion
.dropdown-menu, .menu-popover, .menu-dropdown .dropdown-menu, .menu-popover, .menu-dropdown
{ {
background: linear-gradient(135deg, #1fd1f5 0%, #00c3ea 100%); background: linear-gradient(135deg, #1fd1f5 0%, #00c3ea 100%);
font-family: "Varta", sans-serif; font-family: "Bebas Neue", sans-serif;
font-size: 1.2rem; font-size: 1.25rem;
z-index: 1020; z-index: 1020;
max-height: 60vh; max-height: 80vh;
max-width: 600px;
overflow: auto; overflow: auto;
} }
@ -472,7 +475,7 @@ accordion
{ {
thead thead
{ {
font-family: "Varta", sans-serif; font-family: "Bebas Neue", sans-serif;
font-size: 1.2rem; font-size: 1.2rem;
color: #A3A4B8; color: #A3A4B8;
} }
@ -537,4 +540,4 @@ accordion
.machine-brand b .machine-brand b
{ {
text-transform: uppercase; text-transform: uppercase;
} }