mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-04 22:39:46 +00:00
more styling
This commit is contained in:
committed by
Aiden McClelland
parent
5eaa51d22d
commit
d9f1c9b021
@@ -7,41 +7,43 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding-top">
|
||||
<ng-container *ngIf="pkg">
|
||||
|
||||
<ion-card style="margin-bottom: 16px;" *ngFor="let interface of pkg.installed.manifest.interfaces | keyvalue: asIsOrder">
|
||||
<ion-card-header>
|
||||
<ion-card-title>
|
||||
{{ interface.value.name }}
|
||||
<ion-button class="vertical-align" *ngIf="interface.value.ui" [disabled]="!(pkg | isLaunchable)" fill="clear" (click)="launch(pkg.installed)">
|
||||
<ion-icon slot="icon-only" name="rocket-outline" size="small"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-card-title>
|
||||
<ion-card-subtitle>{{ interface.value.description }}</ion-card-subtitle>
|
||||
</ion-card-header>
|
||||
<ion-card-content>
|
||||
<ng-container *ngIf="pkg.installed['interface-info'].addresses[interface.key] as int">
|
||||
<ion-item>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>Tor Address</h2>
|
||||
<p>{{ 'http://' + int['tor-address'] }}</p>
|
||||
</ion-label>
|
||||
<ion-button slot="end" fill="clear" (click)="copy('http://' + int['tor-address'])">
|
||||
<ion-icon size="small" slot="icon-only" name="copy-outline"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>LAN Address</h2>
|
||||
<p>{{ 'https://' + int['lan-address'] }}</p>
|
||||
</ion-label>
|
||||
<ion-button slot="end" fill="clear" (click)="copy('https://' + int['lan-address'])">
|
||||
<ion-icon size="small" slot="icon-only" name="copy-outline"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</ng-container>
|
||||
<ion-content>
|
||||
<ion-grid *ngIf="pkg">
|
||||
<ion-row>
|
||||
<ion-col *ngFor="let interface of pkg.installed.manifest.interfaces | keyvalue: asIsOrder" sizeSm="12" sizeMd="6">
|
||||
<ion-card>
|
||||
<ion-card-header>
|
||||
<ion-card-title>{{ interface.value.name }}</ion-card-title>
|
||||
<ion-card-subtitle>{{ interface.value.description }}</ion-card-subtitle>
|
||||
<ion-button style="margin-top: 12px;" *ngIf="interface.value.ui" [disabled]="!(pkg | isLaunchable)" fill="outline" color="dark" expand="block" (click)="launch(pkg.installed)">
|
||||
Launch
|
||||
<ion-icon slot="end" name="rocket-outline"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-card-header>
|
||||
<ion-card-content>
|
||||
<ng-container *ngIf="pkg.installed['interface-info'].addresses[interface.key] as int">
|
||||
<ion-item>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>Tor Address</h2>
|
||||
<p>{{ 'http://' + int['tor-address'] }}</p>
|
||||
</ion-label>
|
||||
<ion-button slot="end" fill="clear" (click)="copy('http://' + int['tor-address'])">
|
||||
<ion-icon size="small" slot="icon-only" name="copy-outline"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>LAN Address</h2>
|
||||
<p>{{ 'https://' + int['lan-address'] }}</p>
|
||||
</ion-label>
|
||||
<ion-button slot="end" fill="clear" (click)="copy('https://' + int['lan-address'])">
|
||||
<ion-icon size="small" slot="icon-only" name="copy-outline"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-content>
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<div *ngIf="pkgs | empty; else list" class="ion-text-center ion-padding">
|
||||
<div style="display: flex; flex-direction: column; justify-content: center; height: 40vh">
|
||||
<h2>Welcome to your <span style="font-style: italic; color: var(--ion-color-start9)">Embassy</span></h2>
|
||||
<h2>Welcome to your <span style="font-style: italic; color: var(--ion-color-danger)">Embassy</span></h2>
|
||||
<p class="ion-text-wrap">Get started by installing your first service.</p>
|
||||
</div>
|
||||
<ion-button [routerLink]="['/marketplace']" style="width: 50%;" fill="outline">
|
||||
@@ -24,7 +24,7 @@
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col *ngFor="let pkg of pkgs | keyvalue : asIsOrder" sizeXs="4" sizeSm="3" sizeLg="3" sizeXl="2">
|
||||
<ion-card class="installed-card" style="position:relative" [routerLink]="['/services', (pkg.value | manifest).id]">
|
||||
<ion-card class="installed-card" [routerLink]="['/services', (pkg.value | manifest).id]">
|
||||
<div class="launch-container" *ngIf="pkg.value | hasUi">
|
||||
<div class="launch-button-triangle" (click)="launchUi(pkg.value, $event)" [class.launch-disabled]="!(pkg.value | isLaunchable)">
|
||||
<ion-icon name="rocket-outline"></ion-icon>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.installed-card {
|
||||
margin: 0;
|
||||
margin: 2px;
|
||||
background: linear-gradient(37deg, #333333, #131313);
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
ion-card-title {
|
||||
font-size: calc(10px + .4vw);
|
||||
color: white;
|
||||
color: var(--ion-color-dark);
|
||||
margin: 10px 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -24,8 +24,7 @@
|
||||
|
||||
.main-img {
|
||||
width: 50%;
|
||||
margin: 9px;
|
||||
color: white;
|
||||
margin: 12px;
|
||||
border-radius: var(--icon-border-radius);
|
||||
}
|
||||
|
||||
@@ -48,10 +47,7 @@
|
||||
}
|
||||
|
||||
.launch-button-triangle {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
right: 0px;
|
||||
margin: 0px;
|
||||
|
||||
border-style: solid;
|
||||
border-width: 22px;
|
||||
@@ -81,6 +77,4 @@
|
||||
.launch-container {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<pwa-back-button></pwa-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Logs</ion-title>
|
||||
<ion-buttons slot="end" class="ion-padding-end">
|
||||
<ion-buttons slot="end">
|
||||
<ion-button (click)="getLogs()">
|
||||
<ion-icon slot="icon-only" name="refresh-outline"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
<ion-buttons slot="start">
|
||||
<pwa-back-button></pwa-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Values</ion-title>
|
||||
<ion-buttons slot="end" class="ion-padding-end">
|
||||
<ion-title>Properties</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button (click)="refresh()">
|
||||
<ion-icon slot="icon-only" name="refresh-outline"></ion-icon>
|
||||
</ion-button>
|
||||
@@ -30,7 +30,7 @@
|
||||
<!-- no properties -->
|
||||
<ion-item *ngIf="properties | empty">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<p>No values.</p>
|
||||
<p>No properties.</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
<div *ngFor="let prop of node | keyvalue: asIsOrder">
|
||||
<!-- object -->
|
||||
<ion-item button detail="true" *ngIf="prop.value.type === 'object'" (click)="goToNested(prop.key)">
|
||||
<ion-button *ngIf="prop.value.description" class="help-button" fill="clear" slot="start" (click)="presentDescription(prop, $event)">
|
||||
<ion-icon size="small" slot="icon-only" name="help-circle-outline"></ion-icon>
|
||||
<ion-button *ngIf="prop.value.description" fill="clear" slot="start" (click)="presentDescription(prop, $event)">
|
||||
<ion-icon slot="icon-only" name="help-circle-outline"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ prop.key }}</h2>
|
||||
@@ -48,8 +48,8 @@
|
||||
</ion-item>
|
||||
<!-- not object -->
|
||||
<ion-item *ngIf="prop.value.type === 'string'">
|
||||
<ion-button *ngIf="prop.value.description" class="help-button" fill="clear" slot="start" (click)="presentDescription(prop, $event)">
|
||||
<ion-icon size="small" slot="icon-only" name="help-circle-outline"></ion-icon>
|
||||
<ion-button *ngIf="prop.value.description" fill="clear" slot="start" (click)="presentDescription(prop, $event)">
|
||||
<ion-icon slot="icon-only" name="help-circle-outline"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ prop.key }}</h2>
|
||||
@@ -57,13 +57,13 @@
|
||||
</ion-label>
|
||||
<div slot="end" *ngIf="prop.value.copyable || prop.value.qr">
|
||||
<ion-button *ngIf="prop.value.masked" fill="clear" (click)="toggleMask(prop.key)">
|
||||
<ion-icon slot="icon-only" [name]="unmasked[prop.key] ? 'eye-off-outline' : 'eye-outline'" [color]="unmasked[prop.key] ? 'danger' : 'primary'" size="small"></ion-icon>
|
||||
<ion-icon slot="icon-only" [name]="unmasked[prop.key] ? 'eye-off-outline' : 'eye-outline'" [color]="unmasked[prop.key] ? 'danger' : 'dark'" size="small"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-button *ngIf="prop.value.qr" fill="clear" (click)="showQR(prop.value.value)">
|
||||
<ion-icon slot="icon-only" name="qr-code-outline" size="small" color="primary"></ion-icon>
|
||||
<ion-icon slot="icon-only" name="qr-code-outline" size="small"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-button *ngIf="prop.value.copyable" fill="clear" (click)="copy(prop.value.value)">
|
||||
<ion-icon slot="icon-only" name="copy-outline" size="small" color="primary"></ion-icon>
|
||||
<ion-icon slot="icon-only" name="copy-outline" size="small"></ion-icon>
|
||||
</ion-button>
|
||||
</div>
|
||||
</ion-item>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
<ion-buttons slot="start">
|
||||
<pwa-back-button></pwa-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Restore Backup</ion-title>
|
||||
<ion-buttons slot="end" class="ion-padding-end">
|
||||
<ion-title>Restore From Backup</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button (click)="refresh()">
|
||||
<ion-icon slot="icon-only" name="refresh-outline"></ion-icon>
|
||||
</ion-button>
|
||||
@@ -27,49 +27,52 @@
|
||||
<ion-item *ngIf="error" style="margin-bottom: 16px;">
|
||||
<ion-text class="ion-text-wrap" color="danger">{{ error }}</ion-text>
|
||||
</ion-item>
|
||||
|
||||
|
||||
<ion-item class="ion-margin-bottom">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<p><ion-text color="dark">About</ion-text></p>
|
||||
<p>
|
||||
Select a location from which to restore {{ title }}. This will overwrite all current data.
|
||||
</p>
|
||||
<p class="ion-padding-bottom"><ion-text color="warning">Warning</ion-text></p>
|
||||
<h2>
|
||||
Restoring from backup will overwrite all current data for {{ title }} .
|
||||
</h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-spinner *ngIf="loading; else loaded" name="lines" color="warning" class="center"></ion-spinner>
|
||||
|
||||
<ng-template #loaded>
|
||||
|
||||
<ion-item *ngIf="allPartitionsMounted">
|
||||
<ion-text *ngIf="type === 'restore'" class="ion-text-wrap" color="warning">No partitions available. Insert the storage device containing the backup you intend to restore.</ion-text>
|
||||
</ion-item>
|
||||
|
||||
<ion-card *ngFor="let disk of disks | keyvalue">
|
||||
<ion-card-header>
|
||||
<ion-card-title>
|
||||
{{ disk.value.size }}
|
||||
</ion-card-title>
|
||||
<ion-card-subtitle>
|
||||
{{ disk.key }}
|
||||
</ion-card-subtitle>
|
||||
</ion-card-header>
|
||||
<ion-card-content>
|
||||
<ion-item-group>
|
||||
<ion-item button *ngFor="let partition of disk.value.partitions | keyvalue" [disabled]="partition.value['is-mounted']" (click)="presentModal(partition.key, partition.value)">
|
||||
<ion-icon slot="start" name="save-outline"></ion-icon>
|
||||
<ion-label>
|
||||
<h2>{{ partition.value.label || partition.key }} ({{ partition.value.size || 'unknown size' }})</h2>
|
||||
<p *ngIf="!partition.value['is-mounted']; else unavailable"><ion-text color="success">Available</ion-text></p>
|
||||
<ng-template #unavailable>
|
||||
<p><ion-text color="danger">Unavailable</ion-text></p>
|
||||
</ng-template>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</ng-template>
|
||||
|
||||
<ion-item-divider>Select Backup Drive</ion-item-divider>
|
||||
|
||||
<ion-item *ngIf="allPartitionsMounted">
|
||||
<ion-text class="ion-text-wrap" color="warning">No partitions available. Insert the storage device containing the backup you intend to restore.</ion-text>
|
||||
</ion-item>
|
||||
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col *ngFor="let disk of disks | keyvalue" sizeSm="12" sizeMd="6">
|
||||
<ion-card>
|
||||
<ion-card-header>
|
||||
<ion-card-title>
|
||||
{{ disk.value.size }}
|
||||
</ion-card-title>
|
||||
<ion-card-subtitle>
|
||||
{{ disk.key }}
|
||||
</ion-card-subtitle>
|
||||
</ion-card-header>
|
||||
<ion-card-content>
|
||||
<ion-item-group>
|
||||
<ion-item button *ngFor="let partition of disk.value.partitions | keyvalue" [disabled]="partition.value['is-mounted']" (click)="presentModal(partition.key, partition.value)">
|
||||
<ion-icon slot="start" name="save-outline"></ion-icon>
|
||||
<ion-label>
|
||||
<h2>{{ partition.value.label || partition.key }} ({{ partition.value.size || 'unknown size' }})</h2>
|
||||
<p *ngIf="!partition.value['is-mounted']; else unavailable"><ion-text color="success">Available</ion-text></p>
|
||||
<ng-template #unavailable>
|
||||
<p><ion-text color="danger">Unavailable</ion-text></p>
|
||||
</ng-template>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ng-template>
|
||||
|
||||
</ion-content>
|
||||
|
||||
@@ -19,39 +19,30 @@
|
||||
<ng-container *ngIf="pkg">
|
||||
<!-- top plate -->
|
||||
<div class="top-plate">
|
||||
<ion-item class="no-cushion-item" lines="none">
|
||||
<ion-label class="ion-text-wrap" style="
|
||||
display: grid;
|
||||
grid-template-columns: 80px auto;
|
||||
margin: 0px;
|
||||
margin-top: 15px;"
|
||||
>
|
||||
<ion-avatar style="justify-self: center; height: 55px; width: 55px" slot="start">
|
||||
<img [src]="pkg['static-files'].icon" />
|
||||
</ion-avatar>
|
||||
<div style="display: flex; flex-direction: column;">
|
||||
<ion-text style="font-family: 'Montserrat'; font-size: x-large; line-height: normal;" [class.less-large]="manifest.title.length > 20">
|
||||
{{ manifest.title }}
|
||||
</ion-text>
|
||||
<ion-text style="margin-top: -5px; margin-left: 2px;">
|
||||
{{ manifest.version | displayEmver }}
|
||||
</ion-text>
|
||||
</div>
|
||||
<ion-item lines="none">
|
||||
<ion-thumbnail slot="start">
|
||||
<img [src]="pkg['static-files'].icon" />
|
||||
</ion-thumbnail>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h1 style="font-family: 'Montserrat';" [class.less-large]="manifest.title.length > 20">
|
||||
{{ manifest.title }}
|
||||
</h1>
|
||||
<h5>{{ manifest.version | displayEmver }}</h5>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<div class="status-readout">
|
||||
<status *ngIf="connected" size="large" weight="bold" [pkg]="pkg"></status>
|
||||
<ion-button *ngIf="pkg.status === FeStatus.NeedsConfig" expand="block" fill="outline" [routerLink]="['config']">
|
||||
<status *ngIf="connected" size="large" weight="500" [pkg]="pkg"></status>
|
||||
<ion-button *ngIf="pkg.status === FeStatus.NeedsConfig" expand="block" [routerLink]="['config']">
|
||||
Configure
|
||||
</ion-button>
|
||||
<ion-button *ngIf="[FeStatus.Running, FeStatus.StartingUp, FeStatus.NeedsAttention] | includes : pkg.status" expand="block" fill="outline" color="danger" (click)="stop()">
|
||||
<ion-button *ngIf="[FeStatus.Running, FeStatus.StartingUp, FeStatus.NeedsAttention] | includes : pkg.status" expand="block" color="danger" (click)="stop()">
|
||||
Stop
|
||||
</ion-button>
|
||||
<ion-button *ngIf="pkg.status === FeStatus.DependencyIssue" expand="block" fill="outline" (click)="scrollToRequirements()">
|
||||
<ion-button *ngIf="pkg.status === FeStatus.DependencyIssue" expand="block" (click)="scrollToRequirements()">
|
||||
Fix
|
||||
</ion-button>
|
||||
<ion-button *ngIf="pkg.status === FeStatus.Stopped" expand="block" fill="outline" color="success" (click)="tryStart()">
|
||||
<ion-button *ngIf="pkg.status === FeStatus.Stopped" expand="block" color="success" (click)="tryStart()">
|
||||
Start
|
||||
</ion-button>
|
||||
</div>
|
||||
|
||||
@@ -5,20 +5,24 @@
|
||||
.top-plate {
|
||||
background: var(--ion-item-background);
|
||||
margin: 0 16px;
|
||||
padding: 12px;
|
||||
border-radius: 10px;
|
||||
border-style: solid;
|
||||
border-color: #373737;
|
||||
ion-item {
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-readout {
|
||||
--background: transparent;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 10px;
|
||||
padding: 8px 16px;
|
||||
border-radius: 10px;
|
||||
align-items: center;
|
||||
background: var(--ion-background-color);
|
||||
margin: 10px 10px 0px 10px;
|
||||
margin: 10px;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #404040;
|
||||
@@ -39,18 +43,3 @@
|
||||
border-style: solid;
|
||||
border-color: #404040;
|
||||
}
|
||||
|
||||
|
||||
.dep-issue {
|
||||
background: radial-gradient(var(--ion-color-warning) 40%, transparent)
|
||||
}
|
||||
|
||||
.dep-sat {
|
||||
background: radial-gradient(var(--ion-color-success) 40%, transparent)
|
||||
}
|
||||
|
||||
ion-item-divider {
|
||||
text-transform: uppercase;
|
||||
margin-top: 22px;
|
||||
font-weight: 400;
|
||||
}
|
||||
@@ -239,7 +239,7 @@ export class AppShowPage {
|
||||
},
|
||||
{
|
||||
action: () => this.navCtrl.navigateForward(['properties'], { relativeTo: this.route }),
|
||||
title: 'Values',
|
||||
title: 'Properties',
|
||||
icon: 'briefcase-outline',
|
||||
color: 'danger',
|
||||
disabled: [],
|
||||
@@ -267,7 +267,7 @@ export class AppShowPage {
|
||||
},
|
||||
{
|
||||
action: () => this.navCtrl.navigateForward(['restore'], { relativeTo: this.route }),
|
||||
title: 'Restore Backup',
|
||||
title: 'Restore From Backup',
|
||||
icon: 'color-wand-outline',
|
||||
color: 'danger',
|
||||
disabled: [FEStatus.Connecting, FEStatus.Installing, FEStatus.Updating, FEStatus.Stopping, FEStatus.Removing, FEStatus.BackingUp, FEStatus.Restoring],
|
||||
|
||||
Reference in New Issue
Block a user