diff --git a/frontend/src/components/spectrogram/SpectrogramVizContainer.tsx b/frontend/src/components/spectrogram/SpectrogramVizContainer.tsx
index 0a2aa87..b056f0e 100644
--- a/frontend/src/components/spectrogram/SpectrogramVizContainer.tsx
+++ b/frontend/src/components/spectrogram/SpectrogramVizContainer.tsx
@@ -91,6 +91,38 @@ const SpectrogramVizContainer = ({
}
};
+ const handleSaveSpectrogram = async () => {
+ if (!spectrogramUrl) return;
+
+ try {
+ // Fetch the image blob
+ const response = await fetch(spectrogramUrl);
+ const blob = await response.blob();
+
+ // Create a download link
+ const downloadUrl = URL.createObjectURL(blob);
+ const link = document.createElement('a');
+ link.href = downloadUrl;
+
+ // Generate filename based on timestamp and visualization UUID
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
+ const filename = `spectrogram-${visualizationRecord.uuid}-${timestamp}.png`;
+
+ link.download = filename;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ URL.revokeObjectURL(downloadUrl);
+ } catch (error) {
+ console.error('Error saving spectrogram:', error);
+ setJobInfo((prevStatus) => ({
+ ...prevStatus,
+ status: 'error',
+ message: 'Failed to save spectrogram',
+ }));
+ }
+ };
+
/**
* Once a job is created, periodically poll the server to check its status
*/
@@ -184,6 +216,7 @@ const SpectrogramVizContainer = ({
diff --git a/frontend/src/components/spectrogram/index.tsx b/frontend/src/components/spectrogram/index.tsx
index d868fb3..9c9f334 100644
--- a/frontend/src/components/spectrogram/index.tsx
+++ b/frontend/src/components/spectrogram/index.tsx
@@ -1,16 +1,19 @@
interface SpectrogramVisualizationProps {
imageUrl: string | null;
hasError: boolean;
+ onSave?: () => void;
}
/**
* Renders a spectrogram visualization or placeholder based on provided image URL
* @param imageUrl - URL of the spectrogram image to display
* @param hasError - Whether there was an error generating the spectrogram
+ * @param onSave - Optional callback function to handle saving the spectrogram
*/
const SpectrogramVisualization = ({
imageUrl,
hasError,
+ onSave,
}: SpectrogramVisualizationProps) => {
return (
{imageUrl ? (
-

+ <>
+

+ {onSave && (
+
+ )}
+ >
) : (
{hasError
diff --git a/frontend/src/components/waterfall/WaterfallPlot.tsx b/frontend/src/components/waterfall/WaterfallPlot.tsx
index 4275e04..bb45114 100644
--- a/frontend/src/components/waterfall/WaterfallPlot.tsx
+++ b/frontend/src/components/waterfall/WaterfallPlot.tsx
@@ -581,7 +581,10 @@ export function WaterfallPlot({
/>
)}
-
+