Archiv-Wechsel mit Migrations-Option

Bei gesetztem Archiv-Home fragt ein Dialog nach: Dokumente ins neue
Archiv verschieben (Checkbox, standardmäßig aus — nichts wandert
implizit) oder liegen lassen. change_archive_home_cmd setzt das neue
Home, zieht auf Wunsch die Einträge um (gleiche Platte rename, sonst
Kopie + Löschen; Kollision im Ziel bricht laut ab) und nimmt die Rechte
des alten Ordners zurück.
This commit is contained in:
marcus hinz
2026-07-20 13:48:49 +02:00
parent 347fc70982
commit cf2c25df79
8 changed files with 180 additions and 2 deletions
+52 -1
View File
@@ -238,11 +238,22 @@ async function removeWorkDir(dir: string) {
// Archiv-Home schreibt wie die Arbeitsordner direkt (Config + Permissions);
// ohne Archiv zeigt das Panel nur Befehle und Dokument. Greift ab dem
// nächsten Session-Start.
// nächsten Session-Start. Ist schon eins gesetzt, fragt ein Dialog nach —
// mit der Option, die Dokumente mitzunehmen (nichts wird implizit verschoben).
interface PendingArchiveChange {
dir: string;
migrate: boolean;
}
const pendingArchive = ref<PendingArchiveChange | null>(null);
async function chooseArchive() {
const s = settings.value!;
const dir = await open({ directory: true, multiple: false });
if (typeof dir !== "string") return;
if (s.archiveHome && s.archiveHome !== dir) {
pendingArchive.value = { dir, migrate: false };
return;
}
try {
await invoke("set_archive_home_cmd", { project: s.id, dir });
s.archiveHome = await invoke<string | null>("panel_archive_dir_cmd", {
@@ -253,6 +264,21 @@ async function chooseArchive() {
}
}
async function confirmArchiveChange() {
const s = settings.value!;
const a = pendingArchive.value!;
try {
await invoke("change_archive_home_cmd", { project: s.id, dir: a.dir, migrate: a.migrate });
s.archiveHome = await invoke<string | null>("panel_archive_dir_cmd", {
project: s.id,
});
pendingArchive.value = null;
} catch (e) {
error.value = String(e);
pendingArchive.value = null;
}
}
async function clearArchive() {
const s = settings.value!;
try {
@@ -812,6 +838,31 @@ onUnmounted(() => window.clearInterval(timer));
</div>
</div>
<div v-if="pendingArchive && settings" class="overlay" @click.self="pendingArchive = null">
<div class="dialog">
<h3>{{ $t("projects.archiveChangeTitle") }}</h3>
<p>
{{ $t("projects.archiveChangeText", {
old: contractHome(settings.archiveHome ?? ""),
neu: contractHome(pendingArchive.dir),
}) }}
</p>
<label class="checkline">
<input v-model="pendingArchive.migrate" type="checkbox" />
{{ $t("projects.archiveMigrate") }}
</label>
<p class="hint">{{ $t("projects.archiveMigrateHint") }}</p>
<div class="actions">
<button type="button" @click="pendingArchive = null">
{{ $t("projects.cancel") }}
</button>
<button class="primary" @click="confirmArchiveChange">
{{ $t("projects.archiveChangeConfirm") }}
</button>
</div>
</div>
</div>
<div v-if="pending" class="overlay">
<div class="dialog">
<h3>{{ $t("projects.stillRunning", { name: pending.name }) }}</h3>
+12
View File
@@ -93,6 +93,12 @@ const de = {
artWorkDir: "Arbeitsordner {path}",
todo: "Todoliste",
todoDesc: "OFFENE-PUNKTE.md bei jedem Sessionstart einspielen",
archiveChangeTitle: "Archiv wechseln",
archiveChangeText: "Das Archiv wechselt von {old} nach {neu}.",
archiveMigrate: "Dokumente ins neue Archiv verschieben",
archiveMigrateHint:
"Ohne Haken bleibt das bisherige Archiv unverändert liegen; die App verweist künftig nur noch auf das neue.",
archiveChangeConfirm: "Wechseln",
groupAppearance: "Darstellung",
groupFolders: "Ordner",
groupSession: "Session",
@@ -236,6 +242,12 @@ const en: typeof de = {
artWorkDir: "working folder {path}",
todo: "Todo list",
todoDesc: "Inject OFFENE-PUNKTE.md at every session start",
archiveChangeTitle: "Change archive",
archiveChangeText: "The archive changes from {old} to {neu}.",
archiveMigrate: "Move documents to the new archive",
archiveMigrateHint:
"Unchecked, the previous archive stays untouched; the app just points to the new one.",
archiveChangeConfirm: "Change",
groupAppearance: "Appearance",
groupFolders: "Folders",
groupSession: "Session",