feat: add session sharing types, API client, and utilities
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import apiClient from './client'
|
||||
import type { Session, SessionCreate, SessionUpdate, SessionExport, SaveAsTreeRequest, SaveAsTreeResponse, SessionComplete, RedactionSummary } from '@/types'
|
||||
import type { Session, SessionCreate, SessionUpdate, SessionExport, SaveAsTreeRequest, SaveAsTreeResponse, SessionComplete, RedactionSummary, SessionShareCreate, SessionShare, SharedSessionView } from '@/types'
|
||||
|
||||
export interface SessionListParams {
|
||||
page?: number
|
||||
@@ -85,6 +85,26 @@ export const sessionsApi = {
|
||||
const response = await apiClient.post<SaveAsTreeResponse>(`/sessions/${id}/save-as-tree`, data)
|
||||
return response.data
|
||||
},
|
||||
|
||||
// Session Sharing
|
||||
async createShare(sessionId: string, data: SessionShareCreate): Promise<SessionShare> {
|
||||
const response = await apiClient.post<SessionShare>(`/sessions/${sessionId}/shares`, data)
|
||||
return response.data
|
||||
},
|
||||
|
||||
async listMyShares(): Promise<SessionShare[]> {
|
||||
const response = await apiClient.get<SessionShare[]>('/shares/my-shares')
|
||||
return response.data
|
||||
},
|
||||
|
||||
async revokeShare(shareId: string): Promise<void> {
|
||||
await apiClient.delete(`/shares/${shareId}`)
|
||||
},
|
||||
|
||||
async getSharedSession(shareToken: string): Promise<SharedSessionView> {
|
||||
const response = await apiClient.get<SharedSessionView>(`/share/${shareToken}`)
|
||||
return response.data
|
||||
},
|
||||
}
|
||||
|
||||
export default sessionsApi
|
||||
|
||||
27
frontend/src/lib/sessionShare.ts
Normal file
27
frontend/src/lib/sessionShare.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import type { SessionShare } from '@/types'
|
||||
|
||||
/**
|
||||
* Build the full share URL from a SessionShare object.
|
||||
* Uses share.share_url if present, otherwise constructs from token.
|
||||
*/
|
||||
export function buildSessionShareUrl(share: SessionShare): string {
|
||||
if (share.share_url) return share.share_url
|
||||
return `${window.location.origin}/share/${share.share_token}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter shares to only those belonging to a specific session.
|
||||
*/
|
||||
export function filterSharesForSession(shares: SessionShare[], sessionId: string): SessionShare[] {
|
||||
return shares.filter(s => s.session_id === sessionId && s.is_active)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the most recent active share for a given session.
|
||||
* Returns null if no active shares exist.
|
||||
*/
|
||||
export function getLatestActiveShareForSession(shares: SessionShare[], sessionId: string): SessionShare | null {
|
||||
const sessionShares = filterSharesForSession(shares, sessionId)
|
||||
if (sessionShares.length === 0) return null
|
||||
return sessionShares.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime())[0]
|
||||
}
|
||||
@@ -125,3 +125,45 @@ export interface SaveAsTreeResponse {
|
||||
tree_name: string
|
||||
message: string
|
||||
}
|
||||
|
||||
// Session Sharing
|
||||
export type SessionShareVisibility = 'public' | 'account'
|
||||
|
||||
export interface SessionShareCreate {
|
||||
visibility: SessionShareVisibility
|
||||
share_name?: string
|
||||
expires_at?: string // ISO datetime string
|
||||
}
|
||||
|
||||
export interface SessionShare {
|
||||
id: string
|
||||
session_id: string
|
||||
account_id: string
|
||||
share_token: string
|
||||
share_name: string | null
|
||||
visibility: SessionShareVisibility
|
||||
created_by: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
expires_at: string | null
|
||||
view_count: number
|
||||
last_viewed_at: string | null
|
||||
is_active: boolean
|
||||
share_url: string | null
|
||||
}
|
||||
|
||||
export interface SharedSessionView {
|
||||
session_id: string
|
||||
tree_name: string
|
||||
tree_description: string | null
|
||||
tree_structure: Record<string, unknown>
|
||||
path_taken: string[]
|
||||
decisions: DecisionRecord[]
|
||||
custom_steps: CustomStep[]
|
||||
started_at: string
|
||||
completed_at: string | null
|
||||
ticket_number: string | null
|
||||
client_name: string | null
|
||||
share_name: string | null
|
||||
visibility: SessionShareVisibility
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user