Update Marketplace (#2742)

* update abstract marketplace for usage accuracy andrename store to registry

* use new abstract functions

* fix(marketplace): get rid of `AbstractMarketplaceService`

* bump shared marketplace lib

* update marketplace to use query params for registry url; comment out updates page - will be refactored

* cleanup

* cleanup duplicate

* cleanup unused imports

* rework setting registry url when loading marketplace

* cleanup marketplace service

* fix background

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: waterplea <alexander@inkin.ru>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
This commit is contained in:
Lucy
2024-10-09 11:23:08 -06:00
committed by GitHub
parent a9569d0ed9
commit dfda2f7d5d
26 changed files with 688 additions and 807 deletions

View File

@@ -1,113 +1,108 @@
<header>
<ng-container *tuiLet="store$ | async as store">
<div class="title">
<store-icon
[class.tui-skeleton]="!store"
[class.tui-skeleton_rounded]="!store"
size="60px"
[url]="store?.url || ''"
[marketplace]="iconConfig"
/>
<h1 [class.tui-skeleton]="!store">
{{ store?.info?.name || 'Loading store...' }}
</h1>
<!-- change registry modal -->
<ng-content select="[slot=desktop]"></ng-content>
</div>
<!-- mobile nav -->
<div class="nav-mobile">
<div class="nav-mobile-bar">
<!-- mobile search -->
<marketplace-search
[(query)]="query"
(queryChange)="onQueryChange($event)"
/>
<button
tuiButton
type="button"
appearance="link"
(click)="toggleMenu(true)"
(tuiActiveZoneChange)="toggleMenu($event)"
[style.--tui-padding]="'1.2rem'"
>
<store-icon
size="42px"
[style.height]="'42px'"
[style.border-radius]="'100%'"
[url]="store?.url || ''"
[marketplace]="iconConfig"
[class.tui-skeleton]="!store"
[class.tui-skeleton_rounded]="!store"
/>
<nav
*tuiSidebar="open; direction: 'right'; autoWidth: true"
class="nav-mobile-sidebar divide-bar"
>
<div class="nav-mobile-sidebar-top">
<h1 [class.tui-skeleton]="!store">
{{ store?.info?.name }}
</h1>
<button
[style.--tui-padding]="0"
tuiButton
type="button"
appearance="icon"
iconStart="@tui.x"
(tuiActiveZoneChange)="toggleMenu($event)"
(click)="toggleMenu(false)"
></button>
</div>
<!-- change registry modal -->
<ng-content select="[slot=mobile]"></ng-content>
<div class="nav-mobile-sidebar-bottom divide-bar">
<marketplace-categories
[categories]="store?.info?.categories"
[category]="query ? '' : category"
(categoryChange)="onCategoryChange($event); toggleMenu(false)"
/>
<div>
<!-- link to store for brochure -->
<ng-content select="[slot=store-mobile]" />
<a
target="_blank"
rel="noreferrer"
href="https://docs.start9.com/0.3.5.x/developer-docs/"
>
<span>Package a service</span>
<tui-icon tuiAppearance="icon" icon="@tui.external-link" />
</a>
</div>
</div>
</nav>
</button>
</div>
</div>
<!-- desktop nav -->
<nav class="nav-desktop">
<!-- desktop search -->
<div class="title">
<store-icon
[class.tui-skeleton]="!registry"
[class.tui-skeleton_rounded]="!registry"
size="60px"
[url]="registry?.url || ''"
[marketplace]="iconConfig"
/>
<h1 [class.tui-skeleton]="!registry">
{{ registry?.info?.name || 'Unnamed Registry' }}
</h1>
<!-- change registry modal -->
<ng-content select="[slot=desktop]"></ng-content>
</div>
<!-- mobile nav -->
<div class="nav-mobile">
<div class="nav-mobile-bar">
<!-- mobile search -->
<marketplace-search
[query]="query"
[(query)]="query"
(queryChange)="onQueryChange($event)"
/>
<div class="nav-desktop-container">
<marketplace-categories
[categories]="store?.info?.categories"
[category]="query ? '' : category"
(categoryChange)="onCategoryChange($event)"
<button
tuiButton
type="button"
appearance="link"
(click)="toggleMenu(true)"
(tuiActiveZoneChange)="toggleMenu($event)"
[style.--tui-padding]="'1.2rem'"
>
<store-icon
size="42px"
[style.height]="'42px'"
[style.border-radius]="'100%'"
[url]="registry?.url || ''"
[marketplace]="iconConfig"
[class.tui-skeleton]="!registry"
[class.tui-skeleton_rounded]="!registry"
/>
<div>
<!-- link to store for brochure -->
<ng-content select="[slot=store]" />
<a
target="_blank"
rel="noreferrer"
href="https://docs.start9.com/0.3.5.x/developer-docs/"
>
<span>Package a service</span>
<tui-icon tuiAppearance="icon" icon="@tui.external-link" />
</a>
</div>
<nav
*tuiSidebar="open; direction: 'right'; autoWidth: true"
class="nav-mobile-sidebar divide-bar"
>
<div class="nav-mobile-sidebar-top">
<h1 [class.tui-skeleton]="!registry">
{{ registry?.info?.name }}
</h1>
<button
[style.--tui-padding]="0"
tuiButton
type="button"
appearance="icon"
iconStart="@tui.x"
(tuiActiveZoneChange)="toggleMenu($event)"
(click)="toggleMenu(false)"
></button>
</div>
<!-- change registry modal -->
<ng-content select="[slot=mobile]"></ng-content>
<div class="nav-mobile-sidebar-bottom divide-bar">
<marketplace-categories
[categories]="registry?.info?.categories"
[category]="query ? '' : category"
(categoryChange)="onCategoryChange($event); toggleMenu(false)"
/>
<div>
<!-- link to store for brochure -->
<ng-content select="[slot=store-mobile]" />
<a
target="_blank"
rel="noreferrer"
href="https://docs.start9.com/0.3.5.x/developer-docs/"
>
<span>Package a service</span>
<tui-icon tuiAppearance="icon" icon="@tui.external-link" />
</a>
</div>
</div>
</nav>
</button>
</div>
</div>
<!-- desktop nav -->
<nav class="nav-desktop">
<!-- desktop search -->
<marketplace-search [query]="query" (queryChange)="onQueryChange($event)" />
<div class="nav-desktop-container">
<marketplace-categories
[categories]="registry?.info?.categories"
[category]="query ? '' : category"
(categoryChange)="onCategoryChange($event)"
/>
<div>
<!-- link to store for brochure -->
<ng-content select="[slot=store]" />
<a
target="_blank"
rel="noreferrer"
href="https://docs.start9.com/0.3.5.x/developer-docs/"
>
<span>Package a service</span>
<tui-icon tuiAppearance="icon" icon="@tui.external-link" />
</a>
</div>
</nav>
</ng-container>
</div>
</nav>
</header>

View File

@@ -5,11 +5,10 @@ import {
Input,
OnDestroy,
} from '@angular/core'
import { combineLatest, map, Subject, takeUntil } from 'rxjs'
import { StoreIdentity } from '../../types'
import { AbstractMarketplaceService } from '../../services/marketplace.service'
import { AbstractCategoryService } from '../../services/category.service'
import { MarketplaceConfig } from '@start9labs/shared'
import { Subject, takeUntil } from 'rxjs'
import { AbstractCategoryService } from '../../services/category.service'
import { StoreDataWithUrl } from '../../types'
@Component({
selector: 'menu',
@@ -21,19 +20,11 @@ export class MenuComponent implements OnDestroy {
@Input({ required: true })
iconConfig!: MarketplaceConfig
@Input({ required: true })
registry!: StoreDataWithUrl | null
private destroy$ = new Subject<void>()
private readonly marketplaceService = inject(AbstractMarketplaceService)
private readonly categoryService = inject(AbstractCategoryService)
readonly store$ = this.marketplaceService.getSelectedStoreWithCategories$()
readonly alt$ = combineLatest([
this.marketplaceService.getKnownHosts$(),
this.marketplaceService.getSelectedHost$(),
]).pipe(
map(([stores, selected]) =>
stores.filter(({ url }) => url != selected.url),
),
)
private hosts?: StoreIdentity[]
category = ''
query = ''
open = false
@@ -52,13 +43,6 @@ export class MenuComponent implements OnDestroy {
.subscribe(val => {
this.category = val
})
this.marketplaceService
.getKnownHosts$()
.pipe(takeUntil(this.destroy$))
.subscribe(hosts => {
this.hosts = hosts
})
}
onCategoryChange(category: string): void {
@@ -66,7 +50,6 @@ export class MenuComponent implements OnDestroy {
this.query = ''
this.categoryService.resetQuery()
this.categoryService.changeCategory(category)
this.categoryService.handleNavigation()
}
onQueryChange(query: string): void {

View File

@@ -1,6 +1,5 @@
import { CommonModule } from '@angular/common'
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { MarketplacePkg } from '../../src/types'
import { Exver, MarkdownPipeModule } from '@start9labs/shared'
import { TuiButton, TuiDialogContext, TuiLoader } from '@taiga-ui/core'
import { TuiAccordion } from '@taiga-ui/kit'
@@ -8,26 +7,21 @@ import {
POLYMORPHEUS_CONTEXT,
PolymorpheusComponent,
} from '@taiga-ui/polymorpheus'
import { map } from 'rxjs'
import { AbstractMarketplaceService } from '../services/marketplace.service'
import { MarketplacePkg } from '../../src/types'
@Component({
standalone: true,
template: `
@if (notes$ | async; as notes) {
<tui-accordion>
@for (note of notes | keyvalue: asIsOrder; track $index) {
<tui-accordion-item>
{{ note.key }}
<ng-template tuiAccordionItemContent>
<div [innerHTML]="note.value | markdown"></div>
</ng-template>
</tui-accordion-item>
}
</tui-accordion>
} @else {
<tui-loader textContent="Loading Release Notes" />
}
<tui-accordion>
@for (note of notes | keyvalue: asIsOrder; track $index) {
<tui-accordion-item>
{{ note.key }}
<ng-template tuiAccordionItemContent>
<div [innerHTML]="note.value | markdown"></div>
</ng-template>
</tui-accordion-item>
}
</tui-accordion>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
@@ -43,26 +37,20 @@ export class ReleaseNotesComponent {
private readonly pkg =
inject<TuiDialogContext<void, MarketplacePkg>>(POLYMORPHEUS_CONTEXT).data
readonly notes$ = inject(AbstractMarketplaceService)
.getSelectedStore$()
.pipe(
map(s => {
return Object.entries(this.pkg.otherVersions)
.filter(
([v, _]) =>
this.exver.getFlavor(v) === this.pkg.flavor &&
this.exver.compareExver(this.pkg.version, v) === 1,
)
.reduce(
(obj, [version, info]) => ({
...obj,
[version]: info.releaseNotes,
}),
{
[`${this.pkg.version} (current)`]: this.pkg.releaseNotes,
},
)
readonly notes = Object.entries(this.pkg.otherVersions)
.filter(
([v, _]) =>
this.exver.getFlavor(v) === this.pkg.flavor &&
this.exver.compareExver(this.pkg.version, v) === 1,
)
.reduce(
(obj, [version, info]) => ({
...obj,
[version]: info.releaseNotes,
}),
{
[`${this.pkg.version} (current)`]: this.pkg.releaseNotes,
},
)
asIsOrder(a: any, b: any) {

View File

@@ -28,7 +28,7 @@
</ng-template>
<!-- license -->
<marketplace-additional-item
(click)="presentModalMd('License')"
(click)="static.emit('License')"
[data]="pkg.license"
label="License"
icon="@tui.chevron-right"
@@ -36,7 +36,7 @@
/>
<!-- instructions -->
<marketplace-additional-item
(click)="presentModalMd('Instructions')"
(click)="static.emit('Instructions')"
data="Click to view instructions"
label="Instructions"
icon="@tui.chevron-right"

View File

@@ -1,15 +1,14 @@
import {
ChangeDetectionStrategy,
Component,
inject,
EventEmitter,
Input,
Output,
} from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { CopyService } from '@start9labs/shared'
import { TuiDialogService } from '@taiga-ui/core'
import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
import { CopyService, MarkdownComponent } from '@start9labs/shared'
import { MarketplacePkg } from '../../../types'
import { AbstractMarketplaceService } from '../../../services/marketplace.service'
@Component({
selector: 'marketplace-additional',
@@ -21,7 +20,8 @@ export class AdditionalComponent {
@Input({ required: true })
pkg!: MarketplacePkg
private readonly marketplaceService = inject(AbstractMarketplaceService)
@Output()
readonly static = new EventEmitter<string>()
constructor(
readonly copyService: CopyService,
@@ -30,19 +30,4 @@ export class AdditionalComponent {
) {}
readonly url = this.route.snapshot.queryParamMap.get('url') || undefined
presentModalMd(label: string) {
this.dialogs
.open(new PolymorpheusComponent(MarkdownComponent), {
label,
size: 'l',
data: {
content: this.marketplaceService.fetchStatic$(
this.pkg,
label === 'License' ? 'LICENSE.md' : 'instructions.md',
),
},
})
.subscribe()
}
}

View File

@@ -18,6 +18,7 @@ import { MarketplacePkg } from '../../../types'
tuiCell
[routerLink]="[]"
[queryParams]="{ id: pkg.id, flavor: pkg.flavor }"
queryParamsHandling="merge"
>
<tui-avatar [src]="pkg.icon | trustUrl" />
<span tuiTitle>

View File

@@ -29,7 +29,6 @@ export * from './components/menu/menu.component.module'
export * from './components/menu/menu.component'
export * from './components/registry.component'
export * from './services/marketplace.service'
export * from './services/category.service'
export * from './types'

View File

@@ -1,28 +0,0 @@
import { Observable } from 'rxjs'
import { Marketplace, MarketplacePkg, StoreData, StoreIdentity } from '../types'
export abstract class AbstractMarketplaceService {
abstract getKnownHosts$(): Observable<StoreIdentity[]>
abstract getSelectedHost$(): Observable<StoreIdentity>
abstract getMarketplace$(): Observable<Marketplace>
abstract getSelectedStore$(): Observable<StoreData>
abstract getSelectedStoreWithCategories$(): Observable<
StoreIdentity & StoreData
>
abstract getPackage$(
id: string,
version: string | null,
flavor: string | null,
url?: string,
): Observable<MarketplacePkg>
abstract fetchStatic$(
pkg: MarketplacePkg,
type: 'LICENSE.md' | 'instructions.md',
): Observable<string>
}

View File

@@ -37,3 +37,5 @@ export type MarketplacePkg = T.PackageVersionInfo &
version: string
flavor: string | null
}
export type StoreDataWithUrl = StoreData & { url: string }