add delete
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { describeRepo, listRecordsRaw, getRecordRaw, fetchLexicon, resolveHandle, getServiceInfo } from '../lib/api.js'
|
||||
import { deleteRecord } from '../lib/auth.js'
|
||||
|
||||
function extractRkey(uri: string): string {
|
||||
const parts = uri.split('/')
|
||||
@@ -82,7 +83,7 @@ async function renderRecordList(did: string, handle: string, collection: string)
|
||||
`
|
||||
}
|
||||
|
||||
async function renderRecordDetail(did: string, handle: string, collection: string, rkey: string): Promise<string> {
|
||||
async function renderRecordDetail(did: string, handle: string, collection: string, rkey: string, canDelete: boolean): Promise<string> {
|
||||
const record = await getRecordRaw(did, collection, rkey)
|
||||
|
||||
if (!record) {
|
||||
@@ -94,6 +95,10 @@ async function renderRecordDetail(did: string, handle: string, collection: strin
|
||||
const schemaLabel = lexicon ? '✓ Schema' : '○ No schema'
|
||||
const json = JSON.stringify(record, null, 2)
|
||||
|
||||
const deleteBtn = canDelete
|
||||
? `<button class="delete-btn" data-collection="${collection}" data-rkey="${rkey}">Delete</button>`
|
||||
: ''
|
||||
|
||||
return `
|
||||
<div class="record-detail">
|
||||
<div class="record-header">
|
||||
@@ -101,6 +106,7 @@ async function renderRecordDetail(did: string, handle: string, collection: strin
|
||||
<p class="record-uri">${record.uri}</p>
|
||||
<p class="record-cid">CID: ${record.cid}</p>
|
||||
<span class="schema-status schema-${schemaStatus}">${schemaLabel}</span>
|
||||
${deleteBtn}
|
||||
</div>
|
||||
<div class="json-view">
|
||||
<pre><code>${escapeHtml(json)}</code></pre>
|
||||
@@ -113,19 +119,21 @@ export async function mountAtBrowser(
|
||||
container: HTMLElement,
|
||||
handle: string,
|
||||
collection: string | null,
|
||||
rkey: string | null
|
||||
rkey: string | null,
|
||||
loginDid: string | null = null
|
||||
): Promise<void> {
|
||||
container.innerHTML = '<p class="loading">Loading...</p>'
|
||||
|
||||
try {
|
||||
const did = handle.startsWith('did:') ? handle : await resolveHandle(handle)
|
||||
const canDelete = loginDid !== null && loginDid === did
|
||||
|
||||
let content: string
|
||||
let nav = ''
|
||||
|
||||
if (collection && rkey) {
|
||||
nav = `<a href="?mode=browser&handle=${handle}&collection=${encodeURIComponent(collection)}" class="back-link">← Back</a>`
|
||||
content = await renderRecordDetail(did, handle, collection, rkey)
|
||||
content = await renderRecordDetail(did, handle, collection, rkey, canDelete)
|
||||
} else if (collection) {
|
||||
nav = `<a href="?mode=browser&handle=${handle}" class="back-link">← Collections</a>`
|
||||
content = await renderRecordList(did, handle, collection)
|
||||
@@ -134,6 +142,33 @@ export async function mountAtBrowser(
|
||||
}
|
||||
|
||||
container.innerHTML = nav + content
|
||||
|
||||
// Add delete button handler
|
||||
const deleteBtn = container.querySelector('.delete-btn')
|
||||
if (deleteBtn) {
|
||||
deleteBtn.addEventListener('click', async (e) => {
|
||||
e.preventDefault()
|
||||
const btn = e.target as HTMLButtonElement
|
||||
const col = btn.dataset.collection
|
||||
const rk = btn.dataset.rkey
|
||||
|
||||
if (!col || !rk) return
|
||||
|
||||
if (!confirm('Delete this record?')) return
|
||||
|
||||
try {
|
||||
btn.disabled = true
|
||||
btn.textContent = 'Deleting...'
|
||||
await deleteRecord(col, rk)
|
||||
// Go back to collection
|
||||
window.location.href = `?mode=browser&handle=${handle}&collection=${encodeURIComponent(col)}`
|
||||
} catch (err) {
|
||||
alert('Delete failed: ' + err)
|
||||
btn.disabled = false
|
||||
btn.textContent = 'Delete'
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
container.innerHTML = `<p class="error">Failed to load: ${err}</p>`
|
||||
}
|
||||
|
||||
@@ -145,3 +145,19 @@ export async function createPost(collection: string, title: string, content: str
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteRecord(collection: string, rkey: string): Promise<boolean> {
|
||||
if (!agent) return false
|
||||
|
||||
try {
|
||||
await agent.com.atproto.repo.deleteRecord({
|
||||
repo: agent.assertDid,
|
||||
collection,
|
||||
rkey,
|
||||
})
|
||||
return true
|
||||
} catch (err) {
|
||||
console.error('Delete record error:', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,8 @@ async function init(): Promise<void> {
|
||||
// AT Browser mode
|
||||
if (mode === 'browser') {
|
||||
profileEl.innerHTML = renderTabs(handle, mode, isLoggedIn)
|
||||
await mountAtBrowser(contentEl, handle, collection, rkey)
|
||||
const loginDid = authSession?.did || null
|
||||
await mountAtBrowser(contentEl, handle, collection, rkey, loginDid)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -475,6 +475,27 @@ body {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
display: inline-block;
|
||||
padding: 6px 12px;
|
||||
background: #dc3545;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.delete-btn:hover {
|
||||
background: #c82333;
|
||||
}
|
||||
|
||||
.delete-btn:disabled {
|
||||
background: #999;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* JSON View */
|
||||
.json-view {
|
||||
background: #f5f5f5;
|
||||
@@ -554,4 +575,10 @@ body {
|
||||
background: #2a2a2a;
|
||||
color: #888;
|
||||
}
|
||||
.delete-btn {
|
||||
background: #dc3545;
|
||||
}
|
||||
.delete-btn:hover {
|
||||
background: #c82333;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user