mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-09-12 15:21:09 +00:00
chore: run bun format to automatically format the frontend code
This commit is contained in:
+2
-1
@@ -16,8 +16,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { api } from '@/lib/api'
|
||||
import type { PermissionCatalog } from '@/lib/admin-permissions'
|
||||
import { api } from '@/lib/api'
|
||||
|
||||
import type {
|
||||
User,
|
||||
GetUsersParams,
|
||||
|
||||
@@ -17,7 +17,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { type Table } from '@tanstack/react-table'
|
||||
|
||||
import { DataTableBulkActions as BulkActionsToolbar } from '@/components/data-table'
|
||||
|
||||
import { type User } from '../types'
|
||||
|
||||
interface DataTableBulkActionsProps {
|
||||
|
||||
@@ -16,7 +16,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { useState } from 'react'
|
||||
import type { Row } from '@tanstack/react-table'
|
||||
import {
|
||||
Pencil,
|
||||
@@ -30,22 +29,25 @@ import {
|
||||
Link2,
|
||||
CreditCard,
|
||||
} from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { toast } from 'sonner'
|
||||
|
||||
import { ConfirmDialog } from '@/components/confirm-dialog'
|
||||
import { DataTableRowActionMenu } from '@/components/data-table/core/row-action-menu'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuShortcut,
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
import { DataTableRowActionMenu } from '@/components/data-table/core/row-action-menu'
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from '@/components/ui/tooltip'
|
||||
import { ConfirmDialog } from '@/components/confirm-dialog'
|
||||
import { UserSubscriptionsDialog } from '@/features/subscriptions/components/dialogs/user-subscriptions-dialog'
|
||||
|
||||
import { manageUser, resetUserPasskey, resetUserTwoFA } from '../api'
|
||||
import {
|
||||
USER_STATUS,
|
||||
@@ -155,7 +157,10 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) {
|
||||
<TooltipContent>{t('Edit')}</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<DataTableRowActionMenu ariaLabel={t('Open menu')} contentClassName='w-48'>
|
||||
<DataTableRowActionMenu
|
||||
ariaLabel={t('Open menu')}
|
||||
contentClassName='w-48'
|
||||
>
|
||||
{isDisabled ? (
|
||||
<DropdownMenuItem onClick={() => handleManage('enable')}>
|
||||
{t('Enable')}
|
||||
@@ -175,88 +180,88 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) {
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
{isAdmin && !isRoot && (
|
||||
<DropdownMenuItem onClick={() => handleManage('demote')}>
|
||||
{t('Demote')}
|
||||
<DropdownMenuShortcut>
|
||||
<ArrowDown size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
{!isAdmin && (
|
||||
<DropdownMenuItem onClick={() => handleManage('promote')}>
|
||||
{t('Promote')}
|
||||
<DropdownMenuShortcut>
|
||||
<ArrowUp size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
<DropdownMenuItem
|
||||
onSelect={(event) => {
|
||||
event.preventDefault()
|
||||
setBindingDialogOpen(true)
|
||||
}}
|
||||
>
|
||||
{t('Manage Bindings')}
|
||||
{isAdmin && !isRoot && (
|
||||
<DropdownMenuItem onClick={() => handleManage('demote')}>
|
||||
{t('Demote')}
|
||||
<DropdownMenuShortcut>
|
||||
<Link2 size={16} />
|
||||
<ArrowDown size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
<DropdownMenuItem
|
||||
onSelect={(event) => {
|
||||
event.preventDefault()
|
||||
setSubscriptionsDialogOpen(true)
|
||||
}}
|
||||
>
|
||||
{t('Manage Subscriptions')}
|
||||
{!isAdmin && (
|
||||
<DropdownMenuItem onClick={() => handleManage('promote')}>
|
||||
{t('Promote')}
|
||||
<DropdownMenuShortcut>
|
||||
<CreditCard size={16} />
|
||||
<ArrowUp size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
onSelect={(event) => {
|
||||
event.preventDefault()
|
||||
setBindingDialogOpen(true)
|
||||
}}
|
||||
>
|
||||
{t('Manage Bindings')}
|
||||
<DropdownMenuShortcut>
|
||||
<Link2 size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem
|
||||
onSelect={(event) => {
|
||||
event.preventDefault()
|
||||
setResetPasskeyOpen(true)
|
||||
}}
|
||||
disabled={isRoot}
|
||||
>
|
||||
{t('Reset Passkey')}
|
||||
<DropdownMenuShortcut>
|
||||
<KeyRound size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onSelect={(event) => {
|
||||
event.preventDefault()
|
||||
setSubscriptionsDialogOpen(true)
|
||||
}}
|
||||
>
|
||||
{t('Manage Subscriptions')}
|
||||
<DropdownMenuShortcut>
|
||||
<CreditCard size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem
|
||||
onSelect={(event) => {
|
||||
event.preventDefault()
|
||||
setResetTwoFAOpen(true)
|
||||
}}
|
||||
disabled={isRoot}
|
||||
>
|
||||
{t('Reset 2FA')}
|
||||
<DropdownMenuShortcut>
|
||||
<ShieldAlert size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
onSelect={(event) => {
|
||||
event.preventDefault()
|
||||
setResetPasskeyOpen(true)
|
||||
}}
|
||||
disabled={isRoot}
|
||||
>
|
||||
{t('Reset Passkey')}
|
||||
<DropdownMenuShortcut>
|
||||
<KeyRound size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem
|
||||
onClick={handleDelete}
|
||||
className='text-destructive focus:text-destructive'
|
||||
disabled={isRoot}
|
||||
>
|
||||
{t('Delete')}
|
||||
<DropdownMenuShortcut>
|
||||
<Trash2 size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onSelect={(event) => {
|
||||
event.preventDefault()
|
||||
setResetTwoFAOpen(true)
|
||||
}}
|
||||
disabled={isRoot}
|
||||
>
|
||||
{t('Reset 2FA')}
|
||||
<DropdownMenuShortcut>
|
||||
<ShieldAlert size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
<DropdownMenuItem
|
||||
onClick={handleDelete}
|
||||
className='text-destructive focus:text-destructive'
|
||||
disabled={isRoot}
|
||||
>
|
||||
{t('Delete')}
|
||||
<DropdownMenuShortcut>
|
||||
<Trash2 size={16} />
|
||||
</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
</DataTableRowActionMenu>
|
||||
|
||||
<ConfirmDialog
|
||||
|
||||
@@ -16,7 +16,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { useState, useEffect, useCallback, useMemo } from 'react'
|
||||
import {
|
||||
Mail,
|
||||
Globe,
|
||||
@@ -28,10 +27,14 @@ import {
|
||||
Eye,
|
||||
EyeOff,
|
||||
} from 'lucide-react'
|
||||
import { useState, useEffect, useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { SiGithub, SiDiscord } from 'react-icons/si'
|
||||
import { toast } from 'sonner'
|
||||
import { api } from '@/lib/api'
|
||||
|
||||
import { ConfirmDialog } from '@/components/confirm-dialog'
|
||||
import { Dialog } from '@/components/dialog'
|
||||
import { StatusBadge } from '@/components/status-badge'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
@@ -41,9 +44,8 @@ import {
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from '@/components/ui/tooltip'
|
||||
import { ConfirmDialog } from '@/components/confirm-dialog'
|
||||
import { Dialog } from '@/components/dialog'
|
||||
import { StatusBadge } from '@/components/status-badge'
|
||||
import { api } from '@/lib/api'
|
||||
|
||||
import {
|
||||
getUser,
|
||||
getUserOAuthBindings,
|
||||
|
||||
@@ -19,13 +19,15 @@ For commercial licensing, please contact support@quantumnous.com
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { toast } from 'sonner'
|
||||
import { getCurrencyDisplay, getCurrencyLabel } from '@/lib/currency'
|
||||
import { formatQuota, parseQuotaFromDollars } from '@/lib/format'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
import { Dialog } from '@/components/dialog'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Dialog } from '@/components/dialog'
|
||||
import { getCurrencyDisplay, getCurrencyLabel } from '@/lib/currency'
|
||||
import { formatQuota, parseQuotaFromDollars } from '@/lib/format'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
import { adjustUserQuota } from '../api'
|
||||
import type { QuotaAdjustMode } from '../types'
|
||||
|
||||
|
||||
@@ -18,8 +18,12 @@ For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { type ColumnDef } from '@tanstack/react-table'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { formatQuota, formatTimestamp } from '@/lib/format'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
import { BadgeCell } from '@/components/data-table'
|
||||
import { GroupBadge } from '@/components/group-badge'
|
||||
import { LongText } from '@/components/long-text'
|
||||
import { StatusBadge } from '@/components/status-badge'
|
||||
import { TableId } from '@/components/table-id'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import { Progress } from '@/components/ui/progress'
|
||||
import {
|
||||
@@ -27,11 +31,9 @@ import {
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from '@/components/ui/tooltip'
|
||||
import { BadgeCell } from '@/components/data-table'
|
||||
import { GroupBadge } from '@/components/group-badge'
|
||||
import { LongText } from '@/components/long-text'
|
||||
import { StatusBadge } from '@/components/status-badge'
|
||||
import { TableId } from '@/components/table-id'
|
||||
import { formatQuota, formatTimestamp } from '@/lib/format'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
import {
|
||||
USER_STATUS,
|
||||
USER_STATUSES,
|
||||
|
||||
@@ -19,7 +19,9 @@ For commercial licensing, please contact support@quantumnous.com
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { toast } from 'sonner'
|
||||
|
||||
import { ConfirmDialog } from '@/components/confirm-dialog'
|
||||
|
||||
import { deleteUser } from '../api'
|
||||
import { ERROR_MESSAGES } from '../constants'
|
||||
import { getUserActionMessage } from '../lib'
|
||||
|
||||
+105
-98
@@ -16,24 +16,21 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { Pencil } from 'lucide-react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { toast } from 'sonner'
|
||||
|
||||
import {
|
||||
ADMIN_PERMISSION_ACTIONS,
|
||||
ADMIN_PERMISSION_RESOURCES,
|
||||
EMPTY_PERMISSION_CATALOG,
|
||||
hasPermission,
|
||||
normalizeAdminPermissions,
|
||||
} from '@/lib/admin-permissions'
|
||||
import { getCurrencyDisplay, getCurrencyLabel } from '@/lib/currency'
|
||||
import { formatQuota, parseQuotaFromDollars } from '@/lib/format'
|
||||
import { ROLE } from '@/lib/roles'
|
||||
import { useAuthStore } from '@/stores/auth-store'
|
||||
SideDrawerSection,
|
||||
sideDrawerContentClassName,
|
||||
sideDrawerFooterClassName,
|
||||
sideDrawerFormClassName,
|
||||
sideDrawerHeaderClassName,
|
||||
} from '@/components/drawer-layout'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import {
|
||||
@@ -66,12 +63,17 @@ import {
|
||||
} from '@/components/ui/sheet'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import {
|
||||
SideDrawerSection,
|
||||
sideDrawerContentClassName,
|
||||
sideDrawerFooterClassName,
|
||||
sideDrawerFormClassName,
|
||||
sideDrawerHeaderClassName,
|
||||
} from '@/components/drawer-layout'
|
||||
ADMIN_PERMISSION_ACTIONS,
|
||||
ADMIN_PERMISSION_RESOURCES,
|
||||
EMPTY_PERMISSION_CATALOG,
|
||||
hasPermission,
|
||||
normalizeAdminPermissions,
|
||||
} from '@/lib/admin-permissions'
|
||||
import { getCurrencyDisplay, getCurrencyLabel } from '@/lib/currency'
|
||||
import { formatQuota, parseQuotaFromDollars } from '@/lib/format'
|
||||
import { ROLE } from '@/lib/roles'
|
||||
import { useAuthStore } from '@/stores/auth-store'
|
||||
|
||||
import {
|
||||
createUser,
|
||||
updateUser,
|
||||
@@ -451,88 +453,93 @@ export function UsersMutateDrawer({
|
||||
{canEditAdminPermissions &&
|
||||
targetIsAdmin &&
|
||||
permissionCatalog.resources.length > 0 && (
|
||||
<SideDrawerSection>
|
||||
<h3 className='text-sm font-medium'>
|
||||
{t('Admin Permissions')}
|
||||
</h3>
|
||||
<p className='text-muted-foreground text-xs'>
|
||||
{t(
|
||||
'Default administrator permissions can be overridden for this user.'
|
||||
)}
|
||||
</p>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='admin_permissions'
|
||||
render={({ field }) => {
|
||||
const selected = normalizeAdminPermissions(
|
||||
field.value,
|
||||
permissionCatalog
|
||||
)
|
||||
return (
|
||||
<FormItem>
|
||||
<div className='space-y-3'>
|
||||
{permissionCatalog.resources.map((resource) => (
|
||||
<div
|
||||
key={resource.resource}
|
||||
className='space-y-2 rounded-md border p-3'
|
||||
>
|
||||
<div className='text-sm font-medium'>
|
||||
{t(resource.label_key)}
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
{resource.actions.map((option) => (
|
||||
<label
|
||||
key={option.action}
|
||||
className='flex items-start gap-3'
|
||||
>
|
||||
<Checkbox
|
||||
checked={
|
||||
selected[resource.resource]?.[
|
||||
option.action
|
||||
] === true
|
||||
}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange({
|
||||
...selected,
|
||||
[resource.resource]: {
|
||||
...selected[resource.resource],
|
||||
[option.action]: checked === true,
|
||||
},
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<span className='flex flex-col gap-1'>
|
||||
<span className='text-sm font-medium'>
|
||||
{t(option.label_key)}
|
||||
</span>
|
||||
<span className='text-muted-foreground text-xs'>
|
||||
{t(option.description_key)}
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{currentUser && (
|
||||
<SideDrawerSection>
|
||||
<h3 className='text-sm font-medium'>
|
||||
{t('Admin Permissions')}
|
||||
</h3>
|
||||
<p className='text-muted-foreground text-xs'>
|
||||
{hasPermission(
|
||||
currentUser,
|
||||
ADMIN_PERMISSION_RESOURCES.CHANNEL,
|
||||
ADMIN_PERMISSION_ACTIONS.SENSITIVE_WRITE
|
||||
)
|
||||
? t('Your account can edit sensitive channel settings.')
|
||||
: t('Your account cannot edit sensitive channel settings.')}
|
||||
{t(
|
||||
'Default administrator permissions can be overridden for this user.'
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</SideDrawerSection>
|
||||
)}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='admin_permissions'
|
||||
render={({ field }) => {
|
||||
const selected = normalizeAdminPermissions(
|
||||
field.value,
|
||||
permissionCatalog
|
||||
)
|
||||
return (
|
||||
<FormItem>
|
||||
<div className='space-y-3'>
|
||||
{permissionCatalog.resources.map((resource) => (
|
||||
<div
|
||||
key={resource.resource}
|
||||
className='space-y-2 rounded-md border p-3'
|
||||
>
|
||||
<div className='text-sm font-medium'>
|
||||
{t(resource.label_key)}
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
{resource.actions.map((option) => (
|
||||
<label
|
||||
key={option.action}
|
||||
className='flex items-start gap-3'
|
||||
>
|
||||
<Checkbox
|
||||
checked={
|
||||
selected[resource.resource]?.[
|
||||
option.action
|
||||
] === true
|
||||
}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange({
|
||||
...selected,
|
||||
[resource.resource]: {
|
||||
...selected[resource.resource],
|
||||
[option.action]:
|
||||
checked === true,
|
||||
},
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<span className='flex flex-col gap-1'>
|
||||
<span className='text-sm font-medium'>
|
||||
{t(option.label_key)}
|
||||
</span>
|
||||
<span className='text-muted-foreground text-xs'>
|
||||
{t(option.description_key)}
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{currentUser && (
|
||||
<p className='text-muted-foreground text-xs'>
|
||||
{hasPermission(
|
||||
currentUser,
|
||||
ADMIN_PERMISSION_RESOURCES.CHANNEL,
|
||||
ADMIN_PERMISSION_ACTIONS.SENSITIVE_WRITE
|
||||
)
|
||||
? t(
|
||||
'Your account can edit sensitive channel settings.'
|
||||
)
|
||||
: t(
|
||||
'Your account cannot edit sensitive channel settings.'
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</SideDrawerSection>
|
||||
)}
|
||||
|
||||
{/* Binding Information (Read-only) */}
|
||||
{isUpdate && (
|
||||
|
||||
@@ -18,7 +18,9 @@ For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { Plus } from 'lucide-react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
import { useUsers } from './users-provider'
|
||||
|
||||
export function UsersPrimaryButtons() {
|
||||
|
||||
@@ -17,7 +17,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import useDialogState from '@/hooks/use-dialog'
|
||||
|
||||
import { type User, type UsersDialogType } from '../types'
|
||||
|
||||
type UsersContextType = {
|
||||
|
||||
@@ -18,16 +18,18 @@ For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { getRouteApi } from '@tanstack/react-router'
|
||||
import { useMediaQuery } from '@/hooks'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { toast } from 'sonner'
|
||||
import { useTableUrlState } from '@/hooks/use-table-url-state'
|
||||
|
||||
import {
|
||||
DISABLED_ROW_DESKTOP,
|
||||
DISABLED_ROW_MOBILE,
|
||||
DataTablePage,
|
||||
useDataTable,
|
||||
} from '@/components/data-table'
|
||||
import { useMediaQuery } from '@/hooks'
|
||||
import { useTableUrlState } from '@/hooks/use-table-url-state'
|
||||
|
||||
import { getUsers, searchUsers } from '../api'
|
||||
import {
|
||||
USER_STATUS,
|
||||
|
||||
+1
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { Shield, User, Users } from 'lucide-react'
|
||||
|
||||
import type { User as UserType } from './types'
|
||||
|
||||
// ============================================================================
|
||||
|
||||
+2
@@ -17,7 +17,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { SectionPageLayout } from '@/components/layout'
|
||||
|
||||
import { UsersDeleteDialog } from './components/users-delete-dialog'
|
||||
import { UsersMutateDrawer } from './components/users-mutate-drawer'
|
||||
import { UsersPrimaryButtons } from './components/users-primary-buttons'
|
||||
|
||||
+6
-2
@@ -17,13 +17,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { z } from 'zod'
|
||||
import { quotaUnitsToDollars } from '@/lib/format'
|
||||
|
||||
import {
|
||||
type PermissionCatalog,
|
||||
type AdminPermissionMatrix,
|
||||
normalizeAdminPermissions,
|
||||
} from '@/lib/admin-permissions'
|
||||
import { quotaUnitsToDollars } from '@/lib/format'
|
||||
import { ROLE } from '@/lib/roles'
|
||||
|
||||
import { DEFAULT_GROUP } from '../constants'
|
||||
import { type UserFormData, type User } from '../types'
|
||||
|
||||
@@ -39,7 +41,9 @@ export const userFormSchema = z.object({
|
||||
quota_dollars: z.number().min(0).optional(),
|
||||
group: z.string().optional(),
|
||||
remark: z.string().optional(),
|
||||
admin_permissions: z.record(z.string(), z.record(z.string(), z.boolean())).optional(),
|
||||
admin_permissions: z
|
||||
.record(z.string(), z.record(z.string(), z.boolean()))
|
||||
.optional(),
|
||||
})
|
||||
|
||||
export type UserFormValues = z.infer<typeof userFormSchema>
|
||||
|
||||
+4
-1
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { z } from 'zod'
|
||||
|
||||
import type { AdminPermissionMatrix } from '@/lib/admin-permissions'
|
||||
|
||||
// ============================================================================
|
||||
@@ -58,7 +59,9 @@ export const userSchema = z.object({
|
||||
last_login_at: z.number().optional(),
|
||||
DeletedAt: z.any().nullable().optional(),
|
||||
remark: z.string().optional(),
|
||||
admin_permissions: z.record(z.string(), z.record(z.string(), z.boolean())).optional(),
|
||||
admin_permissions: z
|
||||
.record(z.string(), z.record(z.string(), z.boolean()))
|
||||
.optional(),
|
||||
})
|
||||
export type User = z.infer<typeof userSchema>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user