mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
chore: address comments
This commit is contained in:
@@ -9,13 +9,10 @@ import {
|
||||
} from '@taiga-ui/core'
|
||||
import { TuiButtonModule, TuiIconModule } from '@taiga-ui/experimental'
|
||||
import { TUI_PROMPT, TuiPromptData } from '@taiga-ui/kit'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { filter } from 'rxjs'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { AuthService } from 'src/app/services/auth.service'
|
||||
import { ABOUT } from './about.component'
|
||||
import { getAllPackages } from 'src/app/utils/get-package-data'
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { HeaderConnectionComponent } from './connection.component'
|
||||
|
||||
@Component({
|
||||
@@ -114,7 +111,6 @@ export class HeaderMenuComponent {
|
||||
private readonly errorService = inject(ErrorService)
|
||||
private readonly loader = inject(LoadingService)
|
||||
private readonly auth = inject(AuthService)
|
||||
private readonly patch = inject(PatchDB<DataModel>)
|
||||
private readonly dialogs = inject(TuiDialogService)
|
||||
|
||||
readonly links = [
|
||||
@@ -136,10 +132,6 @@ export class HeaderMenuComponent {
|
||||
]
|
||||
|
||||
readonly system = [
|
||||
{
|
||||
icon: 'tuiIconTool',
|
||||
action: 'System Rebuild',
|
||||
},
|
||||
{
|
||||
icon: 'tuiIconRefreshCw',
|
||||
action: 'Restart',
|
||||
@@ -159,20 +151,17 @@ export class HeaderMenuComponent {
|
||||
this.auth.setUnverified()
|
||||
}
|
||||
|
||||
async prompt(action: keyof typeof METHODS) {
|
||||
const minutes =
|
||||
action === 'System Rebuild'
|
||||
? Object.keys(await getAllPackages(this.patch)).length * 2
|
||||
: ''
|
||||
|
||||
async prompt(action: 'Restart' | 'Shutdown') {
|
||||
this.dialogs
|
||||
.open(TUI_PROMPT, getOptions(action, minutes))
|
||||
.open(TUI_PROMPT, getOptions(action))
|
||||
.pipe(filter(Boolean))
|
||||
.subscribe(async () => {
|
||||
const loader = this.loader.open(`Beginning ${action}...`).subscribe()
|
||||
|
||||
try {
|
||||
await this.api[METHODS[action]]({})
|
||||
await this.api[
|
||||
action === 'Restart' ? 'restartServer' : 'shutdownServer'
|
||||
]({})
|
||||
} catch (e: any) {
|
||||
this.errorService.handleError(e)
|
||||
} finally {
|
||||
@@ -182,19 +171,11 @@ export class HeaderMenuComponent {
|
||||
}
|
||||
}
|
||||
|
||||
const METHODS = {
|
||||
Restart: 'restartServer',
|
||||
Shutdown: 'shutdownServer',
|
||||
'System Rebuild': 'systemRebuild',
|
||||
} as const
|
||||
|
||||
function getOptions(
|
||||
key: keyof typeof METHODS,
|
||||
minutes: unknown,
|
||||
operation: 'Restart' | 'Shutdown',
|
||||
): Partial<TuiDialogOptions<TuiPromptData>> {
|
||||
switch (key) {
|
||||
case 'Restart':
|
||||
return {
|
||||
return operation === 'Restart'
|
||||
? {
|
||||
label: 'Restart',
|
||||
size: 's',
|
||||
data: {
|
||||
@@ -204,8 +185,7 @@ function getOptions(
|
||||
no: 'Cancel',
|
||||
},
|
||||
}
|
||||
case 'Shutdown':
|
||||
return {
|
||||
: {
|
||||
label: 'Warning',
|
||||
size: 's',
|
||||
data: {
|
||||
@@ -215,15 +195,4 @@ function getOptions(
|
||||
no: 'Cancel',
|
||||
},
|
||||
}
|
||||
default:
|
||||
return {
|
||||
label: 'Warning',
|
||||
size: 's',
|
||||
data: {
|
||||
content: `This action will tear down all service containers and rebuild them from scratch. No data will be deleted. This action is useful if your system gets into a bad state, and it should only be performed if you are experiencing general performance or reliability issues. It may take up to ${minutes} minutes to complete. During this time, you will lose all connectivity to your server.`,
|
||||
yes: 'Rebuild',
|
||||
no: 'Cancel',
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
inject,
|
||||
Input,
|
||||
} from '@angular/core'
|
||||
import { RouterLink } from '@angular/router'
|
||||
import { WINDOW } from '@ng-web-apis/common'
|
||||
import { TuiIconModule } from '@taiga-ui/experimental'
|
||||
import { Breadcrumb } from 'src/app/services/breadcrumbs.service'
|
||||
|
||||
@@ -7,8 +13,12 @@ import { Breadcrumb } from 'src/app/services/breadcrumbs.service'
|
||||
standalone: true,
|
||||
selector: '[headerMobile]',
|
||||
template: `
|
||||
@if (headerMobile?.length) {
|
||||
<a [routerLink]="back" [style.padding.rem]="0.75">
|
||||
@if (headerMobile && headerMobile.length > 1) {
|
||||
<a
|
||||
[routerLink]="back"
|
||||
[style.padding.rem]="0.75"
|
||||
[queryParams]="queryParams"
|
||||
>
|
||||
<tui-icon icon="tuiIconArrowLeft" />
|
||||
</a>
|
||||
}
|
||||
@@ -46,6 +56,11 @@ import { Breadcrumb } from 'src/app/services/breadcrumbs.service'
|
||||
.title {
|
||||
@include text-overflow();
|
||||
max-width: calc(100% - 5rem);
|
||||
text-transform: capitalize;
|
||||
|
||||
&:first-child {
|
||||
margin-inline-start: 1rem;
|
||||
}
|
||||
}
|
||||
`,
|
||||
],
|
||||
@@ -53,10 +68,15 @@ import { Breadcrumb } from 'src/app/services/breadcrumbs.service'
|
||||
imports: [TuiIconModule, RouterLink],
|
||||
})
|
||||
export class HeaderMobileComponent {
|
||||
private readonly win = inject(WINDOW)
|
||||
|
||||
@Input() headerMobile: readonly Breadcrumb[] | null = []
|
||||
|
||||
get title() {
|
||||
return this.headerMobile?.[this.headerMobile?.length - 1]?.title || ''
|
||||
return (
|
||||
this.headerMobile?.[this.headerMobile?.length - 1]?.title ||
|
||||
(this.win.location.search ? 'Utilities' : 'Services')
|
||||
)
|
||||
}
|
||||
|
||||
get back() {
|
||||
@@ -65,4 +85,8 @@ export class HeaderMobileComponent {
|
||||
'/portal/dashboard'
|
||||
)
|
||||
}
|
||||
|
||||
get queryParams() {
|
||||
return this.back === '/portal/dashboard' ? { tab: 'utilities' } : null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,10 +24,8 @@ import { NotificationService } from 'src/app/services/notification.service'
|
||||
<a
|
||||
tuiTabBarItem
|
||||
icon="tuiIconActivity"
|
||||
routerLink="/portal/dashboard"
|
||||
routerLink="/portal/system/metrics"
|
||||
routerLinkActive
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
[queryParams]="{ tab: 'metrics' }"
|
||||
>
|
||||
Metrics
|
||||
</a>
|
||||
@@ -58,7 +56,9 @@ import { NotificationService } from 'src/app/services/notification.service'
|
||||
display: none;
|
||||
// TODO: Theme
|
||||
--tui-elevation-01: #333;
|
||||
--tui-base-01: #fff;
|
||||
--tui-base-04: var(--tui-clear);
|
||||
--tui-error-fill: #f52222;
|
||||
backdrop-filter: blur(1rem);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ import { getManifest } from 'src/app/utils/get-package-data'
|
||||
:host {
|
||||
padding: 0;
|
||||
border: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
:host-context(tui-root._mobile) {
|
||||
|
||||
@@ -176,7 +176,8 @@ import { TimeService } from 'src/app/services/time.service'
|
||||
|
||||
section {
|
||||
flex-wrap: wrap;
|
||||
padding: 1rem;
|
||||
padding: 0;
|
||||
margin: 1rem -1rem;
|
||||
}
|
||||
|
||||
aside {
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
Component,
|
||||
inject,
|
||||
Input,
|
||||
OnChanges,
|
||||
} from '@angular/core'
|
||||
import { RouterLink } from '@angular/router'
|
||||
import { tuiPure } from '@taiga-ui/cdk'
|
||||
@@ -19,7 +20,7 @@ import { getManifest } from 'src/app/utils/get-package-data'
|
||||
selector: 'tr[appService]',
|
||||
template: `
|
||||
<td [style.grid-area]="'1 / 1 / 4'">
|
||||
<a [routerLink]="routerLink"><img alt="logo" [src]="pkg.icon" /></a>
|
||||
<img alt="logo" [src]="pkg.icon" />
|
||||
</td>
|
||||
<td [style.grid-area]="'1 / 2'">
|
||||
<a [routerLink]="routerLink">{{ manifest.title }}</a>
|
||||
@@ -36,11 +37,25 @@ import { getManifest } from 'src/app/utils/get-package-data'
|
||||
appControls
|
||||
[disabled]="!installed || !(connected$ | async)"
|
||||
[pkg]="pkg"
|
||||
(click.stop)="(0)"
|
||||
></fieldset>
|
||||
</td>
|
||||
`,
|
||||
styles: `
|
||||
@import '@taiga-ui/core/styles/taiga-ui-local';
|
||||
|
||||
:host {
|
||||
@include transition(background);
|
||||
clip-path: inset(0 round 0.5rem);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: var(--tui-clear);
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
height: 2rem;
|
||||
width: 2rem;
|
||||
border-radius: 100%;
|
||||
@@ -80,10 +95,13 @@ import { getManifest } from 'src/app/utils/get-package-data'
|
||||
}
|
||||
}
|
||||
`,
|
||||
hostDirectives: [RouterLink],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [RouterLink, AsyncPipe, StatusComponent, ControlsComponent],
|
||||
})
|
||||
export class ServiceComponent {
|
||||
export class ServiceComponent implements OnChanges {
|
||||
private readonly link = inject(RouterLink)
|
||||
|
||||
@Input()
|
||||
pkg!: PackageDataEntry
|
||||
|
||||
@@ -104,6 +122,10 @@ export class ServiceComponent {
|
||||
return `/portal/service/${this.manifest.id}`
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
this.link.routerLink = this.routerLink
|
||||
}
|
||||
|
||||
@tuiPure
|
||||
hasError(errors: PkgDependencyErrors = {}): boolean {
|
||||
return Object.values(errors).some(Boolean)
|
||||
|
||||
@@ -19,9 +19,7 @@ import { DepErrorService } from 'src/app/services/dep-error.service'
|
||||
<th>Name</th>
|
||||
<th>Version</th>
|
||||
<th [style.width.rem]="13">Status</th>
|
||||
<th [style.width.rem]="8" [style.text-align]="'center'">
|
||||
Controls
|
||||
</th>
|
||||
<th [style.width.rem]="8" [style.text-indent.rem]="1">Controls</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
@@ -9,8 +9,9 @@ import { LogsComponent } from '../../../components/logs/logs.component'
|
||||
@Component({
|
||||
template: `
|
||||
<tui-select
|
||||
tuiTextfieldAppearance="unstyled"
|
||||
tuiTextfieldAppearance="secondary"
|
||||
tuiTextfieldSize="m"
|
||||
[style.max-width.rem]="26"
|
||||
[(ngModel)]="logs"
|
||||
>
|
||||
{{ subtitle }}
|
||||
@@ -50,7 +51,7 @@ import { LogsComponent } from '../../../components/logs/logs.component'
|
||||
}
|
||||
|
||||
logs {
|
||||
height: calc(100% - 4rem);
|
||||
height: calc(100% - 5rem);
|
||||
}
|
||||
`,
|
||||
],
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { AsyncPipe } from '@angular/common'
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
|
||||
import { MetricsComponent } from 'src/app/routes/portal/routes/dashboard/metrics.component'
|
||||
import { MetricsService } from 'src/app/services/metrics.service'
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<app-metrics [metrics]="metrics$ | async" />
|
||||
`,
|
||||
host: { class: 'g-page' },
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [MetricsComponent, AsyncPipe],
|
||||
})
|
||||
export default class SystemMetricsComponent {
|
||||
readonly metrics$ = inject(MetricsService)
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import { RouterLink } from '@angular/router'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { tuiPure } from '@taiga-ui/cdk'
|
||||
import { TuiSvgModule } from '@taiga-ui/core'
|
||||
import { TuiLinkModule, TuiSvgModule } from '@taiga-ui/core'
|
||||
import { TuiLineClampModule } from '@taiga-ui/kit'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { first, Observable } from 'rxjs'
|
||||
@@ -20,10 +20,10 @@ import { toRouterLink } from 'src/app/utils/to-router-link'
|
||||
@Component({
|
||||
selector: '[notificationItem]',
|
||||
template: `
|
||||
<td><ng-content /></td>
|
||||
<td [style.padding-top.rem]="0.4"><ng-content /></td>
|
||||
<td>{{ notificationItem.createdAt | date: 'MMM d, y, h:mm a' }}</td>
|
||||
<td [style.color]="color">
|
||||
<tui-svg [style.color]="color" [src]="icon"></tui-svg>
|
||||
<tui-svg [src]="icon" />
|
||||
{{ notificationItem.title }}
|
||||
</td>
|
||||
<td>
|
||||
@@ -43,20 +43,44 @@ import { toRouterLink } from 'src/app/utils/to-router-link'
|
||||
[content]="notificationItem.message"
|
||||
(overflownChange)="overflow = $event"
|
||||
/>
|
||||
<a *ngIf="overflow" (click)="service.viewFull(notificationItem)">
|
||||
<button
|
||||
*ngIf="overflow"
|
||||
tuiLink
|
||||
(click)="service.viewFull(notificationItem)"
|
||||
>
|
||||
View Full
|
||||
</a>
|
||||
<a
|
||||
</button>
|
||||
<button
|
||||
*ngIf="notificationItem.code === 1"
|
||||
tuiLink
|
||||
(click)="service.viewReport(notificationItem)"
|
||||
>
|
||||
View Report
|
||||
</a>
|
||||
</button>
|
||||
</td>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [CommonModule, RouterLink, TuiLineClampModule, TuiSvgModule],
|
||||
host: {
|
||||
'[class._new]': '!notificationItem.read',
|
||||
},
|
||||
styles: `
|
||||
:host._new {
|
||||
background: var(--tui-clear);
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.25rem;
|
||||
vertical-align: top;
|
||||
}
|
||||
`,
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterLink,
|
||||
TuiLineClampModule,
|
||||
TuiSvgModule,
|
||||
TuiLinkModule,
|
||||
],
|
||||
})
|
||||
export class NotificationItemComponent {
|
||||
private readonly patch = inject(PatchDB<DataModel>)
|
||||
|
||||
@@ -14,25 +14,24 @@ import { NotificationsTableComponent } from './table.component'
|
||||
template: `
|
||||
<ng-container *tuiLet="notifications$ | async as notifications">
|
||||
<h3 class="g-title">
|
||||
Notifications
|
||||
<ng-container *ngIf="table.selected$ | async as selected">
|
||||
<tui-hosted-dropdown
|
||||
tuiDropdownAlign="right"
|
||||
[content]="dropdown"
|
||||
[sided]="true"
|
||||
[(open)]="open"
|
||||
<tui-hosted-dropdown
|
||||
*ngIf="table.selected$ | async as selected"
|
||||
tuiDropdownAlign="right"
|
||||
[content]="dropdown"
|
||||
[sided]="true"
|
||||
[(open)]="open"
|
||||
[canOpen]="!!selected.length"
|
||||
>
|
||||
<button
|
||||
appearance="primary"
|
||||
iconRight="tuiIconChevronDown"
|
||||
tuiButton
|
||||
size="xs"
|
||||
type="button"
|
||||
[disabled]="!selected.length"
|
||||
>
|
||||
<button
|
||||
appearance="primary"
|
||||
iconRight="tuiIconChevronDown"
|
||||
tuiButton
|
||||
size="xs"
|
||||
type="button"
|
||||
[disabled]="!selected.length"
|
||||
>
|
||||
Batch Action
|
||||
</button>
|
||||
</tui-hosted-dropdown>
|
||||
Batch Action
|
||||
</button>
|
||||
<ng-template #dropdown>
|
||||
<tui-data-list>
|
||||
<button tuiOption (click)="markSeen(notifications!, selected)">
|
||||
@@ -46,7 +45,7 @@ import { NotificationsTableComponent } from './table.component'
|
||||
</button>
|
||||
</tui-data-list>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</tui-hosted-dropdown>
|
||||
</h3>
|
||||
<table #table class="g-table" [notifications]="notifications"></table>
|
||||
</ng-container>
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
import { CommonModule } from '@angular/common'
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
Input,
|
||||
OnChanges,
|
||||
} from '@angular/core'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { TuiCheckboxModule } from '@taiga-ui/experimental'
|
||||
import { TuiLineClampModule } from '@taiga-ui/kit'
|
||||
import { BehaviorSubject } from 'rxjs'
|
||||
import {
|
||||
ServerNotification,
|
||||
ServerNotifications,
|
||||
} from 'src/app/services/api/api.types'
|
||||
import { TuiForModule } from '@taiga-ui/cdk'
|
||||
import { BehaviorSubject } from 'rxjs'
|
||||
import { TuiLineClampModule } from '@taiga-ui/kit'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { NotificationItemComponent } from './item.component'
|
||||
import { TuiCheckboxModule } from '@taiga-ui/experimental'
|
||||
|
||||
@Component({
|
||||
selector: 'table[notifications]',
|
||||
@@ -39,39 +37,40 @@ import { TuiCheckboxModule } from '@taiga-ui/experimental'
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
*ngFor="let notification of notifications; else: loading; empty: blank"
|
||||
[notificationItem]="notification"
|
||||
[style.font-weight]="notification.read ? 'normal' : 'bold'"
|
||||
>
|
||||
<input
|
||||
tuiCheckbox
|
||||
size="s"
|
||||
type="checkbox"
|
||||
[style.display]="'block'"
|
||||
[ngModel]="selected$.value.includes(notification)"
|
||||
(ngModelChange)="handleToggle(notification)"
|
||||
/>
|
||||
</tr>
|
||||
<ng-template #blank>
|
||||
<tr>
|
||||
<td colspan="5">You have no notifications</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
<ng-template #loading>
|
||||
<tr *ngFor="let row of ['', '']">
|
||||
<td colspan="5"><div class="tui-skeleton">Loading</div></td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
@if (notifications) {
|
||||
@for (notification of notifications; track $index) {
|
||||
<tr
|
||||
[notificationItem]="notification"
|
||||
[style.font-weight]="notification.read ? 'normal' : 'bold'"
|
||||
>
|
||||
<input
|
||||
tuiCheckbox
|
||||
size="s"
|
||||
type="checkbox"
|
||||
[style.display]="'block'"
|
||||
[ngModel]="selected$.value.includes(notification)"
|
||||
(ngModelChange)="handleToggle(notification)"
|
||||
/>
|
||||
</tr>
|
||||
} @empty {
|
||||
<tr>
|
||||
<td colspan="5">You have no notifications</td>
|
||||
</tr>
|
||||
}
|
||||
} @else {
|
||||
@for (row of ['', '']; track $index) {
|
||||
<tr>
|
||||
<td colspan="5"><div class="tui-skeleton">Loading</div></td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
TuiForModule,
|
||||
TuiCheckboxModule,
|
||||
FormsModule,
|
||||
TuiCheckboxModule,
|
||||
TuiLineClampModule,
|
||||
NotificationItemComponent,
|
||||
],
|
||||
|
||||
@@ -27,9 +27,16 @@ import { SettingBtn } from '../settings.types'
|
||||
<tui-icon *ngIf="button.routerLink" icon="tuiIconChevronRight" />
|
||||
</ng-template>
|
||||
`,
|
||||
styles: [
|
||||
':host:not(:last-child) { display: block; box-shadow: 0 1px var(--tui-clear); }',
|
||||
],
|
||||
styles: `
|
||||
:host:not(:last-child) {
|
||||
display: block;
|
||||
box-shadow: 0 1px var(--tui-clear);
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [CommonModule, TuiIconModule, TuiTitleModule, RouterLink],
|
||||
|
||||
@@ -51,7 +51,6 @@ import { SettingsUpdateComponent } from './update.component'
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
padding-top: 1rem;
|
||||
}
|
||||
`,
|
||||
],
|
||||
|
||||
@@ -47,10 +47,20 @@ import { UPDATE } from '../modals/update.component'
|
||||
</div>
|
||||
</button>
|
||||
`,
|
||||
styles: [
|
||||
':host { display: block; box-shadow: 0 1px var(--tui-clear); }',
|
||||
'.small { width: 1rem; height: 1rem; }',
|
||||
],
|
||||
styles: `
|
||||
:host {
|
||||
display: block;
|
||||
box-shadow: 0 1px var(--tui-clear);
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-size: 1rem;
|
||||
}
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [CommonModule, TuiIconModule, TuiTitleModule],
|
||||
|
||||
@@ -9,44 +9,29 @@ import { SettingsMenuComponent } from './components/menu.component'
|
||||
routerLink="/portal/system/settings"
|
||||
routerLinkActive="_current"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<tui-icon icon="tuiIconChevronLeft" />
|
||||
Settings
|
||||
</a>
|
||||
<settings-menu class="page" />
|
||||
></a>
|
||||
<settings-menu />
|
||||
<router-outlet />
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
:host {
|
||||
padding-top: 1rem;
|
||||
|
||||
::ng-deep tui-notification {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin: 1rem 0;
|
||||
font-size: 1rem;
|
||||
color: var(--tui-text-01);
|
||||
}
|
||||
|
||||
._current {
|
||||
a,
|
||||
settings-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page {
|
||||
display: none;
|
||||
}
|
||||
|
||||
._current + .page {
|
||||
._current + settings-menu {
|
||||
display: flex;
|
||||
max-width: 45rem;
|
||||
max-width: 30rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
`,
|
||||
|
||||
@@ -48,6 +48,12 @@ const ROUTES: Routes = [
|
||||
loadComponent: () => import('./updates/updates.component'),
|
||||
data: toNavigationItem('/portal/system/updates'),
|
||||
},
|
||||
{
|
||||
title: systemTabResolver,
|
||||
path: 'metrics',
|
||||
loadComponent: () => import('./metrics/metrics.component'),
|
||||
data: toNavigationItem('/portal/system/metrics'),
|
||||
},
|
||||
]
|
||||
|
||||
@NgModule({ imports: [RouterModule.forChild(ROUTES)] })
|
||||
|
||||
@@ -43,7 +43,9 @@ import { hasCurrentDeps } from 'src/app/utils/has-deps'
|
||||
template: `
|
||||
<tui-accordion-item borders="top-bottom">
|
||||
<div class="g-action">
|
||||
<tui-avatar size="s" [src]="marketplacePkg" />
|
||||
<tui-avatar size="s">
|
||||
<img alt="" [src]="marketplacePkg.icon" />
|
||||
</tui-avatar>
|
||||
<div [style.flex]="1" [style.overflow]="'hidden'">
|
||||
<strong>{{ marketplacePkg.manifest.title }}</strong>
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user