|
15 | 15 | type TreeItemState,
|
16 | 16 | } from "svelte-file-tree";
|
17 | 17 | import { toast } from "svelte-sonner";
|
18 |
| - import ConfirmRemoveDialog from "./ConfirmRemoveDialog.svelte"; |
19 |
| - import ResolveConflictDialog from "./ResolveConflictDialog.svelte"; |
| 18 | + import ConfirmDialog from "./ConfirmDialog.svelte"; |
20 | 19 | import TreeItem from "./TreeItem.svelte";
|
21 | 20 | import type { TreeProps } from "./types.js";
|
22 | 21 |
|
|
28 | 27 | let borderAnimationTargetId: string | undefined = $state.raw();
|
29 | 28 | let borderAnimationTimeout: number | undefined;
|
30 | 29 |
|
31 |
| - let confirmRemoveDialog: ConfirmRemoveDialog | null = $state.raw(null); |
32 |
| - let resolveConflictDialog: ResolveConflictDialog | null = $state.raw(null); |
| 30 | + let confirmDialog: ConfirmDialog | null = $state.raw(null); |
33 | 31 |
|
34 | 32 | function startBorderAnimation(targetId: string) {
|
35 | 33 | if (borderAnimationTimeout !== undefined) {
|
|
46 | 44 | nodes.sort((a, b) => a.name.localeCompare(b.name));
|
47 | 45 | }
|
48 | 46 |
|
49 |
| - function onResolveNameConflict({ operation, name }: OnResolveNameConflictArgs) { |
| 47 | + async function onResolveNameConflict({ operation, name }: OnResolveNameConflictArgs) { |
50 | 48 | let title: string;
|
51 | 49 | switch (operation) {
|
52 | 50 | case "copy": {
|
|
59 | 57 | }
|
60 | 58 | }
|
61 | 59 |
|
62 |
| - return resolveConflictDialog!.show({ |
| 60 | + const didConfirm = await confirmDialog!.show({ |
63 | 61 | title,
|
64 | 62 | description: `An item named "${name}" already exists in this location. Do you want to skip it or cancel the operation entirely?`,
|
| 63 | + confirmLabel: "Skip", |
65 | 64 | });
|
| 65 | + return didConfirm ? "skip" : "cancel"; |
66 | 66 | }
|
67 | 67 |
|
68 | 68 | function onCircularReference({ source }: OnCircularReferenceArgs) {
|
69 | 69 | toast.error(`Cannot move "${source.node.name}" inside itself`);
|
70 | 70 | }
|
71 | 71 |
|
72 | 72 | function canRemove({ removed }: OnRemoveArgs) {
|
73 |
| - return confirmRemoveDialog!.show({ |
| 73 | + return confirmDialog!.show({ |
74 | 74 | title: `Are you sure you want to delete ${removed.length} item(s)?`,
|
75 | 75 | description: "They will be permanently deleted. This action cannot be undone.",
|
| 76 | + confirmLabel: "Confirm", |
76 | 77 | });
|
77 | 78 | }
|
78 | 79 |
|
|
155 | 156 | return false;
|
156 | 157 | }
|
157 | 158 |
|
| 159 | + if (name.includes("/")) { |
| 160 | + toast.error("The name cannot contain a slash"); |
| 161 | + return false; |
| 162 | + } |
| 163 | +
|
158 | 164 | const node = item.node;
|
159 | 165 | const siblings = item.parent?.node.children ?? root.children;
|
160 | 166 | for (const sibling of siblings) {
|
|
169 | 175 | }
|
170 | 176 | </script>
|
171 | 177 |
|
172 |
| -<div class="flex min-h-svh p-2"> |
| 178 | +<div class="flex min-h-svh p-4"> |
173 | 179 | <Tree
|
174 | 180 | {root}
|
175 | 181 | {expandedIds}
|
|
202 | 208 | </Tree>
|
203 | 209 | </div>
|
204 | 210 |
|
205 |
| -<ConfirmRemoveDialog bind:this={confirmRemoveDialog} /> |
206 |
| -<ResolveConflictDialog bind:this={resolveConflictDialog} /> |
| 211 | +<ConfirmDialog bind:this={confirmDialog} /> |
0 commit comments