@sneat/ext-assetus-components 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/esm2022/index.js +2 -0
  2. package/esm2022/index.js.map +1 -0
  3. package/esm2022/lib/asset-add/add-asset-base-component.js +48 -0
  4. package/esm2022/lib/asset-add/add-asset-base-component.js.map +1 -0
  5. package/esm2022/lib/asset-add/asset-add-document/asset-add-document.component.js +166 -0
  6. package/esm2022/lib/asset-add/asset-add-document/asset-add-document.component.js.map +1 -0
  7. package/esm2022/lib/asset-add/asset-add-dwelling/asset-add-dwelling.component.js +115 -0
  8. package/esm2022/lib/asset-add/asset-add-dwelling/asset-add-dwelling.component.js.map +1 -0
  9. package/esm2022/lib/asset-add/asset-add-vehicle/asset-add-vehicle.component.js +173 -0
  10. package/esm2022/lib/asset-add/asset-add-vehicle/asset-add-vehicle.component.js.map +1 -0
  11. package/esm2022/lib/asset-add/index.js +4 -0
  12. package/esm2022/lib/asset-add/index.js.map +1 -0
  13. package/esm2022/lib/asset-base-page.js +30 -0
  14. package/esm2022/lib/asset-base-page.js.map +1 -0
  15. package/esm2022/lib/asset-card/asset-card.component.js +41 -0
  16. package/esm2022/lib/asset-card/asset-card.component.js.map +1 -0
  17. package/esm2022/lib/asset-component-base-params.js +16 -0
  18. package/esm2022/lib/asset-component-base-params.js.map +1 -0
  19. package/esm2022/lib/asset-possesion-card/asset-possession-card.component.js +36 -0
  20. package/esm2022/lib/asset-possesion-card/asset-possession-card.component.js.map +1 -0
  21. package/esm2022/lib/asset-reg-number-input/asset-reg-number-input.component.js +118 -0
  22. package/esm2022/lib/asset-reg-number-input/asset-reg-number-input.component.js.map +1 -0
  23. package/esm2022/lib/assets-list/assets-list.component.js +138 -0
  24. package/esm2022/lib/assets-list/assets-list.component.js.map +1 -0
  25. package/esm2022/lib/edit-dwelling-card/edit-dwelling-card.component.js +121 -0
  26. package/esm2022/lib/edit-dwelling-card/edit-dwelling-card.component.js.map +1 -0
  27. package/esm2022/lib/index.js +14 -0
  28. package/esm2022/lib/index.js.map +1 -0
  29. package/esm2022/lib/make-model-card/make-model-card.component.js +68 -0
  30. package/esm2022/lib/make-model-card/make-model-card.component.js.map +1 -0
  31. package/esm2022/lib/mileage-dialog/mileage-dialog.component.js +128 -0
  32. package/esm2022/lib/mileage-dialog/mileage-dialog.component.js.map +1 -0
  33. package/esm2022/lib/period-segment/period-segment.component.js +24 -0
  34. package/esm2022/lib/period-segment/period-segment.component.js.map +1 -0
  35. package/esm2022/lib/real-estate-location/real-estate-location.component.js +22 -0
  36. package/esm2022/lib/real-estate-location/real-estate-location.component.js.map +1 -0
  37. package/esm2022/lib/services/asset-service.dto.js +2 -0
  38. package/esm2022/lib/services/asset-service.dto.js.map +1 -0
  39. package/esm2022/lib/services/asset-service.js +59 -0
  40. package/esm2022/lib/services/asset-service.js.map +1 -0
  41. package/esm2022/lib/services/assetus-services.module.js +17 -0
  42. package/esm2022/lib/services/assetus-services.module.js.map +1 -0
  43. package/esm2022/lib/services/assetus-space.service.js +18 -0
  44. package/esm2022/lib/services/assetus-space.service.js.map +1 -0
  45. package/esm2022/lib/services/index.js +5 -0
  46. package/esm2022/lib/services/index.js.map +1 -0
  47. package/esm2022/lib/vehicle-card/vehicle-card.component.js +160 -0
  48. package/esm2022/lib/vehicle-card/vehicle-card.component.js.map +1 -0
  49. package/esm2022/lib/vehicle-engine/vehicle-engine.component.js +98 -0
  50. package/esm2022/lib/vehicle-engine/vehicle-engine.component.js.map +1 -0
  51. package/esm2022/sneat-ext-assetus-components.js +5 -0
  52. package/esm2022/sneat-ext-assetus-components.js.map +1 -0
  53. package/index.d.ts +1 -0
  54. package/lib/asset-add/add-asset-base-component.d.ts +20 -0
  55. package/lib/asset-add/asset-add-document/asset-add-document.component.d.ts +26 -0
  56. package/lib/asset-add/asset-add-dwelling/asset-add-dwelling.component.d.ts +16 -0
  57. package/lib/asset-add/asset-add-vehicle/asset-add-vehicle.component.d.ts +26 -0
  58. package/lib/asset-add/index.d.ts +3 -0
  59. package/lib/asset-base-page.d.ts +15 -0
  60. package/lib/asset-card/asset-card.component.d.ts +13 -0
  61. package/lib/asset-component-base-params.d.ts +9 -0
  62. package/lib/asset-possesion-card/asset-possession-card.component.d.ts +12 -0
  63. package/lib/asset-reg-number-input/asset-reg-number-input.component.d.ts +31 -0
  64. package/lib/assets-list/assets-list.component.d.ts +25 -0
  65. package/lib/edit-dwelling-card/edit-dwelling-card.component.d.ts +23 -0
  66. package/lib/index.d.ts +13 -0
  67. package/lib/make-model-card/make-model-card.component.d.ts +20 -0
  68. package/lib/mileage-dialog/mileage-dialog.component.d.ts +33 -0
  69. package/lib/period-segment/period-segment.component.d.ts +10 -0
  70. package/lib/real-estate-location/real-estate-location.component.d.ts +7 -0
  71. package/lib/services/asset-service.d.ts +19 -0
  72. package/lib/services/asset-service.dto.d.ts +23 -0
  73. package/lib/services/assetus-services.module.d.ts +6 -0
  74. package/lib/services/assetus-space.service.d.ts +10 -0
  75. package/lib/services/index.d.ts +4 -0
  76. package/lib/vehicle-card/vehicle-card.component.d.ts +34 -0
  77. package/lib/vehicle-engine/vehicle-engine.component.d.ts +14 -0
  78. package/package.json +27 -0
  79. package/sneat-ext-assetus-components.d.ts +5 -0
  80. package/tsconfig.lib.prod.tsbuildinfo +1 -0
