@sneat/extension-debtus-ui 0.2.0 → 0.2.2

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 (28) hide show
  1. package/fesm2022/sneat-extension-debtus-ui-debtus-contact-details-page.component-ygSD0Q-C.mjs +101 -0
  2. package/fesm2022/sneat-extension-debtus-ui-debtus-contact-details-page.component-ygSD0Q-C.mjs.map +1 -0
  3. package/fesm2022/{sneat-extension-debtus-ui-debtus-contacts-page.component-DYtFeNsM.mjs → sneat-extension-debtus-ui-debtus-contacts-page.component-B2SicqpG.mjs} +5 -5
  4. package/fesm2022/sneat-extension-debtus-ui-debtus-contacts-page.component-B2SicqpG.mjs.map +1 -0
  5. package/fesm2022/sneat-extension-debtus-ui-debtus-home-page.component-Dd5-oQdz.mjs +95 -0
  6. package/fesm2022/sneat-extension-debtus-ui-debtus-home-page.component-Dd5-oQdz.mjs.map +1 -0
  7. package/fesm2022/{sneat-extension-debtus-ui-new-transfer-page.component-CT-6X_0e.mjs → sneat-extension-debtus-ui-new-transfer-page.component-YaGgYqKB.mjs} +16 -12
  8. package/fesm2022/sneat-extension-debtus-ui-new-transfer-page.component-YaGgYqKB.mjs.map +1 -0
  9. package/fesm2022/sneat-extension-debtus-ui-settle-up-page.component-48l8YFn4.mjs +162 -0
  10. package/fesm2022/sneat-extension-debtus-ui-settle-up-page.component-48l8YFn4.mjs.map +1 -0
  11. package/fesm2022/sneat-extension-debtus-ui-source-obligations-page.component-6E9_pHCq.mjs +423 -0
  12. package/fesm2022/sneat-extension-debtus-ui-source-obligations-page.component-6E9_pHCq.mjs.map +1 -0
  13. package/fesm2022/sneat-extension-debtus-ui-transfer-details-page.component-B6iQS1YJ.mjs +105 -0
  14. package/fesm2022/sneat-extension-debtus-ui-transfer-details-page.component-B6iQS1YJ.mjs.map +1 -0
  15. package/fesm2022/sneat-extension-debtus-ui.mjs +14 -36
  16. package/fesm2022/sneat-extension-debtus-ui.mjs.map +1 -1
  17. package/package.json +5 -3
  18. package/types/sneat-extension-debtus-ui.d.ts +1 -6
  19. package/fesm2022/sneat-extension-debtus-ui-debtus-contact-details-page.component-DIAVE0D6.mjs +0 -106
  20. package/fesm2022/sneat-extension-debtus-ui-debtus-contact-details-page.component-DIAVE0D6.mjs.map +0 -1
  21. package/fesm2022/sneat-extension-debtus-ui-debtus-contacts-page.component-DYtFeNsM.mjs.map +0 -1
  22. package/fesm2022/sneat-extension-debtus-ui-debtus-home-page.component-BCNMpirX.mjs +0 -97
  23. package/fesm2022/sneat-extension-debtus-ui-debtus-home-page.component-BCNMpirX.mjs.map +0 -1
  24. package/fesm2022/sneat-extension-debtus-ui-new-transfer-page.component-CT-6X_0e.mjs.map +0 -1
  25. package/fesm2022/sneat-extension-debtus-ui-settle-up-page.component-CUoNSuAE.mjs +0 -163
  26. package/fesm2022/sneat-extension-debtus-ui-settle-up-page.component-CUoNSuAE.mjs.map +0 -1
  27. package/fesm2022/sneat-extension-debtus-ui-transfer-details-page.component-uo5lP557.mjs +0 -97
  28. package/fesm2022/sneat-extension-debtus-ui-transfer-details-page.component-uo5lP557.mjs.map +0 -1
