mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
fix preview versions, icons, and misc styling
This commit is contained in:
@@ -1,16 +1,13 @@
|
|||||||
<div class="item-container box-shadow-lg">
|
<div class="item-container box-shadow-lg">
|
||||||
<!-- color background -->
|
<!-- color background -->
|
||||||
<div class="background">
|
<div class="background">
|
||||||
<img
|
<img [src]="pkg.icon" alt="{{ pkg.manifest.title }} Icon" />
|
||||||
[src]="pkg.icon| trustUrl"
|
|
||||||
alt="{{ pkg.manifest.title }} Icon"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- darkening overlay -->
|
<!-- darkening overlay -->
|
||||||
<div class="overlay"></div>
|
<div class="overlay"></div>
|
||||||
<!-- icon -->
|
<!-- icon -->
|
||||||
<img
|
<img
|
||||||
[src]="pkg.icon | trustUrl"
|
[src]="pkg.icon"
|
||||||
class="icon box-shadow-lg"
|
class="icon box-shadow-lg"
|
||||||
alt="{{ pkg.manifest.title }} Icon"
|
alt="{{ pkg.manifest.title }} Icon"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
margin-top: 0.5rem;
|
margin-top: 1rem;
|
||||||
|
|
||||||
:first-child {
|
:first-child {
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ import { MARKETPLACE_REGISTRY } from '../modals/registry.component'
|
|||||||
padding: 1.25rem;
|
padding: 1.25rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1.5rem;
|
line-height: 1.5rem;
|
||||||
|
background-color: transparent;
|
||||||
|
background-image: none;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import { MarketplaceSidebarService } from '../services/sidebar.service'
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 3.5rem 0 0;
|
inset: 3.5rem 0 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import { CommonModule } from '@angular/common'
|
|||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
Input,
|
|
||||||
inject,
|
inject,
|
||||||
|
Input,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import { ActivatedRoute, Router } from '@angular/router'
|
import { ActivatedRoute, Router } from '@angular/router'
|
||||||
import { ItemModule, MarketplacePkg } from '@start9labs/marketplace'
|
import { ItemModule, MarketplacePkg } from '@start9labs/marketplace'
|
||||||
@@ -30,9 +30,8 @@ import { MarketplaceSidebarService } from '../services/sidebar.service'
|
|||||||
direction: 'right';
|
direction: 'right';
|
||||||
autoWidth: true
|
autoWidth: true
|
||||||
"
|
"
|
||||||
|
[pkgId]="pkg.manifest.id"
|
||||||
class="preview-wrapper"
|
class="preview-wrapper"
|
||||||
[pkg]="pkg"
|
|
||||||
(tuiActiveZoneChange)="toggle($event)"
|
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
tuiAutoFocus
|
tuiAutoFocus
|
||||||
@@ -88,6 +87,7 @@ import { MarketplaceSidebarService } from '../services/sidebar.service'
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
height: 4.5rem;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
],
|
],
|
||||||
@@ -113,7 +113,6 @@ import { MarketplaceSidebarService } from '../services/sidebar.service'
|
|||||||
})
|
})
|
||||||
export class MarketplaceTileComponent {
|
export class MarketplaceTileComponent {
|
||||||
private readonly router = inject(Router)
|
private readonly router = inject(Router)
|
||||||
|
|
||||||
readonly id$ = inject(ActivatedRoute).queryParamMap.pipe(
|
readonly id$ = inject(ActivatedRoute).queryParamMap.pipe(
|
||||||
map(map => map.get('id') || ''),
|
map(map => map.get('id') || ''),
|
||||||
debounceTime(100),
|
debounceTime(100),
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ import { CommonModule } from '@angular/common'
|
|||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
EventEmitter,
|
|
||||||
inject,
|
inject,
|
||||||
Input,
|
Input,
|
||||||
Output,
|
|
||||||
TemplateRef,
|
TemplateRef,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import {
|
import {
|
||||||
@@ -17,11 +15,16 @@ import {
|
|||||||
MarketplacePackageHeroComponent,
|
MarketplacePackageHeroComponent,
|
||||||
MarketplacePkg,
|
MarketplacePkg,
|
||||||
ReleaseNotesModule,
|
ReleaseNotesModule,
|
||||||
|
StoreIdentity,
|
||||||
} from '@start9labs/marketplace'
|
} from '@start9labs/marketplace'
|
||||||
import { displayEmver, Emver, SharedPipesModule } from '@start9labs/shared'
|
import { displayEmver, Emver, SharedPipesModule } from '@start9labs/shared'
|
||||||
import { TuiButtonModule } from '@taiga-ui/experimental'
|
import { TuiButtonModule } from '@taiga-ui/experimental'
|
||||||
import { filter, map } from 'rxjs'
|
import { BehaviorSubject, filter, switchMap, tap } from 'rxjs'
|
||||||
import { TuiDialogContext, TuiDialogService } from '@taiga-ui/core'
|
import {
|
||||||
|
TuiDialogContext,
|
||||||
|
TuiDialogService,
|
||||||
|
TuiLoaderModule,
|
||||||
|
} from '@taiga-ui/core'
|
||||||
import {
|
import {
|
||||||
TuiRadioListModule,
|
TuiRadioListModule,
|
||||||
TuiStringifyContentPipeModule,
|
TuiStringifyContentPipeModule,
|
||||||
@@ -34,63 +37,73 @@ import { Router } from '@angular/router'
|
|||||||
template: `
|
template: `
|
||||||
<div class="outer-container">
|
<div class="outer-container">
|
||||||
<ng-content select="[slot=close]" />
|
<ng-content select="[slot=close]" />
|
||||||
<marketplace-package-hero [pkg]="pkg">
|
@if (pkg$ | async; as pkg) {
|
||||||
<ng-content select="[slot=controls]" />
|
@if (loading) {
|
||||||
</marketplace-package-hero>
|
<tui-loader class="loading-dots" textContent="Loading" />
|
||||||
@if (url$ | async; as url) {
|
} @else {
|
||||||
<a
|
<marketplace-package-hero [pkg]="pkg">
|
||||||
[href]="url + '/marketplace/' + pkg.manifest.id"
|
<ng-content select="[slot=controls]" />
|
||||||
tuiButton
|
</marketplace-package-hero>
|
||||||
appearance="tertiary-solid"
|
@if (hostInfo$ | async; as info) {
|
||||||
iconRight="tuiIconExternalLink"
|
<a
|
||||||
target="_blank"
|
[href]="constructDetailLink(info, pkg.manifest.id)"
|
||||||
>
|
tuiButton
|
||||||
View more details
|
appearance="tertiary-solid"
|
||||||
</a>
|
iconRight="tuiIconExternalLink"
|
||||||
}
|
target="_blank"
|
||||||
<div class="inner-container">
|
>
|
||||||
<marketplace-about [pkg]="pkg" />
|
View more details
|
||||||
@if (!(pkg.manifest.dependencies | empty)) {
|
</a>
|
||||||
<marketplace-dependencies
|
}
|
||||||
[pkg]="pkg"
|
<div class="inner-container">
|
||||||
(open)="open($event)"
|
<marketplace-about [pkg]="pkg" />
|
||||||
></marketplace-dependencies>
|
@if (!(pkg.manifest.dependencies | empty)) {
|
||||||
|
<marketplace-dependencies
|
||||||
|
[pkg]="pkg"
|
||||||
|
(open)="open($event)"
|
||||||
|
></marketplace-dependencies>
|
||||||
|
}
|
||||||
|
<release-notes [pkg]="pkg" />
|
||||||
|
<marketplace-additional class="additional-wrapper" [pkg]="pkg">
|
||||||
|
<marketplace-additional-item
|
||||||
|
(click)="presentAlertVersions(pkg, version)"
|
||||||
|
data="Click to view all versions"
|
||||||
|
label="All versions"
|
||||||
|
icon="tuiIconChevronRightLarge"
|
||||||
|
class="versions"
|
||||||
|
></marketplace-additional-item>
|
||||||
|
<ng-template
|
||||||
|
#version
|
||||||
|
let-data="data"
|
||||||
|
let-completeWith="completeWith"
|
||||||
|
>
|
||||||
|
<tui-radio-list
|
||||||
|
size="l"
|
||||||
|
[items]="data.items"
|
||||||
|
[itemContent]="displayEmver | tuiStringifyContent"
|
||||||
|
[(ngModel)]="data.value"
|
||||||
|
></tui-radio-list>
|
||||||
|
<footer class="buttons">
|
||||||
|
<button
|
||||||
|
tuiButton
|
||||||
|
appearance="secondary"
|
||||||
|
(click)="completeWith(null)"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
tuiButton
|
||||||
|
appearance="secondary"
|
||||||
|
(click)="loading = true; completeWith(data.value)"
|
||||||
|
>
|
||||||
|
Ok
|
||||||
|
</button>
|
||||||
|
</footer>
|
||||||
|
</ng-template>
|
||||||
|
</marketplace-additional>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
<release-notes [pkg]="pkg" />
|
}
|
||||||
<marketplace-additional class="additional-wrapper" [pkg]="pkg">
|
|
||||||
<marketplace-additional-item
|
|
||||||
(click)="presentAlertVersions(version)"
|
|
||||||
data="Click to view all versions"
|
|
||||||
label="All versions"
|
|
||||||
icon="tuiIconChevronRightLarge"
|
|
||||||
class="item-pointer"
|
|
||||||
></marketplace-additional-item>
|
|
||||||
<ng-template #version let-data="data" let-completeWith="completeWith">
|
|
||||||
<tui-radio-list
|
|
||||||
size="l"
|
|
||||||
[items]="data.items"
|
|
||||||
[itemContent]="displayEmver | tuiStringifyContent"
|
|
||||||
[(ngModel)]="data.value"
|
|
||||||
></tui-radio-list>
|
|
||||||
<footer class="buttons">
|
|
||||||
<button
|
|
||||||
tuiButton
|
|
||||||
appearance="secondary"
|
|
||||||
(click)="completeWith(null)"
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
tuiButton
|
|
||||||
appearance="secondary"
|
|
||||||
(click)="completeWith(data.value)"
|
|
||||||
>
|
|
||||||
Ok
|
|
||||||
</button>
|
|
||||||
</footer>
|
|
||||||
</ng-template>
|
|
||||||
</marketplace-additional>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
styles: [
|
styles: [
|
||||||
@@ -101,9 +114,9 @@ import { Router } from '@angular/router'
|
|||||||
|
|
||||||
.outer-container {
|
.outer-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
justify-content: center;
|
|
||||||
gap: 2rem;
|
gap: 2rem;
|
||||||
padding: 1.75rem;
|
padding: 1.75rem;
|
||||||
|
min-width: 30rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inner-container {
|
.inner-container {
|
||||||
@@ -115,6 +128,18 @@ import { Router } from '@angular/router'
|
|||||||
.additional-wrapper {
|
.additional-wrapper {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.versions {
|
||||||
|
border: 0;
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-color: rgb(113 113 122);
|
||||||
|
border-style: solid;
|
||||||
|
cursor: pointer;
|
||||||
|
::ng-deep label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
],
|
],
|
||||||
standalone: true,
|
standalone: true,
|
||||||
@@ -132,20 +157,32 @@ import { Router } from '@angular/router'
|
|||||||
TuiStringifyContentPipeModule,
|
TuiStringifyContentPipeModule,
|
||||||
MarketplaceAdditionalItemComponent,
|
MarketplaceAdditionalItemComponent,
|
||||||
TuiRadioListModule,
|
TuiRadioListModule,
|
||||||
|
TuiLoaderModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class MarketplacePreviewComponent {
|
export class MarketplacePreviewComponent {
|
||||||
@Input({ required: true })
|
@Input({ required: true })
|
||||||
pkg!: MarketplacePkg
|
pkgId!: string
|
||||||
|
|
||||||
@Output()
|
loading = true
|
||||||
version = new EventEmitter<string>()
|
|
||||||
|
|
||||||
readonly displayEmver = displayEmver
|
readonly displayEmver = displayEmver
|
||||||
private readonly router = inject(Router)
|
private readonly router = inject(Router)
|
||||||
readonly url$ = inject(AbstractMarketplaceService)
|
private readonly marketplaceService = inject(AbstractMarketplaceService)
|
||||||
.getSelectedHost$()
|
readonly url =
|
||||||
.pipe(map(({ url }) => url))
|
this.router.routerState.snapshot.root.queryParamMap.get('url') || undefined
|
||||||
|
|
||||||
|
readonly loadVersion$ = new BehaviorSubject<string>('*')
|
||||||
|
readonly hostInfo$ = this.marketplaceService.getSelectedHost$()
|
||||||
|
readonly pkg$ = this.loadVersion$.pipe(
|
||||||
|
switchMap(version =>
|
||||||
|
this.marketplaceService.getPackage$(this.pkgId, version, this.url),
|
||||||
|
),
|
||||||
|
tap(data => {
|
||||||
|
this.loading = false
|
||||||
|
return data
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly dialogs: TuiDialogService,
|
private readonly dialogs: TuiDialogService,
|
||||||
@@ -156,19 +193,27 @@ export class MarketplacePreviewComponent {
|
|||||||
this.router.navigate([], { queryParams: { id } })
|
this.router.navigate([], { queryParams: { id } })
|
||||||
}
|
}
|
||||||
|
|
||||||
presentAlertVersions(version: TemplateRef<TuiDialogContext>) {
|
constructDetailLink(info: StoreIdentity, id: string) {
|
||||||
|
const domain = new URL(info.url).hostname
|
||||||
|
return `https://marketplace.start9.com/${id}?api=${domain}&name=${info.name}`
|
||||||
|
}
|
||||||
|
|
||||||
|
presentAlertVersions(
|
||||||
|
pkg: MarketplacePkg,
|
||||||
|
version: TemplateRef<TuiDialogContext>,
|
||||||
|
) {
|
||||||
this.dialogs
|
this.dialogs
|
||||||
.open<string>(version, {
|
.open<string>(version, {
|
||||||
label: 'Versions',
|
label: 'Versions',
|
||||||
size: 's',
|
size: 's',
|
||||||
data: {
|
data: {
|
||||||
value: this.pkg.manifest.version,
|
value: pkg.manifest.version,
|
||||||
items: [...new Set(this.pkg.versions)].sort(
|
items: [...new Set(pkg.versions)].sort(
|
||||||
(a, b) => -1 * (this.emver.compare(a, b) || 0),
|
(a, b) => -1 * (this.emver.compare(a, b) || 0),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.pipe(filter(Boolean))
|
.pipe(filter(Boolean))
|
||||||
.subscribe(version => this.version.emit(version))
|
.subscribe(version => this.loadVersion$.next(version))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,15 @@ import {
|
|||||||
RR,
|
RR,
|
||||||
ServerNotifications,
|
ServerNotifications,
|
||||||
} from './api.types'
|
} from './api.types'
|
||||||
import { BTC_ICON, LND_ICON, PROXY_ICON } from './api-icons'
|
|
||||||
import { DependencyMetadata, MarketplacePkg } from '@start9labs/marketplace'
|
import { DependencyMetadata, MarketplacePkg } from '@start9labs/marketplace'
|
||||||
import { Log } from '@start9labs/shared'
|
import { Log } from '@start9labs/shared'
|
||||||
import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec'
|
import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec'
|
||||||
import { CT, T, CB } from '@start9labs/start-sdk'
|
import { CT, T, CB } from '@start9labs/start-sdk'
|
||||||
|
|
||||||
|
const BTC_ICON = '/assets/img/service-icons/bitcoind.svg'
|
||||||
|
const LND_ICON = '/assets/img/service-icons/lnd.png'
|
||||||
|
const PROXY_ICON = '/assets/img/service-icons/btc-rpc-proxy.png'
|
||||||
|
|
||||||
export module Mock {
|
export module Mock {
|
||||||
export const ServerUpdated: ServerStatusInfo = {
|
export const ServerUpdated: ServerStatusInfo = {
|
||||||
currentBackup: null,
|
currentBackup: null,
|
||||||
@@ -319,8 +322,13 @@ export module Mock {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MarketplacePkgsList: RR.GetMarketplacePackagesRes =
|
export const marketplacePkgsList = (
|
||||||
Object.values(Mock.MarketplacePkgs).map(service => service['latest'])
|
version?: string,
|
||||||
|
): RR.GetMarketplacePackagesRes => {
|
||||||
|
return Object.values(Mock.MarketplacePkgs).map(service =>
|
||||||
|
version ? service[version] : service['latest'],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export const Notifications: ServerNotifications = [
|
export const Notifications: ServerNotifications = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -462,7 +462,11 @@ export class MockApiService extends ApiService {
|
|||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
} else if (path === '/package/v0/index') {
|
} else if (path === '/package/v0/index') {
|
||||||
return Mock.MarketplacePkgsList
|
const version = params['ids']
|
||||||
|
? (JSON.parse(params['ids']) as { version: string; id: string }[])[0]
|
||||||
|
.version
|
||||||
|
: undefined
|
||||||
|
return Mock.marketplacePkgsList(version)
|
||||||
} else if (path.startsWith('/package/v0/release-notes')) {
|
} else if (path.startsWith('/package/v0/release-notes')) {
|
||||||
return Mock.ReleaseNotes
|
return Mock.ReleaseNotes
|
||||||
} else if (path.includes('instructions') || path.includes('license')) {
|
} else if (path.includes('instructions') || path.includes('license')) {
|
||||||
|
|||||||
Reference in New Issue
Block a user