mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 18:31:52 +00:00
better list page
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 56%;
|
||||
border-radius: 5px;
|
||||
border-radius: 6px;
|
||||
z-index: 1;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
@@ -24,38 +24,44 @@
|
||||
Marketplace
|
||||
</ion-button>
|
||||
</div>
|
||||
|
||||
|
||||
<ng-template #list>
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col *ngFor="let pkg of pkgs | keyvalue : asIsOrder" sizeXs="4" sizeSm="3" sizeLg="3" sizeXl="2">
|
||||
<ion-col *ngFor="let pkg of pkgs | keyvalue : asIsOrder" sizeXs="6" sizeSm="4" sizeLg="3">
|
||||
<ion-card class="installed-card" [routerLink]="['/services', pkg.value.entry.manifest.id]">
|
||||
<div
|
||||
class="bulb"
|
||||
[style.background-color]="connectionFailure ? 'var(--ion-color-dark)' : 'var(--ion-color-' + pkg.value.primaryRendering.color + ')'"
|
||||
>
|
||||
</div>
|
||||
<div class="launch-container" *ngIf="pkg.value.entry.manifest.interfaces | hasUi">
|
||||
<div class="launch-button-triangle" (click)="launchUi(pkg.value.entry, $event)" [class.launch-disabled]="!(pkg.value.entry.state | isLaunchable : pkg.value.entry.installed?.status.main.status : pkg.value.entry.manifest.interfaces)">
|
||||
<ion-icon name="open-outline"></ion-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<img style="position: absolute" class="main-img" [src]="pkg.value.entry['static-files'].icon" alt="icon" />
|
||||
<img class="main-img" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=">
|
||||
<img *ngIf="connectionFailure" class="bulb-off" src="assets/img/off-bulb.png" />
|
||||
<img *ngIf="!connectionFailure" [class]="pkg.value.bulb.class" [src]="pkg.value.bulb.img" />
|
||||
|
||||
<img class="main-img" [src]="pkg.value.entry['static-files'].icon" alt="icon" />
|
||||
<ion-card-header>
|
||||
<ion-grid class="status-grid">
|
||||
<ion-row class="ion-align-items-center">
|
||||
<ion-col></ion-col>
|
||||
<ion-col>
|
||||
<status *ngIf="[PackageState.Installed, PackageState.Removing] | includes : pkg.value.entry.state" [disconnected]="connectionFailure" [rendering]="pkg.value.primaryRendering" size="calc(8px + .4vw)" weight="bold"></status>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
<ion-icon *ngIf="pkg.value.error" name="warning-outline" color="warning"></ion-icon>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
<p *ngIf="!!pkg.value.installProgress" class="main-status"><ion-text color="primary">{{ pkg.value.entry.state | titlecase }}...{{ pkg.value.installProgress.totalProgress }}%</ion-text></p>
|
||||
<ion-card-title>{{ pkg.value.entry.manifest.title }}</ion-card-title>
|
||||
<ion-card-title>
|
||||
{{ pkg.value.entry.manifest.title }}
|
||||
</ion-card-title>
|
||||
</ion-card-header>
|
||||
<ion-card-content>
|
||||
<ion-toolbar class="status-toolbar">
|
||||
<ion-title>
|
||||
<ion-text *ngIf="!!pkg.value.installProgress" color="primary">{{ pkg.value.entry.state | titlecase }}...{{ pkg.value.installProgress.totalProgress }}%</ion-text>
|
||||
<status
|
||||
*ngIf="[PackageState.Installed, PackageState.Removing] | includes : pkg.value.entry.state"
|
||||
[disconnected]="connectionFailure"
|
||||
[rendering]="pkg.value.primaryRendering"
|
||||
weight="bold"
|
||||
size="calc(10px + .5vw)"
|
||||
>
|
||||
</status>
|
||||
</ion-title>
|
||||
<ion-icon *ngIf="pkg.value.error" name="warning-outline" color="warning"></ion-icon>
|
||||
</ion-toolbar>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
@@ -2,20 +2,16 @@
|
||||
margin: 4px;
|
||||
padding: 4px;
|
||||
background: linear-gradient(37deg, #333333, #131313);
|
||||
border-radius: 10px;
|
||||
border-radius: 6px;
|
||||
text-align: center;
|
||||
|
||||
ion-card-header {
|
||||
padding: 0 10px;
|
||||
|
||||
status {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
ion-card-title {
|
||||
font-size: calc(10px + .4vw);
|
||||
color: var(--ion-color-dark);
|
||||
margin: 10px 0;
|
||||
font-family: 'Montserrat';
|
||||
font-size: calc(10px + .5vw);
|
||||
margin-bottom: 12px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -24,41 +20,33 @@
|
||||
}
|
||||
|
||||
.main-img {
|
||||
width: 50%;
|
||||
width: 40%;
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
.bulb-on {
|
||||
.bulb {
|
||||
position: absolute !important;
|
||||
left: -7px !important;
|
||||
top: -7px !important;
|
||||
height: 25px !important;
|
||||
width: 25px !important;
|
||||
margin: 9px;
|
||||
}
|
||||
|
||||
.bulb-off {
|
||||
position: absolute !important;
|
||||
left: -1px !important;
|
||||
top: -1px !important;
|
||||
height: 13px !important;
|
||||
width: 13px !important;
|
||||
margin: 9px;
|
||||
left: 10px !important;
|
||||
top: 10px !important;
|
||||
height: calc(10px + .5vw);
|
||||
width: calc(10px + .5vw);
|
||||
border-radius: 100%;
|
||||
box-shadow: 0 0 4px 4px rgba(255, 255, 255, 0.3)
|
||||
}
|
||||
|
||||
.launch-button-triangle {
|
||||
right: 0px;
|
||||
|
||||
border-style: solid;
|
||||
border-width: 22px;
|
||||
border-width: 24px;
|
||||
border-color: rgb(70 193 255 / 75%) rgb(70 193 255 / 75%) transparent transparent;
|
||||
&:hover {
|
||||
border-color: rgb(70 193 255) rgb(70 193 255) transparent transparent;
|
||||
}
|
||||
ion-icon {
|
||||
position: absolute;
|
||||
right: 7px;
|
||||
top: 7px;
|
||||
right: 8px;
|
||||
top: 8px;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
@@ -79,22 +67,13 @@
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.main-status {
|
||||
font-size: calc(8px + .4vw);
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.status-grid {
|
||||
--ion-grid-padding: 0;
|
||||
ion-row {
|
||||
min-height: 22px;
|
||||
}
|
||||
ion-col {
|
||||
--ion-grid-column-padding: 0
|
||||
}
|
||||
.status-toolbar {
|
||||
--min-height: 42px;
|
||||
border-radius: 6px;
|
||||
ion-icon {
|
||||
font-size: calc(12px + .4vw);
|
||||
padding-top: 4px;
|
||||
font-size: calc(10px + .5vw);
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: calc(2vh);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,10 +58,6 @@ export class AppListPage {
|
||||
if (this.pkgs[id]) return
|
||||
this.pkgs[id] = {
|
||||
entry: pkgs[id],
|
||||
bulb: {
|
||||
class: 'bulb-off',
|
||||
img: 'assets/img/off-bulb.png',
|
||||
},
|
||||
primaryRendering: PrimaryRendering[renderPkgStatus(pkgs[id]).primary],
|
||||
installProgress: !isEmptyObject(pkgs[id]['install-progress']) ? this.installPackageService.transform(pkgs[id]['install-progress']) : undefined,
|
||||
error: false,
|
||||
@@ -70,31 +66,10 @@ export class AppListPage {
|
||||
// subscribe to pkg
|
||||
this.pkgs[id].sub = this.patch.watch$('package-data', id).subscribe(pkg => {
|
||||
if (!pkg) return
|
||||
let bulbClass = 'bulb-on'
|
||||
let img = ''
|
||||
const statuses = renderPkgStatus(pkg)
|
||||
const primaryRendering = PrimaryRendering[statuses.primary]
|
||||
switch (primaryRendering.color) {
|
||||
case 'danger':
|
||||
img = 'assets/img/danger-bulb.png'
|
||||
break
|
||||
case 'success':
|
||||
img = 'assets/img/success-bulb.png'
|
||||
break
|
||||
case 'warning':
|
||||
img = 'assets/img/warning-bulb.png'
|
||||
break
|
||||
default:
|
||||
bulbClass = 'bulb-off',
|
||||
img = 'assets/img/off-bulb.png'
|
||||
break
|
||||
}
|
||||
this.pkgs[id].entry = pkg
|
||||
this.pkgs[id].installProgress = !isEmptyObject(pkg['install-progress']) ? this.installPackageService.transform(pkg['install-progress']) : undefined
|
||||
this.pkgs[id].bulb = {
|
||||
class: bulbClass,
|
||||
img,
|
||||
}
|
||||
this.pkgs[id].primaryRendering = primaryRendering
|
||||
this.pkgs[id].error = [HealthStatus.NeedsConfig, HealthStatus.Failure].includes(statuses.health) || [DependencyStatus.Issue, DependencyStatus.Critical].includes(statuses.dependency)
|
||||
})
|
||||
@@ -126,10 +101,6 @@ export class AppListPage {
|
||||
|
||||
interface PkgInfo {
|
||||
entry: PackageDataEntry
|
||||
bulb: {
|
||||
class: string
|
||||
img: string
|
||||
}
|
||||
primaryRendering: StatusRendering
|
||||
installProgress: ProgressData
|
||||
error: boolean
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
</ion-label>
|
||||
<ng-container *ngIf="pkg.state === PackageState.Installed && !connectionFailure">
|
||||
<ion-button slot="end" class="action-button" *ngIf="pkg.manifest.interfaces | hasUi" [disabled]="!(pkg.state | isLaunchable : pkg.installed.status.main.status : pkg.manifest.interfaces)" (click)="launchUi()">
|
||||
<ion-icon slot="start" name="open-outline"></ion-icon>
|
||||
Open UI
|
||||
Launch UI
|
||||
<ion-icon slot="end" name="open-outline"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-button slot="end" class="action-button" *ngIf="!pkg.installed.status.configured" (click)="presentModalConfig()">
|
||||
Configure
|
||||
|
||||
@@ -6,7 +6,7 @@ ion-card-title {
|
||||
}
|
||||
|
||||
ion-item {
|
||||
--border-radius: 4px;
|
||||
--border-radius: 6px;
|
||||
--border-style: solid;
|
||||
--border-width: 1px;
|
||||
--border-color: var(--ion-color-light);
|
||||
|
||||
@@ -234,10 +234,6 @@ ion-button {
|
||||
}
|
||||
}
|
||||
|
||||
.custom-modal {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
ion-slides {
|
||||
.slider-wrapper {
|
||||
height: 100%;
|
||||
@@ -255,7 +251,7 @@ ion-item-divider {
|
||||
}
|
||||
|
||||
ion-item {
|
||||
border-radius: 4px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
ion-label {
|
||||
@@ -278,7 +274,7 @@ ion-loading {
|
||||
border-width: 1px;
|
||||
border-style: groove;
|
||||
border-color: dimgrey;
|
||||
border-radius: 10px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 4px 4px 16px var(--ion-color-primary);
|
||||
--padding-start: 10px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user