@@ -0,0 +1,105 @@
1
+ import { DatePipe } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, signal, Component } from '@angular/core';
4
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import { Router } from '@angular/router';
6
+ import { IonHeader, IonToolbar, IonButtons, IonBackButton, IonTitle, IonContent, IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonList, IonItem, IonLabel, IonNote, IonBadge, IonButton, IonIcon, IonSpinner } from '@ionic/angular';
7
+ import { DEBTUS_SERVICE, formatAmount } from '@sneat/extension-debtus-contract';
8
+ import { SpacePageBaseComponent, SpaceComponentBaseParams } from '@sneat/space-components';
9
+ import { SpaceServiceModule } from '@sneat/space-services';
10
+ import { ClassName } from '@sneat/ui';
11
+ import { combineLatest, switchMap, of } from 'rxjs';
12
+
13
+ // Transfer detail / receipt — amount, parties, date, note, and its effect on
14
+ // the balance. Mirrors the bot's receipt. Offers a settle-up entry.
15
+ class TransferDetailsPageComponent extends SpacePageBaseComponent {
16
+ debtusService = inject(DEBTUS_SERVICE);
17
+ router = inject(Router);
18
+ $loading = signal(true, /* @ts-ignore */
19
+ ...(ngDevMode ? [{ debugName: "$loading" }] : /* istanbul ignore next */ []));
20
+ $error = signal(undefined, /* @ts-ignore */
21
+ ...(ngDevMode ? [{ debugName: "$error" }] : /* istanbul ignore next */ []));
22
+ $transfer = signal(undefined, /* @ts-ignore */
23
+ ...(ngDevMode ? [{ debugName: "$transfer" }] : /* istanbul ignore next */ []));
24
+ formatAmount = formatAmount;
25
+ constructor() {
26
+ super();
27
+ this.$defaultBackUrlSpacePath.set('debts');
28
+ // A transfer just created by the new-transfer/settle-up pages is handed
29
+ // over via router `state` (it survives reloads through history.state).
30
+ // Prefer it to avoid an extra read immediately after creation. A cold load
31
+ // retrieves the same persisted transfer through the Debtus API.
32
+ const stateTransfer = (this.router.getCurrentNavigation()?.extras?.state ?? history.state)?.['transfer'];
33
+ combineLatest([this.spaceIDChanged$, this.route.paramMap])
34
+ .pipe(switchMap(([spaceID, params]) => {
35
+ const transferID = params.get('transferID') ?? '';
36
+ this.$loading.set(true);
37
+ this.$error.set(undefined);
38
+ if (stateTransfer?.id === transferID) {
39
+ return of(stateTransfer);
40
+ }
41
+ return this.debtusService.getTransfer(spaceID ?? '', transferID);
42
+ }), takeUntilDestroyed())
43
+ .subscribe({
44
+ next: (transfer) => {
45
+ this.$transfer.set(transfer);
46
+ this.$loading.set(false);
47
+ },
48
+ error: (err) => {
49
+ this.$error.set('Failed to load transfer');
50
+ this.$loading.set(false);
51
+ this.errorLogger.logError(err, 'Failed to load debtus transfer');
52
+ },
53
+ });
54
+ }
55
+ settleUp() {
56
+ const t = this.$transfer();
57
+ if (!t) {
58
+ return;
59
+ }
60
+ this.spaceNav.navigateForwardToSpacePage(this.space, `settle-up?contactID=${t.counterpartyContactID}`);
61
+ }
62
+ openContact() {
63
+ const t = this.$transfer();
64
+ if (!t?.counterpartyContactID) {
65
+ return;
66
+ }
67
+ this.spaceNav.navigateForwardToSpacePage(this.space, `debtus-contact/${t.counterpartyContactID}`);
68
+ }
69
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TransferDetailsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
70
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: TransferDetailsPageComponent, isStandalone: true, selector: "sneat-debtus-transfer-details-page", providers: [
71
+ { provide: ClassName, useValue: 'TransferDetailsPageComponent' },
72
+ SpaceComponentBaseParams,
73
+ ], usesInheritance: true, ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>Transfer</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"cardy\">\n @if ($loading()) {\n <div class=\"ion-padding ion-text-center\">\n <ion-spinner name=\"dots\" />\n </div>\n } @else if ($error()) {\n <div class=\"ion-padding\">\n <ion-note color=\"danger\">{{ $error() }}</ion-note>\n </div>\n } @else if ($transfer(); as t) {\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n {{ t.direction === 'lend' ? 'You lent' : 'You borrowed' }}\n @if (t.isReturn) { \u00B7 return }\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-badge\n [color]=\"t.direction === 'lend' ? 'success' : 'warning'\"\n style=\"font-size: 1.2rem\"\n >\n {{ formatAmount(t.amount) }}\n </ion-badge>\n </ion-card-content>\n </ion-card>\n\n <ion-card>\n <ion-list lines=\"full\">\n <ion-item button (click)=\"openContact()\">\n <ion-label>\n <p>Counterparty</p>\n <h2>{{ t.counterpartyTitle }}</h2>\n </ion-label>\n </ion-item>\n <ion-item>\n <ion-label>\n <p>Date</p>\n <h2>{{ t.created | date: 'medium' }}</h2>\n </ion-label>\n </ion-item>\n @if (t.dueOn) {\n <ion-item>\n <ion-label>\n <p>Due</p>\n <h2>{{ t.dueOn | date: 'mediumDate' }}</h2>\n </ion-label>\n </ion-item>\n }\n @if (t.note) {\n <ion-item>\n <ion-label class=\"ion-text-wrap\">\n <p>Note</p>\n <h2>{{ t.note }}</h2>\n </ion-label>\n </ion-item>\n }\n <ion-item>\n <ion-label>\n <p>Status</p>\n <h2>{{ t.isOutstanding ? 'Outstanding' : 'Settled' }}</h2>\n </ion-label>\n </ion-item>\n <ion-item>\n <ion-label class=\"ion-text-wrap\">\n <p>Effect on balance</p>\n <h2>\n @if (t.direction === 'lend') {\n {{ t.counterpartyTitle }} owes you {{ formatAmount(t.amount) }}\n } @else {\n You owe {{ t.counterpartyTitle }} {{ formatAmount(t.amount) }}\n }\n </h2>\n </ion-label>\n </ion-item>\n @if (t.counterpartySpaceID) {\n <ion-item>\n <ion-label class=\"ion-text-wrap\">\n <p>Cross-space</p>\n <h2>Counterparty side is in space {{ t.counterpartySpaceID }}</h2>\n <ion-note color=\"medium\">\n Your side: {{ t.creatorSpaceID }}\n </ion-note>\n </ion-label>\n </ion-item>\n }\n </ion-list>\n </ion-card>\n\n @if (t.isOutstanding) {\n <div class=\"ion-padding\">\n <ion-button expand=\"block\" color=\"success\" (click)=\"settleUp()\">\n <ion-icon name=\"checkmark-done-outline\" slot=\"start\" />\n Settle up\n </ion-button>\n </div>\n }\n }\n</ion-content>\n", dependencies: [{ kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonBackButton, selector: "ion-back-button" }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"], outputs: ["ionScrollStart", "ionScroll", "ionScrollEnd"] }, { 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: IonList, selector: "ion-list", inputs: ["inset", "lines", "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"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "component", type: IonBadge, selector: "ion-badge", inputs: ["color", "mode"] }, { 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"], outputs: ["ionFocus", "ionBlur"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "ngmodule", type: SpaceServiceModule }, { kind: "pipe", type: DatePipe, name: "date" }] });
74
+ }
75
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TransferDetailsPageComponent, decorators: [{
76
+ type: Component,
77
+ args: [{ selector: 'sneat-debtus-transfer-details-page', imports: [
78
+ IonHeader,
79
+ IonToolbar,
80
+ IonButtons,
81
+ IonBackButton,
82
+ IonTitle,
83
+ IonContent,
84
+ IonCard,
85
+ IonCardHeader,
86
+ IonCardTitle,
87
+ IonCardContent,
88
+ IonList,
89
+ IonItem,
90
+ IonLabel,
91
+ IonNote,
92
+ IonBadge,
93
+ IonButton,
94
+ IonIcon,
95
+ IonSpinner,
96
+ DatePipe,
97
+ SpaceServiceModule,
98
+ ], providers: [
99
+ { provide: ClassName, useValue: 'TransferDetailsPageComponent' },
100
+ SpaceComponentBaseParams,
101
+ ], template: "<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>Transfer</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"cardy\">\n @if ($loading()) {\n <div class=\"ion-padding ion-text-center\">\n <ion-spinner name=\"dots\" />\n </div>\n } @else if ($error()) {\n <div class=\"ion-padding\">\n <ion-note color=\"danger\">{{ $error() }}</ion-note>\n </div>\n } @else if ($transfer(); as t) {\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n {{ t.direction === 'lend' ? 'You lent' : 'You borrowed' }}\n @if (t.isReturn) { \u00B7 return }\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-badge\n [color]=\"t.direction === 'lend' ? 'success' : 'warning'\"\n style=\"font-size: 1.2rem\"\n >\n {{ formatAmount(t.amount) }}\n </ion-badge>\n </ion-card-content>\n </ion-card>\n\n <ion-card>\n <ion-list lines=\"full\">\n <ion-item button (click)=\"openContact()\">\n <ion-label>\n <p>Counterparty</p>\n <h2>{{ t.counterpartyTitle }}</h2>\n </ion-label>\n </ion-item>\n <ion-item>\n <ion-label>\n <p>Date</p>\n <h2>{{ t.created | date: 'medium' }}</h2>\n </ion-label>\n </ion-item>\n @if (t.dueOn) {\n <ion-item>\n <ion-label>\n <p>Due</p>\n <h2>{{ t.dueOn | date: 'mediumDate' }}</h2>\n </ion-label>\n </ion-item>\n }\n @if (t.note) {\n <ion-item>\n <ion-label class=\"ion-text-wrap\">\n <p>Note</p>\n <h2>{{ t.note }}</h2>\n </ion-label>\n </ion-item>\n }\n <ion-item>\n <ion-label>\n <p>Status</p>\n <h2>{{ t.isOutstanding ? 'Outstanding' : 'Settled' }}</h2>\n </ion-label>\n </ion-item>\n <ion-item>\n <ion-label class=\"ion-text-wrap\">\n <p>Effect on balance</p>\n <h2>\n @if (t.direction === 'lend') {\n {{ t.counterpartyTitle }} owes you {{ formatAmount(t.amount) }}\n } @else {\n You owe {{ t.counterpartyTitle }} {{ formatAmount(t.amount) }}\n }\n </h2>\n </ion-label>\n </ion-item>\n @if (t.counterpartySpaceID) {\n <ion-item>\n <ion-label class=\"ion-text-wrap\">\n <p>Cross-space</p>\n <h2>Counterparty side is in space {{ t.counterpartySpaceID }}</h2>\n <ion-note color=\"medium\">\n Your side: {{ t.creatorSpaceID }}\n </ion-note>\n </ion-label>\n </ion-item>\n }\n </ion-list>\n </ion-card>\n\n @if (t.isOutstanding) {\n <div class=\"ion-padding\">\n <ion-button expand=\"block\" color=\"success\" (click)=\"settleUp()\">\n <ion-icon name=\"checkmark-done-outline\" slot=\"start\" />\n Settle up\n </ion-button>\n </div>\n }\n }\n</ion-content>\n" }]
102
+ }], ctorParameters: () => [] });
103
+
104
+ export { TransferDetailsPageComponent };
105
+ //# sourceMappingURL=sneat-extension-debtus-ui-transfer-details-page.component-B6iQS1YJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sneat-extension-debtus-ui-transfer-details-page.component-B6iQS1YJ.mjs","sources":["../../../../../../libs/extensions/debtus/ui/src/lib/pages/transfer-details/transfer-details-page.component.ts","../../../../../../libs/extensions/debtus/ui/src/lib/pages/transfer-details/transfer-details-page.component.html"],"sourcesContent":["import { DatePipe } from '@angular/common';\nimport { Component, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Router } from '@angular/router';\nimport {\n IonBackButton,\n IonBadge,\n IonButton,\n IonButtons,\n IonCard,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonContent,\n IonHeader,\n IonIcon,\n IonItem,\n IonLabel,\n IonList,\n IonNote,\n IonSpinner,\n IonTitle,\n IonToolbar,\n} from '@ionic/angular';\nimport {\n DEBTUS_SERVICE,\n IDebtusTransfer,\n formatAmount,\n} from '@sneat/extension-debtus-contract';\nimport {\n SpaceComponentBaseParams,\n SpacePageBaseComponent,\n} from '@sneat/space-components';\nimport { SpaceServiceModule } from '@sneat/space-services';\nimport { ClassName } from '@sneat/ui';\nimport { combineLatest, of, switchMap } from 'rxjs';\n\n// Transfer detail / receipt — amount, parties, date, note, and its effect on\n// the balance. Mirrors the bot's receipt. Offers a settle-up entry.\n@Component({\n selector: 'sneat-debtus-transfer-details-page',\n templateUrl: './transfer-details-page.component.html',\n imports: [\n IonHeader,\n IonToolbar,\n IonButtons,\n IonBackButton,\n IonTitle,\n IonContent,\n IonCard,\n IonCardHeader,\n IonCardTitle,\n IonCardContent,\n IonList,\n IonItem,\n IonLabel,\n IonNote,\n IonBadge,\n IonButton,\n IonIcon,\n IonSpinner,\n DatePipe,\n SpaceServiceModule,\n ],\n providers: [\n { provide: ClassName, useValue: 'TransferDetailsPageComponent' },\n SpaceComponentBaseParams,\n ],\n})\nexport class TransferDetailsPageComponent extends SpacePageBaseComponent {\n private readonly debtusService = inject(DEBTUS_SERVICE);\n private readonly router = inject(Router);\n\n protected readonly $loading = signal(true);\n protected readonly $error = signal<string | undefined>(undefined);\n protected readonly $transfer = signal<IDebtusTransfer | undefined>(undefined);\n\n protected readonly formatAmount = formatAmount;\n\n constructor() {\n super();\n this.$defaultBackUrlSpacePath.set('debts');\n // A transfer just created by the new-transfer/settle-up pages is handed\n // over via router `state` (it survives reloads through history.state).\n // Prefer it to avoid an extra read immediately after creation. A cold load\n // retrieves the same persisted transfer through the Debtus API.\n const stateTransfer = (\n this.router.getCurrentNavigation()?.extras?.state ?? history.state\n )?.['transfer'] as IDebtusTransfer | undefined;\n combineLatest([this.spaceIDChanged$, this.route.paramMap])\n .pipe(\n switchMap(([spaceID, params]) => {\n const transferID = params.get('transferID') ?? '';\n this.$loading.set(true);\n this.$error.set(undefined);\n if (stateTransfer?.id === transferID) {\n return of(stateTransfer);\n }\n return this.debtusService.getTransfer(spaceID ?? '', transferID);\n }),\n takeUntilDestroyed(),\n )\n .subscribe({\n next: (transfer) => {\n this.$transfer.set(transfer);\n this.$loading.set(false);\n },\n error: (err) => {\n this.$error.set('Failed to load transfer');\n this.$loading.set(false);\n this.errorLogger.logError(err, 'Failed to load debtus transfer');\n },\n });\n }\n\n protected settleUp(): void {\n const t = this.$transfer();\n if (!t) {\n return;\n }\n this.spaceNav.navigateForwardToSpacePage(\n this.space,\n `settle-up?contactID=${t.counterpartyContactID}`,\n );\n }\n\n protected openContact(): void {\n const t = this.$transfer();\n if (!t?.counterpartyContactID) {\n return;\n }\n this.spaceNav.navigateForwardToSpacePage(\n this.space,\n `debtus-contact/${t.counterpartyContactID}`,\n );\n }\n}\n","<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>Transfer</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"cardy\">\n @if ($loading()) {\n <div class=\"ion-padding ion-text-center\">\n <ion-spinner name=\"dots\" />\n </div>\n } @else if ($error()) {\n <div class=\"ion-padding\">\n <ion-note color=\"danger\">{{ $error() }}</ion-note>\n </div>\n } @else if ($transfer(); as t) {\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n {{ t.direction === 'lend' ? 'You lent' : 'You borrowed' }}\n @if (t.isReturn) { · return }\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-badge\n [color]=\"t.direction === 'lend' ? 'success' : 'warning'\"\n style=\"font-size: 1.2rem\"\n >\n {{ formatAmount(t.amount) }}\n </ion-badge>\n </ion-card-content>\n </ion-card>\n\n <ion-card>\n <ion-list lines=\"full\">\n <ion-item button (click)=\"openContact()\">\n <ion-label>\n <p>Counterparty</p>\n <h2>{{ t.counterpartyTitle }}</h2>\n </ion-label>\n </ion-item>\n <ion-item>\n <ion-label>\n <p>Date</p>\n <h2>{{ t.created | date: 'medium' }}</h2>\n </ion-label>\n </ion-item>\n @if (t.dueOn) {\n <ion-item>\n <ion-label>\n <p>Due</p>\n <h2>{{ t.dueOn | date: 'mediumDate' }}</h2>\n </ion-label>\n </ion-item>\n }\n @if (t.note) {\n <ion-item>\n <ion-label class=\"ion-text-wrap\">\n <p>Note</p>\n <h2>{{ t.note }}</h2>\n </ion-label>\n </ion-item>\n }\n <ion-item>\n <ion-label>\n <p>Status</p>\n <h2>{{ t.isOutstanding ? 'Outstanding' : 'Settled' }}</h2>\n </ion-label>\n </ion-item>\n <ion-item>\n <ion-label class=\"ion-text-wrap\">\n <p>Effect on balance</p>\n <h2>\n @if (t.direction === 'lend') {\n {{ t.counterpartyTitle }} owes you {{ formatAmount(t.amount) }}\n } @else {\n You owe {{ t.counterpartyTitle }} {{ formatAmount(t.amount) }}\n }\n </h2>\n </ion-label>\n </ion-item>\n @if (t.counterpartySpaceID) {\n <ion-item>\n <ion-label class=\"ion-text-wrap\">\n <p>Cross-space</p>\n <h2>Counterparty side is in space {{ t.counterpartySpaceID }}</h2>\n <ion-note color=\"medium\">\n Your side: {{ t.creatorSpaceID }}\n </ion-note>\n </ion-label>\n </ion-item>\n }\n </ion-list>\n </ion-card>\n\n @if (t.isOutstanding) {\n <div class=\"ion-padding\">\n <ion-button expand=\"block\" color=\"success\" (click)=\"settleUp()\">\n <ion-icon name=\"checkmark-done-outline\" slot=\"start\" />\n Settle up\n </ion-button>\n </div>\n }\n }\n</ion-content>\n"],"names":[],"mappings":"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"}
@@ -5,35 +5,7 @@ import { FormControl, Validators, FormGroup, ReactiveFormsModule } from '@angula
5
5
  import { IonCard, IonCardHeader, IonCardTitle, IonItem, IonLabel, IonSelect, IonSelectOption, IonInput, IonButton } from '@ionic/angular';
