Workspaces 4 members invites (#8245)

## Summary

  Add team workspace member management and invite system.

## Changes

- Add members panel with role management (owner/admin/member) and member
removal
- Add invite system with email invites, pending invite display, and
revoke functionality
   - Add invite URL loading for accepting invites
  - Add subscription panel updates for member management
  - Add i18n translations for member and invite features

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8245-Workspaces-4-members-invites-2f06d73d36508176b2caf852a1505c4a)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Simula_r
2026-01-24 15:52:40 -08:00
committed by GitHub
parent aa6f9b7009
commit 4771565486
31 changed files with 1704 additions and 121 deletions

View File

@@ -22,6 +22,7 @@ export interface Member {
name: string
email: string
joined_at: string
role: WorkspaceRole
}
interface PaginationInfo {
@@ -110,6 +111,18 @@ async function getAuthHeaderOrThrow() {
return authHeader
}
async function getFirebaseHeaderOrThrow() {
const authHeader = await useFirebaseAuthStore().getFirebaseAuthHeader()
if (!authHeader) {
throw new WorkspaceApiError(
t('toastMessages.userNotAuthenticated'),
401,
'NOT_AUTHENTICATED'
)
}
return authHeader
}
function handleAxiosError(err: unknown): never {
if (axios.isAxiosError(err)) {
const status = err.response?.status
@@ -296,9 +309,10 @@ export const workspaceApi = {
/**
* Accept a workspace invite.
* POST /api/invites/:token/accept
* Uses Firebase auth (user identity) since the user isn't yet a workspace member.
*/
async acceptInvite(token: string): Promise<AcceptInviteResponse> {
const headers = await getAuthHeaderOrThrow()
const headers = await getFirebaseHeaderOrThrow()
try {
const response = await workspaceApiClient.post<AcceptInviteResponse>(
api.apiURL(`/invites/${token}/accept`),