Posthog, scarf and url navigation overhaul (#4318)

Added post hog project - always enabled
Added scarf pixel - Always enabled 
Reworked Url navigation 
Forward and back now works without reloading page

---------

Co-authored-by: Connor Yoh <[email protected]>
This commit is contained in:
ConnorYoh
2025-08-28 15:42:33 +01:00
committed by GitHub
co-authored by Connor Yoh
parent 5b20f11e20
commit a7d5c80188
31 changed files with 945 additions and 882 deletions
+11 -34
View File
@@ -1,42 +1,19 @@
/**
* Shared navigation types to avoid circular dependencies
* Navigation types for workbench and tool separation
*/
// Navigation mode types - complete list to match contexts
export type ModeType =
| 'viewer'
| 'pageEditor'
| 'fileEditor'
| 'merge'
| 'split'
| 'compress'
| 'ocr'
| 'convert'
| 'sanitize'
| 'addPassword'
| 'changePermissions'
| 'addWatermark'
| 'removePassword'
| 'single-large-page'
| 'repair'
| 'unlockPdfForms'
| 'removeCertificateSign';
import { WorkbenchType } from './workbench';
import { ToolId } from './toolId';
// Utility functions for mode handling
export const isValidMode = (mode: string): mode is ModeType => {
const validModes: ModeType[] = [
'viewer', 'pageEditor', 'fileEditor', 'merge', 'split',
'compress', 'ocr', 'convert', 'addPassword', 'changePermissions',
'sanitize', 'addWatermark', 'removePassword', 'single-large-page',
'repair', 'unlockPdfForms', 'removeCertificateSign'
];
return validModes.includes(mode as ModeType);
};
// Navigation state
export interface NavigationState {
workbench: WorkbenchType;
selectedTool: ToolId | null;
}
export const getDefaultMode = (): ModeType => 'fileEditor';
// Route parsing result
export interface ToolRoute {
mode: ModeType;
toolKey: string | null;
}
workbench: WorkbenchType;
toolId: ToolId | null;
}
+6 -3
View File
@@ -2,10 +2,12 @@
* Navigation action interfaces to break circular dependencies
*/
import { ModeType } from './navigation';
import { WorkbenchType } from './workbench';
import { ToolId } from './toolId';
export interface NavigationActions {
setMode: (mode: ModeType) => void;
setWorkbench: (workbench: WorkbenchType) => void;
setSelectedTool: (toolId: ToolId | null) => void;
setHasUnsavedChanges: (hasChanges: boolean) => void;
showNavigationWarning: (show: boolean) => void;
requestNavigation: (navigationFn: () => void) => void;
@@ -14,7 +16,8 @@ export interface NavigationActions {
}
export interface NavigationState {
currentMode: ModeType;
workbench: WorkbenchType;
selectedTool: ToolId | null;
hasUnsavedChanges: boolean;
pendingNavigation: (() => void) | null;
showNavigationWarning: boolean;
+25
View File
@@ -0,0 +1,25 @@
// Define all possible tool IDs as source of truth
const TOOL_IDS = [
'certSign', 'sign', 'addPassword', 'remove-password', 'removePages', 'remove-blank-pages', 'remove-annotations', 'remove-image',
'change-permissions', 'addWatermark',
'sanitize', 'auto-split-pages', 'auto-split-by-size-count', 'split', 'mergePdfs',
'convert', 'ocr', 'add-image', 'rotate',
'detect-split-scanned-photos',
'edit-table-of-contents',
'scanner-effect',
'auto-rename-pdf-file', 'multi-page-layout', 'adjust-page-size-scale', 'adjust-contrast', 'cropPdf', 'single-large-page', 'multi-tool',
'repair', 'compare', 'addPageNumbers', 'redact',
'flatten', 'remove-certificate-sign',
'unlock-pdf-forms', 'compress', 'extract-page', 'reorganize-pages', 'extract-images',
'add-stamp', 'add-attachments', 'change-metadata', 'overlay-pdfs',
'manage-certificates', 'get-all-info-on-pdf', 'validate-pdf-signature', 'read', 'automate', 'replace-and-invert-color',
'show-javascript', 'dev-api', 'dev-folder-scanning', 'dev-sso-guide', 'dev-airgapped'
] as const;
// Tool identity - what PDF operation we're performing (type-safe)
export type ToolId = typeof TOOL_IDS[number];
// Type guard using the same source of truth
export const isValidToolId = (value: string): value is ToolId => {
return TOOL_IDS.includes(value as ToolId);
};
+12
View File
@@ -0,0 +1,12 @@
// Define workbench values once as source of truth
const WORKBENCH_TYPES = ['viewer', 'pageEditor', 'fileEditor'] as const;
// Workbench types - how the user interacts with content
export type WorkbenchType = typeof WORKBENCH_TYPES[number];
export const getDefaultWorkbench = (): WorkbenchType => 'fileEditor';
// Type guard using the same source of truth
export const isValidWorkbench = (value: string): value is WorkbenchType => {
return WORKBENCH_TYPES.includes(value as WorkbenchType);
};