fix preview versions, icons, and misc styling

This commit is contained in:
Lucy Cifferello
2024-04-02 21:16:14 -04:00
parent 74ba68ff2c
commit 9c4c211233
8 changed files with 140 additions and 86 deletions

View File

@@ -1,16 +1,13 @@
<div class="item-container box-shadow-lg">
<!-- color background -->
<div class="background">
<img
[src]="pkg.icon| trustUrl"
alt="{{ pkg.manifest.title }} Icon"
/>
<img [src]="pkg.icon" alt="{{ pkg.manifest.title }} Icon" />
</div>
<!-- darkening overlay -->
<div class="overlay"></div>
<!-- icon -->
<img
[src]="pkg.icon | trustUrl"
[src]="pkg.icon"
class="icon box-shadow-lg"
alt="{{ pkg.manifest.title }} Icon"
/>

View File

@@ -369,7 +369,7 @@ a {
}
.buttons {
margin-top: 0.5rem;
margin-top: 1rem;
:first-child {
margin-right: 0.5rem;

View File

@@ -34,6 +34,8 @@ import { MARKETPLACE_REGISTRY } from '../modals/registry.component'
padding: 1.25rem;
font-size: 1rem;
line-height: 1.5rem;
background-color: transparent;
background-image: none;
}
`,
],

View File

@@ -15,7 +15,6 @@ import { MarketplaceSidebarService } from '../services/sidebar.service'
position: fixed;
inset: 3.5rem 0 0;
pointer-events: none;
transform: translate3d(0, 0, 0);
}
`,
],

View File

