fix: expose pseudonymized copy location in Raycast
This commit is contained in:
@@ -218,6 +218,7 @@ function HitReview(props: { root: string; rules: ProjectRule[]; whitelist: Proje
|
||||
const [stage, setStage] = useState<"selection" | "merge">("selection");
|
||||
const [personMerges, setPersonMerges] = useState<Record<string, string>>({});
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [completed, setCompleted] = useState<{ directory: string; inPlace: boolean; files: number } | null>(null);
|
||||
const accepted = useMemo(() => new Set(groups.filter((group) => selectedGroups.has(group.key))
|
||||
.flatMap((group) => group.hits.map((hit) => hit.id))), [groups, selectedGroups]);
|
||||
const selectedOccurrences = accepted.size;
|
||||
@@ -351,6 +352,9 @@ function HitReview(props: { root: string; rules: ProjectRule[]; whitelist: Proje
|
||||
}
|
||||
toast.style = Toast.Style.Success;
|
||||
toast.title = inPlace ? `${replacements.length} Dateien ersetzt` : `${run.files.length} Kopien erstellt`;
|
||||
toast.message = inPlace ? "Die Sicherung ist im Raycast-Datenordner gespeichert."
|
||||
: "Die Kopien sind im Raycast-Datenordner gespeichert.";
|
||||
setCompleted({ directory: join(directory, inPlace ? "backup" : "files"), inPlace, files: run.files.length });
|
||||
await showInFinder(inPlace ? props.root : join(directory, "files")).catch(() => undefined);
|
||||
} catch (error) {
|
||||
if (directory && !persisted) await fs.rm(directory, { recursive: true, force: true });
|
||||
@@ -360,6 +364,18 @@ function HitReview(props: { root: string; rules: ProjectRule[]; whitelist: Proje
|
||||
} finally { setBusy(false); }
|
||||
}
|
||||
|
||||
if (completed) return <List navigationTitle="Pseudonymisierung abgeschlossen">
|
||||
<List.Item icon={Icon.CheckCircle}
|
||||
title={completed.inPlace ? "Projektdateien ersetzt" : `${completed.files} pseudonymisierte Kopien erstellt`}
|
||||
subtitle={completed.inPlace ? "Die Originale wurden gesichert."
|
||||
: "Die Originaldateien im Projektordner bleiben unverändert."}
|
||||
actions={<ActionPanel>
|
||||
<Action title={completed.inPlace ? "Sicherung im Finder anzeigen" : "Kopien im Finder anzeigen"}
|
||||
icon={Icon.Folder} onAction={() => showInFinder(completed.directory)} />
|
||||
<Action.CopyToClipboard title="Speicherpfad kopieren" content={completed.directory} />
|
||||
</ActionPanel>} />
|
||||
</List>;
|
||||
|
||||
if (stage === "merge") return <List isLoading={busy} navigationTitle="Personen zusammenfassen"
|
||||
searchBarPlaceholder="Person oder Platzhalter suchen">
|
||||
<List.Section title="Abschluss">
|
||||
@@ -415,7 +431,8 @@ function HitReview(props: { root: string; rules: ProjectRule[]; whitelist: Proje
|
||||
icon={{ source: selectedGroups.has(group.key) ? Icon.CheckCircle : Icon.Circle,
|
||||
tintColor: selectedGroups.has(group.key) ? Color.Green : Color.SecondaryText }}
|
||||
title={group.original} subtitle={`→ ${group.placeholder}`}
|
||||
accessories={[{ text: `${group.hits.length} Vorkommen` }]}
|
||||
accessories={[{ text: `${group.hits.length} Vorkommen` },
|
||||
...(group.hits.some((hit) => hit.source === "Kommentarautor") ? [{ text: "Word-Kommentator" }] : [])]}
|
||||
keywords={[type, labelForType(type)]}
|
||||
actions={<ActionPanel>
|
||||
<Action title={selectedGroups.has(group.key) ? "Zuordnung abwählen" : "Zuordnung auswählen"}
|
||||
@@ -566,7 +583,7 @@ export default function Command() {
|
||||
onChange={setRules} placeholder={"BEGRIFF: KundenSuite\nPERSON: Max Mustermann"}
|
||||
info="Ein Begriff pro Zeile. Ohne Typ wird BEGRIFF verwendet. Diese Regeln werden nur für dieses Projekt gespeichert und bei der Velum-Anfrage mitgesendet." />
|
||||
<Form.TagPicker id="entityTypes" title="Kategorien pseudonymisieren" value={selectedTypes}
|
||||
onChange={setSelectedTypes} info="Die Auswahl wird beim Prüfen für diesen Projektordner gespeichert. Bei neuen Projekten sind Orte wegen häufiger Fehlalarme zunächst abgewählt.">
|
||||
onChange={setSelectedTypes} info="Die Auswahl wird beim Prüfen für diesen Projektordner gespeichert. Word-Kommentatoren werden nur mit der Kategorie Personen maskiert. Bei neuen Projekten sind Orte zunächst abgewählt.">
|
||||
{availableTypes.map((type) => <Form.TagPicker.Item key={type} value={type} title={labelForType(type)} />)}
|
||||
</Form.TagPicker>
|
||||
<Form.Description title="Projekt-Whitelist" text={`${whitelist.length} Begriffe werden bei diesem Ordner nicht mehr vorgeschlagen. Über die Aktionen kannst du sie wieder freigeben.`} />
|
||||
|
||||
@@ -198,6 +198,9 @@ function ProjectHistory(props: { projectName: string; entries: SavedRun[] }) {
|
||||
title={new Date(run.createdAt).toLocaleString("de-AT")}
|
||||
subtitle={`${run.files.length} Dateien`}
|
||||
actions={<ActionPanel>
|
||||
<Action title="Pseudonymisierte Kopien im Finder anzeigen" icon={Icon.Folder}
|
||||
onAction={() => showInFinder(join(directory, "files"))} />
|
||||
<Action.CopyToClipboard title="Speicherpfad kopieren" content={join(directory, "files")} />
|
||||
<Action title="Dateien als Klartext exportieren" icon={Icon.Download}
|
||||
onAction={() => push(<FilePicker run={run} directory={directory} />)} />
|
||||
</ActionPanel>} />)}
|
||||
@@ -229,6 +232,9 @@ export default function Command() {
|
||||
accessories={[{ text: `${run.files.length} Dateien` }, { text: new Date(run.createdAt).toLocaleString("de-AT") },
|
||||
...(entries.length > 1 ? [{ text: `${entries.length} Stände` }] : [])]}
|
||||
actions={<ActionPanel>
|
||||
<Action title="Pseudonymisierte Kopien im Finder anzeigen" icon={Icon.Folder}
|
||||
onAction={() => showInFinder(join(directory, "files"))} />
|
||||
<Action.CopyToClipboard title="Speicherpfad kopieren" content={join(directory, "files")} />
|
||||
<Action title="Aktuellen Stand nachbearbeiten" icon={Icon.Pencil}
|
||||
onAction={() => push(<RevisionReview saved={{ run, directory }} onSaved={refresh} />)} />
|
||||
<Action title="Aktuelle Dateien als Klartext exportieren" icon={Icon.Download}
|
||||
|
||||
Reference in New Issue
Block a user