atproto explorer

mass record recreation

+64 -6
+64 -6
src/views/collection.tsx
··· 8 8 import { Button } from "../components/button.jsx"; 9 9 import { JSONType, JSONValue } from "../components/json.jsx"; 10 10 import { agent } from "../components/login.jsx"; 11 + import { Modal } from "../components/modal.jsx"; 11 12 import { StickyOverlay } from "../components/sticky.jsx"; 12 13 import { TextInput } from "../components/text-input.jsx"; 13 14 import Tooltip from "../components/tooltip.jsx"; ··· 73 74 const [batchDelete, setBatchDelete] = createSignal(false); 74 75 const [lastSelected, setLastSelected] = createSignal<number>(); 75 76 const [reverse, setReverse] = createSignal(false); 77 + const [recreate, setRecreate] = createSignal(false); 78 + const [openDelete, setOpenDelete] = createSignal(false); 76 79 const did = params.repo; 77 80 let pds: string; 78 81 let rpc: Client; ··· 109 112 110 113 const deleteRecords = async () => { 111 114 const recsToDel = records.filter((record) => record.toDelete); 112 - const writes = recsToDel.map((record): $type.enforce<ComAtprotoRepoApplyWrites.Delete> => { 113 - return { 115 + let writes: Array< 116 + | $type.enforce<ComAtprotoRepoApplyWrites.Delete> 117 + | $type.enforce<ComAtprotoRepoApplyWrites.Create> 118 + > = []; 119 + recsToDel.forEach((record) => { 120 + writes.push({ 114 121 $type: "com.atproto.repo.applyWrites#delete", 115 122 collection: params.collection as `${string}.${string}.${string}`, 116 123 rkey: record.rkey, 117 - }; 124 + }); 125 + if (recreate()) { 126 + writes.push({ 127 + $type: "com.atproto.repo.applyWrites#create", 128 + collection: params.collection as `${string}.${string}.${string}`, 129 + rkey: record.rkey, 130 + value: record.record.value, 131 + }); 132 + } 118 133 }); 119 134 120 135 const BATCHSIZE = 200; ··· 127 142 }, 128 143 }); 129 144 } 130 - setNotif({ show: true, icon: "lucide--trash-2", text: `${recsToDel.length} records deleted` }); 145 + setNotif({ 146 + show: true, 147 + icon: "lucide--trash-2", 148 + text: `${recsToDel.length} records ${recreate() ? "recreated" : "deleted"}`, 149 + }); 131 150 setBatchDelete(false); 132 151 setRecords([]); 133 152 setCursor(undefined); 153 + setOpenDelete(false); 154 + setRecreate(false); 134 155 refetch(); 135 156 }; 136 157 ··· 196 217 } 197 218 /> 198 219 <Tooltip 199 - text="Confirm" 220 + text="Recreate" 200 221 children={ 201 - <button onclick={() => deleteRecords()} class="flex items-center"> 222 + <button 223 + onclick={() => { 224 + setRecreate(true); 225 + setOpenDelete(true); 226 + }} 227 + class="flex items-center" 228 + > 229 + <span class="iconify lucide--recycle text-lg text-green-500 dark:text-green-400"></span> 230 + </button> 231 + } 232 + /> 233 + <Tooltip 234 + text="Delete" 235 + children={ 236 + <button 237 + onclick={() => { 238 + setRecreate(false); 239 + setOpenDelete(true); 240 + }} 241 + class="flex items-center" 242 + > 202 243 <span class="iconify lucide--trash-2 text-lg text-red-500 dark:text-red-400"></span> 203 244 </button> 204 245 } 205 246 /> 206 247 </Show> 207 248 </div> 249 + <Modal open={openDelete()} onClose={() => setOpenDelete(false)}> 250 + <div class="dark:bg-dark-300 dark:shadow-dark-800 absolute top-70 left-[50%] -translate-x-1/2 rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-4 shadow-md transition-opacity duration-300 dark:border-neutral-700 starting:opacity-0"> 251 + <h2 class="mb-2 font-semibold"> 252 + {recreate() ? "Recreate" : "Delete"} {records.filter((r) => r.toDelete).length}{" "} 253 + records? 254 + </h2> 255 + <div class="flex justify-end gap-2"> 256 + <Button onClick={() => setOpenDelete(false)}>Cancel</Button> 257 + <Button 258 + onClick={deleteRecords} 259 + class={`dark:shadow-dark-800 rounded-lg px-2 py-1.5 text-xs font-semibold text-neutral-200 shadow-xs ${recreate() ? "bg-green-500 hover:bg-green-400 dark:bg-green-600 dark:hover:bg-green-500" : "bg-red-500 hover:bg-red-400 active:bg-red-400"}`} 260 + > 261 + {recreate() ? "Recreate" : "Delete"} 262 + </Button> 263 + </div> 264 + </div> 265 + </Modal> 208 266 </Show> 209 267 <Tooltip text="Jetstream"> 210 268 <A