@burdenoff/microfe-proserviceworld 2026.709.1 → 2026.709.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.
- package/dist/index.js +2 -1
- package/dist/proserviceworld/ProServiceWorldRoutes.d.ts.map +1 -1
- package/dist/proserviceworld/ProServiceWorldRoutes.js +95 -42
- package/dist/proserviceworld/ProServiceWorldRoutes.js.map +1 -1
- package/dist/proserviceworld/components/FeatureFlaggedPage.d.ts +8 -0
- package/dist/proserviceworld/components/FeatureFlaggedPage.d.ts.map +1 -0
- package/dist/proserviceworld/components/FeatureFlaggedPage.js +17 -0
- package/dist/proserviceworld/components/FeatureFlaggedPage.js.map +1 -0
- package/dist/proserviceworld/components/LoadMore.d.ts +12 -0
- package/dist/proserviceworld/components/LoadMore.d.ts.map +1 -0
- package/dist/proserviceworld/components/LoadMore.js +30 -0
- package/dist/proserviceworld/components/LoadMore.js.map +1 -0
- package/dist/proserviceworld/components/TagPicker.d.ts +11 -0
- package/dist/proserviceworld/components/TagPicker.d.ts.map +1 -0
- package/dist/proserviceworld/components/TagPicker.js +31 -0
- package/dist/proserviceworld/components/TagPicker.js.map +1 -0
- package/dist/proserviceworld/hooks/usePageViewAnalytics.d.ts +10 -0
- package/dist/proserviceworld/hooks/usePageViewAnalytics.d.ts.map +1 -0
- package/dist/proserviceworld/hooks/usePageViewAnalytics.js +24 -0
- package/dist/proserviceworld/hooks/usePageViewAnalytics.js.map +1 -0
- package/dist/proserviceworld/hooks/useProServiceWorldApi.js +47 -27
- package/dist/proserviceworld/hooks/useProServiceWorldApi.js.map +1 -1
- package/dist/proserviceworld/i18n/index.d.ts +13 -0
- package/dist/proserviceworld/i18n/index.d.ts.map +1 -0
- package/dist/proserviceworld/i18n/index.js +171 -0
- package/dist/proserviceworld/i18n/index.js.map +1 -0
- package/dist/proserviceworld/index.d.ts +1 -0
- package/dist/proserviceworld/index.d.ts.map +1 -1
- package/dist/proserviceworld/index.js +1 -0
- package/dist/proserviceworld/pages/ClientsPage.d.ts.map +1 -1
- package/dist/proserviceworld/pages/ClientsPage.js +173 -121
- package/dist/proserviceworld/pages/ClientsPage.js.map +1 -1
- package/dist/proserviceworld/pages/EngagementsPage.d.ts.map +1 -1
- package/dist/proserviceworld/pages/EngagementsPage.js +168 -120
- package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -1
- package/dist/proserviceworld/pages/MattersPage.d.ts.map +1 -1
- package/dist/proserviceworld/pages/MattersPage.js +183 -144
- package/dist/proserviceworld/pages/MattersPage.js.map +1 -1
- package/dist/proserviceworld/utils/native.d.ts +23 -0
- package/dist/proserviceworld/utils/native.d.ts.map +1 -0
- package/dist/proserviceworld/utils/native.js +14 -0
- package/dist/proserviceworld/utils/native.js.map +1 -0
- package/package.json +1 -1
|
@@ -130,6 +130,19 @@ function D() {
|
|
|
130
130
|
});
|
|
131
131
|
}
|
|
132
132
|
function O() {
|
|
133
|
+
let t = n();
|
|
134
|
+
return e({
|
|
135
|
+
mutationFn: (e) => a(`mutation PswUpdateEngagement($id: ID!, $input: PswUpdateEngagementInput!) { pswUpdateEngagement(id: $id, input: $input) { ${l} } }`, e),
|
|
136
|
+
onSuccess: (e, n) => {
|
|
137
|
+
s(t, "engagements"), t.invalidateQueries({ queryKey: [
|
|
138
|
+
o,
|
|
139
|
+
"engagement",
|
|
140
|
+
n.id
|
|
141
|
+
] });
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function k() {
|
|
133
146
|
let t = n();
|
|
134
147
|
return e({
|
|
135
148
|
mutationFn: (e) => a(`mutation PswTransitionEngagement($id: ID!, $status: PswEngagementStatus!) { pswTransitionEngagement(id: $id, status: $status) { ${l} } }`, e),
|
|
@@ -142,7 +155,7 @@ function O() {
|
|
|
142
155
|
}
|
|
143
156
|
});
|
|
144
157
|
}
|
|
145
|
-
function
|
|
158
|
+
function A() {
|
|
146
159
|
let t = n();
|
|
147
160
|
return e({
|
|
148
161
|
mutationFn: (e) => a(`mutation PswCreateDeliverable($input: PswCreateDeliverableInput!) { pswCreateDeliverable(input: $input) { ${u} } }`, { input: e }),
|
|
@@ -153,7 +166,7 @@ function k() {
|
|
|
153
166
|
] })
|
|
154
167
|
});
|
|
155
168
|
}
|
|
156
|
-
function
|
|
169
|
+
function j() {
|
|
157
170
|
let t = n();
|
|
158
171
|
return e({
|
|
159
172
|
mutationFn: (e) => a(`mutation PswTransitionDeliverable($id: ID!, $status: PswDeliverableStatus!) { pswTransitionDeliverable(id: $id, status: $status) { ${u} } }`, {
|
|
@@ -167,7 +180,7 @@ function A() {
|
|
|
167
180
|
] })
|
|
168
181
|
});
|
|
169
182
|
}
|
|
170
|
-
function
|
|
183
|
+
function M() {
|
|
171
184
|
let t = n();
|
|
172
185
|
return e({
|
|
173
186
|
mutationFn: (e) => a(`mutation PswCreateMilestone($input: PswCreateMilestoneInput!) { pswCreateMilestone(input: $input) { ${d} } }`, { input: e }),
|
|
@@ -178,7 +191,7 @@ function j() {
|
|
|
178
191
|
] })
|
|
179
192
|
});
|
|
180
193
|
}
|
|
181
|
-
function
|
|
194
|
+
function N() {
|
|
182
195
|
let t = n();
|
|
183
196
|
return e({
|
|
184
197
|
mutationFn: (e) => a(`mutation PswCompleteMilestone($id: ID!) { pswCompleteMilestone(id: $id) { ${d} } }`, { id: e.id }),
|
|
@@ -189,7 +202,7 @@ function M() {
|
|
|
189
202
|
] })
|
|
190
203
|
});
|
|
191
204
|
}
|
|
192
|
-
function
|
|
205
|
+
function ee(e = {}) {
|
|
193
206
|
return t({
|
|
194
207
|
queryKey: [
|
|
195
208
|
o,
|
|
@@ -209,21 +222,28 @@ function N(e = {}) {
|
|
|
209
222
|
})).pswListMatters
|
|
210
223
|
});
|
|
211
224
|
}
|
|
212
|
-
function
|
|
225
|
+
function P() {
|
|
213
226
|
let t = n();
|
|
214
227
|
return e({
|
|
215
228
|
mutationFn: (e) => a(`mutation PswCreateMatter($input: PswCreateMatterInput!) { pswCreateMatter(input: $input) { ${f} } }`, { input: e }),
|
|
216
229
|
onSuccess: () => s(t, "matters", "dashboard")
|
|
217
230
|
});
|
|
218
231
|
}
|
|
219
|
-
function
|
|
232
|
+
function F() {
|
|
233
|
+
let t = n();
|
|
234
|
+
return e({
|
|
235
|
+
mutationFn: (e) => a(`mutation PswUpdateMatter($id: ID!, $input: PswUpdateMatterInput!) { pswUpdateMatter(id: $id, input: $input) { ${f} } }`, e),
|
|
236
|
+
onSuccess: () => s(t, "matters")
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
function I() {
|
|
220
240
|
let t = n();
|
|
221
241
|
return e({
|
|
222
242
|
mutationFn: (e) => a(`mutation PswCloseMatter($id: ID!) { pswCloseMatter(id: $id) { ${f} } }`, { id: e }),
|
|
223
243
|
onSuccess: () => s(t, "matters", "dashboard")
|
|
224
244
|
});
|
|
225
245
|
}
|
|
226
|
-
function
|
|
246
|
+
function L(e = {}) {
|
|
227
247
|
return t({
|
|
228
248
|
queryKey: [
|
|
229
249
|
o,
|
|
@@ -243,28 +263,28 @@ function F(e = {}) {
|
|
|
243
263
|
})).pswListTimeEntries
|
|
244
264
|
});
|
|
245
265
|
}
|
|
246
|
-
function
|
|
266
|
+
function R() {
|
|
247
267
|
let t = n();
|
|
248
268
|
return e({
|
|
249
269
|
mutationFn: (e) => a(`mutation PswLogTime($input: PswCreateTimeEntryInput!) { pswLogTimeEntry(input: $input) { ${p} } }`, { input: e }),
|
|
250
270
|
onSuccess: () => s(t, "time", "dashboard")
|
|
251
271
|
});
|
|
252
272
|
}
|
|
253
|
-
function
|
|
273
|
+
function z() {
|
|
254
274
|
let t = n();
|
|
255
275
|
return e({
|
|
256
276
|
mutationFn: (e) => a(`mutation PswSubmitTime($id: ID!) { pswSubmitTimeEntry(id: $id) { ${p} } }`, { id: e }),
|
|
257
277
|
onSuccess: () => s(t, "time")
|
|
258
278
|
});
|
|
259
279
|
}
|
|
260
|
-
function
|
|
280
|
+
function B() {
|
|
261
281
|
let t = n();
|
|
262
282
|
return e({
|
|
263
283
|
mutationFn: (e) => a(`mutation PswApproveTime($id: ID!) { pswApproveTimeEntry(id: $id) { ${p} } }`, { id: e }),
|
|
264
284
|
onSuccess: () => s(t, "time")
|
|
265
285
|
});
|
|
266
286
|
}
|
|
267
|
-
function
|
|
287
|
+
function V(e = {}) {
|
|
268
288
|
return t({
|
|
269
289
|
queryKey: [
|
|
270
290
|
o,
|
|
@@ -282,21 +302,21 @@ function z(e = {}) {
|
|
|
282
302
|
})).pswListInvoices
|
|
283
303
|
});
|
|
284
304
|
}
|
|
285
|
-
function
|
|
305
|
+
function H() {
|
|
286
306
|
let t = n();
|
|
287
307
|
return e({
|
|
288
308
|
mutationFn: (e) => a(`mutation PswCreateInvoice($input: PswCreateInvoiceInput!) { pswCreateInvoice(input: $input) { ${m} } }`, { input: e }),
|
|
289
309
|
onSuccess: () => s(t, "invoices", "dashboard")
|
|
290
310
|
});
|
|
291
311
|
}
|
|
292
|
-
function
|
|
312
|
+
function U() {
|
|
293
313
|
let t = n();
|
|
294
314
|
return e({
|
|
295
315
|
mutationFn: (e) => a(`mutation PswMarkPaid($id: ID!) { pswMarkInvoicePaid(id: $id) { ${m} } }`, { id: e }),
|
|
296
316
|
onSuccess: () => s(t, "invoices", "dashboard")
|
|
297
317
|
});
|
|
298
318
|
}
|
|
299
|
-
function
|
|
319
|
+
function W(e = {}) {
|
|
300
320
|
return t({
|
|
301
321
|
queryKey: [
|
|
302
322
|
o,
|
|
@@ -311,21 +331,21 @@ function H(e = {}) {
|
|
|
311
331
|
})).pswListComplianceChecks
|
|
312
332
|
});
|
|
313
333
|
}
|
|
314
|
-
function
|
|
334
|
+
function G() {
|
|
315
335
|
let t = n();
|
|
316
336
|
return e({
|
|
317
337
|
mutationFn: (e) => a(`mutation PswCreateCompliance($input: PswCreateComplianceCheckInput!) { pswCreateComplianceCheck(input: $input) { ${h} } }`, { input: e }),
|
|
318
338
|
onSuccess: () => s(t, "compliance", "dashboard")
|
|
319
339
|
});
|
|
320
340
|
}
|
|
321
|
-
function
|
|
341
|
+
function K() {
|
|
322
342
|
let t = n();
|
|
323
343
|
return e({
|
|
324
344
|
mutationFn: (e) => a(`mutation PswResolveCompliance($id: ID!, $status: PswComplianceStatus!, $details: String) { pswResolveComplianceCheck(id: $id, status: $status, details: $details) { ${h} } }`, e),
|
|
325
345
|
onSuccess: () => s(t, "compliance", "dashboard")
|
|
326
346
|
});
|
|
327
347
|
}
|
|
328
|
-
function
|
|
348
|
+
function q(e = {}) {
|
|
329
349
|
return t({
|
|
330
350
|
queryKey: [
|
|
331
351
|
o,
|
|
@@ -340,14 +360,14 @@ function G(e = {}) {
|
|
|
340
360
|
})).pswListConflictChecks
|
|
341
361
|
});
|
|
342
362
|
}
|
|
343
|
-
function
|
|
363
|
+
function J() {
|
|
344
364
|
let t = n();
|
|
345
365
|
return e({
|
|
346
366
|
mutationFn: (e) => a(`mutation PswCreateConflict($input: PswCreateConflictCheckInput!) { pswCreateConflictCheck(input: $input) { ${g} } }`, { input: e }),
|
|
347
367
|
onSuccess: () => s(t, "conflicts", "dashboard")
|
|
348
368
|
});
|
|
349
369
|
}
|
|
350
|
-
function
|
|
370
|
+
function Y() {
|
|
351
371
|
let t = n();
|
|
352
372
|
return e({
|
|
353
373
|
mutationFn: (e) => a(`mutation PswResolveConflict($id: ID!, $status: PswConflictCheckStatus!, $findings: String, $waiverReason: String) {
|
|
@@ -356,27 +376,27 @@ function q() {
|
|
|
356
376
|
onSuccess: () => s(t, "conflicts", "dashboard")
|
|
357
377
|
});
|
|
358
378
|
}
|
|
359
|
-
function
|
|
379
|
+
function X() {
|
|
360
380
|
return t({
|
|
361
381
|
queryKey: [o, "practiceAreas"],
|
|
362
382
|
queryFn: async () => (await a(`query PswPracticeAreas { pswListPracticeAreas(pagination: { limit: 100 }) { ${_} } }`)).pswListPracticeAreas
|
|
363
383
|
});
|
|
364
384
|
}
|
|
365
|
-
function
|
|
385
|
+
function Z() {
|
|
366
386
|
let t = n();
|
|
367
387
|
return e({
|
|
368
388
|
mutationFn: (e) => a(`mutation PswCreatePracticeArea($input: PswCreatePracticeAreaInput!) { pswCreatePracticeArea(input: $input) { ${_} } }`, { input: e }),
|
|
369
389
|
onSuccess: () => s(t, "practiceAreas")
|
|
370
390
|
});
|
|
371
391
|
}
|
|
372
|
-
function
|
|
392
|
+
function Q() {
|
|
373
393
|
let t = n();
|
|
374
394
|
return e({
|
|
375
395
|
mutationFn: (e) => a(`mutation PswUpdatePracticeArea($id: ID!, $input: PswUpdatePracticeAreaInput!) { pswUpdatePracticeArea(id: $id, input: $input) { ${_} } }`, e),
|
|
376
396
|
onSuccess: () => s(t, "practiceAreas")
|
|
377
397
|
});
|
|
378
398
|
}
|
|
379
|
-
function
|
|
399
|
+
function $(e = {}) {
|
|
380
400
|
return t({
|
|
381
401
|
queryKey: [
|
|
382
402
|
o,
|
|
@@ -396,14 +416,14 @@ function Z(e = {}) {
|
|
|
396
416
|
})).pswListDocuments
|
|
397
417
|
});
|
|
398
418
|
}
|
|
399
|
-
function
|
|
419
|
+
function te() {
|
|
400
420
|
let t = n();
|
|
401
421
|
return e({
|
|
402
422
|
mutationFn: (e) => a(`mutation PswCreateDocument($input: PswCreateDocumentInput!) { pswCreateDocument(input: $input) { ${v} } }`, { input: e }),
|
|
403
423
|
onSuccess: () => s(t, "documents")
|
|
404
424
|
});
|
|
405
425
|
}
|
|
406
|
-
function
|
|
426
|
+
function ne() {
|
|
407
427
|
let t = n();
|
|
408
428
|
return e({
|
|
409
429
|
mutationFn: (e) => a(`mutation PswArchiveDocument($id: ID!) { pswArchiveDocument(id: $id) { ${v} } }`, { id: e }),
|
|
@@ -411,6 +431,6 @@ function $() {
|
|
|
411
431
|
});
|
|
412
432
|
}
|
|
413
433
|
//#endregion
|
|
414
|
-
export {
|
|
434
|
+
export { B as useApproveTimeEntry, w as useArchiveClient, ne as useArchiveDocument, x as useClient, b as useClients, I as useCloseMatter, N as useCompleteMilestone, W as useComplianceChecks, q as useConflictChecks, S as useCreateClient, G as useCreateComplianceCheck, J as useCreateConflictCheck, A as useCreateDeliverable, te as useCreateDocument, D as useCreateEngagement, H as useCreateInvoice, P as useCreateMatter, M as useCreateMilestone, Z as useCreatePracticeArea, y as useDashboardStats, $ as useDocuments, E as useEngagement, T as useEngagements, V as useInvoices, R as useLogTimeEntry, U as useMarkInvoicePaid, ee as useMatters, X as usePracticeAreas, K as useResolveComplianceCheck, Y as useResolveConflictCheck, z as useSubmitTimeEntry, L as useTimeEntries, j as useTransitionDeliverable, k as useTransitionEngagement, C as useUpdateClient, O as useUpdateEngagement, F as useUpdateMatter, Q as useUpdatePracticeArea };
|
|
415
435
|
|
|
416
436
|
//# sourceMappingURL=useProServiceWorldApi.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useProServiceWorldApi.js","names":[],"sources":["../../../src/proserviceworld/hooks/useProServiceWorldApi.ts"],"sourcesContent":["/**\n * ProServiceWorld API hooks\n * @module proserviceworld/hooks\n *\n * Real data layer for the ProServiceWorld workspace subgraph (`proserviceworld`\n * Hive service / `wspace-proserviceworld-svc`). Every hook talks to the live\n * workspace GraphQL gateway via {@link graphqlFetch} with inline operations\n * whose fields mirror `.hive-schema.graphql` exactly. No mocks.\n *\n * Conventions (mirror microfe-hookmovies / microfe-collabkin):\n * - `pswQuery` wraps graphqlFetch({ gateway: 'workspace', workspaceToken: true })\n * and throws on GraphQL errors / missing data.\n * - One react-query `useQuery` per read op and `useMutation` per write op.\n * - Strict hand-written result interfaces — no `any`.\n * - Lists paginate by offset (the workspaces gateway strips the cursor arg);\n * `*Connection { items, pageInfo { hasMore cursor }, totalCount }` verbatim.\n * - After any successful mutation we clear fe-libs' short-lived graphqlFetch\n * read cache so the very next refetch is fresh (fleet stale-read fix).\n */\n\nimport { useMutation, useQuery, useQueryClient, type QueryClient } from '@tanstack/react-query';\n\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\n// ============================================================================\n// Low-level runner\n// ============================================================================\n\nasync function pswQuery<TData>(\n query: string,\n variables: Record<string, unknown> = {}\n): Promise<TData> {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'GraphQL request failed');\n }\n if (!response.data) {\n throw new Error('GraphQL response did not include data');\n }\n if (query.trimStart().startsWith('mutation')) {\n clearGraphqlFetchResponseCache();\n }\n return response.data;\n}\n\nconst QK = 'proserviceworld' as const;\n\n/** Invalidate a set of top-level query keys after a write. */\nfunction invalidate(qc: QueryClient, ...keys: string[]): void {\n for (const key of keys) void qc.invalidateQueries({ queryKey: [QK, key] });\n}\n\n// ============================================================================\n// Shared types (mirror .hive-schema.graphql)\n// ============================================================================\n\nexport interface PswPagination {\n limit?: number;\n offset?: number;\n}\nexport interface PswPageInfo {\n hasMore: boolean;\n cursor: string | null;\n}\nexport interface PswConnection<T> {\n items: T[];\n pageInfo: PswPageInfo;\n totalCount: number;\n}\n\nexport type PswClientType = 'INDIVIDUAL' | 'ORGANIZATION';\nexport type PswClientStatus = 'PROSPECT' | 'ACTIVE' | 'INACTIVE' | 'ARCHIVED';\nexport type PswFeeArrangement = 'FIXED' | 'HOURLY' | 'RETAINER' | 'VALUE_BASED';\nexport type PswEngagementStatus =\n | 'PROPOSAL'\n | 'ACCEPTED'\n | 'IN_PROGRESS'\n | 'REVIEW'\n | 'DELIVERED'\n | 'INVOICED'\n | 'CLOSED'\n | 'CANCELLED';\nexport type PswMatterStatus = 'OPEN' | 'ON_HOLD' | 'CLOSED' | 'ARCHIVED';\nexport type PswMatterPriority = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';\nexport type PswDeliverableStatus =\n | 'DRAFT'\n | 'INTERNAL_REVIEW'\n | 'CLIENT_REVIEW'\n | 'ACCEPTED'\n | 'REJECTED';\nexport type PswMilestoneStatus = 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'CANCELLED';\nexport type PswDocumentStatus = 'DRAFT' | 'FINAL' | 'ARCHIVED';\nexport type PswDocumentClassification = 'PUBLIC' | 'INTERNAL' | 'CONFIDENTIAL' | 'PRIVILEGED';\nexport type PswTimeEntryStatus = 'DRAFT' | 'SUBMITTED' | 'APPROVED' | 'REJECTED' | 'BILLED';\nexport type PswInvoiceStatus = 'DRAFT' | 'SENT' | 'PAID' | 'OVERDUE' | 'CANCELLED';\nexport type PswComplianceType =\n | 'ENGAGEMENT_ACCEPTANCE'\n | 'INDEPENDENCE'\n | 'LICENSING'\n | 'CONTINUING_EDUCATION'\n | 'DATA_RETENTION'\n | 'LEGAL_HOLD';\nexport type PswComplianceStatus = 'PENDING' | 'IN_REVIEW' | 'PASSED' | 'FAILED' | 'WAIVED';\nexport type PswConflictCheckStatus =\n | 'PENDING'\n | 'CLEAR'\n | 'POTENTIAL_CONFLICT'\n | 'CONFLICT'\n | 'WAIVED';\nexport type PswTeamRole = 'PARTNER' | 'MANAGER' | 'ASSOCIATE' | 'SPECIALIST' | 'SUPPORT';\n\nexport interface PswClient {\n id: string;\n name: string;\n type: PswClientType;\n status: PswClientStatus;\n industry: string | null;\n contactName: string | null;\n contactEmail: string | null;\n contactPhone: string | null;\n address: string | null;\n relationshipOwnerId: string | null;\n notes: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\nexport interface PswClientDetail extends PswClient {\n engagements: PswEngagement[];\n matters: PswMatter[];\n}\nexport interface PswEngagement {\n id: string;\n clientId: string;\n practiceAreaId: string | null;\n name: string;\n description: string | null;\n status: PswEngagementStatus;\n feeArrangement: PswFeeArrangement;\n feeAmount: number;\n currency: string;\n startDate: string | null;\n endDate: string | null;\n responsiblePartnerId: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n client?: { id: string; name: string } | null;\n}\nexport interface PswDeliverable {\n id: string;\n engagementId: string;\n name: string;\n description: string | null;\n status: PswDeliverableStatus;\n version: number;\n acceptanceCriteria: string | null;\n dueDate: string | null;\n acceptedAt: string | null;\n createdAt: string;\n}\nexport interface PswMilestone {\n id: string;\n engagementId: string;\n name: string;\n description: string | null;\n status: PswMilestoneStatus;\n dueDate: string | null;\n completedAt: string | null;\n triggerAmount: number;\n triggersInvoice: boolean;\n createdAt: string;\n}\nexport interface PswEngagementDetail extends PswEngagement {\n deliverables: PswDeliverable[];\n milestones: PswMilestone[];\n}\nexport interface PswMatter {\n id: string;\n clientId: string;\n engagementId: string | null;\n practiceAreaId: string | null;\n reference: string | null;\n title: string;\n description: string | null;\n status: PswMatterStatus;\n priority: PswMatterPriority;\n isPrivileged: boolean;\n dueDate: string | null;\n closedAt: string | null;\n leadPractitionerId: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n client?: { id: string; name: string } | null;\n}\nexport interface PswTimeEntry {\n id: string;\n engagementId: string | null;\n matterId: string | null;\n practitionerId: string;\n date: string;\n minutes: number;\n billable: boolean;\n rate: number;\n narrative: string | null;\n status: PswTimeEntryStatus;\n invoiceId: string | null;\n createdAt: string;\n}\nexport interface PswInvoice {\n id: string;\n clientId: string;\n engagementId: string | null;\n number: string;\n status: PswInvoiceStatus;\n currency: string;\n subtotal: number;\n taxAmount: number;\n total: number;\n issueDate: string | null;\n dueDate: string | null;\n paidAt: string | null;\n notes: string | null;\n createdAt: string;\n}\nexport interface PswComplianceCheck {\n id: string;\n type: PswComplianceType;\n status: PswComplianceStatus;\n subjectType: string;\n subjectId: string;\n title: string;\n details: string | null;\n reviewerId: string | null;\n dueDate: string | null;\n resolvedAt: string | null;\n createdAt: string;\n}\nexport interface PswConflictCheck {\n id: string;\n clientId: string;\n matterId: string | null;\n status: PswConflictCheckStatus;\n searchedParties: string[];\n findings: string | null;\n waiverReason: string | null;\n resolvedAt: string | null;\n createdAt: string;\n}\nexport interface PswPracticeArea {\n id: string;\n name: string;\n code: string | null;\n description: string | null;\n isActive: boolean;\n createdAt: string;\n}\nexport interface PswDocument {\n id: string;\n name: string;\n description: string | null;\n status: PswDocumentStatus;\n classification: PswDocumentClassification;\n version: number;\n legalHold: boolean;\n retainUntil: string | null;\n matterId: string | null;\n engagementId: string | null;\n tags: string[];\n file: { id: string } | null;\n createdAt: string;\n}\nexport interface PswStatusCount {\n status: string;\n count: number;\n}\nexport interface PswMonthlyAmount {\n month: string;\n amount: number;\n}\nexport interface PswDashboardStats {\n totalClients: number;\n activeClients: number;\n activeEngagements: number;\n openMatters: number;\n outstandingInvoiceTotal: number;\n paidInvoiceTotal: number;\n unbilledHours: number;\n billedHours: number;\n pendingComplianceChecks: number;\n openConflictChecks: number;\n engagementsByStatus: PswStatusCount[];\n invoicesByStatus: PswStatusCount[];\n mattersByStatus: PswStatusCount[];\n revenueByMonth: PswMonthlyAmount[];\n}\n\n// ============================================================================\n// GraphQL fragments\n// ============================================================================\n\nconst CLIENT_F = `\n id name type status industry contactName contactEmail contactPhone address\n relationshipOwnerId notes tags createdAt updatedAt`;\nconst ENGAGEMENT_F = `\n id clientId practiceAreaId name description status feeArrangement feeAmount currency\n startDate endDate responsiblePartnerId tags createdAt updatedAt client { id name }`;\nconst DELIVERABLE_F = `id engagementId name description status version acceptanceCriteria dueDate acceptedAt createdAt`;\nconst MILESTONE_F = `id engagementId name description status dueDate completedAt triggerAmount triggersInvoice createdAt`;\nconst MATTER_F = `\n id clientId engagementId practiceAreaId reference title description status priority isPrivileged\n dueDate closedAt leadPractitionerId tags createdAt updatedAt client { id name }`;\nconst TIME_F = `id engagementId matterId practitionerId date minutes billable rate narrative status invoiceId createdAt`;\nconst INVOICE_F = `id clientId engagementId number status currency subtotal taxAmount total issueDate dueDate paidAt notes createdAt`;\nconst COMPLIANCE_F = `id type status subjectType subjectId title details reviewerId dueDate resolvedAt createdAt`;\nconst CONFLICT_F = `id clientId matterId status searchedParties findings waiverReason resolvedAt createdAt`;\nconst PRACTICE_AREA_F = `id name code description isActive createdAt`;\nconst DOCUMENT_F = `id name description status classification version legalHold retainUntil matterId engagementId tags file { id } createdAt`;\n\n// ============================================================================\n// Dashboard\n// ============================================================================\n\nexport function useDashboardStats() {\n return useQuery({\n queryKey: [QK, 'dashboard'],\n queryFn: async () => {\n const data = await pswQuery<{ pswDashboardStats: PswDashboardStats }>(`\n query PswDashboard {\n pswDashboardStats {\n totalClients activeClients activeEngagements openMatters\n outstandingInvoiceTotal paidInvoiceTotal unbilledHours billedHours\n pendingComplianceChecks openConflictChecks\n engagementsByStatus { status count }\n invoicesByStatus { status count }\n mattersByStatus { status count }\n revenueByMonth { month amount }\n }\n }`);\n return data.pswDashboardStats;\n },\n });\n}\n\n// ============================================================================\n// Clients\n// ============================================================================\n\nexport function useClients(\n args: { status?: PswClientStatus; search?: string; pagination?: PswPagination } = {}\n) {\n return useQuery({\n queryKey: [QK, 'clients', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListClients: PswConnection<PswClient> }>(\n `query PswClients($status: PswClientStatus, $search: String, $pagination: PaginationInput) {\n pswListClients(status: $status, search: $search, pagination: $pagination) {\n items { ${CLIENT_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n status: args.status ?? null,\n search: args.search ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListClients;\n },\n });\n}\n\nexport function useClient(id: string | null) {\n return useQuery({\n queryKey: [QK, 'client', id],\n enabled: Boolean(id),\n queryFn: async () => {\n const data = await pswQuery<{ pswClient: PswClientDetail | null }>(\n `query PswClient($id: ID!) {\n pswClient(id: $id) {\n ${CLIENT_F}\n engagements { ${ENGAGEMENT_F} }\n matters { ${MATTER_F} }\n }\n }`,\n { id }\n );\n return data.pswClient;\n },\n });\n}\n\nexport function useCreateClient() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery<{ pswCreateClient: PswClient }>(\n `mutation PswCreateClient($input: PswCreateClientInput!) { pswCreateClient(input: $input) { ${CLIENT_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'clients', 'dashboard'),\n });\n}\nexport function useUpdateClient() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; input: Record<string, unknown> }) =>\n pswQuery(\n `mutation PswUpdateClient($id: ID!, $input: PswUpdateClientInput!) { pswUpdateClient(id: $id, input: $input) { ${CLIENT_F} } }`,\n vars\n ),\n onSuccess: (_d, v) => {\n invalidate(qc, 'clients', 'dashboard');\n void qc.invalidateQueries({ queryKey: [QK, 'client', v.id] });\n },\n });\n}\nexport function useArchiveClient() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(`mutation PswArchiveClient($id: ID!) { pswArchiveClient(id: $id) }`, { id }),\n onSuccess: () => invalidate(qc, 'clients', 'dashboard'),\n });\n}\n\n// ============================================================================\n// Engagements\n// ============================================================================\n\nexport function useEngagements(\n args: {\n clientId?: string;\n status?: PswEngagementStatus;\n search?: string;\n pagination?: PswPagination;\n } = {}\n) {\n return useQuery({\n queryKey: [QK, 'engagements', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListEngagements: PswConnection<PswEngagement> }>(\n `query PswEngagements($clientId: ID, $status: PswEngagementStatus, $search: String, $pagination: PaginationInput) {\n pswListEngagements(clientId: $clientId, status: $status, search: $search, pagination: $pagination) {\n items { ${ENGAGEMENT_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n clientId: args.clientId ?? null,\n status: args.status ?? null,\n search: args.search ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListEngagements;\n },\n });\n}\n\nexport function useEngagement(id: string | null) {\n return useQuery({\n queryKey: [QK, 'engagement', id],\n enabled: Boolean(id),\n queryFn: async () => {\n const data = await pswQuery<{ pswEngagement: PswEngagementDetail | null }>(\n `query PswEngagement($id: ID!) {\n pswEngagement(id: $id) {\n ${ENGAGEMENT_F}\n deliverables { ${DELIVERABLE_F} }\n milestones { ${MILESTONE_F} }\n }\n }`,\n { id }\n );\n return data.pswEngagement;\n },\n });\n}\n\nexport function useCreateEngagement() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateEngagement($input: PswCreateEngagementInput!) { pswCreateEngagement(input: $input) { ${ENGAGEMENT_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'engagements', 'dashboard'),\n });\n}\nexport function useUpdateEngagement() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; input: Record<string, unknown> }) =>\n pswQuery(\n `mutation PswUpdateEngagement($id: ID!, $input: PswUpdateEngagementInput!) { pswUpdateEngagement(id: $id, input: $input) { ${ENGAGEMENT_F} } }`,\n vars\n ),\n onSuccess: (_d, v) => {\n invalidate(qc, 'engagements');\n void qc.invalidateQueries({ queryKey: [QK, 'engagement', v.id] });\n },\n });\n}\nexport function useTransitionEngagement() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; status: PswEngagementStatus }) =>\n pswQuery(\n `mutation PswTransitionEngagement($id: ID!, $status: PswEngagementStatus!) { pswTransitionEngagement(id: $id, status: $status) { ${ENGAGEMENT_F} } }`,\n vars\n ),\n onSuccess: (_d, v) => {\n invalidate(qc, 'engagements', 'dashboard');\n void qc.invalidateQueries({ queryKey: [QK, 'engagement', v.id] });\n },\n });\n}\n\n// ============================================================================\n// Deliverables & Milestones (engagement delivery)\n// ============================================================================\n\nexport function useCreateDeliverable() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateDeliverable($input: PswCreateDeliverableInput!) { pswCreateDeliverable(input: $input) { ${DELIVERABLE_F} } }`,\n { input }\n ),\n onSuccess: (_d, input) =>\n qc.invalidateQueries({\n queryKey: [QK, 'engagement', (input as { engagementId: string }).engagementId],\n }),\n });\n}\nexport function useTransitionDeliverable() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; status: PswDeliverableStatus; engagementId: string }) =>\n pswQuery(\n `mutation PswTransitionDeliverable($id: ID!, $status: PswDeliverableStatus!) { pswTransitionDeliverable(id: $id, status: $status) { ${DELIVERABLE_F} } }`,\n {\n id: vars.id,\n status: vars.status,\n }\n ),\n onSuccess: (_d, v) => qc.invalidateQueries({ queryKey: [QK, 'engagement', v.engagementId] }),\n });\n}\nexport function useCreateMilestone() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateMilestone($input: PswCreateMilestoneInput!) { pswCreateMilestone(input: $input) { ${MILESTONE_F} } }`,\n { input }\n ),\n onSuccess: (_d, input) =>\n qc.invalidateQueries({\n queryKey: [QK, 'engagement', (input as { engagementId: string }).engagementId],\n }),\n });\n}\nexport function useCompleteMilestone() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; engagementId: string }) =>\n pswQuery(\n `mutation PswCompleteMilestone($id: ID!) { pswCompleteMilestone(id: $id) { ${MILESTONE_F} } }`,\n { id: vars.id }\n ),\n onSuccess: (_d, v) => qc.invalidateQueries({ queryKey: [QK, 'engagement', v.engagementId] }),\n });\n}\n\n// ============================================================================\n// Matters\n// ============================================================================\n\nexport function useMatters(\n args: {\n clientId?: string;\n engagementId?: string;\n status?: PswMatterStatus;\n search?: string;\n pagination?: PswPagination;\n } = {}\n) {\n return useQuery({\n queryKey: [QK, 'matters', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListMatters: PswConnection<PswMatter> }>(\n `query PswMatters($clientId: ID, $engagementId: ID, $status: PswMatterStatus, $search: String, $pagination: PaginationInput) {\n pswListMatters(clientId: $clientId, engagementId: $engagementId, status: $status, search: $search, pagination: $pagination) {\n items { ${MATTER_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n clientId: args.clientId ?? null,\n engagementId: args.engagementId ?? null,\n status: args.status ?? null,\n search: args.search ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListMatters;\n },\n });\n}\nexport function useCreateMatter() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateMatter($input: PswCreateMatterInput!) { pswCreateMatter(input: $input) { ${MATTER_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'matters', 'dashboard'),\n });\n}\nexport function useUpdateMatter() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; input: Record<string, unknown> }) =>\n pswQuery(\n `mutation PswUpdateMatter($id: ID!, $input: PswUpdateMatterInput!) { pswUpdateMatter(id: $id, input: $input) { ${MATTER_F} } }`,\n vars\n ),\n onSuccess: () => invalidate(qc, 'matters'),\n });\n}\nexport function useCloseMatter() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(`mutation PswCloseMatter($id: ID!) { pswCloseMatter(id: $id) { ${MATTER_F} } }`, {\n id,\n }),\n onSuccess: () => invalidate(qc, 'matters', 'dashboard'),\n });\n}\n\n// ============================================================================\n// Time entries\n// ============================================================================\n\nexport function useTimeEntries(\n args: {\n engagementId?: string;\n matterId?: string;\n status?: PswTimeEntryStatus;\n billable?: boolean;\n pagination?: PswPagination;\n } = {}\n) {\n return useQuery({\n queryKey: [QK, 'time', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListTimeEntries: PswConnection<PswTimeEntry> }>(\n `query PswTimeEntries($engagementId: ID, $matterId: ID, $status: PswTimeEntryStatus, $billable: Boolean, $pagination: PaginationInput) {\n pswListTimeEntries(engagementId: $engagementId, matterId: $matterId, status: $status, billable: $billable, pagination: $pagination) {\n items { ${TIME_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n engagementId: args.engagementId ?? null,\n matterId: args.matterId ?? null,\n status: args.status ?? null,\n billable: args.billable ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListTimeEntries;\n },\n });\n}\nexport function useLogTimeEntry() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswLogTime($input: PswCreateTimeEntryInput!) { pswLogTimeEntry(input: $input) { ${TIME_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'time', 'dashboard'),\n });\n}\nexport function useSubmitTimeEntry() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(`mutation PswSubmitTime($id: ID!) { pswSubmitTimeEntry(id: $id) { ${TIME_F} } }`, {\n id,\n }),\n onSuccess: () => invalidate(qc, 'time'),\n });\n}\nexport function useApproveTimeEntry() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(`mutation PswApproveTime($id: ID!) { pswApproveTimeEntry(id: $id) { ${TIME_F} } }`, {\n id,\n }),\n onSuccess: () => invalidate(qc, 'time'),\n });\n}\n\n// ============================================================================\n// Invoices\n// ============================================================================\n\nexport function useInvoices(\n args: { clientId?: string; status?: PswInvoiceStatus; pagination?: PswPagination } = {}\n) {\n return useQuery({\n queryKey: [QK, 'invoices', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListInvoices: PswConnection<PswInvoice> }>(\n `query PswInvoices($clientId: ID, $status: PswInvoiceStatus, $pagination: PaginationInput) {\n pswListInvoices(clientId: $clientId, status: $status, pagination: $pagination) {\n items { ${INVOICE_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n clientId: args.clientId ?? null,\n status: args.status ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListInvoices;\n },\n });\n}\nexport function useCreateInvoice() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateInvoice($input: PswCreateInvoiceInput!) { pswCreateInvoice(input: $input) { ${INVOICE_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'invoices', 'dashboard'),\n });\n}\nexport function useMarkInvoicePaid() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(`mutation PswMarkPaid($id: ID!) { pswMarkInvoicePaid(id: $id) { ${INVOICE_F} } }`, {\n id,\n }),\n onSuccess: () => invalidate(qc, 'invoices', 'dashboard'),\n });\n}\n\n// ============================================================================\n// Compliance\n// ============================================================================\n\nexport function useComplianceChecks(\n args: { status?: PswComplianceStatus; pagination?: PswPagination } = {}\n) {\n return useQuery({\n queryKey: [QK, 'compliance', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListComplianceChecks: PswComplianceCheck[] }>(\n `query PswCompliance($status: PswComplianceStatus, $pagination: PaginationInput) {\n pswListComplianceChecks(status: $status, pagination: $pagination) { ${COMPLIANCE_F} }\n }`,\n { status: args.status ?? null, pagination: args.pagination ?? { limit: 100 } }\n );\n return data.pswListComplianceChecks;\n },\n });\n}\nexport function useCreateComplianceCheck() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateCompliance($input: PswCreateComplianceCheckInput!) { pswCreateComplianceCheck(input: $input) { ${COMPLIANCE_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'compliance', 'dashboard'),\n });\n}\nexport function useResolveComplianceCheck() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; status: PswComplianceStatus; details?: string }) =>\n pswQuery(\n `mutation PswResolveCompliance($id: ID!, $status: PswComplianceStatus!, $details: String) { pswResolveComplianceCheck(id: $id, status: $status, details: $details) { ${COMPLIANCE_F} } }`,\n vars\n ),\n onSuccess: () => invalidate(qc, 'compliance', 'dashboard'),\n });\n}\n\n// ============================================================================\n// Conflict checks\n// ============================================================================\n\nexport function useConflictChecks(args: { clientId?: string; pagination?: PswPagination } = {}) {\n return useQuery({\n queryKey: [QK, 'conflicts', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListConflictChecks: PswConflictCheck[] }>(\n `query PswConflicts($clientId: ID, $pagination: PaginationInput) {\n pswListConflictChecks(clientId: $clientId, pagination: $pagination) { ${CONFLICT_F} }\n }`,\n { clientId: args.clientId ?? null, pagination: args.pagination ?? { limit: 100 } }\n );\n return data.pswListConflictChecks;\n },\n });\n}\nexport function useCreateConflictCheck() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateConflict($input: PswCreateConflictCheckInput!) { pswCreateConflictCheck(input: $input) { ${CONFLICT_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'conflicts', 'dashboard'),\n });\n}\nexport function useResolveConflictCheck() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: {\n id: string;\n status: PswConflictCheckStatus;\n findings?: string;\n waiverReason?: string;\n }) =>\n pswQuery(\n `mutation PswResolveConflict($id: ID!, $status: PswConflictCheckStatus!, $findings: String, $waiverReason: String) {\n pswResolveConflictCheck(id: $id, status: $status, findings: $findings, waiverReason: $waiverReason) { ${CONFLICT_F} }\n }`,\n vars\n ),\n onSuccess: () => invalidate(qc, 'conflicts', 'dashboard'),\n });\n}\n\n// ============================================================================\n// Practice areas\n// ============================================================================\n\nexport function usePracticeAreas() {\n return useQuery({\n queryKey: [QK, 'practiceAreas'],\n queryFn: async () => {\n const data = await pswQuery<{ pswListPracticeAreas: PswPracticeArea[] }>(\n `query PswPracticeAreas { pswListPracticeAreas(pagination: { limit: 100 }) { ${PRACTICE_AREA_F} } }`\n );\n return data.pswListPracticeAreas;\n },\n });\n}\nexport function useCreatePracticeArea() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreatePracticeArea($input: PswCreatePracticeAreaInput!) { pswCreatePracticeArea(input: $input) { ${PRACTICE_AREA_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'practiceAreas'),\n });\n}\nexport function useUpdatePracticeArea() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; input: Record<string, unknown> }) =>\n pswQuery(\n `mutation PswUpdatePracticeArea($id: ID!, $input: PswUpdatePracticeAreaInput!) { pswUpdatePracticeArea(id: $id, input: $input) { ${PRACTICE_AREA_F} } }`,\n vars\n ),\n onSuccess: () => invalidate(qc, 'practiceAreas'),\n });\n}\n\n// ============================================================================\n// Documents (metadata over wspace-files-svc)\n// ============================================================================\n\nexport function useDocuments(\n args: {\n engagementId?: string;\n matterId?: string;\n classification?: PswDocumentClassification;\n status?: PswDocumentStatus;\n pagination?: PswPagination;\n } = {}\n) {\n return useQuery({\n queryKey: [QK, 'documents', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListDocuments: PswConnection<PswDocument> }>(\n `query PswDocuments($engagementId: ID, $matterId: ID, $classification: PswDocumentClassification, $status: PswDocumentStatus, $pagination: PaginationInput) {\n pswListDocuments(engagementId: $engagementId, matterId: $matterId, classification: $classification, status: $status, pagination: $pagination) {\n items { ${DOCUMENT_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n engagementId: args.engagementId ?? null,\n matterId: args.matterId ?? null,\n classification: args.classification ?? null,\n status: args.status ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListDocuments;\n },\n });\n}\nexport function useCreateDocument() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateDocument($input: PswCreateDocumentInput!) { pswCreateDocument(input: $input) { ${DOCUMENT_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'documents'),\n });\n}\nexport function useArchiveDocument() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(\n `mutation PswArchiveDocument($id: ID!) { pswArchiveDocument(id: $id) { ${DOCUMENT_F} } }`,\n { id }\n ),\n onSuccess: () => invalidate(qc, 'documents'),\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useProServiceWorldApi.js","names":[],"sources":["../../../src/proserviceworld/hooks/useProServiceWorldApi.ts"],"sourcesContent":["/**\n * ProServiceWorld API hooks\n * @module proserviceworld/hooks\n *\n * Real data layer for the ProServiceWorld workspace subgraph (`proserviceworld`\n * Hive service / `wspace-proserviceworld-svc`). Every hook talks to the live\n * workspace GraphQL gateway via {@link graphqlFetch} with inline operations\n * whose fields mirror `.hive-schema.graphql` exactly. No mocks.\n *\n * Conventions (mirror microfe-hookmovies / microfe-collabkin):\n * - `pswQuery` wraps graphqlFetch({ gateway: 'workspace', workspaceToken: true })\n * and throws on GraphQL errors / missing data.\n * - One react-query `useQuery` per read op and `useMutation` per write op.\n * - Strict hand-written result interfaces — no `any`.\n * - Lists paginate by offset (the workspaces gateway strips the cursor arg);\n * `*Connection { items, pageInfo { hasMore cursor }, totalCount }` verbatim.\n * - After any successful mutation we clear fe-libs' short-lived graphqlFetch\n * read cache so the very next refetch is fresh (fleet stale-read fix).\n */\n\nimport { useMutation, useQuery, useQueryClient, type QueryClient } from '@tanstack/react-query';\n\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\n// ============================================================================\n// Low-level runner\n// ============================================================================\n\nasync function pswQuery<TData>(\n query: string,\n variables: Record<string, unknown> = {}\n): Promise<TData> {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'GraphQL request failed');\n }\n if (!response.data) {\n throw new Error('GraphQL response did not include data');\n }\n if (query.trimStart().startsWith('mutation')) {\n clearGraphqlFetchResponseCache();\n }\n return response.data;\n}\n\nconst QK = 'proserviceworld' as const;\n\n/** Invalidate a set of top-level query keys after a write. */\nfunction invalidate(qc: QueryClient, ...keys: string[]): void {\n for (const key of keys) void qc.invalidateQueries({ queryKey: [QK, key] });\n}\n\n// ============================================================================\n// Shared types (mirror .hive-schema.graphql)\n// ============================================================================\n\nexport interface PswPagination {\n limit?: number;\n offset?: number;\n}\nexport interface PswPageInfo {\n hasMore: boolean;\n cursor: string | null;\n}\nexport interface PswConnection<T> {\n items: T[];\n pageInfo: PswPageInfo;\n totalCount: number;\n}\n\nexport type PswClientType = 'INDIVIDUAL' | 'ORGANIZATION';\nexport type PswClientStatus = 'PROSPECT' | 'ACTIVE' | 'INACTIVE' | 'ARCHIVED';\nexport type PswFeeArrangement = 'FIXED' | 'HOURLY' | 'RETAINER' | 'VALUE_BASED';\nexport type PswEngagementStatus =\n | 'PROPOSAL'\n | 'ACCEPTED'\n | 'IN_PROGRESS'\n | 'REVIEW'\n | 'DELIVERED'\n | 'INVOICED'\n | 'CLOSED'\n | 'CANCELLED';\nexport type PswMatterStatus = 'OPEN' | 'ON_HOLD' | 'CLOSED' | 'ARCHIVED';\nexport type PswMatterPriority = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';\nexport type PswDeliverableStatus =\n | 'DRAFT'\n | 'INTERNAL_REVIEW'\n | 'CLIENT_REVIEW'\n | 'ACCEPTED'\n | 'REJECTED';\nexport type PswMilestoneStatus = 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'CANCELLED';\nexport type PswDocumentStatus = 'DRAFT' | 'FINAL' | 'ARCHIVED';\nexport type PswDocumentClassification = 'PUBLIC' | 'INTERNAL' | 'CONFIDENTIAL' | 'PRIVILEGED';\nexport type PswTimeEntryStatus = 'DRAFT' | 'SUBMITTED' | 'APPROVED' | 'REJECTED' | 'BILLED';\nexport type PswInvoiceStatus = 'DRAFT' | 'SENT' | 'PAID' | 'OVERDUE' | 'CANCELLED';\nexport type PswComplianceType =\n | 'ENGAGEMENT_ACCEPTANCE'\n | 'INDEPENDENCE'\n | 'LICENSING'\n | 'CONTINUING_EDUCATION'\n | 'DATA_RETENTION'\n | 'LEGAL_HOLD';\nexport type PswComplianceStatus = 'PENDING' | 'IN_REVIEW' | 'PASSED' | 'FAILED' | 'WAIVED';\nexport type PswConflictCheckStatus =\n | 'PENDING'\n | 'CLEAR'\n | 'POTENTIAL_CONFLICT'\n | 'CONFLICT'\n | 'WAIVED';\nexport type PswTeamRole = 'PARTNER' | 'MANAGER' | 'ASSOCIATE' | 'SPECIALIST' | 'SUPPORT';\n\nexport interface PswClient {\n id: string;\n name: string;\n type: PswClientType;\n status: PswClientStatus;\n industry: string | null;\n contactName: string | null;\n contactEmail: string | null;\n contactPhone: string | null;\n address: string | null;\n relationshipOwnerId: string | null;\n notes: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\nexport interface PswClientDetail extends PswClient {\n engagements: PswEngagement[];\n matters: PswMatter[];\n}\nexport interface PswEngagement {\n id: string;\n clientId: string;\n practiceAreaId: string | null;\n name: string;\n description: string | null;\n status: PswEngagementStatus;\n feeArrangement: PswFeeArrangement;\n feeAmount: number;\n currency: string;\n startDate: string | null;\n endDate: string | null;\n responsiblePartnerId: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n client?: { id: string; name: string } | null;\n}\nexport interface PswDeliverable {\n id: string;\n engagementId: string;\n name: string;\n description: string | null;\n status: PswDeliverableStatus;\n version: number;\n acceptanceCriteria: string | null;\n dueDate: string | null;\n acceptedAt: string | null;\n createdAt: string;\n}\nexport interface PswMilestone {\n id: string;\n engagementId: string;\n name: string;\n description: string | null;\n status: PswMilestoneStatus;\n dueDate: string | null;\n completedAt: string | null;\n triggerAmount: number;\n triggersInvoice: boolean;\n createdAt: string;\n}\nexport interface PswEngagementDetail extends PswEngagement {\n deliverables: PswDeliverable[];\n milestones: PswMilestone[];\n}\nexport interface PswMatter {\n id: string;\n clientId: string;\n engagementId: string | null;\n practiceAreaId: string | null;\n reference: string | null;\n title: string;\n description: string | null;\n status: PswMatterStatus;\n priority: PswMatterPriority;\n isPrivileged: boolean;\n dueDate: string | null;\n closedAt: string | null;\n leadPractitionerId: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n client?: { id: string; name: string } | null;\n}\nexport interface PswTimeEntry {\n id: string;\n engagementId: string | null;\n matterId: string | null;\n practitionerId: string;\n date: string;\n minutes: number;\n billable: boolean;\n rate: number;\n narrative: string | null;\n status: PswTimeEntryStatus;\n invoiceId: string | null;\n createdAt: string;\n}\nexport interface PswInvoice {\n id: string;\n clientId: string;\n engagementId: string | null;\n number: string;\n status: PswInvoiceStatus;\n currency: string;\n subtotal: number;\n taxAmount: number;\n total: number;\n issueDate: string | null;\n dueDate: string | null;\n paidAt: string | null;\n notes: string | null;\n createdAt: string;\n}\nexport interface PswComplianceCheck {\n id: string;\n type: PswComplianceType;\n status: PswComplianceStatus;\n subjectType: string;\n subjectId: string;\n title: string;\n details: string | null;\n reviewerId: string | null;\n dueDate: string | null;\n resolvedAt: string | null;\n createdAt: string;\n}\nexport interface PswConflictCheck {\n id: string;\n clientId: string;\n matterId: string | null;\n status: PswConflictCheckStatus;\n searchedParties: string[];\n findings: string | null;\n waiverReason: string | null;\n resolvedAt: string | null;\n createdAt: string;\n}\nexport interface PswPracticeArea {\n id: string;\n name: string;\n code: string | null;\n description: string | null;\n isActive: boolean;\n createdAt: string;\n}\nexport interface PswDocument {\n id: string;\n name: string;\n description: string | null;\n status: PswDocumentStatus;\n classification: PswDocumentClassification;\n version: number;\n legalHold: boolean;\n retainUntil: string | null;\n matterId: string | null;\n engagementId: string | null;\n tags: string[];\n file: { id: string } | null;\n createdAt: string;\n}\nexport interface PswStatusCount {\n status: string;\n count: number;\n}\nexport interface PswMonthlyAmount {\n month: string;\n amount: number;\n}\nexport interface PswDashboardStats {\n totalClients: number;\n activeClients: number;\n activeEngagements: number;\n openMatters: number;\n outstandingInvoiceTotal: number;\n paidInvoiceTotal: number;\n unbilledHours: number;\n billedHours: number;\n pendingComplianceChecks: number;\n openConflictChecks: number;\n engagementsByStatus: PswStatusCount[];\n invoicesByStatus: PswStatusCount[];\n mattersByStatus: PswStatusCount[];\n revenueByMonth: PswMonthlyAmount[];\n}\n\n// ============================================================================\n// GraphQL fragments\n// ============================================================================\n\nconst CLIENT_F = `\n id name type status industry contactName contactEmail contactPhone address\n relationshipOwnerId notes tags createdAt updatedAt`;\nconst ENGAGEMENT_F = `\n id clientId practiceAreaId name description status feeArrangement feeAmount currency\n startDate endDate responsiblePartnerId tags createdAt updatedAt client { id name }`;\nconst DELIVERABLE_F = `id engagementId name description status version acceptanceCriteria dueDate acceptedAt createdAt`;\nconst MILESTONE_F = `id engagementId name description status dueDate completedAt triggerAmount triggersInvoice createdAt`;\nconst MATTER_F = `\n id clientId engagementId practiceAreaId reference title description status priority isPrivileged\n dueDate closedAt leadPractitionerId tags createdAt updatedAt client { id name }`;\nconst TIME_F = `id engagementId matterId practitionerId date minutes billable rate narrative status invoiceId createdAt`;\nconst INVOICE_F = `id clientId engagementId number status currency subtotal taxAmount total issueDate dueDate paidAt notes createdAt`;\nconst COMPLIANCE_F = `id type status subjectType subjectId title details reviewerId dueDate resolvedAt createdAt`;\nconst CONFLICT_F = `id clientId matterId status searchedParties findings waiverReason resolvedAt createdAt`;\nconst PRACTICE_AREA_F = `id name code description isActive createdAt`;\nconst DOCUMENT_F = `id name description status classification version legalHold retainUntil matterId engagementId tags file { id } createdAt`;\n\n// ============================================================================\n// Dashboard\n// ============================================================================\n\nexport function useDashboardStats() {\n return useQuery({\n queryKey: [QK, 'dashboard'],\n queryFn: async () => {\n const data = await pswQuery<{ pswDashboardStats: PswDashboardStats }>(`\n query PswDashboard {\n pswDashboardStats {\n totalClients activeClients activeEngagements openMatters\n outstandingInvoiceTotal paidInvoiceTotal unbilledHours billedHours\n pendingComplianceChecks openConflictChecks\n engagementsByStatus { status count }\n invoicesByStatus { status count }\n mattersByStatus { status count }\n revenueByMonth { month amount }\n }\n }`);\n return data.pswDashboardStats;\n },\n });\n}\n\n// ============================================================================\n// Clients\n// ============================================================================\n\nexport function useClients(\n args: { status?: PswClientStatus; search?: string; pagination?: PswPagination } = {}\n) {\n return useQuery({\n queryKey: [QK, 'clients', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListClients: PswConnection<PswClient> }>(\n `query PswClients($status: PswClientStatus, $search: String, $pagination: PaginationInput) {\n pswListClients(status: $status, search: $search, pagination: $pagination) {\n items { ${CLIENT_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n status: args.status ?? null,\n search: args.search ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListClients;\n },\n });\n}\n\nexport function useClient(id: string | null) {\n return useQuery({\n queryKey: [QK, 'client', id],\n enabled: Boolean(id),\n queryFn: async () => {\n const data = await pswQuery<{ pswClient: PswClientDetail | null }>(\n `query PswClient($id: ID!) {\n pswClient(id: $id) {\n ${CLIENT_F}\n engagements { ${ENGAGEMENT_F} }\n matters { ${MATTER_F} }\n }\n }`,\n { id }\n );\n return data.pswClient;\n },\n });\n}\n\nexport function useCreateClient() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery<{ pswCreateClient: PswClient }>(\n `mutation PswCreateClient($input: PswCreateClientInput!) { pswCreateClient(input: $input) { ${CLIENT_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'clients', 'dashboard'),\n });\n}\nexport function useUpdateClient() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; input: Record<string, unknown> }) =>\n pswQuery(\n `mutation PswUpdateClient($id: ID!, $input: PswUpdateClientInput!) { pswUpdateClient(id: $id, input: $input) { ${CLIENT_F} } }`,\n vars\n ),\n onSuccess: (_d, v) => {\n invalidate(qc, 'clients', 'dashboard');\n void qc.invalidateQueries({ queryKey: [QK, 'client', v.id] });\n },\n });\n}\nexport function useArchiveClient() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(`mutation PswArchiveClient($id: ID!) { pswArchiveClient(id: $id) }`, { id }),\n onSuccess: () => invalidate(qc, 'clients', 'dashboard'),\n });\n}\n\n// ============================================================================\n// Engagements\n// ============================================================================\n\nexport function useEngagements(\n args: {\n clientId?: string;\n status?: PswEngagementStatus;\n search?: string;\n pagination?: PswPagination;\n } = {}\n) {\n return useQuery({\n queryKey: [QK, 'engagements', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListEngagements: PswConnection<PswEngagement> }>(\n `query PswEngagements($clientId: ID, $status: PswEngagementStatus, $search: String, $pagination: PaginationInput) {\n pswListEngagements(clientId: $clientId, status: $status, search: $search, pagination: $pagination) {\n items { ${ENGAGEMENT_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n clientId: args.clientId ?? null,\n status: args.status ?? null,\n search: args.search ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListEngagements;\n },\n });\n}\n\nexport function useEngagement(id: string | null) {\n return useQuery({\n queryKey: [QK, 'engagement', id],\n enabled: Boolean(id),\n queryFn: async () => {\n const data = await pswQuery<{ pswEngagement: PswEngagementDetail | null }>(\n `query PswEngagement($id: ID!) {\n pswEngagement(id: $id) {\n ${ENGAGEMENT_F}\n deliverables { ${DELIVERABLE_F} }\n milestones { ${MILESTONE_F} }\n }\n }`,\n { id }\n );\n return data.pswEngagement;\n },\n });\n}\n\nexport function useCreateEngagement() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateEngagement($input: PswCreateEngagementInput!) { pswCreateEngagement(input: $input) { ${ENGAGEMENT_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'engagements', 'dashboard'),\n });\n}\nexport function useUpdateEngagement() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; input: Record<string, unknown> }) =>\n pswQuery(\n `mutation PswUpdateEngagement($id: ID!, $input: PswUpdateEngagementInput!) { pswUpdateEngagement(id: $id, input: $input) { ${ENGAGEMENT_F} } }`,\n vars\n ),\n onSuccess: (_d, v) => {\n invalidate(qc, 'engagements');\n void qc.invalidateQueries({ queryKey: [QK, 'engagement', v.id] });\n },\n });\n}\nexport function useTransitionEngagement() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; status: PswEngagementStatus }) =>\n pswQuery(\n `mutation PswTransitionEngagement($id: ID!, $status: PswEngagementStatus!) { pswTransitionEngagement(id: $id, status: $status) { ${ENGAGEMENT_F} } }`,\n vars\n ),\n onSuccess: (_d, v) => {\n invalidate(qc, 'engagements', 'dashboard');\n void qc.invalidateQueries({ queryKey: [QK, 'engagement', v.id] });\n },\n });\n}\n\n// ============================================================================\n// Deliverables & Milestones (engagement delivery)\n// ============================================================================\n\nexport function useCreateDeliverable() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateDeliverable($input: PswCreateDeliverableInput!) { pswCreateDeliverable(input: $input) { ${DELIVERABLE_F} } }`,\n { input }\n ),\n onSuccess: (_d, input) =>\n qc.invalidateQueries({\n queryKey: [QK, 'engagement', (input as { engagementId: string }).engagementId],\n }),\n });\n}\nexport function useTransitionDeliverable() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; status: PswDeliverableStatus; engagementId: string }) =>\n pswQuery(\n `mutation PswTransitionDeliverable($id: ID!, $status: PswDeliverableStatus!) { pswTransitionDeliverable(id: $id, status: $status) { ${DELIVERABLE_F} } }`,\n {\n id: vars.id,\n status: vars.status,\n }\n ),\n onSuccess: (_d, v) => qc.invalidateQueries({ queryKey: [QK, 'engagement', v.engagementId] }),\n });\n}\nexport function useCreateMilestone() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateMilestone($input: PswCreateMilestoneInput!) { pswCreateMilestone(input: $input) { ${MILESTONE_F} } }`,\n { input }\n ),\n onSuccess: (_d, input) =>\n qc.invalidateQueries({\n queryKey: [QK, 'engagement', (input as { engagementId: string }).engagementId],\n }),\n });\n}\nexport function useCompleteMilestone() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; engagementId: string }) =>\n pswQuery(\n `mutation PswCompleteMilestone($id: ID!) { pswCompleteMilestone(id: $id) { ${MILESTONE_F} } }`,\n { id: vars.id }\n ),\n onSuccess: (_d, v) => qc.invalidateQueries({ queryKey: [QK, 'engagement', v.engagementId] }),\n });\n}\n\n// ============================================================================\n// Matters\n// ============================================================================\n\nexport function useMatters(\n args: {\n clientId?: string;\n engagementId?: string;\n status?: PswMatterStatus;\n search?: string;\n pagination?: PswPagination;\n } = {}\n) {\n return useQuery({\n queryKey: [QK, 'matters', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListMatters: PswConnection<PswMatter> }>(\n `query PswMatters($clientId: ID, $engagementId: ID, $status: PswMatterStatus, $search: String, $pagination: PaginationInput) {\n pswListMatters(clientId: $clientId, engagementId: $engagementId, status: $status, search: $search, pagination: $pagination) {\n items { ${MATTER_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n clientId: args.clientId ?? null,\n engagementId: args.engagementId ?? null,\n status: args.status ?? null,\n search: args.search ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListMatters;\n },\n });\n}\nexport function useCreateMatter() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateMatter($input: PswCreateMatterInput!) { pswCreateMatter(input: $input) { ${MATTER_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'matters', 'dashboard'),\n });\n}\nexport function useUpdateMatter() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; input: Record<string, unknown> }) =>\n pswQuery(\n `mutation PswUpdateMatter($id: ID!, $input: PswUpdateMatterInput!) { pswUpdateMatter(id: $id, input: $input) { ${MATTER_F} } }`,\n vars\n ),\n onSuccess: () => invalidate(qc, 'matters'),\n });\n}\nexport function useCloseMatter() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(`mutation PswCloseMatter($id: ID!) { pswCloseMatter(id: $id) { ${MATTER_F} } }`, {\n id,\n }),\n onSuccess: () => invalidate(qc, 'matters', 'dashboard'),\n });\n}\n\n// ============================================================================\n// Time entries\n// ============================================================================\n\nexport function useTimeEntries(\n args: {\n engagementId?: string;\n matterId?: string;\n status?: PswTimeEntryStatus;\n billable?: boolean;\n pagination?: PswPagination;\n } = {}\n) {\n return useQuery({\n queryKey: [QK, 'time', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListTimeEntries: PswConnection<PswTimeEntry> }>(\n `query PswTimeEntries($engagementId: ID, $matterId: ID, $status: PswTimeEntryStatus, $billable: Boolean, $pagination: PaginationInput) {\n pswListTimeEntries(engagementId: $engagementId, matterId: $matterId, status: $status, billable: $billable, pagination: $pagination) {\n items { ${TIME_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n engagementId: args.engagementId ?? null,\n matterId: args.matterId ?? null,\n status: args.status ?? null,\n billable: args.billable ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListTimeEntries;\n },\n });\n}\nexport function useLogTimeEntry() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswLogTime($input: PswCreateTimeEntryInput!) { pswLogTimeEntry(input: $input) { ${TIME_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'time', 'dashboard'),\n });\n}\nexport function useSubmitTimeEntry() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(`mutation PswSubmitTime($id: ID!) { pswSubmitTimeEntry(id: $id) { ${TIME_F} } }`, {\n id,\n }),\n onSuccess: () => invalidate(qc, 'time'),\n });\n}\nexport function useApproveTimeEntry() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(`mutation PswApproveTime($id: ID!) { pswApproveTimeEntry(id: $id) { ${TIME_F} } }`, {\n id,\n }),\n onSuccess: () => invalidate(qc, 'time'),\n });\n}\n\n// ============================================================================\n// Invoices\n// ============================================================================\n\nexport function useInvoices(\n args: { clientId?: string; status?: PswInvoiceStatus; pagination?: PswPagination } = {}\n) {\n return useQuery({\n queryKey: [QK, 'invoices', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListInvoices: PswConnection<PswInvoice> }>(\n `query PswInvoices($clientId: ID, $status: PswInvoiceStatus, $pagination: PaginationInput) {\n pswListInvoices(clientId: $clientId, status: $status, pagination: $pagination) {\n items { ${INVOICE_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n clientId: args.clientId ?? null,\n status: args.status ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListInvoices;\n },\n });\n}\nexport function useCreateInvoice() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateInvoice($input: PswCreateInvoiceInput!) { pswCreateInvoice(input: $input) { ${INVOICE_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'invoices', 'dashboard'),\n });\n}\nexport function useMarkInvoicePaid() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(`mutation PswMarkPaid($id: ID!) { pswMarkInvoicePaid(id: $id) { ${INVOICE_F} } }`, {\n id,\n }),\n onSuccess: () => invalidate(qc, 'invoices', 'dashboard'),\n });\n}\n\n// ============================================================================\n// Compliance\n// ============================================================================\n\nexport function useComplianceChecks(\n args: { status?: PswComplianceStatus; pagination?: PswPagination } = {}\n) {\n return useQuery({\n queryKey: [QK, 'compliance', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListComplianceChecks: PswComplianceCheck[] }>(\n `query PswCompliance($status: PswComplianceStatus, $pagination: PaginationInput) {\n pswListComplianceChecks(status: $status, pagination: $pagination) { ${COMPLIANCE_F} }\n }`,\n { status: args.status ?? null, pagination: args.pagination ?? { limit: 100 } }\n );\n return data.pswListComplianceChecks;\n },\n });\n}\nexport function useCreateComplianceCheck() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateCompliance($input: PswCreateComplianceCheckInput!) { pswCreateComplianceCheck(input: $input) { ${COMPLIANCE_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'compliance', 'dashboard'),\n });\n}\nexport function useResolveComplianceCheck() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; status: PswComplianceStatus; details?: string }) =>\n pswQuery(\n `mutation PswResolveCompliance($id: ID!, $status: PswComplianceStatus!, $details: String) { pswResolveComplianceCheck(id: $id, status: $status, details: $details) { ${COMPLIANCE_F} } }`,\n vars\n ),\n onSuccess: () => invalidate(qc, 'compliance', 'dashboard'),\n });\n}\n\n// ============================================================================\n// Conflict checks\n// ============================================================================\n\nexport function useConflictChecks(args: { clientId?: string; pagination?: PswPagination } = {}) {\n return useQuery({\n queryKey: [QK, 'conflicts', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListConflictChecks: PswConflictCheck[] }>(\n `query PswConflicts($clientId: ID, $pagination: PaginationInput) {\n pswListConflictChecks(clientId: $clientId, pagination: $pagination) { ${CONFLICT_F} }\n }`,\n { clientId: args.clientId ?? null, pagination: args.pagination ?? { limit: 100 } }\n );\n return data.pswListConflictChecks;\n },\n });\n}\nexport function useCreateConflictCheck() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateConflict($input: PswCreateConflictCheckInput!) { pswCreateConflictCheck(input: $input) { ${CONFLICT_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'conflicts', 'dashboard'),\n });\n}\nexport function useResolveConflictCheck() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: {\n id: string;\n status: PswConflictCheckStatus;\n findings?: string;\n waiverReason?: string;\n }) =>\n pswQuery(\n `mutation PswResolveConflict($id: ID!, $status: PswConflictCheckStatus!, $findings: String, $waiverReason: String) {\n pswResolveConflictCheck(id: $id, status: $status, findings: $findings, waiverReason: $waiverReason) { ${CONFLICT_F} }\n }`,\n vars\n ),\n onSuccess: () => invalidate(qc, 'conflicts', 'dashboard'),\n });\n}\n\n// ============================================================================\n// Practice areas\n// ============================================================================\n\nexport function usePracticeAreas() {\n return useQuery({\n queryKey: [QK, 'practiceAreas'],\n queryFn: async () => {\n const data = await pswQuery<{ pswListPracticeAreas: PswPracticeArea[] }>(\n `query PswPracticeAreas { pswListPracticeAreas(pagination: { limit: 100 }) { ${PRACTICE_AREA_F} } }`\n );\n return data.pswListPracticeAreas;\n },\n });\n}\nexport function useCreatePracticeArea() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreatePracticeArea($input: PswCreatePracticeAreaInput!) { pswCreatePracticeArea(input: $input) { ${PRACTICE_AREA_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'practiceAreas'),\n });\n}\nexport function useUpdatePracticeArea() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; input: Record<string, unknown> }) =>\n pswQuery(\n `mutation PswUpdatePracticeArea($id: ID!, $input: PswUpdatePracticeAreaInput!) { pswUpdatePracticeArea(id: $id, input: $input) { ${PRACTICE_AREA_F} } }`,\n vars\n ),\n onSuccess: () => invalidate(qc, 'practiceAreas'),\n });\n}\n\n// ============================================================================\n// Documents (metadata over wspace-files-svc)\n// ============================================================================\n\nexport function useDocuments(\n args: {\n engagementId?: string;\n matterId?: string;\n classification?: PswDocumentClassification;\n status?: PswDocumentStatus;\n pagination?: PswPagination;\n } = {}\n) {\n return useQuery({\n queryKey: [QK, 'documents', args],\n queryFn: async () => {\n const data = await pswQuery<{ pswListDocuments: PswConnection<PswDocument> }>(\n `query PswDocuments($engagementId: ID, $matterId: ID, $classification: PswDocumentClassification, $status: PswDocumentStatus, $pagination: PaginationInput) {\n pswListDocuments(engagementId: $engagementId, matterId: $matterId, classification: $classification, status: $status, pagination: $pagination) {\n items { ${DOCUMENT_F} } pageInfo { hasMore cursor } totalCount\n }\n }`,\n {\n engagementId: args.engagementId ?? null,\n matterId: args.matterId ?? null,\n classification: args.classification ?? null,\n status: args.status ?? null,\n pagination: args.pagination ?? { limit: 100 },\n }\n );\n return data.pswListDocuments;\n },\n });\n}\nexport function useCreateDocument() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (input: Record<string, unknown>) =>\n pswQuery(\n `mutation PswCreateDocument($input: PswCreateDocumentInput!) { pswCreateDocument(input: $input) { ${DOCUMENT_F} } }`,\n { input }\n ),\n onSuccess: () => invalidate(qc, 'documents'),\n });\n}\nexport function useArchiveDocument() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n pswQuery(\n `mutation PswArchiveDocument($id: ID!) { pswArchiveDocument(id: $id) { ${DOCUMENT_F} } }`,\n { id }\n ),\n onSuccess: () => invalidate(qc, 'documents'),\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProServiceWorld MFE local i18n.
|
|
3
|
+
*
|
|
4
|
+
* The host app shell owns the global I18nProvider and product translations.
|
|
5
|
+
* This lightweight module provides fallback translations for MFE-owned UI
|
|
6
|
+
* strings (page titles, empty states, form labels) so the MFE can be mounted
|
|
7
|
+
* standalone (dev harness, tests) and still render in all supported locales.
|
|
8
|
+
* When running inside the shell, the shell's `useI18n` translations take
|
|
9
|
+
* precedence via the `t` helper below.
|
|
10
|
+
*/
|
|
11
|
+
export type SupportedLocale = 'en' | 'es' | 'hi' | 'ta' | 'zh' | 'ar';
|
|
12
|
+
export declare function t(key: string, fallback?: string, locale?: SupportedLocale): string;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/i18n/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AA4KtE,wBAAgB,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,CAGlF"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
//#region src/proserviceworld/i18n/index.ts
|
|
2
|
+
var e = {
|
|
3
|
+
en: {
|
|
4
|
+
"psw.clients.title": "Clients",
|
|
5
|
+
"psw.clients.subtitle": "Every person or organization your firm serves.",
|
|
6
|
+
"psw.clients.emptyTitle": "No clients yet",
|
|
7
|
+
"psw.clients.emptyDescription": "Add your first client to start scoping engagements and matters.",
|
|
8
|
+
"psw.clients.new": "New client",
|
|
9
|
+
"psw.clients.searchPlaceholder": "Search clients…",
|
|
10
|
+
"psw.clients.allStatuses": "All statuses",
|
|
11
|
+
"psw.common.loading": "Loading…",
|
|
12
|
+
"psw.common.retry": "Retry",
|
|
13
|
+
"psw.common.cancel": "Cancel",
|
|
14
|
+
"psw.common.save": "Save",
|
|
15
|
+
"psw.common.create": "Create",
|
|
16
|
+
"psw.common.edit": "Edit",
|
|
17
|
+
"psw.common.archive": "Archive",
|
|
18
|
+
"psw.common.actions": "Actions",
|
|
19
|
+
"psw.common.name": "Name",
|
|
20
|
+
"psw.common.status": "Status",
|
|
21
|
+
"psw.common.type": "Type",
|
|
22
|
+
"psw.common.added": "Added",
|
|
23
|
+
"psw.common.loadMore": "Load more",
|
|
24
|
+
"psw.common.showing": "Showing",
|
|
25
|
+
"psw.common.of": "of",
|
|
26
|
+
"psw.tags.title": "Tags",
|
|
27
|
+
"psw.tags.add": "Add tag"
|
|
28
|
+
},
|
|
29
|
+
es: {
|
|
30
|
+
"psw.clients.title": "Clientes",
|
|
31
|
+
"psw.clients.subtitle": "Toda persona u organización que atiende su firma.",
|
|
32
|
+
"psw.clients.emptyTitle": "Aún no hay clientes",
|
|
33
|
+
"psw.clients.emptyDescription": "Agregue su primer cliente para comenzar a definir compromisos y asuntos.",
|
|
34
|
+
"psw.clients.new": "Nuevo cliente",
|
|
35
|
+
"psw.clients.searchPlaceholder": "Buscar clientes…",
|
|
36
|
+
"psw.clients.allStatuses": "Todos los estados",
|
|
37
|
+
"psw.common.loading": "Cargando…",
|
|
38
|
+
"psw.common.retry": "Reintentar",
|
|
39
|
+
"psw.common.cancel": "Cancelar",
|
|
40
|
+
"psw.common.save": "Guardar",
|
|
41
|
+
"psw.common.create": "Crear",
|
|
42
|
+
"psw.common.edit": "Editar",
|
|
43
|
+
"psw.common.archive": "Archivar",
|
|
44
|
+
"psw.common.actions": "Acciones",
|
|
45
|
+
"psw.common.name": "Nombre",
|
|
46
|
+
"psw.common.status": "Estado",
|
|
47
|
+
"psw.common.type": "Tipo",
|
|
48
|
+
"psw.common.added": "Añadido",
|
|
49
|
+
"psw.common.loadMore": "Cargar más",
|
|
50
|
+
"psw.common.showing": "Mostrando",
|
|
51
|
+
"psw.common.of": "de",
|
|
52
|
+
"psw.tags.title": "Etiquetas",
|
|
53
|
+
"psw.tags.add": "Agregar etiqueta"
|
|
54
|
+
},
|
|
55
|
+
hi: {
|
|
56
|
+
"psw.clients.title": "ग्राहक",
|
|
57
|
+
"psw.clients.subtitle": "हर व्यक्ति या संगठन जिसे आपकी फर्म सेवा देती है।",
|
|
58
|
+
"psw.clients.emptyTitle": "अभी तक कोई ग्राहक नहीं",
|
|
59
|
+
"psw.clients.emptyDescription": "समझौते और मामलों का दायरा तय करना शुरू करने के लिए अपना पहला ग्राहक जोड़ें।",
|
|
60
|
+
"psw.clients.new": "नया ग्राहक",
|
|
61
|
+
"psw.clients.searchPlaceholder": "ग्राहक खोजें…",
|
|
62
|
+
"psw.clients.allStatuses": "सभी स्थिति",
|
|
63
|
+
"psw.common.loading": "लोड हो रहा है…",
|
|
64
|
+
"psw.common.retry": "पुनः प्रयास करें",
|
|
65
|
+
"psw.common.cancel": "रद्द करें",
|
|
66
|
+
"psw.common.save": "सहेजें",
|
|
67
|
+
"psw.common.create": "बनाएं",
|
|
68
|
+
"psw.common.edit": "संपादित करें",
|
|
69
|
+
"psw.common.archive": "संग्रहीत करें",
|
|
70
|
+
"psw.common.actions": "कार्रवाइयाँ",
|
|
71
|
+
"psw.common.name": "नाम",
|
|
72
|
+
"psw.common.status": "स्थिति",
|
|
73
|
+
"psw.common.type": "प्रकार",
|
|
74
|
+
"psw.common.added": "जोड़ा गया",
|
|
75
|
+
"psw.common.loadMore": "और लोड करें",
|
|
76
|
+
"psw.common.showing": "दिखा रहा है",
|
|
77
|
+
"psw.common.of": "में से",
|
|
78
|
+
"psw.tags.title": "टैग",
|
|
79
|
+
"psw.tags.add": "टैग जोड़ें"
|
|
80
|
+
},
|
|
81
|
+
ta: {
|
|
82
|
+
"psw.clients.title": "வாடிக்கையாளர்கள்",
|
|
83
|
+
"psw.clients.subtitle": "உங்கள் நிறுவனம் சேவை செய்யும் ஒவ்வொரு நபரும் அல்லது நிறுவனமும்.",
|
|
84
|
+
"psw.clients.emptyTitle": "இன்னும் வாடிக்கையாளர்கள் இல்லை",
|
|
85
|
+
"psw.clients.emptyDescription": "உறுதிமொழிகள் மற்றும் விவகாரங்களை வரையறுக்க முதல் வாடிக்கையாளரைச் சேர்க்கவும்.",
|
|
86
|
+
"psw.clients.new": "புதிய வாடிக்கையாளர்",
|
|
87
|
+
"psw.clients.searchPlaceholder": "வாடிக்கையாளர்களைத் தேடு…",
|
|
88
|
+
"psw.clients.allStatuses": "அனைத்து நிலைகள்",
|
|
89
|
+
"psw.common.loading": "ஏற்றுகிறது…",
|
|
90
|
+
"psw.common.retry": "மீண்டும் முயற்சி",
|
|
91
|
+
"psw.common.cancel": "ரத்து",
|
|
92
|
+
"psw.common.save": "சேமி",
|
|
93
|
+
"psw.common.create": "உருவாக்கு",
|
|
94
|
+
"psw.common.edit": "திருத்து",
|
|
95
|
+
"psw.common.archive": "காப்பகம்",
|
|
96
|
+
"psw.common.actions": "செயல்கள்",
|
|
97
|
+
"psw.common.name": "பெயர்",
|
|
98
|
+
"psw.common.status": "நிலை",
|
|
99
|
+
"psw.common.type": "வகை",
|
|
100
|
+
"psw.common.added": "சேர்க்கப்பட்டது",
|
|
101
|
+
"psw.common.loadMore": "மேலும் ஏற்று",
|
|
102
|
+
"psw.common.showing": "காட்டுகிறது",
|
|
103
|
+
"psw.common.of": "இல்",
|
|
104
|
+
"psw.tags.title": "குறிச்சொற்கள்",
|
|
105
|
+
"psw.tags.add": "குறிச்சொல் சேர்"
|
|
106
|
+
},
|
|
107
|
+
zh: {
|
|
108
|
+
"psw.clients.title": "客户",
|
|
109
|
+
"psw.clients.subtitle": "贵公司服务的每一个人或组织。",
|
|
110
|
+
"psw.clients.emptyTitle": "暂无客户",
|
|
111
|
+
"psw.clients.emptyDescription": "添加您的第一个客户,开始确定业务和事项范围。",
|
|
112
|
+
"psw.clients.new": "新建客户",
|
|
113
|
+
"psw.clients.searchPlaceholder": "搜索客户…",
|
|
114
|
+
"psw.clients.allStatuses": "全部状态",
|
|
115
|
+
"psw.common.loading": "加载中…",
|
|
116
|
+
"psw.common.retry": "重试",
|
|
117
|
+
"psw.common.cancel": "取消",
|
|
118
|
+
"psw.common.save": "保存",
|
|
119
|
+
"psw.common.create": "创建",
|
|
120
|
+
"psw.common.edit": "编辑",
|
|
121
|
+
"psw.common.archive": "归档",
|
|
122
|
+
"psw.common.actions": "操作",
|
|
123
|
+
"psw.common.name": "名称",
|
|
124
|
+
"psw.common.status": "状态",
|
|
125
|
+
"psw.common.type": "类型",
|
|
126
|
+
"psw.common.added": "添加时间",
|
|
127
|
+
"psw.common.loadMore": "加载更多",
|
|
128
|
+
"psw.common.showing": "显示",
|
|
129
|
+
"psw.common.of": "共",
|
|
130
|
+
"psw.tags.title": "标签",
|
|
131
|
+
"psw.tags.add": "添加标签"
|
|
132
|
+
},
|
|
133
|
+
ar: {
|
|
134
|
+
"psw.clients.title": "العملاء",
|
|
135
|
+
"psw.clients.subtitle": "كل شخص أو مؤسسة تخدمها شركتك.",
|
|
136
|
+
"psw.clients.emptyTitle": "لا يوجد عملاء بعد",
|
|
137
|
+
"psw.clients.emptyDescription": "أضف عميلك الأول لبدء تحديد نطاق الالتزامات والقضايا.",
|
|
138
|
+
"psw.clients.new": "عميل جديد",
|
|
139
|
+
"psw.clients.searchPlaceholder": "البحث في العملاء…",
|
|
140
|
+
"psw.clients.allStatuses": "جميع الحالات",
|
|
141
|
+
"psw.common.loading": "جارٍ التحميل…",
|
|
142
|
+
"psw.common.retry": "إعادة المحاولة",
|
|
143
|
+
"psw.common.cancel": "إلغاء",
|
|
144
|
+
"psw.common.save": "حفظ",
|
|
145
|
+
"psw.common.create": "إنشاء",
|
|
146
|
+
"psw.common.edit": "تعديل",
|
|
147
|
+
"psw.common.archive": "أرشفة",
|
|
148
|
+
"psw.common.actions": "إجراءات",
|
|
149
|
+
"psw.common.name": "الاسم",
|
|
150
|
+
"psw.common.status": "الحالة",
|
|
151
|
+
"psw.common.type": "النوع",
|
|
152
|
+
"psw.common.added": "تاريخ الإضافة",
|
|
153
|
+
"psw.common.loadMore": "تحميل المزيد",
|
|
154
|
+
"psw.common.showing": "عرض",
|
|
155
|
+
"psw.common.of": "من",
|
|
156
|
+
"psw.tags.title": "الوسوم",
|
|
157
|
+
"psw.tags.add": "إضافة وسم"
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
function t() {
|
|
161
|
+
if (typeof navigator > "u") return "en";
|
|
162
|
+
let t = (navigator.language ?? "en").split("-")[0].toLowerCase();
|
|
163
|
+
return t in e ? t : "en";
|
|
164
|
+
}
|
|
165
|
+
function n(n, r, i) {
|
|
166
|
+
return e[i ?? t()]?.[n] ?? e.en[n] ?? r ?? n;
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
169
|
+
export { n as t };
|
|
170
|
+
|
|
171
|
+
//# sourceMappingURL=index.js.map
|