documentation-hub 5.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/.eslintrc.json +43 -0
  2. package/.github/workflows/build.yml +64 -0
  3. package/.github/workflows/ci.yml +39 -0
  4. package/.vscode/extensions.json +3 -0
  5. package/Current.md +97 -0
  6. package/DocHub_Image.png +0 -0
  7. package/README.md +666 -0
  8. package/USER_GUIDE.md +1173 -0
  9. package/Updater.md +311 -0
  10. package/build/256x256.png +0 -0
  11. package/build/512x512.png +0 -0
  12. package/build/app-update.yml +4 -0
  13. package/build/create-icon.js +208 -0
  14. package/build/icon.ico +0 -0
  15. package/build/icon.png +0 -0
  16. package/build/icon_1024x1024.png +0 -0
  17. package/dist/assets/Analytics-BpsG9895.js +1 -0
  18. package/dist/assets/Card-IAZin8kp.js +1 -0
  19. package/dist/assets/CurrentSession-B-rFkHvf.js +12 -0
  20. package/dist/assets/Dashboard-C_5gMb0q.js +1 -0
  21. package/dist/assets/Documents-CqZ25axS.js +1 -0
  22. package/dist/assets/Input-l89xwXBi.js +1 -0
  23. package/dist/assets/Reporting-DqdHJY_a.js +1 -0
  24. package/dist/assets/Search-XNbu5z_3.js +1 -0
  25. package/dist/assets/SessionManager-lH9hZfzH.js +1 -0
  26. package/dist/assets/Sessions-ClZOPYNc.js +1 -0
  27. package/dist/assets/Settings-DUEHGURa.js +11 -0
  28. package/dist/assets/index-8xUe8ptc.js +24 -0
  29. package/dist/assets/index-RYyJqF7O.css +1 -0
  30. package/dist/assets/path-BkOl0AGO.js +1 -0
  31. package/dist/assets/promises-ID_B9S-h.js +1 -0
  32. package/dist/assets/urlHelpers-TvgahX0r.js +1 -0
  33. package/dist/assets/useToast-yRSO1dkm.js +1 -0
  34. package/dist/assets/vendor-charts-RkGK5ROP.js +36 -0
  35. package/dist/assets/vendor-db-l0sNRNKZ.js +1 -0
  36. package/dist/assets/vendor-react-BVZ_anCF.js +4 -0
  37. package/dist/assets/vendor-search-Dw8P0qyA.js +1 -0
  38. package/dist/assets/vendor-ui-BU7NfluV.js +53 -0
  39. package/dist/electron/PowerAutomateApiService-LfW09ZGr.js +147 -0
  40. package/dist/electron/main-CXkNtyv-.js +19789 -0
  41. package/dist/electron/main.js +5 -0
  42. package/dist/electron/preload.js +1 -0
  43. package/dist/icon.png +0 -0
  44. package/dist/index.html +27 -0
  45. package/docs/CODEBASE_ANALYSIS_REPORT.md +309 -0
  46. package/docs/DEBUG_LOGGING_GUIDE.md +244 -0
  47. package/docs/README.md +115 -0
  48. package/docs/TOC_WIRING_GUIDE.md +344 -0
  49. package/docs/analysis/Bullet_Symbol_Bug_Analysis.md +136 -0
  50. package/docs/analysis/DOCXMLATER_ANALYSIS_SUMMARY.txt +169 -0
  51. package/docs/analysis/Document_Processing_Issues_Analysis.md +704 -0
  52. package/docs/analysis/FIELD_PRESERVATION_ANALYSIS.md +1200 -0
  53. package/docs/analysis/INDENTATION_PRESERVE_ANALYSIS.md +181 -0
  54. package/docs/analysis/INDENTATION_PRESERVE_IMPLEMENTATION.md +207 -0
  55. package/docs/analysis/List_Implementation.md +206 -0
  56. package/docs/analysis/List_Implementation_Accuracy_Report.md +366 -0
  57. package/docs/analysis/PROCESSING_OPTIONS_UI_UPDATES.md +220 -0
  58. package/docs/analysis/RefactorStyles.md +852 -0
  59. package/docs/analysis/STYLE_PARAMETER_ENHANCEMENT.md +143 -0
  60. package/docs/analysis/docxmlater-comparison-todo-2025-11-13.md +636 -0
  61. package/docs/analysis/docxmlater-implementation-analysis-2025-11-13.md +340 -0
  62. package/docs/analysis/docxmlater-template_ui-integration-analysis.md +263 -0
  63. package/docs/analysis/github-issues-to-create.md +237 -0
  64. package/docs/api/API_README.md +538 -0
  65. package/docs/api/API_REFERENCE.md +751 -0
  66. package/docs/api/TYPE_DEFINITIONS.md +869 -0
  67. package/docs/architecture/FONT_EMBEDDING_GUIDE.md +318 -0
  68. package/docs/architecture/docxmlater-functions-and-structure.md +726 -0
  69. package/docs/docxmlater-readme.md +1341 -0
  70. package/docs/fixes/EXECUTION_LOG_TEST_BASE.md +573 -0
  71. package/docs/fixes/HYPERLINK_TEXT_SANITIZATION.md +253 -0
  72. package/docs/fixes/README.md +37 -0
  73. package/docs/github-issues/issue-1-body.md +125 -0
  74. package/docs/github-issues/issue-10-body.md +850 -0
  75. package/docs/github-issues/issue-2-body.md +200 -0
  76. package/docs/github-issues/issue-3-body.md +270 -0
  77. package/docs/github-issues/issue-4-body.md +169 -0
  78. package/docs/github-issues/issue-5-body.md +173 -0
  79. package/docs/github-issues/issue-6-body.md +158 -0
  80. package/docs/github-issues/issue-7-body.md +171 -0
  81. package/docs/github-issues/issue-8-body.md +407 -0
  82. package/docs/github-issues/issue-9-body.md +515 -0
  83. package/docs/github-issues/issue-tracker.md +274 -0
  84. package/docs/github-issues/predictive-analysis-2025-10-18.md +2131 -0
  85. package/docs/implementation/List_Framework_Refactor_Plan.md +336 -0
  86. package/docs/implementation/PRIMARY_TEXT_COLOR_FEATURE.md +217 -0
  87. package/docs/implementation/RELEASE_PLAN_v2.1.0.md +362 -0
  88. package/docs/implementation/RefactorStyles.md +588 -0
  89. package/docs/implementation/implement-plan.md +489 -0
  90. package/docs/implementation/missing-helpers-implementation.md +391 -0
  91. package/docs/implementation/refactor-plan.md +520 -0
  92. package/docs/implementation/session-implementation-complete.md +233 -0
  93. package/docs/implementation/session-management-plan.md +250 -0
  94. package/docs/setup-checklist.md +77 -0
  95. package/docs/versions/changelog.md +345 -0
  96. package/electron/customUpdater.ts +656 -0
  97. package/electron/main.ts +2441 -0
  98. package/electron/memoryConfig.ts +187 -0
  99. package/electron/preload.ts +394 -0
  100. package/electron/proxyConfig.ts +340 -0
  101. package/electron/services/BackupService.ts +452 -0
  102. package/electron/services/DictionaryService.ts +402 -0
  103. package/electron/services/LocalDictionaryLookupService.ts +147 -0
  104. package/electron/services/PowerAutomateApiService.ts +231 -0
  105. package/electron/services/SharePointSyncService.ts +474 -0
  106. package/electron/windowsCertStore.ts +427 -0
  107. package/electron/zscalerConfig.ts +381 -0
  108. package/eslint.config.js +92 -0
  109. package/jest.config.js +52 -0
  110. package/package.json +214 -0
  111. package/postcss.config.mjs +6 -0
  112. package/public/icon.png +0 -0
  113. package/publish-release.ps1 +5 -0
  114. package/renovate.json +30 -0
  115. package/src/App.tsx +216 -0
  116. package/src/__mocks__/p-limit.js +12 -0
  117. package/src/__mocks__/styleMock.js +1 -0
  118. package/src/components/common/BugReportButton.tsx +44 -0
  119. package/src/components/common/BugReportDialog.tsx +193 -0
  120. package/src/components/common/Button.tsx +153 -0
  121. package/src/components/common/Card.tsx +86 -0
  122. package/src/components/common/ColorPickerDialog.tsx +177 -0
  123. package/src/components/common/ConfirmDialog.tsx +96 -0
  124. package/src/components/common/DebugConsole.tsx +275 -0
  125. package/src/components/common/EmptyState.tsx +183 -0
  126. package/src/components/common/ErrorBoundary.tsx +98 -0
  127. package/src/components/common/ErrorDetailsDialog.tsx +153 -0
  128. package/src/components/common/ErrorFallback.tsx +218 -0
  129. package/src/components/common/Input.tsx +109 -0
  130. package/src/components/common/Skeleton.tsx +184 -0
  131. package/src/components/common/SplashScreen.tsx +81 -0
  132. package/src/components/common/Toast.tsx +155 -0
  133. package/src/components/common/Tooltip.tsx +79 -0
  134. package/src/components/common/UpdateNotification.tsx +320 -0
  135. package/src/components/comparison/ComparisonWindow.tsx +374 -0
  136. package/src/components/comparison/SideBySideDiff.tsx +486 -0
  137. package/src/components/comparison/index.ts +8 -0
  138. package/src/components/document/DocumentUploader.tsx +288 -0
  139. package/src/components/document/HyperlinkPreview.tsx +430 -0
  140. package/src/components/document/HyperlinkService.md +1484 -0
  141. package/src/components/document/Hyperlink_Technical_Documentation.md +496 -0
  142. package/src/components/document/InlineChangesView.tsx +707 -0
  143. package/src/components/document/ProcessingProgress.tsx +303 -0
  144. package/src/components/document/ProcessingResults.tsx +256 -0
  145. package/src/components/document/TrackedChangesDetail.tsx +530 -0
  146. package/src/components/document/TrackedChangesPanel.tsx +546 -0
  147. package/src/components/document/VirtualDocumentList.tsx +240 -0
  148. package/src/components/editor/DocumentEditor.tsx +723 -0
  149. package/src/components/editor/DocumentEditorModal.tsx +640 -0
  150. package/src/components/editor/EditorQuickActions.tsx +502 -0
  151. package/src/components/editor/EditorToolbar.tsx +312 -0
  152. package/src/components/editor/TableEditor.tsx +926 -0
  153. package/src/components/editor/index.ts +18 -0
  154. package/src/components/layout/Header.tsx +190 -0
  155. package/src/components/layout/Sidebar.tsx +313 -0
  156. package/src/components/layout/TitleBar.tsx +190 -0
  157. package/src/components/navigation/CommandPalette.tsx +233 -0
  158. package/src/components/navigation/KeyboardShortcutsModal.tsx +173 -0
  159. package/src/components/sessions/ChangeItem.tsx +408 -0
  160. package/src/components/sessions/ChangeViewer.tsx +1155 -0
  161. package/src/components/sessions/DocumentComparisonModal.tsx +314 -0
  162. package/src/components/sessions/ProcessingOptions.tsx +297 -0
  163. package/src/components/sessions/ReplacementsTab.tsx +438 -0
  164. package/src/components/sessions/RevisionHandlingOptions.tsx +87 -0
  165. package/src/components/sessions/SessionManager.tsx +188 -0
  166. package/src/components/sessions/StylesEditor.tsx +1335 -0
  167. package/src/components/sessions/TabContainer.tsx +151 -0
  168. package/src/components/sessions/VirtualSessionList.tsx +157 -0
  169. package/src/components/sessions/sessionToProcessorManager.tsx +420 -0
  170. package/src/components/settings/CertificateManager.tsx +410 -0
  171. package/src/components/settings/SegmentedControl.tsx +88 -0
  172. package/src/components/settings/SettingRow.tsx +52 -0
  173. package/src/contexts/GlobalStatsContext.tsx +396 -0
  174. package/src/contexts/SessionContext.tsx +2129 -0
  175. package/src/contexts/ThemeContext.tsx +428 -0
  176. package/src/contexts/UserSettingsContext.tsx +290 -0
  177. package/src/contexts/__tests__/GlobalStatsContext.test.tsx +390 -0
  178. package/src/global.d.ts +273 -0
  179. package/src/hooks/useDocumentQueue.tsx +210 -0
  180. package/src/hooks/useToast.tsx +55 -0
  181. package/src/main.tsx +10 -0
  182. package/src/pages/Analytics.tsx +386 -0
  183. package/src/pages/CurrentSession.tsx +1174 -0
  184. package/src/pages/Dashboard.tsx +319 -0
  185. package/src/pages/Documents.tsx +317 -0
  186. package/src/pages/Projects.tsx +250 -0
  187. package/src/pages/Reporting.tsx +386 -0
  188. package/src/pages/Search.tsx +349 -0
  189. package/src/pages/Sessions.tsx +285 -0
  190. package/src/pages/Settings.tsx +2662 -0
  191. package/src/services/HyperlinkService.ts +1085 -0
  192. package/src/services/document/DocXMLaterProcessor.ts +617 -0
  193. package/src/services/document/DocumentProcessingComparison.ts +856 -0
  194. package/src/services/document/DocumentSnapshotService.ts +575 -0
  195. package/src/services/document/WordDocumentProcessor.ts +10509 -0
  196. package/src/services/document/__tests__/DocXMLaterProcessor.hyperlinks.test.md +311 -0
  197. package/src/services/document/__tests__/WordDocumentProcessor.integration.test.ts +515 -0
  198. package/src/services/document/__tests__/WordDocumentProcessor.test.ts +812 -0
  199. package/src/services/document/blanklines/BlankLineManager.ts +658 -0
  200. package/src/services/document/blanklines/__tests__/paragraphChecks.test.ts +281 -0
  201. package/src/services/document/blanklines/helpers/blankLineInsertion.ts +87 -0
  202. package/src/services/document/blanklines/helpers/blankLineSnapshot.ts +251 -0
  203. package/src/services/document/blanklines/helpers/clearCustom.ts +121 -0
  204. package/src/services/document/blanklines/helpers/contextChecks.ts +117 -0
  205. package/src/services/document/blanklines/helpers/imageChecks.ts +51 -0
  206. package/src/services/document/blanklines/helpers/paragraphChecks.ts +236 -0
  207. package/src/services/document/blanklines/helpers/removeBlanksBetweenListItems.ts +91 -0
  208. package/src/services/document/blanklines/helpers/removeTrailingBlanks.ts +35 -0
  209. package/src/services/document/blanklines/helpers/tableGuards.ts +21 -0
  210. package/src/services/document/blanklines/index.ts +67 -0
  211. package/src/services/document/blanklines/rules/additionRules.ts +337 -0
  212. package/src/services/document/blanklines/rules/indentationRules.ts +317 -0
  213. package/src/services/document/blanklines/rules/removalRules.ts +362 -0
  214. package/src/services/document/blanklines/rules/ruleTypes.ts +92 -0
  215. package/src/services/document/blanklines/types.ts +29 -0
  216. package/src/services/document/helpers/ImageBorderCropper.ts +377 -0
  217. package/src/services/document/helpers/__tests__/whitespace.test.ts +272 -0
  218. package/src/services/document/helpers/whitespace.ts +117 -0
  219. package/src/services/document/list/ListNormalizer.ts +947 -0
  220. package/src/services/document/list/index.ts +45 -0
  221. package/src/services/document/list/list-detection.ts +275 -0
  222. package/src/services/document/list/list-types.ts +162 -0
  223. package/src/services/document/processors/HyperlinkProcessor.ts +370 -0
  224. package/src/services/document/processors/ListProcessor.ts +257 -0
  225. package/src/services/document/processors/StructureProcessor.ts +176 -0
  226. package/src/services/document/processors/StyleProcessor.ts +389 -0
  227. package/src/services/document/processors/TableProcessor.ts +2238 -0
  228. package/src/services/document/processors/__tests__/HyperlinkProcessor.test.ts +314 -0
  229. package/src/services/document/processors/__tests__/ListProcessor.test.ts +291 -0
  230. package/src/services/document/processors/__tests__/StructureProcessor.test.ts +257 -0
  231. package/src/services/document/processors/__tests__/TableProcessor.hlp-tips-bullets.test.ts +459 -0
  232. package/src/services/document/processors/__tests__/TableProcessor.test.ts +1604 -0
  233. package/src/services/document/processors/index.ts +28 -0
  234. package/src/services/document/types/docx-processing.ts +310 -0
  235. package/src/services/editor/EditorActionHandlers.ts +901 -0
  236. package/src/services/editor/index.ts +13 -0
  237. package/src/setupTests.ts +47 -0
  238. package/src/styles/global.css +782 -0
  239. package/src/types/backup.ts +132 -0
  240. package/src/types/dictionary.ts +125 -0
  241. package/src/types/document-processing.ts +331 -0
  242. package/src/types/docxmlater-augments.d.ts +142 -0
  243. package/src/types/editor.ts +280 -0
  244. package/src/types/electron.ts +340 -0
  245. package/src/types/globalStats.ts +155 -0
  246. package/src/types/hyperlink.ts +471 -0
  247. package/src/types/operations.ts +354 -0
  248. package/src/types/session.ts +427 -0
  249. package/src/types/settings.ts +112 -0
  250. package/src/utils/MemoryMonitor.ts +248 -0
  251. package/src/utils/cn.ts +6 -0
  252. package/src/utils/colorConvert.ts +306 -0
  253. package/src/utils/diffUtils.ts +347 -0
  254. package/src/utils/documentUtils.ts +202 -0
  255. package/src/utils/electronGuard.ts +62 -0
  256. package/src/utils/indexedDB.ts +915 -0
  257. package/src/utils/logger.ts +717 -0
  258. package/src/utils/pathSecurity.ts +232 -0
  259. package/src/utils/pathValidator.ts +236 -0
  260. package/src/utils/processingTimeEstimator.ts +153 -0
  261. package/src/utils/safeJsonParse.ts +62 -0
  262. package/src/utils/textSanitizer.ts +162 -0
  263. package/src/utils/urlHelpers.ts +304 -0
  264. package/src/utils/urlPatterns.ts +198 -0
  265. package/src/utils/urlSanitizer.ts +152 -0
  266. package/src/vite-env.d.ts +11 -0
  267. package/tsconfig.electron.json +19 -0
  268. package/tsconfig.json +36 -0
  269. package/tsconfig.node.json +12 -0
  270. package/typedoc.json +45 -0
  271. package/vite.config.ts +152 -0
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Global TypeScript Type Declarations
3
+ *
4
+ * This file provides type definitions for globally accessible APIs,
5
+ * particularly the Electron IPC bridge exposed via contextBridge in preload.ts
6
+ */
7
+
8
+ import type {
9
+ HyperlinkProcessingOptions,
10
+ HyperlinkProcessingResult,
11
+ BatchProcessingOptions,
12
+ BatchProcessingResult,
13
+ BatchProgress,
14
+ } from './types/hyperlink';
15
+ import type {
16
+ BackupCreateResponse,
17
+ BackupRestoreResponse,
18
+ BackupListResponse,
19
+ BackupDeleteResponse,
20
+ BackupCleanupResponse,
21
+ BackupVerifyResponse,
22
+ BackupStorageInfoResponse,
23
+ BackupSetConfigResponse,
24
+ BackupConfig,
25
+ } from './types/backup';
26
+ import type {
27
+ SharePointConfig,
28
+ DictionarySyncStatus,
29
+ DictionarySyncResponse,
30
+ DictionaryInitResponse,
31
+ DictionaryCredentialsResponse,
32
+ SyncProgressUpdate,
33
+ } from './types/dictionary';
34
+
35
+ /**
36
+ * Hyperlink lookup result type (from local dictionary)
37
+ */
38
+ export type HyperlinkLookupResult = {
39
+ Document_ID: string;
40
+ Content_ID: string;
41
+ Title: string;
42
+ Status: string;
43
+ };
44
+
45
+ /**
46
+ * ElectronAPI Type Definition
47
+ *
48
+ * Mirrors the electronAPI object exposed via contextBridge in electron/preload.ts
49
+ * This provides full type safety for IPC communication between renderer and main processes
50
+ */
51
+ export type ElectronAPI = {
52
+ // Window controls
53
+ minimizeWindow: () => Promise<void>;
54
+ maximizeWindow: () => Promise<void>;
55
+ closeWindow: () => Promise<void>;
56
+ isMaximized: () => Promise<boolean>;
57
+ isFullscreen: () => Promise<boolean>;
58
+ getAppVersion: () => Promise<string>;
59
+ getPlatform: () => Promise<string>;
60
+ openDevTools: () => Promise<void>;
61
+
62
+ // Always on top (pin window)
63
+ setAlwaysOnTop: (flag: boolean) => Promise<boolean>;
64
+ isAlwaysOnTop: () => Promise<boolean>;
65
+ onAlwaysOnTopChanged: (callback: (isOnTop: boolean) => void) => () => void;
66
+
67
+ // File handling
68
+ selectDocuments: () => Promise<string[]>;
69
+ processDocument: (path: string) => Promise<any>;
70
+ showInFolder: (path: string) => Promise<void>;
71
+ openDocument: (path: string) => Promise<void>;
72
+ getFileStats: (filePath: string) => Promise<any>;
73
+ restoreFromBackup: (backupPath: string, targetPath: string) => Promise<any>;
74
+ getPathsForFiles: (files: File[]) => string[];
75
+
76
+ // Export and Reporting
77
+ selectFolder: () => Promise<string | null>;
78
+ copyFilesToFolder: (
79
+ filePaths: string[],
80
+ destinationFolder: string
81
+ ) => Promise<{ copied: number; skipped: number }>;
82
+ getDownloadsPath: () => Promise<string>;
83
+ createFolder: (folderPath: string) => Promise<boolean>;
84
+ copyFileToFolder: (sourcePath: string, destFolder: string) => Promise<boolean>;
85
+ createReportZip: (folderPath: string, zipName: string) => Promise<string>;
86
+ openOutlookEmail: (subject: string, attachmentPath: string) => Promise<{
87
+ success: boolean;
88
+ method: 'outlook' | 'mailto';
89
+ }>;
90
+
91
+ // Document text extraction (for comparison views)
92
+ extractDocumentText: (filePath: string) => Promise<{
93
+ success: boolean;
94
+ textContent?: string[];
95
+ error?: string;
96
+ }>;
97
+
98
+ // Read file as buffer (for snapshot capture)
99
+ readFileAsBuffer: (filePath: string) => Promise<ArrayBuffer>;
100
+
101
+ // Hyperlink processing
102
+ selectFiles: () => Promise<string[]>;
103
+ processHyperlinkDocument: (
104
+ filePath: string,
105
+ options: HyperlinkProcessingOptions
106
+ ) => Promise<HyperlinkProcessingResult>;
107
+ batchProcessDocuments: (
108
+ filePaths: string[],
109
+ options: BatchProcessingOptions
110
+ ) => Promise<BatchProcessingResult>;
111
+ validateApi: (apiUrl: string) => Promise<{ valid: boolean; error?: string }>;
112
+ callPowerAutomateApi: (
113
+ apiUrl: string,
114
+ payload: {
115
+ Lookup_ID: string[];
116
+ Hyperlinks_Checked: number;
117
+ Total_Hyperlinks: number;
118
+ First_Name: string;
119
+ Last_Name: string;
120
+ Email: string;
121
+ },
122
+ timeout?: number
123
+ ) => Promise<{
124
+ success: boolean;
125
+ statusCode?: number;
126
+ data?: unknown;
127
+ error?: string;
128
+ rawResponse?: string;
129
+ }>;
130
+ cancelOperation: (operationId: string) => Promise<void>;
131
+ onBatchProgress: (callback: (progress: BatchProgress) => void) => () => void;
132
+
133
+ // Window events
134
+ onWindowMaximized: (callback: () => void) => () => void;
135
+ onWindowUnmaximized: (callback: () => void) => () => void;
136
+ onWindowFullscreen: (callback: () => void) => () => void;
137
+ onWindowUnfullscreen: (callback: () => void) => () => void;
138
+
139
+ // Export/Import
140
+ exportSettings: () => Promise<{ success?: boolean; canceled?: boolean; filePath?: string }>;
141
+ importSettings: () => Promise<{ success?: boolean; canceled?: boolean; data?: any }>;
142
+ saveExportData: (filePath: string, data: any) => Promise<{ success?: boolean; error?: string }>;
143
+
144
+ // Backup operations
145
+ backup: {
146
+ create: (documentPath: string) => Promise<BackupCreateResponse>;
147
+ restore: (backupPath: string, targetPath: string) => Promise<BackupRestoreResponse>;
148
+ list: (documentPath: string) => Promise<BackupListResponse>;
149
+ delete: (backupPath: string) => Promise<BackupDeleteResponse>;
150
+ cleanup: (documentPath: string) => Promise<BackupCleanupResponse>;
151
+ cleanupAll: () => Promise<BackupCleanupResponse>;
152
+ verify: (backupPath: string) => Promise<BackupVerifyResponse>;
153
+ getStorageInfo: () => Promise<BackupStorageInfoResponse>;
154
+ setConfig: (config: Partial<BackupConfig>) => Promise<BackupSetConfigResponse>;
155
+ };
156
+
157
+ // Dictionary operations (Local SharePoint Dictionary)
158
+ dictionary: {
159
+ initialize: () => Promise<DictionaryInitResponse>;
160
+ configureSync: (config: SharePointConfig) => Promise<{ success: boolean; error?: string }>;
161
+ setCredentials: (clientSecret: string) => Promise<DictionaryCredentialsResponse>;
162
+ sync: () => Promise<DictionarySyncResponse>;
163
+ startScheduler: (intervalHours: number) => Promise<{ success: boolean; error?: string }>;
164
+ stopScheduler: () => Promise<{ success: boolean; error?: string }>;
165
+ lookup: (lookupId: string) => Promise<{ success: boolean; result?: HyperlinkLookupResult; error?: string }>;
166
+ batchLookup: (lookupIds: string[]) => Promise<{ success: boolean; results?: HyperlinkLookupResult[]; error?: string }>;
167
+ getStatus: () => Promise<{ success: boolean; status?: DictionarySyncStatus; error?: string }>;
168
+ // Interactive SharePoint retrieval (using browser login)
169
+ retrieveFromSharePoint: (fileUrl: string) => Promise<{ success: boolean; entriesImported?: number; error?: string }>;
170
+ sharePointLogin: () => Promise<{ success: boolean; error?: string }>;
171
+ isSharePointAuthenticated: () => Promise<{ authenticated: boolean }>;
172
+ onSyncProgress: (callback: (progress: SyncProgressUpdate) => void) => () => void;
173
+ onSyncComplete: (callback: (result: DictionarySyncResponse) => void) => () => void;
174
+ };
175
+
176
+ // Display/Monitor operations
177
+ display: {
178
+ getAllDisplays: () => Promise<Array<{
179
+ id: number;
180
+ label: string;
181
+ bounds: { x: number; y: number; width: number; height: number };
182
+ workArea: { x: number; y: number; width: number; height: number };
183
+ scaleFactor: number;
184
+ isPrimary: boolean;
185
+ }>>;
186
+ identifyMonitors: () => Promise<{ success: boolean }>;
187
+ openComparison: (
188
+ backupPath: string,
189
+ processedPath: string,
190
+ monitorIndex: number
191
+ ) => Promise<{ success: boolean; error?: string }>;
192
+ };
193
+
194
+ // Auto-updater
195
+ checkForUpdates: () => Promise<any>;
196
+ downloadUpdate: () => Promise<void>;
197
+ installUpdate: () => Promise<void>;
198
+ getCurrentVersion: () => Promise<string>;
199
+
200
+ // SharePoint update source
201
+ setUpdateProvider: (config: { type: 'github' | 'sharepoint'; sharePointUrl?: string }) => Promise<{ success: boolean; error?: string }>;
202
+ testSharePointConnection: (url: string) => Promise<{ success: boolean; message: string; authenticated?: boolean }>;
203
+ sharePointLogin: () => Promise<{ success: boolean; error?: string }>;
204
+ sharePointLogout: () => Promise<void>;
205
+
206
+ // Update event listeners
207
+ onUpdateChecking: (callback: () => void) => () => void;
208
+ onUpdateAvailable: (
209
+ callback: (info: { version: string; releaseDate: string; releaseNotes: string }) => void
210
+ ) => () => void;
211
+ onUpdateNotAvailable: (callback: (info: { version: string }) => void) => () => void;
212
+ onUpdateError: (callback: (error: { message: string }) => void) => () => void;
213
+ onUpdateDownloadProgress: (
214
+ callback: (progress: {
215
+ bytesPerSecond: number;
216
+ percent: number;
217
+ transferred: number;
218
+ total: number;
219
+ }) => void
220
+ ) => () => void;
221
+ onUpdateDownloaded: (
222
+ callback: (info: { version: string; releaseNotes: string; fallbackUsed?: boolean }) => void
223
+ ) => () => void;
224
+ onUpdateFallbackMode: (callback: (data: { message: string }) => void) => () => void;
225
+ onUpdateExtracting: (callback: (data: { message: string }) => void) => () => void;
226
+ onUpdateStatus: (callback: (data: { message: string }) => void) => () => void;
227
+
228
+ // Manual download
229
+ openUpdateInBrowser: () => Promise<void>;
230
+
231
+ // Certificate Management
232
+ checkZscalerStatus: () => Promise<any>;
233
+ getCertificatePath: () => Promise<string>;
234
+ getInstalledCertificates: () => Promise<string[]>;
235
+ importCertificate: () => Promise<{ success?: boolean; name?: string; error?: string }>;
236
+ autoDetectCertificates: () => Promise<{ success: boolean; count?: number }>;
237
+ removeCertificate: (certPath: string) => Promise<{ success?: boolean }>;
238
+ testGitHubConnection: () => Promise<any>;
239
+ openExternal: (url: string) => Promise<void>;
240
+
241
+ // Event system helpers
242
+ on: (channel: string, callback: (...args: any[]) => void) => () => void;
243
+ removeListener: (channel: string, callback: (...args: any[]) => void) => void;
244
+
245
+ // Debug events
246
+ onDebugNetworkRequest: (callback: (data: any) => void) => () => void;
247
+ onDebugCertError: (callback: (data: any) => void) => () => void;
248
+ onDebugNetworkError: (callback: (data: any) => void) => () => void;
249
+ onDebugTLSError: (callback: (data: any) => void) => () => void;
250
+ onUpdateManualDownload: (
251
+ callback: (data: { message: string; downloadUrl: string }) => void
252
+ ) => () => void;
253
+
254
+ // Certificate check events
255
+ onCertificateCheckComplete: (
256
+ callback: (data: { success: boolean; error?: string; timestamp: string }) => void
257
+ ) => () => void;
258
+ onCertificateConfigured: (
259
+ callback: (data: { message: string; certPath?: string }) => void
260
+ ) => () => void;
261
+ };
262
+
263
+ /**
264
+ * Extend the Window interface to include electronAPI
265
+ * This makes window.electronAPI available throughout the application with full type safety
266
+ */
267
+ declare global {
268
+ interface Window {
269
+ electronAPI: ElectronAPI;
270
+ }
271
+ }
272
+
273
+ export {};
@@ -0,0 +1,210 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { useSession } from '@/contexts/SessionContext';
3
+ import type { QueueItem } from '@/types/session';
4
+ import { processingTimeEstimator, ProcessingTimeEstimator } from '@/utils/processingTimeEstimator';
5
+
6
+ export interface UseDocumentQueueOptions {
7
+ onDocumentComplete?: (documentId: string, success: boolean) => void;
8
+ onQueueComplete?: () => void;
9
+ onError?: (documentId: string, error: string) => void;
10
+ }
11
+
12
+ export interface UseDocumentQueueReturn {
13
+ // State
14
+ queue: QueueItem[];
15
+ isProcessing: boolean;
16
+ currentDocumentId: string | null;
17
+ estimatedTimeRemaining: number; // in milliseconds
18
+ estimatedTimeRemainingFormatted: string; // human-readable format
19
+
20
+ // Actions
21
+ addToQueue: (sessionId: string, documentId: string) => void;
22
+ addManyToQueue: (sessionId: string, documentIds: string[]) => void;
23
+ removeFromQueue: (documentId: string) => void;
24
+ clearQueue: () => void;
25
+
26
+ // Utility
27
+ getQueuePosition: (documentId: string) => number; // -1 if not in queue
28
+ isInQueue: (documentId: string) => boolean;
29
+ }
30
+
31
+ export function useDocumentQueue(
32
+ options: UseDocumentQueueOptions = {}
33
+ ): UseDocumentQueueReturn {
34
+ const { processDocument } = useSession();
35
+ const { onDocumentComplete, onQueueComplete, onError } = options;
36
+
37
+ // Use refs for queue management to prevent stale closures
38
+ const queueRef = useRef<QueueItem[]>([]);
39
+ const isProcessingRef = useRef(false);
40
+ const isMountedRef = useRef(true);
41
+
42
+ // State for UI reactivity (synced from refs)
43
+ const [queue, setQueue] = useState<QueueItem[]>([]);
44
+ const [isProcessing, setIsProcessing] = useState(false);
45
+ const [currentDocumentId, setCurrentDocumentId] = useState<string | null>(null);
46
+ const [estimatedTimeRemaining, setEstimatedTimeRemaining] = useState(0);
47
+
48
+ // Sync ref to state for UI updates
49
+ const syncState = useCallback(() => {
50
+ if (isMountedRef.current) {
51
+ setQueue([...queueRef.current]);
52
+ setIsProcessing(isProcessingRef.current);
53
+ // Update estimated time remaining
54
+ const remaining = processingTimeEstimator.estimateRemainingTime(queueRef.current.length);
55
+ setEstimatedTimeRemaining(remaining);
56
+ }
57
+ }, []);
58
+
59
+ // Process next document in queue
60
+ const processNext = useCallback(async () => {
61
+ // Check if we should process
62
+ if (isProcessingRef.current || queueRef.current.length === 0) {
63
+ return;
64
+ }
65
+
66
+ // Get next item that is still queued
67
+ const nextItem = queueRef.current.find(item => item.status === 'queued');
68
+ if (!nextItem) {
69
+ return;
70
+ }
71
+
72
+ // Mark as processing
73
+ isProcessingRef.current = true;
74
+ nextItem.status = 'processing';
75
+ setCurrentDocumentId(nextItem.documentId);
76
+ syncState();
77
+
78
+ // Start timing this document (assume 1 API call per document)
79
+ processingTimeEstimator.startDocument(nextItem.documentId, 1);
80
+
81
+ try {
82
+ // Process the document (this is the IPC call that makes the API request)
83
+ await processDocument(nextItem.sessionId, nextItem.documentId);
84
+
85
+ // Mark as completed
86
+ nextItem.status = 'completed';
87
+ onDocumentComplete?.(nextItem.documentId, true);
88
+ } catch (error) {
89
+ // Mark as error
90
+ nextItem.status = 'error';
91
+ const errorMessage = error instanceof Error ? error.message : 'Processing failed';
92
+ onError?.(nextItem.documentId, errorMessage);
93
+ onDocumentComplete?.(nextItem.documentId, false);
94
+ }
95
+
96
+ // End timing for this document
97
+ processingTimeEstimator.endDocument();
98
+
99
+ // Remove from queue
100
+ queueRef.current = queueRef.current.filter(item => item.documentId !== nextItem.documentId);
101
+ isProcessingRef.current = false;
102
+ setCurrentDocumentId(null);
103
+ syncState();
104
+
105
+ // Check if queue is complete
106
+ if (queueRef.current.length === 0) {
107
+ onQueueComplete?.();
108
+ } else {
109
+ // Process next item with small delay to prevent overwhelming
110
+ setTimeout(processNext, 100);
111
+ }
112
+ }, [processDocument, syncState, onDocumentComplete, onQueueComplete, onError]);
113
+
114
+ // Add single document to queue
115
+ const addToQueue = useCallback((sessionId: string, documentId: string) => {
116
+ // Check if already in queue
117
+ if (queueRef.current.some(item => item.documentId === documentId)) {
118
+ return;
119
+ }
120
+
121
+ const newItem: QueueItem = {
122
+ documentId,
123
+ sessionId,
124
+ addedAt: new Date(),
125
+ status: 'queued',
126
+ };
127
+
128
+ queueRef.current = [...queueRef.current, newItem];
129
+ syncState();
130
+
131
+ // Start processing if not already
132
+ processNext();
133
+ }, [syncState, processNext]);
134
+
135
+ // Add multiple documents to queue
136
+ const addManyToQueue = useCallback((sessionId: string, documentIds: string[]) => {
137
+ const newItems: QueueItem[] = documentIds
138
+ .filter(id => !queueRef.current.some(item => item.documentId === id))
139
+ .map(documentId => ({
140
+ documentId,
141
+ sessionId,
142
+ addedAt: new Date(),
143
+ status: 'queued' as const,
144
+ }));
145
+
146
+ if (newItems.length > 0) {
147
+ queueRef.current = [...queueRef.current, ...newItems];
148
+ syncState();
149
+ processNext();
150
+ }
151
+ }, [syncState, processNext]);
152
+
153
+ // Remove document from queue
154
+ const removeFromQueue = useCallback((documentId: string) => {
155
+ queueRef.current = queueRef.current.filter(item => item.documentId !== documentId);
156
+ syncState();
157
+ }, [syncState]);
158
+
159
+ // Clear entire queue
160
+ const clearQueue = useCallback(() => {
161
+ queueRef.current = [];
162
+ syncState();
163
+ }, [syncState]);
164
+
165
+ // Get queue position for a document
166
+ const getQueuePosition = useCallback((documentId: string): number => {
167
+ return queueRef.current.findIndex(item => item.documentId === documentId);
168
+ }, []);
169
+
170
+ // Check if document is in queue
171
+ const isInQueue = useCallback((documentId: string): boolean => {
172
+ return queueRef.current.some(item => item.documentId === documentId);
173
+ }, []);
174
+
175
+ // Update estimated time remaining periodically while processing
176
+ useEffect(() => {
177
+ if (!isProcessing) return;
178
+
179
+ const updateTimer = setInterval(() => {
180
+ if (isMountedRef.current) {
181
+ const remaining = processingTimeEstimator.estimateRemainingTime(queueRef.current.length);
182
+ setEstimatedTimeRemaining(remaining);
183
+ }
184
+ }, 1000);
185
+
186
+ return () => clearInterval(updateTimer);
187
+ }, [isProcessing]);
188
+
189
+ // Cleanup on unmount
190
+ useEffect(() => {
191
+ isMountedRef.current = true;
192
+ return () => {
193
+ isMountedRef.current = false;
194
+ };
195
+ }, []);
196
+
197
+ return {
198
+ queue,
199
+ isProcessing,
200
+ currentDocumentId,
201
+ estimatedTimeRemaining,
202
+ estimatedTimeRemainingFormatted: ProcessingTimeEstimator.formatTime(estimatedTimeRemaining),
203
+ addToQueue,
204
+ addManyToQueue,
205
+ removeFromQueue,
206
+ clearQueue,
207
+ getQueuePosition,
208
+ isInQueue,
209
+ };
210
+ }
@@ -0,0 +1,55 @@
1
+ import { useState, useCallback } from 'react';
2
+
3
+ export interface Toast {
4
+ id: string;
5
+ title: string;
6
+ description?: string;
7
+ variant?: 'default' | 'destructive' | 'success';
8
+ duration?: number;
9
+ }
10
+
11
+ // Default duration: 3 seconds for quick, unobtrusive notifications
12
+ // Error notifications get slightly longer (4 seconds) for readability
13
+ const DEFAULT_DURATION = 3000;
14
+ const ERROR_DURATION = 4000;
15
+
16
+ export function useToast() {
17
+ const [toasts, setToasts] = useState<Toast[]>([]);
18
+
19
+ const toast = useCallback(
20
+ ({ title, description, variant = 'default', duration }: Omit<Toast, 'id'>) => {
21
+ // Use provided duration, or default based on variant
22
+ const effectiveDuration = duration ?? (variant === 'destructive' ? ERROR_DURATION : DEFAULT_DURATION);
23
+
24
+ const id = Math.random().toString(36).substring(7);
25
+ const newToast: Toast = { id, title, description, variant, duration: effectiveDuration };
26
+
27
+ setToasts((prev) => [...prev, newToast]);
28
+
29
+ // Auto-remove toast after duration
30
+ if (effectiveDuration > 0) {
31
+ setTimeout(() => {
32
+ setToasts((prev) => prev.filter((t) => t.id !== id));
33
+ }, effectiveDuration);
34
+ }
35
+
36
+ return id;
37
+ },
38
+ []
39
+ );
40
+
41
+ const dismiss = useCallback((id: string) => {
42
+ setToasts((prev) => prev.filter((t) => t.id !== id));
43
+ }, []);
44
+
45
+ const dismissAll = useCallback(() => {
46
+ setToasts([]);
47
+ }, []);
48
+
49
+ return {
50
+ toasts,
51
+ toast,
52
+ dismiss,
53
+ dismissAll,
54
+ };
55
+ }
package/src/main.tsx ADDED
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import App from './App';
4
+ import './styles/global.css';
5
+
6
+ ReactDOM.createRoot(document.getElementById('root')!).render(
7
+ <React.StrictMode>
8
+ <App />
9
+ </React.StrictMode>
10
+ );