97 lines
2.0 KiB
TypeScript
97 lines
2.0 KiB
TypeScript
import { useApi } from '@/composables/useApi'
|
|
import type { LinkableUser } from '@/lib/directoryTypes'
|
|
|
|
export type UserListItem =
|
|
| {
|
|
kind: 'user'
|
|
id: number
|
|
username: string
|
|
display_name: string
|
|
email: string
|
|
role: 'owner' | 'admin'
|
|
status: 'accepted'
|
|
created_at: string
|
|
}
|
|
| {
|
|
kind: 'invite'
|
|
id: number
|
|
email: string
|
|
display_name?: string
|
|
status: 'pending' | 'expired'
|
|
created_at: string
|
|
}
|
|
|
|
export const USER_SKELETON_ROWS = 5
|
|
|
|
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'
|
|
email: string
|
|
status: 'pending'
|
|
created_at: string
|
|
expires_at: string
|
|
}
|
|
|
|
export function useUsers() {
|
|
const { request } = useApi()
|
|
|
|
function listUsers(): Promise<UserListItem[]> {
|
|
return request<UserListItem[]>('/v1/user/')
|
|
}
|
|
|
|
async function listLinkableUsers(
|
|
takenUserIds: ReadonlySet<number | null>,
|
|
): Promise<LinkableUser[]> {
|
|
const users = await listUsers()
|
|
return users.flatMap((user) =>
|
|
user.kind === 'user' && !takenUserIds.has(user.id)
|
|
? [
|
|
{
|
|
id: user.id,
|
|
label: user.display_name || user.username,
|
|
email: user.email,
|
|
},
|
|
]
|
|
: [],
|
|
)
|
|
}
|
|
|
|
function inviteUser(email: string): Promise<CreatedInvite> {
|
|
return request<CreatedInvite>('/v1/user/invite', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ email }),
|
|
})
|
|
}
|
|
|
|
function cancelInvite(id: number): Promise<void> {
|
|
return request<void>(`/v1/user/invite/${id}`, { method: 'DELETE' })
|
|
}
|
|
|
|
function renewInvite(id: number): Promise<CreatedInvite> {
|
|
return request<CreatedInvite>(`/v1/user/invite/${id}/renew`, {
|
|
method: 'POST',
|
|
})
|
|
}
|
|
|
|
return {
|
|
listUsers,
|
|
listLinkableUsers,
|
|
inviteUser,
|
|
cancelInvite,
|
|
renewInvite,
|
|
}
|
|
}
|