fix: fix build after minor merged into major

This commit is contained in:
waterplea
2024-08-15 12:40:49 +04:00
parent b43ad93c54
commit a730543c76
189 changed files with 714 additions and 3652 deletions

View File

@@ -0,0 +1,90 @@
import { CommonModule } from '@angular/common'
import {
ChangeDetectionStrategy,
Component,
inject,
Input,
} from '@angular/core'
import { Exver, MarkdownPipeModule } from '@start9labs/shared'
import { TuiButton, TuiLoader } from '@taiga-ui/core'
import { TuiCardLarge } from '@taiga-ui/layout'
import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
import { map } from 'rxjs'
import { AbstractMarketplaceService } from '../services/marketplace.service'
import { MarketplacePkg } from '../types'
@Component({
standalone: true,
template: `
@if (notes$ | async; as notes) {
@for (note of notes | keyvalue: asIsOrder; track $index) {
<button tuiButton (click)="setSelected(note.key)">
{{ note.key }}
</button>
<div
tuiCardLarge
#element
[id]="note.key"
[style.max-height.px]="getDocSize(note.key, element)"
[innerHTML]="note.value | markdown"
></div>
}
} @else {
<tui-loader textContent="Loading Release Notes" />
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
CommonModule,
TuiButton,
TuiLoader,
TuiCardLarge,
MarkdownPipeModule,
],
})
export class ReleaseNotesComponent {
@Input() pkg!: MarketplacePkg
private selected: string | null = null
private readonly exver = inject(Exver)
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,
},
)
}),
)
isSelected(key: string): boolean {
return this.selected === key
}
setSelected(selected: string) {
this.selected = this.isSelected(selected) ? null : selected
}
getDocSize(key: string, { scrollHeight }: HTMLElement) {
return this.isSelected(key) ? scrollHeight : 0
}
asIsOrder(a: any, b: any) {
return 0
}
}
export const RELEASE_NOTES = new PolymorpheusComponent(ReleaseNotesComponent)

View File

@@ -1,51 +0,0 @@
<div class="background-border box-shadow-lg shadow-color-light">
<div class="box-container">
<h2 class="additional-detail-title">What's new</h2>
<div class="box-container-details">
<div class="box-container-details-version">
<h3>Version {{ pkg.manifest.version }}</h3>
<p
safeLinks
class="box-container-details-notes"
[innerHTML]="pkg.manifest.releaseNotes | markdown | dompurify"
></p>
</div>
<button
*ngIf="pkg.versions.length > 2"
tuiButton
type="button"
appearance="secondary"
size="m"
(click)="showReleaseNotes(template)"
>
Previous releases
</button>
</div>
</div>
</div>
<ng-template #template let-observer>
<ng-container *ngIf="notes$ | async as notes; else loading">
<tui-accordion
class="max-width-lg"
style="max-width: 32rem"
[closeOthers]="false"
*ngFor="
let note of notes
| filterVersions: pkg.manifest.version
| keyvalue: asIsOrder
"
>
<tui-accordion-item style="margin: 0.25rem 0">
{{ note.key | displayEmver }}
<ng-template tuiAccordionItemContent>
<p safeLinks [innerHTML]="note.value | markdown | dompurify"></p>
</ng-template>
</tui-accordion-item>
</tui-accordion>
</ng-container>
<ng-template #loading>
<tui-loader textContent="Loading Release Notes" />
</ng-template>
</ng-template>

View File

@@ -1,44 +0,0 @@
.box-container {
background-color: rgb(39 39 42);
border-radius: 0.75rem;
padding: 1.75rem;
display: grid;
grid-auto-flow: row;
align-items: center;
&-details {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
&-version {
line-height: 1.5rem;
font-size: 1rem;
h3 {
font-size: 1.2rem;
margin-bottom: 1.25rem;
pointer-events: none;
}
}
&-notes {
flex-wrap: wrap;
margin-top: 0.25rem;
pointer-events: none;
}
button {
margin-top: 0.75rem;
place-self: end;
@media (min-width: 768px) {
place-self: start;
}
@media (min-width: 1024px) {
place-self: end;
}
}
}
}

View File

@@ -1,70 +0,0 @@
import {
ChangeDetectionStrategy,
Component,
ElementRef,
Input,
} from '@angular/core'
import { AbstractMarketplaceService } from '../../services/marketplace.service'
import { MarketplacePkg } from '../../types'
import { map } from 'rxjs'
import { Exver } from '@start9labs/shared'
// @TODO Alex use Taiga modal
import { ModalController } from '@ionic/angular'
@Component({
selector: 'release-notes',
templateUrl: './release-notes.component.html',
styleUrls: ['./release-notes.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ReleaseNotesComponent {
@Input() pkg!: MarketplacePkg
private selected: string | null = null
readonly notes$ = this.marketplaceService.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,
},
)
}),
)
constructor(
private readonly marketplaceService: AbstractMarketplaceService,
private readonly exver: Exver,
private readonly modalCtrl: ModalController,
) {}
async dismiss() {
return this.modalCtrl.dismiss()
}
isSelected(key: string): boolean {
return this.selected === key
}
setSelected(selected: string) {
this.selected = this.isSelected(selected) ? null : selected
}
getDocSize(key: string, { nativeElement }: ElementRef<HTMLElement>) {
return this.isSelected(key) ? nativeElement.scrollHeight : 0
}
asIsOrder(a: any, b: any) {
return 0
}
}

View File

@@ -1,32 +0,0 @@
import { TuiAccordion } from '@taiga-ui/kit'
import { NgModule } from '@angular/core'
import { CommonModule } from '@angular/common'
import {
ExverPipesModule,
MarkdownPipeModule,
SafeLinksDirective,
} from '@start9labs/shared'
import { TuiLoader, TuiButton } from '@taiga-ui/core'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
import {
FilterVersionsPipe,
ReleaseNotesComponent,
} from './release-notes.component'
import { ReleaseNotesComponent } from './release-notes.component'
@NgModule({
imports: [
CommonModule,
ExverPipesModule,
MarkdownPipeModule,
NgDompurifyModule,
SafeLinksDirective,
TuiButton,
...TuiAccordion,
TuiLoader,
FilterVersionsPipe,
],
declarations: [ReleaseNotesComponent],
exports: [ReleaseNotesComponent],
})
export class ReleaseNotesComponentModule {}

View File

@@ -1,14 +1,14 @@
<button
*ngFor="let cat of categories || ['', '', '', '', '', '']"
(click)="switchCategory(cat)"
[class.category_selected]="cat === category"
*ngFor="let cat of categories || fallback | keyvalue"
(click)="switchCategory(cat.key)"
[class.category_selected]="cat.key === category"
>
<div
class="category-wrapper"
[class.tui-skeleton]="!categories"
[class.tui-skeleton_rounded]="!categories"
>
<tui-icon tuiAppearance="icon" icon="{{ determineIcon(cat) }}"></tui-icon>
<tui-icon tuiAppearance="icon" [icon]="determineIcon(cat.key)" />
</div>
<span
class="category-title"
@@ -16,9 +16,9 @@
[class.tui-skeleton_rounded]="!categories"
>
{{
cat === 'ai'
? (cat | uppercase)
: (cat | titlecase) || 'Loading category...'
cat.key === 'ai'
? (cat.key | uppercase)
: (cat.value.name | titlecase) || 'Loading category...'
}}
</span>
</button>

View File

@@ -15,7 +15,7 @@ import { T } from '@start9labs/start-sdk'
})
export class CategoriesComponent {
@Input()
categories!: Map<string, T.Category>
categories?: Record<string, T.Category>
@Input()
category = ''
@@ -23,6 +23,14 @@ export class CategoriesComponent {
@Output()
readonly categoryChange = new EventEmitter<string>()
readonly fallback: Record<string, T.Category> = {
a: { name: 'a', description: { short: 'a', long: 'a' } },
b: { name: 'a', description: { short: 'a', long: 'a' } },
c: { name: 'a', description: { short: 'a', long: 'a' } },
d: { name: 'a', description: { short: 'a', long: 'a' } },
e: { name: 'a', description: { short: 'a', long: 'a' } },
}
switchCategory(category: string): void {
this.category = category
this.categoryChange.emit(category)

View File

@@ -25,7 +25,7 @@ export class ItemComponent {
const iconUrl = new URL(this.pkg.icon)
return iconUrl.href
} catch (e) {
return `${marketplace?.url}package/v0/icon/${this.pkg.manifest.id}`
return `${marketplace?.url}package/v0/icon/${this.pkg.id}`
}
}
}

View File

@@ -1,8 +1,23 @@
<div class="background-border box-shadow-lg shadow-color-light">
<div class="box-container">
<h2 class="additional-detail-title">New in {{ pkg.version }}</h2>
<p [innerHTML]="pkg.releaseNotes | markdown"></p>
<button tuiButton iconEnd="@tui.chevron-right" (click)="onPast()">
Past Release Notes
</button>
</div>
<div class="box-container">
<h2 class="additional-detail-title">About</h2>
<p>
{{ pkg.manifest.description.long }}
</p>
<p>{{ pkg.description.long }}</p>
<a
*ngIf="pkg.marketingSite as url"
tuiButton
iconEnd="@tui.external-link"
target="_blank"
rel="noreferrer"
[href]="url"
>
View website
</a>
</div>
</div>

View File

@@ -1,7 +1,12 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import {
ChangeDetectionStrategy,
Component,
inject,
Input,
} from '@angular/core'
import { TuiDialogService } from '@taiga-ui/core'
import { RELEASE_NOTES } from '../../../modals/release-notes.component'
import { MarketplacePkg } from '../../../types'
import { ModalController } from '@ionic/angular'
import { ReleaseNotesComponent } from '../../../modals/release-notes/release-notes.component'
@Component({
selector: 'marketplace-about',
@@ -10,17 +15,14 @@ import { ReleaseNotesComponent } from '../../../modals/release-notes/release-not
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AboutComponent {
private readonly dialogs = inject(TuiDialogService)
@Input({ required: true })
pkg!: MarketplacePkg
constructor(private readonly modalCtrl: ModalController) {}
async presentModalNotes() {
const modal = await this.modalCtrl.create({
componentProps: { pkg: this.pkg },
component: ReleaseNotesComponent,
})
await modal.present()
async onPast() {
this.dialogs
.open(RELEASE_NOTES, { label: 'Past Release Notes' })
.subscribe()
}
}

View File

@@ -1,10 +1,11 @@
import { TuiButton } from '@taiga-ui/core'
import { TuiTagModule } from '@taiga-ui/legacy'
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { RouterModule } from '@angular/router'
import { AboutComponent } from './about.component'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
import { SafeLinksDirective } from '@start9labs/shared'
import { MarkdownPipeModule, SafeLinksDirective } from '@start9labs/shared'
@NgModule({
imports: [
@@ -13,6 +14,8 @@ import { SafeLinksDirective } from '@start9labs/shared'
TuiTagModule,
NgDompurifyModule,
SafeLinksDirective,
MarkdownPipeModule,
TuiButton,
],
declarations: [AboutComponent],
exports: [AboutComponent],

View File

@@ -4,11 +4,11 @@
<div class="detail-container">
<!-- release date -->
<marketplace-additional-item
*ngIf="pkg.publishedAt as published"
*ngIf="pkg.s9pk.publishedAt as published"
[data]="(published | date: 'medium')!"
label="Released"
icon=""
></marketplace-additional-item>
/>
<!-- git hash -->
<marketplace-additional-item
*ngIf="pkg.gitHash as gitHash; else noHash"
@@ -17,7 +17,7 @@
label="Git Hash"
icon="@tui.copy"
class="item-copy"
></marketplace-additional-item>
/>
<ng-template #noHash>
<div class="item-padding">
<label tuiTitle>
@@ -33,7 +33,7 @@
label="License"
icon="@tui.chevron-right"
class="item-pointer"
></marketplace-additional-item>
/>
<!-- instructions -->
<marketplace-additional-item
(click)="presentModalMd('Instructions')"
@@ -41,7 +41,7 @@
label="Instructions"
icon="@tui.chevron-right"
class="item-pointer"
></marketplace-additional-item>
/>
<!-- versions -->
<ng-content />
<!-- links -->
@@ -51,28 +51,28 @@
label="Marketing Site"
icon="@tui.external-link"
class="item-pointer"
></marketplace-additional-link>
/>
<marketplace-additional-link
*ngIf="pkg.upstreamRepo"
[url]="pkg.upstreamRepo"
label="Source Repository"
icon="@tui.external-link"
class="item-pointer"
></marketplace-additional-link>
/>
<marketplace-additional-link
*ngIf="pkg.wrapperRepo"
[url]="pkg.wrapperRepo"
label="Wrapper Repository"
icon="@tui.external-link"
class="item-pointer"
></marketplace-additional-link>
/>
<marketplace-additional-link
*ngIf="pkg.supportSite"
[url]="pkg.supportSite"
label="Support Site"
icon="@tui.external-link"
class="item-pointer"
></marketplace-additional-link>
/>
</div>
</div>
</div>

View File

@@ -7,7 +7,7 @@ import {
import { ActivatedRoute } from '@angular/router'
import { TuiDialogService } from '@taiga-ui/core'
import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
import { CopyService, Exver, MarkdownComponent } from '@start9labs/shared'
import { CopyService, MarkdownComponent } from '@start9labs/shared'
import { MarketplacePkg } from '../../../types'
import { AbstractMarketplaceService } from '../../../services/marketplace.service'
@@ -38,9 +38,8 @@ export class AdditionalComponent {
size: 'l',
data: {
content: this.marketplaceService.fetchStatic$(
this.pkg.id,
label.toLowerCase(),
this.url,
this.pkg,
label === 'License' ? 'LICENSE.md' : 'instructions.md',
),
},
})

View File

@@ -1,14 +1,13 @@
import { CommonModule } from '@angular/common'
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
Input,
Output,
inject,
} from '@angular/core'
import { CommonModule } from '@angular/common'
import { MarketplaceDepItemComponent } from './dependency-item.component'
import { MarketplacePkg } from '../../../types'
import { MarketplaceDepItemComponent } from './dependency-item.component'
@Component({
selector: 'marketplace-dependencies',
@@ -17,7 +16,7 @@ import { MarketplacePkg } from '../../../types'
<div class="dependencies-container">
<h2 class="additional-detail-title">Dependencies</h2>
<div class="dependencies-list">
@for (dep of pkg.manifest.dependencies | keyvalue; track $index) {
@for (dep of pkg.dependencyMetadata | keyvalue; track $index) {
<marketplace-dep-item
[dep]="dep"
[pkg]="pkg"

View File

@@ -2,15 +2,16 @@ import { CommonModule, KeyValue } from '@angular/common'
import {
ChangeDetectionStrategy,
Component,
Input,
inject,
Input,
} from '@angular/core'
import { RouterModule } from '@angular/router'
import { EmverPipesModule } from '@start9labs/shared'
import { ExverPipesModule } from '@start9labs/shared'
import { T } from '@start9labs/start-sdk'
import { TuiLet } from '@taiga-ui/cdk'
import { TuiAvatar, TuiLineClamp } from '@taiga-ui/kit'
import { Dependency, MarketplacePkg, StoreIdentity } from '../../../types'
import { AbstractMarketplaceService } from '../../../services/marketplace.service'
import { MarketplacePkg, StoreIdentity } from '../../../types'
@Component({
selector: 'marketplace-dep-item',
@@ -104,7 +105,7 @@ import { AbstractMarketplaceService } from '../../../services/marketplace.servic
CommonModule,
RouterModule,
TuiAvatar,
EmverPipesModule,
ExverPipesModule,
TuiLineClamp,
TuiLet,
],
@@ -114,7 +115,7 @@ export class MarketplaceDepItemComponent {
pkg!: MarketplacePkg
@Input({ required: true })
dep!: KeyValue<string, Dependency>
dep!: KeyValue<string, T.DependencyMetadata>
private readonly marketplaceService = inject(AbstractMarketplaceService)
readonly marketplace$ = this.marketplaceService.getSelectedHost$()

View File

@@ -1,21 +0,0 @@
<ion-item-divider>Alternative Implementations</ion-item-divider>
<ion-grid>
<ion-row>
<ion-col *ngFor="let pkg of pkgs" responsiveCol sizeSm="12" sizeMd="6">
<ion-item
[routerLink]="['/marketplace', pkg.id]"
[queryParams]="{ flavor: pkg.flavor }"
>
<ion-thumbnail slot="start">
<img alt="" style="border-radius: 100%" [src]="pkg.icon | trustUrl" />
</ion-thumbnail>
<ion-label>
<h2>
{{ pkg.title }}
</h2>
<p>{{ pkg.version }}</p>
</ion-label>
</ion-item>
</ion-col>
</ion-row>
</ion-grid>

View File

@@ -1,10 +1,31 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { RouterLink } from '@angular/router'
import { SharedPipesModule } from '@start9labs/shared'
import { TuiTitle } from '@taiga-ui/core'
import { TuiCell } from '@taiga-ui/layout'
import { MarketplacePkg } from '../../../types'
@Component({
standalone: true,
selector: 'marketplace-flavors',
templateUrl: 'flavors.component.html',
template: `
<h2>Alternative Implementations</h2>
@for (pkg of pkgs; track $index) {
<a
tuiCell
[routerLink]="['/marketplace', pkg.id]"
[queryParams]="{ flavor: pkg.flavor }"
>
<img alt="" style="border-radius: 100%" [src]="pkg.icon | trustUrl" />
<span tuiTitle>
{{ pkg.title }}
<span tuiSubtitle>{{ pkg.version }}</span>
</span>
</a>
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [RouterLink, TuiCell, TuiTitle, SharedPipesModule],
})
export class FlavorsComponent {
@Input()

View File

@@ -1,19 +0,0 @@
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { RouterModule } from '@angular/router'
import { IonicModule } from '@ionic/angular'
import { ResponsiveColModule, SharedPipesModule } from '@start9labs/shared'
import { FlavorsComponent } from './flavors.component'
@NgModule({
imports: [
CommonModule,
RouterModule,
IonicModule,
SharedPipesModule,
ResponsiveColModule,
],
declarations: [FlavorsComponent],
exports: [FlavorsComponent],
})
export class FlavorsModule {}

View File

@@ -18,26 +18,26 @@ import { MarketplacePkg, StoreIdentity } from '../../../types'
<!-- icon -->
<img
[src]="determineIcon(marketplace) | trustUrl"
alt="{{ pkg.manifest.title }} Icon"
alt="{{ pkg.title }} Icon"
/>
<!-- color background -->
<div class="color-background">
<img
[src]="determineIcon(marketplace) | trustUrl"
alt="{{ pkg.manifest.title }} background image"
alt="{{ pkg.title }} background image"
/>
</div>
<!-- background darkening overlay -->
<div class="dark-overlay"></div>
<div class="inner-container-title">
<h2 ticker>
{{ pkg.manifest.title }}
{{ pkg.title }}
</h2>
<h3>
{{ pkg.manifest.version }}
{{ pkg.version }}
</h3>
<p>
{{ pkg.manifest.description.short }}
{{ pkg.description.short }}
</p>
</div>
<!-- control buttons -->
@@ -175,7 +175,7 @@ export class MarketplacePackageHeroComponent {
const iconUrl = new URL(this.pkg.icon)
return iconUrl.href
} catch (e) {
return `${marketplace?.url}package/v0/icon/${this.pkg.manifest.id}`
return `${marketplace?.url}package/v0/icon/${this.pkg.id}`
}
}
}