@@ -0,0 +1,4 @@
1
+ export * from './add-asset-base-component';
2
+ export * from './asset-add-document/asset-add-document.component';
3
+ export * from './asset-add-dwelling/asset-add-dwelling.component';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../libs/extensions/assetus/components/src/lib/asset-add/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mDAAmD,CAAC;AAClE,cAAc,mDAAmD,CAAC","sourcesContent":["export * from './add-asset-base-component';\nexport * from './asset-add-document/asset-add-document.component';\nexport * from './asset-add-dwelling/asset-add-dwelling.component';\n"]}
@@ -0,0 +1,30 @@
1
+ import { SpaceItemPageBaseComponent } from '@sneat/space-components';
2
+ import { NEVER, throwError } from 'rxjs';
3
+ export class AssetBasePage extends SpaceItemPageBaseComponent {
4
+ get vehicleAsset() {
5
+ return this.asset;
6
+ }
7
+ constructor(params, parentPagePath = 'assets') {
8
+ super(parentPagePath, 'asset', params.assetService);
9
+ this.params = params;
10
+ this.assetService = this.params.assetService;
11
+ }
12
+ watchItemChanges() {
13
+ if (!this.asset?.id) {
14
+ return throwError(() => new Error('no asset context'));
15
+ }
16
+ const space = this.space;
17
+ if (!space) {
18
+ return NEVER;
19
+ }
20
+ return this.assetService.watchAssetByID(space, this.asset.id);
21
+ }
22
+ setItemContext(item) {
23
+ super.setItemContext(item);
24
+ this.asset = item;
25
+ }
26
+ briefs() {
27
+ return this.assetusSpace?.dbo?.assets;
28
+ }
29
+ }
30
+ //# sourceMappingURL=asset-base-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-base-page.js","sourceRoot":"","sources":["../../../../../../../libs/extensions/assetus/components/src/lib/asset-base-page.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,KAAK,EAAc,UAAU,EAAE,MAAM,MAAM,CAAC;AAGrD,MAAM,OAAgB,aAAc,SAAQ,0BAG3C;IAKC,IAAc,YAAY;QACxB,OAAO,IAAI,CAAC,KAA6B,CAAC;IAC5C,CAAC;IAID,YACkB,MAAgC,EAChD,cAAc,GAAG,QAAQ;QAEzB,KAAK,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;QAHpC,WAAM,GAAN,MAAM,CAA0B;QAH/B,iBAAY,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;IAO3D,CAAC;IAEkB,gBAAgB;QACjC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC;YACpB,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IAEkB,cAAc,CAAC,IAAoB;QACpD,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAEkB,MAAM;QACvB,OAAO,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,MAAM,CAAC;IACxC,CAAC;CACF","sourcesContent":["import {\n IAssetBrief,\n IAssetDboBase,\n IAssetusSpaceContext,\n IAssetContext,\n IAssetVehicleContext,\n} from '@sneat/mod-assetus-core';\nimport { SpaceItemPageBaseComponent } from '@sneat/space-components';\nimport { NEVER, Observable, throwError } from 'rxjs';\nimport { AssetComponentBaseParams } from './asset-component-base-params';\n\nexport abstract class AssetBasePage extends SpaceItemPageBaseComponent<\n IAssetBrief,\n IAssetDboBase\n> {\n protected assetusSpace?: IAssetusSpaceContext;\n\n protected asset?: IAssetContext;\n\n protected get vehicleAsset(): IAssetVehicleContext {\n return this.asset as IAssetVehicleContext;\n }\n\n protected readonly assetService = this.params.assetService;\n\n protected constructor(\n public readonly params: AssetComponentBaseParams,\n parentPagePath = 'assets',\n ) {\n super(parentPagePath, 'asset', params.assetService);\n }\n\n protected override watchItemChanges(): Observable<IAssetContext> {\n if (!this.asset?.id) {\n return throwError(() => new Error('no asset context'));\n }\n const space = this.space;\n if (!space) {\n return NEVER;\n }\n return this.assetService.watchAssetByID(space, this.asset.id);\n }\n\n protected override setItemContext(item?: IAssetContext) {\n super.setItemContext(item);\n this.asset = item;\n }\n\n protected override briefs(): Record<string, IAssetBrief> | undefined {\n return this.assetusSpace?.dbo?.assets;\n }\n}\n"]}
@@ -0,0 +1,41 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { RouterModule } from '@angular/router';
3
+ import { IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonItem, IonLabel, } from '@ionic/angular/standalone';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/router";
6
+ export class AssetCardComponent {
7
+ constructor() {
8
+ this.segment = 'expenses';
9
+ }
10
+ ngOnChanges(changes) {
11
+ if (changes['asset'] && this.asset) {
12
+ const incomes = this.asset?.dbo?.totals?.incomes, expenses = this.asset?.dbo?.totals?.expenses;
13
+ if (incomes && (!expenses || incomes.count > expenses.count)) {
14
+ this.segment = 'income';
15
+ }
16
+ }
17
+ }
18
+ segmentChanged(ev) {
19
+ this.segment = ev.detail.value;
20
+ }
21
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AssetCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
22
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: AssetCardComponent, isStandalone: true, selector: "sneat-asset-card", inputs: { period: "period", asset: "asset" }, usesOnChanges: true, ngImport: i0, template: "<ion-card\n tappable\n [routerLink]=\"'/asset/' + asset?.id\"\n routerDirection=\"forward\"\n>\n <ion-card-header>\n <ion-card-title>\n {{ asset?.dbo?.title }}\n </ion-card-title>\n </ion-card-header>\n <!--\t<ion-list>-->\n <!--\t\t<ion-item *ngIf=\"asset?.dto?.totals.per(period, true, false)\">-->\n <!--\t\t\tIncomes ({{ asset.totals.incomes.count }})-->\n <!--\t\t\t<div slot=\"end\">-->\n <!--\t\t\t\t{{ asset.totals.per(period, true, false) }}-->\n <!--\t\t\t</div>-->\n <!--\t\t</ion-item>-->\n <!--\t\t<ion-item *ngIf=\"asset.totals.per(period, false, true)\">-->\n <!--\t\t\tExpenses ({{ asset.totals.expenses.count }})-->\n <!--\t\t\t<div slot=\"end\">-->\n <!--\t\t\t\t{{ asset.totals.per(period, false, true) }}-->\n <!--\t\t\t</div>-->\n <!--\t\t</ion-item>-->\n <!--\t\t<ion-item-->\n <!--\t\t\t*ngIf=\"-->\n <!--\t\t\t\tasset.totals.per(period, true, false) &&-->\n <!--\t\t\t\tasset.totals.per(period, false, true)-->\n <!--\t\t\t\"-->\n <!--\t\t\tstyle=\"font-weight: bold\"-->\n <!--\t\t>-->\n <!--\t\t\tTotal-->\n <!--\t\t\t<div slot=\"end\">-->\n <!--\t\t\t\t{{ asset.totals.per(period, true, true) }}-->\n <!--\t\t\t</div>-->\n <!--\t\t</ion-item>-->\n <!--\t</ion-list>-->\n <!--<ion-card-content *ngIf=\"asset.incomes || asset.liabilities\">-->\n <!--<ion-segment [(value)]=\"segment\" (ionChange)=\"segmentChanged($event)\">-->\n <!--<ion-segment-button value=\"expenses\">-->\n <!--Expenses-->\n <!--<ng-container *ngIf=\"!asset.liabilities || !asset.liabilities.length\">: none</ng-container>-->\n <!--</ion-segment-button>-->\n <!--<ion-segment-button value=\"income\">-->\n <!--Income-->\n <!--<ng-container *ngIf=\"!asset.incomes || !asset.incomes.length\">: none</ng-container>-->\n <!--</ion-segment-button>-->\n <!--</ion-segment>-->\n <!--<ion-list *ngIf=\"segment === 'expenses'\">-->\n <!--<ng-container *ngIf=\"!asset.liabilities || !asset.liabilities.length\">-->\n <!--No expenses.-->\n <!--</ng-container>-->\n <!--<ion-item *ngFor=\"let liability of asset.liabilities\">-->\n <!--{{liability.title}}: \u20AC{{liability.amount}}/{{liability.period}}-->\n <!--</ion-item>-->\n <!--</ion-list>-->\n <!--<ion-list *ngIf=\"segment === 'income'\">-->\n <!--<ng-container *ngIf=\"!asset.incomes || !asset.incomes.length\">-->\n <!--No income.-->\n <!--</ng-container>-->\n <!--<ion-item *ngFor=\"let income of asset.incomes\">-->\n <!--{{income.title}}: \u20AC{{income.amount}}/{{income.period}}-->\n <!--</ion-item>-->\n <!--</ion-list>-->\n <!--</ion-card-content>-->\n @if (asset?.dbo?.subAssets) {\n <ion-card-content>\n @for (subAsset of asset?.dbo?.subAssets || []; track subAsset.id) {\n <ion-item>\n <ion-label>\n <h3>{{ subAsset.title }}</h3>\n </ion-label>\n </ion-item>\n }\n </ion-card-content>\n }\n</ion-card>\n", dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }] }); }
23
+ }
24
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AssetCardComponent, decorators: [{
25
+ type: Component,
26
+ args: [{ selector: 'sneat-asset-card', imports: [
27
+ RouterModule,
28
+ IonCard,
29
+ IonCardHeader,
30
+ IonCardTitle,
31
+ IonCardContent,
32
+ IonItem,
33
+ IonLabel,
34
+ ], template: "<ion-card\n tappable\n [routerLink]=\"'/asset/' + asset?.id\"\n routerDirection=\"forward\"\n>\n <ion-card-header>\n <ion-card-title>\n {{ asset?.dbo?.title }}\n </ion-card-title>\n </ion-card-header>\n <!--\t<ion-list>-->\n <!--\t\t<ion-item *ngIf=\"asset?.dto?.totals.per(period, true, false)\">-->\n <!--\t\t\tIncomes ({{ asset.totals.incomes.count }})-->\n <!--\t\t\t<div slot=\"end\">-->\n <!--\t\t\t\t{{ asset.totals.per(period, true, false) }}-->\n <!--\t\t\t</div>-->\n <!--\t\t</ion-item>-->\n <!--\t\t<ion-item *ngIf=\"asset.totals.per(period, false, true)\">-->\n <!--\t\t\tExpenses ({{ asset.totals.expenses.count }})-->\n <!--\t\t\t<div slot=\"end\">-->\n <!--\t\t\t\t{{ asset.totals.per(period, false, true) }}-->\n <!--\t\t\t</div>-->\n <!--\t\t</ion-item>-->\n <!--\t\t<ion-item-->\n <!--\t\t\t*ngIf=\"-->\n <!--\t\t\t\tasset.totals.per(period, true, false) &&-->\n <!--\t\t\t\tasset.totals.per(period, false, true)-->\n <!--\t\t\t\"-->\n <!--\t\t\tstyle=\"font-weight: bold\"-->\n <!--\t\t>-->\n <!--\t\t\tTotal-->\n <!--\t\t\t<div slot=\"end\">-->\n <!--\t\t\t\t{{ asset.totals.per(period, true, true) }}-->\n <!--\t\t\t</div>-->\n <!--\t\t</ion-item>-->\n <!--\t</ion-list>-->\n <!--<ion-card-content *ngIf=\"asset.incomes || asset.liabilities\">-->\n <!--<ion-segment [(value)]=\"segment\" (ionChange)=\"segmentChanged($event)\">-->\n <!--<ion-segment-button value=\"expenses\">-->\n <!--Expenses-->\n <!--<ng-container *ngIf=\"!asset.liabilities || !asset.liabilities.length\">: none</ng-container>-->\n <!--</ion-segment-button>-->\n <!--<ion-segment-button value=\"income\">-->\n <!--Income-->\n <!--<ng-container *ngIf=\"!asset.incomes || !asset.incomes.length\">: none</ng-container>-->\n <!--</ion-segment-button>-->\n <!--</ion-segment>-->\n <!--<ion-list *ngIf=\"segment === 'expenses'\">-->\n <!--<ng-container *ngIf=\"!asset.liabilities || !asset.liabilities.length\">-->\n <!--No expenses.-->\n <!--</ng-container>-->\n <!--<ion-item *ngFor=\"let liability of asset.liabilities\">-->\n <!--{{liability.title}}: \u20AC{{liability.amount}}/{{liability.period}}-->\n <!--</ion-item>-->\n <!--</ion-list>-->\n <!--<ion-list *ngIf=\"segment === 'income'\">-->\n <!--<ng-container *ngIf=\"!asset.incomes || !asset.incomes.length\">-->\n <!--No income.-->\n <!--</ng-container>-->\n <!--<ion-item *ngFor=\"let income of asset.incomes\">-->\n <!--{{income.title}}: \u20AC{{income.amount}}/{{income.period}}-->\n <!--</ion-item>-->\n <!--</ion-list>-->\n <!--</ion-card-content>-->\n @if (asset?.dbo?.subAssets) {\n <ion-card-content>\n @for (subAsset of asset?.dbo?.subAssets || []; track subAsset.id) {\n <ion-item>\n <ion-label>\n <h3>{{ subAsset.title }}</h3>\n </ion-label>\n </ion-item>\n }\n </ion-card-content>\n }\n</ion-card>\n" }]
35
+ }], propDecorators: { period: [{
36
+ type: Input
37
+ }], asset: [{
38
+ type: Input,
39
+ args: [{ required: true }]
40
+ }] } });
41
+ //# sourceMappingURL=asset-card.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-card.component.js","sourceRoot":"","sources":["../../../../../../../../libs/extensions/assetus/components/src/lib/asset-card/asset-card.component.ts","../../../../../../../../libs/extensions/assetus/components/src/lib/asset-card/asset-card.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAA4B,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,OAAO,EACP,cAAc,EACd,aAAa,EACb,YAAY,EACZ,OAAO,EACP,QAAQ,GACT,MAAM,2BAA2B,CAAC;;;AAiBnC,MAAM,OAAO,kBAAkB;IAb/B;QAiBY,YAAO,GAA0B,UAAU,CAAC;KAevD;IAbC,WAAW,CAAC,OAAsB;QAChC,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAC9C,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC;YAC/C,IAAI,OAAO,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC7D,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IAED,cAAc,CAAC,EAAe;QAC5B,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;IACjC,CAAC;8GAlBU,kBAAkB;kGAAlB,kBAAkB,+IC1B/B,40FA4EA,2CD3DI,YAAY,gRACZ,OAAO,yLACP,aAAa,sGACb,YAAY,sFACZ,cAAc,+EACd,OAAO,0NACP,QAAQ;;2FAGC,kBAAkB;kBAb9B,SAAS;+BACE,kBAAkB,WAEnB;wBACP,YAAY;wBACZ,OAAO;wBACP,aAAa;wBACb,YAAY;wBACZ,cAAc;wBACd,OAAO;wBACP,QAAQ;qBACT;;sBAGA,KAAK;;sBACL,KAAK;uBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE","sourcesContent":["import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport {\n IonCard,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonItem,\n IonLabel,\n} from '@ionic/angular/standalone';\nimport { Period } from '@sneat/dto';\nimport { IAssetContext } from '@sneat/mod-assetus-core';\n\n@Component({\n selector: 'sneat-asset-card',\n templateUrl: './asset-card.component.html',\n imports: [\n RouterModule,\n IonCard,\n IonCardHeader,\n IonCardTitle,\n IonCardContent,\n IonItem,\n IonLabel,\n ],\n})\nexport class AssetCardComponent implements OnChanges {\n @Input() period?: Period;\n @Input({ required: true }) asset?: IAssetContext;\n\n protected segment: 'expenses' | 'income' = 'expenses';\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['asset'] && this.asset) {\n const incomes = this.asset?.dbo?.totals?.incomes,\n expenses = this.asset?.dbo?.totals?.expenses;\n if (incomes && (!expenses || incomes.count > expenses.count)) {\n this.segment = 'income';\n }\n }\n }\n\n segmentChanged(ev: CustomEvent): void {\n this.segment = ev.detail.value;\n }\n}\n","<ion-card\n tappable\n [routerLink]=\"'/asset/' + asset?.id\"\n routerDirection=\"forward\"\n>\n <ion-card-header>\n <ion-card-title>\n {{ asset?.dbo?.title }}\n </ion-card-title>\n </ion-card-header>\n <!--\t<ion-list>-->\n <!--\t\t<ion-item *ngIf=\"asset?.dto?.totals.per(period, true, false)\">-->\n <!--\t\t\tIncomes ({{ asset.totals.incomes.count }})-->\n <!--\t\t\t<div slot=\"end\">-->\n <!--\t\t\t\t{{ asset.totals.per(period, true, false) }}-->\n <!--\t\t\t</div>-->\n <!--\t\t</ion-item>-->\n <!--\t\t<ion-item *ngIf=\"asset.totals.per(period, false, true)\">-->\n <!--\t\t\tExpenses ({{ asset.totals.expenses.count }})-->\n <!--\t\t\t<div slot=\"end\">-->\n <!--\t\t\t\t{{ asset.totals.per(period, false, true) }}-->\n <!--\t\t\t</div>-->\n <!--\t\t</ion-item>-->\n <!--\t\t<ion-item-->\n <!--\t\t\t*ngIf=\"-->\n <!--\t\t\t\tasset.totals.per(period, true, false) &&-->\n <!--\t\t\t\tasset.totals.per(period, false, true)-->\n <!--\t\t\t\"-->\n <!--\t\t\tstyle=\"font-weight: bold\"-->\n <!--\t\t>-->\n <!--\t\t\tTotal-->\n <!--\t\t\t<div slot=\"end\">-->\n <!--\t\t\t\t{{ asset.totals.per(period, true, true) }}-->\n <!--\t\t\t</div>-->\n <!--\t\t</ion-item>-->\n <!--\t</ion-list>-->\n <!--<ion-card-content *ngIf=\"asset.incomes || asset.liabilities\">-->\n <!--<ion-segment [(value)]=\"segment\" (ionChange)=\"segmentChanged($event)\">-->\n <!--<ion-segment-button value=\"expenses\">-->\n <!--Expenses-->\n <!--<ng-container *ngIf=\"!asset.liabilities || !asset.liabilities.length\">: none</ng-container>-->\n <!--</ion-segment-button>-->\n <!--<ion-segment-button value=\"income\">-->\n <!--Income-->\n <!--<ng-container *ngIf=\"!asset.incomes || !asset.incomes.length\">: none</ng-container>-->\n <!--</ion-segment-button>-->\n <!--</ion-segment>-->\n <!--<ion-list *ngIf=\"segment === 'expenses'\">-->\n <!--<ng-container *ngIf=\"!asset.liabilities || !asset.liabilities.length\">-->\n <!--No expenses.-->\n <!--</ng-container>-->\n <!--<ion-item *ngFor=\"let liability of asset.liabilities\">-->\n <!--{{liability.title}}: €{{liability.amount}}/{{liability.period}}-->\n <!--</ion-item>-->\n <!--</ion-list>-->\n <!--<ion-list *ngIf=\"segment === 'income'\">-->\n <!--<ng-container *ngIf=\"!asset.incomes || !asset.incomes.length\">-->\n <!--No income.-->\n <!--</ng-container>-->\n <!--<ion-item *ngFor=\"let income of asset.incomes\">-->\n <!--{{income.title}}: €{{income.amount}}/{{income.period}}-->\n <!--</ion-item>-->\n <!--</ion-list>-->\n <!--</ion-card-content>-->\n @if (asset?.dbo?.subAssets) {\n <ion-card-content>\n @for (subAsset of asset?.dbo?.subAssets || []; track subAsset.id) {\n <ion-item>\n <ion-label>\n <h3>{{ subAsset.title }}</h3>\n </ion-label>\n </ion-item>\n }\n </ion-card-content>\n }\n</ion-card>\n"]}
@@ -0,0 +1,16 @@
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { AssetService } from './services';
3
+ import { SpaceComponentBaseParams } from '@sneat/space-components';
4
+ import * as i0 from "@angular/core";
5
+ export class AssetComponentBaseParams {
6
+ constructor() {
7
+ this.spaceParams = inject(SpaceComponentBaseParams);
8
+ this.assetService = inject(AssetService);
9
+ }
10
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AssetComponentBaseParams, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
11
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AssetComponentBaseParams }); }
12
+ }
13
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AssetComponentBaseParams, decorators: [{
14
+ type: Injectable
15
+ }] });
16
+ //# sourceMappingURL=asset-component-base-params.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-component-base-params.js","sourceRoot":"","sources":["../../../../../../../libs/extensions/assetus/components/src/lib/asset-component-base-params.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;;AAGnE,MAAM,OAAO,wBAAwB;IADrC;QAEW,gBAAW,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;QAC/C,iBAAY,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;KAC9C;8GAHY,wBAAwB;kHAAxB,wBAAwB;;2FAAxB,wBAAwB;kBADpC,UAAU","sourcesContent":["import { Injectable, inject } from '@angular/core';\nimport { AssetService } from './services';\nimport { SpaceComponentBaseParams } from '@sneat/space-components';\n\n@Injectable()\nexport class AssetComponentBaseParams {\n readonly spaceParams = inject(SpaceComponentBaseParams);\n readonly assetService = inject(AssetService);\n}\n"]}
@@ -0,0 +1,36 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { FormsModule } from '@angular/forms';
3
+ import { IonCard, IonItem, IonLabel } from '@ionic/angular/standalone';
4
+ import { SelectFromListComponent } from '@sneat/ui';
5
+ import { AssetPossessions, } from '@sneat/mod-assetus-core';
6
+ import * as i0 from "@angular/core";
7
+ export class AssetPossessionCardComponent {
8
+ constructor() {
9
+ this.assetChange = new EventEmitter();
10
+ this.possessionOptions = AssetPossessions.map((p) => ({
11
+ id: p,
12
+ title: p,
13
+ iconName: 'radio-button-off',
14
+ }));
15
+ }
16
+ onPossessionChanged(possession) {
17
+ if (this.asset?.dbo) {
18
+ this.asset = {
19
+ ...this.asset,
20
+ dbo: { ...this.asset.dbo, possession: possession },
21
+ };
22
+ this.assetChange.emit(this.asset);
23
+ }
24
+ }
25
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AssetPossessionCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: AssetPossessionCardComponent, isStandalone: true, selector: "sneat-asset-possession-card", inputs: { asset: "asset" }, outputs: { assetChange: "assetChange" }, ngImport: i0, template: "<ion-card>\n @if (!asset?.dbo?.possession) {\n <ion-item lines=\"full\" color=\"light\">\n <ion-label>Possession</ion-label>\n </ion-item>\n }\n <sneat-select-from-list\n [items]=\"possessionOptions\"\n [value]=\"asset?.dbo?.possession || ''\"\n label=\"Possession\"\n [isFilterable]=\"false\"\n labelPlacement=\"end\"\n (valueChange)=\"onPossessionChanged($event)\"\n />\n</ion-card>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: SelectFromListComponent, selector: "sneat-select-from-list", inputs: ["value", "filterLabel", "label", "listLabel", "listLabelColor", "isFilterable", "isLoading", "items", "items$", "lastItemLines", "labelPlacement", "justify", "other", "canAdd", "filterItem", "selectMode", "isReadonly", "$isProcessing", "sortBy"], outputs: ["valueChange", "filterChanged"] }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }] }); }
27
+ }
28
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AssetPossessionCardComponent, decorators: [{
29
+ type: Component,
30
+ args: [{ selector: 'sneat-asset-possession-card', imports: [FormsModule, SelectFromListComponent, IonCard, IonItem, IonLabel], template: "<ion-card>\n @if (!asset?.dbo?.possession) {\n <ion-item lines=\"full\" color=\"light\">\n <ion-label>Possession</ion-label>\n </ion-item>\n }\n <sneat-select-from-list\n [items]=\"possessionOptions\"\n [value]=\"asset?.dbo?.possession || ''\"\n label=\"Possession\"\n [isFilterable]=\"false\"\n labelPlacement=\"end\"\n (valueChange)=\"onPossessionChanged($event)\"\n />\n</ion-card>\n" }]
31
+ }], propDecorators: { asset: [{
32
+ type: Input
33
+ }], assetChange: [{
34
+ type: Output
35
+ }] } });
36
+ //# sourceMappingURL=asset-possession-card.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-possession-card.component.js","sourceRoot":"","sources":["../../../../../../../../libs/extensions/assetus/components/src/lib/asset-possesion-card/asset-possession-card.component.ts","../../../../../../../../libs/extensions/assetus/components/src/lib/asset-possesion-card/asset-possession-card.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAe,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAEL,gBAAgB,GAEjB,MAAM,yBAAyB,CAAC;;AAOjC,MAAM,OAAO,4BAA4B;IALzC;QAO4B,gBAAW,GAAG,IAAI,YAAY,EAAiB,CAAC;QAEvD,sBAAiB,GAAkB,gBAAgB,CAAC,GAAG,CACxE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACN,EAAE,EAAE,CAAC;YACL,KAAK,EAAE,CAAC;YACR,QAAQ,EAAE,kBAAkB;SAC7B,CAAC,CACH,CAAC;KAWH;IATW,mBAAmB,CAAC,UAAkB;QAC9C,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;YACpB,IAAI,CAAC,KAAK,GAAG;gBACX,GAAG,IAAI,CAAC,KAAK;gBACb,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,UAA6B,EAAE;aACtE,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;8GApBU,4BAA4B;kGAA5B,4BAA4B,4JCfzC,qaAeA,2CDFY,WAAW,+BAAE,uBAAuB,8WAAE,OAAO,yLAAE,OAAO,0NAAE,QAAQ;;2FAE/D,4BAA4B;kBALxC,SAAS;+BACE,6BAA6B,WAE9B,CAAC,WAAW,EAAE,uBAAuB,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC;;sBAG1E,KAAK;;sBACL,MAAM","sourcesContent":["import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { IonCard, IonItem, IonLabel } from '@ionic/angular/standalone';\nimport { ISelectItem, SelectFromListComponent } from '@sneat/ui';\nimport {\n AssetPossession,\n AssetPossessions,\n IAssetContext,\n} from '@sneat/mod-assetus-core';\n\n@Component({\n selector: 'sneat-asset-possession-card',\n templateUrl: './asset-possession-card.component.html',\n imports: [FormsModule, SelectFromListComponent, IonCard, IonItem, IonLabel],\n})\nexport class AssetPossessionCardComponent {\n @Input() public asset?: IAssetContext;\n @Output() public readonly assetChange = new EventEmitter<IAssetContext>();\n\n protected readonly possessionOptions: ISelectItem[] = AssetPossessions.map(\n (p) => ({\n id: p,\n title: p,\n iconName: 'radio-button-off',\n }),\n );\n\n protected onPossessionChanged(possession: string): void {\n if (this.asset?.dbo) {\n this.asset = {\n ...this.asset,\n dbo: { ...this.asset.dbo, possession: possession as AssetPossession },\n };\n this.assetChange.emit(this.asset);\n }\n }\n}\n","<ion-card>\n @if (!asset?.dbo?.possession) {\n <ion-item lines=\"full\" color=\"light\">\n <ion-label>Possession</ion-label>\n </ion-item>\n }\n <sneat-select-from-list\n [items]=\"possessionOptions\"\n [value]=\"asset?.dbo?.possession || ''\"\n label=\"Possession\"\n [isFilterable]=\"false\"\n labelPlacement=\"end\"\n (valueChange)=\"onPossessionChanged($event)\"\n />\n</ion-card>\n"]}
@@ -0,0 +1,118 @@
1
+ import { Component, EventEmitter, Input, Output, ViewChild, inject, } from '@angular/core';
2
+ import { FormControl, ReactiveFormsModule } from '@angular/forms';
3
+ import { IonButton, IonButtons, IonIcon, IonInput, IonItem, IonLabel, } from '@ionic/angular/standalone';
4
+ import { AssetService } from '../services';
5
+ import { ErrorLogger } from '@sneat/core';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "@angular/forms";
8
+ export class AssetRegNumberInputComponent {
9
+ constructor() {
10
+ this.assetService = inject(AssetService);
11
+ this.errorLogger = inject(ErrorLogger);
12
+ this.regNumber = '';
13
+ this.hideSaveButton = false;
14
+ this.placeholder = '';
15
+ this.regNumberChange = new EventEmitter();
16
+ this.isSkipped = false;
17
+ this.isSkippedChange = new EventEmitter();
18
+ this.isSaving = false;
19
+ this.regNumberControl = new FormControl('');
20
+ }
21
+ ngOnChanges(changes) {
22
+ if (changes['regNumber'] && !this.regNumberControl.dirty) {
23
+ this.regNumberControl.setValue(this.regNumber || '');
24
+ }
25
+ }
26
+ get showSave() {
27
+ return (!this.hideSaveButton &&
28
+ this.regNumberControl.dirty &&
29
+ (this.regNumber || '') !== this.regNumberControl.value);
30
+ }
31
+ get isValidated() {
32
+ return this.validatedRegNumber === this.regNumberControl.value?.trim();
33
+ }
34
+ validate() {
35
+ this.validatedRegNumber = this.regNumberControl.value?.trim();
36
+ this.skipOrNext();
37
+ }
38
+ skipOrNext() {
39
+ const regNumber = this.regNumberControl.value?.trim();
40
+ if (regNumber) {
41
+ this.regNumberChange.emit(regNumber);
42
+ }
43
+ this.isSkippedChange.emit();
44
+ }
45
+ submit() {
46
+ const space = this.space;
47
+ if (!space?.id || !this.assetID) {
48
+ return;
49
+ }
50
+ const request = {
51
+ spaceID: space.id,
52
+ assetID: this.assetID,
53
+ assetCategory: 'vehicle',
54
+ regNumber: this.regNumberControl.value || '',
55
+ };
56
+ this.isSaving = true;
57
+ this.regNumberControl.disable();
58
+ this.assetService.updateAsset(request).subscribe({
59
+ next: () => {
60
+ this.regNumberControl.markAsPristine();
61
+ this.isSaving = false;
62
+ this.regNumberControl.enable();
63
+ },
64
+ error: (e) => {
65
+ setTimeout(() => {
66
+ this.isSaving = false;
67
+ this.regNumberControl.enable();
68
+ }, 1000);
69
+ this.errorLogger.logError(e, 'Failed to save registration number');
70
+ },
71
+ });
72
+ }
73
+ focusToRegNumberInput() {
74
+ this.regNumberInput
75
+ .setFocus()
76
+ .catch((e) => console.error('Failed to focus to reg number input', e));
77
+ }
78
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AssetRegNumberInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
79
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: AssetRegNumberInputComponent, isStandalone: true, selector: "sneat-asset-reg-number", inputs: { space: "space", assetID: "assetID", countyID: "countyID", regNumber: "regNumber", hideSaveButton: "hideSaveButton", placeholder: "placeholder", isSkipped: "isSkipped" }, outputs: { regNumberChange: "regNumberChange", isSkippedChange: "isSkippedChange" }, viewQueries: [{ propertyName: "regNumberInput", first: true, predicate: IonInput, descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<ion-item>\n <ion-input\n label=\"Registration #\"\n [formControl]=\"regNumberControl\"\n [placeholder]=\"placeholder\"\n (keyup.enter)=\"submit()\"\n />\n <ion-buttons slot=\"end\">\n @if (!isSkipped && !assetID) {\n <ion-button color=\"medium\" (click)=\"skipOrNext()\">\n @if (regNumberControl.value) {\n Next\n } @else {\n Skip\n }\n </ion-button>\n }\n\n @if (!isValidated && (!assetID || regNumberControl.dirty)) {\n <ion-button\n fill=\"solid\"\n color=\"primary\"\n [disabled]=\"!regNumberControl.value\"\n (click)=\"validate()\"\n >\n <ion-icon name=\"search-outline\" />\n <ion-label>Validate</ion-label>\n </ion-button>\n }\n\n @if (assetID && regNumberControl.dirty) {\n <ion-button\n (click)=\"\n regNumberControl.setValue(regNumber || '');\n regNumberControl.markAsPristine()\n \"\n >\n <ion-label>Cancel</ion-label>\n </ion-button>\n }\n\n @if (showSave) {\n <ion-button\n [color]=\"isSaving ? 'primary' : undefined\"\n [disabled]=\"isSaving\"\n (click)=\"submit()\"\n >\n <ion-icon name=\"save\" slot=\"start\" />\n <ion-label>\n @if (isSaving) {\n Saving...\n } @else {\n Save\n }\n </ion-label>\n </ion-button>\n }\n </ion-buttons>\n</ion-item>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
80
+ }
81
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AssetRegNumberInputComponent, decorators: [{
82
+ type: Component,
83
+ args: [{ selector: 'sneat-asset-reg-number', imports: [
84
+ ReactiveFormsModule,
85
+ IonItem,
86
+ IonInput,
87
+ IonButtons,
88
+ IonButton,
89
+ IonLabel,
90
+ IonIcon,
91
+ ], template: "<ion-item>\n <ion-input\n label=\"Registration #\"\n [formControl]=\"regNumberControl\"\n [placeholder]=\"placeholder\"\n (keyup.enter)=\"submit()\"\n />\n <ion-buttons slot=\"end\">\n @if (!isSkipped && !assetID) {\n <ion-button color=\"medium\" (click)=\"skipOrNext()\">\n @if (regNumberControl.value) {\n Next\n } @else {\n Skip\n }\n </ion-button>\n }\n\n @if (!isValidated && (!assetID || regNumberControl.dirty)) {\n <ion-button\n fill=\"solid\"\n color=\"primary\"\n [disabled]=\"!regNumberControl.value\"\n (click)=\"validate()\"\n >\n <ion-icon name=\"search-outline\" />\n <ion-label>Validate</ion-label>\n </ion-button>\n }\n\n @if (assetID && regNumberControl.dirty) {\n <ion-button\n (click)=\"\n regNumberControl.setValue(regNumber || '');\n regNumberControl.markAsPristine()\n \"\n >\n <ion-label>Cancel</ion-label>\n </ion-button>\n }\n\n @if (showSave) {\n <ion-button\n [color]=\"isSaving ? 'primary' : undefined\"\n [disabled]=\"isSaving\"\n (click)=\"submit()\"\n >\n <ion-icon name=\"save\" slot=\"start\" />\n <ion-label>\n @if (isSaving) {\n Saving...\n } @else {\n Save\n }\n </ion-label>\n </ion-button>\n }\n </ion-buttons>\n</ion-item>\n" }]
92
+ }], propDecorators: { space: [{
93
+ type: Input,
94
+ args: [{ required: true }]
95
+ }], assetID: [{
96
+ type: Input,
97
+ args: [{ required: true }]
98
+ }], countyID: [{
99
+ type: Input,
100
+ args: [{ required: true }]
101
+ }], regNumber: [{
102
+ type: Input,
103
+ args: [{ required: true }]
104
+ }], hideSaveButton: [{
105
+ type: Input
106
+ }], placeholder: [{
107
+ type: Input
108
+ }], regNumberChange: [{
109
+ type: Output
110
+ }], isSkipped: [{
111
+ type: Input
112
+ }], isSkippedChange: [{
113
+ type: Output
114
+ }], regNumberInput: [{
115
+ type: ViewChild,
116
+ args: [IonInput, { static: true }]
117
+ }] } });
118
+ //# sourceMappingURL=asset-reg-number-input.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-reg-number-input.component.js","sourceRoot":"","sources":["../../../../../../../../libs/extensions/assetus/components/src/lib/asset-reg-number-input/asset-reg-number-input.component.ts","../../../../../../../../libs/extensions/assetus/components/src/lib/asset-reg-number-input/asset-reg-number-input.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n EventEmitter,\n Input,\n OnChanges,\n Output,\n SimpleChanges,\n ViewChild,\n inject,\n} from '@angular/core';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport {\n IonButton,\n IonButtons,\n IonIcon,\n IonInput,\n IonItem,\n IonLabel,\n} from '@ionic/angular/standalone';\nimport { AssetService, IUpdateAssetRequest } from '../services';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport { ISpaceContext } from '@sneat/space-models';\n\n@Component({\n selector: 'sneat-asset-reg-number',\n templateUrl: 'asset-reg-number-input.component.html',\n imports: [\n ReactiveFormsModule,\n IonItem,\n IonInput,\n IonButtons,\n IonButton,\n IonLabel,\n IonIcon,\n ],\n})\nexport class AssetRegNumberInputComponent implements OnChanges {\n private readonly assetService = inject(AssetService);\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n\n @Input({ required: true }) space?: ISpaceContext;\n @Input({ required: true }) assetID?: string;\n @Input({ required: true }) countyID?: string;\n @Input({ required: true }) regNumber?: string = '';\n @Input() hideSaveButton = false;\n @Input() placeholder = '';\n\n @Output() regNumberChange = new EventEmitter<string>();\n\n @Input() isSkipped = false;\n @Output() isSkippedChange = new EventEmitter<boolean>();\n\n @ViewChild(IonInput, { static: true }) regNumberInput!: IonInput;\n\n protected validatedRegNumber?: string;\n\n protected isSaving = false;\n protected readonly regNumberControl = new FormControl('');\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['regNumber'] && !this.regNumberControl.dirty) {\n this.regNumberControl.setValue(this.regNumber || '');\n }\n }\n\n protected get showSave(): boolean {\n return (\n !this.hideSaveButton &&\n this.regNumberControl.dirty &&\n (this.regNumber || '') !== this.regNumberControl.value\n );\n }\n\n protected get isValidated(): boolean {\n return this.validatedRegNumber === this.regNumberControl.value?.trim();\n }\n protected validate(): void {\n this.validatedRegNumber = this.regNumberControl.value?.trim();\n this.skipOrNext();\n }\n\n protected skipOrNext(): void {\n const regNumber = this.regNumberControl.value?.trim();\n if (regNumber) {\n this.regNumberChange.emit(regNumber);\n }\n this.isSkippedChange.emit();\n }\n\n protected submit(): void {\n const space = this.space;\n\n if (!space?.id || !this.assetID) {\n return;\n }\n\n const request: IUpdateAssetRequest = {\n spaceID: space.id,\n assetID: this.assetID,\n assetCategory: 'vehicle',\n regNumber: this.regNumberControl.value || '',\n };\n this.isSaving = true;\n this.regNumberControl.disable();\n this.assetService.updateAsset(request).subscribe({\n next: () => {\n this.regNumberControl.markAsPristine();\n this.isSaving = false;\n this.regNumberControl.enable();\n },\n error: (e) => {\n setTimeout(() => {\n this.isSaving = false;\n this.regNumberControl.enable();\n }, 1000);\n this.errorLogger.logError(e, 'Failed to save registration number');\n },\n });\n }\n\n public focusToRegNumberInput(): void {\n this.regNumberInput\n .setFocus()\n .catch((e) => console.error('Failed to focus to reg number input', e));\n }\n}\n","<ion-item>\n <ion-input\n label=\"Registration #\"\n [formControl]=\"regNumberControl\"\n [placeholder]=\"placeholder\"\n (keyup.enter)=\"submit()\"\n />\n <ion-buttons slot=\"end\">\n @if (!isSkipped && !assetID) {\n <ion-button color=\"medium\" (click)=\"skipOrNext()\">\n @if (regNumberControl.value) {\n Next\n } @else {\n Skip\n }\n </ion-button>\n }\n\n @if (!isValidated && (!assetID || regNumberControl.dirty)) {\n <ion-button\n fill=\"solid\"\n color=\"primary\"\n [disabled]=\"!regNumberControl.value\"\n (click)=\"validate()\"\n >\n <ion-icon name=\"search-outline\" />\n <ion-label>Validate</ion-label>\n </ion-button>\n }\n\n @if (assetID && regNumberControl.dirty) {\n <ion-button\n (click)=\"\n regNumberControl.setValue(regNumber || '');\n regNumberControl.markAsPristine()\n \"\n >\n <ion-label>Cancel</ion-label>\n </ion-button>\n }\n\n @if (showSave) {\n <ion-button\n [color]=\"isSaving ? 'primary' : undefined\"\n [disabled]=\"isSaving\"\n (click)=\"submit()\"\n >\n <ion-icon name=\"save\" slot=\"start\" />\n <ion-label>\n @if (isSaving) {\n Saving...\n } @else {\n Save\n }\n </ion-label>\n </ion-button>\n }\n </ion-buttons>\n</ion-item>\n"]}
@@ -0,0 +1,138 @@
1
+ import { Component, Input, inject, } from '@angular/core';
2
+ import { IonBadge, IonButton, IonButtons, IonIcon, IonItem, IonLabel, IonSpinner, ModalController, } from '@ionic/angular/standalone';
3
+ import { ErrorLogger } from '@sneat/core';
4
+ import { SpaceNavService } from '@sneat/space-services';
5
+ import { AssetService } from '../services';
6
+ import { MileAgeDialogComponent } from '../mileage-dialog/mileage-dialog.component';
7
+ import * as i0 from "@angular/core";
8
+ export class AssetsListComponent {
9
+ constructor() {
10
+ this.errorLogger = inject(ErrorLogger);
11
+ this.assetService = inject(AssetService);
12
+ this.spaceNavService = inject(SpaceNavService);
13
+ this.modalCtrl = inject(ModalController);
14
+ this.filter = '';
15
+ this.sorter = () => {
16
+ // if (a.brief && b.brief && a.brief.title > b.brief?.title) return 1;
17
+ // if (a.brief && b.brief && a.brief.title < b.brief?.title) return -1;
18
+ return 0;
19
+ };
20
+ this.deletingIDs = [];
21
+ }
22
+ ngOnChanges(changes) {
23
+ const { allAssets, assetType, filter } = this;
24
+ if (!allAssets) {
25
+ this.assets = undefined;
26
+ return;
27
+ }
28
+ if (!allAssets.length) {
29
+ this.assets = [];
30
+ return;
31
+ }
32
+ const f = filter?.toLowerCase();
33
+ if (!allAssets || (!filter && !assetType)) {
34
+ this.assets = [...allAssets];
35
+ }
36
+ else {
37
+ this.assets = allAssets?.filter((asset) => (!assetType || asset?.brief?.category === assetType) &&
38
+ (!filter || asset?.brief?.title?.toLowerCase().includes(f) || -1));
39
+ }
40
+ this.assets = this.assets?.toSorted(this.sorter);
41
+ console.log('AssetsListComponent.ngOnChanges =>', changes, this.assetType, this.space, 'allAssets:', this.allAssets, 'filtered assets:', this.assets);
42
+ }
43
+ goAsset(asset) {
44
+ if (!asset) {
45
+ return;
46
+ }
47
+ // let path: string;
48
+ // switch (asset?.brief?.type) {
49
+ // // case 'vehicle':
50
+ // // path = 'vehicle';
51
+ // // break;
52
+ // // case 'real_estate':
53
+ // // path = this.team?.type === 'realtor' ? 'real-estate' : 'property';
54
+ // // break;
55
+ // default:
56
+ // path = 'asset';
57
+ // break;
58
+ // }
59
+ if (!this.space) {
60
+ this.errorLogger.logError('can not navigate to asset page without team context');
61
+ return;
62
+ }
63
+ this.spaceNavService
64
+ .navigateForwardToSpacePage(this.space, `asset/${asset.id}`, {
65
+ state: { asset },
66
+ })
67
+ .catch(this.errorLogger.logErrorHandler('failed to navigate to asset page'));
68
+ }
69
+ delete(event, asset) {
70
+ event.stopPropagation();
71
+ event.preventDefault();
72
+ const { id, brief } = asset;
73
+ this.deletingIDs.push(id);
74
+ const deleteCompleted = () => (this.deletingIDs = this.deletingIDs.filter((v) => v !== id));
75
+ setTimeout(() => {
76
+ if (!confirm(`Are you sure you want to delete this asset?
77
+
78
+ ID: ${id}
79
+ Title: ${brief?.title}
80
+
81
+ This operation can not be undone.`)) {
82
+ deleteCompleted();
83
+ return;
84
+ }
85
+ this.assetService.deleteAsset(this.space?.id || '', asset.id).subscribe({
86
+ next: () => {
87
+ this.assets = this.assets?.filter((a) => a.id !== id);
88
+ },
89
+ error: this.errorLogger.logErrorHandler('failed to delete an asset with ID=' + id),
90
+ complete: deleteCompleted,
91
+ });
92
+ }, 1);
93
+ }
94
+ async addNewMilesAndFuel(event, asset) {
95
+ event.stopPropagation();
96
+ event.preventDefault();
97
+ const modal = await this.modalCtrl.create({
98
+ component: MileAgeDialogComponent,
99
+ componentProps: { asset },
100
+ });
101
+ await modal.present();
102
+ // this.mileAgeAsset = asset;
103
+ // this.assetService.addNewMilesAndFuel(asset.id).subscribe({
104
+ // next: () => {
105
+ // this.goAsset(asset);
106
+ // },
107
+ // error: this.errorLogger.logErrorHandler(
108
+ // 'failed to add new miles and fuel to asset with ID=' + asset.id,
109
+ // ),
110
+ // });
111
+ }
112
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AssetsListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
113
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: AssetsListComponent, isStandalone: true, selector: "sneat-assets-list", inputs: { allAssets: "allAssets", space: "space", assetType: "assetType", filter: "filter", sorter: "sorter" }, providers: [ModalController], usesOnChanges: true, ngImport: i0, template: "@if (!assets) {\n <ion-item [disabled]=\"true\">\n <ion-spinner slot=\"start\" name=\"lines-small\" />\n <ion-label>Loading...</ion-label>\n </ion-item>\n} @else if (!assets.length) {\n <ion-item [disabled]=\"true\">No items created yet</ion-item>\n} @else {\n <div class=\"last-child-no-border\">\n @for (asset of assets; track asset.id) {\n <ion-item\n tappable\n (click)=\"goAsset(asset)\"\n class=\"sneat-tiny-end-padding\"\n [class.deleting]=\"deletingIDs.includes(asset.id)\"\n >\n <ion-label\n [color]=\"deletingIDs.includes(asset.id) ? 'medium' : undefined\"\n >\n @switch (asset.brief.extraType) {\n @case (\"vehicle\") {\n @if (\n asset.brief.extra?.[\"make\"] && asset.brief.extra?.[\"model\"]\n ) {\n {{ asset.brief.extra?.[\"make\"] }}/{{\n asset.brief.extra?.[\"model\"]\n }}\n }\n @if (\n asset.brief.title &&\n asset.brief.extra?.[\"make\"] &&\n asset.brief.extra?.[\"model\"]\n ) {\n &mdash;\n }\n }\n @case (\"dwelling\") {\n {{ asset.brief.extra?.[\"address\"] || asset.brief.title }}\n }\n }\n @if (asset.brief.title) {\n {{ asset.brief.title }}\n }\n </ion-label>\n @if (asset.brief.yearOfBuild && !asset.brief.extra?.[\"regNumber\"]) {\n <ion-badge color=\"light\" style=\"font-weight: normal\"\n >{{ asset.brief.yearOfBuild }}\n </ion-badge>\n }\n @if (asset.brief.extra?.[\"regNumber\"]) {\n <ion-badge color=\"light\" style=\"font-weight: normal\"\n >{{ asset.brief.extra?.[\"regNumber\"] }}\n </ion-badge>\n }\n <ion-buttons slot=\"end\">\n @if (asset.brief.category === \"vehicle\") {\n <ion-button (click)=\"addNewMilesAndFuel($event, asset)\">\n <ion-icon name=\"add\" slot=\"start\"></ion-icon>\n <ion-label>Record miles</ion-label>\n <!-- <ion-label>Add miles & fuel</ion-label> -->\n </ion-button>\n }\n <ion-button\n (click)=\"delete($event, asset)\"\n [disabled]=\"deletingIDs.includes(asset.id)\"\n >\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n </ion-item>\n }\n </div>\n}\n", dependencies: [{ kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonBadge, selector: "ion-badge", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }] }); }
114
+ }
115
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AssetsListComponent, decorators: [{
116
+ type: Component,
117
+ args: [{ selector: 'sneat-assets-list', providers: [ModalController], imports: [
118
+ IonItem,
119
+ IonSpinner,
120
+ IonLabel,
121
+ IonButton,
122
+ IonIcon,
123
+ IonBadge,
124
+ IonButtons,
125
+ ], template: "@if (!assets) {\n <ion-item [disabled]=\"true\">\n <ion-spinner slot=\"start\" name=\"lines-small\" />\n <ion-label>Loading...</ion-label>\n </ion-item>\n} @else if (!assets.length) {\n <ion-item [disabled]=\"true\">No items created yet</ion-item>\n} @else {\n <div class=\"last-child-no-border\">\n @for (asset of assets; track asset.id) {\n <ion-item\n tappable\n (click)=\"goAsset(asset)\"\n class=\"sneat-tiny-end-padding\"\n [class.deleting]=\"deletingIDs.includes(asset.id)\"\n >\n <ion-label\n [color]=\"deletingIDs.includes(asset.id) ? 'medium' : undefined\"\n >\n @switch (asset.brief.extraType) {\n @case (\"vehicle\") {\n @if (\n asset.brief.extra?.[\"make\"] && asset.brief.extra?.[\"model\"]\n ) {\n {{ asset.brief.extra?.[\"make\"] }}/{{\n asset.brief.extra?.[\"model\"]\n }}\n }\n @if (\n asset.brief.title &&\n asset.brief.extra?.[\"make\"] &&\n asset.brief.extra?.[\"model\"]\n ) {\n &mdash;\n }\n }\n @case (\"dwelling\") {\n {{ asset.brief.extra?.[\"address\"] || asset.brief.title }}\n }\n }\n @if (asset.brief.title) {\n {{ asset.brief.title }}\n }\n </ion-label>\n @if (asset.brief.yearOfBuild && !asset.brief.extra?.[\"regNumber\"]) {\n <ion-badge color=\"light\" style=\"font-weight: normal\"\n >{{ asset.brief.yearOfBuild }}\n </ion-badge>\n }\n @if (asset.brief.extra?.[\"regNumber\"]) {\n <ion-badge color=\"light\" style=\"font-weight: normal\"\n >{{ asset.brief.extra?.[\"regNumber\"] }}\n </ion-badge>\n }\n <ion-buttons slot=\"end\">\n @if (asset.brief.category === \"vehicle\") {\n <ion-button (click)=\"addNewMilesAndFuel($event, asset)\">\n <ion-icon name=\"add\" slot=\"start\"></ion-icon>\n <ion-label>Record miles</ion-label>\n <!-- <ion-label>Add miles & fuel</ion-label> -->\n </ion-button>\n }\n <ion-button\n (click)=\"delete($event, asset)\"\n [disabled]=\"deletingIDs.includes(asset.id)\"\n >\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n </ion-item>\n }\n </div>\n}\n" }]
126
+ }], propDecorators: { allAssets: [{
127
+ type: Input
128
+ }], space: [{
129
+ type: Input,
130
+ args: [{ required: true }]
131
+ }], assetType: [{
132
+ type: Input
133
+ }], filter: [{
134
+ type: Input
135
+ }], sorter: [{
136
+ type: Input
137
+ }] } });
138
+ //# sourceMappingURL=assets-list.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets-list.component.js","sourceRoot":"","sources":["../../../../../../../../libs/extensions/assetus/components/src/lib/assets-list/assets-list.component.ts","../../../../../../../../libs/extensions/assetus/components/src/lib/assets-list/assets-list.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n OnChanges,\n SimpleChanges,\n inject,\n} from '@angular/core';\nimport {\n IonBadge,\n IonButton,\n IonButtons,\n IonIcon,\n IonItem,\n IonLabel,\n IonSpinner,\n ModalController,\n} from '@ionic/angular/standalone';\nimport { IIdAndBrief } from '@sneat/core';\nimport { AssetCategory, IAssetBrief } from '@sneat/mod-assetus-core';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport { ISpaceContext } from '@sneat/space-models';\nimport { SpaceNavService } from '@sneat/space-services';\nimport { AssetService } from '../services';\nimport { MileAgeDialogComponent } from '../mileage-dialog/mileage-dialog.component';\n\n@Component({\n selector: 'sneat-assets-list',\n templateUrl: './assets-list.component.html',\n providers: [ModalController],\n imports: [\n IonItem,\n IonSpinner,\n IonLabel,\n IonButton,\n IonIcon,\n IonBadge,\n IonButtons,\n ],\n})\nexport class AssetsListComponent implements OnChanges {\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n private readonly assetService = inject(AssetService);\n private readonly spaceNavService = inject(SpaceNavService);\n private readonly modalCtrl = inject(ModalController);\n\n protected assets?: IIdAndBrief<IAssetBrief>[];\n protected mileAgeAsset?: IIdAndBrief<IAssetBrief>;\n\n @Input() allAssets?: IIdAndBrief<IAssetBrief>[];\n @Input({ required: true }) space?: ISpaceContext;\n @Input() assetType?: AssetCategory;\n @Input() filter = '';\n\n @Input() sorter: (\n a: IIdAndBrief<IAssetBrief>,\n b: IIdAndBrief<IAssetBrief>,\n ) => number = () => {\n // if (a.brief && b.brief && a.brief.title > b.brief?.title) return 1;\n // if (a.brief && b.brief && a.brief.title < b.brief?.title) return -1;\n return 0;\n };\n\n protected deletingIDs: string[] = [];\n\n ngOnChanges(changes: SimpleChanges): void {\n const { allAssets, assetType, filter } = this;\n if (!allAssets) {\n this.assets = undefined;\n return;\n }\n if (!allAssets.length) {\n this.assets = [];\n return;\n }\n const f = filter?.toLowerCase();\n if (!allAssets || (!filter && !assetType)) {\n this.assets = [...allAssets];\n } else {\n this.assets = allAssets?.filter(\n (asset) =>\n (!assetType || asset?.brief?.category === assetType) &&\n (!filter || asset?.brief?.title?.toLowerCase().includes(f) || -1),\n );\n }\n this.assets = this.assets?.toSorted(this.sorter);\n console.log(\n 'AssetsListComponent.ngOnChanges =>',\n changes,\n this.assetType,\n this.space,\n 'allAssets:',\n this.allAssets,\n 'filtered assets:',\n this.assets,\n );\n }\n\n protected goAsset(asset: IIdAndBrief<IAssetBrief>): void {\n if (!asset) {\n return;\n }\n // let path: string;\n // switch (asset?.brief?.type) {\n // \t// case 'vehicle':\n // \t// \tpath = 'vehicle';\n // \t// \tbreak;\n // \t// case 'real_estate':\n // \t// \tpath = this.team?.type === 'realtor' ? 'real-estate' : 'property';\n // \t// \tbreak;\n // \tdefault:\n // \t\tpath = 'asset';\n // \t\tbreak;\n // }\n if (!this.space) {\n this.errorLogger.logError(\n 'can not navigate to asset page without team context',\n );\n return;\n }\n this.spaceNavService\n .navigateForwardToSpacePage(this.space, `asset/${asset.id}`, {\n state: { asset },\n })\n .catch(\n this.errorLogger.logErrorHandler('failed to navigate to asset page'),\n );\n }\n\n protected delete(event: Event, asset: IIdAndBrief<IAssetBrief>): void {\n event.stopPropagation();\n event.preventDefault();\n const { id, brief } = asset;\n this.deletingIDs.push(id);\n const deleteCompleted = () =>\n (this.deletingIDs = this.deletingIDs.filter((v) => v !== id));\n setTimeout(() => {\n if (\n !confirm(\n `Are you sure you want to delete this asset?\n\n ID: ${id}\n Title: ${brief?.title}\n\n This operation can not be undone.`,\n )\n ) {\n deleteCompleted();\n return;\n }\n this.assetService.deleteAsset(this.space?.id || '', asset.id).subscribe({\n next: () => {\n this.assets = this.assets?.filter((a) => a.id !== id);\n },\n error: this.errorLogger.logErrorHandler(\n 'failed to delete an asset with ID=' + id,\n ),\n complete: deleteCompleted,\n });\n }, 1);\n }\n\n protected async addNewMilesAndFuel(\n event: Event,\n asset: IIdAndBrief<IAssetBrief>,\n ) {\n event.stopPropagation();\n event.preventDefault();\n\n const modal = await this.modalCtrl.create({\n component: MileAgeDialogComponent,\n componentProps: { asset },\n });\n await modal.present();\n\n // this.mileAgeAsset = asset;\n\n // this.assetService.addNewMilesAndFuel(asset.id).subscribe({\n // \tnext: () => {\n // \t\tthis.goAsset(asset);\n // \t},\n // \terror: this.errorLogger.logErrorHandler(\n // \t\t'failed to add new miles and fuel to asset with ID=' + asset.id,\n // \t),\n // });\n }\n}\n","@if (!assets) {\n <ion-item [disabled]=\"true\">\n <ion-spinner slot=\"start\" name=\"lines-small\" />\n <ion-label>Loading...</ion-label>\n </ion-item>\n} @else if (!assets.length) {\n <ion-item [disabled]=\"true\">No items created yet</ion-item>\n} @else {\n <div class=\"last-child-no-border\">\n @for (asset of assets; track asset.id) {\n <ion-item\n tappable\n (click)=\"goAsset(asset)\"\n class=\"sneat-tiny-end-padding\"\n [class.deleting]=\"deletingIDs.includes(asset.id)\"\n >\n <ion-label\n [color]=\"deletingIDs.includes(asset.id) ? 'medium' : undefined\"\n >\n @switch (asset.brief.extraType) {\n @case (\"vehicle\") {\n @if (\n asset.brief.extra?.[\"make\"] && asset.brief.extra?.[\"model\"]\n ) {\n {{ asset.brief.extra?.[\"make\"] }}/{{\n asset.brief.extra?.[\"model\"]\n }}\n }\n @if (\n asset.brief.title &&\n asset.brief.extra?.[\"make\"] &&\n asset.brief.extra?.[\"model\"]\n ) {\n &mdash;\n }\n }\n @case (\"dwelling\") {\n {{ asset.brief.extra?.[\"address\"] || asset.brief.title }}\n }\n }\n @if (asset.brief.title) {\n {{ asset.brief.title }}\n }\n </ion-label>\n @if (asset.brief.yearOfBuild && !asset.brief.extra?.[\"regNumber\"]) {\n <ion-badge color=\"light\" style=\"font-weight: normal\"\n >{{ asset.brief.yearOfBuild }}\n </ion-badge>\n }\n @if (asset.brief.extra?.[\"regNumber\"]) {\n <ion-badge color=\"light\" style=\"font-weight: normal\"\n >{{ asset.brief.extra?.[\"regNumber\"] }}\n </ion-badge>\n }\n <ion-buttons slot=\"end\">\n @if (asset.brief.category === \"vehicle\") {\n <ion-button (click)=\"addNewMilesAndFuel($event, asset)\">\n <ion-icon name=\"add\" slot=\"start\"></ion-icon>\n <ion-label>Record miles</ion-label>\n <!-- <ion-label>Add miles & fuel</ion-label> -->\n </ion-button>\n }\n <ion-button\n (click)=\"delete($event, asset)\"\n [disabled]=\"deletingIDs.includes(asset.id)\"\n >\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n </ion-item>\n }\n </div>\n}\n"]}