@burdenoff/microfe-proserviceworld 2026.728.1 → 2026.731.1
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/dist/proserviceworld/ProServiceWorldRoot.d.ts.map +1 -1
- package/dist/proserviceworld/ProServiceWorldRoot.js +44 -20
- package/dist/proserviceworld/ProServiceWorldRoot.js.map +1 -1
- package/dist/proserviceworld/ProServiceWorldRoutes.d.ts.map +1 -1
- package/dist/proserviceworld/ProServiceWorldRoutes.js +51 -23
- package/dist/proserviceworld/ProServiceWorldRoutes.js.map +1 -1
- package/dist/proserviceworld/components/ui.d.ts.map +1 -1
- package/dist/proserviceworld/components/ui.js +7 -1
- package/dist/proserviceworld/components/ui.js.map +1 -1
- package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts +110 -0
- package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts.map +1 -1
- package/dist/proserviceworld/hooks/useProServiceWorldApi.js +223 -49
- package/dist/proserviceworld/hooks/useProServiceWorldApi.js.map +1 -1
- package/dist/proserviceworld/pages/ClientPortalAccessPage.d.ts +4 -0
- package/dist/proserviceworld/pages/ClientPortalAccessPage.d.ts.map +1 -0
- package/dist/proserviceworld/pages/ClientPortalAccessPage.js +191 -0
- package/dist/proserviceworld/pages/ClientPortalAccessPage.js.map +1 -0
- package/dist/proserviceworld/pages/MyPortalPage.d.ts +4 -0
- package/dist/proserviceworld/pages/MyPortalPage.d.ts.map +1 -0
- package/dist/proserviceworld/pages/MyPortalPage.js +162 -0
- package/dist/proserviceworld/pages/MyPortalPage.js.map +1 -0
- package/dist/proserviceworld/pages/MySignaturesPage.d.ts +4 -0
- package/dist/proserviceworld/pages/MySignaturesPage.d.ts.map +1 -0
- package/dist/proserviceworld/pages/MySignaturesPage.js +240 -0
- package/dist/proserviceworld/pages/MySignaturesPage.js.map +1 -0
- package/dist/proserviceworld/pages/SignaturesPage.d.ts +4 -0
- package/dist/proserviceworld/pages/SignaturesPage.d.ts.map +1 -0
- package/dist/proserviceworld/pages/SignaturesPage.js +317 -0
- package/dist/proserviceworld/pages/SignaturesPage.js.map +1 -0
- package/package.json +6 -6
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { useCancelSignatureRequest as e, useCreateSignatureRequest as t, useDocuments as n, useSendSignatureRequest as r, useSignatureAuditEvents as i, useSignatureRequests as a } from "../hooks/useProServiceWorldApi.js";
|
|
2
|
+
import { Banner as o, Empty as s, ErrorState as c, Field as l, LoadingBlock as u, Modal as d, NativeSelect as f, PageHeader as p, SectionCard as m, StatusPill as h, TableWrap as g, Td as _, TextArea as v, TextInput as y, Th as b, fmtDate as x } from "../components/ui.js";
|
|
3
|
+
import { useState as S } from "react";
|
|
4
|
+
import { FileSignature as C, History as w, Plus as T, Send as E, Trash2 as D, XCircle as O } from "lucide-react";
|
|
5
|
+
import { Fragment as k, jsx as A, jsxs as j } from "react/jsx-runtime";
|
|
6
|
+
import { Button as M } from "@burdenoff/fe-libs/ui";
|
|
7
|
+
//#region src/proserviceworld/pages/SignaturesPage.tsx
|
|
8
|
+
var N = /* @__PURE__ */ new Set([
|
|
9
|
+
"DRAFT",
|
|
10
|
+
"SENT",
|
|
11
|
+
"VIEWED",
|
|
12
|
+
"PARTIALLY_SIGNED"
|
|
13
|
+
]), P = () => {
|
|
14
|
+
let { data: t, isLoading: n, error: i, refetch: l } = a(), d = t?.items ?? [], [f, v] = S(!1), [y, D] = S(null), [k, P] = S(null), L = r(), R = e();
|
|
15
|
+
return /* @__PURE__ */ j("div", {
|
|
16
|
+
className: "space-y-6",
|
|
17
|
+
children: [
|
|
18
|
+
/* @__PURE__ */ A(p, {
|
|
19
|
+
title: "Signatures",
|
|
20
|
+
subtitle: "Request, track, and audit e-signatures on your practice's documents.",
|
|
21
|
+
icon: /* @__PURE__ */ A(C, { className: "h-6 w-6" }),
|
|
22
|
+
actions: /* @__PURE__ */ j(M, {
|
|
23
|
+
onClick: () => v(!0),
|
|
24
|
+
children: [/* @__PURE__ */ A(T, { className: "mr-1.5 h-4 w-4" }), "New signature request"]
|
|
25
|
+
})
|
|
26
|
+
}),
|
|
27
|
+
k && /* @__PURE__ */ A(o, {
|
|
28
|
+
tone: k.tone,
|
|
29
|
+
onClose: () => P(null),
|
|
30
|
+
children: k.text
|
|
31
|
+
}),
|
|
32
|
+
n ? /* @__PURE__ */ A(u, {}) : i ? /* @__PURE__ */ A(c, {
|
|
33
|
+
error: i,
|
|
34
|
+
onRetry: () => void l()
|
|
35
|
+
}) : d.length === 0 ? /* @__PURE__ */ A(s, {
|
|
36
|
+
title: "No signature requests",
|
|
37
|
+
description: "Request a signature on an engagement letter or other document.",
|
|
38
|
+
icon: /* @__PURE__ */ A(C, { className: "h-8 w-8" }),
|
|
39
|
+
action: /* @__PURE__ */ j(M, {
|
|
40
|
+
onClick: () => v(!0),
|
|
41
|
+
children: [/* @__PURE__ */ A(T, { className: "mr-1.5 h-4 w-4" }), "New signature request"]
|
|
42
|
+
})
|
|
43
|
+
}) : /* @__PURE__ */ A(m, {
|
|
44
|
+
title: `${t?.totalCount ?? d.length} request${(t?.totalCount ?? d.length) === 1 ? "" : "s"}`,
|
|
45
|
+
children: /* @__PURE__ */ j(g, { children: [/* @__PURE__ */ A("thead", { children: /* @__PURE__ */ j("tr", { children: [
|
|
46
|
+
/* @__PURE__ */ A(b, { children: "Document" }),
|
|
47
|
+
/* @__PURE__ */ A(b, { children: "Status" }),
|
|
48
|
+
/* @__PURE__ */ A(b, { children: "Signers" }),
|
|
49
|
+
/* @__PURE__ */ A(b, { children: "Sent" }),
|
|
50
|
+
/* @__PURE__ */ A(b, {
|
|
51
|
+
className: "text-right",
|
|
52
|
+
children: "Actions"
|
|
53
|
+
})
|
|
54
|
+
] }) }), /* @__PURE__ */ A("tbody", { children: d.map((e) => /* @__PURE__ */ j("tr", {
|
|
55
|
+
className: "hover:bg-bg-sunken/50",
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ A(_, { children: /* @__PURE__ */ A("span", {
|
|
58
|
+
className: "font-medium text-text-primary",
|
|
59
|
+
children: e.document?.name ?? e.documentId
|
|
60
|
+
}) }),
|
|
61
|
+
/* @__PURE__ */ A(_, { children: /* @__PURE__ */ A(h, { status: e.status }) }),
|
|
62
|
+
/* @__PURE__ */ A(_, { children: /* @__PURE__ */ A("div", {
|
|
63
|
+
className: "flex flex-col gap-0.5",
|
|
64
|
+
children: e.signers.map((e) => /* @__PURE__ */ j("span", {
|
|
65
|
+
className: "text-xs text-text-secondary",
|
|
66
|
+
children: [
|
|
67
|
+
e.name,
|
|
68
|
+
" — ",
|
|
69
|
+
/* @__PURE__ */ A(h, { status: e.status })
|
|
70
|
+
]
|
|
71
|
+
}, e.id))
|
|
72
|
+
}) }),
|
|
73
|
+
/* @__PURE__ */ A(_, { children: x(e.sentAt) }),
|
|
74
|
+
/* @__PURE__ */ A(_, {
|
|
75
|
+
className: "text-right",
|
|
76
|
+
children: /* @__PURE__ */ j("div", {
|
|
77
|
+
className: "flex justify-end gap-1",
|
|
78
|
+
children: [
|
|
79
|
+
e.status === "DRAFT" && /* @__PURE__ */ A(M, {
|
|
80
|
+
variant: "ghost",
|
|
81
|
+
size: "sm",
|
|
82
|
+
"aria-label": "Send",
|
|
83
|
+
disabled: L.isPending,
|
|
84
|
+
onClick: () => L.mutate(e.id, {
|
|
85
|
+
onSuccess: () => P({
|
|
86
|
+
tone: "success",
|
|
87
|
+
text: "Signature request sent."
|
|
88
|
+
}),
|
|
89
|
+
onError: (e) => P({
|
|
90
|
+
tone: "danger",
|
|
91
|
+
text: e instanceof Error ? e.message : "Failed."
|
|
92
|
+
})
|
|
93
|
+
}),
|
|
94
|
+
children: /* @__PURE__ */ A(E, { className: "h-4 w-4" })
|
|
95
|
+
}),
|
|
96
|
+
/* @__PURE__ */ A(M, {
|
|
97
|
+
variant: "ghost",
|
|
98
|
+
size: "sm",
|
|
99
|
+
"aria-label": "Audit trail",
|
|
100
|
+
onClick: () => D(e),
|
|
101
|
+
children: /* @__PURE__ */ A(w, { className: "h-4 w-4" })
|
|
102
|
+
}),
|
|
103
|
+
N.has(e.status) && /* @__PURE__ */ A(M, {
|
|
104
|
+
variant: "ghost",
|
|
105
|
+
size: "sm",
|
|
106
|
+
"aria-label": "Cancel",
|
|
107
|
+
disabled: R.isPending,
|
|
108
|
+
onClick: () => R.mutate(e.id, {
|
|
109
|
+
onSuccess: () => P({
|
|
110
|
+
tone: "success",
|
|
111
|
+
text: "Signature request cancelled."
|
|
112
|
+
}),
|
|
113
|
+
onError: (e) => P({
|
|
114
|
+
tone: "danger",
|
|
115
|
+
text: e instanceof Error ? e.message : "Failed."
|
|
116
|
+
})
|
|
117
|
+
}),
|
|
118
|
+
children: /* @__PURE__ */ A(O, { className: "h-4 w-4" })
|
|
119
|
+
})
|
|
120
|
+
]
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
]
|
|
124
|
+
}, e.id)) })] })
|
|
125
|
+
}),
|
|
126
|
+
f && /* @__PURE__ */ A(I, {
|
|
127
|
+
onClose: () => v(!1),
|
|
128
|
+
onDone: () => {
|
|
129
|
+
l(), P({
|
|
130
|
+
tone: "success",
|
|
131
|
+
text: "Signature request created and sent."
|
|
132
|
+
});
|
|
133
|
+
},
|
|
134
|
+
onFail: (e) => P({
|
|
135
|
+
tone: "danger",
|
|
136
|
+
text: e
|
|
137
|
+
})
|
|
138
|
+
}),
|
|
139
|
+
y && /* @__PURE__ */ A(F, {
|
|
140
|
+
request: y,
|
|
141
|
+
onClose: () => D(null)
|
|
142
|
+
})
|
|
143
|
+
]
|
|
144
|
+
});
|
|
145
|
+
}, F = ({ request: e, onClose: t }) => {
|
|
146
|
+
let { data: n, isLoading: r, error: a } = i(e.id);
|
|
147
|
+
return /* @__PURE__ */ A(d, {
|
|
148
|
+
open: !0,
|
|
149
|
+
onClose: t,
|
|
150
|
+
title: `Audit trail — ${e.document?.name ?? e.documentId}`,
|
|
151
|
+
children: r ? /* @__PURE__ */ A(u, {}) : a ? /* @__PURE__ */ A(c, { error: a }) : !n || n.items.length === 0 ? /* @__PURE__ */ A(s, {
|
|
152
|
+
title: "No events yet",
|
|
153
|
+
icon: /* @__PURE__ */ A(w, { className: "h-8 w-8" })
|
|
154
|
+
}) : /* @__PURE__ */ A("ul", {
|
|
155
|
+
className: "space-y-2 text-sm",
|
|
156
|
+
children: n.items.map((e) => /* @__PURE__ */ j("li", {
|
|
157
|
+
className: "rounded-lg border border-border-seam p-2",
|
|
158
|
+
children: [/* @__PURE__ */ j("div", {
|
|
159
|
+
className: "flex items-center justify-between",
|
|
160
|
+
children: [/* @__PURE__ */ A("span", {
|
|
161
|
+
className: "font-medium text-text-primary",
|
|
162
|
+
children: e.eventType
|
|
163
|
+
}), /* @__PURE__ */ A("span", {
|
|
164
|
+
className: "text-text-tertiary",
|
|
165
|
+
children: x(e.createdAt)
|
|
166
|
+
})]
|
|
167
|
+
}), /* @__PURE__ */ j("div", {
|
|
168
|
+
className: "text-text-secondary",
|
|
169
|
+
children: [
|
|
170
|
+
e.actorLabel,
|
|
171
|
+
e.ipAddress ? ` · ${e.ipAddress}` : "",
|
|
172
|
+
e.documentVersion == null ? "" : ` · doc v${e.documentVersion}`
|
|
173
|
+
]
|
|
174
|
+
})]
|
|
175
|
+
}, e.id))
|
|
176
|
+
})
|
|
177
|
+
});
|
|
178
|
+
}, I = ({ onClose: e, onDone: i, onFail: a }) => {
|
|
179
|
+
let { data: s } = n(), c = t(), u = r(), [p, m] = S(""), [h, g] = S(""), [_, b] = S([{
|
|
180
|
+
actorId: "",
|
|
181
|
+
name: "",
|
|
182
|
+
email: ""
|
|
183
|
+
}]), [x, C] = S(null), w = (e, t) => b((n) => n.map((n, r) => r === e ? {
|
|
184
|
+
...n,
|
|
185
|
+
...t
|
|
186
|
+
} : n)), E = async () => {
|
|
187
|
+
if (C(null), !p) return C("Choose a document.");
|
|
188
|
+
let t = _.filter((e) => e.actorId.trim() && e.name.trim() && e.email.trim());
|
|
189
|
+
if (t.length === 0) return C("Add at least one signer (platform user ID, name, email).");
|
|
190
|
+
c.mutate({
|
|
191
|
+
documentId: p,
|
|
192
|
+
message: h.trim() || null,
|
|
193
|
+
signers: t.map((e) => ({
|
|
194
|
+
actorId: e.actorId.trim(),
|
|
195
|
+
name: e.name.trim(),
|
|
196
|
+
email: e.email.trim()
|
|
197
|
+
}))
|
|
198
|
+
}, {
|
|
199
|
+
onSuccess: (t) => {
|
|
200
|
+
let n = t.pswCreateSignatureRequest?.id;
|
|
201
|
+
if (!n) {
|
|
202
|
+
i(), e();
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
u.mutate(n, {
|
|
206
|
+
onSuccess: () => {
|
|
207
|
+
i(), e();
|
|
208
|
+
},
|
|
209
|
+
onError: (e) => a(e instanceof Error ? e.message : "Created but failed to send.")
|
|
210
|
+
});
|
|
211
|
+
},
|
|
212
|
+
onError: (e) => C(e instanceof Error ? e.message : "Failed.")
|
|
213
|
+
});
|
|
214
|
+
}, O = c.isPending || u.isPending;
|
|
215
|
+
return /* @__PURE__ */ A(d, {
|
|
216
|
+
open: !0,
|
|
217
|
+
onClose: e,
|
|
218
|
+
title: "New signature request",
|
|
219
|
+
footer: /* @__PURE__ */ j(k, { children: [/* @__PURE__ */ A(M, {
|
|
220
|
+
variant: "outline",
|
|
221
|
+
onClick: e,
|
|
222
|
+
disabled: O,
|
|
223
|
+
children: "Cancel"
|
|
224
|
+
}), /* @__PURE__ */ A(M, {
|
|
225
|
+
onClick: () => void E(),
|
|
226
|
+
disabled: O,
|
|
227
|
+
children: O ? "Sending…" : "Create & send"
|
|
228
|
+
})] }),
|
|
229
|
+
children: /* @__PURE__ */ j("div", {
|
|
230
|
+
className: "space-y-3",
|
|
231
|
+
children: [
|
|
232
|
+
x && /* @__PURE__ */ A(o, {
|
|
233
|
+
tone: "danger",
|
|
234
|
+
children: x
|
|
235
|
+
}),
|
|
236
|
+
/* @__PURE__ */ A(l, {
|
|
237
|
+
label: "Document",
|
|
238
|
+
required: !0,
|
|
239
|
+
children: /* @__PURE__ */ j(f, {
|
|
240
|
+
value: p,
|
|
241
|
+
onChange: (e) => m(e.target.value),
|
|
242
|
+
children: [/* @__PURE__ */ A("option", {
|
|
243
|
+
value: "",
|
|
244
|
+
children: "Select a document…"
|
|
245
|
+
}), (s?.items ?? []).map((e) => /* @__PURE__ */ j("option", {
|
|
246
|
+
value: e.id,
|
|
247
|
+
children: [
|
|
248
|
+
e.name,
|
|
249
|
+
" (v",
|
|
250
|
+
e.version,
|
|
251
|
+
")"
|
|
252
|
+
]
|
|
253
|
+
}, e.id))]
|
|
254
|
+
})
|
|
255
|
+
}),
|
|
256
|
+
/* @__PURE__ */ A(l, {
|
|
257
|
+
label: "Message",
|
|
258
|
+
hint: "Optional note shown to signers.",
|
|
259
|
+
children: /* @__PURE__ */ A(v, {
|
|
260
|
+
value: h,
|
|
261
|
+
onChange: (e) => g(e.target.value)
|
|
262
|
+
})
|
|
263
|
+
}),
|
|
264
|
+
/* @__PURE__ */ A(l, {
|
|
265
|
+
label: "Signers",
|
|
266
|
+
hint: "Each signer must already be a platform actor — a workspace member or a client-portal contact (see Client Portal Access for their platform user ID).",
|
|
267
|
+
children: /* @__PURE__ */ j("div", {
|
|
268
|
+
className: "space-y-2",
|
|
269
|
+
children: [_.map((e, t) => /* @__PURE__ */ j("div", {
|
|
270
|
+
className: "grid grid-cols-3 gap-2",
|
|
271
|
+
children: [
|
|
272
|
+
/* @__PURE__ */ A(y, {
|
|
273
|
+
placeholder: "Platform user ID",
|
|
274
|
+
value: e.actorId,
|
|
275
|
+
onChange: (e) => w(t, { actorId: e.target.value })
|
|
276
|
+
}),
|
|
277
|
+
/* @__PURE__ */ A(y, {
|
|
278
|
+
placeholder: "Name",
|
|
279
|
+
value: e.name,
|
|
280
|
+
onChange: (e) => w(t, { name: e.target.value })
|
|
281
|
+
}),
|
|
282
|
+
/* @__PURE__ */ A(y, {
|
|
283
|
+
placeholder: "Email",
|
|
284
|
+
value: e.email,
|
|
285
|
+
onChange: (e) => w(t, { email: e.target.value })
|
|
286
|
+
})
|
|
287
|
+
]
|
|
288
|
+
}, t)), /* @__PURE__ */ j("div", {
|
|
289
|
+
className: "flex items-center gap-2",
|
|
290
|
+
children: [/* @__PURE__ */ j(M, {
|
|
291
|
+
type: "button",
|
|
292
|
+
variant: "outline",
|
|
293
|
+
size: "sm",
|
|
294
|
+
onClick: () => b((e) => [...e, {
|
|
295
|
+
actorId: "",
|
|
296
|
+
name: "",
|
|
297
|
+
email: ""
|
|
298
|
+
}]),
|
|
299
|
+
children: [/* @__PURE__ */ A(T, { className: "mr-1 h-3.5 w-3.5" }), "Add signer"]
|
|
300
|
+
}), _.length > 1 && /* @__PURE__ */ j(M, {
|
|
301
|
+
type: "button",
|
|
302
|
+
variant: "ghost",
|
|
303
|
+
size: "sm",
|
|
304
|
+
onClick: () => b((e) => e.slice(0, -1)),
|
|
305
|
+
children: [/* @__PURE__ */ A(D, { className: "mr-1 h-3.5 w-3.5" }), "Remove last"]
|
|
306
|
+
})]
|
|
307
|
+
})]
|
|
308
|
+
})
|
|
309
|
+
})
|
|
310
|
+
]
|
|
311
|
+
})
|
|
312
|
+
});
|
|
313
|
+
};
|
|
314
|
+
//#endregion
|
|
315
|
+
export { P as SignaturesPage };
|
|
316
|
+
|
|
317
|
+
//# sourceMappingURL=SignaturesPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SignaturesPage.js","names":[],"sources":["../../../src/proserviceworld/pages/SignaturesPage.tsx"],"sourcesContent":["/**\n * Signatures — practitioner-side e-signature request management (BOFF-4212).\n *\n * Scope: a real capture-and-audit core, not a DocuSign-equivalent. Signers\n * are existing platform actors (workspace members or client-portal contacts\n * — see the \"Client Portal Access\" page for granting the latter) identified\n * by their platform user ID; there is no email-invite/magic-link flow for\n * non-platform signers here — that is documented, deferred scope.\n */\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { FileSignature, Plus, Send, XCircle, History, Trash2 } from 'lucide-react';\nimport {\n useSignatureRequests,\n useCreateSignatureRequest,\n useSendSignatureRequest,\n useCancelSignatureRequest,\n useSignatureAuditEvents,\n useDocuments,\n type PswSignatureRequest,\n} from '../hooks/useProServiceWorldApi';\nimport {\n PageHeader,\n SectionCard,\n LoadingBlock,\n ErrorState,\n Empty,\n StatusPill,\n Modal,\n Field,\n TextInput,\n TextArea,\n NativeSelect,\n Banner,\n TableWrap,\n Th,\n Td,\n fmtDate,\n} from '../components/ui';\n\nconst ACTIVE_STATUSES = new Set(['DRAFT', 'SENT', 'VIEWED', 'PARTIALLY_SIGNED']);\n\nexport const SignaturesPage: FC = () => {\n const { data, isLoading, error, refetch } = useSignatureRequests();\n const requests = data?.items ?? [];\n const [creating, setCreating] = useState(false);\n const [auditFor, setAuditFor] = useState<PswSignatureRequest | null>(null);\n const [banner, setBanner] = useState<{ tone: 'success' | 'danger'; text: string } | null>(null);\n\n const send = useSendSignatureRequest();\n const cancel = useCancelSignatureRequest();\n\n return (\n <div className=\"space-y-6\">\n <PageHeader\n title=\"Signatures\"\n subtitle=\"Request, track, and audit e-signatures on your practice's documents.\"\n icon={<FileSignature className=\"h-6 w-6\" />}\n actions={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New signature request\n </Button>\n }\n />\n\n {banner && (\n <Banner tone={banner.tone} onClose={() => setBanner(null)}>\n {banner.text}\n </Banner>\n )}\n\n {isLoading ? (\n <LoadingBlock />\n ) : error ? (\n <ErrorState error={error} onRetry={() => void refetch()} />\n ) : requests.length === 0 ? (\n <Empty\n title=\"No signature requests\"\n description=\"Request a signature on an engagement letter or other document.\"\n icon={<FileSignature className=\"h-8 w-8\" />}\n action={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New signature request\n </Button>\n }\n />\n ) : (\n <SectionCard\n title={`${data?.totalCount ?? requests.length} request${(data?.totalCount ?? requests.length) === 1 ? '' : 's'}`}\n >\n <TableWrap>\n <thead>\n <tr>\n <Th>Document</Th>\n <Th>Status</Th>\n <Th>Signers</Th>\n <Th>Sent</Th>\n <Th className=\"text-right\">Actions</Th>\n </tr>\n </thead>\n <tbody>\n {requests.map((r) => (\n <tr key={r.id} className=\"hover:bg-bg-sunken/50\">\n <Td>\n <span className=\"font-medium text-text-primary\">\n {r.document?.name ?? r.documentId}\n </span>\n </Td>\n <Td>\n <StatusPill status={r.status} />\n </Td>\n <Td>\n <div className=\"flex flex-col gap-0.5\">\n {r.signers.map((s) => (\n <span key={s.id} className=\"text-xs text-text-secondary\">\n {s.name} — <StatusPill status={s.status} />\n </span>\n ))}\n </div>\n </Td>\n <Td>{fmtDate(r.sentAt)}</Td>\n <Td className=\"text-right\">\n <div className=\"flex justify-end gap-1\">\n {r.status === 'DRAFT' && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Send\"\n disabled={send.isPending}\n onClick={() =>\n send.mutate(r.id, {\n onSuccess: () =>\n setBanner({ tone: 'success', text: 'Signature request sent.' }),\n onError: (e) =>\n setBanner({\n tone: 'danger',\n text: e instanceof Error ? e.message : 'Failed.',\n }),\n })\n }\n >\n <Send className=\"h-4 w-4\" />\n </Button>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Audit trail\"\n onClick={() => setAuditFor(r)}\n >\n <History className=\"h-4 w-4\" />\n </Button>\n {ACTIVE_STATUSES.has(r.status) && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Cancel\"\n disabled={cancel.isPending}\n onClick={() =>\n cancel.mutate(r.id, {\n onSuccess: () =>\n setBanner({\n tone: 'success',\n text: 'Signature request cancelled.',\n }),\n onError: (e) =>\n setBanner({\n tone: 'danger',\n text: e instanceof Error ? e.message : 'Failed.',\n }),\n })\n }\n >\n <XCircle className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n </Td>\n </tr>\n ))}\n </tbody>\n </TableWrap>\n </SectionCard>\n )}\n\n {creating && (\n <NewSignatureRequestModal\n onClose={() => setCreating(false)}\n onDone={() => {\n void refetch();\n setBanner({ tone: 'success', text: 'Signature request created and sent.' });\n }}\n onFail={(msg) => setBanner({ tone: 'danger', text: msg })}\n />\n )}\n\n {auditFor && <AuditTrailModal request={auditFor} onClose={() => setAuditFor(null)} />}\n </div>\n );\n};\n\nconst AuditTrailModal: FC<{ request: PswSignatureRequest; onClose: () => void }> = ({\n request,\n onClose,\n}) => {\n const { data, isLoading, error } = useSignatureAuditEvents(request.id);\n return (\n <Modal\n open\n onClose={onClose}\n title={`Audit trail — ${request.document?.name ?? request.documentId}`}\n >\n {isLoading ? (\n <LoadingBlock />\n ) : error ? (\n <ErrorState error={error} />\n ) : !data || data.items.length === 0 ? (\n <Empty title=\"No events yet\" icon={<History className=\"h-8 w-8\" />} />\n ) : (\n <ul className=\"space-y-2 text-sm\">\n {data.items.map((e) => (\n <li key={e.id} className=\"rounded-lg border border-border-seam p-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-medium text-text-primary\">{e.eventType}</span>\n <span className=\"text-text-tertiary\">{fmtDate(e.createdAt)}</span>\n </div>\n <div className=\"text-text-secondary\">\n {e.actorLabel}\n {e.ipAddress ? ` · ${e.ipAddress}` : ''}\n {e.documentVersion != null ? ` · doc v${e.documentVersion}` : ''}\n </div>\n </li>\n ))}\n </ul>\n )}\n </Modal>\n );\n};\n\ninterface SignerDraft {\n actorId: string;\n name: string;\n email: string;\n}\n\nconst NewSignatureRequestModal: FC<{\n onClose: () => void;\n onDone: () => void;\n onFail: (msg: string) => void;\n}> = ({ onClose, onDone, onFail }) => {\n const { data: documents } = useDocuments();\n const create = useCreateSignatureRequest();\n const send = useSendSignatureRequest();\n const [documentId, setDocumentId] = useState('');\n const [message, setMessage] = useState('');\n const [signers, setSigners] = useState<SignerDraft[]>([{ actorId: '', name: '', email: '' }]);\n const [err, setErr] = useState<string | null>(null);\n\n const updateSigner = (i: number, patch: Partial<SignerDraft>) =>\n setSigners((prev) => prev.map((s, idx) => (idx === i ? { ...s, ...patch } : s)));\n\n const submit = async () => {\n setErr(null);\n if (!documentId) return setErr('Choose a document.');\n const validSigners = signers.filter((s) => s.actorId.trim() && s.name.trim() && s.email.trim());\n if (validSigners.length === 0)\n return setErr('Add at least one signer (platform user ID, name, email).');\n\n create.mutate(\n {\n documentId,\n message: message.trim() || null,\n signers: validSigners.map((s) => ({\n actorId: s.actorId.trim(),\n name: s.name.trim(),\n email: s.email.trim(),\n })),\n },\n {\n onSuccess: (result) => {\n const created = result as { pswCreateSignatureRequest?: { id: string } };\n const id = created.pswCreateSignatureRequest?.id;\n if (!id) {\n onDone();\n onClose();\n return;\n }\n send.mutate(id, {\n onSuccess: () => {\n onDone();\n onClose();\n },\n onError: (e) => onFail(e instanceof Error ? e.message : 'Created but failed to send.'),\n });\n },\n onError: (e) => setErr(e instanceof Error ? e.message : 'Failed.'),\n }\n );\n };\n\n const busy = create.isPending || send.isPending;\n\n return (\n <Modal\n open\n onClose={onClose}\n title=\"New signature request\"\n footer={\n <>\n <Button variant=\"outline\" onClick={onClose} disabled={busy}>\n Cancel\n </Button>\n <Button onClick={() => void submit()} disabled={busy}>\n {busy ? 'Sending…' : 'Create & send'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Document\" required>\n <NativeSelect value={documentId} onChange={(e) => setDocumentId(e.target.value)}>\n <option value=\"\">Select a document…</option>\n {(documents?.items ?? []).map((d) => (\n <option key={d.id} value={d.id}>\n {d.name} (v{d.version})\n </option>\n ))}\n </NativeSelect>\n </Field>\n <Field label=\"Message\" hint=\"Optional note shown to signers.\">\n <TextArea value={message} onChange={(e) => setMessage(e.target.value)} />\n </Field>\n <Field\n label=\"Signers\"\n hint=\"Each signer must already be a platform actor — a workspace member or a client-portal contact (see Client Portal Access for their platform user ID).\"\n >\n <div className=\"space-y-2\">\n {signers.map((s, i) => (\n <div key={i} className=\"grid grid-cols-3 gap-2\">\n <TextInput\n placeholder=\"Platform user ID\"\n value={s.actorId}\n onChange={(e) => updateSigner(i, { actorId: e.target.value })}\n />\n <TextInput\n placeholder=\"Name\"\n value={s.name}\n onChange={(e) => updateSigner(i, { name: e.target.value })}\n />\n <TextInput\n placeholder=\"Email\"\n value={s.email}\n onChange={(e) => updateSigner(i, { email: e.target.value })}\n />\n </div>\n ))}\n <div className=\"flex items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() =>\n setSigners((prev) => [...prev, { actorId: '', name: '', email: '' }])\n }\n >\n <Plus className=\"mr-1 h-3.5 w-3.5\" />\n Add signer\n </Button>\n {signers.length > 1 && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setSigners((prev) => prev.slice(0, -1))}\n >\n <Trash2 className=\"mr-1 h-3.5 w-3.5\" />\n Remove last\n </Button>\n )}\n </div>\n </div>\n </Field>\n </div>\n </Modal>\n );\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-proserviceworld",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.731.1",
|
|
4
4
|
"description": "Burdenoff ProServiceWorld Microfrontend",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -22,15 +22,15 @@
|
|
|
22
22
|
"types": "./dist/index.d.ts",
|
|
23
23
|
"scripts": {
|
|
24
24
|
"dev": "vite",
|
|
25
|
-
"build": "tsc && vite build",
|
|
25
|
+
"build": "tsc && bash scripts/build-limits.sh --gate vite build",
|
|
26
26
|
"lint": "eslint .",
|
|
27
27
|
"lint:sanity": "if [ \"${CI:-}\" = \"true\" ]; then bun run lint; else bun run lint -- --cache --cache-location .eslintcache; fi",
|
|
28
28
|
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
29
|
-
"type:check": "tsc --noEmit",
|
|
30
|
-
"test": "vitest run",
|
|
29
|
+
"type:check": "bash scripts/build-limits.sh tsc --noEmit",
|
|
30
|
+
"test": "bash scripts/build-limits.sh vitest run",
|
|
31
31
|
"test:watch": "vitest",
|
|
32
|
-
"test:coverage": "vitest run --coverage",
|
|
33
|
-
"sanity": "bun run codegen && bun run lint:sanity && bun run format && bun run type:check && bun run test && bun run build && bun run build-storybook",
|
|
32
|
+
"test:coverage": "bash scripts/build-limits.sh vitest run --coverage",
|
|
33
|
+
"sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run codegen && bun run lint:sanity && bun run format && bun run type:check && bun run test && bun run build && bun run build-storybook'",
|
|
34
34
|
"schema:pull": "graphql-codegen --project schema-wspace && graphql-codegen --project schema-global",
|
|
35
35
|
"codegen": "graphql-codegen --project wspace && graphql-codegen --project global",
|
|
36
36
|
"codegen:all": "bun run schema:pull && bun run codegen",
|