Feat v0.5.0 realtime primitive + dialog audit + permissions UI
All checks were successful
CI/CD / detect-changes (pull_request) Successful in 18s
CI/CD / test-frontend (pull_request) Successful in 5s
CI/CD / test-go-pg (pull_request) Successful in 2m42s
CI/CD / test-sqlite (pull_request) Successful in 2m59s
CI/CD / build-and-deploy (pull_request) Successful in 1m24s
All checks were successful
CI/CD / detect-changes (pull_request) Successful in 18s
CI/CD / test-frontend (pull_request) Successful in 5s
CI/CD / test-go-pg (pull_request) Successful in 2m42s
CI/CD / test-sqlite (pull_request) Successful in 2m59s
CI/CD / build-and-deploy (pull_request) Successful in 1m24s
Add realtime pub/sub: Starlark realtime.publish() module gated by new realtime.publish permission, WS room protocol (room.subscribe/ room.unsubscribe intercepted in readPump with 100-room cap), and SDK sw.realtime.subscribe() with auto room join/leave and reconnect recovery. Migrate 5 bare confirm() calls to sw.confirm() with destructive styling in tasks, schedules, notes (×2), and editor packages. Add admin permissions UI: per-permission grant/revoke drawer, Grant All bulk action, pending_review/suspended status badges, disabled enable toggle when pending. Closes v0.4.7 permissions UI gap. 8 new Go tests, all passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -372,8 +372,8 @@
|
||||
// ── File Operations ─────────────────────────
|
||||
|
||||
async function _deleteFile(wsId, path, fileTree, codeEditor) {
|
||||
const ok = typeof showConfirm === 'function'
|
||||
? await showConfirm('Delete ' + path + '?')
|
||||
const ok = typeof sw !== 'undefined' && sw.confirm
|
||||
? await sw.confirm('Delete ' + path + '?', { destructive: true })
|
||||
: window.confirm('Delete ' + path + '?');
|
||||
if (!ok) return;
|
||||
try {
|
||||
|
||||
@@ -811,7 +811,7 @@
|
||||
}
|
||||
|
||||
async function handleArchive() {
|
||||
if (!note || !confirm('Archive this note?')) return;
|
||||
if (!note || !await sw.confirm('Archive this note?', { destructive: true })) return;
|
||||
await api.del('/notes/' + note.id);
|
||||
onDelete();
|
||||
}
|
||||
@@ -1717,7 +1717,7 @@
|
||||
} catch (e) { console.error('Rename folder failed:', e); }
|
||||
}
|
||||
async function handleDeleteFolder(folderId) {
|
||||
if (!confirm('Delete this folder? Notes will be moved to Unfiled.')) return;
|
||||
if (!await sw.confirm('Delete this folder? Notes will be moved to Unfiled.', { destructive: true })) return;
|
||||
try {
|
||||
await api.del('/folders/' + folderId);
|
||||
if (activeFolderId === folderId) setActiveFolderId(null);
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
}
|
||||
|
||||
async function handleDelete(item) {
|
||||
if (!confirm('Delete schedule "' + item.name + '"?')) return;
|
||||
if (!await sw.confirm('Delete schedule "' + item.name + '"?', { destructive: true })) return;
|
||||
try {
|
||||
await apiDelete(item.id);
|
||||
sw.toast('Schedule deleted', 'success');
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
}
|
||||
|
||||
async function handleDelete(id) {
|
||||
if (!confirm('Delete this task?')) return;
|
||||
if (!await sw.confirm('Delete this task?', { destructive: true })) return;
|
||||
await api.del('/items/' + id);
|
||||
onRefresh();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user