Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 167 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
"@fontsource/ibm-plex-sans": "^5.3.0",
"@strata/core": "*",
"@tauri-apps/api": "^2.12.0",
"@tauri-apps/plugin-dialog": "^2.8.2",
"@tauri-apps/plugin-fs": "^2.7.0",
"class-variance-authority": "^0.7.1",
"cn": "^0.4.0",
"leaflet": "^1.9.4",
"lucide-react": "^1.48.0",
"pdf-lib": "^1.17.1",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-leaflet": "^5.0.0",
Expand Down
2 changes: 2 additions & 0 deletions app/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ tauri-build = { version = "2", features = [] }

[dependencies]
tauri = { version = "2", features = [] }
tauri-plugin-dialog = "2"
tauri-plugin-fs = "2"
serde = { version = "1", features = ["derive"] }
strata_db = { path = "../../strata/core/db" }
# Must stay the same version as strata_db's, so both use one SQLite and one Connection type.
Expand Down
2 changes: 1 addition & 1 deletion app/src-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": ["core:default"]
"permissions": ["core:default", "dialog:allow-save", "fs:allow-write-file"]
}
3 changes: 3 additions & 0 deletions app/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ fn load_data(app: tauri::AppHandle) -> Result<data::Records, data::LoadError> {

pub fn run() {
tauri::Builder::default()
// Saving a section as a picture or PDF: the Save dialog, and writing the file chosen there.
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_fs::init())
.setup(|app| Ok(open_main_window(app)?))
.invoke_handler(tauri::generate_handler![load_data])
.run(tauri::generate_context!())
Expand Down
11 changes: 8 additions & 3 deletions app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ import { useModel } from "@/lib/useModel";
import { text } from "@/text";
import { MapView } from "@/views/MapView";
import { QualityView } from "@/views/QualityView";
import { SectionView } from "@/views/SectionView";

type State = { records: Records; as: string } | { problem: LoadError } | null;
type View = "map" | "quality";
type View = "map" | "section" | "quality";

export default function App() {
const [state, setState] = useState<State>(null);
const [view, setView] = useState<View>("map");
// The section's map is first drawn when it is first shown: a map set up while hidden has no size to fit the borewells to.
const [sectionSeen, setSectionSeen] = useState(false);
if (view === "section" && !sectionSeen) setSectionSeen(true);

// Reading again keeps what is on screen until the new records arrive, so the map does not blink.
// Records that turn out unchanged are kept as they are, so nothing is worked out again for them.
Expand Down Expand Up @@ -42,7 +46,7 @@ export default function App() {
<h1 className="text-base font-semibold">{text.appName}</h1>
{records && (
<nav className="flex gap-1">
{(["map", "quality"] as const).map((v) => (
{(["map", "section", "quality"] as const).map((v) => (
<Button key={v} variant={view === v ? "secondary" : "ghost"} size="sm" aria-current={view === v ? "page" : undefined} onClick={() => setView(v)}>
{text.tabs[v]}
</Button>
Expand All @@ -56,8 +60,9 @@ export default function App() {
: !records ? <Message>{text.empty}</Message>
: (
<>
{/* The map stays mounted behind Data quality, so it keeps its place and the picked spot. */}
{/* The maps stay mounted behind the other screens, so they keep their place, the picked spot and the line. */}
<div className={view === "map" ? "flex min-h-0 flex-1" : "hidden"}><MapView records={records} model={model} onHowGood={() => setView("quality")} /></div>
{sectionSeen && <div className={view === "section" ? "flex min-h-0 flex-1" : "hidden"}><SectionView records={records} model={model} onHowGood={() => setView("quality")} /></div>}
{view === "quality" && <QualityView model={model} />}
</>
)}
Expand Down
Loading
Loading