mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-04 14:29:45 +00:00
feat: migrate to Angular 14 and RxJS 7 (#1681)
* feat: migrate to Angular 14 and RxJS 7 * chore: update ng-qrcode * chore: update patch-db * chore: remove unnecessary generics
This commit is contained in:
@@ -426,9 +426,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultProject": "ui",
|
|
||||||
"cli": {
|
"cli": {
|
||||||
"defaultCollection": "@ionic/angular-toolkit"
|
"schematicCollections": ["@ionic/angular-toolkit"]
|
||||||
},
|
},
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"@ionic/angular-toolkit:component": {
|
"@ionic/angular-toolkit:component": {
|
||||||
|
|||||||
9028
frontend/package-lock.json
generated
9028
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -22,15 +22,15 @@
|
|||||||
"build-config": "node build-config.js"
|
"build-config": "node build-config.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^13.3.0",
|
"@angular/animations": "^14.1.0",
|
||||||
"@angular/common": "^13.3.0",
|
"@angular/common": "^14.1.0",
|
||||||
"@angular/compiler": "^13.3.0",
|
"@angular/compiler": "^14.1.0",
|
||||||
"@angular/core": "^13.3.0",
|
"@angular/core": "^14.1.0",
|
||||||
"@angular/forms": "^13.3.0",
|
"@angular/forms": "^14.1.0",
|
||||||
"@angular/platform-browser": "^13.3.0",
|
"@angular/platform-browser": "^14.1.0",
|
||||||
"@angular/platform-browser-dynamic": "^13.3.0",
|
"@angular/platform-browser-dynamic": "^14.1.0",
|
||||||
"@angular/router": "^13.3.0",
|
"@angular/router": "^14.1.0",
|
||||||
"@ionic/angular": "^6.0.13",
|
"@ionic/angular": "^6.1.15",
|
||||||
"@ionic/storage-angular": "^3.0.6",
|
"@ionic/storage-angular": "^3.0.6",
|
||||||
"@materia-ui/ngx-monaco-editor": "^6.0.0",
|
"@materia-ui/ngx-monaco-editor": "^6.0.0",
|
||||||
"@start9labs/argon2": "^0.1.0",
|
"@start9labs/argon2": "^0.1.0",
|
||||||
@@ -47,10 +47,10 @@
|
|||||||
"marked": "^4.0.0",
|
"marked": "^4.0.0",
|
||||||
"monaco-editor": "^0.33.0",
|
"monaco-editor": "^0.33.0",
|
||||||
"mustache": "^4.2.0",
|
"mustache": "^4.2.0",
|
||||||
"ng-qrcode": "^6.0.0",
|
"ng-qrcode": "^7.0.0",
|
||||||
"patch-db-client": "file: ../../../patch-db/client",
|
"patch-db-client": "file: ../../../patch-db/client",
|
||||||
"pbkdf2": "^3.1.2",
|
"pbkdf2": "^3.1.2",
|
||||||
"rxjs": "^6.6.7",
|
"rxjs": "^7.5.6",
|
||||||
"swiper": "^8.2.4",
|
"swiper": "^8.2.4",
|
||||||
"ts-matches": "^5.1.7",
|
"ts-matches": "^5.1.7",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
@@ -58,10 +58,10 @@
|
|||||||
"zone.js": "^0.11.5"
|
"zone.js": "^0.11.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^13.1.4",
|
"@angular-devkit/build-angular": "^14.1.0",
|
||||||
"@angular/cli": "^13.1.4",
|
"@angular/cli": "^14.1.0",
|
||||||
"@angular/compiler-cli": "^13.3.0",
|
"@angular/compiler-cli": "^14.1.0",
|
||||||
"@angular/language-service": "^13.3.0",
|
"@angular/language-service": "^14.1.0",
|
||||||
"@ionic/cli": "^6.19.0",
|
"@ionic/cli": "^6.19.0",
|
||||||
"@types/aes-js": "^3.1.1",
|
"@types/aes-js": "^3.1.1",
|
||||||
"@types/dompurify": "^2.3.3",
|
"@types/dompurify": "^2.3.3",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"@types/uuid": "^8.3.1",
|
"@types/uuid": "^8.3.1",
|
||||||
"husky": "^4.3.8",
|
"husky": "^4.3.8",
|
||||||
"lint-staged": "^12.3.7",
|
"lint-staged": "^12.3.7",
|
||||||
"ng-packagr": "^13.3.0",
|
"ng-packagr": "^14.1.0",
|
||||||
"node-html-parser": "^5.3.3",
|
"node-html-parser": "^5.3.3",
|
||||||
"prettier": "^2.6.1",
|
"prettier": "^2.6.1",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ const { useMocks } = require('../../../../config.json') as WorkspaceConfig
|
|||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [AppComponent],
|
declarations: [AppComponent],
|
||||||
entryComponents: [],
|
|
||||||
imports: [
|
imports: [
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { HttpClient } from '@angular/common/http'
|
import { HttpClient } from '@angular/common/http'
|
||||||
import { HttpError, RpcError } from '@start9labs/shared'
|
import { HttpError, RpcError } from '@start9labs/shared'
|
||||||
|
import { firstValueFrom } from 'rxjs'
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -16,13 +17,9 @@ export class HttpService {
|
|||||||
|
|
||||||
async httpRequest<T>(body: RPCOptions): Promise<T> {
|
async httpRequest<T>(body: RPCOptions): Promise<T> {
|
||||||
const url = `${window.location.protocol}//${window.location.hostname}:${window.location.port}/rpc/v1`
|
const url = `${window.location.protocol}//${window.location.hostname}:${window.location.port}/rpc/v1`
|
||||||
return this.http
|
return firstValueFrom(this.http.post<T>(url, body)).catch(e => {
|
||||||
.post(url, body)
|
throw new HttpError(e)
|
||||||
.toPromise()
|
})
|
||||||
.then(a => a as T)
|
|
||||||
.catch(e => {
|
|
||||||
throw new HttpError(e)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ const { useMocks } = require('../../../../config.json') as WorkspaceConfig
|
|||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [AppComponent],
|
declarations: [AppComponent],
|
||||||
entryComponents: [],
|
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
IonicModule.forRoot({
|
IonicModule.forRoot({
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import {
|
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'
|
||||||
HttpClient,
|
import { firstValueFrom, Observable } from 'rxjs'
|
||||||
HttpErrorResponse,
|
|
||||||
HttpHeaders,
|
|
||||||
HttpParams,
|
|
||||||
} from '@angular/common/http'
|
|
||||||
import { Observable } from 'rxjs'
|
|
||||||
import * as aesjs from 'aes-js'
|
import * as aesjs from 'aes-js'
|
||||||
import * as pbkdf2 from 'pbkdf2'
|
import * as pbkdf2 from 'pbkdf2'
|
||||||
import { HttpError, RpcError } from '@start9labs/shared'
|
import { HttpError, RpcError } from '@start9labs/shared'
|
||||||
@@ -70,8 +65,7 @@ export class HttpService {
|
|||||||
|
|
||||||
const req = this.http.post(url, options.body, options)
|
const req = this.http.post(url, options.body, options)
|
||||||
|
|
||||||
return req
|
return firstValueFrom(req)
|
||||||
.toPromise()
|
|
||||||
.then(res =>
|
.then(res =>
|
||||||
AES_CTR.decryptPbkdf2(
|
AES_CTR.decryptPbkdf2(
|
||||||
this.productKey || '',
|
this.productKey || '',
|
||||||
@@ -112,8 +106,7 @@ export class HttpService {
|
|||||||
options,
|
options,
|
||||||
) as any
|
) as any
|
||||||
|
|
||||||
return req
|
return firstValueFrom(req)
|
||||||
.toPromise()
|
|
||||||
.then(res => res.body)
|
.then(res => res.body)
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
throw new HttpError(e)
|
throw new HttpError(e)
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ export function partitionArray<T>(
|
|||||||
ts: T[],
|
ts: T[],
|
||||||
condition: (t: T) => boolean,
|
condition: (t: T) => boolean,
|
||||||
): [T[], T[]] {
|
): [T[], T[]] {
|
||||||
const yes = [] as T[]
|
const yes: T[] = []
|
||||||
const no = [] as T[]
|
const no: T[] = []
|
||||||
ts.forEach(t => {
|
ts.forEach(t => {
|
||||||
if (condition(t)) {
|
if (condition(t)) {
|
||||||
yes.push(t)
|
yes.push(t)
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import { PatchDbModule } from './services/patch-db/patch-db.module'
|
|||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [AppComponent],
|
declarations: [AppComponent],
|
||||||
entryComponents: [],
|
|
||||||
imports: [
|
imports: [
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Bootstrapper, DBCache } from 'patch-db-client'
|
import { Bootstrapper, DBCache } from 'patch-db-client'
|
||||||
import { APP_INITIALIZER, ErrorHandler, Provider } from '@angular/core'
|
import { APP_INITIALIZER, ErrorHandler, Provider } from '@angular/core'
|
||||||
import { FormBuilder } from '@angular/forms'
|
import { UntypedFormBuilder } from '@angular/forms'
|
||||||
import { Router, RouteReuseStrategy } from '@angular/router'
|
import { Router, RouteReuseStrategy } from '@angular/router'
|
||||||
import { IonicRouteStrategy, IonNav } from '@ionic/angular'
|
import { IonicRouteStrategy, IonNav } from '@ionic/angular'
|
||||||
import { Storage } from '@ionic/storage-angular'
|
import { Storage } from '@ionic/storage-angular'
|
||||||
@@ -20,7 +20,7 @@ const { useMocks } = require('../../../../config.json') as WorkspaceConfig
|
|||||||
|
|
||||||
export const APP_PROVIDERS: Provider[] = [
|
export const APP_PROVIDERS: Provider[] = [
|
||||||
FilterPackagesPipe,
|
FilterPackagesPipe,
|
||||||
FormBuilder,
|
UntypedFormBuilder,
|
||||||
IonNav,
|
IonNav,
|
||||||
{
|
{
|
||||||
provide: RouteReuseStrategy,
|
provide: RouteReuseStrategy,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { ApiService } from '../../services/api/embassy-api.service'
|
|||||||
import { AppWizardComponent, SlideDefinition } from './app-wizard.component'
|
import { AppWizardComponent, SlideDefinition } from './app-wizard.component'
|
||||||
import { ConfigService } from 'src/app/services/config.service'
|
import { ConfigService } from 'src/app/services/config.service'
|
||||||
import { MarketplaceService } from 'src/app/services/marketplace.service'
|
import { MarketplaceService } from 'src/app/services/marketplace.service'
|
||||||
|
import { firstValueFrom } from 'rxjs'
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class WizardDefs {
|
export class WizardDefs {
|
||||||
@@ -39,12 +40,12 @@ export class WizardDefs {
|
|||||||
verb: 'beginning update for',
|
verb: 'beginning update for',
|
||||||
title,
|
title,
|
||||||
Fn: () =>
|
Fn: () =>
|
||||||
this.marketplaceService
|
firstValueFrom(
|
||||||
.installPackage({
|
this.marketplaceService.installPackage({
|
||||||
id,
|
id,
|
||||||
'version-spec': version ? `=${version}` : undefined,
|
'version-spec': version ? `=${version}` : undefined,
|
||||||
})
|
}),
|
||||||
.toPromise(),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -80,12 +81,12 @@ export class WizardDefs {
|
|||||||
verb: 'beginning downgrade for',
|
verb: 'beginning downgrade for',
|
||||||
title,
|
title,
|
||||||
Fn: () =>
|
Fn: () =>
|
||||||
this.marketplaceService
|
firstValueFrom(
|
||||||
.installPackage({
|
this.marketplaceService.installPackage({
|
||||||
id,
|
id,
|
||||||
'version-spec': version ? `=${version}` : undefined,
|
'version-spec': version ? `=${version}` : undefined,
|
||||||
})
|
}),
|
||||||
.toPromise(),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Component, Input, Output, EventEmitter } from '@angular/core'
|
import { Component, Input, Output, EventEmitter } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
AbstractFormGroupDirective,
|
AbstractFormGroupDirective,
|
||||||
FormArray,
|
UntypedFormArray,
|
||||||
FormGroup,
|
UntypedFormGroup,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import {
|
import {
|
||||||
AlertButton,
|
AlertButton,
|
||||||
@@ -36,7 +36,7 @@ interface Config {
|
|||||||
})
|
})
|
||||||
export class FormObjectComponent {
|
export class FormObjectComponent {
|
||||||
@Input() objectSpec!: ConfigSpec
|
@Input() objectSpec!: ConfigSpec
|
||||||
@Input() formGroup!: FormGroup
|
@Input() formGroup!: UntypedFormGroup
|
||||||
@Input() unionSpec?: ValueSpecUnion
|
@Input() unionSpec?: ValueSpecUnion
|
||||||
@Input() current?: Config
|
@Input() current?: Config
|
||||||
@Input() original?: Config
|
@Input() original?: Config
|
||||||
@@ -153,7 +153,7 @@ export class FormObjectComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addListItem(key: string, markDirty = true, val?: string): void {
|
addListItem(key: string, markDirty = true, val?: string): void {
|
||||||
const arr = this.formGroup.get(key) as FormArray
|
const arr = this.formGroup.get(key) as UntypedFormArray
|
||||||
if (markDirty) arr.markAsDirty()
|
if (markDirty) arr.markAsDirty()
|
||||||
const listSpec = this.objectSpec[key] as ValueSpecList
|
const listSpec = this.objectSpec[key] as ValueSpecList
|
||||||
const newItem = this.formService.getListItem(listSpec, val)
|
const newItem = this.formService.getListItem(listSpec, val)
|
||||||
@@ -330,7 +330,7 @@ export class FormObjectComponent {
|
|||||||
private deleteListItem(key: string, index: number, markDirty = true): void {
|
private deleteListItem(key: string, index: number, markDirty = true): void {
|
||||||
if (this.objectListDisplay[key])
|
if (this.objectListDisplay[key])
|
||||||
this.objectListDisplay[key][index].height = '0px'
|
this.objectListDisplay[key][index].height = '0px'
|
||||||
const arr = this.formGroup.get(key) as FormArray
|
const arr = this.formGroup.get(key) as UntypedFormArray
|
||||||
if (markDirty) arr.markAsDirty()
|
if (markDirty) arr.markAsDirty()
|
||||||
pauseFor(250).then(() => {
|
pauseFor(250).then(() => {
|
||||||
if (this.objectListDisplay[key])
|
if (this.objectListDisplay[key])
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { DependentInfo } from 'src/app/types/dependent-info'
|
|||||||
import { ConfigSpec } from 'src/app/pkg-config/config-types'
|
import { ConfigSpec } from 'src/app/pkg-config/config-types'
|
||||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||||
import { FormGroup } from '@angular/forms'
|
import { UntypedFormGroup } from '@angular/forms'
|
||||||
import {
|
import {
|
||||||
convertValuesRecursive,
|
convertValuesRecursive,
|
||||||
FormService,
|
FormService,
|
||||||
@@ -40,7 +40,7 @@ export class AppConfigPage {
|
|||||||
pkg!: PackageDataEntry
|
pkg!: PackageDataEntry
|
||||||
loadingText!: string
|
loadingText!: string
|
||||||
configSpec!: ConfigSpec
|
configSpec!: ConfigSpec
|
||||||
configForm!: FormGroup
|
configForm!: UntypedFormGroup
|
||||||
|
|
||||||
original?: object // only if existing config
|
original?: object // only if existing config
|
||||||
diff?: string[] // only if dependent info
|
diff?: string[] // only if dependent info
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
import { Component, Input } from '@angular/core'
|
||||||
import { FormGroup } from '@angular/forms'
|
import { UntypedFormGroup } from '@angular/forms'
|
||||||
import { ModalController } from '@ionic/angular'
|
import { ModalController } from '@ionic/angular'
|
||||||
import {
|
import {
|
||||||
convertValuesRecursive,
|
convertValuesRecursive,
|
||||||
@@ -25,7 +25,7 @@ export class GenericFormPage {
|
|||||||
@Input() initialValue: object = {}
|
@Input() initialValue: object = {}
|
||||||
|
|
||||||
submitBtn!: ActionButton
|
submitBtn!: ActionButton
|
||||||
formGroup!: FormGroup
|
formGroup!: UntypedFormGroup
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly modalCtrl: ModalController,
|
private readonly modalCtrl: ModalController,
|
||||||
|
|||||||
@@ -14,10 +14,6 @@ export class PackageInfoPipe implements PipeTransform {
|
|||||||
transform(pkg: PackageDataEntry): Observable<PkgInfo> {
|
transform(pkg: PackageDataEntry): Observable<PkgInfo> {
|
||||||
return this.patch
|
return this.patch
|
||||||
.watch$('package-data', pkg.manifest.id)
|
.watch$('package-data', pkg.manifest.id)
|
||||||
.pipe(
|
.pipe(filter(Boolean), startWith(pkg), map(getPackageInfo))
|
||||||
filter<PackageDataEntry>(Boolean),
|
|
||||||
startWith(pkg),
|
|
||||||
map(getPackageInfo),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { ApiService } from 'src/app/services/api/embassy-api.service'
|
|||||||
import { Breakages } from 'src/app/services/api/api.types'
|
import { Breakages } from 'src/app/services/api/api.types'
|
||||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||||
import { getAllPackages } from 'src/app/util/get-package-data'
|
import { getAllPackages } from 'src/app/util/get-package-data'
|
||||||
|
import { firstValueFrom } from 'rxjs'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'marketplace-show-controls',
|
selector: 'marketplace-show-controls',
|
||||||
@@ -136,12 +137,12 @@ export class MarketplaceShowControlsComponent {
|
|||||||
const { id, version } = this.pkg.manifest
|
const { id, version } = this.pkg.manifest
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.marketplaceService
|
await firstValueFrom(
|
||||||
.installPackage({
|
this.marketplaceService.installPackage({
|
||||||
id,
|
id,
|
||||||
'version-spec': `=${version}`,
|
'version-spec': `=${version}`,
|
||||||
})
|
}),
|
||||||
.toPromise()
|
)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
this.errToast.present(e)
|
this.errToast.present(e)
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -23,10 +23,7 @@ export class MarketplaceShowPage {
|
|||||||
|
|
||||||
readonly localPkg$ = this.patch
|
readonly localPkg$ = this.patch
|
||||||
.watch$('package-data', this.pkgId)
|
.watch$('package-data', this.pkgId)
|
||||||
.pipe(
|
.pipe(filter(Boolean), shareReplay({ bufferSize: 1, refCount: true }))
|
||||||
filter<PackageDataEntry>(Boolean),
|
|
||||||
shareReplay({ bufferSize: 1, refCount: true }),
|
|
||||||
)
|
|
||||||
|
|
||||||
readonly pkg$: Observable<MarketplacePkg | null> = this.loadVersion$.pipe(
|
readonly pkg$: Observable<MarketplacePkg | null> = this.loadVersion$.pipe(
|
||||||
switchMap(version =>
|
switchMap(version =>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormArray,
|
UntypedFormArray,
|
||||||
FormBuilder,
|
UntypedFormBuilder,
|
||||||
FormControl,
|
UntypedFormControl,
|
||||||
FormGroup,
|
UntypedFormGroup,
|
||||||
ValidatorFn,
|
ValidatorFn,
|
||||||
Validators,
|
Validators,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
@@ -31,12 +31,12 @@ const Mustache = require('mustache')
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class FormService {
|
export class FormService {
|
||||||
constructor(private readonly formBuilder: FormBuilder) {}
|
constructor(private readonly formBuilder: UntypedFormBuilder) {}
|
||||||
|
|
||||||
createForm(
|
createForm(
|
||||||
spec: ConfigSpec,
|
spec: ConfigSpec,
|
||||||
current: { [key: string]: any } = {},
|
current: { [key: string]: any } = {},
|
||||||
): FormGroup {
|
): UntypedFormGroup {
|
||||||
return this.getFormGroup(spec, [], current)
|
return this.getFormGroup(spec, [], current)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ export class FormService {
|
|||||||
spec: ValueSpecUnion | ListValueSpecUnion,
|
spec: ValueSpecUnion | ListValueSpecUnion,
|
||||||
selection: string,
|
selection: string,
|
||||||
current?: { [key: string]: any } | null,
|
current?: { [key: string]: any } | null,
|
||||||
): FormGroup {
|
): UntypedFormGroup {
|
||||||
const { variants, tag } = spec
|
const { variants, tag } = spec
|
||||||
const { name, description, warning } = isFullUnion(spec)
|
const { name, description, warning } = isFullUnion(spec)
|
||||||
? spec
|
? spec
|
||||||
@@ -85,8 +85,11 @@ export class FormService {
|
|||||||
config: ConfigSpec,
|
config: ConfigSpec,
|
||||||
validators: ValidatorFn[] = [],
|
validators: ValidatorFn[] = [],
|
||||||
current?: { [key: string]: any } | null,
|
current?: { [key: string]: any } | null,
|
||||||
): FormGroup {
|
): UntypedFormGroup {
|
||||||
let group: Record<string, FormGroup | FormArray | FormControl> = {}
|
let group: Record<
|
||||||
|
string,
|
||||||
|
UntypedFormGroup | UntypedFormArray | UntypedFormControl
|
||||||
|
> = {}
|
||||||
Object.entries(config).map(([key, spec]) => {
|
Object.entries(config).map(([key, spec]) => {
|
||||||
if (spec.type === 'pointer') return
|
if (spec.type === 'pointer') return
|
||||||
group[key] = this.getFormEntry(spec, current ? current[key] : undefined)
|
group[key] = this.getFormEntry(spec, current ? current[key] : undefined)
|
||||||
@@ -97,7 +100,7 @@ export class FormService {
|
|||||||
private getFormEntry(
|
private getFormEntry(
|
||||||
spec: ValueSpec,
|
spec: ValueSpec,
|
||||||
currentValue?: any,
|
currentValue?: any,
|
||||||
): FormGroup | FormArray | FormControl {
|
): UntypedFormGroup | UntypedFormArray | UntypedFormControl {
|
||||||
let validators: ValidatorFn[]
|
let validators: ValidatorFn[]
|
||||||
let value: any
|
let value: any
|
||||||
switch (spec.type) {
|
switch (spec.type) {
|
||||||
@@ -250,7 +253,7 @@ export function listInRange(stringRange: string): ValidatorFn {
|
|||||||
|
|
||||||
export function listItemIssue(): ValidatorFn {
|
export function listItemIssue(): ValidatorFn {
|
||||||
return parentControl => {
|
return parentControl => {
|
||||||
const { controls } = parentControl as FormArray
|
const { controls } = parentControl as UntypedFormArray
|
||||||
const problemChild = controls.find(c => c.invalid)
|
const problemChild = controls.find(c => c.invalid)
|
||||||
if (problemChild) {
|
if (problemChild) {
|
||||||
return { listItemIssue: { value: 'Invalid entries' } }
|
return { listItemIssue: { value: 'Invalid entries' } }
|
||||||
@@ -512,7 +515,7 @@ function isUnion(spec: any): spec is ListValueSpecUnion {
|
|||||||
|
|
||||||
export function convertValuesRecursive(
|
export function convertValuesRecursive(
|
||||||
configSpec: ConfigSpec,
|
configSpec: ConfigSpec,
|
||||||
group: FormGroup,
|
group: UntypedFormGroup,
|
||||||
) {
|
) {
|
||||||
Object.entries(configSpec).forEach(([key, valueSpec]) => {
|
Object.entries(configSpec).forEach(([key, valueSpec]) => {
|
||||||
const control = group.get(key)
|
const control = group.get(key)
|
||||||
@@ -524,13 +527,13 @@ export function convertValuesRecursive(
|
|||||||
} else if (valueSpec.type === 'string') {
|
} else if (valueSpec.type === 'string') {
|
||||||
if (!control.value) control.setValue(null)
|
if (!control.value) control.setValue(null)
|
||||||
} else if (valueSpec.type === 'object') {
|
} else if (valueSpec.type === 'object') {
|
||||||
convertValuesRecursive(valueSpec.spec, group.get(key) as FormGroup)
|
convertValuesRecursive(valueSpec.spec, group.get(key) as UntypedFormGroup)
|
||||||
} else if (valueSpec.type === 'union') {
|
} else if (valueSpec.type === 'union') {
|
||||||
const formGr = group.get(key) as FormGroup
|
const formGr = group.get(key) as UntypedFormGroup
|
||||||
const spec = valueSpec.variants[formGr.controls[valueSpec.tag.id].value]
|
const spec = valueSpec.variants[formGr.controls[valueSpec.tag.id].value]
|
||||||
convertValuesRecursive(spec, formGr)
|
convertValuesRecursive(spec, formGr)
|
||||||
} else if (valueSpec.type === 'list') {
|
} else if (valueSpec.type === 'list') {
|
||||||
const formArr = group.get(key) as FormArray
|
const formArr = group.get(key) as UntypedFormArray
|
||||||
const { controls } = formArr
|
const { controls } = formArr
|
||||||
|
|
||||||
if (valueSpec.subtype === 'number') {
|
if (valueSpec.subtype === 'number') {
|
||||||
@@ -544,16 +547,16 @@ export function convertValuesRecursive(
|
|||||||
} else if (valueSpec.subtype === 'object') {
|
} else if (valueSpec.subtype === 'object') {
|
||||||
controls.forEach(formGroup => {
|
controls.forEach(formGroup => {
|
||||||
const objectSpec = valueSpec.spec as ListValueSpecObject
|
const objectSpec = valueSpec.spec as ListValueSpecObject
|
||||||
convertValuesRecursive(objectSpec.spec, formGroup as FormGroup)
|
convertValuesRecursive(objectSpec.spec, formGroup as UntypedFormGroup)
|
||||||
})
|
})
|
||||||
} else if (valueSpec.subtype === 'union') {
|
} else if (valueSpec.subtype === 'union') {
|
||||||
controls.forEach(formGroup => {
|
controls.forEach(formGroup => {
|
||||||
const unionSpec = valueSpec.spec as ListValueSpecUnion
|
const unionSpec = valueSpec.spec as ListValueSpecUnion
|
||||||
const spec =
|
const spec =
|
||||||
unionSpec.variants[
|
unionSpec.variants[
|
||||||
(formGroup as FormGroup).controls[unionSpec.tag.id].value
|
(formGroup as UntypedFormGroup).controls[unionSpec.tag.id].value
|
||||||
]
|
]
|
||||||
convertValuesRecursive(spec, formGroup as FormGroup)
|
convertValuesRecursive(spec, formGroup as UntypedFormGroup)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'
|
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'
|
||||||
import { from, interval, Observable, race } from 'rxjs'
|
import {
|
||||||
|
Observable,
|
||||||
|
from,
|
||||||
|
interval,
|
||||||
|
race,
|
||||||
|
firstValueFrom,
|
||||||
|
lastValueFrom,
|
||||||
|
} from 'rxjs'
|
||||||
import { map, take } from 'rxjs/operators'
|
import { map, take } from 'rxjs/operators'
|
||||||
import { ConfigService } from './config.service'
|
import { ConfigService } from './config.service'
|
||||||
import { Revision } from 'patch-db-client'
|
import { Revision } from 'patch-db-client'
|
||||||
@@ -90,8 +97,9 @@ export class HttpService {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
return (httpOpts.timeout ? withTimeout(req, httpOpts.timeout) : req)
|
return firstValueFrom(
|
||||||
.toPromise()
|
httpOpts.timeout ? withTimeout(req, httpOpts.timeout) : req,
|
||||||
|
)
|
||||||
.then(res => res.body)
|
.then(res => res.body)
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
throw new HttpError(e)
|
throw new HttpError(e)
|
||||||
@@ -183,7 +191,7 @@ function hasParams(
|
|||||||
|
|
||||||
function withTimeout<U>(req: Observable<U>, timeout: number): Observable<U> {
|
function withTimeout<U>(req: Observable<U>, timeout: number): Observable<U> {
|
||||||
return race(
|
return race(
|
||||||
from(req.toPromise()), // this guarantees it only emits on completion, intermediary emissions are suppressed.
|
from(lastValueFrom(req)), // this guarantees it only emits on completion, intermediary emissions are suppressed.
|
||||||
interval(timeout).pipe(
|
interval(timeout).pipe(
|
||||||
take(1),
|
take(1),
|
||||||
map(() => {
|
map(() => {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { first } from 'rxjs/operators'
|
import { first } from 'rxjs/operators'
|
||||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||||
import { UIMarketplaceData } from 'src/app/services/patch-db/data-model'
|
import { UIMarketplaceData } from 'src/app/services/patch-db/data-model'
|
||||||
|
import { firstValueFrom } from 'rxjs'
|
||||||
|
|
||||||
export function getMarketplace(
|
export function getMarketplace(
|
||||||
patch: PatchDbService,
|
patch: PatchDbService,
|
||||||
): Promise<UIMarketplaceData> {
|
): Promise<UIMarketplaceData> {
|
||||||
return patch.watch$('ui', 'marketplace').pipe(first()).toPromise()
|
return firstValueFrom(patch.watch$('ui', 'marketplace'))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
import { first } from 'rxjs/operators'
|
import { first } from 'rxjs/operators'
|
||||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||||
|
import { firstValueFrom } from 'rxjs'
|
||||||
|
|
||||||
export function getPackage(
|
export function getPackage(
|
||||||
patch: PatchDbService,
|
patch: PatchDbService,
|
||||||
id: string,
|
id: string,
|
||||||
): Promise<PackageDataEntry> {
|
): Promise<PackageDataEntry> {
|
||||||
return patch.watch$('package-data', id).pipe(first()).toPromise()
|
return firstValueFrom(patch.watch$('package-data', id))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAllPackages(
|
export function getAllPackages(
|
||||||
patch: PatchDbService,
|
patch: PatchDbService,
|
||||||
): Promise<Record<string, PackageDataEntry>> {
|
): Promise<Record<string, PackageDataEntry>> {
|
||||||
return patch.watch$('package-data').pipe(first()).toPromise()
|
return firstValueFrom(patch.watch$('package-data'))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { first } from 'rxjs/operators'
|
import { first } from 'rxjs/operators'
|
||||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||||
import { ServerInfo } from 'src/app/services/patch-db/data-model'
|
import { ServerInfo } from 'src/app/services/patch-db/data-model'
|
||||||
|
import { firstValueFrom } from 'rxjs'
|
||||||
|
|
||||||
export function getServerInfo(patch: PatchDbService): Promise<ServerInfo> {
|
export function getServerInfo(patch: PatchDbService): Promise<ServerInfo> {
|
||||||
return patch.watch$('server-info').pipe(first()).toPromise()
|
return firstValueFrom(patch.watch$('server-info'))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
"target": "es2015",
|
"target": "es2020",
|
||||||
"module": "es2020",
|
"module": "es2020",
|
||||||
"lib": ["es2020", "dom"],
|
"lib": ["es2020", "dom"],
|
||||||
"paths": {
|
"paths": {
|
||||||
|
|||||||
2
patch-db
2
patch-db
Submodule patch-db updated: ec35e5f14c...2fef1e572c
Reference in New Issue
Block a user