marketplace release fixes and refactors

This commit is contained in:
Lucy Cifferello
2024-04-01 18:09:28 -04:00
parent 352b2fb4e7
commit 0d4ebffc0e
43 changed files with 748 additions and 565 deletions

5
web/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "startos-ui",
"version": "0.3.5.1",
"version": "0.3.5.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "startos-ui",
"version": "0.3.5.1",
"version": "0.3.5.2",
"dependencies": {
"@angular/animations": "^17.3.1",
"@angular/cdk": "^17.3.1",
@@ -1988,6 +1988,7 @@
"devDependencies": {
"@iarna/toml": "^2.2.5",
"@types/jest": "^29.4.0",
"copyfiles": "^2.4.1",
"jest": "^29.4.3",
"prettier": "^3.2.5",
"ts-jest": "^29.0.5",

View File

@@ -1,6 +1,6 @@
{
"name": "@start9labs/marketplace",
"version": "0.3.19",
"version": "0.3.25",
"peerDependencies": {
"@angular/common": ">=13.2.0",
"@angular/core": ">=13.2.0",

View File

@@ -4,7 +4,7 @@
<store-icon
[class.tui-skeleton]="!store"
[class.tui-skeleton_rounded]="!store"
size="64px"
size="60px"
[url]="store?.url || ''"
[marketplace]="iconConfig"
></store-icon>
@@ -27,13 +27,14 @@
type="button"
appearance="flat"
[pseudoActive]="false"
[pseudoHover]="false"
(click)="toggleMenu(true)"
(tuiActiveZoneChange)="toggleMenu($event)"
[style.--tui-padding]="'1rem'"
[style.--tui-padding]="'1.2rem'"
>
<store-icon
size="48px"
[style.height]="'48px'"
size="42px"
[style.height]="'42px'"
[style.border-radius]="'100%'"
[url]="store?.url || ''"
[marketplace]="iconConfig"
@@ -66,17 +67,22 @@
[category]="query ? '' : category"
(categoryChange)="onCategoryChange($event); toggleMenu(false)"
></marketplace-categories>
<a
target="_blank"
href="https://github.com/Start9Labs/service-pipeline#readme"
>
<!-- @TODO need rocket icon -->
<tui-icon
tuiAppearance="icon"
icon="tuiIconExternalLinkLarge"
></tui-icon>
<span>Launch your project</span>
</a>
<div>
<!-- link to store for brochure -->
<ng-content select="[slot=store-mobile]"></ng-content>
<a
target="_blank"
rel="noreferrer"
href="https://docs.start9.com/0.3.5.x/developer-docs/"
>
<!-- @TODO need rocket icon -->
<span>Package a service</span>
<tui-icon
tuiAppearance="icon"
icon="tuiIconExternalLinkLarge"
></tui-icon>
</a>
</div>
</div>
</nav>
</button>
@@ -95,17 +101,22 @@
[category]="query ? '' : category"
(categoryChange)="onCategoryChange($event)"
></marketplace-categories>
<a
target="_blank"
href="https://github.com/Start9Labs/service-pipeline#readme"
>
<!-- @TODO need rocket icon -->
<tui-icon
tuiAppearance="icon"
icon="tuiIconExternalLinkLarge"
></tui-icon>
<span>Launch your project</span>
</a>
<div>
<!-- link to store for brochure -->
<ng-content select="[slot=store]"></ng-content>
<a
target="_blank"
rel="noreferrer"
href="https://docs.start9.com/0.3.5.x/developer-docs/"
>
<!-- @TODO need rocket icon -->
<span>Package a service</span>
<tui-icon
tuiAppearance="icon"
icon="tuiIconExternalLinkLarge"
></tui-icon>
</a>
</div>
</div>
</nav>
</ng-container>

View File

@@ -14,12 +14,12 @@ header {
flex-direction: column;
z-index: 10;
@media screen and (min-width: 640px) {
width: 15rem;
@media screen and (min-width: 768px) {
width: 17rem;
background-color: rgb(var(--tw-color-zinc-700) / 0.9);
backdrop-filter: blur(40px);
min-height: calc(100vh - var(--portal-header-height));
padding: 1.5rem 0;
padding: 2rem 0 1.5rem 0;
&::after {
display: block;
@@ -36,12 +36,16 @@ header {
);
}
}
@media screen and (min-width: 1536px) {
width: 18rem;
}
}
.title {
display: none;
@media (min-width: 640px) {
@media (min-width: 768px) {
display: flex;
flex-direction: column;
align-items: center;
@@ -74,9 +78,10 @@ header {
marketplace-search {
place-self: center;
padding-bottom: 2rem;
width: 100%;
}
@media (min-width: 640px) {
@media (min-width: 768px) {
display: flex;
flex-grow: 1;
flex-direction: column;
@@ -88,27 +93,17 @@ header {
flex-direction: column;
justify-content: space-between;
a {
::ng-deep a {
display: flex;
justify-content: center;
gap: 0.5rem;
padding: 0.5rem;
z-index: 50;
border-top-left-radius: 0.5rem;
border-bottom-left-radius: 0.5rem;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-delay: 75ms;
transition-duration: 300ms;
&:hover {
text-decoration-line: none;
cursor: pointer;
}
img {
opacity: 0.7;
filter: invert(100%);
}
span {
font-size: 1rem;
line-height: 1.5rem;
@@ -117,31 +112,23 @@ header {
overflow: hidden;
white-space: nowrap;
}
@media (min-width: 640px) {
width: 120%;
&:hover {
background-color: rgb(34 36 40);
}
}
}
}
}
&-mobile {
@media (min-width: 640px) {
@media (min-width: 768px) {
display: none;
}
&-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
width: 100vw;
marketplace-search {
max-width: fit-content;
flex-grow: 1;
}
}
@@ -184,9 +171,8 @@ header {
padding: 1.25rem 1.25rem 0px 1.25rem;
}
a {
::ng-deep a {
display: flex;
position: relative;
gap: 0.5rem;
padding: 1.25rem;
@@ -194,11 +180,6 @@ header {
text-decoration-line: none;
}
img {
opacity: 0.7;
filter: invert(100%);
}
span {
font-size: 1rem;
line-height: 1.5rem;

View File

@@ -1,11 +1,10 @@
import { NgModule } from '@angular/core'
import { CommonModule } from '@angular/common'
import { TuiIconModule } from '@taiga-ui/experimental'
import { StoreIconComponent } from './store-icon.component'
@NgModule({
declarations: [StoreIconComponent],
imports: [CommonModule, TuiIconModule],
imports: [CommonModule],
exports: [StoreIconComponent],
})
export class StoreIconComponentModule {}

View File

@@ -9,10 +9,14 @@ import { MarketplaceConfig, sameUrl } from '@start9labs/shared'
[style.border-radius.%]="100"
[style.max-width]="size || '100%'"
[src]="icon"
alt="Service Icon"
alt="Marketplace Icon"
/>
<ng-template #noIcon>
<tui-icon icon="tuiIconShoppingCart" [style.font-size]="size" />
<img
[style.max-width]="size || '100%'"
src="assets/img/storefront-outline.png"
alt="Marketplace Icon"
/>
</ng-template>
`,
changeDetection: ChangeDetectionStrategy.OnPush,

View File

@@ -19,7 +19,7 @@
{{
cat === 'ai'
? (cat | uppercase)
: (cat | titlecase) || 'loading category...'
: (cat | titlecase) || 'Loading category...'
}}
</span>
</button>

View File

@@ -2,7 +2,7 @@
font-weight: bold;
}
@media (min-width: 600px) {
@media (min-width: 768px) {
.category_selected {
border-top-left-radius: 0.5rem;
border-bottom-left-radius: 0.5rem;
@@ -20,7 +20,7 @@ button {
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-delay: 75ms;
transition-duration: 300ms;
margin-bottom: 1.25rem;
margin-bottom: 2rem;
z-index: 50;
&:hover {

View File

@@ -32,7 +32,7 @@
width: 150%;
height: 150%;
max-width: 200%;
filter: blur(100px);
filter: blur(100px) saturate(85%);
}
}
@@ -45,7 +45,7 @@
left: 0px;
border-radius: 1.5rem;
background-color: rgb(39 39 42);
opacity: 0.4;
opacity: 0.6;
}
.icon {
@@ -56,7 +56,6 @@
top: -2.5rem;
border-radius: 9999px;
object-fit: cover;
z-index: 10;
backdrop-filter: blur(24px);
background-color: rgb(0 0 0 / 0.5);
transform: none;
@@ -67,11 +66,10 @@
mix-blend-mode: plus-lighter;
&-title {
display: block;
font-size: 1.5rem;
line-height: 2rem;
margin-bottom: 0.25rem;
font-weight: 500;
font-weight: 400;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
@@ -79,9 +77,9 @@
}
&-description {
display: block;
font-size: 1rem;
line-height: 1.5rem;
font-weight: 300;
height: 3rem;
overflow: hidden;
display: -webkit-box;

View File

@@ -6,6 +6,7 @@ import {
Input,
Output,
} from '@angular/core'
import { Router } from '@angular/router'
import { THEME } from '@start9labs/shared'
@Component({
@@ -20,11 +21,12 @@ export class SearchComponent {
@Output()
readonly queryChange = new EventEmitter<string>()
private readonly router = inject(Router)
readonly theme$ = inject(THEME)
onModelChange(query: string) {
this.query = query
this.queryChange.emit(query)
this.router.navigate(['../'])
}
}

View File

@@ -1,18 +1,9 @@
<div class="background-border box-shadow-lg shadow-color-light">
<div class="box-container">
<div class="box-container-title">
<h3 class="small-caps">What's new</h3>
<p *ngIf="pkg.publishedAt as published">
<span class="small-caps">Latest Release</span>
&nbsp;-&nbsp;
<span class="box-container-title-date">
{{ published | date: 'medium' }}
</span>
</p>
</div>
<h2 class="additional-detail-title">What's new</h2>
<div class="box-container-details">
<div class="box-container-details-version">
<p>Version {{ pkg.manifest.version }}</p>
<h3>Version {{ pkg.manifest.version }}</h3>
<p
safeLinks
class="box-container-details-notes"
@@ -20,6 +11,7 @@
></p>
</div>
<button
*ngIf="pkg.versions.length > 2"
tuiButton
type="button"
appearance="secondary"
@@ -38,7 +30,11 @@
class="max-width-lg"
style="max-width: 32rem"
[closeOthers]="false"
*ngFor="let note of notes | keyvalue: asIsOrder"
*ngFor="
let note of notes
| filterVersions: pkg.manifest.version
| keyvalue: asIsOrder
"
>
<tui-accordion-item style="margin: 0.25rem 0">
{{ note.key | displayEmver }}

View File

@@ -5,30 +5,6 @@
display: grid;
grid-auto-flow: row;
align-items: center;
gap: 1.5rem;
&-title {
display: block;
h3 {
font-size: 1.125rem;
line-height: 1.75rem;
font-weight: 700;
}
p {
font-size: 1rem;
line-height: 1.5rem;
font-weight: 300;
margin-bottom: 0.25rem;
color: rgb(212 212 216);
}
&-date {
font-size: 0.875rem;
line-height: 1.25rem;
}
}
&-details {
display: flex;
@@ -37,8 +13,13 @@
gap: 1.5rem;
&-version {
font-size: 1rem;
line-height: 1.5rem;
font-size: 1rem;
h3 {
font-size: 1.2rem;
margin-bottom: 1.25rem;
}
}
&-notes {
@@ -50,10 +31,6 @@
margin-top: 0.75rem;
place-self: end;
// @media (min-width: 640px) {
// place-self: start;
// }
@media (min-width: 768px) {
place-self: start;
}

View File

@@ -3,13 +3,16 @@ import {
Component,
Inject,
Input,
Pipe,
PipeTransform,
} from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { AbstractMarketplaceService } from '../../services/marketplace.service'
import { PolymorpheusContent } from '@tinkoff/ng-polymorpheus'
import { TuiDialogContext, TuiDialogService } from '@taiga-ui/core'
import { MarketplacePkg } from '../../types'
import { Observable } from 'rxjs'
import { Emver } from '@start9labs/shared'
import { KeyValue } from '@angular/common'
@Component({
selector: 'release-notes',
@@ -19,7 +22,7 @@ import { Observable } from 'rxjs'
})
export class ReleaseNotesComponent {
constructor(
private readonly route: ActivatedRoute,
private readonly emver: Emver,
private readonly marketplaceService: AbstractMarketplaceService,
@Inject(TuiDialogService) private readonly dialogs: TuiDialogService,
) {}
@@ -35,8 +38,8 @@ export class ReleaseNotesComponent {
)
}
asIsOrder(a: any, b: any) {
return 0
asIsOrder(a: KeyValue<string, string>, b: KeyValue<string, string>) {
return a.key > b.key ? -1 : b.key > a.key ? 1 : 0
}
async showReleaseNotes(content: PolymorpheusContent<TuiDialogContext>) {
@@ -47,3 +50,17 @@ export class ReleaseNotesComponent {
.subscribe()
}
}
@Pipe({
name: 'filterVersions',
standalone: true,
})
export class FilterVersionsPipe implements PipeTransform {
transform(
notes: Record<string, string>,
pkgVersion: string,
): Record<string, string> {
delete notes[pkgVersion]
return notes
}
}

View File

@@ -8,7 +8,10 @@ import {
import { TuiAccordionModule } from '@taiga-ui/kit'
import { TuiButtonModule, TuiLoaderModule } from '@taiga-ui/core'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
import { ReleaseNotesComponent } from './release-notes.component'
import {
FilterVersionsPipe,
ReleaseNotesComponent,
} from './release-notes.component'
@NgModule({
imports: [
@@ -20,6 +23,7 @@ import { ReleaseNotesComponent } from './release-notes.component'
TuiButtonModule,
TuiAccordionModule,
TuiLoaderModule,
FilterVersionsPipe,
],
declarations: [ReleaseNotesComponent],
exports: [ReleaseNotesComponent],

View File

@@ -1,12 +1,12 @@
<div class="background-border box-shadow-lg shadow-color-light">
<div class="box-container">
<h2 class="additional-detail-title">Description</h2>
<h2 class="additional-detail-title">About</h2>
<p>
{{ pkg.manifest.description.long }}
</p>
<ng-container *ngIf="pkg.manifest.replaces as replaces">
<div *ngIf="replaces.length">
<h2 class="replaces">Intended to replace</h2>
<h2 class="replaces">Intended to replace:</h2>
<tui-tag
*ngFor="let app; index as i; of: replaces"
size="l"

View File

@@ -27,5 +27,10 @@
}
.replaces {
font-weight: 600;
margin: 1.5rem 0 1rem 0;
font-family: 'Montserrat';
font-size: 0.75rem;
font-weight: 300;
letter-spacing: .06rem;
text-transform: uppercase;
}

View File

@@ -0,0 +1,52 @@
import { CommonModule } from '@angular/common'
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { TuiLabelModule, TuiSvgModule } from '@taiga-ui/core'
import { TuiLineClampModule } from '@taiga-ui/kit'
@Component({
selector: 'marketplace-additional-item',
template: `
<div class="item-container">
<label [tuiLabel]="label">
<tui-line-clamp [content]="data" [linesLimit]="1"></tui-line-clamp>
</label>
<tui-svg [src]="icon"></tui-svg>
</div>
`,
styles: [
`
.item-container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem 0.25rem;
&:hover {
background-color: rgb(113 113 122 / 0.1);
}
tui-svg {
opacity: 0.7;
}
}
::ng-deep .t-text {
font-family: 'Montserrat';
font-weight: 600;
}
`,
],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, TuiSvgModule, TuiLineClampModule, TuiLabelModule],
})
export class MarketplaceAdditionalItemComponent {
@Input({ required: true })
label!: string
@Input({ required: true })
icon!: string
@Input({ required: true })
data!: string
}

View File

@@ -0,0 +1,29 @@
import { CommonModule } from '@angular/common'
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { MarketplaceAdditionalItemComponent } from './additional-item.component'
@Component({
selector: 'marketplace-additional-link',
template: `
<a [href]="url" target="_blank" rel="noreferrer">
<marketplace-additional-item
[label]="label"
[icon]="icon"
[data]="url"
></marketplace-additional-item>
</a>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, MarketplaceAdditionalItemComponent],
})
export class MarketplaceAdditionalLinkComponent {
@Input({ required: true })
label!: string
@Input({ required: true })
icon!: string
@Input({ required: true })
url!: string
}

View File

@@ -1,8 +0,0 @@
<a [href]="url" target="_blank" rel="noreferrer">
<div class="link-container">
<label [tuiLabel]="label">
<tui-line-clamp [content]="url" [linesLimit]="1"></tui-line-clamp>
</label>
<tui-svg src="tuiIconExternalLinkLarge"></tui-svg>
</div>
</a>

View File

@@ -1,12 +0,0 @@
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { AdditionalLinkComponent } from './additional-link.component'
import { TuiLabelModule, TuiSvgModule } from '@taiga-ui/core'
import { TuiLineClampModule } from '@taiga-ui/kit'
@NgModule({
imports: [CommonModule, TuiLabelModule, TuiLineClampModule, TuiSvgModule],
declarations: [AdditionalLinkComponent],
exports: [AdditionalLinkComponent],
})
export class AdditionalLinkModule {}

View File

@@ -1,13 +0,0 @@
.link-container {
display: flex;
justify-content: space-between;
align-items: center;
label:hover {
cursor: pointer;
}
tui-svg {
opacity: 0.7;
}
}

View File

@@ -1,16 +0,0 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { Url } from '@start9labs/shared'
@Component({
selector: 'marketplace-additional-link',
templateUrl: 'additional-link.component.html',
styleUrls: ['additional-link.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AdditionalLinkComponent {
@Input({ required: true })
url!: Url
@Input({ required: true })
label!: string
}

View File

@@ -2,92 +2,75 @@
<div class="box-container">
<h2 class="additional-detail-title">Information</h2>
<div class="detail-container">
<!-- release date -->
<marketplace-additional-item
*ngIf="pkg.publishedAt as published"
[data]="(published | date: 'medium')!"
label="Released"
icon=""
></marketplace-additional-item>
<!-- git hash -->
<div
<marketplace-additional-item
*ngIf="pkg.manifest.gitHash as gitHash; else noHash"
(click)="copyService.copy(gitHash)"
[data]="gitHash"
label="Git Hash"
icon="tuiIconCopyLarge"
class="item-copy"
button
detail="false"
class="detail-container-item item-padding item-copy"
(click)="copyService.copy(gitHash)"
>
<label class="git-hash-label" tuiLabel="Git Hash">{{ gitHash }}</label>
<tui-svg src="tuiIconCopyLarge"></tui-svg>
</div>
></marketplace-additional-item>
<ng-template #noHash>
<div class="item-padding">
<label tuiLabel="Git Hash">Unknown</label>
</div>
</ng-template>
<!-- license -->
<div
class="detail-container-item item-padding item-pointer"
<marketplace-additional-item
(click)="presentModalMd('License')"
>
<label tuiLabel="License">
{{ pkg.manifest.license }}
</label>
<tui-svg src="tuiIconChevronRightLarge"></tui-svg>
</div>
[data]="pkg.manifest.license"
label="License"
icon="tuiIconChevronRightLarge"
class="item-pointer"
></marketplace-additional-item>
<!-- instructions -->
<div
class="detail-container-item item-padding item-pointer"
<marketplace-additional-item
(click)="presentModalMd('Instructions')"
>
<label tuiLabel="Instructions">Click to view instructions</label>
<tui-svg src="tuiIconChevronRightLarge"></tui-svg>
</div>
data="Click to view instructions"
label="Instructions"
icon="tuiIconChevronRightLarge"
class="item-pointer"
></marketplace-additional-item>
<!-- versions -->
<div
class="detail-container-item item-padding item-pointer"
(click)="presentAlertVersions(version)"
>
<label tuiLabel="Other versions">Click to view other versions</label>
<tui-svg src="tuiIconChevronRightLarge"></tui-svg>
</div>
<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>
<ng-content></ng-content>
<!-- links -->
<marketplace-additional-link
*ngIf="pkg.manifest.marketingSite"
[url]="pkg.manifest.marketingSite"
label="Marketing Site"
class="item-padding item-pointer"
icon="tuiIconExternalLinkLarge"
class="item-pointer"
></marketplace-additional-link>
<marketplace-additional-link
*ngIf="pkg.manifest.upstreamRepo"
[url]="pkg.manifest.upstreamRepo"
label="Source Repository"
class="item-padding item-pointer"
icon="tuiIconExternalLinkLarge"
class="item-pointer"
></marketplace-additional-link>
<marketplace-additional-link
*ngIf="pkg.manifest.wrapperRepo"
[url]="pkg.manifest.wrapperRepo"
label="Wrapper Repository"
class="item-padding item-pointer"
icon="tuiIconExternalLinkLarge"
class="item-pointer"
></marketplace-additional-link>
<marketplace-additional-link
*ngIf="pkg.manifest.supportSite"
[url]="pkg.manifest.supportSite"
label="Support Site"
class="item-padding item-pointer"
icon="tuiIconExternalLinkLarge"
class="item-pointer"
></marketplace-additional-link>
</div>
</div>

View File

@@ -13,33 +13,26 @@
border-bottom-width: 0px;
border-color: rgb(113 113 122);
}
&-item {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
}
.item {
&-padding {
padding: 0.75rem 0.25rem;
}
.item-pointer:hover {
cursor: pointer;
&-pointer:hover {
::ng-deep label {
cursor: pointer;
background-color: rgb(113 113 122 / 0.1);
}
&-copy:hover {
cursor: copy;
background-color: rgb(113 113 122 / 0.1);
}
}
::ng-deep .t-text {
font-weight: 600;
.item-copy:hover {
cursor: copy;
::ng-deep label {
cursor: copy;
}
}
.item-padding {
padding: 0.75rem 0.25rem;
}
*,
@@ -50,7 +43,3 @@
border-style: solid;
border-color: rgb(var(--tw-color-gray-200) / 1);
}
.git-hash-label {
font-size: 0.73rem;
}

View File

@@ -1,26 +1,13 @@
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
inject,
Input,
Output,
TemplateRef,
} from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import {
TuiAlertService,
TuiDialogContext,
TuiDialogService,
} from '@taiga-ui/core'
import { TuiDialogService } from '@taiga-ui/core'
import { PolymorpheusComponent } from '@tinkoff/ng-polymorpheus'
import {
CopyService,
displayEmver,
Emver,
MarkdownComponent,
} from '@start9labs/shared'
import { filter } from 'rxjs'
import { CopyService, MarkdownComponent } from '@start9labs/shared'
import { MarketplacePkg } from '../../../types'
import { AbstractMarketplaceService } from '../../../services/marketplace.service'
@@ -34,38 +21,16 @@ export class AdditionalComponent {
@Input({ required: true })
pkg!: MarketplacePkg
@Output()
version = new EventEmitter<string>()
readonly displayEmver = displayEmver
private readonly marketplaceService = inject(AbstractMarketplaceService)
constructor(
readonly copyService: CopyService,
private readonly alerts: TuiAlertService,
private readonly dialogs: TuiDialogService,
private readonly emver: Emver,
private readonly route: ActivatedRoute,
) {}
readonly url = this.route.snapshot.queryParamMap.get('url') || undefined
presentAlertVersions(version: TemplateRef<TuiDialogContext>) {
this.dialogs
.open<string>(version, {
label: 'Versions',
size: 's',
data: {
value: this.pkg.manifest.version,
items: this.pkg.versions.sort(
(a, b) => -1 * (this.emver.compare(a, b) || 0),
),
},
})
.pipe(filter(Boolean))
.subscribe(version => this.version.emit(version))
}
presentModalMd(label: string) {
this.dialogs
.open(new PolymorpheusComponent(MarkdownComponent), {

View File

@@ -1,24 +1,17 @@
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { AdditionalComponent } from './additional.component'
import {
TuiRadioListModule,
TuiStringifyContentPipeModule,
} from '@taiga-ui/kit'
import { FormsModule } from '@angular/forms'
import { TuiButtonModule, TuiLabelModule, TuiSvgModule } from '@taiga-ui/core'
import { AdditionalLinkModule } from './additional-link/additional-link.component.module'
import { TuiButtonModule, TuiLabelModule } from '@taiga-ui/core'
import { MarketplaceAdditionalItemComponent } from './additional-item.component'
import { MarketplaceAdditionalLinkComponent } from './additional-link.component'
@NgModule({
imports: [
CommonModule,
TuiRadioListModule,
FormsModule,
TuiStringifyContentPipeModule,
TuiButtonModule,
TuiLabelModule,
AdditionalLinkModule,
TuiSvgModule,
MarketplaceAdditionalItemComponent,
MarketplaceAdditionalLinkComponent,
],
declarations: [AdditionalComponent],
exports: [AdditionalComponent],

View File

@@ -1,22 +0,0 @@
<div class="outer-container">
<div class="inner-container">
<tui-avatar class="dep-img" [src]="pkg.dependencyMetadata[dep.key].icon"></tui-avatar>
<div class="wrapper-margin">
<div class="inner-container-title">
<span>
{{ pkg.dependencyMetadata[dep.key].title || dep.key }}
</span>
<p>
@if (dep.value.optional) {
<span>(optional)</span>
} @else {
<span>(required)</span>
}
</p>
</div>
<span class="inner-container-description">
{{ dep.value.description }}
</span>
</div>
</div>
</div>

View File

@@ -1,63 +0,0 @@
.outer-container {
background-color: rgb(63 63 70 / 0.4);
border-radius: 0.75rem;
padding: 0.75rem 1.25rem;
gap: 0.5rem;
filter: drop-shadow(0 10px 8px rgb(0 0 0 / 0.04))
drop-shadow(0 4px 3px rgb(0 0 0 / 0.1));
&:hover {
background-color: rgb(63 63 70 / 0.7);
}
}
.inner-container {
display: flex;
align-items: center;
gap: 1.5rem;
&-title {
margin-bottom: 0.25rem;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.25rem;
span {
display: block;
font-size: 1rem;
line-height: 1.5rem;
font-weight: 500;
color: rgb(250 250 250 / 0.9);
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
}
&-description {
font-size: 0.875rem;
line-height: 1.25rem;
color: rgb(250 250 250 / 0.7);
height: 2.75rem;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
}
::ng-deep .dep-img {
width: 4rem;
pointer-events: none;
border-radius: 9999px;
object-fit: cover;
filter: drop-shadow(0 10px 8px rgb(0 0 0 / 0.04))
drop-shadow(0 4px 3px rgb(0 0 0 / 0.1));
margin-bottom: 0.75rem;
}
.wrapper-margin {
margin-top: 0.75rem;
}

View File

@@ -1,17 +1,62 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { Dependency, MarketplacePkg } from '../../../types'
import { KeyValue } 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'
@Component({
selector: 'marketplace-dependencies',
templateUrl: 'dependencies.component.html',
styleUrls: ['./dependencies.component.scss'],
template: `
<div class="background-border shadow-color-light box-shadow-lg">
<div class="dependencies-container">
<h2 class="additional-detail-title">Dependencies</h2>
<div class="dependencies-list">
@for (dep of pkg.manifest.dependencies | keyvalue; track $index) {
<marketplace-dep-item
[dep]="dep"
[pkg]="pkg"
(click)="open.emit(dep.key)"
/>
}
</div>
</div>
</div>
`,
styles: [
`
.dependencies-container {
background-color: rgb(39 39 42);
border-radius: 0.75rem;
padding: 1.75rem;
@media (min-width: 1024px) {
grid-column: span 5 / span 5;
}
@media (min-width: 1280px) {
grid-column: span 4 / span 4;
}
}
.dependencies-list {
display: grid;
grid-auto-rows: auto;
gap: 0.75rem;
}
`,
],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, MarketplaceDepItemComponent],
})
export class DependenciesComponent {
export class MarketplaceDependenciesComponent {
@Input({ required: true })
pkg!: MarketplacePkg
@Input({ required: true })
dep!: KeyValue<string, Dependency>
@Output() open = new EventEmitter<string>()
}

View File

@@ -1,12 +0,0 @@
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { RouterModule } from '@angular/router'
import { EmverPipesModule } from '@start9labs/shared'
import { DependenciesComponent } from './dependencies.component'
import { TuiAvatarModule } from '@taiga-ui/experimental'
@NgModule({
imports: [CommonModule, RouterModule, TuiAvatarModule, EmverPipesModule],
declarations: [DependenciesComponent],
exports: [DependenciesComponent],
})
export class DependenciesModule {}

View File

@@ -0,0 +1,133 @@
import { CommonModule, KeyValue } from '@angular/common'
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { EmverPipesModule } from '@start9labs/shared'
import { Dependency, MarketplacePkg } from '../../../types'
import { RouterModule } from '@angular/router'
import { TuiAvatarModule } from '@taiga-ui/experimental'
@Component({
selector: 'marketplace-dep-item',
template: `
<div class="outer-container">
<div class="inner-container">
<tui-avatar class="dep-img" [src]="getImage(dep.key)"></tui-avatar>
<div class="wrapper-margin">
<div class="inner-container-title">
<span>
{{ getTitle(dep.key) }}
</span>
<p>
<ng-container [ngSwitch]="dep.value.optional">
<span *ngSwitchCase="true">(required)</span>
<span *ngSwitchCase="false">(optional)</span>
</ng-container>
</p>
</div>
<span class="inner-container-version">
<!-- {{ dep.value.version | displayEmver }} -->
</span>
<span class="inner-container-description">
{{ dep.value.description }}
</span>
</div>
</div>
</div>
`,
styles: [
`
.outer-container {
background-color: rgb(63 63 70 / 0.4);
border-radius: 0.75rem;
padding: 0.75rem 1.25rem;
gap: 0.5rem;
filter: drop-shadow(0 10px 8px rgb(0 0 0 / 0.04))
drop-shadow(0 4px 3px rgb(0 0 0 / 0.1));
&:hover {
background-color: rgb(63 63 70 / 0.7);
cursor: pointer;
}
}
.inner-container {
display: flex;
align-items: center;
gap: 1.5rem;
}
.inner-container-title {
margin-bottom: 0.25rem;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.25rem;
span {
display: block;
font-size: 1rem;
line-height: 1.5rem;
font-weight: 500;
color: rgb(250 250 250 / 0.9);
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
}
.inner-container-version {
font-size: 0.875rem;
line-height: 1.25rem;
color: rgb(250 250 250 / 0.7);
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
.inner-container-description {
font-size: 0.875rem;
line-height: 1.25rem;
color: rgb(250 250 250 / 0.7);
height: 2.75rem;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
::ng-deep .dep-img {
width: 4rem;
pointer-events: none;
border-radius: 100%;
object-fit: cover;
filter: drop-shadow(0 10px 8px rgb(0 0 0 / 0.04))
drop-shadow(0 4px 3px rgb(0 0 0 / 0.1));
}
.wrapper-margin {
margin-top: 0.75rem;
}
`,
],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, RouterModule, TuiAvatarModule, EmverPipesModule],
})
export class MarketplaceDepItemComponent {
@Input({ required: true })
pkg!: MarketplacePkg
@Input({ required: true })
dep!: KeyValue<string, Dependency>
getImage(key: string): string {
const icon = this.pkg.dependencyMetadata[key]?.icon
// @TODO fix when registry api is updated to include mimetype in icon url
return icon ? `data:image/png;base64,${icon}` : key.substring(0, 2)
}
getTitle(key: string): string {
return this.pkg.dependencyMetadata[key]?.title || key
}
}

View File

@@ -27,6 +27,9 @@ import { MarketplacePkg } from '../../../types'
<h2>
{{ pkg.manifest.title }}
</h2>
<h3>
{{ pkg.manifest.version }}
</h3>
<p>
{{ pkg.manifest.description.short }}
</p>
@@ -42,7 +45,6 @@ import { MarketplacePkg } from '../../../types'
display: flex;
justify-content: center;
margin-top: 2.5rem;
z-index: 0;
@media (min-width: 768px) {
margin-top: 0px;
@@ -53,13 +55,13 @@ import { MarketplacePkg } from '../../../types'
display: flex;
flex-direction: column;
width: 100%;
height: 32vh;
min-height: 32vh;
position: relative;
border-radius: 1.5rem;
padding: 4rem 2rem 0 2rem;
@media (min-width: 376px) {
height: 26vh;
min-height: 26vh;
}
@media (min-width: 768px) {
min-height: 14rem;
@@ -72,6 +74,8 @@ import { MarketplacePkg } from '../../../types'
border-radius: 9999px;
object-fit: cover;
position: absolute;
backdrop-filter: blur(24px);
background-color: rgb(0 0 0 / 0.5);
top: -2.25rem;
left: 1.75rem;
z-index: 1;
@@ -84,20 +88,26 @@ import { MarketplacePkg } from '../../../types'
z-index: 1;
h2 {
font-size: 1.5rem;
line-height: 2rem;
font-weight: 500;
font-size: 2rem;
line-height: 3rem;
font-weight: 400;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
margin-bottom: 0.25rem;
margin-left: -1px;
}
h3 {
font-size: 1.1rem;
font-weight: 400;
margin-bottom: 1rem;
}
p {
display: block;
font-size: 1rem;
line-height: 1.5rem;
font-weight: 300;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
@@ -123,7 +133,7 @@ import { MarketplacePkg } from '../../../types'
width: 200%;
height: 200%;
max-width: 200%;
filter: blur(100px) saturate(1.5);
filter: blur(100px);
}
}

View File

@@ -38,7 +38,7 @@ import { PolymorpheusContent } from '@tinkoff/ng-polymorpheus'
*tuiItem
draggable="false"
[class.item_active]="i === index + 1"
class="screenshot-item box-shadow-lg"
class="screenshot-item"
>
<img
#template
@@ -93,9 +93,6 @@ import { PolymorpheusContent } from '@tinkoff/ng-polymorpheus'
}
.screenshot-item {
--tw-shadow-color: rgb(161 161 170 / 0.1);
--tw-shadow: var(--tw-shadow-colored);
object-fit: cover;
overflow: hidden;
border-radius: 0.5rem;

View File

@@ -12,10 +12,12 @@ export * from './pages/release-notes/release-notes.component'
export * from './pages/release-notes/release-notes.module'
export * from './pages/show/about/about.component'
export * from './pages/show/about/about.module'
export * from './pages/show/additional/additional-link.component'
export * from './pages/show/additional/additional-item.component'
export * from './pages/show/additional/additional.component'
export * from './pages/show/additional/additional.module'
export * from './pages/show/dependencies/dependencies.component'
export * from './pages/show/dependencies/dependencies.module'
export * from './pages/show/dependencies/dependency-item.component'
export * from './pages/show/screenshots/screenshots.component'
export * from './pages/show/hero/hero.component'

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,6 +1,6 @@
{
"name": "@start9labs/shared",
"version": "0.3.9",
"version": "0.3.12",
"peerDependencies": {
"@angular/common": "^17.0.6",
"@angular/core": "^17.0.6",

View File

@@ -1,3 +1,163 @@
@font-face {
font-family: 'text-security-disc';
src: url('/assets/fonts/text-security-disc.woff2') format('woff2');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: normal;
src: url('/assets/fonts/Montserrat/Montserrat-Regular.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: bold;
src: url('/assets/fonts/Montserrat/Montserrat-Bold.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: thin;
src: url('/assets/fonts/Montserrat/Montserrat-Light.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 900;
src: url('/assets/fonts/Montserrat/Montserrat-Black.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 800;
src: url('/assets/fonts/Montserrat/Montserrat-ExtraBold.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: url('/assets/fonts/Montserrat/Montserrat-Bold.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 600;
src: url('/assets/fonts/Montserrat/Montserrat-SemiBold.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
src: url('/assets/fonts/Montserrat/Montserrat-Medium.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: url('/assets/fonts/Montserrat/Montserrat-Regular.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 300;
src: url('/assets/fonts/Montserrat/Montserrat-Light.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 200;
src: url('/assets/fonts/Montserrat/Montserrat-ExtraLight.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 100;
src: url('/assets/fonts/Montserrat/Montserrat-Thin.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: normal;
src: url('/assets/fonts/Open_Sans/OpenSans-Regular.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: bold;
src: url('/assets/fonts/Open_Sans/OpenSans-Bold.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: thin;
src: url('/assets/fonts/Open_Sans/OpenSans-Light.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 800;
src: url('/assets/fonts/Open_Sans/OpenSans-ExtraBold.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
src: url('/assets/fonts/Open_Sans/OpenSans-Bold.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 600;
src: url('/assets/fonts/Open_Sans/OpenSans-SemiBold.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: url('/assets/fonts/Open_Sans/OpenSans-Regular.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 300;
src: url('/assets/fonts/Open_Sans/OpenSans-Light.ttf');
}
@font-face {
font-family: 'Courier New';
font-style: normal;
font-weight: normal;
src: url('/assets/fonts/Courier_New/CourierNew-Regular.ttf');
}
@font-face {
font-family: 'Courier New';
font-style: normal;
font-weight: bold;
src: url('/assets/fonts/Courier_New/CourierNew-Bold.ttf');
}
$wide-modal: 900px;
body {
@@ -199,11 +359,13 @@ a {
}
.additional-detail-title {
font-size: 1.125rem;
font-family: 'Montserrat';
font-size: 0.85rem;
line-height: 1.75rem;
font-weight: 700;
padding-bottom: 0.75rem;
font-variant: all-small-caps;
font-weight: 300;
text-transform: uppercase;
letter-spacing: .06rem;
margin-bottom: 1rem;
}
.buttons {

View File

@@ -51,8 +51,8 @@ import { MarketplaceSidebarsComponent } from './components/sidebars.component'
max-height: 100%;
overflow: auto;
// TODO: Theme
background: #18181b url('/assets/img/background.png') no-repeat top
right;
background: #18181b url('/assets/img/background_marketplace.png')
no-repeat top right;
}
::ng-deep menu {

View File

@@ -2,21 +2,31 @@ import { CommonModule } from '@angular/common'
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
inject,
Input,
Output,
TemplateRef,
} from '@angular/core'
import {
AboutModule,
AbstractMarketplaceService,
AdditionalModule,
DependenciesModule,
MarketplaceAdditionalItemComponent,
MarketplaceDependenciesComponent,
MarketplacePackageHeroComponent,
MarketplacePkg,
ReleaseNotesModule,
} from '@start9labs/marketplace'
import { SharedPipesModule } from '@start9labs/shared'
import { displayEmver, Emver, SharedPipesModule } from '@start9labs/shared'
import { TuiButtonModule } from '@taiga-ui/experimental'
import { map } from 'rxjs'
import { filter, map } from 'rxjs'
import { TuiDialogContext, TuiDialogService } from '@taiga-ui/core'
import {
TuiRadioListModule,
TuiStringifyContentPipeModule,
} from '@taiga-ui/kit'
import { FormsModule } from '@angular/forms'
import { Router } from '@angular/router'
@Component({
@@ -41,26 +51,45 @@ import { Router } from '@angular/router'
<div class="inner-container">
<marketplace-about [pkg]="pkg" />
@if (!(pkg.manifest.dependencies | empty)) {
<div class="background-border shadow-color-light box-shadow-lg">
<div class="dependencies-container">
<h2>Dependencies</h2>
<div class="dependencies-list">
@for (
dep of pkg.manifest.dependencies | keyvalue;
track $index
) {
<marketplace-dependencies
[dep]="dep"
[pkg]="pkg"
(click)="open(dep.key)"
/>
}
</div>
</div>
</div>
<marketplace-dependencies
[pkg]="pkg"
(open)="open($event)"
></marketplace-dependencies>
}
<release-notes [pkg]="pkg" />
<marketplace-additional class="additional-wrapper" [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>
`,
@@ -83,36 +112,6 @@ import { Router } from '@angular/router'
column-gap: 2rem;
}
.dependencies {
&-container {
background-color: rgb(39 39 42);
border-radius: 0.75rem;
padding: 1.75rem;
@media (min-width: 1024px) {
grid-column: span 5 / span 5;
}
@media (min-width: 1280px) {
grid-column: span 4 / span 4;
}
h2 {
font-size: 1.125rem;
line-height: 1.75rem;
font-weight: 700;
margin: 0.5rem 0;
padding-bottom: 0.75rem;
font-variant: all-small-caps;
}
}
&-list {
display: grid;
grid-auto-rows: auto;
gap: 0.75rem;
}
}
.additional-wrapper {
margin-top: 1.5rem;
}
@@ -124,24 +123,52 @@ import { Router } from '@angular/router'
CommonModule,
MarketplacePackageHeroComponent,
TuiButtonModule,
DependenciesModule,
MarketplaceDependenciesComponent,
ReleaseNotesModule,
AdditionalModule,
AboutModule,
SharedPipesModule,
FormsModule,
TuiStringifyContentPipeModule,
MarketplaceAdditionalItemComponent,
TuiRadioListModule,
],
})
export class MarketplacePreviewComponent {
private readonly router = inject(Router)
@Input({ required: true })
pkg!: MarketplacePkg
@Output()
version = new EventEmitter<string>()
readonly displayEmver = displayEmver
private readonly router = inject(Router)
readonly url$ = inject(AbstractMarketplaceService)
.getSelectedHost$()
.pipe(map(({ url }) => url))
constructor(
private readonly dialogs: TuiDialogService,
private readonly emver: Emver,
) {}
open(id: string) {
this.router.navigate([], { queryParams: { id } })
}
presentAlertVersions(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(
(a, b) => -1 * (this.emver.compare(a, b) || 0),
),
},
})
.pipe(filter(Boolean))
.subscribe(version => this.version.emit(version))
}
}

View File

@@ -4,7 +4,7 @@ import { Router, RouterLink } from '@angular/router'
import {
AboutModule,
AdditionalModule,
DependenciesModule,
MarketplaceDependenciesComponent,
MarketplacePackageHeroComponent,
MarketplacePkg,
} from '@start9labs/marketplace'
@@ -27,13 +27,13 @@ import { getManifest } from 'src/app/util/get-package-data'
@Component({
selector: 'sideload-package',
template: `
<div class="grid gap-8 mb-16 p-4 lg:px-16 lg:pb-8 pt-14 justify-center">
<div class="outer-container">
<ng-content />
<marketplace-package-hero
*tuiLet="button$ | async as button"
[pkg]="package"
>
<div class="flex justify-start">
<div class="inner-container">
<a
*ngIf="button !== null && button !== 'Install'"
tuiButton
@@ -48,22 +48,32 @@ import { getManifest } from 'src/app/util/get-package-data'
</div>
</marketplace-package-hero>
<marketplace-about [pkg]="package" />
<div
*ngIf="!(package.manifest.dependencies | empty)"
class="rounded-xl bg-gradient-to-bl from-zinc-400/75 to-zinc-600 p-px shadow-lg shadow-zinc-400/10"
>
<div class="lg:col-span-5 xl:col-span-4 bg-zinc-800 rounded-xl p-7">
<h2 class="text-lg font-bold small-caps my-2 pb-3">Dependencies</h2>
<div class="grid grid-row-auto gap-3">
<div *ngFor="let dep of package.manifest.dependencies | keyvalue">
<marketplace-dependencies [dep]="dep" [pkg]="package" />
</div>
</div>
</div>
</div>
@if (!(package.manifest.dependencies | empty)) {
<marketplace-dependencies [pkg]="package" (open)="open($event)" />
}
<marketplace-additional [pkg]="package" />
</div>
`,
styles: [
`
.outer-container {
display: grid;
justify-content: center;
gap: 2rem;
padding: 2.5rem 1rem 1rem 1rem;
margin-bottom: 4rem;
@media (min-width: 1024px) {
padding: 2.5rem 4rem 2rem 4rem;
}
}
.inner-container {
display: flex;
justify-content: flex-start;
}
`,
],
standalone: true,
imports: [
CommonModule,
@@ -74,7 +84,7 @@ import { getManifest } from 'src/app/util/get-package-data'
TuiButtonModule,
TuiLetModule,
MarketplacePackageHeroComponent,
DependenciesModule,
MarketplaceDependenciesComponent,
],
})
export class SideloadPackageComponent {
@@ -140,4 +150,8 @@ export class SideloadPackageComponent {
loader.unsubscribe()
}
}
open(id: string) {
this.router.navigate(['/marketplace'], { queryParams: { id } })
}
}

View File

@@ -1,72 +1,5 @@
@import '@taiga-ui/core/styles/taiga-ui-local';
@font-face {
font-family: 'text-security-disc';
src: url('/assets/fonts/text-security-disc.woff2') format('woff2');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: normal;
src: url('/assets/fonts/Montserrat/Montserrat-Regular.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: bold;
src: url('/assets/fonts/Montserrat/Montserrat-Bold.ttf');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: thin;
src: url('/assets/fonts/Montserrat/Montserrat-Light.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: normal;
src: url('/assets/fonts/Open_Sans/OpenSans-Regular.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 600;
src: url('/assets/fonts/Open_Sans/OpenSans-SemiBold.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: bold;
src: url('/assets/fonts/Open_Sans/OpenSans-Bold.ttf');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: thin;
src: url('/assets/fonts/Open_Sans/OpenSans-Light.ttf');
}
@font-face {
font-family: 'Courier New';
font-style: normal;
font-weight: normal;
src: url('/assets/fonts/Courier_New/CourierNew-Regular.ttf');
}
@font-face {
font-family: 'Courier New';
font-style: normal;
font-weight: bold;
src: url('/assets/fonts/Courier_New/CourierNew-Bold.ttf');
}
@import '@start9labs/shared/styles/shared.scss';
/** Ionic CSS Variables overrides **/
:root {