1// SPDX-License-Identifier: GPL-2-0-only
2// Copyright (c) 2025-present FERS Contributors (see AUTHORS.md).
4import { IconButton, Tooltip } from '@mui/material';
5import FileUploadIcon from '@mui/icons-material/FileUpload';
6import FileDownloadIcon from '@mui/icons-material/FileDownload';
7import { useScenarioStore } from '@/stores/scenarioStore';
8import { invoke } from '@tauri-apps/api/core';
9import { save, open } from '@tauri-apps/plugin-dialog';
10import { writeTextFile } from '@tauri-apps/plugin-fs';
11import { useState } from 'react';
12import ConfirmDialog from './ConfirmDialog';
14export default function ScenarioIO() {
15 const loadScenario = useScenarioStore((state) => state.loadScenario);
16 const isDirty = useScenarioStore((state) => state.isDirty);
17 const resetScenario = useScenarioStore((state) => state.resetScenario);
18 const showError = useScenarioStore((state) => state.showError);
20 const [isConfirmOpen, setConfirmOpen] = useState(false);
22 const handleExport = async () => {
24 await useScenarioStore.getState().syncBackend();
26 const xmlContent = await invoke<string>('get_scenario_as_xml');
28 const filePath = await save({
29 title: 'Export Scenario',
32 name: 'FERS XML Scenario',
33 extensions: ['xml', 'fersxml'],
39 await writeTextFile(filePath, xmlContent);
40 console.log('Scenario exported successfully to:', filePath);
44 error instanceof Error ? error.message : String(error);
45 console.error('Failed to export scenario:', errorMessage);
46 showError(`Export failed: ${errorMessage}`);
50 const performImport = async () => {
52 const selectedPath = await open({
53 title: 'Import Scenario',
57 name: 'FERS XML Scenario',
58 extensions: ['xml', 'fersxml'],
63 if (typeof selectedPath === 'string') {
64 // Load the XML file into the C++ core
65 await invoke('load_scenario_from_xml_file', {
66 filepath: selectedPath,
69 // Fetch the new state as JSON from the C++ core
70 const jsonState = await invoke<string>('get_scenario_as_json');
71 const scenarioData = JSON.parse(jsonState);
73 // Update the UI's Zustand store with the new state after resetting the current state
75 loadScenario(scenarioData);
78 'Scenario imported and synchronized successfully from:',
84 error instanceof Error ? error.message : String(error);
85 console.error('Failed to import scenario:', errorMessage);
86 showError(`Import failed: ${errorMessage}`);
90 const handleImport = () => {
98 const handleConfirmImport = () => {
99 setConfirmOpen(false);
100 void performImport();
103 const handleCancelImport = () => {
104 setConfirmOpen(false);
109 <Tooltip title="Import Scenario (XML)">
110 <IconButton size="small" onClick={handleImport}>
111 <FileUploadIcon fontSize="inherit" />
114 <Tooltip title="Export Scenario (XML)">
115 <IconButton size="small" onClick={handleExport}>
116 <FileDownloadIcon fontSize="inherit" />
121 onConfirm={handleConfirmImport}
122 onCancel={handleCancelImport}
123 title="Overwrite Current Scenario?"
124 message="Importing a new scenario will discard all unsaved changes. Are you sure you want to proceed?"