mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
@@ -28,7 +28,7 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
<!-- license -->
|
<!-- license -->
|
||||||
<marketplace-additional-item
|
<marketplace-additional-item
|
||||||
(click)="static.emit('License')"
|
(click)="static.emit('license')"
|
||||||
[data]="pkg.license"
|
[data]="pkg.license"
|
||||||
label="License"
|
label="License"
|
||||||
icon="@tui.chevron-right"
|
icon="@tui.chevron-right"
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
/>
|
/>
|
||||||
<!-- instructions -->
|
<!-- instructions -->
|
||||||
<marketplace-additional-item
|
<marketplace-additional-item
|
||||||
(click)="static.emit('Instructions')"
|
(click)="static.emit('instructions')"
|
||||||
data="Click to view instructions"
|
data="Click to view instructions"
|
||||||
label="Instructions"
|
label="Instructions"
|
||||||
icon="@tui.chevron-right"
|
icon="@tui.chevron-right"
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export class AdditionalComponent {
|
|||||||
pkg!: MarketplacePkgBase
|
pkg!: MarketplacePkgBase
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
readonly static = new EventEmitter<'License' | 'Instructions'>()
|
readonly static = new EventEmitter<'license' | 'instructions'>()
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly copyService: CopyService,
|
readonly copyService: CopyService,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import { i18nPipe } from '../i18n/i18n.pipe'
|
|||||||
[style.margin]="'1rem auto'"
|
[style.margin]="'1rem auto'"
|
||||||
[attr.value]="progress.total"
|
[attr.value]="progress.total"
|
||||||
></progress>
|
></progress>
|
||||||
<p>{{ progress.message }}</p>
|
<p [innerHTML]="progress.message"></p>
|
||||||
</section>
|
</section>
|
||||||
<logs-window />
|
<logs-window />
|
||||||
`,
|
`,
|
||||||
|
|||||||
@@ -486,4 +486,5 @@ export const ENGLISH = {
|
|||||||
'Refresh the page. If refreshing the page does not work, you may need to quit and re-open your browser, then revisit this page.': 484,
|
'Refresh the page. If refreshing the page does not work, you may need to quit and re-open your browser, then revisit this page.': 484,
|
||||||
'StartOS UI': 485,
|
'StartOS UI': 485,
|
||||||
'WiFi': 486,
|
'WiFi': 486,
|
||||||
|
'Instructions': 487,
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@@ -487,4 +487,5 @@ export default {
|
|||||||
484: 'Laden Sie die Seite neu. Wenn das nicht funktioniert, beenden Sie Ihren Browser und öffnen Sie ihn erneut, um diese Seite erneut zu besuchen.',
|
484: 'Laden Sie die Seite neu. Wenn das nicht funktioniert, beenden Sie Ihren Browser und öffnen Sie ihn erneut, um diese Seite erneut zu besuchen.',
|
||||||
485: 'StartOS-Benutzeroberfläche',
|
485: 'StartOS-Benutzeroberfläche',
|
||||||
486: 'WiFi',
|
486: 'WiFi',
|
||||||
|
487: 'Anleitungen',
|
||||||
} satisfies i18n
|
} satisfies i18n
|
||||||
|
|||||||
@@ -487,4 +487,5 @@ export default {
|
|||||||
484: 'Odśwież stronę. Jeśli to nie pomoże, zamknij i ponownie otwórz przeglądarkę, a następnie wróć do tej strony.',
|
484: 'Odśwież stronę. Jeśli to nie pomoże, zamknij i ponownie otwórz przeglądarkę, a następnie wróć do tej strony.',
|
||||||
485: 'Interfejs StartOS',
|
485: 'Interfejs StartOS',
|
||||||
486: 'WiFi',
|
486: 'WiFi',
|
||||||
|
487: 'instrukcje',
|
||||||
} satisfies i18n
|
} satisfies i18n
|
||||||
|
|||||||
@@ -487,4 +487,5 @@ export default {
|
|||||||
484: 'Actualiza la página. Si actualizar no funciona, puede que necesites cerrar y volver a abrir tu navegador, y luego volver a esta página.',
|
484: 'Actualiza la página. Si actualizar no funciona, puede que necesites cerrar y volver a abrir tu navegador, y luego volver a esta página.',
|
||||||
485: 'Interfaz de StartOS',
|
485: 'Interfaz de StartOS',
|
||||||
486: 'WiFi',
|
486: 'WiFi',
|
||||||
|
487: 'Instrucciones',
|
||||||
} as any satisfies i18n
|
} as any satisfies i18n
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { filter } from 'rxjs'
|
|||||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||||
import { ConfigService } from 'src/app/services/config.service'
|
import { ConfigService } from 'src/app/services/config.service'
|
||||||
|
|
||||||
// @TODO Alex how to use i18nPipe in this component since not standalone?
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'diagnostic-home',
|
selector: 'diagnostic-home',
|
||||||
templateUrl: 'home.page.html',
|
templateUrl: 'home.page.html',
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
inject,
|
inject,
|
||||||
|
input,
|
||||||
Input,
|
Input,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import { Router } from '@angular/router'
|
import { Router } from '@angular/router'
|
||||||
@@ -29,6 +30,7 @@ import { getAllPackages, getManifest } from 'src/app/utils/get-package-data'
|
|||||||
import { dryUpdate } from 'src/app/utils/dry-update'
|
import { dryUpdate } from 'src/app/utils/dry-update'
|
||||||
import { MarketplaceAlertsService } from '../services/alerts.service'
|
import { MarketplaceAlertsService } from '../services/alerts.service'
|
||||||
import { ToManifestPipe } from 'src/app/routes/portal/pipes/to-manifest'
|
import { ToManifestPipe } from 'src/app/routes/portal/pipes/to-manifest'
|
||||||
|
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'marketplace-controls',
|
selector: 'marketplace-controls',
|
||||||
@@ -108,6 +110,7 @@ export class MarketplaceControlsComponent {
|
|||||||
private readonly exver = inject(Exver)
|
private readonly exver = inject(Exver)
|
||||||
private readonly router = inject(Router)
|
private readonly router = inject(Router)
|
||||||
private readonly marketplaceService = inject(MarketplaceService)
|
private readonly marketplaceService = inject(MarketplaceService)
|
||||||
|
private readonly api = inject(ApiService)
|
||||||
|
|
||||||
@Input({ required: true })
|
@Input({ required: true })
|
||||||
pkg!: MarketplacePkgBase
|
pkg!: MarketplacePkgBase
|
||||||
@@ -118,18 +121,25 @@ export class MarketplaceControlsComponent {
|
|||||||
@Input()
|
@Input()
|
||||||
localFlavor!: boolean
|
localFlavor!: boolean
|
||||||
|
|
||||||
async tryInstall() {
|
// only present if side loading
|
||||||
const currentUrl = await firstValueFrom(
|
@Input()
|
||||||
this.marketplaceService.getRegistryUrl$(),
|
file?: File
|
||||||
)
|
|
||||||
const originalUrl = this.localPkg?.registry || ''
|
|
||||||
if (!this.localPkg) {
|
|
||||||
if (await this.alerts.alertInstall(this.pkg)) this.install(currentUrl)
|
|
||||||
|
|
||||||
|
async tryInstall() {
|
||||||
|
const currentUrl = this.file
|
||||||
|
? null
|
||||||
|
: await firstValueFrom(this.marketplaceService.getRegistryUrl$())
|
||||||
|
const originalUrl = this.localPkg?.registry || ''
|
||||||
|
|
||||||
|
if (!this.localPkg) {
|
||||||
|
if (await this.alerts.alertInstall(this.pkg)) {
|
||||||
|
this.installOrUpload(currentUrl)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
currentUrl &&
|
||||||
!sameUrl(currentUrl, originalUrl) &&
|
!sameUrl(currentUrl, originalUrl) &&
|
||||||
!(await this.alerts.alertMarketplace(currentUrl, originalUrl))
|
!(await this.alerts.alertMarketplace(currentUrl, originalUrl))
|
||||||
) {
|
) {
|
||||||
@@ -144,7 +154,7 @@ export class MarketplaceControlsComponent {
|
|||||||
) {
|
) {
|
||||||
this.dryInstall(currentUrl)
|
this.dryInstall(currentUrl)
|
||||||
} else {
|
} else {
|
||||||
this.install(currentUrl)
|
this.installOrUpload(currentUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +162,7 @@ export class MarketplaceControlsComponent {
|
|||||||
this.router.navigate(['/portal/services', this.pkg.id])
|
this.router.navigate(['/portal/services', this.pkg.id])
|
||||||
}
|
}
|
||||||
|
|
||||||
private async dryInstall(url: string) {
|
private async dryInstall(url: string | null) {
|
||||||
const breakages = dryUpdate(
|
const breakages = dryUpdate(
|
||||||
this.pkg,
|
this.pkg,
|
||||||
await getAllPackages(this.patch),
|
await getAllPackages(this.patch),
|
||||||
@@ -163,6 +173,14 @@ export class MarketplaceControlsComponent {
|
|||||||
isEmptyObject(breakages) ||
|
isEmptyObject(breakages) ||
|
||||||
(await this.alerts.alertBreakages(breakages))
|
(await this.alerts.alertBreakages(breakages))
|
||||||
) {
|
) {
|
||||||
|
this.installOrUpload(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async installOrUpload(url: string | null) {
|
||||||
|
if (this.file) {
|
||||||
|
await this.upload()
|
||||||
|
} else if (url) {
|
||||||
this.install(url)
|
this.install(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,4 +197,17 @@ export class MarketplaceControlsComponent {
|
|||||||
loader.unsubscribe()
|
loader.unsubscribe()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async upload() {
|
||||||
|
const loader = this.loader.open('Starting upload').subscribe()
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { upload } = await this.api.sideloadPackage()
|
||||||
|
this.api.uploadPackage(upload, this.file!).catch(console.error)
|
||||||
|
} catch (e: any) {
|
||||||
|
this.errorService.handleError(e)
|
||||||
|
} finally {
|
||||||
|
loader.unsubscribe()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ export class MarketplacePreviewComponent {
|
|||||||
this.router.navigate([], { queryParams: { id } })
|
this.router.navigate([], { queryParams: { id } })
|
||||||
}
|
}
|
||||||
|
|
||||||
onStatic(type: 'License' | 'Instructions') {
|
onStatic(type: 'license' | 'instructions') {
|
||||||
// @TODO Alex need to display License or Instructions. This requires an API request, check out next/minor
|
// @TODO Alex need to display License or Instructions. This requires an API request, check out next/minor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export interface AdditionalItem {
|
|||||||
target: '_blank',
|
target: '_blank',
|
||||||
'[class._disabled]': 'disabled',
|
'[class._disabled]': 'disabled',
|
||||||
'[attr.href]':
|
'[attr.href]':
|
||||||
'additionalItem.description.startsWith("http") ? additionalItem.description : null',
|
'additionalItem.value.startsWith("http") ? additionalItem.value : null',
|
||||||
},
|
},
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
standalone: true,
|
standalone: true,
|
||||||
|
|||||||
@@ -5,15 +5,13 @@ import {
|
|||||||
AdditionalModule,
|
AdditionalModule,
|
||||||
MarketplaceDependenciesComponent,
|
MarketplaceDependenciesComponent,
|
||||||
MarketplacePackageHeroComponent,
|
MarketplacePackageHeroComponent,
|
||||||
MarketplacePkgBase,
|
|
||||||
} from '@start9labs/marketplace'
|
} from '@start9labs/marketplace'
|
||||||
import {
|
import {
|
||||||
ErrorService,
|
DialogService,
|
||||||
Exver,
|
Exver,
|
||||||
LoadingService,
|
MARKDOWN,
|
||||||
SharedPipesModule,
|
SharedPipesModule,
|
||||||
} from '@start9labs/shared'
|
} from '@start9labs/shared'
|
||||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
|
||||||
import { MarketplaceControlsComponent } from '../marketplace/components/controls.component'
|
import { MarketplaceControlsComponent } from '../marketplace/components/controls.component'
|
||||||
import { filter, first, map } from 'rxjs'
|
import { filter, first, map } from 'rxjs'
|
||||||
import { PatchDB } from 'patch-db-client'
|
import { PatchDB } from 'patch-db-client'
|
||||||
@@ -33,6 +31,7 @@ import { MarketplacePkgSideload } from './sideload.utils'
|
|||||||
[pkg]="pkg"
|
[pkg]="pkg"
|
||||||
[localPkg]="local$ | async"
|
[localPkg]="local$ | async"
|
||||||
[localFlavor]="!!(flavor$ | async)"
|
[localFlavor]="!!(flavor$ | async)"
|
||||||
|
[file]="file"
|
||||||
/>
|
/>
|
||||||
</marketplace-package-hero>
|
</marketplace-package-hero>
|
||||||
<div class="package-details">
|
<div class="package-details">
|
||||||
@@ -105,11 +104,9 @@ import { MarketplacePkgSideload } from './sideload.utils'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class SideloadPackageComponent {
|
export class SideloadPackageComponent {
|
||||||
private readonly loader = inject(LoadingService)
|
|
||||||
private readonly api = inject(ApiService)
|
|
||||||
private readonly errorService = inject(ErrorService)
|
|
||||||
private readonly exver = inject(Exver)
|
private readonly exver = inject(Exver)
|
||||||
private readonly patch = inject<PatchDB<DataModel>>(PatchDB)
|
private readonly patch = inject<PatchDB<DataModel>>(PatchDB)
|
||||||
|
private readonly dialog = inject(DialogService)
|
||||||
|
|
||||||
// @Input({ required: true })
|
// @Input({ required: true })
|
||||||
// pkg!: MarketplacePkgSideload
|
// pkg!: MarketplacePkgSideload
|
||||||
@@ -133,20 +130,17 @@ export class SideloadPackageComponent {
|
|||||||
|
|
||||||
readonly flavor$ = this.local$.pipe(map(pkg => !pkg))
|
readonly flavor$ = this.local$.pipe(map(pkg => !pkg))
|
||||||
|
|
||||||
onStatic(type: 'License' | 'Instructions') {
|
// @TODO Alex, struggling to get this working. I don't understand how to use this markdown component, only one other example, and it's very different.
|
||||||
// @TODO Matt display License or Instructions
|
onStatic(type: 'license' | 'instructions') {
|
||||||
}
|
this.dialog
|
||||||
|
.openComponent(MARKDOWN, {
|
||||||
async upload() {
|
label: type === 'license' ? 'License' : 'Instructions',
|
||||||
const loader = this.loader.open('Starting upload').subscribe()
|
size: 'l',
|
||||||
|
data: {
|
||||||
try {
|
content:
|
||||||
const { upload } = await this.api.sideloadPackage()
|
this.pkg[type === 'license' ? 'fullLicense' : 'instructions'],
|
||||||
this.api.uploadPackage(upload, this.file).catch(console.error)
|
},
|
||||||
} catch (e: any) {
|
})
|
||||||
this.errorService.handleError(e)
|
.subscribe()
|
||||||
} finally {
|
|
||||||
loader.unsubscribe()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ async function parseS9pk(file: File): Promise<MarketplacePkgSideload> {
|
|||||||
icon: await s9pk.icon(),
|
icon: await s9pk.icon(),
|
||||||
sourceVersion: s9pk.manifest.canMigrateFrom,
|
sourceVersion: s9pk.manifest.canMigrateFrom,
|
||||||
flavor: ExtendedVersion.parse(s9pk.manifest.version).flavor,
|
flavor: ExtendedVersion.parse(s9pk.manifest.version).flavor,
|
||||||
license: await s9pk.license(),
|
fullLicense: await s9pk.license(),
|
||||||
instructions: await s9pk.instructions(),
|
instructions: await s9pk.instructions(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,6 +77,6 @@ function compare(a: Uint8Array, b: Uint8Array) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type MarketplacePkgSideload = MarketplacePkgBase & {
|
export type MarketplacePkgSideload = MarketplacePkgBase & {
|
||||||
license: string
|
|
||||||
instructions: string
|
instructions: string
|
||||||
|
fullLicense: string
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user