Prevent workspace name collisions

Adding explicit duplicate-name checks to the Tauri commands that create
workspaces prevents a new workspace from silently overwriting an
existing one. The change returns an error if a workspace with the given
name already exists.

Also set sane defaults in the setup UI: default workspace name to "Onyx"
for both local and WebDAV flows, default the local folder to the user's
Documents directory via documentDir(), and ensure the create flow resets
the name to the "Onyx" default when starting creation.
This commit is contained in:
Tristan Michael 2026-04-05 14:49:55 -07:00
parent 095ac8fa97
commit a709df609f
2 changed files with 12 additions and 3 deletions

View file

@ -120,6 +120,9 @@ fn add_workspace(
state: State<'_, Mutex<AppState>>,
) -> Result<(), String> {
let mut s = lock_state(&state)?;
if s.config.workspaces.contains_key(&name) {
return Err(format!("A workspace named '{}' already exists", name));
}
let ws = WorkspaceConfig::new(PathBuf::from(&path));
s.config.add_workspace(name.clone(), ws);
s.config
@ -569,6 +572,9 @@ fn add_webdav_workspace(
state: State<'_, Mutex<AppState>>,
) -> Result<(), String> {
let mut s = lock_state(&state)?;
if s.config.workspaces.contains_key(&name) {
return Err(format!("A workspace named '{}' already exists", name));
}
let managed_dir = s.app_data_dir.join("workspaces").join(&name);
std::fs::create_dir_all(&managed_dir).map_err(|e| e.to_string())?;
TaskRepository::init(managed_dir.clone()).map(|_| ()).map_err(|e| e.to_string())?;

View file

@ -1,5 +1,6 @@
<script lang="ts">
import { invoke } from "@tauri-apps/api/core";
import { documentDir } from "@tauri-apps/api/path";
import { open } from "@tauri-apps/plugin-dialog";
import { app } from "../stores/app.svelte";
import { getCurrentWindow } from "@tauri-apps/api/window";
@ -15,9 +16,11 @@
// ── Shared state ──────────────────────────────────────────────────
let mode = $state<"local" | "webdav" | null>(isMobile ? "webdav" : null);
let name = $state("");
let name = $state("Onyx");
let path = $state("");
documentDir().then((d) => { path = d; }).catch(() => {});
// ── WebDAV state ──────────────────────────────────────────────────
let webdavUrl = $state("");
let webdavUser = $state("");
@ -37,7 +40,7 @@
let previewLoading = $state(false);
// Create workspace state
let createName = $state("");
let createName = $state("Onyx");
let creating = $state(false);
// ── Derived ───────────────────────────────────────────────────────
@ -157,7 +160,7 @@
}
function startCreate() {
createName = "";
createName = "Onyx";
webdavStep = "create";
}