mirror of
https://github.com/narrrl/narl-workspace.git
synced 2026-11-03 16:41:27 +01:00
trash: a delete can be undone
`x`, `dd`, `:delete` and `:rmspace` no longer end anything. What they delete is moved, whole, under one hidden root, and `u` puts the last of it back where it was. `:trash` lists everything deleted, the last first: Enter or `r` restores, `x` deletes one for good and `:trash purge` empties it, each asking first. Something whose folder has gone since comes back to the root of its space; something whose space is in the trash too waits for the space. The daily sweep purges what has waited WORKSPACE_TRASH_DAYS (30), and only then are its files deleted. While it waits, a trashed node is out of the tree, the search, the agenda, the mails, the SFTP mount, the export and the readable files/ view, and a shared document answers 404 until it comes back with the same link. `rm` over the mount trashes too; a rename onto a taken name still replaces what was there, so editor saves do not fill the trash.
This commit is contained in:
1 parent
439d5b083b
commit
8ffad6350f
22 files changed
+1154
-78
No files matched your search
+28
-2
@@ -23,7 +23,7 @@ export interface NodeSummary {
|
||||
excerpt: string
|
||||
position: number
|
||||
has_board: boolean
|
||||
/** Spaces the app has to tell apart: `diary`, or nothing. */
|
||||
/** Nodes the app has to tell apart: `diary`, `trash`, or nothing. */
|
||||
role: string | null
|
||||
child_count: number
|
||||
created_at: number
|
||||
@@ -78,6 +78,21 @@ export interface SshKey {
|
||||
vault: boolean
|
||||
}
|
||||
|
||||
/** Something deleted, waiting in the trash to be restored or purged. */
|
||||
export interface TrashItem {
|
||||
id: number
|
||||
kind: NodeKind
|
||||
name: string
|
||||
slug: string
|
||||
/** The folder it was deleted from, `work/notes`; empty for a space. */
|
||||
from: string
|
||||
deleted_at: number
|
||||
/** When the sweep deletes it for good. */
|
||||
purge_at: number
|
||||
/** How many nodes are inside it. */
|
||||
inside: number
|
||||
}
|
||||
|
||||
export interface SharedDocument {
|
||||
name: string
|
||||
body: string
|
||||
@@ -383,8 +398,19 @@ export const api = {
|
||||
input: { name: string; body: string; created_at?: number; has_board?: boolean; base_updated_at?: number },
|
||||
) => request<WorkspaceNode>(`/nodes/${id}`, { method: 'PUT', body: body(input) }),
|
||||
|
||||
/** Into the trash; `purged` when it was in the trash already and is now gone. */
|
||||
deleteNode: (id: number) =>
|
||||
request<{ ok: true; removed: number }>(`/nodes/${id}`, { method: 'DELETE' }),
|
||||
request<{ ok: true; removed: number; purged: boolean }>(`/nodes/${id}`, { method: 'DELETE' }),
|
||||
|
||||
trash: () => request<TrashItem[]>('/trash'),
|
||||
|
||||
/** Back where it was; `elsewhere` when that folder is gone and it went to its space. */
|
||||
restore: (id: number) =>
|
||||
request<{ node: WorkspaceNode; elsewhere: boolean }>(`/trash/${id}/restore`, { method: 'POST' }),
|
||||
|
||||
purge: (id: number) => request<{ ok: true; removed: number }>(`/trash/${id}`, { method: 'DELETE' }),
|
||||
|
||||
emptyTrash: () => request<{ ok: true; removed: number }>('/trash', { method: 'DELETE' }),
|
||||
|
||||
moveNode: (id: number, parent_id: number, position?: number) =>
|
||||
request<WorkspaceNode>(`/nodes/${id}/move`, { method: 'POST', body: body({ parent_id, position }) }),
|
||||
|
||||
Reference in new issue
Block a user