diff --git a/client/www/pages/_devtool/index.tsx b/client/www/pages/_devtool/index.tsx index 55df47ef1..591c2a388 100644 --- a/client/www/pages/_devtool/index.tsx +++ b/client/www/pages/_devtool/index.tsx @@ -1,15 +1,19 @@ import { useRouter } from 'next/router'; import { TokenContext } from '@/lib/contexts'; import { useIsHydrated } from '@/lib/hooks/useIsHydrated'; -import { DashResponse } from '@/lib/types'; +import { successToast } from '@/lib/toast'; +import { DashResponse, InstantApp } from '@/lib/types'; import config from '@/lib/config'; -import { useAuthToken, useTokenFetch } from '@/lib/auth'; +import { jsonFetch } from '@/lib/fetch'; +import { APIResponse, useAuthToken, useTokenFetch } from '@/lib/auth'; import { Sandbox } from '@/components/dash/Sandbox'; import { Explorer } from '@/components/dash/explorer/Explorer'; import { init } from '@instantdb/react'; -import { useEffect, useState } from 'react'; -import { SectionHeading, Stack, TabBar, twel } from '@/components/ui'; +import { useEffect, useState, useContext } from 'react'; +import { Button, Checkbox, Dialog, SectionHeading, SubsectionHeading, Stack, TabBar, Content, twel, useDialog } from '@/components/ui'; import Auth from '@/components/dash/Auth'; +import { isMinRole } from '@/pages/dash/index' +import { TrashIcon } from '@heroicons/react/solid'; type InstantReactClient = ReturnType; @@ -187,6 +191,10 @@ export default function Devtool() { id: 'sandbox', label: 'Sandbox', }, + { + id: 'admin', + label: 'Admin', + }, { id: 'help', label: 'Help', @@ -203,6 +211,10 @@ export default function Devtool() {
+ ) : tab === 'admin' ? ( +
+ +
) : tab === 'help' ? (
@@ -215,6 +227,81 @@ export default function Devtool() { ); } +function Admin({ + dashResponse, + app, +}: { + dashResponse: APIResponse; + app: InstantApp; +}) { + const token = useContext(TokenContext); + const [clearAppOk, updateClearAppOk] = useState(false); + const clearDialog = useDialog(); + + return ( + + {isMinRole('owner', app.user_app_role) ? ( +
+ Danger zone + + These are destructive actions and will irreversibly delete associated data. + +
+
+ +
+
+ +
+ + Clear app + + +

Clearing an app will irreversibly delete all namespaces, triples, and permissions.

+

All other data like app id, admin token, users, billing, team members, etc. will remain.

+

This is equivalent to deleting all your namespaces in the explorer and clearing your permissions.

+
+ updateClearAppOk(c)} + label="I understand and want to clear this app." + /> + +
+
+
+ ) : + <> + Insufficent Role + + Only app owners can use admin features in the devtool. + + + } +
+ ) +} + function Help() { return ( diff --git a/client/www/pages/dash/index.tsx b/client/www/pages/dash/index.tsx index c1c354dce..059c69206 100644 --- a/client/www/pages/dash/index.tsx +++ b/client/www/pages/dash/index.tsx @@ -101,7 +101,7 @@ const tabs: Tab[] = [ const tabIndex = new Map(tabs.map((t) => [t.id, t])); -function isMinRole(minRole: Role, role: Role) { +export function isMinRole(minRole: Role, role: Role) { return roleOrder.indexOf(role) >= roleOrder.indexOf(minRole); }