6
6
  import { ErrorLogger } from '@sneat/core';
7
7
  import { DEBTUS_SERVICE } from '@sneat/extension-debtus-contract';
8
-
9
- // Persistent "demo data" banner for fixture-backed READ surfaces.
10
- //
11
- // Balances, contacts and transfer history are still served from demo fixtures
12
- // (no wired read endpoints yet — see DebtusService), while creates/settles
13
- // WRITE real records. Without this banner users see fiction presented as
14
- // their data, and the transfers they record never appear in any list. Show
15
- // this on every page that renders fixture-backed reads; remove per page once
16
- // its live read endpoint is wired.
17
- class DemoDataBannerComponent {
18
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: DemoDataBannerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
19
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.3", type: DemoDataBannerComponent, isStandalone: true, selector: "sneat-debtus-demo-data-banner", ngImport: i0, template: `
20
- <div class="demo-banner" role="note">
21
- ⚠️ <b>Demo data</b> — balances, contacts &amp; history shown here are
22
- sample fixtures, not your records yet. Transfers you record are saved for
23
- real and will show up once live reads are wired.
24
- </div>
25
- `, isInline: true, styles: [".demo-banner{margin:8px 12px 0;padding:8px 12px;border-radius:8px;font-size:.85rem;background:var(--ion-color-warning-tint, #ffd534);color:var(--ion-color-warning-contrast, #000)}\n"] });
26
- }
27
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: DemoDataBannerComponent, decorators: [{
28
- type: Component,
29
- args: [{ selector: 'sneat-debtus-demo-data-banner', template: `
30
- <div class="demo-banner" role="note">
31
- ⚠️ <b>Demo data</b> — balances, contacts &amp; history shown here are
32
- sample fixtures, not your records yet. Transfers you record are saved for
33
- real and will show up once live reads are wired.
34
- </div>
35
- `, styles: [".demo-banner{margin:8px 12px 0;padding:8px 12px;border-radius:8px;font-size:.85rem;background:var(--ion-color-warning-tint, #ffd534);color:var(--ion-color-warning-contrast, #000)}\n"] }]
36
- }] });
8
+ import { sneatAuthGuard } from '@sneat/auth-core';
37
9
 
38
10
  class MemberDebtsSummaryComponent {
39
11
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: MemberDebtsSummaryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -113,35 +85,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
113
85
  // Full flow: debts (home/balances) -> debtus-contacts -> debtus-contact/:id
114
86
  // -> new-transfer / settle-up -> transfer/:id (receipt).
115
87
  const spacePagesRoutes = [
88
+ {
89
+ path: 'source-obligations',
90
+ data: { title: 'Bill settlement' },
91
+ canActivate: [sneatAuthGuard],
92
+ loadComponent: () => import('./sneat-extension-debtus-ui-source-obligations-page.component-6E9_pHCq.mjs').then((m) => m.SourceObligationsPageComponent),
93
+ },
116
94
  {
117
95
  path: 'debts',
118
96
  data: { title: 'Debts' },
119
- loadComponent: () => import('./sneat-extension-debtus-ui-debtus-home-page.component-BCNMpirX.mjs').then((m) => m.DebtusHomePageComponent),
97
+ loadComponent: () => import('./sneat-extension-debtus-ui-debtus-home-page.component-Dd5-oQdz.mjs').then((m) => m.DebtusHomePageComponent),
120
98
  },
121
99
  {
122
100
  path: 'debtus-contacts',
123
101
  data: { title: 'Contacts' },
124
- loadComponent: () => import('./sneat-extension-debtus-ui-debtus-contacts-page.component-DYtFeNsM.mjs').then((m) => m.DebtusContactsPageComponent),
102
+ loadComponent: () => import('./sneat-extension-debtus-ui-debtus-contacts-page.component-B2SicqpG.mjs').then((m) => m.DebtusContactsPageComponent),
125
103
  },
126
104
  {
127
105
  path: 'debtus-contact/:contactID',
128
106
  data: { title: 'Contact' },
129
- loadComponent: () => import('./sneat-extension-debtus-ui-debtus-contact-details-page.component-DIAVE0D6.mjs').then((m) => m.DebtusContactDetailsPageComponent),
107
+ loadComponent: () => import('./sneat-extension-debtus-ui-debtus-contact-details-page.component-ygSD0Q-C.mjs').then((m) => m.DebtusContactDetailsPageComponent),
130
108
  },
131
109
  {
132
110
  path: 'new-transfer',
133
111
  data: { title: 'New transfer' },
134
- loadComponent: () => import('./sneat-extension-debtus-ui-new-transfer-page.component-CT-6X_0e.mjs').then((m) => m.NewTransferPageComponent),
112
+ loadComponent: () => import('./sneat-extension-debtus-ui-new-transfer-page.component-YaGgYqKB.mjs').then((m) => m.NewTransferPageComponent),
135
113
  },
136
114
  {
137
115
  path: 'settle-up',
138
116
  data: { title: 'Settle up' },
139
- loadComponent: () => import('./sneat-extension-debtus-ui-settle-up-page.component-CUoNSuAE.mjs').then((m) => m.SettleUpPageComponent),
117
+ loadComponent: () => import('./sneat-extension-debtus-ui-settle-up-page.component-48l8YFn4.mjs').then((m) => m.SettleUpPageComponent),
140
118
  },
141
119
  {
142
120
  path: 'transfer/:transferID',
143
121
  data: { title: 'Transfer' },
144
- loadComponent: () => import('./sneat-extension-debtus-ui-transfer-details-page.component-uo5lP557.mjs').then((m) => m.TransferDetailsPageComponent),
122
+ loadComponent: () => import('./sneat-extension-debtus-ui-transfer-details-page.component-B6iQS1YJ.mjs').then((m) => m.TransferDetailsPageComponent),
145
123
  },
146
124
  ];
147
125
 
@@ -149,5 +127,5 @@ const spacePagesRoutes = [
149
127
  * Generated bundle index. Do not edit.
150
128
  */
151
129
 
152
- export { DemoDataBannerComponent, MemberDebtsSummaryComponent, NewDebtFormComponent, spacePagesRoutes };
130
+ export { MemberDebtsSummaryComponent, NewDebtFormComponent, spacePagesRoutes };
153
131
  //# sourceMappingURL=sneat-extension-debtus-ui.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sneat-extension-debtus-ui.mjs","sources":["../../../../../../libs/extensions/debtus/ui/src/lib/components/demo-data-banner/demo-data-banner.component.ts","../../../../../../libs/extensions/debtus/ui/src/lib/components/member-debts-summary/member-debts-summary.component.ts","../../../../../../libs/extensions/debtus/ui/src/lib/components/member-debts-summary/member-debts-summary.component.html","../../../../../../libs/extensions/debtus/ui/src/lib/components/new-debt-form/new-debt-form.component.ts","../../../../../../libs/extensions/debtus/ui/src/lib/components/new-debt-form/new-debt-form.component.html","../../../../../../libs/extensions/debtus/ui/src/lib/pages/space-pages-routing.ts","../../../../../../libs/extensions/debtus/ui/src/sneat-extension-debtus-ui.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n// Persistent \"demo data\" banner for fixture-backed READ surfaces.\n//\n// Balances, contacts and transfer history are still served from demo fixtures\n// (no wired read endpoints yet — see DebtusService), while creates/settles\n// WRITE real records. Without this banner users see fiction presented as\n// their data, and the transfers they record never appear in any list. Show\n// this on every page that renders fixture-backed reads; remove per page once\n// its live read endpoint is wired.\n@Component({\n selector: 'sneat-debtus-demo-data-banner',\n template: `\n <div class=\"demo-banner\" role=\"note\">\n ⚠️ <b>Demo data</b> — balances, contacts &amp; history shown here are\n sample fixtures, not your records yet. Transfers you record are saved for\n real and will show up once live reads are wired.\n </div>\n `,\n styles: [\n `\n .demo-banner {\n margin: 8px 12px 0;\n padding: 8px 12px;\n border-radius: 8px;\n font-size: 0.85rem;\n background: var(--ion-color-warning-tint, #ffd534);\n color: var(--ion-color-warning-contrast, #000);\n }\n `,\n ],\n})\nexport class DemoDataBannerComponent {}\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'sneat-debtus-member-debts-summary',\n templateUrl: './member-debts-summary.component.html',\n})\nexport class MemberDebtsSummaryComponent {}\n","<h2>Debts</h2>\n","import { Component, inject, input } from '@angular/core';\nimport {\n FormControl,\n FormGroup,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport {\n IonButton,\n IonCard,\n IonCardHeader,\n IonCardTitle,\n IonInput,\n IonItem,\n IonLabel,\n IonSelect,\n IonSelectOption,\n} from '@ionic/angular';\nimport { IContactContext } from '@sneat/extension-contactus-contract';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport {\n CurrencyCode,\n DEBTUS_SERVICE,\n ICreateDebtRecordRequest,\n} from '@sneat/extension-debtus-contract';\nimport { ISpaceContext } from '@sneat/space-models';\n\n@Component({\n selector: 'sneat-debtus-new-debt-form',\n templateUrl: './new-debt-form.component.html',\n imports: [\n ReactiveFormsModule,\n IonCard,\n IonCardHeader,\n IonCardTitle,\n IonItem,\n IonLabel,\n IonSelect,\n IonSelectOption,\n IonInput,\n IonButton,\n // ContactInputComponent,\n // forwardRef(() => ContactInputComponent),\n ],\n})\nexport class NewDebtFormComponent {\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n private readonly debtusService = inject(DEBTUS_SERVICE);\n\n public readonly space = input.required<ISpaceContext | undefined>();\n public readonly contact = input.required<IContactContext | undefined>();\n\n protected currency = new FormControl<CurrencyCode>('EUR');\n protected amount = new FormControl<number | undefined>(\n undefined,\n Validators.required,\n );\n\n protected newDebtForm = new FormGroup({\n currency: this.currency,\n amount: this.amount,\n });\n\n protected readonly currencies = ['EUR', 'USD'];\n\n protected submit() {\n const spaceID = this.space()?.id;\n if (!spaceID) {\n throw new Error('spaceID is not set');\n }\n const contactID = this.contact()?.id;\n if (!contactID) {\n throw new Error('contactID is not set');\n }\n if (!this.amount.value) {\n throw new Error('amount is not set');\n }\n if (!this.currency.value) {\n throw new Error('currency is not set');\n }\n const request: ICreateDebtRecordRequest = {\n spaceID,\n contactID,\n amount: this.amount.value,\n currency: this.currency.value,\n };\n this.debtusService.createDebtRecord(request).subscribe({\n next: () => {\n // Debt record created successfully\n },\n error: (err) => {\n console.error('Failed to create debt record:', err);\n },\n });\n }\n}\n","<ion-card>\n <ion-card-header>\n <ion-card-title>New debt</ion-card-title>\n </ion-card-header>\n <ion-item>\n <ion-label>Currency</ion-label>\n <ion-select [formControl]=\"currency\" placeholder=\"Select Currency\">\n @for (currency of currencies; track currency) {\n <ion-select-option [value]=\"currency\">{{ currency }}</ion-select-option>\n }\n </ion-select>\n </ion-item>\n <ion-item>\n <ion-label>Amount</ion-label>\n <ion-input type=\"number\" [formControl]=\"amount\" />\n </ion-item>\n\n <!--\t<sneat-contact-input [team]=\"team\" />-->\n\n <ion-button (click)=\"submit()\">Add debt</ion-button>\n</ion-card>\n","import { Route } from '@angular/router';\n\n// Debtus space-scoped routes, mounted under space/:spaceType/:spaceID.\n// Full flow: debts (home/balances) -> debtus-contacts -> debtus-contact/:id\n// -> new-transfer / settle-up -> transfer/:id (receipt).\nexport const spacePagesRoutes: Route[] = [\n {\n path: 'debts',\n data: { title: 'Debts' },\n loadComponent: () =>\n import('./debtus-home/debtus-home-page.component').then(\n (m) => m.DebtusHomePageComponent,\n ),\n },\n {\n path: 'debtus-contacts',\n data: { title: 'Contacts' },\n loadComponent: () =>\n import('./debtus-contacts/debtus-contacts-page.component').then(\n (m) => m.DebtusContactsPageComponent,\n ),\n },\n {\n path: 'debtus-contact/:contactID',\n data: { title: 'Contact' },\n loadComponent: () =>\n import(\n './debtus-contact-details/debtus-contact-details-page.component'\n ).then((m) => m.DebtusContactDetailsPageComponent),\n },\n {\n path: 'new-transfer',\n data: { title: 'New transfer' },\n loadComponent: () =>\n import('./new-transfer/new-transfer-page.component').then(\n (m) => m.NewTransferPageComponent,\n ),\n },\n {\n path: 'settle-up',\n data: { title: 'Settle up' },\n loadComponent: () =>\n import('./settle-up/settle-up-page.component').then(\n (m) => m.SettleUpPageComponent,\n ),\n },\n {\n path: 'transfer/:transferID',\n data: { title: 'Transfer' },\n loadComponent: () =>\n import('./transfer-details/transfer-details-page.component').then(\n (m) => m.TransferDetailsPageComponent,\n ),\n },\n];\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sneat-extension-debtus-ui.mjs","sources":["../../../../../../libs/extensions/debtus/ui/src/lib/components/member-debts-summary/member-debts-summary.component.ts","../../../../../../libs/extensions/debtus/ui/src/lib/components/member-debts-summary/member-debts-summary.component.html","../../../../../../libs/extensions/debtus/ui/src/lib/components/new-debt-form/new-debt-form.component.ts","../../../../../../libs/extensions/debtus/ui/src/lib/components/new-debt-form/new-debt-form.component.html","../../../../../../libs/extensions/debtus/ui/src/lib/pages/space-pages-routing.ts","../../../../../../libs/extensions/debtus/ui/src/sneat-extension-debtus-ui.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 'sneat-debtus-member-debts-summary',\n templateUrl: './member-debts-summary.component.html',\n})\nexport class MemberDebtsSummaryComponent {}\n","<h2>Debts</h2>\n","import { Component, inject, input } from '@angular/core';\nimport {\n FormControl,\n FormGroup,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport {\n IonButton,\n IonCard,\n IonCardHeader,\n IonCardTitle,\n IonInput,\n IonItem,\n IonLabel,\n IonSelect,\n IonSelectOption,\n} from '@ionic/angular';\nimport { IContactContext } from '@sneat/extension-contactus-contract';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport {\n CurrencyCode,\n DEBTUS_SERVICE,\n ICreateDebtRecordRequest,\n} from '@sneat/extension-debtus-contract';\nimport { ISpaceContext } from '@sneat/space-models';\n\n@Component({\n selector: 'sneat-debtus-new-debt-form',\n templateUrl: './new-debt-form.component.html',\n imports: [\n ReactiveFormsModule,\n IonCard,\n IonCardHeader,\n IonCardTitle,\n IonItem,\n IonLabel,\n IonSelect,\n IonSelectOption,\n IonInput,\n IonButton,\n // ContactInputComponent,\n // forwardRef(() => ContactInputComponent),\n ],\n})\nexport class NewDebtFormComponent {\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n private readonly debtusService = inject(DEBTUS_SERVICE);\n\n public readonly space = input.required<ISpaceContext | undefined>();\n public readonly contact = input.required<IContactContext | undefined>();\n\n protected currency = new FormControl<CurrencyCode>('EUR');\n protected amount = new FormControl<number | undefined>(\n undefined,\n Validators.required,\n );\n\n protected newDebtForm = new FormGroup({\n currency: this.currency,\n amount: this.amount,\n });\n\n protected readonly currencies = ['EUR', 'USD'];\n\n protected submit() {\n const spaceID = this.space()?.id;\n if (!spaceID) {\n throw new Error('spaceID is not set');\n }\n const contactID = this.contact()?.id;\n if (!contactID) {\n throw new Error('contactID is not set');\n }\n if (!this.amount.value) {\n throw new Error('amount is not set');\n }\n if (!this.currency.value) {\n throw new Error('currency is not set');\n }\n const request: ICreateDebtRecordRequest = {\n spaceID,\n contactID,\n amount: this.amount.value,\n currency: this.currency.value,\n };\n this.debtusService.createDebtRecord(request).subscribe({\n next: () => {\n // Debt record created successfully\n },\n error: (err) => {\n console.error('Failed to create debt record:', err);\n },\n });\n }\n}\n","<ion-card>\n <ion-card-header>\n <ion-card-title>New debt</ion-card-title>\n </ion-card-header>\n <ion-item>\n <ion-label>Currency</ion-label>\n <ion-select [formControl]=\"currency\" placeholder=\"Select Currency\">\n @for (currency of currencies; track currency) {\n <ion-select-option [value]=\"currency\">{{ currency }}</ion-select-option>\n }\n </ion-select>\n </ion-item>\n <ion-item>\n <ion-label>Amount</ion-label>\n <ion-input type=\"number\" [formControl]=\"amount\" />\n </ion-item>\n\n <!--\t<sneat-contact-input [team]=\"team\" />-->\n\n <ion-button (click)=\"submit()\">Add debt</ion-button>\n</ion-card>\n","import { Route } from '@angular/router';\nimport { sneatAuthGuard } from '@sneat/auth-core';\n\n// Debtus space-scoped routes, mounted under space/:spaceType/:spaceID.\n// Full flow: debts (home/balances) -> debtus-contacts -> debtus-contact/:id\n// -> new-transfer / settle-up -> transfer/:id (receipt).\nexport const spacePagesRoutes: Route[] = [\n {\n path: 'source-obligations',\n data: { title: 'Bill settlement' },\n canActivate: [sneatAuthGuard],\n loadComponent: () =>\n import('./source-obligations/source-obligations-page.component').then(\n (m) => m.SourceObligationsPageComponent,\n ),\n },\n {\n path: 'debts',\n data: { title: 'Debts' },\n loadComponent: () =>\n import('./debtus-home/debtus-home-page.component').then(\n (m) => m.DebtusHomePageComponent,\n ),\n },\n {\n path: 'debtus-contacts',\n data: { title: 'Contacts' },\n loadComponent: () =>\n import('./debtus-contacts/debtus-contacts-page.component').then(\n (m) => m.DebtusContactsPageComponent,\n ),\n },\n {\n path: 'debtus-contact/:contactID',\n data: { title: 'Contact' },\n loadComponent: () =>\n import(\n './debtus-contact-details/debtus-contact-details-page.component'\n ).then((m) => m.DebtusContactDetailsPageComponent),\n },\n {\n path: 'new-transfer',\n data: { title: 'New transfer' },\n loadComponent: () =>\n import('./new-transfer/new-transfer-page.component').then(\n (m) => m.NewTransferPageComponent,\n ),\n },\n {\n path: 'settle-up',\n data: { title: 'Settle up' },\n loadComponent: () =>\n import('./settle-up/settle-up-page.component').then(\n (m) => m.SettleUpPageComponent,\n ),\n },\n {\n path: 'transfer/:transferID',\n data: { title: 'Transfer' },\n loadComponent: () =>\n import('./transfer-details/transfer-details-page.component').then(\n (m) => m.TransferDetailsPageComponent,\n ),\n },\n];\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sneat/extension-debtus-ui",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=22.0.0 <23.0.0",
6
6
  "@angular/core": ">=22.0.0 <23.0.0",
@@ -8,14 +8,16 @@
8
8
  "@angular/router": ">=22.0.0 <23.0.0",
9
9
  "@ionic/angular": ">=9.0.0 <10.0.0",
10
10
  "rxjs": "^7.0.0",
11
- "@sneat/extension-contactus-contract": "0.12.2",
11
+ "@sneat/extension-contactus-contract": "^0.12.2",
12
12
  "@sneat/core": "^0.27.0",
13
13
  "@sneat/space-components": "^0.27.0",
14
14
  "@sneat/space-models": "^0.27.0",
15
15
  "@sneat/space-services": "^0.27.0",
16
16
  "@sneat/ui": "^0.27.0",
17
17
  "@sneat/extension-debtus-contract": "^0.2.0",
18
- "@sneat/extension-contactus-ui": "0.14.0"
18
+ "@sneat/extension-contactus-ui": "^0.14.0",
19
+ "@sneat/api": "^0.27.0",
20
+ "@sneat/auth-core": "^0.27.0"
19
21
  },
20
22
  "dependencies": {
21
23
  "tslib": "^2.3.0"
@@ -5,11 +5,6 @@ import { CurrencyCode } from '@sneat/extension-debtus-contract';
5
5
  import { ISpaceContext } from '@sneat/space-models';
6
6
  import { Route } from '@angular/router';
7
7
 
8
- declare class DemoDataBannerComponent {
9
- static ɵfac: i0.ɵɵFactoryDeclaration<DemoDataBannerComponent, never>;
10
- static ɵcmp: i0.ɵɵComponentDeclaration<DemoDataBannerComponent, "sneat-debtus-demo-data-banner", never, {}, {}, never, never, true, never>;
11
- }
12
-
13
8
  declare class MemberDebtsSummaryComponent {
14
9
  static ɵfac: i0.ɵɵFactoryDeclaration<MemberDebtsSummaryComponent, never>;
15
10
  static ɵcmp: i0.ɵɵComponentDeclaration<MemberDebtsSummaryComponent, "sneat-debtus-member-debts-summary", never, {}, {}, never, never, true, never>;
@@ -34,4 +29,4 @@ declare class NewDebtFormComponent {
34
29
 
35
30
  declare const spacePagesRoutes: Route[];
36
31
 
37
- export { DemoDataBannerComponent, MemberDebtsSummaryComponent, NewDebtFormComponent, spacePagesRoutes };
32
+ export { MemberDebtsSummaryComponent, NewDebtFormComponent, spacePagesRoutes };
@@ -1,106 +0,0 @@
1
- import { DatePipe } from '@angular/common';
2
- import * as i0 from '@angular/core';
3
- import { inject, signal, Component } from '@angular/core';
4
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
- import { ToastController, IonHeader, IonToolbar, IonButtons, IonBackButton, IonTitle, IonContent, IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonList, IonItem, IonLabel, IonNote, IonBadge, IonButton, IonIcon, IonSpinner } from '@ionic/angular';
6
- import { DemoDataBannerComponent } from './sneat-extension-debtus-ui.mjs';
7
- import { DEBTUS_SERVICE, formatAmount, formatSignedBalance } from '@sneat/extension-debtus-contract';
8
- import { SpacePageBaseComponent, SpaceComponentBaseParams } from '@sneat/space-components';
9
- import { combineLatest, switchMap } from 'rxjs';
10
-
11
- // Contact detail — balance with one counterparty plus their transfer history.
12
- // Actions mirror the bot: record a lend/borrow, remind, and settle up.
13
- class DebtusContactDetailsPageComponent extends SpacePageBaseComponent {
14
- debtusService = inject(DEBTUS_SERVICE);
15
- toastController = inject(ToastController);
16
- $loading = signal(true, /* @ts-ignore */
17
- ...(ngDevMode ? [{ debugName: "$loading" }] : /* istanbul ignore next */ []));
18
- $error = signal(undefined, /* @ts-ignore */
19
- ...(ngDevMode ? [{ debugName: "$error" }] : /* istanbul ignore next */ []));
20
- $contact = signal(undefined, /* @ts-ignore */
21
- ...(ngDevMode ? [{ debugName: "$contact" }] : /* istanbul ignore next */ []));
22
- $transfers = signal([], /* @ts-ignore */
23
- ...(ngDevMode ? [{ debugName: "$transfers" }] : /* istanbul ignore next */ []));
24
- contactID = '';
25
- formatAmount = formatAmount;
26
- formatSignedBalance = formatSignedBalance;
27
- constructor() {
28
- super();
29
- this.$defaultBackUrlSpacePath.set('debtus-contacts');
30
- combineLatest([this.spaceIDChanged$, this.route.paramMap])
31
- .pipe(switchMap(([spaceID, params]) => {
32
- this.contactID = params.get('contactID') ?? '';
33
- this.$loading.set(true);
34
- this.$error.set(undefined);
35
- return combineLatest([
36
- this.debtusService.getContactBalance(spaceID ?? '', this.contactID),
37
- this.debtusService.getTransfers(spaceID ?? '', this.contactID),
38
- ]);
39
- }), takeUntilDestroyed())
40
- .subscribe({
41
- next: ([contact, transfers]) => {
42
- this.$contact.set(contact);
43
- this.$transfers.set(transfers);
44
- this.$loading.set(false);
45
- },
46
- error: (err) => {
47
- this.$error.set('Failed to load contact');
48
- this.$loading.set(false);
49
- this.errorLogger.logError(err, 'Failed to load debtus contact');
50
- },
51
- });
52
- }
53
- recordLend() {
54
- this.spaceNav.navigateForwardToSpacePage(this.space, `new-transfer?direction=lend&contactID=${this.contactID}`);
55
- }
56
- recordBorrow() {
57
- this.spaceNav.navigateForwardToSpacePage(this.space, `new-transfer?direction=borrow&contactID=${this.contactID}`);
58
- }
59
- settleUp() {
60
- this.spaceNav.navigateForwardToSpacePage(this.space, `settle-up?contactID=${this.contactID}`);
61
- }
62
- async remind() {
63
- // Fable: prototype demo data — no wired reminder-send HTTP endpoint yet.
64
- // The bot schedules reminders via a background cron; here we just confirm
65
- // the intent. SWAP: call a POST reminder endpoint once available.
66
- const toast = await this.toastController.create({
67
- message: `Reminder queued for ${this.$contact()?.title ?? 'contact'} (demo).`,
68
- duration: 2500,
69
- color: 'medium',
70
- });
71
- await toast.present();
72
- }
73
- openTransfer(transferID) {
74
- this.spaceNav.navigateForwardToSpacePage(this.space, `transfer/${transferID}`);
75
- }
76
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: DebtusContactDetailsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
77
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: DebtusContactDetailsPageComponent, isStandalone: true, selector: "sneat-debtus-contact-details-page", providers: [SpaceComponentBaseParams], usesInheritance: true, ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>{{ $contact()?.title ?? 'Contact' }}</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"cardy\">\n <!-- Reads on this page are still demo fixtures (see DebtusService). -->\n <sneat-debtus-demo-data-banner />\n\n @if ($loading()) {\n <div class=\"ion-padding ion-text-center\">\n <ion-spinner name=\"dots\" />\n </div>\n } @else if ($error()) {\n <div class=\"ion-padding\">\n <ion-note color=\"danger\">{{ $error() }}</ion-note>\n </div>\n } @else {\n <ion-card>\n <ion-card-header>\n <ion-card-title>Balance</ion-card-title>\n </ion-card-header>\n <ion-card-content>\n {{ formatSignedBalance($contact()?.balance ?? {}) }}\n @if ($contact()?.counterpartySpaceID) {\n <p>\n <ion-note color=\"medium\">\n Cross-space loan \u2014 counterparty is in space\n {{ $contact()?.counterpartySpaceID }}.\n </ion-note>\n </p>\n }\n </ion-card-content>\n </ion-card>\n\n <ion-card>\n <ion-card-content>\n <ion-button expand=\"block\" (click)=\"recordLend()\">\n <ion-icon name=\"arrow-up-outline\" slot=\"start\" />\n Record what I lent\n </ion-button>\n <ion-button expand=\"block\" fill=\"outline\" (click)=\"recordBorrow()\">\n <ion-icon name=\"arrow-down-outline\" slot=\"start\" />\n Record what I borrowed\n </ion-button>\n <ion-button expand=\"block\" fill=\"clear\" (click)=\"remind()\">\n <ion-icon name=\"notifications-outline\" slot=\"start\" />\n Remind\n </ion-button>\n <ion-button\n expand=\"block\"\n color=\"success\"\n fill=\"outline\"\n (click)=\"settleUp()\"\n >\n <ion-icon name=\"checkmark-done-outline\" slot=\"start\" />\n Settle up\n </ion-button>\n </ion-card-content>\n </ion-card>\n\n <ion-card>\n <ion-card-header>\n <ion-card-title>History</ion-card-title>\n </ion-card-header>\n @if ($transfers().length) {\n <ion-list>\n @for (t of $transfers(); track t.id) {\n <ion-item button (click)=\"openTransfer(t.id)\">\n <ion-label>\n <h2>\n {{ t.direction === 'lend' ? 'You lent' : 'You borrowed' }}\n @if (t.isReturn) { (return) }\n </h2>\n <p>{{ t.note || (t.created | date: 'mediumDate') }}</p>\n </ion-label>\n <ion-badge\n slot=\"end\"\n [color]=\"t.direction === 'lend' ? 'success' : 'warning'\"\n >\n {{ formatAmount(t.amount) }}\n </ion-badge>\n </ion-item>\n }\n </ion-list>\n } @else {\n <ion-card-content>\n <ion-note>No transfers with this contact yet.</ion-note>\n </ion-card-content>\n }\n </ion-card>\n }\n</ion-content>\n", dependencies: [{ kind: "component", type: DemoDataBannerComponent, selector: "sneat-debtus-demo-data-banner" }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonBackButton, selector: "ion-back-button" }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"], outputs: ["ionScrollStart", "ionScroll", "ionScrollEnd"] }, { 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: IonList, selector: "ion-list", inputs: ["inset", "lines", "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"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "component", type: IonBadge, selector: "ion-badge", inputs: ["color", "mode"] }, { 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"], outputs: ["ionFocus", "ionBlur"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "pipe", type: DatePipe, name: "date" }] });
78
- }
79
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: DebtusContactDetailsPageComponent, decorators: [{
80
- type: Component,
81
- args: [{ selector: 'sneat-debtus-contact-details-page', imports: [
82
- DemoDataBannerComponent,
83
- IonHeader,
84
- IonToolbar,
85
- IonButtons,
86
- IonBackButton,
87
- IonTitle,
88
- IonContent,
89
- IonCard,
90
- IonCardHeader,
91
- IonCardTitle,
92
- IonCardContent,
93
- IonList,
94
- IonItem,
95
- IonLabel,
96
- IonNote,
97
- IonBadge,
98
- IonButton,
99
- IonIcon,
100
- IonSpinner,
101
- DatePipe,
102
- ], providers: [SpaceComponentBaseParams], template: "<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>{{ $contact()?.title ?? 'Contact' }}</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"cardy\">\n <!-- Reads on this page are still demo fixtures (see DebtusService). -->\n <sneat-debtus-demo-data-banner />\n\n @if ($loading()) {\n <div class=\"ion-padding ion-text-center\">\n <ion-spinner name=\"dots\" />\n </div>\n } @else if ($error()) {\n <div class=\"ion-padding\">\n <ion-note color=\"danger\">{{ $error() }}</ion-note>\n </div>\n } @else {\n <ion-card>\n <ion-card-header>\n <ion-card-title>Balance</ion-card-title>\n </ion-card-header>\n <ion-card-content>\n {{ formatSignedBalance($contact()?.balance ?? {}) }}\n @if ($contact()?.counterpartySpaceID) {\n <p>\n <ion-note color=\"medium\">\n Cross-space loan \u2014 counterparty is in space\n {{ $contact()?.counterpartySpaceID }}.\n </ion-note>\n </p>\n }\n </ion-card-content>\n </ion-card>\n\n <ion-card>\n <ion-card-content>\n <ion-button expand=\"block\" (click)=\"recordLend()\">\n <ion-icon name=\"arrow-up-outline\" slot=\"start\" />\n Record what I lent\n </ion-button>\n <ion-button expand=\"block\" fill=\"outline\" (click)=\"recordBorrow()\">\n <ion-icon name=\"arrow-down-outline\" slot=\"start\" />\n Record what I borrowed\n </ion-button>\n <ion-button expand=\"block\" fill=\"clear\" (click)=\"remind()\">\n <ion-icon name=\"notifications-outline\" slot=\"start\" />\n Remind\n </ion-button>\n <ion-button\n expand=\"block\"\n color=\"success\"\n fill=\"outline\"\n (click)=\"settleUp()\"\n >\n <ion-icon name=\"checkmark-done-outline\" slot=\"start\" />\n Settle up\n </ion-button>\n </ion-card-content>\n </ion-card>\n\n <ion-card>\n <ion-card-header>\n <ion-card-title>History</ion-card-title>\n </ion-card-header>\n @if ($transfers().length) {\n <ion-list>\n @for (t of $transfers(); track t.id) {\n <ion-item button (click)=\"openTransfer(t.id)\">\n <ion-label>\n <h2>\n {{ t.direction === 'lend' ? 'You lent' : 'You borrowed' }}\n @if (t.isReturn) { (return) }\n </h2>\n <p>{{ t.note || (t.created | date: 'mediumDate') }}</p>\n </ion-label>\n <ion-badge\n slot=\"end\"\n [color]=\"t.direction === 'lend' ? 'success' : 'warning'\"\n >\n {{ formatAmount(t.amount) }}\n </ion-badge>\n </ion-item>\n }\n </ion-list>\n } @else {\n <ion-card-content>\n <ion-note>No transfers with this contact yet.</ion-note>\n </ion-card-content>\n }\n </ion-card>\n }\n</ion-content>\n" }]
103
- }], ctorParameters: () => [] });
104
-
105
- export { DebtusContactDetailsPageComponent };
106
- //# sourceMappingURL=sneat-extension-debtus-ui-debtus-contact-details-page.component-DIAVE0D6.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sneat-extension-debtus-ui-debtus-contact-details-page.component-DIAVE0D6.mjs","sources":["../../../../../../libs/extensions/debtus/ui/src/lib/pages/debtus-contact-details/debtus-contact-details-page.component.ts","../../../../../../libs/extensions/debtus/ui/src/lib/pages/debtus-contact-details/debtus-contact-details-page.component.html"],"sourcesContent":["import { DatePipe } from '@angular/common';\nimport { Component, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport {\n IonBackButton,\n IonBadge,\n IonButton,\n IonButtons,\n IonCard,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonContent,\n IonHeader,\n IonIcon,\n IonItem,\n IonLabel,\n IonList,\n IonNote,\n IonSpinner,\n IonTitle,\n IonToolbar,\n ToastController,\n} from '@ionic/angular';\nimport { DemoDataBannerComponent } from '../../components/demo-data-banner/demo-data-banner.component';\nimport {\n DEBTUS_SERVICE,\n IContactBalance,\n IDebtusTransfer,\n formatAmount,\n formatSignedBalance,\n} from '@sneat/extension-debtus-contract';\nimport {\n SpaceComponentBaseParams,\n SpacePageBaseComponent,\n} from '@sneat/space-components';\nimport { combineLatest, switchMap } from 'rxjs';\n\n// Contact detail — balance with one counterparty plus their transfer history.\n// Actions mirror the bot: record a lend/borrow, remind, and settle up.\n@Component({\n selector: 'sneat-debtus-contact-details-page',\n templateUrl: './debtus-contact-details-page.component.html',\n imports: [\n DemoDataBannerComponent,\n IonHeader,\n IonToolbar,\n IonButtons,\n IonBackButton,\n IonTitle,\n IonContent,\n IonCard,\n IonCardHeader,\n IonCardTitle,\n IonCardContent,\n IonList,\n IonItem,\n IonLabel,\n IonNote,\n IonBadge,\n IonButton,\n IonIcon,\n IonSpinner,\n DatePipe,\n ],\n providers: [SpaceComponentBaseParams],\n})\nexport class DebtusContactDetailsPageComponent extends SpacePageBaseComponent {\n private readonly debtusService = inject(DEBTUS_SERVICE);\n private readonly toastController = inject(ToastController);\n\n protected readonly $loading = signal(true);\n protected readonly $error = signal<string | undefined>(undefined);\n protected readonly $contact = signal<IContactBalance | undefined>(undefined);\n protected readonly $transfers = signal<IDebtusTransfer[]>([]);\n protected contactID = '';\n\n protected readonly formatAmount = formatAmount;\n protected readonly formatSignedBalance = formatSignedBalance;\n\n constructor() {\n super();\n this.$defaultBackUrlSpacePath.set('debtus-contacts');\n combineLatest([this.spaceIDChanged$, this.route.paramMap])\n .pipe(\n switchMap(([spaceID, params]) => {\n this.contactID = params.get('contactID') ?? '';\n this.$loading.set(true);\n this.$error.set(undefined);\n return combineLatest([\n this.debtusService.getContactBalance(\n spaceID ?? '',\n this.contactID,\n ),\n this.debtusService.getTransfers(spaceID ?? '', this.contactID),\n ]);\n }),\n takeUntilDestroyed(),\n )\n .subscribe({\n next: ([contact, transfers]) => {\n this.$contact.set(contact);\n this.$transfers.set(transfers);\n this.$loading.set(false);\n },\n error: (err) => {\n this.$error.set('Failed to load contact');\n this.$loading.set(false);\n this.errorLogger.logError(err, 'Failed to load debtus contact');\n },\n });\n }\n\n protected recordLend(): void {\n this.spaceNav.navigateForwardToSpacePage(\n this.space,\n `new-transfer?direction=lend&contactID=${this.contactID}`,\n );\n }\n\n protected recordBorrow(): void {\n this.spaceNav.navigateForwardToSpacePage(\n this.space,\n `new-transfer?direction=borrow&contactID=${this.contactID}`,\n );\n }\n\n protected settleUp(): void {\n this.spaceNav.navigateForwardToSpacePage(\n this.space,\n `settle-up?contactID=${this.contactID}`,\n );\n }\n\n protected async remind(): Promise<void> {\n // Fable: prototype demo data — no wired reminder-send HTTP endpoint yet.\n // The bot schedules reminders via a background cron; here we just confirm\n // the intent. SWAP: call a POST reminder endpoint once available.\n const toast = await this.toastController.create({\n message: `Reminder queued for ${this.$contact()?.title ?? 'contact'} (demo).`,\n duration: 2500,\n color: 'medium',\n });\n await toast.present();\n }\n\n protected openTransfer(transferID: string): void {\n this.spaceNav.navigateForwardToSpacePage(\n this.space,\n `transfer/${transferID}`,\n );\n }\n}\n","<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>{{ $contact()?.title ?? 'Contact' }}</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"cardy\">\n <!-- Reads on this page are still demo fixtures (see DebtusService). -->\n <sneat-debtus-demo-data-banner />\n\n @if ($loading()) {\n <div class=\"ion-padding ion-text-center\">\n <ion-spinner name=\"dots\" />\n </div>\n } @else if ($error()) {\n <div class=\"ion-padding\">\n <ion-note color=\"danger\">{{ $error() }}</ion-note>\n </div>\n } @else {\n <ion-card>\n <ion-card-header>\n <ion-card-title>Balance</ion-card-title>\n </ion-card-header>\n <ion-card-content>\n {{ formatSignedBalance($contact()?.balance ?? {}) }}\n @if ($contact()?.counterpartySpaceID) {\n <p>\n <ion-note color=\"medium\">\n Cross-space loan — counterparty is in space\n {{ $contact()?.counterpartySpaceID }}.\n </ion-note>\n </p>\n }\n </ion-card-content>\n </ion-card>\n\n <ion-card>\n <ion-card-content>\n <ion-button expand=\"block\" (click)=\"recordLend()\">\n <ion-icon name=\"arrow-up-outline\" slot=\"start\" />\n Record what I lent\n </ion-button>\n <ion-button expand=\"block\" fill=\"outline\" (click)=\"recordBorrow()\">\n <ion-icon name=\"arrow-down-outline\" slot=\"start\" />\n Record what I borrowed\n </ion-button>\n <ion-button expand=\"block\" fill=\"clear\" (click)=\"remind()\">\n <ion-icon name=\"notifications-outline\" slot=\"start\" />\n Remind\n </ion-button>\n <ion-button\n expand=\"block\"\n color=\"success\"\n fill=\"outline\"\n (click)=\"settleUp()\"\n >\n <ion-icon name=\"checkmark-done-outline\" slot=\"start\" />\n Settle up\n </ion-button>\n </ion-card-content>\n </ion-card>\n\n <ion-card>\n <ion-card-header>\n <ion-card-title>History</ion-card-title>\n </ion-card-header>\n @if ($transfers().length) {\n <ion-list>\n @for (t of $transfers(); track t.id) {\n <ion-item button (click)=\"openTransfer(t.id)\">\n <ion-label>\n <h2>\n {{ t.direction === 'lend' ? 'You lent' : 'You borrowed' }}\n @if (t.isReturn) { (return) }\n </h2>\n <p>{{ t.note || (t.created | date: 'mediumDate') }}</p>\n </ion-label>\n <ion-badge\n slot=\"end\"\n [color]=\"t.direction === 'lend' ? 'success' : 'warning'\"\n >\n {{ formatAmount(t.amount) }}\n </ion-badge>\n </ion-item>\n }\n </ion-list>\n } @else {\n <ion-card-content>\n <ion-note>No transfers with this contact yet.</ion-note>\n </ion-card-content>\n }\n </ion-card>\n }\n</ion-content>\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sneat-extension-debtus-ui-debtus-contacts-page.component-DYtFeNsM.mjs","sources":["../../../../../../libs/extensions/debtus/ui/src/lib/pages/debtus-contacts/debtus-contacts-page.component.ts","../../../../../../libs/extensions/debtus/ui/src/lib/pages/debtus-contacts/debtus-contacts-page.component.html"],"sourcesContent":["import { Component, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport {\n IonBackButton,\n IonButtons,\n IonContent,\n IonHeader,\n IonItem,\n IonLabel,\n IonList,\n IonNote,\n IonSpinner,\n IonTitle,\n IonToolbar,\n} from '@ionic/angular';\nimport { DemoDataBannerComponent } from '../../components/demo-data-banner/demo-data-banner.component';\nimport {\n DEBTUS_SERVICE,\n IContactBalance,\n formatSignedBalance,\n} from '@sneat/extension-debtus-contract';\nimport {\n SpaceComponentBaseParams,\n SpacePageBaseComponent,\n} from '@sneat/space-components';\nimport { ClassName } from '@sneat/ui';\nimport { switchMap } from 'rxjs';\n\n// Contacts list — counterparties (contactus space contacts) with their net\n// balance. Tap a row to open the per-contact detail.\n@Component({\n selector: 'sneat-debtus-contacts-page',\n templateUrl: './debtus-contacts-page.component.html',\n imports: [\n DemoDataBannerComponent,\n IonHeader,\n IonToolbar,\n IonButtons,\n IonBackButton,\n IonTitle,\n IonContent,\n IonList,\n IonItem,\n IonLabel,\n IonNote,\n IonSpinner,\n ],\n providers: [\n { provide: ClassName, useValue: 'DebtusContactsPageComponent' },\n SpaceComponentBaseParams,\n ],\n})\nexport class DebtusContactsPageComponent extends SpacePageBaseComponent {\n private readonly debtusService = inject(DEBTUS_SERVICE);\n\n protected readonly $loading = signal(true);\n protected readonly $error = signal<string | undefined>(undefined);\n protected readonly $contacts = signal<IContactBalance[]>([]);\n\n protected readonly formatSignedBalance = formatSignedBalance;\n\n constructor() {\n super();\n this.$defaultBackUrlSpacePath.set('debts');\n this.spaceIDChanged$\n .pipe(\n switchMap((spaceID) => {\n this.$loading.set(true);\n this.$error.set(undefined);\n return this.debtusService.getContactBalances(spaceID ?? '');\n }),\n takeUntilDestroyed(),\n )\n .subscribe({\n next: (contacts) => {\n this.$contacts.set(contacts);\n this.$loading.set(false);\n },\n error: (err) => {\n this.$error.set('Failed to load contacts');\n this.$loading.set(false);\n this.errorLogger.logError(err, 'Failed to load debtus contacts');\n },\n });\n }\n\n protected openContact(contactID: string): void {\n this.spaceNav.navigateForwardToSpacePage(\n this.space,\n `debtus-contact/${contactID}`,\n );\n }\n}\n","<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>Contacts</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"cardy\">\n <!-- Reads on this page are still demo fixtures (see DebtusService). -->\n <sneat-debtus-demo-data-banner />\n\n @if ($loading()) {\n <div class=\"ion-padding ion-text-center\">\n <ion-spinner name=\"dots\" />\n </div>\n } @else if ($error()) {\n <div class=\"ion-padding\">\n <ion-note color=\"danger\">{{ $error() }}</ion-note>\n </div>\n } @else if ($contacts().length) {\n <ion-list>\n @for (c of $contacts(); track c.contactID) {\n <ion-item button (click)=\"openContact(c.contactID)\">\n <ion-label>\n <h2>{{ c.title }}</h2>\n <p>{{ formatSignedBalance(c.balance) }}</p>\n @if (c.counterpartySpaceID) {\n <ion-note color=\"medium\"\n >cross-space · {{ c.counterpartySpaceID }}</ion-note\n >\n }\n </ion-label>\n </ion-item>\n }\n </ion-list>\n } @else {\n <div class=\"ion-padding ion-text-center\">\n <ion-note>No contacts with debts yet.</ion-note>\n </div>\n }\n</ion-content>\n"],"names":[],"mappings":";;;;;;;;;;AA4BA;AACA;AAuBM,MAAO,2BAA4B,SAAQ,sBAAsB,CAAA;AACpD,IAAA,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC;IAEpC,QAAQ,GAAG,MAAM,CAAC,IAAI;iFAAC;IACvB,MAAM,GAAG,MAAM,CAAqB,SAAS;+EAAC;IAC9C,SAAS,GAAG,MAAM,CAAoB,EAAE;kFAAC;IAEzC,mBAAmB,GAAG,mBAAmB;AAE5D,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC;AAC1C,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CACH,SAAS,CAAC,CAAC,OAAO,KAAI;AACpB,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;AACvB,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;YAC1B,OAAO,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,OAAO,IAAI,EAAE,CAAC;AAC7D,QAAA,CAAC,CAAC,EACF,kBAAkB,EAAE;AAErB,aAAA,SAAS,CAAC;AACT,YAAA,IAAI,EAAE,CAAC,QAAQ,KAAI;AACjB,gBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC5B,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;YAC1B,CAAC;AACD,YAAA,KAAK,EAAE,CAAC,GAAG,KAAI;AACb,gBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC;AAC1C,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;gBACxB,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,EAAE,gCAAgC,CAAC;YAClE,CAAC;AACF,SAAA,CAAC;IACN;AAEU,IAAA,WAAW,CAAC,SAAiB,EAAA;AACrC,QAAA,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CACtC,IAAI,CAAC,KAAK,EACV,CAAA,eAAA,EAAkB,SAAS,CAAA,CAAE,CAC9B;IACH;uGAvCW,2BAA2B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAA3B,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,2BAA2B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,SAAA,EAL3B;AACT,YAAA,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,6BAA6B,EAAE;YAC/D,wBAAwB;SACzB,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClDH,uzCA2CA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDTI,uBAAuB,EAAA,QAAA,EAAA,+BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACvB,SAAS,oGACT,UAAU,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACV,UAAU,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACV,aAAa,EAAA,QAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACb,QAAQ,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACR,UAAU,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,oBAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,SAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,EAAA,WAAA,EAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACV,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACP,OAAO,0NACP,QAAQ,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACR,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACP,UAAU,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAOD,2BAA2B,EAAA,UAAA,EAAA,CAAA;kBAtBvC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,4BAA4B,EAAA,OAAA,EAE7B;wBACP,uBAAuB;wBACvB,SAAS;wBACT,UAAU;wBACV,UAAU;wBACV,aAAa;wBACb,QAAQ;wBACR,UAAU;wBACV,OAAO;wBACP,OAAO;wBACP,QAAQ;wBACR,OAAO;wBACP,UAAU;qBACX,EAAA,SAAA,EACU;AACT,wBAAA,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,6BAA6B,EAAE;wBAC/D,wBAAwB;AACzB,qBAAA,EAAA,QAAA,EAAA,uzCAAA,EAAA;;;;;"}