@@ -2,8 +2,8 @@ import { CommonModule } from '@angular/common'
import {
ChangeDetectionStrategy,
Component,
Input,
inject,
Input,
} from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { ItemModule, MarketplacePkg } from '@start9labs/marketplace'
@@ -30,9 +30,8 @@ import { MarketplaceSidebarService } from '../services/sidebar.service'
direction: 'right';
autoWidth: true
"
[pkgId]="pkg.manifest.id"
class="preview-wrapper"
[pkg]="pkg"
(tuiActiveZoneChange)="toggle($event)"
>
<button
tuiAutoFocus
@@ -88,6 +87,7 @@ import { MarketplaceSidebarService } from '../services/sidebar.service'
display: flex;
justify-content: flex-start;
gap: 0.5rem;
height: 4.5rem;
}
`,
],
@@ -113,7 +113,6 @@ import { MarketplaceSidebarService } from '../services/sidebar.service'
})
export class MarketplaceTileComponent {
private readonly router = inject(Router)
readonly id$ = inject(ActivatedRoute).queryParamMap.pipe(
map(map => map.get('id') || ''),
debounceTime(100),

View File

@@ -2,10 +2,8 @@ import { CommonModule } from '@angular/common'
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
inject,
Input,
Output,
TemplateRef,
} from '@angular/core'
import {
@@ -17,11 +15,16 @@ import {
MarketplacePackageHeroComponent,
MarketplacePkg,
ReleaseNotesModule,
StoreIdentity,
} from '@start9labs/marketplace'
import { displayEmver, Emver, SharedPipesModule } from '@start9labs/shared'
import { TuiButtonModule } from '@taiga-ui/experimental'
import { filter, map } from 'rxjs'
import { TuiDialogContext, TuiDialogService } from '@taiga-ui/core'
import { BehaviorSubject, filter, switchMap, tap } from 'rxjs'
import {
TuiDialogContext,
TuiDialogService,
TuiLoaderModule,
} from '@taiga-ui/core'
import {
TuiRadioListModule,
TuiStringifyContentPipeModule,
@@ -34,63 +37,73 @@ import { Router } from '@angular/router'
template: `
<div class="outer-container">
<ng-content select="[slot=close]" />
<marketplace-package-hero [pkg]="pkg">
<ng-content select="[slot=controls]" />
</marketplace-package-hero>
@if (url$ | async; as url) {
<a
[href]="url + '/marketplace/' + pkg.manifest.id"
tuiButton
appearance="tertiary-solid"
iconRight="tuiIconExternalLink"
target="_blank"
>
View more details
</a>
}
<div class="inner-container">
<marketplace-about [pkg]="pkg" />
@if (!(pkg.manifest.dependencies | empty)) {
<marketplace-dependencies
[pkg]="pkg"
(open)="open($event)"
></marketplace-dependencies>
@if (pkg$ | async; as pkg) {
@if (loading) {
<tui-loader class="loading-dots" textContent="Loading" />
} @else {
<marketplace-package-hero [pkg]="pkg">
<ng-content select="[slot=controls]" />
</marketplace-package-hero>
@if (hostInfo$ | async; as info) {
<a
[href]="constructDetailLink(info, pkg.manifest.id)"
tuiButton
appearance="tertiary-solid"
iconRight="tuiIconExternalLink"
target="_blank"
>
View more details
</a>
}
<div class="inner-container">
<marketplace-about [pkg]="pkg" />
@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>
`,
styles: [
@@ -101,9 +114,9 @@ import { Router } from '@angular/router'
.outer-container {
display: grid;
justify-content: center;
gap: 2rem;
padding: 1.75rem;
min-width: 30rem;
}
.inner-container {
@@ -115,6 +128,18 @@ import { Router } from '@angular/router'
.additional-wrapper {
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,
@@ -132,20 +157,32 @@ import { Router } from '@angular/router'
TuiStringifyContentPipeModule,
MarketplaceAdditionalItemComponent,
TuiRadioListModule,
TuiLoaderModule,
],
})
export class MarketplacePreviewComponent {
@Input({ required: true })
pkg!: MarketplacePkg
pkgId!: string
@Output()
version = new EventEmitter<string>()
loading = true
readonly displayEmver = displayEmver
private readonly router = inject(Router)
readonly url$ = inject(AbstractMarketplaceService)
.getSelectedHost$()
.pipe(map(({ url }) => url))
private readonly marketplaceService = inject(AbstractMarketplaceService)
readonly 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(
private readonly dialogs: TuiDialogService,
@@ -156,19 +193,27 @@ export class MarketplacePreviewComponent {
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
.open<string>(version, {
label: 'Versions',
size: 's',
data: {
value: this.pkg.manifest.version,
items: [...new Set(this.pkg.versions)].sort(
value: pkg.manifest.version,
items: [...new Set(pkg.versions)].sort(
(a, b) => -1 * (this.emver.compare(a, b) || 0),
),
},
})
.pipe(filter(Boolean))
.subscribe(version => this.version.emit(version))
.subscribe(version => this.loadVersion$.next(version))
}
}

View File

@@ -9,12 +9,15 @@ import {
RR,
ServerNotifications,
} from './api.types'
import { BTC_ICON, LND_ICON, PROXY_ICON } from './api-icons'
import { DependencyMetadata, MarketplacePkg } from '@start9labs/marketplace'
import { Log } from '@start9labs/shared'
import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec'
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 const ServerUpdated: ServerStatusInfo = {
currentBackup: null,
@@ -319,8 +322,13 @@ export module Mock {
},
}
export const MarketplacePkgsList: RR.GetMarketplacePackagesRes =
Object.values(Mock.MarketplacePkgs).map(service => service['latest'])
export const marketplacePkgsList = (
version?: string,
): RR.GetMarketplacePackagesRes => {
return Object.values(Mock.MarketplacePkgs).map(service =>
version ? service[version] : service['latest'],
)
}
export const Notifications: ServerNotifications = [
{

View File

@@ -462,7 +462,11 @@ export class MockApiService extends ApiService {
}
return info
} 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')) {
return Mock.ReleaseNotes
} else if (path.includes('instructions') || path.includes('license')) {