Update Angular (#2952)

* fix Tor logs actually fetching od logs

* chore: update to Angular 18

* chore: update to Angular 19

* bump patchDB

* chore: update Angular

* chore: fix setup-wizard success page

* chore: fix

* chore: fix

* chore: fix

* chore: fix

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
Alex Inkin
2025-05-30 21:34:24 +07:00
committed by GitHub
parent 05b8dd9ad8
commit 02413a4fac
257 changed files with 5921 additions and 9539 deletions

View File

@@ -11,12 +11,15 @@
"prefix": "app", "prefix": "app",
"architect": { "architect": {
"build": { "build": {
"builder": "@angular-devkit/build-angular:browser", "builder": "@angular/build:application",
"options": { "options": {
"preserveSymlinks": true, "preserveSymlinks": true,
"outputPath": "dist/raw/ui", "outputPath": {
"base": "dist/raw/ui",
"browser": ""
},
"index": "projects/ui/src/index.html", "index": "projects/ui/src/index.html",
"main": "projects/ui/src/main.ts", "browser": "projects/ui/src/main.ts",
"polyfills": ["zone.js", "projects/ui/src/polyfills.ts"], "polyfills": ["zone.js", "projects/ui/src/polyfills.ts"],
"tsConfig": "projects/ui/tsconfig.json", "tsConfig": "projects/ui/tsconfig.json",
"inlineStyleLanguage": "scss", "inlineStyleLanguage": "scss",
@@ -26,6 +29,11 @@
"input": "projects/shared/assets", "input": "projects/shared/assets",
"output": "assets" "output": "assets"
}, },
{
"glob": "**/*.wasm",
"input": "node_modules/@start9labs/argon2",
"output": "assets"
},
{ {
"glob": "**/*", "glob": "**/*",
"input": "node_modules/monaco-editor", "input": "node_modules/monaco-editor",
@@ -36,12 +44,7 @@
"input": "node_modules/@taiga-ui/icons/src", "input": "node_modules/@taiga-ui/icons/src",
"output": "assets/taiga-ui/icons" "output": "assets/taiga-ui/icons"
}, },
"projects/ui/src/manifest.webmanifest", "projects/ui/src/manifest.webmanifest"
{
"glob": "ngsw.json",
"input": "dist/raw/ui",
"output": "projects/ui/src"
}
], ],
"styles": [ "styles": [
"node_modules/@taiga-ui/core/styles/taiga-ui-theme.less", "node_modules/@taiga-ui/core/styles/taiga-ui-theme.less",
@@ -50,11 +53,14 @@
"projects/ui/src/styles.scss" "projects/ui/src/styles.scss"
], ],
"scripts": [], "scripts": [],
"ngswConfigPath": "projects/ui/ngsw-config.json" "loader": {
".md": "text"
},
"serviceWorker": "projects/ui/ngsw-config.json"
}, },
"configurations": { "configurations": {
"production": { "production": {
"serviceWorker": true, "serviceWorker": "projects/ui/ngsw-config.json",
"budgets": [ "budgets": [
{ {
"type": "initial", "type": "initial",
@@ -72,9 +78,7 @@
"extractLicenses": false "extractLicenses": false
}, },
"development": { "development": {
"buildOptimizer": false,
"optimization": false, "optimization": false,
"vendorChunk": true,
"extractLicenses": false, "extractLicenses": false,
"sourceMap": true, "sourceMap": true,
"namedChunks": true "namedChunks": true
@@ -86,7 +90,7 @@
"defaultConfiguration": "production" "defaultConfiguration": "production"
}, },
"serve": { "serve": {
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular/build:dev-server",
"configurations": { "configurations": {
"production": { "production": {
"buildTarget": "ui:build:production" "buildTarget": "ui:build:production"
@@ -101,7 +105,7 @@
} }
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n", "builder": "@angular/build:extract-i18n",
"options": { "options": {
"buildTarget": "ui:build" "buildTarget": "ui:build"
} }
@@ -125,11 +129,14 @@
"prefix": "app", "prefix": "app",
"architect": { "architect": {
"build": { "build": {
"builder": "@angular-devkit/build-angular:browser", "builder": "@angular/build:application",
"options": { "options": {
"outputPath": "dist/raw/install-wizard", "outputPath": {
"base": "dist/raw/install-wizard",
"browser": ""
},
"index": "projects/install-wizard/src/index.html", "index": "projects/install-wizard/src/index.html",
"main": "projects/install-wizard/src/main.ts", "browser": "projects/install-wizard/src/main.ts",
"polyfills": ["zone.js"], "polyfills": ["zone.js"],
"tsConfig": "projects/install-wizard/tsconfig.json", "tsConfig": "projects/install-wizard/tsconfig.json",
"inlineStyleLanguage": "scss", "inlineStyleLanguage": "scss",
@@ -169,8 +176,6 @@
"namedChunks": false, "namedChunks": false,
"aot": true, "aot": true,
"extractLicenses": true, "extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [ "budgets": [
{ {
"type": "initial", "type": "initial",
@@ -183,9 +188,7 @@
"progress": false "progress": false
}, },
"development": { "development": {
"buildOptimizer": false,
"optimization": false, "optimization": false,
"vendorChunk": true,
"extractLicenses": false, "extractLicenses": false,
"sourceMap": true, "sourceMap": true,
"namedChunks": true "namedChunks": true
@@ -194,7 +197,7 @@
"defaultConfiguration": "production" "defaultConfiguration": "production"
}, },
"serve": { "serve": {
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular/build:dev-server",
"options": { "options": {
"buildTarget": "install-wizard:build", "buildTarget": "install-wizard:build",
"port": 8100 "port": 8100
@@ -210,7 +213,7 @@
"defaultConfiguration": "development" "defaultConfiguration": "development"
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n", "builder": "@angular/build:extract-i18n",
"options": { "options": {
"buildTarget": "install-wizard:build" "buildTarget": "install-wizard:build"
} }
@@ -234,11 +237,14 @@
"prefix": "app", "prefix": "app",
"architect": { "architect": {
"build": { "build": {
"builder": "@angular-devkit/build-angular:browser", "builder": "@angular/build:application",
"options": { "options": {
"outputPath": "dist/raw/setup-wizard", "outputPath": {
"base": "dist/raw/setup-wizard",
"browser": ""
},
"index": "projects/setup-wizard/src/index.html", "index": "projects/setup-wizard/src/index.html",
"main": "projects/setup-wizard/src/main.ts", "browser": "projects/setup-wizard/src/main.ts",
"polyfills": ["zone.js"], "polyfills": ["zone.js"],
"tsConfig": "projects/setup-wizard/tsconfig.json", "tsConfig": "projects/setup-wizard/tsconfig.json",
"inlineStyleLanguage": "scss", "inlineStyleLanguage": "scss",
@@ -249,9 +255,9 @@
"output": "assets" "output": "assets"
}, },
{ {
"glob": "**/*.svg", "glob": "**/*.wasm",
"input": "node_modules/ionicons/dist/ionicons/svg", "input": "node_modules/@start9labs/argon2",
"output": "./svg" "output": "assets"
}, },
{ {
"glob": "**/*", "glob": "**/*",
@@ -285,9 +291,7 @@
"outputHashing": "all" "outputHashing": "all"
}, },
"development": { "development": {
"buildOptimizer": false,
"optimization": false, "optimization": false,
"vendorChunk": true,
"extractLicenses": false, "extractLicenses": false,
"sourceMap": true, "sourceMap": true,
"namedChunks": true "namedChunks": true
@@ -299,7 +303,7 @@
"defaultConfiguration": "production" "defaultConfiguration": "production"
}, },
"serve": { "serve": {
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular/build:dev-server",
"configurations": { "configurations": {
"production": { "production": {
"buildTarget": "setup-wizard:build:production" "buildTarget": "setup-wizard:build:production"
@@ -314,7 +318,7 @@
} }
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n", "builder": "@angular/build:extract-i18n",
"options": { "options": {
"buildTarget": "setup-wizard:build" "buildTarget": "setup-wizard:build"
} }
@@ -337,7 +341,7 @@
"prefix": "lib", "prefix": "lib",
"architect": { "architect": {
"build": { "build": {
"builder": "@angular-devkit/build-angular:ng-packagr", "builder": "@angular/build:ng-packagr",
"options": { "options": {
"project": "projects/marketplace/ng-package.json" "project": "projects/marketplace/ng-package.json"
}, },
@@ -357,7 +361,7 @@
"prefix": "lib", "prefix": "lib",
"architect": { "architect": {
"build": { "build": {
"builder": "@angular-devkit/build-angular:ng-packagr", "builder": "@angular/build:ng-packagr",
"options": { "options": {
"project": "projects/shared/ng-package.json" "project": "projects/shared/ng-package.json"
}, },

12024
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -17,11 +17,10 @@
"build:setup": "ng run setup-wizard:build", "build:setup": "ng run setup-wizard:build",
"build:ui": "ng run ui:build", "build:ui": "ng run ui:build",
"build:ui:dev": "ng run ui:build:development", "build:ui:dev": "ng run ui:build:development",
"build:ui:stats": "ng run ui:build --stats-json",
"build:all": "npm run build:deps && npm run build:setup && npm run build:ui && npm run build:install", "build:all": "npm run build:deps && npm run build:setup && npm run build:ui && npm run build:install",
"build:shared": "ng build shared", "build:shared": "ng build shared",
"build:marketplace": "npm run build:shared && ng build marketplace", "build:marketplace": "npm run build:shared && ng build marketplace",
"analyze:ui": "webpack-bundle-analyzer dist/raw/ui/stats.json", "analyze:ui": "ng build ui --stats-json --named-chunks && npx -y @angular-experts/hawkeye dist/raw/ui/stats.json",
"publish:shared": "npm run build:shared && npm publish ./dist/shared --access public", "publish:shared": "npm run build:shared && npm publish ./dist/shared --access public",
"publish:marketplace": "npm run build:marketplace && npm publish ./dist/marketplace --access public", "publish:marketplace": "npm run build:marketplace && npm publish ./dist/marketplace --access public",
"start:install": "npm run-script build-config && ng serve --project install-wizard --host 0.0.0.0", "start:install": "npm run-script build-config && ng serve --project install-wizard --host 0.0.0.0",
@@ -31,45 +30,45 @@
"build-config": "node build-config.js" "build-config": "node build-config.js"
}, },
"dependencies": { "dependencies": {
"@angular/animations": "^17.3.1", "@angular/animations": "^19.2.11",
"@angular/cdk": "^17.3.1", "@angular/cdk": "^19.2.16",
"@angular/common": "^17.3.1", "@angular/common": "^19.2.11",
"@angular/compiler": "^17.3.1", "@angular/compiler": "^19.2.11",
"@angular/core": "^17.3.1", "@angular/core": "^19.2.11",
"@angular/forms": "^17.3.1", "@angular/forms": "^19.2.11",
"@angular/platform-browser": "^17.3.1", "@angular/platform-browser": "^19.2.11",
"@angular/platform-browser-dynamic": "^17.3.1", "@angular/platform-browser-dynamic": "^19.2.11",
"@angular/pwa": "^17.3.1", "@angular/pwa": "^19.2.12",
"@angular/router": "^17.3.1", "@angular/router": "^19.2.11",
"@angular/service-worker": "^17.3.1", "@angular/service-worker": "^19.2.11",
"@materia-ui/ngx-monaco-editor": "^6.0.0", "@materia-ui/ngx-monaco-editor": "^6.0.0",
"@noble/curves": "^1.4.0", "@noble/curves": "^1.4.0",
"@noble/hashes": "^1.4.0", "@noble/hashes": "^1.4.0",
"@start9labs/argon2": "^0.2.2", "@start9labs/argon2": "^0.3.0",
"@start9labs/start-sdk": "file:../sdk/baseDist", "@start9labs/start-sdk": "file:../sdk/baseDist",
"@taiga-ui/addon-charts": "4.36.0", "@taiga-ui/addon-charts": "4.38.0",
"@taiga-ui/addon-commerce": "4.36.0", "@taiga-ui/addon-commerce": "4.38.0",
"@taiga-ui/addon-mobile": "4.36.0", "@taiga-ui/addon-mobile": "4.38.0",
"@taiga-ui/addon-table": "4.36.0", "@taiga-ui/addon-table": "4.38.0",
"@taiga-ui/cdk": "4.36.0", "@taiga-ui/cdk": "4.38.0",
"@taiga-ui/core": "4.36.0", "@taiga-ui/core": "4.38.0",
"@taiga-ui/event-plugins": "4.5.1", "@taiga-ui/event-plugins": "4.5.1",
"@taiga-ui/experimental": "4.36.0", "@taiga-ui/experimental": "4.38.0",
"@taiga-ui/icons": "4.36.0", "@taiga-ui/icons": "4.38.0",
"@taiga-ui/kit": "4.36.0", "@taiga-ui/kit": "4.38.0",
"@taiga-ui/layout": "4.36.0", "@taiga-ui/layout": "4.38.0",
"@taiga-ui/legacy": "4.36.0", "@taiga-ui/legacy": "4.38.0",
"@taiga-ui/polymorpheus": "4.9.0", "@taiga-ui/polymorpheus": "4.9.0",
"@tinkoff/ng-dompurify": "4.0.0", "@taiga-ui/dompurify": "4.1.11",
"ansi-to-html": "^0.7.2", "ansi-to-html": "^0.7.2",
"base64-js": "^1.5.1", "base64-js": "^1.5.1",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"cbor": "npm:@jprochazk/cbor@^0.4.9", "cbor": "npm:@jprochazk/cbor@^0.4.9",
"cbor-web": "^8.1.0", "cbor-web": "^8.1.0",
"core-js": "^3.21.1", "core-js": "^3.42.0",
"cron": "^2.2.0", "cron": "^2.2.0",
"cronstrue": "^2.21.0", "cronstrue": "^2.21.0",
"dompurify": "^2.3.6", "dompurify": "^3.1.7",
"deep-equality-data-structures": "1.5.1", "deep-equality-data-structures": "1.5.1",
"fast-json-patch": "^3.1.1", "fast-json-patch": "^3.1.1",
"fuse.js": "^6.4.6", "fuse.js": "^6.4.6",
@@ -79,44 +78,41 @@
"mime": "^4.0.3", "mime": "^4.0.3",
"monaco-editor": "^0.33.0", "monaco-editor": "^0.33.0",
"mustache": "^4.2.0", "mustache": "^4.2.0",
"ng-qrcode": "^17.0.0", "ng-qrcode": "^19.0.1",
"node-jose": "^2.2.0", "node-jose": "^2.2.0",
"patch-db-client": "file:../patch-db/client", "patch-db-client": "file:../patch-db/client",
"path-browserify": "^1.0.1",
"pbkdf2": "^3.1.2", "pbkdf2": "^3.1.2",
"rxjs": "^7.5.6", "rxjs": "^7.8.2",
"swiper": "^8.2.4", "ts-matches": "^6.3.2",
"ts-matches": "^6.1.0",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"zone.js": "^0.14.2" "zone.js": "^0.15.0"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "^17.3.1", "@angular/build": "^19.2.12",
"@angular/cli": "^17.3.1", "@angular/cli": "^19.2.12",
"@angular/compiler-cli": "^17.3.1", "@angular/compiler-cli": "^19.2.11",
"@angular/language-service": "^17.3.1", "@angular/language-service": "^19.2.11",
"@types/dompurify": "^2.3.3", "@angular-experts/hawkeye": "^1.7.2",
"@types/dompurify": "3.0.5",
"@types/estree": "^0.0.51", "@types/estree": "^0.0.51",
"@types/js-yaml": "^4.0.5", "@types/js-yaml": "^4.0.5",
"@types/marked": "^4.0.3", "@types/marked": "^4.0.3",
"@types/mustache": "^4.1.2", "@types/mustache": "^4.2.6",
"@types/node": "^18.15.0", "@types/node": "^22.15.19",
"@types/node-jose": "^1.1.10", "@types/node-jose": "^1.1.10",
"@types/pbkdf2": "^3.1.0", "@types/pbkdf2": "^3.1.0",
"@types/uuid": "^8.3.1", "@types/uuid": "^8.3.1",
"autoprefixer": "^10.4.14",
"husky": "^4.3.8", "husky": "^4.3.8",
"lint-staged": "^13.2.0", "lint-staged": "^13.2.0",
"ng-packagr": "^17.0.2", "ng-packagr": "^19.2.2",
"node-html-parser": "^5.3.3", "node-html-parser": "^5.3.3",
"postcss": "^8.4.21", "postcss": "^8.4.21",
"prettier": "^3.2.5", "prettier": "^3.5.3",
"raw-loader": "^4.0.2", "rimraf": "^6.0.1",
"ts-node": "^10.7.0", "ts-node": "^10.7.0",
"tslint": "^6.1.3", "tslint": "^6.1.3",
"typescript": "^5.2.2", "typescript": "^5.8.3"
"webpack-bundle-analyzer": "^4.8.0"
}, },
"husky": { "husky": {
"hooks": { "hooks": {

View File

@@ -1,4 +1,4 @@
@import '@taiga-ui/core/styles/taiga-ui-local'; @use '@taiga-ui/core/styles/taiga-ui-local' as taiga;
::ng-deep html, ::ng-deep html,
::ng-deep body, ::ng-deep body,
@@ -48,7 +48,7 @@ main {
} }
.options { .options {
@include transition(margin); @include taiga.transition(margin);
min-width: 100%; min-width: 100%;
display: flex; display: flex;

View File

@@ -10,6 +10,7 @@ import { ApiService } from 'src/app/services/api.service'
selector: 'app-root', selector: 'app-root',
templateUrl: 'app.component.html', templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'], styleUrls: ['app.component.scss'],
standalone: false,
}) })
export class AppComponent { export class AppComponent {
private readonly loader = inject(LoadingService) private readonly loader = inject(LoadingService)

View File

@@ -1,4 +1,4 @@
import { HttpClientModule } from '@angular/common/http' import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
import { NgModule } from '@angular/core' import { NgModule } from '@angular/core'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations' import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
import { import {
@@ -29,7 +29,6 @@ const {
@NgModule({ @NgModule({
declarations: [AppComponent], declarations: [AppComponent],
imports: [ imports: [
HttpClientModule,
BrowserAnimationsModule, BrowserAnimationsModule,
TuiRoot, TuiRoot,
DriveComponent, DriveComponent,
@@ -51,6 +50,7 @@ const {
provide: RELATIVE_URL, provide: RELATIVE_URL,
useValue: `/${api.url}/${api.version}`, useValue: `/${api.url}/${api.version}`,
}, },
provideHttpClient(withInterceptorsFromDi()),
], ],
bootstrap: [AppComponent], bootstrap: [AppComponent],
}) })

View File

@@ -1,4 +1,4 @@
@import '@taiga-ui/core/styles/taiga-ui-local'; @use '@taiga-ui/core/styles/taiga-ui-local' as taiga;
:host { :host {
margin: 0; margin: 0;
@@ -12,7 +12,7 @@ tui-drawer {
} }
header { header {
@include scrollbar-hidden(); @include taiga.scrollbar-hidden();
// @TODO Theme // @TODO Theme
background: #2b2b2f; background: #2b2b2f;

View File

@@ -15,6 +15,7 @@ import { StoreDataWithUrl } from '../../types'
templateUrl: './menu.component.html', templateUrl: './menu.component.html',
styleUrls: ['./menu.component.scss'], styleUrls: ['./menu.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
}) })
export class MenuComponent implements OnDestroy { export class MenuComponent implements OnDestroy {
@Input({ required: true }) @Input({ required: true })

View File

@@ -3,7 +3,6 @@ import { TuiIcon, TuiTitle } from '@taiga-ui/core'
import { StoreIconComponentModule } from './store-icon/store-icon.component.module' import { StoreIconComponentModule } from './store-icon/store-icon.component.module'
@Component({ @Component({
standalone: true,
selector: '[registry]', selector: '[registry]',
template: ` template: `
<store-icon [url]="registry.url" size="40px" /> <store-icon [url]="registry.url" size="40px" />

View File

@@ -21,6 +21,7 @@ import { knownRegistries, sameUrl } from '@start9labs/shared'
`, `,
styles: ':host { overflow: hidden; }', styles: ':host { overflow: hidden; }',
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
}) })
export class StoreIconComponent { export class StoreIconComponent {
@Input() @Input()

View File

@@ -1,27 +1,27 @@
import { CommonModule } from '@angular/common' import { CommonModule } from '@angular/common'
import { ChangeDetectionStrategy, Component, inject } from '@angular/core' import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { Exver, MarkdownPipe } from '@start9labs/shared' import { Exver, MarkdownPipe } from '@start9labs/shared'
import { TuiButton, TuiDialogContext, TuiLoader } from '@taiga-ui/core' import { TuiDialogContext } from '@taiga-ui/core'
import { NgDompurifyPipe } from '@taiga-ui/dompurify'
import { TuiAccordion } from '@taiga-ui/kit' import { TuiAccordion } from '@taiga-ui/kit'
import { injectContext, PolymorpheusComponent } from '@taiga-ui/polymorpheus' import { injectContext, PolymorpheusComponent } from '@taiga-ui/polymorpheus'
import { MarketplacePkg } from '../../src/types' import { MarketplacePkg } from '../../src/types'
@Component({ @Component({
standalone: true,
template: ` template: `
<tui-accordion> <tui-accordion>
@for (note of notes | keyvalue: asIsOrder; track $index) { @for (note of notes | keyvalue: asIsOrder; track $index) {
<tui-accordion-item> <tui-accordion-item>
{{ note.key }} {{ note.key }}
<ng-template tuiAccordionItemContent> <ng-template tuiAccordionItemContent>
<div [innerHTML]="note.value | markdown"></div> <div [innerHTML]="note.value | markdown | dompurify"></div>
</ng-template> </ng-template>
</tui-accordion-item> </tui-accordion-item>
} }
</tui-accordion> </tui-accordion>
`, `,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, TuiButton, TuiLoader, TuiAccordion, MarkdownPipe], imports: [CommonModule, TuiAccordion, MarkdownPipe, NgDompurifyPipe],
}) })
export class ReleaseNotesComponent { export class ReleaseNotesComponent {
private readonly exver = inject(Exver) private readonly exver = inject(Exver)

View File

@@ -27,6 +27,7 @@ const ICONS: Record<string, string> = {
templateUrl: 'categories.component.html', templateUrl: 'categories.component.html',
styleUrls: ['categories.component.scss'], styleUrls: ['categories.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
}) })
export class CategoriesComponent { export class CategoriesComponent {
@Input() @Input()

View File

@@ -6,6 +6,7 @@ import { MarketplacePkg } from '../../../types'
templateUrl: 'item.component.html', templateUrl: 'item.component.html',
styleUrls: ['item.component.scss'], styleUrls: ['item.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
}) })
export class ItemComponent { export class ItemComponent {
@Input({ required: true }) @Input({ required: true })

View File

@@ -11,6 +11,7 @@ import {
templateUrl: 'search.component.html', templateUrl: 'search.component.html',
styleUrls: ['search.component.scss'], styleUrls: ['search.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
}) })
export class SearchComponent { export class SearchComponent {
@Input() @Input()

View File

@@ -1,7 +1,7 @@
<div class="background-border box-shadow-lg shadow-color-light"> <div class="background-border box-shadow-lg shadow-color-light">
<div class="box-container"> <div class="box-container">
<h2 class="additional-detail-title">New in {{ pkg.version }}</h2> <h2 class="additional-detail-title">New in {{ pkg.version }}</h2>
<p [innerHTML]="pkg.releaseNotes | markdown"></p> <p [innerHTML]="pkg.releaseNotes | markdown | dompurify"></p>
<button <button
tuiButton tuiButton
size="s" size="s"

View File

@@ -13,6 +13,7 @@ import { MarketplacePkgBase } from '../../../types'
templateUrl: 'about.component.html', templateUrl: 'about.component.html',
styleUrls: ['about.component.scss'], styleUrls: ['about.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
}) })
export class AboutComponent { export class AboutComponent {
private readonly dialogs = inject(TuiDialogService) private readonly dialogs = inject(TuiDialogService)

View File

@@ -1,18 +1,18 @@
import { TuiButton } from '@taiga-ui/core'
import { TuiTagModule } from '@taiga-ui/legacy'
import { CommonModule } from '@angular/common' import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core' import { NgModule } from '@angular/core'
import { RouterModule } from '@angular/router' import { RouterModule } from '@angular/router'
import { AboutComponent } from './about.component'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
import { MarkdownPipe, SafeLinksDirective } from '@start9labs/shared' import { MarkdownPipe, SafeLinksDirective } from '@start9labs/shared'
import { TuiButton } from '@taiga-ui/core'
import { NgDompurifyPipe } from '@taiga-ui/dompurify'
import { TuiTagModule } from '@taiga-ui/legacy'
import { AboutComponent } from './about.component'
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, CommonModule,
RouterModule, RouterModule,
TuiTagModule, TuiTagModule,
NgDompurifyModule, NgDompurifyPipe,
SafeLinksDirective, SafeLinksDirective,
MarkdownPipe, MarkdownPipe,
TuiButton, TuiButton,

View File

@@ -12,32 +12,29 @@ import { TuiFade } from '@taiga-ui/kit'
</label> </label>
<tui-icon [icon]="icon" /> <tui-icon [icon]="icon" />
`, `,
styles: [ styles: `
` :host {
:host { display: flex;
display: flex; justify-content: space-between;
justify-content: space-between; align-items: center;
align-items: center; gap: 0.5rem;
gap: 0.5rem; padding: 0.75rem 0.25rem;
padding: 0.75rem 0.25rem; white-space: nowrap;
white-space: nowrap;
&:hover { &:hover {
background-color: var(--tui-background-neutral-1); background-color: var(--tui-background-neutral-1);
}
[tuiSubtitle] {
color: var(--tui-text-secondary);
}
tui-icon {
opacity: 0.7;
}
} }
`,
], [tuiSubtitle] {
color: var(--tui-text-secondary);
}
tui-icon {
opacity: 0.7;
}
}
`,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, TuiIcon, TuiTitle, TuiFade], imports: [CommonModule, TuiIcon, TuiTitle, TuiFade],
}) })
export class MarketplaceAdditionalItemComponent { export class MarketplaceAdditionalItemComponent {

View File

@@ -14,7 +14,6 @@ import { MarketplaceAdditionalItemComponent } from './additional-item.component'
</a> </a>
`, `,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, MarketplaceAdditionalItemComponent], imports: [CommonModule, MarketplaceAdditionalItemComponent],
}) })
export class MarketplaceAdditionalLinkComponent { export class MarketplaceAdditionalLinkComponent {

View File

@@ -14,6 +14,7 @@ import { MarketplacePkgBase } from '../../../types'
templateUrl: 'additional.component.html', templateUrl: 'additional.component.html',
styleUrls: ['additional.component.scss'], styleUrls: ['additional.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
}) })
export class AdditionalComponent { export class AdditionalComponent {
@Input({ required: true }) @Input({ required: true })

View File

@@ -27,30 +27,27 @@ import { MarketplaceDepItemComponent } from './dependency-item.component'
</div> </div>
</div> </div>
`, `,
styles: [ styles: `
` .dependencies-container {
.dependencies-container { background-color: rgb(39 39 42);
background-color: rgb(39 39 42); border-radius: 0.75rem;
border-radius: 0.75rem; padding: 1.75rem;
padding: 1.75rem;
@media (min-width: 1024px) { @media (min-width: 1024px) {
grid-column: span 5 / span 5; grid-column: span 5 / span 5;
}
@media (min-width: 1280px) {
grid-column: span 4 / span 4;
}
} }
@media (min-width: 1280px) {
grid-column: span 4 / span 4;
}
}
.dependencies-list { .dependencies-list {
display: grid; display: grid;
grid-auto-rows: auto; grid-auto-rows: auto;
gap: 0.75rem; gap: 0.75rem;
} }
`, `,
],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, MarketplaceDepItemComponent], imports: [CommonModule, MarketplaceDepItemComponent],
}) })
export class MarketplaceDependenciesComponent { export class MarketplaceDependenciesComponent {

View File

@@ -37,59 +37,56 @@ import { MarketplacePkgBase } from '../../../types'
</div> </div>
</div> </div>
`, `,
styles: [ styles: `
` .outer-container {
.outer-container { display: flex;
display: flex; align-items: center;
align-items: center; gap: 1.5rem;
gap: 1.5rem; padding: 1rem 1.25rem;
padding: 1rem 1.25rem; background-color: rgb(63 63 70 / 0.4);
background-color: rgb(63 63 70 / 0.4); border-radius: 0.75rem;
border-radius: 0.75rem; filter: drop-shadow(0 10px 8px rgb(0 0 0 / 0.04))
filter: drop-shadow(0 10px 8px rgb(0 0 0 / 0.04)) drop-shadow(0 4px 3px rgb(0 0 0 / 0.1));
drop-shadow(0 4px 3px rgb(0 0 0 / 0.1));
&:hover { &:hover {
background-color: rgb(63 63 70 / 0.7); background-color: rgb(63 63 70 / 0.7);
cursor: pointer; cursor: pointer;
} }
}
.title {
display: flex;
gap: 0;
flex-wrap: wrap;
@media (min-width: 640px) {
gap: 0.25rem;
} }
.title { p {
display: flex; margin: 0;
gap: 0;
flex-wrap: wrap;
@media (min-width: 640px) {
gap: 0.25rem;
}
p {
margin: 0;
}
span {
font-size: 1rem;
line-height: 1.5rem;
font-weight: 500;
color: rgb(250 250 250 / 0.9);
}
} }
.description { span {
font-size: 0.875rem; font-size: 1rem;
line-height: 1.25rem; line-height: 1.5rem;
color: rgb(250 250 250 / 0.7); font-weight: 500;
color: rgb(250 250 250 / 0.9);
} }
}
::ng-deep .dep-img { .description {
filter: drop-shadow(0 10px 8px rgb(0 0 0 / 0.04)) font-size: 0.875rem;
drop-shadow(0 4px 3px rgb(0 0 0 / 0.1)); line-height: 1.25rem;
} color: rgb(250 250 250 / 0.7);
`, }
],
::ng-deep .dep-img {
filter: drop-shadow(0 10px 8px rgb(0 0 0 / 0.04))
drop-shadow(0 4px 3px rgb(0 0 0 / 0.1));
}
`,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [ imports: [
CommonModule, CommonModule,
RouterModule, RouterModule,

View File

@@ -7,7 +7,6 @@ import { TuiCell } from '@taiga-ui/layout'
import { MarketplacePkg } from '../../../types' import { MarketplacePkg } from '../../../types'
@Component({ @Component({
standalone: true,
selector: 'marketplace-flavors', selector: 'marketplace-flavors',
template: ` template: `
<div class="background-border box-shadow-lg shadow-color-light"> <div class="background-border box-shadow-lg shadow-color-light">

View File

@@ -25,122 +25,119 @@ import { SharedPipesModule, TickerComponent } from '@start9labs/shared'
</div> </div>
</div> </div>
`, `,
styles: [ styles: `
` .outer-container {
.outer-container { display: flex;
display: flex; justify-content: center;
justify-content: center; margin-top: 2.5rem;
margin-top: 2.5rem;
@media (min-width: 768px) {
margin-top: 0;
}
}
.inner-container {
display: flex;
flex-direction: column;
width: 100%;
min-height: 32vh;
position: relative;
border-radius: 1.5rem;
padding: 4rem 2rem 0 2rem;
@media (min-width: 376px) {
min-height: 20vh;
}
@media (min-width: 768px) {
min-height: 11rem;
}
img {
width: 6rem;
height: 6rem;
pointer-events: none;
border-radius: 9999px;
object-fit: cover;
position: absolute;
top: -2.25rem;
left: 1.75rem;
z-index: 1;
}
.inner-container-title {
margin: 1rem 0;
color: rgb(250 250 250);
mix-blend-mode: plus-lighter;
z-index: 1;
max-width: 17rem;
@media (min-width: 768px) { @media (min-width: 768px) {
margin-top: 0; min-width: 100%;
}
h2 {
font-size: 2rem;
line-height: 3rem;
font-weight: 400;
display: inline-block;
margin-left: -1px;
}
h3 {
font-size: 1.1rem;
font-weight: 400;
margin-bottom: 1rem;
pointer-events: none;
}
p {
font-size: 1rem;
line-height: 1.5rem;
font-weight: 300;
pointer-events: none;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
} }
} }
.inner-container { .color-background {
display: flex; overflow: hidden;
flex-direction: column; position: absolute;
width: 100%; width: 100%;
min-height: 32vh; height: 100%;
position: relative; top: 0;
left: 0;
z-index: -50;
border-radius: 1.5rem; border-radius: 1.5rem;
padding: 4rem 2rem 0 2rem;
@media (min-width: 376px) {
min-height: 20vh;
}
@media (min-width: 768px) {
min-height: 11rem;
}
img { img {
width: 6rem; position: absolute;
height: 6rem;
pointer-events: none;
border-radius: 9999px;
object-fit: cover; object-fit: cover;
position: absolute; pointer-events: none;
top: -2.25rem; width: 200%;
left: 1.75rem; height: 200%;
z-index: 1; max-width: 200%;
} filter: blur(100px);
.inner-container-title {
margin: 1rem 0;
color: rgb(250 250 250);
mix-blend-mode: plus-lighter;
z-index: 1;
max-width: 17rem;
@media (min-width: 768px) {
min-width: 100%;
}
h2 {
font-size: 2rem;
line-height: 3rem;
font-weight: 400;
display: inline-block;
margin-left: -1px;
}
h3 {
font-size: 1.1rem;
font-weight: 400;
margin-bottom: 1rem;
pointer-events: none;
}
p {
font-size: 1rem;
line-height: 1.5rem;
font-weight: 300;
pointer-events: none;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
}
.color-background {
overflow: hidden;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: -50;
border-radius: 1.5rem;
img {
position: absolute;
object-fit: cover;
pointer-events: none;
width: 200%;
height: 200%;
max-width: 200%;
filter: blur(100px);
}
}
.dark-overlay {
overflow: hidden;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
border-radius: 1.5rem;
background-color: rgb(63 63 70);
opacity: 0.7;
} }
} }
`,
], .dark-overlay {
overflow: hidden;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
border-radius: 1.5rem;
background-color: rgb(63 63 70);
opacity: 0.7;
}
}
`,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, SharedPipesModule, TickerComponent], imports: [CommonModule, SharedPipesModule, TickerComponent],
}) })
export class MarketplacePackageHeroComponent { export class MarketplacePackageHeroComponent {

View File

@@ -68,64 +68,61 @@ import { PolymorpheusContent } from '@taiga-ui/polymorpheus'
></button> ></button>
</div> </div>
`, `,
styles: [ styles: `
` .outer-container {
.outer-container { display: flex;
display: flex; align-items: center;
align-items: center; align-content: center;
align-content: center; margin: 0px;
margin: 0px;
@media (min-width: 1024px) { @media (min-width: 1024px) {
margin-left: -3.5rem; margin-left: -3.5rem;
margin-right: -3.5rem; margin-right: -3.5rem;
min-height: 20rem; min-height: 20rem;
height: 20rem; height: 20rem;
} }
@media (min-width: 1536px) { @media (min-width: 1536px) {
height: 100%; height: 100%;
} }
}
.carousel {
overflow-y: hidden;
overflow-x: scroll;
overflow: hidden;
}
.screenshot-item {
object-fit: cover;
overflow: hidden;
border-radius: 0.5rem;
border-width: 1px;
border-color: rgb(161 161 170 / 0.3);
&:hover {
cursor: pointer;
} }
.carousel { @media (min-width: 768px) {
overflow-y: hidden; border-radius: 0.75rem;
overflow-x: scroll;
overflow: hidden;
} }
.screenshot-item { .screenshot-item-img {
object-fit: cover; width: 100%;
overflow: hidden; height: 100%;
border-radius: 0.5rem; border-radius: 0.5rem;
border-width: 1px;
border-color: rgb(161 161 170 / 0.3);
&:hover {
cursor: pointer;
}
@media (min-width: 768px) { @media (min-width: 768px) {
border-radius: 0.75rem; border-radius: 0.75rem;
} }
.screenshot-item-img { .screenshot-item-img-enlarged {
width: 100%; border-radius: 0;
height: 100%;
border-radius: 0.5rem;
@media (min-width: 768px) {
border-radius: 0.75rem;
}
.screenshot-item-img-enlarged {
border-radius: 0px;
}
} }
} }
`, }
], `,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, TuiCarousel, TuiButton], imports: [CommonModule, TuiCarousel, TuiButton],
}) })
export class MarketplacePackageScreenshotComponent { export class MarketplacePackageScreenshotComponent {

View File

@@ -4,6 +4,7 @@ import Fuse from 'fuse.js'
@Pipe({ @Pipe({
name: 'filterPackages', name: 'filterPackages',
standalone: false,
}) })
export class FilterPackagesPipe implements PipeTransform { export class FilterPackagesPipe implements PipeTransform {
transform( transform(

View File

@@ -8,6 +8,7 @@ import { DOCUMENT } from '@angular/common'
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
template: '<tui-root tuiTheme="dark"><router-outlet /></tui-root>', template: '<tui-root tuiTheme="dark"><router-outlet /></tui-root>',
standalone: false,
}) })
export class AppComponent { export class AppComponent {
private readonly api = inject(ApiService) private readonly api = inject(ApiService)

View File

@@ -1,7 +1,9 @@
import { HttpClientModule } from '@angular/common/http' import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
import { NgModule } from '@angular/core' import { inject, NgModule, provideAppInitializer } from '@angular/core'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations' import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
import { PreloadAllModules, RouterModule } from '@angular/router' import { PreloadAllModules, RouterModule } from '@angular/router'
import { WA_LOCATION } from '@ng-web-apis/common'
import initArgon from '@start9labs/argon2'
import { import {
provideSetupLogsService, provideSetupLogsService,
RELATIVE_URL, RELATIVE_URL,
@@ -27,7 +29,6 @@ const version = require('../../../../package.json').version
declarations: [AppComponent], declarations: [AppComponent],
imports: [ imports: [
BrowserAnimationsModule, BrowserAnimationsModule,
HttpClientModule,
RouterModule.forRoot(ROUTES, { RouterModule.forRoot(ROUTES, {
preloadingStrategy: PreloadAllModules, preloadingStrategy: PreloadAllModules,
initialNavigation: 'disabled', initialNavigation: 'disabled',
@@ -50,6 +51,13 @@ const version = require('../../../../package.json').version
provide: VERSION, provide: VERSION,
useValue: version, useValue: version,
}, },
provideHttpClient(withInterceptorsFromDi()),
provideAppInitializer(() => {
const origin = inject(WA_LOCATION).origin
const module_or_path = new URL('/assets/argon2_bg.wasm', origin)
initArgon({ module_or_path })
}),
], ],
bootstrap: [AppComponent], bootstrap: [AppComponent],
}) })

View File

@@ -28,7 +28,6 @@ export interface CifsResponse {
} }
@Component({ @Component({
standalone: true,
template: ` template: `
<form [formGroup]="form" (ngSubmit)="submit()"> <form [formGroup]="form" (ngSubmit)="submit()">
<tui-input formControlName="hostname"> <tui-input formControlName="hostname">
@@ -78,10 +77,17 @@ export interface CifsResponse {
</footer> </footer>
</form> </form>
`, `,
styles: [ styles: `
'.input { margin-top: 1rem }', .input {
'footer { display: flex; gap: 1rem; margin-top: 1rem }', margin-top: 1rem;
], }
footer {
display: flex;
gap: 1rem;
margin-top: 1rem;
}
`,
imports: [ imports: [
CommonModule, CommonModule,
FormsModule, FormsModule,

View File

@@ -2,7 +2,6 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { DocsLinkDirective } from '@start9labs/shared' import { DocsLinkDirective } from '@start9labs/shared'
@Component({ @Component({
standalone: true,
selector: 'app-documentation', selector: 'app-documentation',
template: ` template: `
<!doctype html> <!doctype html>

View File

@@ -5,7 +5,6 @@ import { WA_WINDOW } from '@ng-web-apis/common'
const FADE_FACTOR = 0.07 const FADE_FACTOR = 0.07
@Component({ @Component({
standalone: true,
selector: 'canvas[matrix]', selector: 'canvas[matrix]',
template: 'Your browser does not support the canvas element.', template: 'Your browser does not support the canvas element.',
styles: ':host { position: fixed; top: 0 }', styles: ':host { position: fixed; top: 0 }',

View File

@@ -7,7 +7,7 @@ import {
ReactiveFormsModule, ReactiveFormsModule,
Validators, Validators,
} from '@angular/forms' } from '@angular/forms'
import * as argon2 from '@start9labs/argon2' import { verify } from '@start9labs/argon2'
import { ErrorService } from '@start9labs/shared' import { ErrorService } from '@start9labs/shared'
import { TuiAutoFocus, TuiMapperPipe, TuiValidator } from '@taiga-ui/cdk' import { TuiAutoFocus, TuiMapperPipe, TuiValidator } from '@taiga-ui/cdk'
import { import {
@@ -30,7 +30,6 @@ interface DialogData {
} }
@Component({ @Component({
standalone: true,
template: ` template: `
@if (storageDrive) { @if (storageDrive) {
Choose a password for your server. Choose a password for your server.
@@ -142,7 +141,7 @@ export class PasswordComponent {
} }
try { try {
argon2.verify(this.context.data.passwordHash || '', password) verify(this.context.data.passwordHash || '', password)
this.context.completeWith(password) this.context.completeWith(password)
} catch (e) { } catch (e) {
this.errorService.handleError('Incorrect password provided') this.errorService.handleError('Incorrect password provided')

View File

@@ -5,7 +5,6 @@ import { filter, fromEvent, switchMap } from 'rxjs'
import { PASSWORD } from 'src/app/components/password.component' import { PASSWORD } from 'src/app/components/password.component'
@Directive({ @Directive({
standalone: true,
selector: 'button[server][password]', selector: 'button[server][password]',
}) })
export class PasswordDirective { export class PasswordDirective {

View File

@@ -4,7 +4,6 @@ import { Component, Input } from '@angular/core'
import { RouterModule } from '@angular/router' import { RouterModule } from '@angular/router'
@Component({ @Component({
standalone: true,
selector: 'app-recover', selector: 'app-recover',
template: ` template: `
<a tuiCell [routerLink]="disabled ? null : '/attach'"> <a tuiCell [routerLink]="disabled ? null : '/attach'">

View File

@@ -15,7 +15,6 @@ export interface ServersResponse {
} }
@Component({ @Component({
standalone: true,
template: ` template: `
@for (server of context.data.servers; track $index) { @for (server of context.data.servers; track $index) {
<button [server]="server" (password)="select($event, server.id)"></button> <button [server]="server" (password)="select($event, server.id)"></button>

View File

@@ -15,7 +15,6 @@ import { ApiService } from 'src/app/services/api.service'
import { StateService } from 'src/app/services/state.service' import { StateService } from 'src/app/services/state.service'
@Component({ @Component({
standalone: true,
template: ` template: `
<section tuiCardLarge="compact"> <section tuiCardLarge="compact">
<header>Use existing drive</header> <header>Use existing drive</header>

View File

@@ -9,7 +9,6 @@ import { ApiService } from 'src/app/services/api.service'
import { StateService } from 'src/app/services/state.service' import { StateService } from 'src/app/services/state.service'
@Component({ @Component({
standalone: true,
template: ` template: `
<img class="logo" src="assets/img/icon.png" alt="Start9" /> <img class="logo" src="assets/img/icon.png" alt="Start9" />
@if (!loading) { @if (!loading) {
@@ -59,7 +58,7 @@ import { StateService } from 'src/app/services/state.service'
} }
`, `,
styles: ` styles: `
@import '@taiga-ui/core/styles/taiga-ui-local'; @use '@taiga-ui/core/styles/taiga-ui-local' as taiga;
.logo { .logo {
width: 6rem; width: 6rem;
@@ -88,7 +87,7 @@ import { StateService } from 'src/app/services/state.service'
} }
.options { .options {
@include transition(margin); @include taiga.transition(margin);
min-width: 100%; min-width: 100%;
display: flex; display: flex;

View File

@@ -23,9 +23,13 @@ import { ApiService } from 'src/app/services/api.service'
import { StateService } from 'src/app/services/state.service' import { StateService } from 'src/app/services/state.service'
@Component({ @Component({
standalone: true,
template: '<app-initializing [setupType]="type" [progress]="progress()" />', template: '<app-initializing [setupType]="type" [progress]="progress()" />',
styles: ':host { max-width: unset; align-items: stretch; }', styles: `
:host {
max-width: unset;
align-items: stretch;
}
`,
imports: [InitializingComponent], imports: [InitializingComponent],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })

View File

@@ -15,7 +15,6 @@ import { ApiService, StartOSDiskInfoFull } from 'src/app/services/api.service'
import { StateService } from 'src/app/services/state.service' import { StateService } from 'src/app/services/state.service'
@Component({ @Component({
standalone: true,
template: ` template: `
<section tuiCardLarge="compact"> <section tuiCardLarge="compact">
<header>Restore from Backup</header> <header>Restore from Backup</header>

View File

@@ -17,7 +17,6 @@ import { ApiService } from 'src/app/services/api.service'
import { StateService } from 'src/app/services/state.service' import { StateService } from 'src/app/services/state.service'
@Component({ @Component({
standalone: true,
template: ` template: `
<section tuiCardLarge="compact"> <section tuiCardLarge="compact">
@if (loading || drives.length) { @if (loading || drives.length) {

View File

@@ -15,7 +15,6 @@ import { ApiService } from 'src/app/services/api.service'
import { StateService } from 'src/app/services/state.service' import { StateService } from 'src/app/services/state.service'
@Component({ @Component({
standalone: true,
template: ` template: `
<canvas matrix></canvas> <canvas matrix></canvas>
@if (stateService.kiosk) { @if (stateService.kiosk) {
@@ -90,6 +89,14 @@ import { StateService } from 'src/app/services/state.service'
color: var(--tui-text-primary); color: var(--tui-text-primary);
text-decoration: none; text-decoration: none;
text-align: center; text-align: center;
&[data-appearance='floating'] {
background: var(--tui-background-neutral-1);
&:hover {
background: var(--tui-background-neutral-1-hover) !important;
}
}
} }
a[tuiCardLarge]:not([href]) { a[tuiCardLarge]:not([href]) {

View File

@@ -19,7 +19,6 @@ import { ApiService } from 'src/app/services/api.service'
import { StateService } from 'src/app/services/state.service' import { StateService } from 'src/app/services/state.service'
@Component({ @Component({
standalone: true,
template: ` template: `
<section tuiCardLarge="compact"> <section tuiCardLarge="compact">
<header>Transfer</header> <header>Transfer</header>

View File

@@ -3,7 +3,6 @@ import { Component, Input } from '@angular/core'
import { UnitConversionPipesModule } from '../pipes/unit-conversion/unit-conversion.module' import { UnitConversionPipesModule } from '../pipes/unit-conversion/unit-conversion.module'
@Component({ @Component({
standalone: true,
selector: 'button[drive]', selector: 'button[drive]',
template: ` template: `
<tui-icon icon="@tui.save" /> <tui-icon icon="@tui.save" />

View File

@@ -5,7 +5,6 @@ import { LogsWindowComponent } from './logs-window.component'
import { i18nPipe } from '../i18n/i18n.pipe' import { i18nPipe } from '../i18n/i18n.pipe'
@Component({ @Component({
standalone: true,
selector: 'app-initializing', selector: 'app-initializing',
template: ` template: `
<section> <section>

View File

@@ -1,16 +1,15 @@
import { TuiScrollbar } from '@taiga-ui/core'
import { AsyncPipe } from '@angular/common' import { AsyncPipe } from '@angular/common'
import { Component, ElementRef, inject } from '@angular/core' import { Component, ElementRef, inject } from '@angular/core'
import { import {
WaIntersectionObserver,
INTERSECTION_ROOT, INTERSECTION_ROOT,
WaIntersectionObserver,
} from '@ng-web-apis/intersection-observer' } from '@ng-web-apis/intersection-observer'
import { WaMutationObserver } from '@ng-web-apis/mutation-observer' import { WaMutationObserver } from '@ng-web-apis/mutation-observer'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify' import { TuiScrollbar } from '@taiga-ui/core'
import { NgDompurifyPipe } from '@taiga-ui/dompurify'
import { SetupLogsService } from '../services/setup-logs.service' import { SetupLogsService } from '../services/setup-logs.service'
@Component({ @Component({
standalone: true,
selector: 'logs-window', selector: 'logs-window',
template: ` template: `
<tui-scrollbar childList subtree (waMutationObserver)="scrollTo(bottom)"> <tui-scrollbar childList subtree (waMutationObserver)="scrollTo(bottom)">
@@ -25,11 +24,16 @@ import { SetupLogsService } from '../services/setup-logs.service'
></section> ></section>
</tui-scrollbar> </tui-scrollbar>
`, `,
styles: `
pre {
white-space: normal;
}
`,
imports: [ imports: [
AsyncPipe, AsyncPipe,
WaMutationObserver, WaMutationObserver,
WaIntersectionObserver, WaIntersectionObserver,
NgDompurifyModule, NgDompurifyPipe,
TuiScrollbar, TuiScrollbar,
], ],
providers: [ providers: [

View File

@@ -2,8 +2,8 @@ import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { toSignal } from '@angular/core/rxjs-interop' import { toSignal } from '@angular/core/rxjs-interop'
import { ActivatedRoute } from '@angular/router' import { ActivatedRoute } from '@angular/router'
import { TuiDialogContext, TuiLoader, TuiNotification } from '@taiga-ui/core' import { TuiDialogContext, TuiLoader, TuiNotification } from '@taiga-ui/core'
import { NgDompurifyPipe } from '@taiga-ui/dompurify'
import { injectContext, PolymorpheusComponent } from '@taiga-ui/polymorpheus' import { injectContext, PolymorpheusComponent } from '@taiga-ui/polymorpheus'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
import { catchError, ignoreElements, Observable, of } from 'rxjs' import { catchError, ignoreElements, Observable, of } from 'rxjs'
import { SafeLinksDirective } from '../directives/safe-links.directive' import { SafeLinksDirective } from '../directives/safe-links.directive'
import { MarkdownPipe } from '../pipes/markdown.pipe' import { MarkdownPipe } from '../pipes/markdown.pipe'
@@ -24,12 +24,11 @@ import { getErrorMessage } from '../services/error.service'
} }
`, `,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
host: { class: 'g-subpage' }, host: { class: 'g-subpage' },
imports: [ imports: [
TuiNotification, TuiNotification,
TuiLoader, TuiLoader,
NgDompurifyModule, NgDompurifyPipe,
MarkdownPipe, MarkdownPipe,
SafeLinksDirective, SafeLinksDirective,
], ],

View File

@@ -12,7 +12,6 @@ import { i18nPipe } from '../i18n/i18n.pipe'
import { i18nKey } from '../i18n/i18n.providers' import { i18nKey } from '../i18n/i18n.providers'
@Component({ @Component({
standalone: true,
template: ` template: `
<p>{{ options.message }}</p> <p>{{ options.message }}</p>
<p *ngIf="options.warning" class="warning">{{ options.warning }}</p> <p *ngIf="options.warning" class="warning">{{ options.warning }}</p>
@@ -60,22 +59,20 @@ import { i18nKey } from '../i18n/i18n.providers'
></button> ></button>
</ng-template> </ng-template>
`, `,
styles: [ styles: `
` .warning {
.warning { color: var(--tui-status-warning);
color: var(--tui-status-warning); }
}
.button { .button {
pointer-events: auto; pointer-events: auto;
margin-left: 0.25rem; margin-left: 0.25rem;
} }
.masked { .masked {
-webkit-text-security: disc; -webkit-text-security: disc;
} }
`, `,
],
imports: [ imports: [
CommonModule, CommonModule,
FormsModule, FormsModule,

View File

@@ -5,7 +5,6 @@ import { TuiCell } from '@taiga-ui/layout'
import { StartOSDiskInfo } from '../types/api' import { StartOSDiskInfo } from '../types/api'
@Component({ @Component({
standalone: true,
selector: 'button[server]', selector: 'button[server]',
template: ` template: `
<tui-icon icon="@tui.save" /> <tui-icon icon="@tui.save" />
@@ -21,7 +20,12 @@ import { StartOSDiskInfo } from '../types/api'
</span> </span>
</span> </span>
`, `,
styles: ':host { width: stretch; border-radius: var(--tui-radius-l); }', styles: `
:host {
border-radius: var(--tui-radius-l);
}
`,
host: { class: 'g-stretch' },
hostDirectives: [TuiCell], hostDirectives: [TuiCell],
imports: [DatePipe, TuiIcon, TuiTitle], imports: [DatePipe, TuiIcon, TuiTitle],
}) })

View File

@@ -7,7 +7,6 @@ import {
} from '@angular/core' } from '@angular/core'
@Component({ @Component({
standalone: true,
selector: '[ticker]', selector: '[ticker]',
template: '<ng-content />', template: '<ng-content />',
styles: ` styles: `

View File

@@ -10,7 +10,6 @@ export const VERSION = new InjectionToken<string>('VERSION')
@Directive({ @Directive({
selector: '[docsLink]', selector: '[docsLink]',
standalone: true,
host: { host: {
target: '_blank', target: '_blank',
rel: 'noreferrer', rel: 'noreferrer',

View File

@@ -1,59 +0,0 @@
import {
Directive,
ElementRef,
HostListener,
inject,
NgZone,
} from '@angular/core'
import { ANIMATION_FRAME } from '@ng-web-apis/common'
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'
import { tuiZonefree } from '@taiga-ui/cdk'
import { filter } from 'rxjs'
const SIZE = 100
const SPEED = 15
@Directive({
selector: '[dragScroller]',
standalone: true,
})
export class DragScrollerDirective {
private readonly element: HTMLElement = inject(ElementRef).nativeElement
private dragging = false
private x = 0
private y = 0
private readonly sub = inject(ANIMATION_FRAME)
.pipe(
filter(() => this.dragging),
tuiZonefree(inject(NgZone)),
takeUntilDestroyed(),
)
.subscribe(() => {
this.element.scrollTop += this.y * SPEED
this.element.scrollLeft += this.x * SPEED
})
@HostListener('document:pointerdown.silent', ['true'])
@HostListener('document:pointerup.silent', ['false'])
onPointer(dragging: boolean) {
this.dragging = dragging
this.x = 0
this.y = 0
}
@HostListener('pointermove.silent', ['$event'])
onPointerMove(event: PointerEvent) {
if (!this.dragging) {
return
}
const { clientX, clientY } = event
const { top, left, right, bottom } = this.element.getBoundingClientRect()
const x = Math.min(clientX - left, SIZE) - Math.min(right - clientX, SIZE)
const y = Math.min(clientY - top, SIZE) - Math.min(bottom - clientY, SIZE)
this.x = x / SIZE
this.y = y / SIZE
}
}

View File

@@ -16,7 +16,6 @@ import { tuiInjectElement } from '@taiga-ui/cdk'
subtree: true, subtree: true,
}), }),
], ],
standalone: true,
}) })
export class SafeLinksDirective { export class SafeLinksDirective {
private readonly doc = inject(DOCUMENT) private readonly doc = inject(DOCUMENT)

View File

@@ -519,4 +519,5 @@ export default {
517: 'Möchten Sie diese Aufgabe wirklich verwerfen?', 517: 'Möchten Sie diese Aufgabe wirklich verwerfen?',
518: 'Verwerfen', 518: 'Verwerfen',
519: 'Um Clearnet-Domains zu veröffentlichen, musst du oben auf „Öffentlich machen“ klicken.', 519: 'Um Clearnet-Domains zu veröffentlichen, musst du oben auf „Öffentlich machen“ klicken.',
520: 'Update verfügbar',
} satisfies i18n } satisfies i18n

View File

@@ -518,4 +518,5 @@ export const ENGLISH = {
'Are you sure you want to dismiss this task?': 517, 'Are you sure you want to dismiss this task?': 517,
'Dismiss': 518, // as in, dismiss or delete a task 'Dismiss': 518, // as in, dismiss or delete a task
'To publish clearnet domains, you must click "Make Public", above.': 519, 'To publish clearnet domains, you must click "Make Public", above.': 519,
'Update available': 520,
} as const } as const

View File

@@ -519,4 +519,5 @@ export default {
517: '¿Estás seguro de que deseas descartar esta tarea?', 517: '¿Estás seguro de que deseas descartar esta tarea?',
518: 'Descartar', 518: 'Descartar',
519: 'Para publicar dominios en clearnet, debes hacer clic en "Hacer público" arriba.', 519: 'Para publicar dominios en clearnet, debes hacer clic en "Hacer público" arriba.',
520: 'Actualización disponible',
} satisfies i18n } satisfies i18n

View File

@@ -519,4 +519,5 @@ export default {
517: 'Êtes-vous sûr de vouloir ignorer cette tâche ?', 517: 'Êtes-vous sûr de vouloir ignorer cette tâche ?',
518: 'Ignorer', 518: 'Ignorer',
519: 'Pour publier des domaines clearnet, vous devez cliquer sur « Rendre public » ci-dessus.', 519: 'Pour publier des domaines clearnet, vous devez cliquer sur « Rendre public » ci-dessus.',
520: 'Mise à jour disponible',
} satisfies i18n } satisfies i18n

View File

@@ -519,4 +519,5 @@ export default {
517: 'Czy na pewno chcesz odrzucić to zadanie?', 517: 'Czy na pewno chcesz odrzucić to zadanie?',
518: 'Odrzuć', 518: 'Odrzuć',
519: 'Aby opublikować domeny w clearnet, kliknij „Upublicznij” powyżej.', 519: 'Aby opublikować domeny w clearnet, kliknij „Upublicznij” powyżej.',
520: 'Aktualizacja dostępna',
} satisfies i18n } satisfies i18n

View File

@@ -3,7 +3,6 @@ import { ENGLISH } from './dictionaries/en'
import { I18N, i18nKey } from './i18n.providers' import { I18N, i18nKey } from './i18n.providers'
@Pipe({ @Pipe({
standalone: true,
name: 'i18n', name: 'i18n',
pure: false, pure: false,
}) })

View File

@@ -3,6 +3,7 @@ import { Exver } from '../../services/exver.service'
@Pipe({ @Pipe({
name: 'satisfiesExver', name: 'satisfiesExver',
standalone: false,
}) })
export class ExverSatisfiesPipe implements PipeTransform { export class ExverSatisfiesPipe implements PipeTransform {
constructor(private readonly exver: Exver) {} constructor(private readonly exver: Exver) {}
@@ -18,6 +19,7 @@ export class ExverSatisfiesPipe implements PipeTransform {
@Pipe({ @Pipe({
name: 'compareExver', name: 'compareExver',
standalone: false,
}) })
export class ExverComparesPipe implements PipeTransform { export class ExverComparesPipe implements PipeTransform {
constructor(private readonly exver: Exver) {} constructor(private readonly exver: Exver) {}

View File

@@ -2,7 +2,6 @@ import { Pipe, PipeTransform } from '@angular/core'
import { marked } from 'marked' import { marked } from 'marked'
@Pipe({ @Pipe({
standalone: true,
name: 'markdown', name: 'markdown',
}) })
export class MarkdownPipe implements PipeTransform { export class MarkdownPipe implements PipeTransform {

View File

@@ -3,6 +3,7 @@ import { isEmptyObject } from '../../util/misc.util'
@Pipe({ @Pipe({
name: 'empty', name: 'empty',
standalone: false,
}) })
export class EmptyPipe implements PipeTransform { export class EmptyPipe implements PipeTransform {
transform(val: object | [] = {}): boolean { transform(val: object | [] = {}): boolean {

View File

@@ -2,6 +2,7 @@ import { Pipe, PipeTransform } from '@angular/core'
@Pipe({ @Pipe({
name: 'includes', name: 'includes',
standalone: false,
}) })
export class IncludesPipe implements PipeTransform { export class IncludesPipe implements PipeTransform {
transform<T>(list: T[], val: T): boolean { transform<T>(list: T[], val: T): boolean {

View File

@@ -2,6 +2,7 @@ import { Pipe, PipeTransform } from '@angular/core'
@Pipe({ @Pipe({
name: 'sort', name: 'sort',
standalone: false,
}) })
export class SortPipe implements PipeTransform { export class SortPipe implements PipeTransform {
transform( transform(

View File

@@ -3,6 +3,7 @@ import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'
@Pipe({ @Pipe({
name: 'trustUrl', name: 'trustUrl',
standalone: false,
}) })
export class TrustUrlPipe implements PipeTransform { export class TrustUrlPipe implements PipeTransform {
constructor(private readonly sanitizer: DomSanitizer) {} constructor(private readonly sanitizer: DomSanitizer) {}

View File

@@ -3,6 +3,7 @@ import { Pipe, PipeTransform } from '@angular/core'
// converts bytes to gigabytes // converts bytes to gigabytes
@Pipe({ @Pipe({
name: 'convertBytes', name: 'convertBytes',
standalone: false,
}) })
export class ConvertBytesPipe implements PipeTransform { export class ConvertBytesPipe implements PipeTransform {
transform(bytes: number): string { transform(bytes: number): string {
@@ -21,6 +22,7 @@ export function convertBytes(bytes: number): string {
@Pipe({ @Pipe({
name: 'durationToSeconds', name: 'durationToSeconds',
standalone: false,
}) })
export class DurationToSecondsPipe implements PipeTransform { export class DurationToSecondsPipe implements PipeTransform {
transform(duration?: string | null): number { transform(duration?: string | null): number {

View File

@@ -14,7 +14,6 @@ export * from './components/prompt.component'
export * from './components/server.component' export * from './components/server.component'
export * from './directives/docs-link.directive' export * from './directives/docs-link.directive'
export * from './directives/drag-scroller.directive'
export * from './directives/safe-links.directive' export * from './directives/safe-links.directive'
export * from './i18n/i18n.pipe' export * from './i18n/i18n.pipe'

View File

@@ -6,7 +6,6 @@ import { i18nPipe } from '../i18n/i18n.pipe'
import { i18nKey } from '../i18n/i18n.providers' import { i18nKey } from '../i18n/i18n.providers'
@Component({ @Component({
standalone: true,
template: '<tui-loader [textContent]="content | i18n" />', template: '<tui-loader [textContent]="content | i18n" />',
styles: ` styles: `
:host { :host {

View File

@@ -1,4 +1,4 @@
@import '@taiga-ui/core/styles/taiga-ui-local'; @use '@taiga-ui/core/styles/taiga-ui-local' as taiga;
[tuiTheme='dark'] { [tuiTheme='dark'] {
--tui-background-base: rgba(23, 23, 23, 1); --tui-background-base: rgba(23, 23, 23, 1);
@@ -89,7 +89,7 @@
} }
[tuiAppearance][data-appearance^='primary'] { [tuiAppearance][data-appearance^='primary'] {
@include appearance-disabled { @include taiga.appearance-disabled {
background: var(--tui-status-neutral); background: var(--tui-status-neutral);
color: #333; color: #333;
} }
@@ -99,15 +99,15 @@
color: var(--tui-text-primary-on-accent-1); color: var(--tui-text-primary-on-accent-1);
background: var(--tui-status-positive); background: var(--tui-status-positive);
@include appearance-hover { @include taiga.appearance-hover {
filter: brightness(1.2); filter: brightness(1.2);
} }
@include appearance-active { @include taiga.appearance-active {
filter: brightness(0.9); filter: brightness(0.9);
} }
@include appearance-disabled { @include taiga.appearance-disabled {
background: var(--tui-status-neutral); background: var(--tui-status-neutral);
color: #333; color: #333;
} }

View File

@@ -26,6 +26,7 @@ import { PatchMonitorService } from './services/patch-monitor.service'
font-family: 'Proxima Nova', sans-serif; font-family: 'Proxima Nova', sans-serif;
} }
`, `,
standalone: false,
}) })
export class AppComponent { export class AppComponent {
private readonly i18n = inject(i18nService) private readonly i18n = inject(i18nService)

View File

@@ -1,4 +1,4 @@
import { HttpClientModule } from '@angular/common/http' import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
import { NgModule } from '@angular/core' import { NgModule } from '@angular/core'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations' import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
import { ServiceWorkerModule } from '@angular/service-worker' import { ServiceWorkerModule } from '@angular/service-worker'
@@ -12,7 +12,6 @@ import { RoutingModule } from './routing.module'
@NgModule({ @NgModule({
declarations: [AppComponent], declarations: [AppComponent],
imports: [ imports: [
HttpClientModule,
BrowserAnimationsModule, BrowserAnimationsModule,
RoutingModule, RoutingModule,
ToastContainerComponent, ToastContainerComponent,
@@ -24,7 +23,7 @@ import { RoutingModule } from './routing.module'
registrationStrategy: 'registerWhenStable:30000', registrationStrategy: 'registerWhenStable:30000',
}), }),
], ],
providers: APP_PROVIDERS, providers: [APP_PROVIDERS, provideHttpClient(withInterceptorsFromDi())],
bootstrap: [AppComponent], bootstrap: [AppComponent],
}) })
export class AppModule {} export class AppModule {}

View File

@@ -1,6 +1,8 @@
import { APP_INITIALIZER, inject, Provider } from '@angular/core' import { inject, provideAppInitializer } from '@angular/core'
import { UntypedFormBuilder } from '@angular/forms' import { UntypedFormBuilder } from '@angular/forms'
import { Router } from '@angular/router' import { Router } from '@angular/router'
import { WA_LOCATION } from '@ng-web-apis/common'
import initArgon from '@start9labs/argon2'
import { import {
AbstractCategoryService, AbstractCategoryService,
FilterPackagesPipe, FilterPackagesPipe,
@@ -50,7 +52,7 @@ const {
ui: { api }, ui: { api },
} = require('../../../../config.json') as WorkspaceConfig } = require('../../../../config.json') as WorkspaceConfig
export const APP_PROVIDERS: Provider[] = [ export const APP_PROVIDERS = [
provideEventPlugins(), provideEventPlugins(),
I18N_PROVIDERS, I18N_PROVIDERS,
FilterPackagesPipe, FilterPackagesPipe,
@@ -86,11 +88,18 @@ export const APP_PROVIDERS: Provider[] = [
deps: [PatchDbSource, PATCH_CACHE], deps: [PatchDbSource, PATCH_CACHE],
useClass: PatchDB, useClass: PatchDB,
}, },
{ provideAppInitializer(() => {
provide: APP_INITIALIZER, const i18n = inject(i18nService)
useFactory: appInitializer, const origin = inject(WA_LOCATION).origin
multi: true, const module_or_path = new URL('/assets/argon2_bg.wasm', origin)
},
initArgon({ module_or_path })
inject(StorageService).migrate036()
inject(AuthService).init()
inject(ClientStorageService).init()
inject(Router).initialNavigation()
i18n.setLanguage(i18n.language || 'english')
}),
{ {
provide: RELATIVE_URL, provide: RELATIVE_URL,
useValue: `/${api.url}/${api.version}`, useValue: `/${api.url}/${api.version}`,
@@ -123,19 +132,3 @@ export const APP_PROVIDERS: Provider[] = [
useFactory: () => inject(ConfigService).version, useFactory: () => inject(ConfigService).version,
}, },
] ]
export function appInitializer(): () => void {
const storage = inject(StorageService)
const auth = inject(AuthService)
const localStorage = inject(ClientStorageService)
const router = inject(Router)
const i18n = inject(i18nService)
return () => {
storage.migrate036()
auth.init()
localStorage.init()
router.initialNavigation()
i18n.setLanguage(i18n.language || 'english')
}
}

View File

@@ -45,7 +45,6 @@ import { BackupReport } from 'src/app/services/api/api.types'
} }
`, `,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, TuiIcon, TuiCell, TuiTitle, i18nPipe], imports: [CommonModule, TuiIcon, TuiCell, TuiTitle, i18nPipe],
}) })
export class BackupsReportModal { export class BackupsReportModal {

View File

@@ -8,7 +8,6 @@ import { endWith, map, merge, Observable, pairwise, Subject } from 'rxjs'
import { DataModel } from 'src/app/services/patch-db/data-model' import { DataModel } from 'src/app/services/patch-db/data-model'
@Component({ @Component({
standalone: true,
selector: 'notifications-toast', selector: 'notifications-toast',
template: ` template: `
<ng-template <ng-template

View File

@@ -13,7 +13,6 @@ import { ConfigService } from 'src/app/services/config.service'
import { DataModel } from 'src/app/services/patch-db/data-model' import { DataModel } from 'src/app/services/patch-db/data-model'
@Component({ @Component({
standalone: true,
selector: 'refresh-alert', selector: 'refresh-alert',
template: ` template: `
<ng-template <ng-template

View File

@@ -3,7 +3,6 @@ import { NotificationsToastComponent } from './notifications-toast.component'
import { RefreshAlertComponent } from './refresh-alert.component' import { RefreshAlertComponent } from './refresh-alert.component'
@Component({ @Component({
standalone: true,
selector: 'toast-container', selector: 'toast-container',
template: ` template: `
<notifications-toast /> <notifications-toast />

View File

@@ -9,6 +9,7 @@ import { ConfigService } from 'src/app/services/config.service'
selector: 'diagnostic-home', selector: 'diagnostic-home',
templateUrl: 'home.page.html', templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'], styleUrls: ['home.page.scss'],
standalone: false,
}) })
export class HomePage { export class HomePage {
restarted = false restarted = false

View File

@@ -8,11 +8,10 @@ import { WaMutationObserver } from '@ng-web-apis/mutation-observer'
import { convertAnsi, ErrorService } from '@start9labs/shared' import { convertAnsi, ErrorService } from '@start9labs/shared'
import { tuiProvide } from '@taiga-ui/cdk' import { tuiProvide } from '@taiga-ui/cdk'
import { TuiButton, TuiLoader, TuiScrollbar } from '@taiga-ui/core' import { TuiButton, TuiLoader, TuiScrollbar } from '@taiga-ui/core'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify' import { NgDompurifyPipe } from '@taiga-ui/dompurify'
import { ApiService } from 'src/app/services/api/embassy-api.service' import { ApiService } from 'src/app/services/api/embassy-api.service'
@Component({ @Component({
standalone: true,
template: ` template: `
<a <a
routerLink="../" routerLink="../"
@@ -48,12 +47,16 @@ import { ApiService } from 'src/app/services/api/embassy-api.service'
gap: 1rem; gap: 1rem;
background: var(--tui-background-base); background: var(--tui-background-base);
} }
pre {
white-space: normal;
}
`, `,
imports: [ imports: [
RouterLink, RouterLink,
WaIntersectionObserver, WaIntersectionObserver,
WaMutationObserver, WaMutationObserver,
NgDompurifyModule, NgDompurifyPipe,
TuiButton, TuiButton,
TuiLoader, TuiLoader,
TuiScrollbar, TuiScrollbar,

View File

@@ -11,7 +11,6 @@ import { ApiService } from 'src/app/services/api/embassy-api.service'
import { StateService } from 'src/app/services/state.service' import { StateService } from 'src/app/services/state.service'
@Component({ @Component({
standalone: true,
template: ` template: `
<app-initializing [progress]="progress()" /> <app-initializing [progress]="progress()" />
`, `,

View File

@@ -7,7 +7,6 @@ import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ConfigService } from 'src/app/services/config.service' import { ConfigService } from 'src/app/services/config.service'
@Component({ @Component({
standalone: true,
selector: 'ca-wizard', selector: 'ca-wizard',
templateUrl: './ca-wizard.component.html', templateUrl: './ca-wizard.component.html',
styleUrls: ['./ca-wizard.component.scss'], styleUrls: ['./ca-wizard.component.scss'],

View File

@@ -1,7 +1,7 @@
@import '@taiga-ui/core/styles/taiga-ui-local'; @use '@taiga-ui/core/styles/taiga-ui-local' as taiga;
.card { .card {
@include center-all(); @include taiga.center-all();
overflow: visible; overflow: visible;
align-items: center; align-items: center;
text-align: center; text-align: center;
@@ -11,7 +11,7 @@
} }
.logo { .logo {
@include center-left(); @include taiga.center-left();
top: -17%; top: -17%;
width: 6rem; width: 6rem;
} }

View File

@@ -12,6 +12,7 @@ import { DOCUMENT } from '@angular/common'
templateUrl: './login.page.html', templateUrl: './login.page.html',
styleUrls: ['./login.page.scss'], styleUrls: ['./login.page.scss'],
providers: [], providers: [],
standalone: false,
}) })
export class LoginPage { export class LoginPage {
password = '' password = ''

View File

@@ -35,7 +35,6 @@ export interface FormContext<T> {
} }
@Component({ @Component({
standalone: true,
selector: 'app-form', selector: 'app-form',
template: ` template: `
<form <form
@@ -71,22 +70,20 @@ export interface FormContext<T> {
</footer> </footer>
</form> </form>
`, `,
styles: [ styles: `
` footer {
footer { position: sticky;
position: sticky; bottom: 0;
bottom: 0; z-index: 10;
z-index: 10; display: flex;
display: flex; justify-content: flex-end;
justify-content: flex-end; padding: 1rem 0;
padding: 1rem 0; margin: 1rem -1px -1rem;
margin: 1rem -1px -1rem; gap: 1rem;
gap: 1rem; background: var(--tui-background-elevation-1);
background: var(--tui-background-elevation-1); border-top: 1px solid var(--tui-background-base-alt);
border-top: 1px solid var(--tui-background-base-alt); }
} `,
`,
],
imports: [ imports: [
CommonModule, CommonModule,
ReactiveFormsModule, ReactiveFormsModule,

View File

@@ -4,6 +4,7 @@ import { InvalidService } from './invalid.service'
@Directive({ @Directive({
selector: 'form-control, form-array, form-object', selector: 'form-control, form-array, form-object',
standalone: false,
}) })
export class ControlDirective implements OnInit, OnDestroy { export class ControlDirective implements OnInit, OnDestroy {
private readonly invalidService = inject(InvalidService, { optional: true }) private readonly invalidService = inject(InvalidService, { optional: true })

View File

@@ -4,6 +4,7 @@ import { KeyValue } from '@angular/common'
@Pipe({ @Pipe({
name: 'filterHidden', name: 'filterHidden',
standalone: false,
}) })
export class FilterHiddenPipe implements PipeTransform { export class FilterHiddenPipe implements PipeTransform {
transform(value: KeyValue<string, IST.ValueSpec>[]) { transform(value: KeyValue<string, IST.ValueSpec>[]) {

View File

@@ -1,4 +1,4 @@
@import '@taiga-ui/core/styles/taiga-ui-local'; @use '@taiga-ui/core/styles/taiga-ui-local' as taiga;
:host { :host {
display: block; display: block;
@@ -27,7 +27,7 @@
} }
&::after { &::after {
@include transition(opacity); @include taiga.transition(opacity);
content: ''; content: '';
position: absolute; position: absolute;

View File

@@ -25,6 +25,7 @@ import { DialogService, i18nKey } from '@start9labs/shared'
templateUrl: './form-array.component.html', templateUrl: './form-array.component.html',
styleUrls: ['./form-array.component.scss'], styleUrls: ['./form-array.component.scss'],
animations: [tuiFadeIn, tuiHeightCollapse, tuiParentStop], animations: [tuiFadeIn, tuiHeightCollapse, tuiParentStop],
standalone: false,
}) })
export class FormArrayComponent { export class FormArrayComponent {
@Input({ required: true }) @Input({ required: true })

View File

@@ -1,4 +1,4 @@
@import '@taiga-ui/core/styles/taiga-ui-local'; @use '@taiga-ui/core/styles/taiga-ui-local' as taiga;
.wrapper { .wrapper {
position: relative; position: relative;
@@ -19,12 +19,12 @@
} }
.color { .color {
@include fullsize(); @include taiga.fullsize();
opacity: 0; opacity: 0;
} }
.icon { .icon {
@include fullsize(); @include taiga.fullsize();
pointer-events: none; pointer-events: none;
input:hover + & { input:hover + & {

View File

@@ -7,6 +7,7 @@ import { MaskitoOptions } from '@maskito/core'
selector: 'form-color', selector: 'form-color',
templateUrl: './form-color.component.html', templateUrl: './form-color.component.html',
styleUrls: ['./form-color.component.scss'], styleUrls: ['./form-color.component.scss'],
standalone: false,
}) })
export class FormColorComponent extends Control<IST.ValueSpecColor, string> { export class FormColorComponent extends Control<IST.ValueSpecColor, string> {
readonly mask: MaskitoOptions = { readonly mask: MaskitoOptions = {

View File

@@ -21,6 +21,7 @@ import { DialogService, i18nKey, i18nPipe } from '@start9labs/shared'
styleUrls: ['./form-control.component.scss'], styleUrls: ['./form-control.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
providers: FORM_CONTROL_PROVIDERS, providers: FORM_CONTROL_PROVIDERS,
standalone: false,
}) })
export class FormControlComponent< export class FormControlComponent<
T extends Exclude<IST.ValueSpec, IST.ValueSpecHidden>, T extends Exclude<IST.ValueSpec, IST.ValueSpecHidden>,

View File

@@ -12,6 +12,7 @@ import { Control } from '../control'
@Component({ @Component({
selector: 'form-datetime', selector: 'form-datetime',
templateUrl: './form-datetime.component.html', templateUrl: './form-datetime.component.html',
standalone: false,
}) })
export class FormDatetimeComponent extends Control< export class FormDatetimeComponent extends Control<
IST.ValueSpecDatetime, IST.ValueSpecDatetime,

View File

@@ -1,7 +1,7 @@
@import '@taiga-ui/core/styles/taiga-ui-local'; @use '@taiga-ui/core/styles/taiga-ui-local' as taiga;
.template { .template {
@include transition(opacity); @include taiga.transition(opacity);
width: 100%; width: 100%;
display: flex; display: flex;
@@ -16,8 +16,8 @@
} }
.drop { .drop {
@include fullsize(); @include taiga.fullsize();
@include transition(opacity); @include taiga.transition(opacity);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-around; justify-content: space-around;

View File

@@ -7,6 +7,7 @@ import { Control } from '../control'
selector: 'form-file', selector: 'form-file',
templateUrl: './form-file.component.html', templateUrl: './form-file.component.html',
styleUrls: ['./form-file.component.scss'], styleUrls: ['./form-file.component.scss'],
standalone: false,
}) })
export class FormFileComponent extends Control< export class FormFileComponent extends Control<
IST.ValueSpecFile, IST.ValueSpecFile,

View File

@@ -25,6 +25,7 @@ export const ERRORS = [
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
viewProviders: [FORM_GROUP_PROVIDERS], viewProviders: [FORM_GROUP_PROVIDERS],
standalone: false,
}) })
export class FormGroupComponent { export class FormGroupComponent {
@Input() spec: IST.InputSpec = {} @Input() spec: IST.InputSpec = {}

View File

@@ -7,6 +7,7 @@ import { invert } from '@start9labs/shared'
@Component({ @Component({
selector: 'form-multiselect', selector: 'form-multiselect',
templateUrl: './form-multiselect.component.html', templateUrl: './form-multiselect.component.html',
standalone: false,
}) })
export class FormMultiselectComponent extends Control< export class FormMultiselectComponent extends Control<
IST.ValueSpecMultiselect, IST.ValueSpecMultiselect,

View File

@@ -5,6 +5,7 @@ import { Control } from '../control'
@Component({ @Component({
selector: 'form-number', selector: 'form-number',
templateUrl: './form-number.component.html', templateUrl: './form-number.component.html',
standalone: false,
}) })
export class FormNumberComponent extends Control<IST.ValueSpecNumber, number> { export class FormNumberComponent extends Control<IST.ValueSpecNumber, number> {
protected readonly Infinity = Infinity protected readonly Infinity = Infinity

View File

@@ -1,4 +1,4 @@
@import '@taiga-ui/core/styles/taiga-ui-local'; @use '@taiga-ui/core/styles/taiga-ui-local' as taiga;
:host { :host {
display: flex; display: flex;
@@ -18,7 +18,7 @@
} }
.button { .button {
@include transition(transform); @include taiga.transition(transform);
margin-right: 1rem; margin-right: 1rem;

View File

@@ -14,6 +14,7 @@ import { IST } from '@start9labs/start-sdk'
templateUrl: './form-object.component.html', templateUrl: './form-object.component.html',
styleUrls: ['./form-object.component.scss'], styleUrls: ['./form-object.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
}) })
export class FormObjectComponent { export class FormObjectComponent {
@Input({ required: true }) @Input({ required: true })

View File

@@ -6,6 +6,7 @@ import { Control } from '../control'
@Component({ @Component({
selector: 'form-select', selector: 'form-select',
templateUrl: './form-select.component.html', templateUrl: './form-select.component.html',
standalone: false,
}) })
export class FormSelectComponent extends Control<IST.ValueSpecSelect, string> { export class FormSelectComponent extends Control<IST.ValueSpecSelect, string> {
private readonly inverted = invert(this.spec.values) private readonly inverted = invert(this.spec.values)

View File

@@ -6,6 +6,7 @@ import { Control } from '../control'
selector: 'form-text', selector: 'form-text',
templateUrl: './form-text.component.html', templateUrl: './form-text.component.html',
styleUrls: ['./form-text.component.scss'], styleUrls: ['./form-text.component.scss'],
standalone: false,
}) })
export class FormTextComponent extends Control<IST.ValueSpecText, string> { export class FormTextComponent extends Control<IST.ValueSpecText, string> {
masked = true masked = true

Some files were not shown because too many files have changed in this diff Show More