feat: UsersTable and UserCardList get Email, Display name (dash when empty), Role (new RoleBadge), Invite status and Created
This commit is contained in:
1 parent
153fd8719a
commit
1ece778caf
19 files changed
+485
-204
No files matched your search
@@ -0,0 +1,34 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { userRole, type UserListItem } from '@/composables/useUsers'
|
||||
|
||||
describe('userRole', () => {
|
||||
it.each([['owner' as const], ['admin' as const]])('passes a user role %s through', (role) => {
|
||||
const item: UserListItem = {
|
||||
kind: 'user',
|
||||
id: 1,
|
||||
username: 'u',
|
||||
display_name: '',
|
||||
email: 'u@renew.example',
|
||||
role,
|
||||
status: 'accepted',
|
||||
created_at: '2026-03-12T00:00:00Z',
|
||||
}
|
||||
|
||||
expect(userRole(item)).toBe(role)
|
||||
})
|
||||
|
||||
it.each([['pending' as const], ['expired' as const]])(
|
||||
'returns admin for a %s invite',
|
||||
(status) => {
|
||||
const item: UserListItem = {
|
||||
kind: 'invite',
|
||||
id: 2,
|
||||
email: 'i@renew.example',
|
||||
status,
|
||||
created_at: '2026-03-12T00:00:00Z',
|
||||
}
|
||||
|
||||
expect(userRole(item)).toBe('admin')
|
||||
},
|
||||
)
|
||||
})
|
||||
@@ -21,12 +21,15 @@ export class NetworkError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
export type UserRole = 'owner' | 'admin'
|
||||
|
||||
export interface MeResult {
|
||||
id?: number
|
||||
verified: boolean
|
||||
username?: string
|
||||
email?: string
|
||||
displayName: string
|
||||
role?: UserRole
|
||||
}
|
||||
|
||||
export type OnUnauthorized = 'redirect' | 'passthrough'
|
||||
@@ -135,6 +138,7 @@ export function useApi() {
|
||||
username?: string
|
||||
email?: string
|
||||
display_name?: string | null
|
||||
role?: string
|
||||
}>('/v1/auth/me', { onUnauthorized: 'passthrough' })
|
||||
return {
|
||||
id: body.id,
|
||||
@@ -142,6 +146,7 @@ export function useApi() {
|
||||
username: body.username,
|
||||
email: body.email,
|
||||
displayName: body.display_name ?? '',
|
||||
role: body.role as UserRole | undefined,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ export type UserListItem =
|
||||
id: number
|
||||
username: string
|
||||
display_name: string
|
||||
email: string
|
||||
role: 'owner' | 'admin'
|
||||
status: 'accepted'
|
||||
created_at: string
|
||||
}
|
||||
@@ -13,6 +15,7 @@ export type UserListItem =
|
||||
kind: 'invite'
|
||||
id: number
|
||||
email: string
|
||||
display_name?: string
|
||||
status: 'pending' | 'expired'
|
||||
created_at: string
|
||||
}
|
||||
@@ -23,6 +26,14 @@ export function userRowKey(kind: UserListItem['kind'], id: number) {
|
||||
return `${kind}-${id}`
|
||||
}
|
||||
|
||||
export function userDisplayName(item: UserListItem) {
|
||||
return item.display_name ?? ''
|
||||
}
|
||||
|
||||
export function userRole(item: UserListItem): 'owner' | 'admin' {
|
||||
return item.kind === 'user' ? item.role : 'admin'
|
||||
}
|
||||
|
||||
export interface CreatedInvite {
|
||||
id: number
|
||||
kind: 'invite'
|
||||
|
||||
Reference in new issue
Block a user