mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-15 19:10:47 +02:00
# Summary - Adds desktop file tracking: local paths are preserved and save buttons now work as expcted (doing Save/Save As as appropriate) - Adds logic to track whether files are 'dirty' (they've been modified by some tool, and not saved to disk yet). - Improves file state UX (dirty vs saved) and close warnings - Web behaviour should be unaffected by these changes ## Indicators Files now have indicators in desktop mode to tell you their state. ### File up-to-date with disk <img width="318" height="393" alt="image" src="https://github.com/user-attachments/assets/06325f9a-afd7-4c2f-8a5b-6d11e3093115" /> ### File modified by a tool but not saved to disk yet <img width="357" height="385" alt="image" src="https://github.com/user-attachments/assets/1a7716d9-c6f7-4d13-be0d-c1de6493954b" /> ### File not tracked on disk <img width="312" height="379" alt="image" src="https://github.com/user-attachments/assets/9cffe300-bd9a-4e19-97c7-9b98bebefacc" /> # Limitations - It's a bit weird that we still have files stored in indexeddb in the app, which are still loadable. We might want to change this behaviour in the future - Viewer's Save doesn't persist to disk. I've left that out here because it'd need a lot of testing to make sure the logic's right with making sure you can leave the Viewer with applying the changes to the PDF _without_ saving to disk - There's no current way to do Save As on a file that has already been persisted to disk - it's only ever Save. Similarly, there's no way to duplicate a file. --------- Co-authored-by: James Brunton <[email protected]> Co-authored-by: James Brunton <[email protected]>
101 lines
3.1 KiB
TypeScript
101 lines
3.1 KiB
TypeScript
/**
|
|
* Utility functions for converting between automation formats
|
|
*/
|
|
|
|
import { AutomationConfig } from '@app/types/automation';
|
|
import { ToolRegistry } from '@app/data/toolsTaxonomy';
|
|
import { downloadFile } from '@app/services/downloadService';
|
|
import { ToolId } from '@app/types/toolId';
|
|
|
|
/**
|
|
* Pipeline configuration format used by folder scanning
|
|
*/
|
|
interface FolderScanningPipeline {
|
|
name: string;
|
|
pipeline: Array<{
|
|
operation: string;
|
|
parameters: Record<string, any>;
|
|
}>;
|
|
_examples: {
|
|
outputDir: string;
|
|
outputFileName: string;
|
|
};
|
|
outputDir: string;
|
|
outputFileName: string;
|
|
}
|
|
|
|
/**
|
|
* Converts an AutomationConfig to a folder scanning pipeline configuration
|
|
* @param automation The automation configuration to convert
|
|
* @param toolRegistry The tool registry to map operation types to endpoints
|
|
* @returns Folder scanning pipeline configuration
|
|
*/
|
|
export function convertToFolderScanningConfig(
|
|
automation: AutomationConfig,
|
|
toolRegistry: Partial<ToolRegistry>
|
|
): FolderScanningPipeline {
|
|
return {
|
|
name: automation.name,
|
|
pipeline: automation.operations.map(op => {
|
|
// Map operationType to full API endpoint path
|
|
const toolId = op.operation as ToolId;
|
|
const toolEntry = toolRegistry[toolId];
|
|
const endpointConfig = toolEntry?.operationConfig?.endpoint;
|
|
|
|
let endpoint: string | undefined;
|
|
|
|
if (typeof endpointConfig === 'string') {
|
|
endpoint = endpointConfig;
|
|
} else if (typeof endpointConfig === 'function') {
|
|
// For dynamic endpoints, call with the saved parameters
|
|
try {
|
|
endpoint = endpointConfig(op.parameters);
|
|
} catch (error) {
|
|
console.warn(
|
|
`Failed to resolve dynamic endpoint for operation "${op.operation}". ` +
|
|
`This may happen if the tool requires specific parameters. ` +
|
|
`Error: ${error}`
|
|
);
|
|
}
|
|
}
|
|
|
|
if (!endpoint) {
|
|
console.warn(
|
|
`No endpoint found for operation "${op.operation}". ` +
|
|
`This operation may fail in folder scanning. ` +
|
|
`Using operation type as fallback.`
|
|
);
|
|
}
|
|
|
|
return {
|
|
operation: endpoint || op.operation,
|
|
parameters: {
|
|
...op.parameters,
|
|
fileInput: "automated"
|
|
}
|
|
};
|
|
}),
|
|
_examples: {
|
|
outputDir: "{outputFolder}/{folderName}",
|
|
outputFileName: "{filename}-{pipelineName}-{date}-{time}"
|
|
},
|
|
outputDir: "{outputFolder}",
|
|
outputFileName: "{filename}"
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Downloads a folder scanning configuration as a JSON file
|
|
* @param automation The automation configuration to export
|
|
* @param toolRegistry The tool registry to map operation types to endpoints
|
|
*/
|
|
export function downloadFolderScanningConfig(
|
|
automation: AutomationConfig,
|
|
toolRegistry: Partial<ToolRegistry>
|
|
): void {
|
|
const config = convertToFolderScanningConfig(automation, toolRegistry);
|
|
const json = JSON.stringify(config, null, 2);
|
|
const blob = new Blob([json], { type: 'application/json' });
|
|
void downloadFile({ data: blob, filename: `${automation.name}.json` });
|
|
}
|