@nauticana/sail 1.1.24 → 1.1.26
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.
- package/README.md +46 -12
- package/package.json +2 -1
- package/src/component/abstract/base_table.ts +19 -4
- package/src/component/dashboard/stat_tile.html +29 -0
- package/src/component/dashboard/stat_tile.ts +46 -0
- package/src/component/document/document_review_queue.html +24 -0
- package/src/component/document/document_review_queue.ts +67 -0
- package/src/component/document/document_upload.html +31 -0
- package/src/component/document/document_upload.ts +113 -0
- package/src/component/document/partner_documents.html +33 -0
- package/src/component/document/partner_documents.ts +92 -0
- package/src/component/payment/user_payment_methods.html +1 -1
- package/src/component/payment/user_payment_methods.ts +6 -6
- package/src/component/table/action_params_dialog.html +50 -0
- package/src/component/table/action_params_dialog.ts +107 -0
- package/src/index.ts +6 -0
- package/src/model/appdata.ts +10 -0
- package/src/model/document.ts +36 -0
- package/src/service/label.service.ts +22 -0
- package/src/service/notification_inbox.service.ts +54 -15
- package/src/service/partner_document.service.ts +111 -0
- package/src/service/realtime.service.ts +5 -3
- package/src/service/rest_service.ts +11 -1
- package/src/service/rest_url.ts +7 -4
- package/src/service/user_payment_method.service.ts +8 -14
|
@@ -8,9 +8,11 @@ export interface RealtimeChannelFrame<T = unknown> {
|
|
|
8
8
|
data: T;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
const CONTROL_OPS = ['subscribed', 'unsubscribed', 'error'] as const;
|
|
12
|
+
|
|
11
13
|
/** Control frames of the keel realtime wire protocol. */
|
|
12
14
|
interface ControlFrame {
|
|
13
|
-
op:
|
|
15
|
+
op: typeof CONTROL_OPS[number];
|
|
14
16
|
channel?: string;
|
|
15
17
|
reason?: string;
|
|
16
18
|
}
|
|
@@ -93,7 +95,7 @@ export class RealtimeService {
|
|
|
93
95
|
if (this.channels.delete(channel) && this.connected()) this.sendFrame({ op: 'unsubscribe', channel });
|
|
94
96
|
}
|
|
95
97
|
|
|
96
|
-
/** Payloads keel delivers to this user directly (SendToUser / PublishUser). */
|
|
98
|
+
/** Payloads keel delivers to this user directly (SendToUser / PublishUser), e.g. `{op: 'notification', ...}`. */
|
|
97
99
|
userFrames<T = unknown>(): Observable<T> {
|
|
98
100
|
return this.frames$.pipe(filter((f): f is T => !isChannelFrame(f) && !isControlFrame(f)));
|
|
99
101
|
}
|
|
@@ -132,7 +134,7 @@ function isChannelFrame(f: unknown): f is RealtimeChannelFrame {
|
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
function isControlFrame(f: unknown): f is ControlFrame {
|
|
135
|
-
return !!f && typeof f === 'object' && 'op'
|
|
137
|
+
return !!f && typeof f === 'object' && CONTROL_OPS.includes((f as { op?: unknown }).op as ControlFrame['op']);
|
|
136
138
|
}
|
|
137
139
|
|
|
138
140
|
/** ws(s):// form of the configured backend host plus `path`; same-origin when no host is set. */
|
|
@@ -153,8 +153,18 @@ export class BackendService extends BaseRestService {
|
|
|
153
153
|
* the call will POST to {host}{api_prefix}{actionPath} with the
|
|
154
154
|
* supplied body. For record-specific actions the body carries the
|
|
155
155
|
* primary key values; for table-level actions it is typically `{}`.
|
|
156
|
+
* A body carrying a File/Blob posts as `multipart/form-data`.
|
|
156
157
|
*/
|
|
157
158
|
executeAction<T = unknown>(actionPath: string, body: Record<string, unknown> = {}): Observable<T> {
|
|
158
|
-
return this.http.post<T>(this.apiUrl(actionPath), body).pipe(catchError((err) => this.handleError(err)));
|
|
159
|
+
return this.http.post<T>(this.apiUrl(actionPath), multipartWhenFile(body)).pipe(catchError((err) => this.handleError(err)));
|
|
159
160
|
}
|
|
160
161
|
}
|
|
162
|
+
|
|
163
|
+
function multipartWhenFile(body: Record<string, unknown>): Record<string, unknown> | FormData {
|
|
164
|
+
if (!Object.values(body).some((value) => value instanceof Blob)) return body;
|
|
165
|
+
const form = new FormData();
|
|
166
|
+
for (const [key, value] of Object.entries(body)) {
|
|
167
|
+
if (value != null) form.append(key, value instanceof Blob ? value : String(value));
|
|
168
|
+
}
|
|
169
|
+
return form;
|
|
170
|
+
}
|
package/src/service/rest_url.ts
CHANGED
|
@@ -77,11 +77,14 @@ export const RestURL = {
|
|
|
77
77
|
agencyAcceptInviteURL: '/api/v1/agency/invite/accept',
|
|
78
78
|
agencyDelegationURL: '/api/v1/agency/delegation',
|
|
79
79
|
agencyRevokeDelegationURL: '/api/v1/agency/delegation/revoke',
|
|
80
|
-
// User payment methods — list
|
|
81
|
-
//
|
|
82
|
-
// TableAction (basis table_action row), mounted at the conventional
|
|
83
|
-
// URL POST /api/v1/user_payment_method/set_default.
|
|
80
|
+
// User payment methods — list is keel's generic REST CRUD; set_default and
|
|
81
|
+
// remove are keel UserPaymentMethodHandler table actions.
|
|
84
82
|
paymentMethodSetDefaultURL: '/api/v1/user_payment_method/set_default',
|
|
83
|
+
paymentMethodRemoveURL: '/api/v1/user_payment_method/remove',
|
|
84
|
+
// Partner documents — keel DocumentHandler, mounted at its TableActionPath shape.
|
|
85
|
+
partnerDocumentUploadURL: '/api/v1/partner_document/upload',
|
|
86
|
+
partnerDocumentPreviewURL: '/api/v1/partner_document/preview',
|
|
87
|
+
partnerDocumentReviewURL: '/api/v1/partner_document/review',
|
|
85
88
|
};
|
|
86
89
|
|
|
87
90
|
/** Call this at app startup to set the backend host URL */
|
|
@@ -8,13 +8,10 @@ import { UserPaymentMethod } from '../model/appdata';
|
|
|
8
8
|
/**
|
|
9
9
|
* UserPaymentMethodService — consumer-side saved-payment-methods API.
|
|
10
10
|
*
|
|
11
|
-
* list
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* endpoint because it needs an atomic multi-row UPDATE
|
|
16
|
-
* (`SET is_default = (id = ?) WHERE user_id = session`) that abstract
|
|
17
|
-
* single-row CRUD can't express.
|
|
11
|
+
* list goes through keel's generic REST CRUD against the UserSpecific basis
|
|
12
|
+
* user_payment_method table. remove and setDefault are keel table actions:
|
|
13
|
+
* remove detaches the method at the provider before deleting the row, so keel
|
|
14
|
+
* grants no generic DELETE on the table.
|
|
18
15
|
*/
|
|
19
16
|
@Injectable({ providedIn: 'root' })
|
|
20
17
|
export class UserPaymentMethodService extends BaseRestService {
|
|
@@ -29,15 +26,12 @@ export class UserPaymentMethodService extends BaseRestService {
|
|
|
29
26
|
return this.backend.list<UserPaymentMethod>('user_payment_method');
|
|
30
27
|
}
|
|
31
28
|
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
-
return this.
|
|
29
|
+
/** Detach a saved payment method at the provider and delete it. */
|
|
30
|
+
remove(id: number): Observable<{ message: string }> {
|
|
31
|
+
return this.http.post<{ message: string }>(this.url(RestURL.paymentMethodRemoveURL), { id });
|
|
35
32
|
}
|
|
36
33
|
|
|
37
|
-
/**
|
|
38
|
-
* Mark one row as default; clears every other row in the same call.
|
|
39
|
-
* Custom endpoint — see service-class doc for the rationale.
|
|
40
|
-
*/
|
|
34
|
+
/** Mark one row as default; clears every other row in the same call. */
|
|
41
35
|
setDefault(id: number): Observable<{ message: string }> {
|
|
42
36
|
return this.http.post<{ message: string }>(this.url(RestURL.paymentMethodSetDefaultURL), { id });
|
|
43
37
|
}
|