View File

@@ -14,11 +14,16 @@ import { PolymorpheusContent } from '@taiga-ui/polymorpheus'
@Component({
selector: 'marketplace-package-screenshots',
template: `
<div *ngIf="pkg.screenshots" tuiCarouselButtons class="outer-container">
<!--@TODO Matt or Lucy?-->
<div
*ngIf="$any(pkg).screenshots as screenshots"
tuiCarouselButtons
class="outer-container"
>
<button
tuiIconButton
appearance="flat"
icon="@tui.chevron-left"
iconStart="@tui.chevron-left"
title="Previous"
type="button"
(click)="carousel.prev()"
@@ -29,7 +34,7 @@ import { PolymorpheusContent } from '@taiga-ui/polymorpheus'
[(index)]="index"
class="carousel"
>
<ng-container *ngFor="let item of pkg.screenshots; let i = index">
<ng-container *ngFor="let item of screenshots; let i = index">
<div
*tuiItem
draggable="false"
@@ -57,7 +62,7 @@ import { PolymorpheusContent } from '@taiga-ui/polymorpheus'
tuiIconButton
appearance="flat"
type="button"
icon="@tui.chevron-right"
iconStart="@tui.chevron-right"
title="Next"
(click)="carousel.next()"
></button>

View File

@@ -19,7 +19,6 @@ export * from './pages/show/dependencies/dependency-item.component'
export * from './pages/show/screenshots/screenshots.component'
export * from './pages/show/hero/hero.component'
export * from './pages/show/flavors/flavors.component'
export * from './pages/show/flavors/flavors.module'
export * from './pipes/filter-packages.pipe'

View File

@@ -1,11 +1,5 @@
import { Observable } from 'rxjs'
import {
Marketplace,
MarketplacePkg,
StoreData,
StoreIdentity,
StoreIdentityWithData,
} from '../types'
import { Marketplace, MarketplacePkg, StoreData, StoreIdentity } from '../types'
export abstract class AbstractMarketplaceService {
abstract getKnownHosts$(): Observable<StoreIdentity[]>
@@ -16,7 +10,9 @@ export abstract class AbstractMarketplaceService {
abstract getSelectedStore$(): Observable<StoreData>
abstract getSelectedStoreWithCategories$(): Observable<StoreIdentityWithData>
abstract getSelectedStoreWithCategories$(): Observable<
StoreIdentity & StoreData
>
abstract getPackage$(
id: string,