@striae-org/striae 4.3.2 → 4.3.4
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/app/components/actions/case-import/orchestrator.ts +1 -1
- package/app/components/actions/case-manage.ts +50 -14
- package/app/components/audit/user-audit.module.css +49 -0
- package/app/components/audit/viewer/audit-entries-list.tsx +130 -48
- package/app/components/navbar/navbar.tsx +25 -12
- package/app/components/sidebar/case-import/case-import.tsx +56 -14
- package/app/components/sidebar/case-import/components/CasePreviewSection.tsx +7 -6
- package/app/components/sidebar/case-import/components/ConfirmationDialog.tsx +9 -5
- package/app/components/sidebar/cases/cases-modal.module.css +19 -0
- package/app/components/sidebar/cases/cases-modal.tsx +23 -8
- package/app/routes/striae/hooks/use-striae-reset-helpers.ts +102 -0
- package/app/routes/striae/striae.tsx +72 -74
- package/app/routes/striae/utils/case-export.ts +37 -0
- package/app/routes/striae/utils/open-case-helper.ts +18 -0
- package/app/services/audit/audit-console-logger.ts +1 -1
- package/app/services/audit/audit-export-csv.ts +1 -1
- package/app/services/audit/audit-export-signing.ts +2 -2
- package/app/services/audit/audit-export.service.ts +1 -1
- package/app/services/audit/audit-worker-client.ts +1 -1
- package/app/services/audit/audit.service.ts +5 -75
- package/app/services/audit/builders/audit-event-builders-case-file.ts +3 -0
- package/app/services/audit/index.ts +2 -2
- package/app/types/audit.ts +8 -7
- package/app/utils/data/case-filters.ts +1 -1
- package/app/utils/ui/case-messages.ts +69 -0
- package/app/utils/ui/index.ts +1 -0
- package/package.json +5 -5
- package/workers/audit-worker/wrangler.jsonc.example +1 -1
- package/workers/data-worker/wrangler.jsonc.example +1 -1
- package/workers/image-worker/wrangler.jsonc.example +1 -1
- package/workers/keys-worker/wrangler.jsonc.example +1 -1
- package/workers/pdf-worker/wrangler.jsonc.example +1 -1
- package/workers/user-worker/wrangler.jsonc.example +1 -1
- package/wrangler.toml.example +1 -1
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { useState, useEffect, useRef, useContext, useCallback } from 'react';
|
|
2
2
|
import { AuthContext } from '~/contexts/auth.context';
|
|
3
3
|
import { useOverlayDismiss } from '~/hooks/useOverlayDismiss';
|
|
4
|
+
import {
|
|
5
|
+
ARCHIVED_REGULAR_CASE_BLOCK_MESSAGE,
|
|
6
|
+
IMPORT_FILE_TYPE_NOT_ALLOWED,
|
|
7
|
+
IMPORT_FILE_TYPE_NOT_SUPPORTED,
|
|
8
|
+
DATA_INTEGRITY_BLOCKED_TAMPERING
|
|
9
|
+
} from '~/utils/ui';
|
|
4
10
|
import {
|
|
5
11
|
listReadOnlyCases,
|
|
6
12
|
deleteReadOnlyCase
|
|
@@ -63,13 +69,13 @@ export const CaseImport = ({
|
|
|
63
69
|
});
|
|
64
70
|
|
|
65
71
|
const [existingReadOnlyCase, setExistingReadOnlyCase] = useState<string | null>(null);
|
|
66
|
-
const [
|
|
72
|
+
const [isArchivedRegularCaseImportBlocked, setIsArchivedRegularCaseImportBlocked] = useState(false);
|
|
67
73
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
68
74
|
|
|
69
75
|
// Clear import selection state (used by preview hook on validation failure)
|
|
70
76
|
const clearImportSelection = useCallback(() => {
|
|
71
77
|
updateImportState({ selectedFile: null, importType: null });
|
|
72
|
-
|
|
78
|
+
setIsArchivedRegularCaseImportBlocked(false);
|
|
73
79
|
resetFileInput(fileInputRef);
|
|
74
80
|
}, [updateImportState]);
|
|
75
81
|
|
|
@@ -203,14 +209,14 @@ export const CaseImport = ({
|
|
|
203
209
|
clearMessages();
|
|
204
210
|
|
|
205
211
|
if (!isValidImportFile(file)) {
|
|
206
|
-
setError(
|
|
212
|
+
setError(IMPORT_FILE_TYPE_NOT_ALLOWED);
|
|
207
213
|
clearImportData();
|
|
208
214
|
return;
|
|
209
215
|
}
|
|
210
216
|
|
|
211
217
|
const importType = await resolveImportType(file);
|
|
212
218
|
if (!importType) {
|
|
213
|
-
setError(
|
|
219
|
+
setError(IMPORT_FILE_TYPE_NOT_SUPPORTED);
|
|
214
220
|
clearImportData();
|
|
215
221
|
return;
|
|
216
222
|
}
|
|
@@ -232,6 +238,11 @@ export const CaseImport = ({
|
|
|
232
238
|
// Handle import action
|
|
233
239
|
const handleImport = useCallback(() => {
|
|
234
240
|
if (!user || !importState.selectedFile || !importState.importType) return;
|
|
241
|
+
|
|
242
|
+
if (importState.importType === 'case' && isArchivedRegularCaseImportBlocked) {
|
|
243
|
+
setError(ARCHIVED_REGULAR_CASE_BLOCK_MESSAGE);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
235
246
|
|
|
236
247
|
// For case imports, show confirmation dialog with preview
|
|
237
248
|
// For confirmation imports, proceed directly to import
|
|
@@ -242,7 +253,16 @@ export const CaseImport = ({
|
|
|
242
253
|
// Direct import for confirmations
|
|
243
254
|
executeImport();
|
|
244
255
|
}
|
|
245
|
-
}, [
|
|
256
|
+
}, [
|
|
257
|
+
user,
|
|
258
|
+
importState.selectedFile,
|
|
259
|
+
importState.importType,
|
|
260
|
+
isArchivedRegularCaseImportBlocked,
|
|
261
|
+
casePreview,
|
|
262
|
+
updateImportState,
|
|
263
|
+
executeImport,
|
|
264
|
+
setError,
|
|
265
|
+
]);
|
|
246
266
|
|
|
247
267
|
const handleCancelImport = useCallback(() => {
|
|
248
268
|
updateImportState({ showConfirmation: false });
|
|
@@ -273,7 +293,7 @@ export const CaseImport = ({
|
|
|
273
293
|
!casePreview.caseNumber
|
|
274
294
|
) {
|
|
275
295
|
if (isMounted) {
|
|
276
|
-
|
|
296
|
+
setIsArchivedRegularCaseImportBlocked(false);
|
|
277
297
|
}
|
|
278
298
|
return;
|
|
279
299
|
}
|
|
@@ -281,11 +301,12 @@ export const CaseImport = ({
|
|
|
281
301
|
try {
|
|
282
302
|
const regularCases = await listCases(user);
|
|
283
303
|
if (isMounted) {
|
|
284
|
-
|
|
304
|
+
const hasConflict = regularCases.includes(casePreview.caseNumber);
|
|
305
|
+
setIsArchivedRegularCaseImportBlocked(hasConflict);
|
|
285
306
|
}
|
|
286
307
|
} catch {
|
|
287
308
|
if (isMounted) {
|
|
288
|
-
|
|
309
|
+
setIsArchivedRegularCaseImportBlocked(false);
|
|
289
310
|
}
|
|
290
311
|
}
|
|
291
312
|
};
|
|
@@ -295,7 +316,13 @@ export const CaseImport = ({
|
|
|
295
316
|
return () => {
|
|
296
317
|
isMounted = false;
|
|
297
318
|
};
|
|
298
|
-
}, [
|
|
319
|
+
}, [
|
|
320
|
+
user,
|
|
321
|
+
isOpen,
|
|
322
|
+
importState.importType,
|
|
323
|
+
casePreview?.archived,
|
|
324
|
+
casePreview?.caseNumber,
|
|
325
|
+
]);
|
|
299
326
|
|
|
300
327
|
// Reset state when modal closes
|
|
301
328
|
useEffect(() => {
|
|
@@ -306,9 +333,19 @@ export const CaseImport = ({
|
|
|
306
333
|
|
|
307
334
|
// Handle confirmation import
|
|
308
335
|
const handleConfirmImport = useCallback(() => {
|
|
336
|
+
if (isArchivedRegularCaseImportBlocked) {
|
|
337
|
+
setError(ARCHIVED_REGULAR_CASE_BLOCK_MESSAGE);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
|
|
309
341
|
executeImport();
|
|
310
342
|
updateImportState({ showConfirmation: false });
|
|
311
|
-
}, [
|
|
343
|
+
}, [
|
|
344
|
+
isArchivedRegularCaseImportBlocked,
|
|
345
|
+
executeImport,
|
|
346
|
+
updateImportState,
|
|
347
|
+
setError,
|
|
348
|
+
]);
|
|
312
349
|
|
|
313
350
|
if (!isOpen) return null;
|
|
314
351
|
|
|
@@ -362,7 +399,7 @@ export const CaseImport = ({
|
|
|
362
399
|
<CasePreviewSection
|
|
363
400
|
casePreview={casePreview}
|
|
364
401
|
isLoadingPreview={importState.isLoadingPreview}
|
|
365
|
-
|
|
402
|
+
isArchivedRegularCaseImportBlocked={isArchivedRegularCaseImportBlocked}
|
|
366
403
|
/>
|
|
367
404
|
)}
|
|
368
405
|
|
|
@@ -381,11 +418,14 @@ export const CaseImport = ({
|
|
|
381
418
|
{/* Hash validation warning */}
|
|
382
419
|
{casePreview?.hashValid === false && (
|
|
383
420
|
<div className={styles.hashWarning}>
|
|
384
|
-
<strong>⚠️ Import Blocked:</strong>
|
|
385
|
-
This file may have been tampered with or corrupted and cannot be imported.
|
|
421
|
+
<strong>⚠️ Import Blocked:</strong> {DATA_INTEGRITY_BLOCKED_TAMPERING}
|
|
386
422
|
</div>
|
|
387
423
|
)}
|
|
388
424
|
|
|
425
|
+
{isArchivedRegularCaseImportBlocked && (
|
|
426
|
+
<div className={styles.error}>{ARCHIVED_REGULAR_CASE_BLOCK_MESSAGE}</div>
|
|
427
|
+
)}
|
|
428
|
+
|
|
389
429
|
{/* Success message */}
|
|
390
430
|
{messages.success && (
|
|
391
431
|
<div className={styles.success}>
|
|
@@ -411,6 +451,7 @@ export const CaseImport = ({
|
|
|
411
451
|
importState.isImporting ||
|
|
412
452
|
importState.isClearing ||
|
|
413
453
|
importState.isLoadingPreview ||
|
|
454
|
+
(importState.importType === 'case' && isArchivedRegularCaseImportBlocked) ||
|
|
414
455
|
(importState.importType === 'case' && (!casePreview || casePreview.hashValid !== true))
|
|
415
456
|
}
|
|
416
457
|
>
|
|
@@ -454,7 +495,8 @@ export const CaseImport = ({
|
|
|
454
495
|
<ConfirmationDialog
|
|
455
496
|
showConfirmation={importState.showConfirmation}
|
|
456
497
|
casePreview={casePreview}
|
|
457
|
-
|
|
498
|
+
isArchivedRegularCaseImportBlocked={isArchivedRegularCaseImportBlocked}
|
|
499
|
+
archivedRegularCaseBlockMessage={ARCHIVED_REGULAR_CASE_BLOCK_MESSAGE}
|
|
458
500
|
onConfirm={handleConfirmImport}
|
|
459
501
|
onCancel={handleCancelImport}
|
|
460
502
|
/>
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { type CaseImportPreview } from '~/types';
|
|
2
|
+
import { ARCHIVED_REGULAR_CASE_BLOCK_MESSAGE, DATA_INTEGRITY_VALIDATION_PASSED, DATA_INTEGRITY_VALIDATION_FAILED } from '~/utils/ui';
|
|
2
3
|
import styles from '../case-import.module.css';
|
|
3
4
|
|
|
4
5
|
interface CasePreviewSectionProps {
|
|
5
6
|
casePreview: CaseImportPreview | null;
|
|
6
7
|
isLoadingPreview: boolean;
|
|
7
|
-
|
|
8
|
+
isArchivedRegularCaseImportBlocked?: boolean;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export const CasePreviewSection = ({
|
|
11
12
|
casePreview,
|
|
12
13
|
isLoadingPreview,
|
|
13
|
-
|
|
14
|
+
isArchivedRegularCaseImportBlocked = false
|
|
14
15
|
}: CasePreviewSectionProps) => {
|
|
15
16
|
if (isLoadingPreview) {
|
|
16
17
|
return (
|
|
@@ -34,9 +35,9 @@ export const CasePreviewSection = ({
|
|
|
34
35
|
Archived export detected. Original exporter imports are allowed for archived cases.
|
|
35
36
|
</div>
|
|
36
37
|
)}
|
|
37
|
-
{
|
|
38
|
+
{isArchivedRegularCaseImportBlocked && (
|
|
38
39
|
<div className={styles.archivedRegularCaseRiskNote}>
|
|
39
|
-
|
|
40
|
+
{ARCHIVED_REGULAR_CASE_BLOCK_MESSAGE}
|
|
40
41
|
</div>
|
|
41
42
|
)}
|
|
42
43
|
<div className={styles.previewGrid}>
|
|
@@ -78,9 +79,9 @@ export const CasePreviewSection = ({
|
|
|
78
79
|
<div className={styles.validationItem}>
|
|
79
80
|
<span className={`${styles.validationValue} ${casePreview.hashValid ? styles.validationSuccess : styles.validationError}`}>
|
|
80
81
|
{casePreview.hashValid ? (
|
|
81
|
-
|
|
82
|
+
<>{DATA_INTEGRITY_VALIDATION_PASSED}</>
|
|
82
83
|
) : (
|
|
83
|
-
|
|
84
|
+
<>{DATA_INTEGRITY_VALIDATION_FAILED}</>
|
|
84
85
|
)}
|
|
85
86
|
</span>
|
|
86
87
|
</div>
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type CaseImportPreview } from '~/types';
|
|
2
|
+
import { ARCHIVED_REGULAR_CASE_BLOCK_MESSAGE, DATA_INTEGRITY_VALIDATION_PASSED, DATA_INTEGRITY_VALIDATION_FAILED } from '~/utils/ui';
|
|
2
3
|
import styles from '../case-import.module.css';
|
|
3
4
|
|
|
4
5
|
interface ConfirmationDialogProps {
|
|
5
6
|
showConfirmation: boolean;
|
|
6
7
|
casePreview: CaseImportPreview | null;
|
|
7
|
-
|
|
8
|
+
isArchivedRegularCaseImportBlocked?: boolean;
|
|
9
|
+
archivedRegularCaseBlockMessage?: string;
|
|
8
10
|
onConfirm: () => void;
|
|
9
11
|
onCancel: () => void;
|
|
10
12
|
}
|
|
@@ -12,7 +14,8 @@ interface ConfirmationDialogProps {
|
|
|
12
14
|
export const ConfirmationDialog = ({
|
|
13
15
|
showConfirmation,
|
|
14
16
|
casePreview,
|
|
15
|
-
|
|
17
|
+
isArchivedRegularCaseImportBlocked = false,
|
|
18
|
+
archivedRegularCaseBlockMessage = ARCHIVED_REGULAR_CASE_BLOCK_MESSAGE,
|
|
16
19
|
onConfirm,
|
|
17
20
|
onCancel
|
|
18
21
|
}: ConfirmationDialogProps) => {
|
|
@@ -51,16 +54,16 @@ export const ConfirmationDialog = ({
|
|
|
51
54
|
Archived export detected. Original exporter imports are allowed for archived cases.
|
|
52
55
|
</div>
|
|
53
56
|
)}
|
|
54
|
-
{
|
|
57
|
+
{isArchivedRegularCaseImportBlocked && (
|
|
55
58
|
<div className={styles.archivedRegularCaseRiskNote}>
|
|
56
|
-
|
|
59
|
+
{archivedRegularCaseBlockMessage}
|
|
57
60
|
</div>
|
|
58
61
|
)}
|
|
59
62
|
{casePreview.hashValid !== undefined && (
|
|
60
63
|
<div className={`${styles.confirmationItem} ${casePreview.hashValid ? styles.confirmationItemValid : styles.confirmationItemInvalid}`}>
|
|
61
64
|
<strong>Data Integrity:</strong>
|
|
62
65
|
<span className={casePreview.hashValid ? styles.confirmationSuccess : styles.confirmationError}>
|
|
63
|
-
{casePreview.hashValid ?
|
|
66
|
+
{casePreview.hashValid ? DATA_INTEGRITY_VALIDATION_PASSED : DATA_INTEGRITY_VALIDATION_FAILED}
|
|
64
67
|
</span>
|
|
65
68
|
</div>
|
|
66
69
|
)}
|
|
@@ -70,6 +73,7 @@ export const ConfirmationDialog = ({
|
|
|
70
73
|
<button
|
|
71
74
|
className={styles.confirmButton}
|
|
72
75
|
onClick={onConfirm}
|
|
76
|
+
disabled={isArchivedRegularCaseImportBlocked}
|
|
73
77
|
>
|
|
74
78
|
Confirm Import
|
|
75
79
|
</button>
|
|
@@ -260,6 +260,19 @@
|
|
|
260
260
|
white-space: nowrap;
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
.badgeColumn {
|
|
264
|
+
justify-self: end;
|
|
265
|
+
display: flex;
|
|
266
|
+
flex-direction: column;
|
|
267
|
+
align-items: flex-end;
|
|
268
|
+
gap: var(--spaceXS);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.archivedBadge {
|
|
272
|
+
background-color: color-mix(in lab, #6c757d 18%, var(--backgroundLight));
|
|
273
|
+
border-color: color-mix(in lab, #6c757d 30%, transparent);
|
|
274
|
+
}
|
|
275
|
+
|
|
263
276
|
.footerActions {
|
|
264
277
|
display: flex;
|
|
265
278
|
justify-content: space-between;
|
|
@@ -489,6 +502,12 @@
|
|
|
489
502
|
justify-self: start;
|
|
490
503
|
}
|
|
491
504
|
|
|
505
|
+
.badgeColumn {
|
|
506
|
+
grid-column: 1 / -1;
|
|
507
|
+
justify-self: start;
|
|
508
|
+
align-items: flex-start;
|
|
509
|
+
}
|
|
510
|
+
|
|
492
511
|
.footerActions {
|
|
493
512
|
flex-direction: column;
|
|
494
513
|
align-items: stretch;
|
|
@@ -169,7 +169,7 @@ export const CasesModal = ({
|
|
|
169
169
|
return allCases.filter((entry) => entry.archived && !entry.isReadOnly);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
return allCases.filter((entry) => !entry.
|
|
172
|
+
return allCases.filter((entry) => !entry.isReadOnly);
|
|
173
173
|
}, [allCases, preferences.showArchivedOnly]);
|
|
174
174
|
|
|
175
175
|
const visibleCases = useMemo(() => {
|
|
@@ -185,6 +185,11 @@ export const CasesModal = ({
|
|
|
185
185
|
);
|
|
186
186
|
}, [allCases, preferences, caseConfirmationStatus, searchQuery]);
|
|
187
187
|
|
|
188
|
+
const totalRegularCases = useMemo(
|
|
189
|
+
() => allCases.filter((entry) => !entry.isReadOnly).length,
|
|
190
|
+
[allCases]
|
|
191
|
+
);
|
|
192
|
+
|
|
188
193
|
const totalPages = Math.max(1, Math.ceil(visibleCases.length / CASES_PER_PAGE));
|
|
189
194
|
|
|
190
195
|
useEffect(() => {
|
|
@@ -653,7 +658,7 @@ export const CasesModal = ({
|
|
|
653
658
|
</div>
|
|
654
659
|
|
|
655
660
|
<p className={styles.caseCount}>
|
|
656
|
-
{visibleCases.length} shown of {
|
|
661
|
+
{visibleCases.length} shown of {totalRegularCases} total cases
|
|
657
662
|
</p>
|
|
658
663
|
|
|
659
664
|
{actionNotice && (
|
|
@@ -720,12 +725,22 @@ export const CasesModal = ({
|
|
|
720
725
|
</span>
|
|
721
726
|
</div>
|
|
722
727
|
|
|
723
|
-
<
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
728
|
+
<div className={styles.badgeColumn}>
|
|
729
|
+
{caseEntry.archived && (
|
|
730
|
+
<span
|
|
731
|
+
className={`${styles.confirmationBadge} ${styles.archivedBadge}`}
|
|
732
|
+
aria-label="Archived case"
|
|
733
|
+
>
|
|
734
|
+
Archived
|
|
735
|
+
</span>
|
|
736
|
+
)}
|
|
737
|
+
<span
|
|
738
|
+
className={`${styles.confirmationBadge} ${confirmationClass}`}
|
|
739
|
+
aria-label={`Confirmation status: ${confirmationLabel}`}
|
|
740
|
+
>
|
|
741
|
+
{confirmationLabel}
|
|
742
|
+
</span>
|
|
743
|
+
</div>
|
|
729
744
|
</div>
|
|
730
745
|
</li>
|
|
731
746
|
);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { useCallback, type Dispatch, type SetStateAction } from 'react';
|
|
2
|
+
import { type AnnotationData, type FileData } from '~/types';
|
|
3
|
+
|
|
4
|
+
interface ArchiveDetailsState {
|
|
5
|
+
archived: boolean;
|
|
6
|
+
archivedAt?: string;
|
|
7
|
+
archivedBy?: string;
|
|
8
|
+
archivedByDisplay?: string;
|
|
9
|
+
archiveReason?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface UseStriaeResetHelpersProps {
|
|
13
|
+
setSelectedImage: Dispatch<SetStateAction<string | undefined>>;
|
|
14
|
+
setSelectedFilename: Dispatch<SetStateAction<string | undefined>>;
|
|
15
|
+
setImageId: Dispatch<SetStateAction<string | undefined>>;
|
|
16
|
+
setAnnotationData: Dispatch<SetStateAction<AnnotationData | null>>;
|
|
17
|
+
setError: Dispatch<SetStateAction<string | undefined>>;
|
|
18
|
+
setImageLoaded: Dispatch<SetStateAction<boolean>>;
|
|
19
|
+
setCurrentCase: Dispatch<SetStateAction<string>>;
|
|
20
|
+
setFiles: Dispatch<SetStateAction<FileData[]>>;
|
|
21
|
+
setActiveAnnotations: Dispatch<SetStateAction<Set<string>>>;
|
|
22
|
+
setIsBoxAnnotationMode: Dispatch<SetStateAction<boolean>>;
|
|
23
|
+
setIsReadOnlyCase: Dispatch<SetStateAction<boolean>>;
|
|
24
|
+
setIsReviewOnlyCase: Dispatch<SetStateAction<boolean>>;
|
|
25
|
+
setArchiveDetails: Dispatch<SetStateAction<ArchiveDetailsState>>;
|
|
26
|
+
setShowNotes: Dispatch<SetStateAction<boolean>>;
|
|
27
|
+
setIsAuditTrailOpen: Dispatch<SetStateAction<boolean>>;
|
|
28
|
+
setIsRenameCaseModalOpen: Dispatch<SetStateAction<boolean>>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const useStriaeResetHelpers = ({
|
|
32
|
+
setSelectedImage,
|
|
33
|
+
setSelectedFilename,
|
|
34
|
+
setImageId,
|
|
35
|
+
setAnnotationData,
|
|
36
|
+
setError,
|
|
37
|
+
setImageLoaded,
|
|
38
|
+
setCurrentCase,
|
|
39
|
+
setFiles,
|
|
40
|
+
setActiveAnnotations,
|
|
41
|
+
setIsBoxAnnotationMode,
|
|
42
|
+
setIsReadOnlyCase,
|
|
43
|
+
setIsReviewOnlyCase,
|
|
44
|
+
setArchiveDetails,
|
|
45
|
+
setShowNotes,
|
|
46
|
+
setIsAuditTrailOpen,
|
|
47
|
+
setIsRenameCaseModalOpen,
|
|
48
|
+
}: UseStriaeResetHelpersProps) => {
|
|
49
|
+
const clearSelectedImageState = useCallback(() => {
|
|
50
|
+
setSelectedImage('/clear.jpg');
|
|
51
|
+
setSelectedFilename(undefined);
|
|
52
|
+
setImageId(undefined);
|
|
53
|
+
setAnnotationData(null);
|
|
54
|
+
setError(undefined);
|
|
55
|
+
setImageLoaded(false);
|
|
56
|
+
}, [
|
|
57
|
+
setSelectedImage,
|
|
58
|
+
setSelectedFilename,
|
|
59
|
+
setImageId,
|
|
60
|
+
setAnnotationData,
|
|
61
|
+
setError,
|
|
62
|
+
setImageLoaded,
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
const clearCaseContextState = useCallback(() => {
|
|
66
|
+
setActiveAnnotations(new Set());
|
|
67
|
+
setIsBoxAnnotationMode(false);
|
|
68
|
+
setIsReadOnlyCase(false);
|
|
69
|
+
setIsReviewOnlyCase(false);
|
|
70
|
+
setArchiveDetails({ archived: false });
|
|
71
|
+
}, [
|
|
72
|
+
setActiveAnnotations,
|
|
73
|
+
setIsBoxAnnotationMode,
|
|
74
|
+
setIsReadOnlyCase,
|
|
75
|
+
setIsReviewOnlyCase,
|
|
76
|
+
setArchiveDetails,
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
const clearLoadedCaseState = useCallback(() => {
|
|
80
|
+
setCurrentCase('');
|
|
81
|
+
setFiles([]);
|
|
82
|
+
clearCaseContextState();
|
|
83
|
+
clearSelectedImageState();
|
|
84
|
+
setShowNotes(false);
|
|
85
|
+
setIsAuditTrailOpen(false);
|
|
86
|
+
setIsRenameCaseModalOpen(false);
|
|
87
|
+
}, [
|
|
88
|
+
setCurrentCase,
|
|
89
|
+
setFiles,
|
|
90
|
+
clearCaseContextState,
|
|
91
|
+
clearSelectedImageState,
|
|
92
|
+
setShowNotes,
|
|
93
|
+
setIsAuditTrailOpen,
|
|
94
|
+
setIsRenameCaseModalOpen,
|
|
95
|
+
]);
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
clearSelectedImageState,
|
|
99
|
+
clearCaseContextState,
|
|
100
|
+
clearLoadedCaseState,
|
|
101
|
+
};
|
|
102
|
+
};
|