mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
Fix updates badge and rework updates page (#2205)
* fix updates badge and rework updates page * resize icons * better language around browser tab title * no period * updates tab more fixes
This commit is contained in:
@@ -88,9 +88,9 @@
|
||||
<b>
|
||||
<span *ngIf="not['package-id'] as pkgId">
|
||||
<!-- @TODO remove $any when Angular gets smart enough -->
|
||||
{{ $any(packageData[pkgId])?.manifest?.title || pkgId }} -
|
||||
{{ $any(packageData[pkgId])?.manifest.title || pkgId }} -
|
||||
</span>
|
||||
<ion-text [color]="getColor(not)"> {{ not.title }} </ion-text>
|
||||
<ion-text [color]="getColor(not)">{{ not.title }}</ion-text>
|
||||
</b>
|
||||
</h2>
|
||||
<h2 class="notification-message">{{ truncate(not.message) }}</h2>
|
||||
|
||||
@@ -15,6 +15,7 @@ import { ErrorToastService } from '@start9labs/shared'
|
||||
import { BackupReportPage } from 'src/app/modals/backup-report/backup-report.page'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { first } from 'rxjs'
|
||||
|
||||
@Component({
|
||||
selector: 'notifications',
|
||||
@@ -28,7 +29,7 @@ export class NotificationsPage {
|
||||
needInfinite = false
|
||||
fromToast = !!this.route.snapshot.queryParamMap.get('toast')
|
||||
readonly perPage = 40
|
||||
readonly packageData$ = this.patch.watch$('package-data')
|
||||
readonly packageData$ = this.patch.watch$('package-data').pipe(first())
|
||||
|
||||
constructor(
|
||||
private readonly embassyApi: ApiService,
|
||||
|
||||
@@ -57,12 +57,12 @@ export class ServerShowPage {
|
||||
@Inject(DOCUMENT) private readonly document: Document,
|
||||
) {}
|
||||
|
||||
async presentModalName(): Promise<void> {
|
||||
async setBrowserTab(): Promise<void> {
|
||||
const chosenName = await firstValueFrom(this.patch.watch$('ui', 'name'))
|
||||
|
||||
const options: GenericInputOptions = {
|
||||
title: 'Set Device Name',
|
||||
message: 'This will be displayed in your browser tab',
|
||||
title: 'Browser Tab Title',
|
||||
message: `This value will be displayed as the title of your browser tab.`,
|
||||
label: 'Device Name',
|
||||
useMask: false,
|
||||
placeholder: 'embassyOS',
|
||||
@@ -391,9 +391,9 @@ export class ServerShowPage {
|
||||
},
|
||||
{
|
||||
title: 'Browser Tab Title',
|
||||
description: `Customize the display name of your browser tab. This does not affect your server's LAN address.`,
|
||||
description: `Customize the display name of your browser tab`,
|
||||
icon: 'pricetag-outline',
|
||||
action: () => this.presentModalName(),
|
||||
action: () => this.setBrowserTab(),
|
||||
detail: false,
|
||||
disabled$: of(false),
|
||||
},
|
||||
|
||||
@@ -9,16 +9,14 @@
|
||||
|
||||
<ion-content class="with-widgets">
|
||||
<ion-item-group *ngIf="data$ | async as data">
|
||||
<ng-container *ngFor="let host of data.hosts">
|
||||
<div class="header">
|
||||
<div class="header_items">
|
||||
<store-icon [url]="host.url" size="48px"></store-icon>
|
||||
<div class="header_title pl-1">
|
||||
<h1>{{ host.name }}</h1>
|
||||
<p>{{ host.url }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngFor="let host of data.hosts">
|
||||
<ion-item-divider class="inline">
|
||||
<store-icon [url]="host.url" size="26px"></store-icon>
|
||||
|
||||
<span style="padding-left: 8px; letter-spacing: 0.7px; font-size: 20px">
|
||||
{{ host.name }}
|
||||
</span>
|
||||
</ion-item-divider>
|
||||
|
||||
<ion-item *ngIf="data.errors.includes(host.url)">
|
||||
<ion-text color="danger">Request Failed</ion-text>
|
||||
@@ -30,92 +28,79 @@
|
||||
<ng-container
|
||||
*ngIf="packages | filterUpdates : data.localPkgs as updates"
|
||||
>
|
||||
<ion-grid>
|
||||
<div *ngFor="let pkg of updates">
|
||||
<ng-container *ngIf="data.localPkgs[pkg.manifest.id] as local">
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-accordion-group class="accordian-padding">
|
||||
<ion-accordion class="item-container">
|
||||
<ion-item slot="header">
|
||||
<ion-col class="accordian-padding">
|
||||
<ion-row
|
||||
(click)="viewInMarketplace($event, local)"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
<ion-thumbnail class="align-center">
|
||||
<img
|
||||
[src]="'data:image/png;base64,' + pkg.icon | trustUrl"
|
||||
/>
|
||||
</ion-thumbnail>
|
||||
<ion-label class="pl-1">
|
||||
<h2>{{ pkg.manifest.title }}</h2>
|
||||
<h3 class="inline">
|
||||
<span>
|
||||
{{ local.manifest.version | displayEmver }}
|
||||
</span>
|
||||
|
||||
<ion-icon name="arrow-forward"></ion-icon>
|
||||
|
||||
<ion-text color="success">
|
||||
{{ pkg.manifest.version | displayEmver }}
|
||||
</ion-text>
|
||||
</h3>
|
||||
<p
|
||||
*ngIf="marketplaceService.updateErrors[pkg.manifest.id] as error"
|
||||
>
|
||||
<ion-text color="danger">
|
||||
{{ error }}
|
||||
</ion-text>
|
||||
</p>
|
||||
</ion-label>
|
||||
</ion-row>
|
||||
</ion-col>
|
||||
<div class="align-center">
|
||||
<round-progress
|
||||
*ngIf="local.state === PackageState.Updating else notUpdating"
|
||||
[current]="local['install-progress'] | installProgress"
|
||||
[max]="100"
|
||||
[radius]="13"
|
||||
[stroke]="3"
|
||||
[rounded]="true"
|
||||
color="var(--ion-color-primary)"
|
||||
></round-progress>
|
||||
<ng-template #notUpdating>
|
||||
<ion-spinner
|
||||
*ngIf="marketplaceService.updateQueue[pkg.manifest.id] else updateBtn"
|
||||
color="dark"
|
||||
></ion-spinner>
|
||||
<ng-template #updateBtn>
|
||||
<ion-button
|
||||
(click)="tryUpdate(pkg.manifest, host.url, local)"
|
||||
[color]="marketplaceService.updateErrors[pkg.manifest.id] ? 'danger' : 'tertiary'"
|
||||
strong
|
||||
size="default"
|
||||
>
|
||||
{{
|
||||
marketplaceService.updateErrors[pkg.manifest.id]
|
||||
? 'Retry' : 'Update' }}
|
||||
</ion-button>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</div>
|
||||
</ion-item>
|
||||
<div class="ion-padding" slot="content">
|
||||
<div class="notes">
|
||||
<h4>What's new</h4>
|
||||
<p
|
||||
[innerHTML]="pkg.manifest['release-notes'] | markdown"
|
||||
></p>
|
||||
</div>
|
||||
</div>
|
||||
</ion-accordion>
|
||||
</ion-accordion-group>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ng-container>
|
||||
<ion-accordion-group multiple="true" class="ion-padding-start">
|
||||
<div *ngFor="let pkg of updates" class="item-container">
|
||||
<ion-accordion *ngIf="data.localPkgs[pkg.manifest.id] as local">
|
||||
<ion-item lines="none" slot="header">
|
||||
<ion-avatar slot="start" style="width: 50px; height: 50px">
|
||||
<img
|
||||
[src]="'data:image/png;base64,' + pkg.icon | trustUrl"
|
||||
/>
|
||||
</ion-avatar>
|
||||
<ion-label>
|
||||
<h1 style="line-height: 1.3">{{ pkg.manifest.title }}</h1>
|
||||
<h2 class="inline">
|
||||
<span>{{ local.manifest.version | displayEmver }}</span>
|
||||
|
||||
<ion-icon name="arrow-forward"></ion-icon>
|
||||
|
||||
<ion-text color="success">
|
||||
{{ pkg.manifest.version | displayEmver }}
|
||||
</ion-text>
|
||||
</h2>
|
||||
<p
|
||||
*ngIf="marketplaceService.updateErrors[pkg.manifest.id] as error"
|
||||
>
|
||||
<ion-text color="danger">{{ error }}</ion-text>
|
||||
</p>
|
||||
</ion-label>
|
||||
<div slot="end" style="margin-left: 4px">
|
||||
<round-progress
|
||||
*ngIf="local.state === 'updating' else notUpdating"
|
||||
[current]="local['install-progress'] | installProgress"
|
||||
[max]="100"
|
||||
[radius]="13"
|
||||
[stroke]="3"
|
||||
[rounded]="true"
|
||||
color="var(--ion-color-primary)"
|
||||
></round-progress>
|
||||
<ng-template #notUpdating>
|
||||
<ion-spinner
|
||||
*ngIf="marketplaceService.updateQueue[pkg.manifest.id] else updateBtn"
|
||||
color="dark"
|
||||
></ion-spinner>
|
||||
<ng-template #updateBtn>
|
||||
<ion-button
|
||||
(click)="tryUpdate(pkg.manifest, host.url, local, $event)"
|
||||
[color]="marketplaceService.updateErrors[pkg.manifest.id] ? 'danger' : 'tertiary'"
|
||||
strong
|
||||
>
|
||||
{{ marketplaceService.updateErrors[pkg.manifest.id] ?
|
||||
'Retry' : 'Update' }}
|
||||
</ion-button>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</div>
|
||||
</ion-item>
|
||||
<div class="ion-padding" slot="content">
|
||||
<div class="notes">
|
||||
<h5>What's new</h5>
|
||||
<p
|
||||
[innerHTML]="pkg.manifest['release-notes'] | markdown"
|
||||
></p>
|
||||
</div>
|
||||
<ion-button
|
||||
fill="clear"
|
||||
strong
|
||||
(click)="viewInMarketplace($event, local)"
|
||||
>
|
||||
View listing
|
||||
<ion-icon slot="end" name="open-outline"></ion-icon>
|
||||
</ion-button>
|
||||
</div>
|
||||
</ion-accordion>
|
||||
</div>
|
||||
</ion-grid>
|
||||
</ion-accordion-group>
|
||||
<ion-item
|
||||
*ngIf="!updates.length"
|
||||
class="ion-text-center ion-padding"
|
||||
@@ -127,8 +112,10 @@
|
||||
</ng-container>
|
||||
|
||||
<ng-template #loading>
|
||||
<skeleton-list [showAvatar]="true" [rows]="2"></skeleton-list>
|
||||
<div class="ion-padding">
|
||||
<skeleton-list [showAvatar]="true" [rows]="2"></skeleton-list>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ion-item-group>
|
||||
</ion-content>
|
||||
|
||||
@@ -1,77 +1,26 @@
|
||||
.item-container {
|
||||
padding-bottom: 24px;
|
||||
border-bottom: 1px solid #373737;
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.notes {
|
||||
margin-left: 20px;
|
||||
|
||||
h4 {
|
||||
font-size: 1rem;
|
||||
h5 {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 1.5rem;
|
||||
background: var(--ion-color-medium-tint);
|
||||
|
||||
&_items {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
height: 85%;
|
||||
width: 85%;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.pl-1 {
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1rem;
|
||||
margin-top: 0;
|
||||
ion-item-divider {
|
||||
--padding-top: 8px;
|
||||
--padding-bottom: 8px;
|
||||
--background: var(--ion-color-medium-tint);
|
||||
}
|
||||
|
||||
ion-item {
|
||||
--background-hover: none;
|
||||
}
|
||||
|
||||
ion-label {
|
||||
h2 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.accordian-padding {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.accordian-padding {
|
||||
padding: 0.5rem 0 0.5rem 0;
|
||||
|
||||
&::part(native) {
|
||||
cursor: context-menu;
|
||||
}
|
||||
}
|
||||
@@ -46,8 +46,6 @@ export class UpdatesPage {
|
||||
errors: this.marketplaceService.getRequestErrors$(),
|
||||
})
|
||||
|
||||
readonly PackageState = PackageState
|
||||
|
||||
constructor(
|
||||
@Inject(AbstractMarketplaceService)
|
||||
readonly marketplaceService: MarketplaceService,
|
||||
@@ -72,7 +70,10 @@ export class UpdatesPage {
|
||||
manifest: MarketplaceManifest,
|
||||
url: string,
|
||||
local: PackageDataEntry,
|
||||
e: Event,
|
||||
): Promise<void> {
|
||||
e.stopPropagation()
|
||||
|
||||
const { id, version } = manifest
|
||||
|
||||
delete this.marketplaceService.updateErrors[id]
|
||||
|
||||
Reference in New Issue
Block a user