mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
feat: add multi-user support and role-based access control #31
This commit is contained in:
@@ -42,6 +42,8 @@ import { SyncFoldersDialog } from './components/sync-folders'
|
||||
import { NoSyncAccountDialog } from './components/nosync-dialog'
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { AccountAccessAssignmentDialog } from './components/access-assignment-dialog'
|
||||
import { useCurrentUser } from '@/hooks/use-current-user'
|
||||
|
||||
export default function Accounts() {
|
||||
const { t } = useTranslation()
|
||||
@@ -49,6 +51,7 @@ export default function Accounts() {
|
||||
// Dialog states
|
||||
const [currentRow, setCurrentRow] = useState<AccountModel | null>(null)
|
||||
const [open, setOpen] = useDialogState<AccountDialogType>(null)
|
||||
const { require_any_permission } = useCurrentUser()
|
||||
|
||||
const { data: accountList, isLoading } = useQuery({
|
||||
queryKey: ['account-list'],
|
||||
@@ -63,7 +66,6 @@ export default function Accounts() {
|
||||
|
||||
<Main>
|
||||
<div className="mx-auto w-full max-w-[88rem] px-4">
|
||||
{/* Header Section */}
|
||||
<div className='mb-2 flex items-center justify-between flex-wrap gap-x-4 gap-y-2'>
|
||||
<div>
|
||||
<h2 className='text-2xl font-bold tracking-tight'>{t('accounts.title')}</h2>
|
||||
@@ -71,7 +73,7 @@ export default function Accounts() {
|
||||
{t('accounts.description')}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
{require_any_permission(['system:root', 'account:create']) && <div className="flex gap-2">
|
||||
<div className="flex rounded-md shadow-sm">
|
||||
<Button
|
||||
onClick={() => setOpen("add-imap")}
|
||||
@@ -98,10 +100,9 @@ export default function Accounts() {
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
|
||||
{/* Table / Empty State Section */}
|
||||
<div className='flex-1 overflow-auto py-1 flex-row lg:space-x-12 space-y-0'>
|
||||
{isLoading ? (
|
||||
<TableSkeleton columns={columns.length} rows={10} />
|
||||
@@ -168,7 +169,8 @@ export default function Accounts() {
|
||||
}}
|
||||
currentRow={currentRow}
|
||||
/>
|
||||
<RunningStateDialog
|
||||
|
||||
{require_any_permission(['system:root', 'account:read_details'], currentRow.id) && <RunningStateDialog
|
||||
key='running-state'
|
||||
open={open === 'running-state'}
|
||||
onOpenChange={() => {
|
||||
@@ -178,7 +180,8 @@ export default function Accounts() {
|
||||
}, 500)
|
||||
}}
|
||||
currentRow={currentRow}
|
||||
/>
|
||||
/>}
|
||||
|
||||
<AccountDeleteDialog
|
||||
key={`account-delete-${currentRow.id}`}
|
||||
open={open === 'delete'}
|
||||
@@ -201,17 +204,27 @@ export default function Accounts() {
|
||||
}}
|
||||
currentRow={currentRow}
|
||||
/>
|
||||
{require_any_permission(['system:root', 'account:manage'], currentRow.id) && <AccountAccessAssignmentDialog
|
||||
key={`access-assign-${currentRow.id}`}
|
||||
open={open === 'access-assign'}
|
||||
onOpenChange={() => {
|
||||
setOpen('access-assign')
|
||||
setTimeout(() => {
|
||||
setCurrentRow(null)
|
||||
}, 500)
|
||||
}}
|
||||
currentRow={currentRow}
|
||||
/>}
|
||||
|
||||
<AccountDetailDrawer
|
||||
open={open === 'detail'}
|
||||
onOpenChange={() => setOpen('detail')}
|
||||
currentRow={currentRow}
|
||||
/>
|
||||
|
||||
<OAuth2TokensDialog open={open === 'oauth2'}
|
||||
{require_any_permission(['system:root', 'account:manage'], currentRow.id) && <OAuth2TokensDialog open={open === 'oauth2'}
|
||||
onOpenChange={() => setOpen('oauth2')}
|
||||
currentRow={currentRow}
|
||||
/>
|
||||
/>}
|
||||
</>
|
||||
)}
|
||||
</AccountProvider>
|
||||
|
||||
Reference in New Issue
Block a user