diff --git a/doc/developer_guide.md b/doc/developer_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..2f102d884afc0618f8a31a24205fd552c41e150e --- /dev/null +++ b/doc/developer_guide.md @@ -0,0 +1,30 @@ +# Developer guide + +## Writing a component + +- Pour chaque composant Angular (v14): + - Utiliser Ionic framework, et si besoin Angular Material. Utiliser la classe Moment pour les dates. + - Utiliser RxState avec providers: [RxState] dans la déclaration @Component. + - Juste au-dessus de chaque classe composant, déclarer une interface MonComponentState : + * En remplaçant "MonComponent" par le nom du composant. + * Ajouter les attributs dynamiques du composant dans cette interface. + - Dans le constructeur : + * Limiter les paramètres en utilisant injector: Injector pour faciliter l'héritage. + * Définir tous les paramètres avec une visibilité protected. + * Ajouter un paramètre state: RxState<MonComposantState>. + - Pour chaque attribut dynamique du composant : + * Définir l'attribut avec son type simple dans la classe MonComposantState. + * Dans le composant, définir un getter et un setter avec @Input qui utilise state : + ```ts + get attribute(): string { + return this.state.get('attribute'); + } + @Input() set attribute(value: string) { + this.state.set('attribute', () => value); + } + ``` + - Pour les modales (si besoin) : + * Utiliser IonicModal. + * Ne pas définir la modale dans le template HTML (inline) mais dans un composant séparé. + * Gérer la modale depuis le composant appelant via ModalController. + - Ne pas générer les imports TypeScript. diff --git a/package.json b/package.json index c67d543ea4e98197a0eb57d9c570ff9fe6c2f157..a918d22d22ec05e58dd2de8a8b5a38f93e929d86 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,9 @@ "@polkadot/ui-settings": "^2.9.7", "@polkadot/util": "^10.1.6", "@polkadot/util-crypto": "^10.1.6", - "@rx-angular/state": "^1.7.0", + "@rx-angular/state": "^2.0.0", + "@rx-angular/cdk": "^2.0.0", + "@rx-angular/template": "^2.0.0", "angular2-qrcode": "^2.0.3", "crypto-browserify": "^3.12.0", "jdenticon": "^3.1.1", @@ -75,10 +77,10 @@ "@angular-eslint/eslint-plugin": "~13.5.0", "@angular-eslint/eslint-plugin-template": "~13.5.0", "@angular-eslint/template-parser": "~13.5.0", - "@angular/cli": "^14.2.2", - "@angular/compiler": "^14.2.1", - "@angular/compiler-cli": "^14.2.1", - "@angular/language-service": "^14.2.1", + "@angular/cli": "^14.2.11", + "@angular/compiler": "^14.2.12", + "@angular/compiler-cli": "^14.2.12", + "@angular/language-service": "^14.2.12", "@capacitor/cli": "4.1.0", "@ionic/angular-toolkit": "^6.1.0", "@ionic/cli": "^6.20.1", @@ -102,10 +104,10 @@ "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "^2.0.0", "ngx-color-picker": "^12.0.1", - "ngx-jdenticon": "^1.0.4", + "ngx-jdenticon": "^2.0.0", "ngx-markdown": "^14.0.1", "ngx-material-timepicker": "5.5.3", - "ngx-quicklink": "^0.3.0", + "ngx-quicklink": "^0.3.1", "protractor": "~7.0.0", "ts-node": "^8.10.2", "typescript": "~4.6.4" diff --git a/src/app/_test/account-detail.modal.html b/src/app/_test/account-detail.modal.html new file mode 100644 index 0000000000000000000000000000000000000000..daf90cef04d10bb8ab84625a3bd2942649d8e51d --- /dev/null +++ b/src/app/_test/account-detail.modal.html @@ -0,0 +1,23 @@ +<ion-header> + <ion-toolbar> + <ion-title>Détails du compte</ion-title> + <ion-buttons slot="end"> + <ion-button (click)="closeModal()"> + <ion-icon slot="icon-only" name="close"></ion-icon> + </ion-button> + </ion-buttons> + </ion-toolbar> +</ion-header> + +<ion-content> + <ion-list> + <ion-item> + <ion-label position="stacked">Nom</ion-label> + <ion-input [(ngModel)]="account.meta.name" readonly></ion-input> + </ion-item> + <ion-item> + <ion-label position="stacked">Adresse</ion-label> + <ion-input [(ngModel)]="account.address" readonly></ion-input> + </ion-item> + </ion-list> +</ion-content> diff --git a/src/app/_test/account-detail.modal.scss b/src/app/_test/account-detail.modal.scss new file mode 100644 index 0000000000000000000000000000000000000000..5d4e87f30f6362b8597dbe54a44aadaffa915763 --- /dev/null +++ b/src/app/_test/account-detail.modal.scss @@ -0,0 +1,3 @@ +:host { + display: block; +} diff --git a/src/app/_test/account-detail.modal.ts b/src/app/_test/account-detail.modal.ts new file mode 100644 index 0000000000000000000000000000000000000000..2d25f0e8ac833640376508856f4dc0d61aec6027 --- /dev/null +++ b/src/app/_test/account-detail.modal.ts @@ -0,0 +1,30 @@ +import { Component, Injector, Input } from '@angular/core'; +import { RxState } from '@rx-angular/state'; +import { ModalController } from '@ionic/angular'; +import {Account} from "@app/wallet/account.model"; + +interface AccountDetailModalState { + account: Account; +} + +@Component({ + selector: 'app-account-detail-modal', + templateUrl: './account-detail.modal.html', + styleUrls: ['./account-detail.modal.scss'], + providers: [RxState] +}) +export class AccountDetailModal { + constructor(protected injector: Injector, protected state: RxState<AccountDetailModalState>, protected modalController: ModalController) {} + + get account(): Account { + return this.state.get('account'); + } + + @Input() set account(value: Account) { + this.state.set('account', () => value); + } + + closeModal() { + this.modalController.dismiss(); + } +} diff --git a/src/app/_test/account-list.component.html b/src/app/_test/account-list.component.html new file mode 100644 index 0000000000000000000000000000000000000000..3053191c7eb42da3fa8b004ca63e6ef3b29637b5 --- /dev/null +++ b/src/app/_test/account-list.component.html @@ -0,0 +1,9 @@ +<ion-list> + <ion-item *ngFor="let account of accounts; let i = index" (click)="showAccountDetail(account)" [@listAnimation]> + <ion-avatar slot="start"> + <svg width="40" width="40" [data-jdenticon-value]="account.data?.randomId||account.address"></svg> + </ion-avatar> + <ion-label>{{ account.meta.name }}</ion-label> + <ion-icon name="chevron-forward-outline" slot="end"></ion-icon> + </ion-item> +</ion-list> diff --git a/src/app/_test/account-list.component.scss b/src/app/_test/account-list.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..5d4e87f30f6362b8597dbe54a44aadaffa915763 --- /dev/null +++ b/src/app/_test/account-list.component.scss @@ -0,0 +1,3 @@ +:host { + display: block; +} diff --git a/src/app/_test/account-list.component.ts b/src/app/_test/account-list.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..f52f123276d6695c37d1838d101234b36f7ec79c --- /dev/null +++ b/src/app/_test/account-list.component.ts @@ -0,0 +1,53 @@ +import { Component, Injector, Input } from '@angular/core'; +import { RxState } from '@rx-angular/state'; +import { ModalController } from '@ionic/angular'; +import { AccountDetailModal } from './account-detail.modal'; +import { trigger, transition, style, animate, query, stagger } from '@angular/animations'; +import {Account} from "@app/wallet/account.model"; + +interface AccountListComponentState { + accounts: Account[]; +} + +@Component({ + selector: 'app-account-list', + templateUrl: './account-list.component.html', + styleUrls: ['./account-list.component.scss'], + providers: [RxState], + animations: [ + trigger('listAnimation', [ + transition('* <=> *', [ + query(':enter', style({ opacity: 0, transform: 'translateY(100%) translateX(100%)' }), { optional: true }), + query(':enter', stagger('200ms', [animate('300ms ease-out', style({ opacity: 1, transform: 'none' }))]), { optional: true }), + ]), + ]), + ], +}) +export class AccountListComponent { + constructor(protected injector: Injector, + protected state: RxState<AccountListComponentState>, + protected modalController: ModalController) { + + this.accounts = [ + {address: 'tototototototot', meta: {name: 'portefeuille 1'}}, + {address: 'totosstototot', meta: {name: 'portefeuille 2'}}, + ] + } + + get accounts(): Account[] { + return this.state.get('accounts'); + } + + @Input() set accounts(value: Account[]) { + this.state.set('accounts', () => value); + } + + async showAccountDetail(account: Account) { + const modal = await this.modalController.create({ + component: AccountDetailModal, + componentProps: { account }, + }); + + return await modal.present(); + } +} diff --git a/src/app/_test/account-routing.module.ts b/src/app/_test/account-routing.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..8b4e11968722110a824c6e1633dff0ca01ff6ce3 --- /dev/null +++ b/src/app/_test/account-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { AccountListComponent } from './account-list.component'; + +const routes: Routes = [ + { + path: 'accounts', + component: AccountListComponent, + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class AccountRoutingModule {} diff --git a/src/app/_test/account.module.ts b/src/app/_test/account.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..ff5eb011376ad23c2f7206489710b2ba96f154b1 --- /dev/null +++ b/src/app/_test/account.module.ts @@ -0,0 +1,17 @@ +import {NgModule} from '@angular/core'; +import {AccountListComponent} from './account-list.component'; +import {AccountDetailModal} from './account-detail.modal'; +import {NgxJdenticonModule} from 'ngx-jdenticon'; +import {AccountRoutingModule} from "@app/_test/account-routing.module"; +import {AppSharedModule} from "@app/shared/shared.module"; + +@NgModule({ + imports: [ + AppSharedModule, + NgxJdenticonModule, + AccountRoutingModule + ], + declarations: [AccountListComponent, AccountDetailModal], + exports: [AccountListComponent], +}) +export class AccountModule {} diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d38eb84335d759268809aba7171dbfc724daa5ba..622a9df790949fbf17957a7cc8b9488919fe05d2 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -26,6 +26,10 @@ const routes: Routes = [ { path: 'settings', loadChildren: () => import('./settings/settings.module').then( m => m.SettingsPageModule) + }, + { + path: 'test', + loadChildren: () => import('./_test/account.module').then( m => m.AccountModule) } ]; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9302d7171e0f367ce422a08212c7ace2e46d5056..835c726aba6d8dac3af2ddc4e6c3dd3dfda0d236 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -23,6 +23,7 @@ import {BarcodeScanner} from "@capacitor-community/barcode-scanner"; import {StatusBar} from "@capacitor/status-bar"; import {SplashScreen} from "@capacitor/splash-screen"; import {AppTransferModule} from "@app/transfer/transfer.module"; +import {AccountModule} from "@app/_test/account.module"; export function createTranslateLoader(http: HttpClient) { return new TranslateHttpLoader(http, './assets/i18n/', '.json'); @@ -51,6 +52,8 @@ export function createTranslateLoader(http: HttpClient) { deps: [HttpClient] } }), + + AccountModule ], providers: [ PlatformService, diff --git a/src/app/shared/services/startable-service.class.ts b/src/app/shared/services/startable-service.class.ts index 9fcbe65583b35f366be08bd961a55a592b4d293e..edf1b0c931cf85e62785e5ed6c8bd862c2401a7a 100644 --- a/src/app/shared/services/startable-service.class.ts +++ b/src/app/shared/services/startable-service.class.ts @@ -1,5 +1,5 @@ import {Optional} from '@angular/core'; -import {Subject} from 'rxjs'; +import {firstValueFrom, Subject, takeUntil} from 'rxjs'; import {waitFor} from '../observables'; import {BaseService, IBaseServiceOptions} from "@app/shared/services/base-service.class"; import {environment} from "@environments/environment"; @@ -18,7 +18,8 @@ export abstract class StartableService<T = any, O extends IStartableServiceOptio extends BaseService<O> implements IStartableService<T> { - onStart = new Subject<T>(); + startSubject = new Subject<T>(); + stopSubject = new Subject<void>(); protected _startByReadyFunction = true; // should start when calling ready() ? protected _data: T = null; @@ -51,7 +52,7 @@ export abstract class StartableService<T = any, O extends IStartableServiceOptio this._started = true; this._startPromise = undefined; - this.onStart.next(this._data); + this.startSubject.next(this._data); return this._data; }) @@ -68,12 +69,16 @@ export abstract class StartableService<T = any, O extends IStartableServiceOptio try { this.unsubscribe(); await this.ngOnStop(); - this._started = false; - this._startPromise = undefined; } catch (err) { console.error('Failed to stop a service: ' + (err && err.message || err), err); } + finally { + this.stopSubject.next(); + this._data = null; + this._started = false; + this._startPromise = undefined; + } } async restart(): Promise<T> { @@ -94,12 +99,13 @@ export abstract class StartableService<T = any, O extends IStartableServiceOptio if (this._started) return Promise.resolve(this._data); if (this._startPromise) return this._startPromise; if (this._startByReadyFunction) return this.start(); - return waitFor(() => this._started) - .then(() => this._data); + return firstValueFrom(this.startSubject + .pipe(takeUntil(this.stopSubject)) + ); } protected async ngOnStop(): Promise<void> { - // Can be override by subclasses + // Can be overwritten by subclasses } protected abstract ngOnStart(): Promise<T>; diff --git a/yarn.lock b/yarn.lock index 554f6a003ab7f6a1ad149828cde4f8d6caab47fc..ec3ce864e8e3cab12f12eb091d16a1f5a00f397d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15,6 +15,14 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" +"@angular-devkit/architect@0.1402.11": + version "0.1402.11" + resolved "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.11.tgz#53d12c2433a4bad0b863028e0e3b38e5540f3739" + integrity sha512-RuSZrBQ+QbipAESZ4aXCyAMQHaEaDyyV/FDS9J2HJWfEFbRD5oxlEt/tBC8XjmJQsktaUOh07GT8MNJjPKVAQw== + dependencies: + "@angular-devkit/core" "14.2.11" + rxjs "6.6.7" + "@angular-devkit/architect@0.1402.2": version "0.1402.2" resolved "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.2.tgz#174cd1c86d5c9493192dfa9c0c52b9191a728b2b" @@ -113,6 +121,17 @@ rxjs "6.6.7" source-map "0.7.3" +"@angular-devkit/core@14.2.11": + version "14.2.11" + resolved "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.11.tgz#a92397c1b4c04c2a710b9de9b53eecc78d7db6b3" + integrity sha512-cBIGs6y9rykOQqnuAQOB1DgIRyBFYtvKRJb7QNUfIJ0qUfARKkuV/yikv3lrb95ePGkmoRzmjkFqcFZiYU+r7A== + dependencies: + ajv "8.11.0" + ajv-formats "2.1.1" + jsonc-parser "3.1.0" + rxjs "6.6.7" + source-map "0.7.4" + "@angular-devkit/core@14.2.2": version "14.2.2" resolved "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.2.tgz#d616ada7c9a0610454da47445e64520a0b34e400" @@ -135,12 +154,12 @@ ora "5.4.1" rxjs "6.6.7" -"@angular-devkit/schematics@14.2.2": - version "14.2.2" - resolved "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.2.tgz#ceb024214aee56f0c61e26e768775f69045b4f4c" - integrity sha512-90hseNg1yQ2AR+lVr/NByZRHnYAlzCL6hr9p9q1KPHxA3Owo04yX6n6dvR/xf27hCopXInXKPsasR59XCx5ZOQ== +"@angular-devkit/schematics@14.2.11": + version "14.2.11" + resolved "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.11.tgz#3ab31b736aaf1087b923050874fa1ce0a8bd74c4" + integrity sha512-OTEOu4uf3kZDcSGYkuESxf/IOlJSn/GdLt63Sd1QwJu6pJSeFxkANw/WEWICZyJfRLNW6fdLJLEGPM9Zt5ZqAg== dependencies: - "@angular-devkit/core" "14.2.2" + "@angular-devkit/core" "14.2.11" jsonc-parser "3.1.0" magic-string "0.26.2" ora "5.4.1" @@ -199,15 +218,15 @@ dependencies: tslib "^2.3.0" -"@angular/cli@^14.2.2": - version "14.2.2" - resolved "https://registry.npmjs.org/@angular/cli/-/cli-14.2.2.tgz#f5d29360f5daa1f25d98ab6a34306872748f6657" - integrity sha512-oRsKFn8grq+mZrirDD2Ea0CFx5+eeb928ltI/B3ML7s3mOpTfhuuF04033TARY/UzcGsX31V2L9kORJXN30Ycw== +"@angular/cli@^14.2.11": + version "14.2.11" + resolved "https://registry.npmjs.org/@angular/cli/-/cli-14.2.11.tgz#6dceb316b27501ee3e8176fa37ac523d6fd89a4d" + integrity sha512-k4Epob8Xz+9oyC6Ty9SNntTa2wHAvzxfcCi7itefPMcwEU9pqBcAv4XYfyawb5d7n/S5RBNwdsDpjoh2DPtmow== dependencies: - "@angular-devkit/architect" "0.1402.2" - "@angular-devkit/core" "14.2.2" - "@angular-devkit/schematics" "14.2.2" - "@schematics/angular" "14.2.2" + "@angular-devkit/architect" "0.1402.11" + "@angular-devkit/core" "14.2.11" + "@angular-devkit/schematics" "14.2.11" + "@schematics/angular" "14.2.11" "@yarnpkg/lockfile" "1.1.0" ansi-colors "4.1.3" debug "4.3.4" @@ -232,10 +251,10 @@ dependencies: tslib "^2.3.0" -"@angular/compiler-cli@^14.2.1": - version "14.2.1" - resolved "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.2.1.tgz#1de8e4c7372a09c1384b797075a2943a81507a0e" - integrity sha512-ncwX/033cP2+5kvUaqJcLSBNJb2YYxSaXlsQ8+/l5xUMjRN6/t//xOfYdcfzefgvfkxVsTcOu76GSJerdK0SLg== +"@angular/compiler-cli@^14.2.12": + version "14.3.0" + resolved "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.3.0.tgz#e9c4760cf4473c53217f6cf3a27365954438e7a6" + integrity sha512-eoKpKdQ2X6axMgzcPUMZVYl3bIlTMzMeTo5V29No4BzgiUB+QoOTYGNJZkGRyqTNpwD9uSBJvmT2vG9+eC4ghQ== dependencies: "@babel/core" "^7.17.2" chokidar "^3.0.0" @@ -248,10 +267,10 @@ tslib "^2.3.0" yargs "^17.2.1" -"@angular/compiler@^14.2.1": - version "14.2.1" - resolved "https://registry.npmjs.org/@angular/compiler/-/compiler-14.2.1.tgz#6d11031ec08c815605d7aa19589f447c58a01f81" - integrity sha512-MvyAYun6D8+/wRxbDswTMidYahveEnZan95LSM5dLk26CAGAeSx6VR5EAftVPo1NChLpcboVBz+tn9PsjhtP1A== +"@angular/compiler@^14.2.12": + version "14.3.0" + resolved "https://registry.npmjs.org/@angular/compiler/-/compiler-14.3.0.tgz#106d3ef296700ab7021a52b2e09d8da1384d086a" + integrity sha512-E15Rh0t3vA+bctbKnBCaDmLvc3ix+ZBt6yFZmhZalReQ+KpOlvOJv+L9oiFEgg+rYVl2QdvN7US1fvT0PqswLw== dependencies: tslib "^2.3.0" @@ -269,10 +288,10 @@ dependencies: tslib "^2.3.0" -"@angular/language-service@^14.2.1": - version "14.2.1" - resolved "https://registry.npmjs.org/@angular/language-service/-/language-service-14.2.1.tgz#600d95b7b42775a8fe9524129a71002d946a543c" - integrity sha512-i7a33+2Aq7c67udxAd6O9RYYLWEFHG0AI/pt0w+RL9ftrHjP4pTHZyRN+/KTn88jiIm39+bJVcnlhMwWUjgPKQ== +"@angular/language-service@^14.2.12": + version "14.3.0" + resolved "https://registry.npmjs.org/@angular/language-service/-/language-service-14.3.0.tgz#cc370072103b312d4057ab2554a1d8b25e076ad9" + integrity sha512-Sij3OQzj1UGs1O8H9PxVAY/o27+oqZwQRnib66rsWvtbIBTjHp4FV3dTs5iVcr62GGv4V4Mff/2I82NP10GPQg== "@angular/platform-browser-dynamic@^14.2.1": version "14.2.1" @@ -2388,21 +2407,37 @@ "@types/websocket" "^1.0.5" websocket "^1.0.34" -"@rx-angular/state@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@rx-angular/state/-/state-1.7.0.tgz#54a1dbe34145c49b5101f13f89775f3e17aec34c" - integrity sha512-rrM5qlI6lDsSbTVo+uBoGpOuZ//msi2q72WYvw1MESPDrb9TnOLtVceDaYL0FBMDBhcqtmUsdOs6OoICaroSew== +"@rx-angular/cdk@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@rx-angular/cdk/-/cdk-2.0.0.tgz#7ab7c0e3143226c47f5579aad0e9dc62df9aaf82" + integrity sha512-EaTsfxnPXy6Dr8JT2KklpIsyaFljQa8Z43XzH8N9+GfEz+/OAFXowKT4IxkgdTpdYHfdP7aPPoe0c/5wZrN4aA== + dependencies: + ng-morph "^2.1.3" + tslib "^2.4.1" + +"@rx-angular/state@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@rx-angular/state/-/state-2.0.0.tgz#56be0056460c02e48b40cb440d0395aeb565ab69" + integrity sha512-OzLglO9x7jf9QCTwSKFA0wZzV0t4rbLGRT3HfATTrXeN79KAkUygqXU3mCvwruFignBB4XJryOYQhANp+nIGDg== dependencies: - ng-morph "^2.0.0" - tslib "^2.0.0" + ng-morph "^2.1.3" + tslib "^2.4.1" -"@schematics/angular@14.2.2": - version "14.2.2" - resolved "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.2.tgz#3a9be8912e4f5a2d59c50e866b2853097fd656ff" - integrity sha512-ExejSuQrkhVzcvq1MH1hSHufp2HUrrCSb0ol1JVlekIkq6H3A5839/8mDC6U/stRMo/gNz01sibBBJmQwH2h6Q== +"@rx-angular/template@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@rx-angular/template/-/template-2.0.0.tgz#2bad384159a99168992f0503f8557b350ff5c6c1" + integrity sha512-QXxVjREI8IEnq9uEzlQ8GCGQGcMGfW/UCL2NnWsY3SSJ1WqHCAvmHvyqS1mwRIIoFjGHsZqa/RRvGopibCs2mw== dependencies: - "@angular-devkit/core" "14.2.2" - "@angular-devkit/schematics" "14.2.2" + ng-morph "^2.1.3" + tslib "^2.4.1" + +"@schematics/angular@14.2.11": + version "14.2.11" + resolved "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.11.tgz#dba5ed5bd87c24b478c035aa84666eae7392c142" + integrity sha512-tejU2BOc25bQO34mZmTwmtAfOiFtDE/io/yHqYgUsTn804kyMQbz2QOOXN0epdzRYrkAHvH4KV8c2LDyO6iijA== + dependencies: + "@angular-devkit/core" "14.2.11" + "@angular-devkit/schematics" "14.2.11" jsonc-parser "3.1.0" "@schematics/angular@^13.0.1": @@ -7879,13 +7914,6 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - minimatch@3.0.5, minimatch@^3.0.4: version "3.0.5" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz" @@ -8103,13 +8131,13 @@ next-tick@^1.1.0: resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz" integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== -ng-morph@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ng-morph/-/ng-morph-2.1.0.tgz#3f5735962b112981de531c375b42311f18fa74d5" - integrity sha512-jn34Ter6HlY7E3yOoMhfk3cnUwjLlvcGTsAJ7jS0pZ3SAGi3hzqlf3oyUQO6fNfbFnydc33yNqQtUIrbHKCtNA== +ng-morph@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ng-morph/-/ng-morph-2.1.3.tgz#def40b5a1f8ba92416705a9b7c6688ed2b575a4d" + integrity sha512-bFeSMSn2ORgtYw4ZmwISJ/RGdZxi03IwODrnXB6FbTEvmyfuTCB7x0FyQsm8euNX43fTp3FZclCZpRmO8t5w8w== dependencies: jsonc-parser "3.0.0" - minimatch "3.0.4" + minimatch "3.0.5" multimatch "5.0.0" ts-morph "10.0.2" @@ -8150,10 +8178,10 @@ ngx-material-timepicker@5.5.3: luxon "1.24.0" tslib "^1.9.0" -ngx-quicklink@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/ngx-quicklink/-/ngx-quicklink-0.3.0.tgz#62c2083681649b0533e247a9da2641cbdc93dabd" - integrity sha512-VyJZ41Ztd9M9FOslQDIr2+qQK4EVLrneGh2OXfkjJnqkYZXSP8iVK/vwkrhFqxdc9D2YhU8rMjD2As/4KQBKhQ== +ngx-quicklink@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/ngx-quicklink/-/ngx-quicklink-0.3.1.tgz#282bedf4c4f7b6024b41727118b9e580f0858167" + integrity sha512-4R2RZueHGCZ6NJ7R/U/YO4ji0GpWisdPca00OJTjoz82koudQZQPEefGjSXBAGFLKcHlZJZTzVGonBXBDDq0QA== dependencies: tslib "^2.3.0" @@ -10623,6 +10651,11 @@ tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.3.0: resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== +tslib@^2.4.1: + version "2.5.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz"