@workspace-platform/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin.d.mts +2 -0
- package/dist/admin.d.ts +2 -0
- package/dist/admin.js +19 -0
- package/dist/admin.js.map +1 -0
- package/dist/admin.mjs +1 -0
- package/dist/admin.mjs.map +1 -0
- package/dist/index.d.mts +784 -0
- package/dist/index.d.ts +784 -0
- package/dist/index.js +1881 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1841 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/provider.tsx","../src/api/client.ts","../src/socket/client.ts","../src/types/index.ts","../src/types/activity.ts","../src/api/index.ts","../src/store/useWorkspaceListStore.ts","../src/hooks/useWorkspaceApi.ts","../src/utils/constants.ts","../src/utils/formatExport.ts","../src/components/ui/Modal.tsx","../src/components/ui/cn.ts","../src/components/MemberAvatar.tsx","../src/components/MembersPanel.tsx","../src/components/CreateWorkspaceModal.tsx","../src/components/CreatePrivateWorkspaceModal.tsx","../src/components/SyncPanel.tsx","../src/components/Pagination.tsx"],"sourcesContent":["// ─── @workspace-platform/ui ───────────────────────────────────────────────────\n// Main barrel export\n\n// Provider\nexport { WorkspaceProvider, useWorkspaceContext } from './provider';\nexport type { WorkspaceConfig, WorkspaceContextValue, UserSearchResult } from './provider';\n\n// Types\nexport * from './types';\nexport type { SyncLink, SyncStatus, SyncProviderInfo, ToggleReactionResponse, WorkspaceApis } from './api';\n\n// Activity types\nexport * from './types/activity';\n\n// API\nexport { createWorkspaceApis } from './api';\nexport { createWorkspaceClient } from './api/client';\nexport type { WorkspaceClient } from './api/client';\n\n// Socket\nexport { createWorkspaceSocket } from './socket/client';\nexport type { WorkspaceSocketManager } from './socket/client';\n\n// Store\nexport { createWorkspaceListStore } from './store/useWorkspaceListStore';\nexport type { WorkspaceListState, WorkspaceListFilters, WorkspaceTab } from './store/useWorkspaceListStore';\n\n// Hooks\nexport { useWorkspaceApi } from './hooks/useWorkspaceApi';\n\n// Utils\nexport { getInitials, ROLE_LABELS, STATUS_LABELS, AVAILABLE_AGENTS } from './utils/constants';\nexport { formatWorkspaceExport } from './utils/formatExport';\nexport type { WorkspaceExportData } from './utils/formatExport';\n\n// UI Primitives\nexport { Modal } from './components/ui/Modal';\nexport type { ModalProps, ModalSize } from './components/ui/Modal';\nexport { cn } from './components/ui/cn';\n\n// Components\nexport { MemberAvatar } from './components/MemberAvatar';\nexport type { MemberAvatarProps } from './components/MemberAvatar';\nexport { MembersPanel } from './components/MembersPanel';\nexport type { AvatarUser } from './components/MembersPanel';\nexport { CreateWorkspaceModal } from './components/CreateWorkspaceModal';\nexport { CreatePrivateWorkspaceModal } from './components/CreatePrivateWorkspaceModal';\nexport { SyncPanel } from './components/SyncPanel';\nexport { Pagination } from './components/Pagination';\n","import React, { createContext, useContext, useMemo } from 'react';\nimport { createWorkspaceClient, type WorkspaceClient } from './api/client';\nimport { createWorkspaceSocket, type WorkspaceSocketManager } from './socket/client';\n\n// ─── Config types ─────────────────────────────────────────────────────────────\n\nexport interface UserSearchResult {\n id: string;\n email: string;\n displayName: string;\n avatarUrl?: string;\n}\n\nexport interface WorkspaceConfig {\n /** Base URL of the workspace-platform server (e.g. http://localhost:3100) */\n baseUrl: string;\n /** Function that returns the current Bearer token (JWT) */\n getAuthToken: () => string | null;\n /** Current user identifier (email or ID) — used for socket auth & UI */\n currentUserId: string | null;\n /** Current user display name */\n currentUserName?: string | null;\n /** Optional: additional headers for API requests (e.g. { 'x-auth-mode': 'keycloak' }) */\n extraHeaders?: Record<string, string>;\n /** Optional: function to search users for member invitation */\n searchUsers?: (query: string) => Promise<UserSearchResult[]>;\n /** Optional: function to resolve user avatar URLs by email */\n resolveAvatars?: (memberIds: string[]) => Promise<Record<string, string>>;\n /** Optional: callback when navigating to a workspace */\n onNavigateToWorkspace?: (workspaceId: string) => void;\n}\n\n// ─── Context ──────────────────────────────────────────────────────────────────\n\nexport interface WorkspaceContextValue {\n config: WorkspaceConfig;\n apiClient: WorkspaceClient;\n socket: WorkspaceSocketManager;\n}\n\nconst WorkspaceContext = createContext<WorkspaceContextValue | null>(null);\n\nexport function WorkspaceProvider({\n config,\n children,\n}: {\n config: WorkspaceConfig;\n children: React.ReactNode;\n}) {\n const value = useMemo(() => {\n const apiClient = createWorkspaceClient(config);\n const socket = createWorkspaceSocket(config);\n return { config, apiClient, socket };\n }, [config.baseUrl, config.currentUserId]);\n\n return (\n <WorkspaceContext.Provider value={value}>\n {children}\n </WorkspaceContext.Provider>\n );\n}\n\nexport function useWorkspaceContext(): WorkspaceContextValue {\n const ctx = useContext(WorkspaceContext);\n if (!ctx)\n throw new Error(\n 'useWorkspaceContext must be used within <WorkspaceProvider>'\n );\n return ctx;\n}\n","import type { WorkspaceConfig } from '../provider';\n\n// ─── Decoupled Workspace API HTTP Client ──────────────────────────────────────\n// Uses config from WorkspaceProvider instead of localStorage.\n\nexport interface WorkspaceClient {\n get: <T>(path: string) => Promise<T>;\n post: <T>(path: string, body: unknown) => Promise<T>;\n patch: <T>(path: string, body: unknown) => Promise<T>;\n delete: <T>(path: string) => Promise<T>;\n upload: <T>(path: string, formData: FormData) => Promise<T>;\n getBlob: (path: string) => Promise<Blob>;\n}\n\nexport function createWorkspaceClient(config: WorkspaceConfig): WorkspaceClient {\n function buildHeaders(extra?: HeadersInit): Record<string, string> {\n const base: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(extra as Record<string, string> | undefined),\n };\n const token = config.getAuthToken();\n if (token) base['Authorization'] = `Bearer ${token}`;\n if (config.extraHeaders) Object.assign(base, config.extraHeaders);\n return base;\n }\n\n async function req<T>(path: string, options?: RequestInit): Promise<T> {\n const res = await fetch(`${config.baseUrl}${path}`, {\n ...options,\n headers: buildHeaders(options?.headers),\n });\n if (res.status === 204) return undefined as T;\n const json = await res.json();\n if (!res.ok) {\n const rawMessage = json?.message ?? `Error ${res.status}`;\n const errorMessage = Array.isArray(rawMessage)\n ? rawMessage.join(', ')\n : typeof rawMessage === 'string'\n ? rawMessage\n : JSON.stringify(rawMessage);\n throw new Error(errorMessage);\n }\n return json as T;\n }\n\n async function reqBlob(path: string): Promise<Blob> {\n const res = await fetch(`${config.baseUrl}${path}`, {\n headers: buildHeaders(),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`Error ${res.status}: ${text}`);\n }\n return res.blob();\n }\n\n async function upload<T>(path: string, formData: FormData): Promise<T> {\n const headers: Record<string, string> = {};\n const token = config.getAuthToken();\n if (token) headers['Authorization'] = `Bearer ${token}`;\n if (config.extraHeaders) Object.assign(headers, config.extraHeaders);\n // Do NOT set Content-Type — browser handles multipart boundary\n const res = await fetch(`${config.baseUrl}${path}`, {\n method: 'POST',\n headers,\n body: formData,\n });\n if (!res.ok) {\n const json = await res.json().catch(() => ({}));\n throw new Error(\n (json as { message?: string })?.message ??\n `Upload failed (${res.status})`\n );\n }\n return res.json();\n }\n\n return {\n get: <T>(path: string) => req<T>(path),\n post: <T>(path: string, body: unknown) =>\n req<T>(path, { method: 'POST', body: JSON.stringify(body) }),\n patch: <T>(path: string, body: unknown) =>\n req<T>(path, { method: 'PATCH', body: JSON.stringify(body) }),\n delete: <T>(path: string) => req<T>(path, { method: 'DELETE' }),\n upload: <T>(path: string, formData: FormData) => upload<T>(path, formData),\n getBlob: (path: string) => reqBlob(path),\n };\n}\n","import { io, Socket } from 'socket.io-client';\nimport type { WorkspaceConfig } from '../provider';\n\n// ─── Decoupled Workspace Socket.IO Client ─────────────────────────────────────\n\nexport interface WorkspaceSocketManager {\n getSocket: () => Socket;\n connect: (userId?: string) => Socket;\n disconnect: () => void;\n}\n\nexport function createWorkspaceSocket(\n config: WorkspaceConfig\n): WorkspaceSocketManager {\n let socket: Socket | null = null;\n\n function getSocket(): Socket {\n if (!socket) {\n const token = config.getAuthToken();\n socket = io(`${config.baseUrl}/workspaces`, {\n autoConnect: false,\n auth: { token: token ?? '' },\n });\n }\n return socket;\n }\n\n function connect(userId?: string): Socket {\n const s = getSocket();\n if (!s.connected) s.connect();\n const uid = userId ?? config.currentUserId;\n if (uid) {\n if (s.connected) {\n s.emit('authenticate', { userId: uid });\n } else {\n s.once('connect', () => {\n s.emit('authenticate', { userId: uid });\n });\n }\n }\n return s;\n }\n\n function disconnect() {\n socket?.disconnect();\n socket = null;\n }\n\n return { getSocket, connect, disconnect };\n}\n","// ─── Workspace Platform Types ─────────────────────────────────────────────────\n// Mirrors workspace-platform server schemas.\n\nexport type WorkspaceStatus = 'ACTIVE' | 'CLOSED' | 'ARCHIVED';\nexport type ArtefactType = 'NOTE' | 'EXPORT' | 'DECISION' | 'FILE' | 'TASK';\nexport type MemberType = 'user' | 'agent';\nexport type MemberRole = 'owner' | 'participant' | 'viewer';\n\n// ─── Socket / Webhook Event Enum ──────────────────────────────────────────────\n// Must stay synchronised with WebhookEvent in workspace-platform server\n// (webhook-dispatcher.service.ts).\n\nexport enum WorkspaceEvent {\n // ── Workspace lifecycle ──────────────────────────────────────────────────\n WORKSPACE_CREATED = 'workspace.created',\n WORKSPACE_UPDATED = 'workspace.updated',\n WORKSPACE_DELETED = 'workspace.deleted',\n WORKSPACE_STATUS_CHANGED = 'workspace.statusChanged',\n\n // ── Personal-room events (list-level) ────────────────────────────────────\n /** Sent to user's personal room when they are added as a member */\n WORKSPACE_ADDED = 'workspace.added',\n /** Sent to user's personal room when they are removed as a member */\n WORKSPACE_REMOVED = 'workspace.removed',\n\n // ── Workspace room events (detail-level) ─────────────────────────────────\n WORKSPACE_MEMBER_ADDED = 'workspace.member.added',\n WORKSPACE_MEMBER_UPDATED = 'workspace.member.updated',\n WORKSPACE_MEMBER_REMOVED = 'workspace.member.removed',\n WORKSPACE_MESSAGE_CREATED = 'workspace.message.created',\n WORKSPACE_MESSAGE_UPDATED = 'workspace.message.updated',\n WORKSPACE_MESSAGE_DELETED = 'workspace.message.deleted',\n WORKSPACE_MEMBER_USER_MENTIONED = 'workspace.member.user.mentioned',\n WORKSPACE_MEMBER_AGENT_MENTIONED = 'workspace.member.agent.mentioned',\n WORKSPACE_ARTEFACT_CREATED = 'workspace.artefact.created',\n WORKSPACE_TYPING_STARTED = 'workspace.typing.started',\n WORKSPACE_TYPING_STOPPED = 'workspace.typing.stopped',\n WORKSPACE_MESSAGE_REACTION_CREATED = 'workspace.message.reaction.created',\n WORKSPACE_MESSAGE_REACTION_DELETED = 'workspace.message.reaction.deleted',\n WORKSPACE_MESSAGE_PINNED = 'workspace.message.pinned',\n\n // ── Private workspace events ────────────────────────────────────────────\n PRIVATE_WORKSPACE_CREATED = 'private.workspace.created',\n PRIVATE_WORKSPACE_MESSAGE_CREATED = 'private.workspace.message.created',\n PRIVATE_WORKSPACE_MEMBER_ADDED = 'private.workspace.member.added',\n}\n\n// ─── API Response Wrapper ─────────────────────────────────────────────────────\n\nexport interface PaginatedResponse<T> {\n data: T[];\n total: number;\n offset: number;\n limit: number;\n}\n\n// ─── Domain Models ────────────────────────────────────────────────────────────\n\nexport interface EntityWithSecret {\n key: string;\n value: string;\n isSecret: boolean;\n}\n\nexport interface WorkspaceType {\n _id: string;\n name: string;\n entitiesWithSecrets?: EntityWithSecret[];\n createdBy?: string;\n updatedBy?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface Workspace {\n _id: string;\n name: string;\n isPrivate?: boolean;\n type?: WorkspaceType | string;\n scope?: string;\n entitiesWithSecrets?: EntityWithSecret[];\n status: WorkspaceStatus;\n syncWithSlack?: boolean;\n createdBy?: string;\n updatedBy?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface WorkspaceMember {\n _id: string;\n workspace: string;\n memberId: string;\n memberName: string;\n memberType: MemberType;\n role: MemberRole;\n createdBy?: string;\n updatedBy?: string;\n joinedAt: string;\n createdAt?: string;\n}\n\n/** Subset of WorkspaceMessage returned when populated as a reply reference */\nexport interface ReplyMessage {\n _id: string;\n senderId: string;\n senderName: string;\n senderType: MemberType;\n content: string;\n createdAt: string;\n /** Set locally when the replied-to message is soft-deleted */\n deleted?: boolean;\n}\n\nexport interface WorkspaceMessage {\n _id: string;\n workspace: string;\n senderId: string;\n senderName: string;\n senderType: MemberType;\n sender?: WorkspaceMessageSender;\n content: string;\n mentionedUsers?: string[];\n mentionedAgents?: string[];\n replyToMessage?: ReplyMessage | null;\n metadata?: Record<string, unknown>;\n deleted?: boolean;\n editedAt?: string;\n pinned?: boolean;\n pinnedAt?: string;\n pinnedBy?: string;\n createdBy?: string;\n createdAt: string;\n}\n\nexport interface WorkspaceMessageSender {\n _id: string;\n memberId: string;\n memberName: string;\n memberType: MemberType;\n role: MemberRole;\n}\n\nexport interface FileRecord {\n _id: string;\n filename: string;\n originalName: string;\n mimetype: string;\n size: number;\n bucket: string;\n key: string;\n storageProvider: string;\n createdBy?: string;\n updatedBy?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface WorkspaceArtefact {\n _id: string;\n workspace: string;\n message?: string;\n file: FileRecord;\n type: ArtefactType;\n createdBy?: string;\n updatedBy?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface WorkspaceMessageReaction {\n _id: string;\n reaction: string;\n message: string;\n member?: string;\n memberId?: string;\n memberName?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface MessageWithArtefacts extends WorkspaceMessage {\n artefacts: WorkspaceArtefact[];\n reactions: WorkspaceMessageReaction[];\n}\n\nexport interface WorkspaceAgent {\n _id: string;\n agentId: string;\n agentName: string;\n webhookCount: number;\n createdBy?: string;\n updatedBy?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface AgentDeleteInfo {\n webhookCount: number;\n memberCount: number;\n}\n\nexport interface WebhookSubscription {\n _id: string;\n name: string;\n targetUrl: string;\n secretKey: string;\n secretValue: string;\n eventTypes: string[];\n active: boolean;\n isAgent: boolean;\n agentId?: string;\n metadata?: Record<string, unknown>;\n createdBy?: string;\n updatedBy?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface WorkspaceSummary {\n _id: string;\n workspace: string;\n keyPoints: string[];\n keyTasks: string[];\n keyDecisions: string[];\n messageCount: number;\n lastMessage?: {\n _id: string;\n senderId: string;\n senderName: string;\n senderType: MemberType;\n content: string;\n createdAt: string;\n } | null;\n wasTruncated: boolean;\n generatedAt: string;\n threadId?: string;\n threadState?: 'queued' | 'running' | 'succeeded' | 'failed';\n createdBy?: string;\n updatedBy?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LatestSummaryResponse {\n summary: WorkspaceSummary | null;\n messagesAfterCount: number;\n}\n\n// ─── API Payload Types ────────────────────────────────────────────────────────\n\nexport interface CreateWorkspacePayload {\n name: string;\n isPrivate?: boolean;\n type?: string;\n scope?: string;\n entitiesWithSecrets?: EntityWithSecret[];\n members?: {\n memberId: string;\n memberName: string;\n memberType?: MemberType;\n role?: string;\n }[];\n syncWithSlack?: boolean;\n}\n\nexport interface SendMessagePayload {\n senderType?: MemberType;\n content: string;\n metadata?: Record<string, unknown>;\n replyToMessageId?: string;\n}\n\nexport interface UpdateMessagePayload {\n content: string;\n}\n\n// ─── Socket Event Payload Types ───────────────────────────────────────────────\n// These mirror exactly what workspace.gateway.ts emits over Socket.IO.\n\n/** workspace.created → emitted to each member's personal room */\nexport interface WsPayloadWorkspaceCreated {\n workspace: Workspace;\n}\n\n/** workspace.added → emitted to the new member's personal room */\nexport interface WsPayloadWorkspaceAdded {\n workspaceId: string;\n workspace?: Workspace;\n}\n\n/** workspace.removed → emitted to the removed member's personal room */\nexport interface WsPayloadWorkspaceRemoved {\n workspaceId: string;\n}\n\n/** workspace.updated → emitted to workspace room */\nexport interface WsPayloadWorkspaceUpdated {\n workspace: Workspace;\n}\n\n/** workspace.statusChanged → emitted to workspace room */\nexport interface WsPayloadWorkspaceStatusChanged {\n workspace: Workspace;\n}\n\n/** workspace.member.added → emitted to workspace room */\nexport interface WsPayloadMemberAdded {\n workspaceId: string;\n member: WorkspaceMember;\n}\n\n/** workspace.member.updated → emitted to workspace room */\nexport interface WsPayloadMemberUpdated {\n workspaceId: string;\n member: WorkspaceMember;\n}\n\n/**\n * workspace.member.removed → emitted to workspace room.\n * `memberId` = the WorkspaceMember document _id (ObjectId string)\n * `memberId_field` = the actual userId/email of the removed member\n */\nexport interface WsPayloadMemberRemoved {\n workspaceId: string;\n memberId: string;\n memberId_field: string;\n}\n\n/** workspace.message.created → emitted to workspace room */\nexport interface WsPayloadMessageCreated {\n workspaceId: string;\n message: WorkspaceMessage;\n}\n\n/** workspace.artefact.created → emitted to workspace room */\nexport interface WsPayloadArtefactCreated {\n workspaceId: string;\n artefacts: WorkspaceArtefact[];\n}\n\n/** workspace.typing.started / workspace.typing.stopped */\nexport interface WsPayloadTyping {\n workspaceId: string;\n member: {\n memberId: string;\n memberName: string;\n memberType?: 'user' | 'agent' | string;\n };\n}\n\n/** workspace.message.updated → emitted to workspace room */\nexport interface WsPayloadMessageUpdated {\n workspaceId: string;\n message: WorkspaceMessage;\n}\n\n/** workspace.message.deleted → emitted to workspace room */\nexport interface WsPayloadMessageDeleted {\n workspaceId: string;\n messageId: string;\n}\n\n/** workspace.message.reaction.created → emitted to workspace room */\nexport interface WsPayloadReactionCreated {\n workspaceId: string;\n messageId: string;\n reaction: WorkspaceMessageReaction;\n}\n\n/** workspace.message.reaction.deleted → emitted to workspace room */\nexport interface WsPayloadReactionDeleted {\n workspaceId: string;\n messageId: string;\n reaction: string;\n memberId: string;\n memberName: string;\n}\n\n/** workspace.message.pinned → emitted to workspace room */\nexport interface WsPayloadMessagePinned {\n workspaceId: string;\n message: WorkspaceMessage;\n action: 'pinned' | 'unpinned';\n author: string;\n}\n","// ─── Types ────────────────────────────────────────────────────────────────────\n\n/** Payload shape sent by the backend Atlas Change Stream trigger */\nexport interface ChangeLogData {\n /** Full document snapshot (insert / replace events) */\n fullDocument?: Record<string, unknown>;\n /** Flat fields sent directly on data (legacy / simplified events) */\n updatedFields?: Record<string, unknown>;\n name?: string;\n memberName?: string;\n role?: string;\n originalName?: string;\n filename?: string;\n /** MongoDB update description (update events) */\n updateDescription?: {\n updatedFields?: Record<string, unknown>;\n removedFields?: string[];\n };\n}\n\n/** Matches the backend ChangeLog schema */\nexport interface ChangeLog {\n _id: string;\n event: string;\n timestamp: number;\n type: string;\n entityId: string;\n data?: ChangeLogData;\n createdBy?: string;\n updatedBy?: string;\n}\n\nexport type ActivityIcon =\n | 'created'\n | 'updated'\n | 'deleted'\n | 'member_added'\n | 'member_removed'\n | 'member_role'\n | 'artefact_added'\n | 'artefact_deleted'\n | 'archived'\n | 'generic';\n\nexport type EntityCategory = 'context' | 'members' | 'artefacts' | 'other';\n\nexport interface ActivityEntry {\n _id: string;\n title: string;\n description: string;\n date: string;\n author: string;\n icon: ActivityIcon;\n category: EntityCategory;\n}\n\nexport interface FilterPill {\n label: string;\n value: string | undefined; // undefined = Tout\n entityType: string | undefined; // sent to backend\n category: EntityCategory | undefined;\n}\n\n// ─── Filtre pills ─────────────────────────────────────────────────────────────\n\nexport const FILTER_PILLS: FilterPill[] = [\n {\n label: 'Tout',\n value: undefined,\n entityType: undefined,\n category: undefined,\n },\n {\n label: 'Contexte',\n value: 'context',\n entityType: 'workspaces',\n category: 'context',\n },\n {\n label: 'Membres',\n value: 'members',\n entityType: 'workspace_members',\n category: 'members',\n },\n {\n label: 'Artefacts',\n value: 'artefacts',\n entityType: 'workspace_artefacts',\n category: 'artefacts',\n },\n];\n\n// ─── Mapping helpers ──────────────────────────────────────────────────────────\n\nexport const WORKSPACE_FIELD_LABELS: Record<string, string> = {\n name: 'Nom',\n type: 'Type',\n scope: 'Périmètre',\n entities: 'Entités',\n entitiesWithSecrets: 'Entités',\n status: 'Statut',\n description: 'Description',\n};\n\nexport const WORKSPACE_STATUS_LABELS: Record<string, string> = {\n ACTIVE: 'Actif',\n ARCHIVED: 'Archivé',\n DRAFT: 'Brouillon',\n CLOSED: 'Clôturé',\n};\n\nexport const MEMBER_ROLE_LABELS: Record<string, string> = {\n owner: 'Propriétaire',\n participant: 'Participant',\n viewer: 'Lecteur',\n};\n\nexport const IGNORED_FIELDS = [\n '_id',\n '__v',\n 'updatedAt',\n 'createdAt',\n 'createdBy',\n 'updatedBy',\n 'workspace',\n];\n\n// ─── Icon / category style maps ───────────────────────────────────────────────\n\nexport const CATEGORY_STYLES: Record<\n EntityCategory,\n { dot: string; badge: string; label: string }\n> = {\n context: {\n dot: 'bg-primary/15 border-primary/30',\n badge: 'bg-primary/10 text-primary',\n label: 'Contexte',\n },\n members: {\n dot: 'bg-info/15 border-info/30',\n badge: 'bg-info/10 text-info',\n label: 'Membre',\n },\n artefacts: {\n dot: 'bg-success/15 border-success/30',\n badge: 'bg-success/10 text-success',\n label: 'Artefact',\n },\n other: {\n dot: 'bg-border',\n badge: 'bg-border text-text-muted',\n label: 'Autre',\n },\n};\n\nexport const ICON_COLOR: Record<ActivityIcon, string> = {\n created: 'text-primary',\n updated: 'text-primary',\n deleted: 'text-danger',\n member_added: 'text-info',\n member_removed: 'text-danger',\n member_role: 'text-info',\n artefact_added: 'text-success',\n artefact_deleted: 'text-danger',\n archived: 'text-text-muted',\n generic: 'text-text-muted',\n};\n","import type { WorkspaceClient } from './client';\nimport type {\n Workspace,\n WorkspaceType,\n WorkspaceMember,\n WorkspaceMessage,\n WorkspaceArtefact,\n WorkspaceMessageReaction,\n MessageWithArtefacts,\n PaginatedResponse,\n CreateWorkspacePayload,\n SendMessagePayload,\n UpdateMessagePayload,\n WebhookSubscription,\n WorkspaceStatus,\n MemberRole,\n MemberType,\n ArtefactType,\n WorkspaceAgent,\n AgentDeleteInfo,\n EntityWithSecret,\n WorkspaceSummary,\n LatestSummaryResponse,\n} from '../types';\n\n// ─── Sync types (co-located with API for convenience) ─────────────────────────\n\nexport interface SyncLink {\n provider: string;\n externalId: string;\n externalName?: string;\n externalTeamId?: string;\n active: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface SyncStatus {\n syncWithSlack: boolean;\n syncProviders?: string[];\n links: SyncLink[];\n}\n\nexport interface SyncProviderInfo {\n id: string;\n enabled: boolean;\n}\n\nexport interface ToggleReactionResponse {\n action: 'created' | 'deleted';\n reaction: WorkspaceMessageReaction | null;\n}\n\n// ─── API factory ──────────────────────────────────────────────────────────────\n// Each API object uses the injected client (from WorkspaceProvider).\n\nexport function createWorkspaceApis(client: WorkspaceClient) {\n // ── Workspace Types ──\n const workspaceTypeApi = {\n list: () => client.get<WorkspaceType[]>('/workspace-types'),\n get: (id: string) => client.get<WorkspaceType>(`/workspace-types/${id}`),\n create: (payload: { name: string; entitiesWithSecrets?: EntityWithSecret[] }) =>\n client.post<WorkspaceType>('/workspace-types', payload),\n update: (id: string, payload: { name?: string; entitiesWithSecrets?: EntityWithSecret[] }) =>\n client.patch<WorkspaceType>(`/workspace-types/${id}`, payload),\n delete: (id: string) => client.delete<void>(`/workspace-types/${id}`),\n };\n\n // ── Workspaces ──\n const workspaceApi = {\n list: (params?: {\n search?: string;\n status?: string;\n type?: string;\n isPrivate?: boolean;\n limit?: number;\n skip?: number;\n }) => {\n const cleanParams = Object.fromEntries(\n Object.entries(params || {})\n .filter(([, v]) => v != null && v !== '' && v !== 'all')\n .map(([k, v]) => [k, String(v)])\n );\n const qs =\n Object.keys(cleanParams).length > 0\n ? '?' + new URLSearchParams(cleanParams as Record<string, string>).toString()\n : '';\n return client.get<PaginatedResponse<Workspace>>(`/workspaces${qs}`);\n },\n get: (id: string) => client.get<Workspace>(`/workspaces/${id}`),\n create: (payload: CreateWorkspacePayload) =>\n client.post<Workspace>('/workspaces', payload),\n update: (id: string, payload: Partial<Omit<CreateWorkspacePayload, 'members'>>) =>\n client.patch<Workspace>(`/workspaces/${id}`, payload),\n updateStatus: (id: string, status: WorkspaceStatus) =>\n client.patch<Workspace>(`/workspaces/${id}/status`, { status }),\n delete: (id: string) => client.delete<void>(`/workspaces/${id}`),\n startTyping: (id: string) => client.post<void>(`/workspaces/${id}/writing/start`, {}),\n stopTyping: (id: string) => client.post<void>(`/workspaces/${id}/writing/stop`, {}),\n timeline: (\n workspaceId: string,\n params?: { limit?: number; offset?: number; entityType?: string }\n ) => {\n const qs = params\n ? '?' +\n new URLSearchParams(\n Object.fromEntries(\n Object.entries(params)\n .filter(([, v]) => v != null)\n .map(([k, v]) => [k, String(v)])\n )\n ).toString()\n : '';\n return client.get<PaginatedResponse<any>>(`/workspaces/${workspaceId}/timeline${qs}`);\n },\n };\n\n // ── Members ──\n const memberApi = {\n list: (workspaceId: string) =>\n client.get<WorkspaceMember[]>(`/workspaces/${workspaceId}/members`),\n add: (\n workspaceId: string,\n payload: { memberId: string; memberName: string; memberType?: MemberType; role?: MemberRole }\n ) => client.post<WorkspaceMember>(`/workspaces/${workspaceId}/members`, payload),\n updateRole: (workspaceId: string, memberId: string, role: MemberRole) =>\n client.patch<WorkspaceMember>(`/workspaces/${workspaceId}/members/${memberId}`, { role }),\n remove: (workspaceId: string, memberId: string) =>\n client.delete<void>(`/workspaces/${workspaceId}/members/${memberId}`),\n };\n\n // ── Messages ──\n const messageApi = {\n list: (\n workspaceId: string,\n params?: { limit?: number; offset?: number; sort?: 'asc' | 'desc' }\n ) => {\n const qs = params\n ? '?' +\n new URLSearchParams(\n Object.fromEntries(\n Object.entries(params)\n .filter(([, v]) => v != null)\n .map(([k, v]) => [k, String(v)])\n )\n ).toString()\n : '';\n return client.get<PaginatedResponse<WorkspaceMessage>>(`/workspaces/${workspaceId}/messages${qs}`);\n },\n send: (workspaceId: string, payload: SendMessagePayload) =>\n client.post<WorkspaceMessage>(`/workspaces/${workspaceId}/messages`, payload),\n update: (workspaceId: string, messageId: string, payload: UpdateMessagePayload) =>\n client.patch<WorkspaceMessage>(`/workspaces/${workspaceId}/messages/${messageId}`, payload),\n delete: (workspaceId: string, messageId: string) =>\n client.delete<WorkspaceMessage>(`/workspaces/${workspaceId}/messages/${messageId}`),\n togglePin: (workspaceId: string, messageId: string) =>\n client.patch<WorkspaceMessage>(`/workspaces/${workspaceId}/messages/${messageId}/pin`, {}),\n };\n\n // ── Artefacts ──\n const artefactApi = {\n upload: async (\n workspaceId: string,\n files: File[],\n messageId?: string,\n artefactType?: string\n ): Promise<{ success: boolean; count: number; results: WorkspaceArtefact[] }> => {\n const formData = new FormData();\n files.forEach((f) => formData.append('files', f));\n if (messageId) formData.append('messageId', messageId);\n if (artefactType) formData.append('type', artefactType);\n return client.upload(`/workspaces/${workspaceId}/artefacts`, formData);\n },\n list: (workspaceId: string, artefactType?: ArtefactType) => {\n const query = artefactType ? `?type=${artefactType}` : '';\n return client.get<{ data: WorkspaceArtefact[]; total: number }>(\n `/workspaces/${workspaceId}/artefacts${query}`\n );\n },\n listPaginated: (\n workspaceId: string,\n params?: { type?: ArtefactType; limit?: number; offset?: number }\n ) => {\n const entries: [string, string][] = [];\n if (params) {\n if (params.type) entries.push(['type', params.type]);\n if (params.limit != null) entries.push(['limit', String(params.limit)]);\n if (params.offset != null) entries.push(['offset', String(params.offset)]);\n }\n const qs = entries.length > 0 ? '?' + new URLSearchParams(entries).toString() : '';\n return client.get<PaginatedResponse<WorkspaceArtefact>>(\n `/workspaces/${workspaceId}/artefacts${qs}`\n );\n },\n delete: (workspaceId: string, artefactId: string) =>\n client.delete(`/workspaces/${workspaceId}/artefacts/${artefactId}`),\n getSignedUrl: (fileId: string) =>\n client.get<{ url: string }>(`/files/${fileId}/signed-url`),\n getDownloadBlob: (fileId: string) => client.getBlob(`/files/${fileId}/download`),\n messagesWithArtefacts: (\n workspaceId: string,\n params?: {\n limit?: number;\n offset?: number;\n sort?: 'asc' | 'desc';\n members?: string[];\n concernsMe?: boolean;\n pinned?: boolean;\n }\n ) => {\n const entries: [string, string][] = [];\n if (params) {\n if (params.limit != null) entries.push(['limit', String(params.limit)]);\n if (params.offset != null) entries.push(['offset', String(params.offset)]);\n if (params.sort) entries.push(['sort', params.sort]);\n if (params.members && params.members.length > 0)\n entries.push(['members', params.members.join(',')]);\n if (params.concernsMe) entries.push(['concernsMe', 'true']);\n if (params.pinned) entries.push(['pinned', 'true']);\n }\n const qs = entries.length > 0 ? '?' + new URLSearchParams(entries).toString() : '';\n return client.get<PaginatedResponse<MessageWithArtefacts>>(\n `/workspaces/${workspaceId}/messages/with-artefacts${qs}`\n );\n },\n };\n\n // ── Reactions ──\n const reactionApi = {\n toggle: (workspaceId: string, messageId: string, reaction: string) =>\n client.post<ToggleReactionResponse>(\n `/workspaces/${workspaceId}/messages/${messageId}/reactions/toggle`,\n { reaction }\n ),\n };\n\n // ── Agents ──\n const agentApi = {\n list: (search?: string) => {\n const qs = search ? `?search=${encodeURIComponent(search)}` : '';\n return client.get<WorkspaceAgent[]>(`/workspace-agents${qs}`);\n },\n create: (body: { agentId: string; agentName: string }) =>\n client.post<WorkspaceAgent>('/workspace-agents', body),\n update: (id: string, body: { agentName: string }) =>\n client.patch<WorkspaceAgent>(`/workspace-agents/${id}`, body),\n delete: (id: string) => client.delete<void>(`/workspace-agents/${id}`),\n getDeleteInfo: (id: string) =>\n client.get<AgentDeleteInfo>(`/workspace-agents/${id}/delete-info`),\n };\n\n // ── Summaries ──\n const summaryApi = {\n generate: (workspaceId: string) =>\n client.post<WorkspaceSummary>(`/workspaces/${workspaceId}/summaries/generate`, {}),\n getLatest: (workspaceId: string) =>\n client.get<LatestSummaryResponse>(`/workspaces/${workspaceId}/summaries/latest`),\n getHistory: (workspaceId: string) =>\n client.get<WorkspaceSummary[]>(`/workspaces/${workspaceId}/summaries`),\n create: (\n workspaceId: string,\n payload: {\n keyPoints: string[];\n keyTasks: string[];\n keyDecisions: string[];\n messageCount: number;\n lastMessage?: string;\n wasTruncated?: boolean;\n generatedAt?: string;\n }\n ) => client.post<WorkspaceSummary>(`/workspaces/${workspaceId}/summaries`, payload),\n update: (\n workspaceId: string,\n summaryId: string,\n payload: Partial<{\n keyPoints: string[];\n keyTasks: string[];\n keyDecisions: string[];\n messageCount: number;\n wasTruncated: boolean;\n }>\n ) =>\n client.patch<WorkspaceSummary>(\n `/workspaces/${workspaceId}/summaries/${summaryId}`,\n payload\n ),\n };\n\n // ── Webhooks ──\n const webhookApi = {\n list: (params?: { search?: string; isAgent?: string; agentId?: string }) => {\n const cleanParams = Object.fromEntries(\n Object.entries(params || {}).filter(([, v]) => v !== undefined && v !== '')\n );\n const qs =\n Object.keys(cleanParams).length > 0\n ? '?' + new URLSearchParams(cleanParams as Record<string, string>).toString()\n : '';\n return client.get<WebhookSubscription[]>(`/webhook-subscriptions${qs}`);\n },\n create: (data: {\n name: string;\n targetUrl: string;\n secretKey: string;\n secretValue: string;\n eventTypes?: string[];\n active?: boolean;\n isAgent?: boolean;\n agentId?: string;\n metadata?: Record<string, unknown>;\n }) => client.post<WebhookSubscription>('/webhook-subscriptions', data),\n update: (\n id: string,\n data: Partial<{\n name: string;\n targetUrl: string;\n secretKey: string;\n secretValue: string;\n eventTypes: string[];\n active: boolean;\n isAgent: boolean;\n agentId: string;\n metadata: Record<string, unknown>;\n }>\n ) => client.patch<WebhookSubscription>(`/webhook-subscriptions/${id}`, data),\n delete: (id: string) => client.delete(`/webhook-subscriptions/${id}`),\n };\n\n // ── Sync ──\n const syncApi = {\n getAvailableProviders: () =>\n client\n .get<{ providers: SyncProviderInfo[] }>('/workspaces/sync/providers')\n .then((res) => res.providers),\n getStatus: (workspaceId: string) =>\n client.get<SyncStatus>(`/workspaces/${workspaceId}/sync-status`),\n toggleSync: (workspaceId: string, provider: string, enabled: boolean) =>\n client.patch<Workspace>(`/workspaces/${workspaceId}/sync`, { provider, enabled }),\n };\n\n return {\n workspaceTypeApi,\n workspaceApi,\n memberApi,\n messageApi,\n artefactApi,\n reactionApi,\n agentApi,\n summaryApi,\n webhookApi,\n syncApi,\n };\n}\n\nexport type WorkspaceApis = ReturnType<typeof createWorkspaceApis>;\n","import { create, type StoreApi, type UseBoundStore } from 'zustand';\nimport type { Workspace, WorkspaceMember, WorkspaceType } from '../types';\nimport type { WorkspaceApis } from '../api';\n\n// ─── Workspace List Store ─────────────────────────────────────────────────────\n// Zustand store for workspace list with in-memory cache, pagination,\n// group/private tabs, and real-time prepend/remove.\n\nconst PAGE_SIZE = 12;\n\nexport type WorkspaceTab = 'group' | 'private';\n\nexport interface WorkspaceListFilters {\n search: string;\n status: string;\n type: string;\n}\n\nexport interface WorkspaceListState {\n workspaces: Workspace[];\n total: number;\n membersMap: Record<string, WorkspaceMember[]>;\n types: WorkspaceType[];\n tab: WorkspaceTab;\n page: number;\n pageSize: number;\n totalPages: number;\n filters: WorkspaceListFilters;\n initialLoading: boolean;\n fetching: boolean;\n hydrated: boolean;\n\n setTab: (tab: WorkspaceTab) => void;\n setFilters: (filters: WorkspaceListFilters) => void;\n setPage: (page: number) => void;\n fetchWorkspaces: () => Promise<void>;\n fetchTypes: () => Promise<void>;\n prependWorkspace: (ws: Workspace, members?: WorkspaceMember[]) => void;\n removeWorkspace: (workspaceId: string) => void;\n refresh: () => Promise<void>;\n}\n\n/**\n * Factory that creates a Zustand store bound to the injected API client.\n * Call this inside your WorkspaceProvider or in a hook.\n */\nexport function createWorkspaceListStore(\n apis: WorkspaceApis\n): UseBoundStore<StoreApi<WorkspaceListState>> {\n return create<WorkspaceListState>()((set, get) => ({\n workspaces: [],\n total: 0,\n membersMap: {},\n types: [],\n tab: 'group',\n page: 1,\n pageSize: PAGE_SIZE,\n totalPages: 0,\n filters: { search: '', status: 'ACTIVE', type: 'all' },\n initialLoading: true,\n fetching: false,\n hydrated: false,\n\n setTab: (tab) => {\n const prev = get().tab;\n if (prev === tab) return;\n set({\n tab,\n page: 1,\n workspaces: [],\n total: 0,\n totalPages: 0,\n membersMap: {},\n });\n get().fetchWorkspaces();\n },\n\n setFilters: (filters) => {\n set({ filters, page: 1 });\n },\n\n setPage: (page) => {\n set({ page });\n },\n\n fetchTypes: async () => {\n try {\n const types = await apis.workspaceTypeApi.list();\n set({ types });\n } catch (err) {\n console.error('Failed to load workspace types:', err);\n }\n },\n\n fetchWorkspaces: async () => {\n const { filters, page, pageSize, hydrated, tab } = get();\n if (!hydrated) set({ initialLoading: true });\n set({ fetching: true });\n\n try {\n const skip = (page - 1) * pageSize;\n const result = await apis.workspaceApi.list({\n ...filters,\n isPrivate: tab === 'private',\n limit: pageSize,\n skip,\n });\n\n const wsList = result.data;\n const totalPages = Math.ceil(result.total / pageSize);\n\n const map: Record<string, WorkspaceMember[]> = {};\n await Promise.all(\n wsList.map(async (ws) => {\n try {\n map[ws._id] = await apis.memberApi.list(ws._id);\n } catch {\n map[ws._id] = [];\n }\n })\n );\n\n set({\n workspaces: wsList,\n total: result.total,\n totalPages,\n membersMap: map,\n hydrated: true,\n initialLoading: false,\n fetching: false,\n });\n } catch (err) {\n console.error('Failed to load workspaces:', err);\n set({ initialLoading: false, fetching: false });\n }\n },\n\n prependWorkspace: (ws, members = []) => {\n set((state) => {\n if (state.workspaces.some((w) => w._id === ws._id)) return state;\n return {\n workspaces: [ws, ...state.workspaces],\n total: state.total + 1,\n totalPages: Math.ceil((state.total + 1) / state.pageSize),\n membersMap: { ...state.membersMap, [ws._id]: members },\n };\n });\n },\n\n removeWorkspace: (workspaceId) => {\n set((state) => {\n const next = { ...state.membersMap };\n delete next[workspaceId];\n const newTotal = Math.max(0, state.total - 1);\n return {\n workspaces: state.workspaces.filter((w) => w._id !== workspaceId),\n total: newTotal,\n totalPages: Math.ceil(newTotal / state.pageSize),\n membersMap: next,\n };\n });\n },\n\n refresh: async () => {\n const { fetchWorkspaces } = get();\n await fetchWorkspaces();\n },\n }));\n}\n","import { useMemo } from 'react';\nimport { createWorkspaceApis, type WorkspaceApis } from '../api';\nimport { useWorkspaceContext } from '../provider';\n\n/**\n * Hook to access all workspace API modules within a WorkspaceProvider.\n * The APIs are memoized and only recreated when the client changes.\n */\nexport function useWorkspaceApi(): WorkspaceApis {\n const { apiClient } = useWorkspaceContext();\n return useMemo(() => createWorkspaceApis(apiClient), [apiClient]);\n}\n","import type { MemberType } from '../types';\n\n// ─── Static Agent Members ─────────────────────────────────────────────────────\n\nexport const AVAILABLE_AGENTS: {\n memberId: string;\n memberName: string;\n memberType: MemberType;\n}[] = [\n { memberId: 'james-agent', memberName: 'James', memberType: 'agent' },\n { memberId: 'eclaireur-agent', memberName: 'Éclaireur IA', memberType: 'agent' },\n { memberId: 'sentinelle-agent', memberName: 'Sentinelle', memberType: 'agent' },\n { memberId: 'archiviste-agent', memberName: 'Archiviste', memberType: 'agent' },\n { memberId: 'stratege-agent', memberName: 'Stratège', memberType: 'agent' },\n];\n\n// ─── Role Labels (French) ─────────────────────────────────────────────────────\n\nexport const ROLE_LABELS: Record<string, string> = {\n owner: 'Propriétaire',\n participant: 'Participant',\n viewer: 'Observateur',\n};\n\n// ─── Status Labels (French) ───────────────────────────────────────────────────\n\nexport const STATUS_LABELS: Record<string, string> = {\n ACTIVE: 'Actif',\n CLOSED: 'Fermé',\n ARCHIVED: 'Archivé',\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nexport function getInitials(name: string): string {\n return name\n .split(/\\s+/)\n .map((w) => w[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n}\n","import type {\n Workspace,\n WorkspaceType,\n WorkspaceMember,\n MessageWithArtefacts,\n} from '../types';\n\n// ─── Role labels ──────────────────────────────────────────────────────────────\n\nconst ROLE_LABELS: Record<string, string> = {\n owner: 'Propriétaire',\n participant: 'Participant',\n viewer: 'Observateur',\n};\n\nconst MEMBER_TYPE_LABELS: Record<string, string> = {\n user: 'Utilisateur',\n agent: 'Agent IA',\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatDate(iso: string): string {\n return new Date(iso).toLocaleDateString('fr-FR', {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n });\n}\n\nfunction formatDateTime(iso: string): string {\n return new Date(iso).toLocaleString('fr-FR', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nfunction getTypeName(workspace: Workspace): string {\n if (!workspace.type) return '—';\n if (typeof workspace.type === 'object') return (workspace.type as WorkspaceType).name;\n return workspace.type;\n}\n\n/**\n * Attempt to fix common mojibake patterns (UTF-8 decoded as Latin-1).\n * Simplified version — consumers can override with their own implementation.\n */\nfunction fixMojibake(text: string): string {\n return text\n .replace(/é/g, 'é')\n .replace(/è/g, 'è')\n .replace(/à /g, 'à')\n .replace(/ç/g, 'ç')\n .replace(/ô/g, 'ô')\n .replace(/î/g, 'î')\n .replace(/â/g, 'â')\n .replace(/ë/g, 'ë')\n .replace(/ü/g, 'ü');\n}\n\n// ─── Main export function ─────────────────────────────────────────────────────\n\nexport interface WorkspaceExportData {\n workspace: Workspace;\n members: WorkspaceMember[];\n messages: MessageWithArtefacts[];\n}\n\n/**\n * Generates a formatted Markdown string representing the full workspace export.\n * Includes context, members, and the complete discussion thread.\n */\nexport function formatWorkspaceExport(data: WorkspaceExportData): string {\n const { workspace, members, messages } = data;\n const lines: string[] = [];\n\n lines.push(`# 📋 Export — ${workspace.name}`);\n lines.push('');\n lines.push(`> Export généré le **${formatDateTime(new Date().toISOString())}**`);\n lines.push('');\n lines.push('---');\n lines.push('');\n\n lines.push('## 📌 Contexte');\n lines.push('');\n lines.push(`| Champ | Valeur |`);\n lines.push(`| ----- | ------ |`);\n lines.push(`| **Nom** | ${workspace.name} |`);\n lines.push(`| **Type** | ${getTypeName(workspace)} |`);\n lines.push(`| **Scope** | ${workspace.scope || '—'} |`);\n lines.push(`| **Statut** | ${workspace.status} |`);\n lines.push(`| **Créé le** | ${formatDate(workspace.createdAt)} |`);\n lines.push(`| **Mis à jour le** | ${formatDate(workspace.updatedAt)} |`);\n\n const displayEntities = workspace.entitiesWithSecrets ?? [];\n if (displayEntities.length > 0) {\n lines.push('');\n lines.push('### Entités');\n lines.push('');\n lines.push('| Clé | Valeur | Secret |');\n lines.push('| --- | ------ | ------ |');\n for (const ent of displayEntities) {\n lines.push(\n `| ${ent.key} | ${ent.isSecret ? '••••••' : ent.value} | ${ent.isSecret ? '🔒 Oui' : 'Non'} |`\n );\n }\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n\n lines.push(`## 👥 Membres (${members.length})`);\n lines.push('');\n lines.push('| Nom | Type | Rôle | Rejoint le |');\n lines.push('| --- | ---- | ---- | ---------- |');\n for (const m of members) {\n lines.push(\n `| ${m.memberName} | ${MEMBER_TYPE_LABELS[m.memberType] || m.memberType} | ${ROLE_LABELS[m.role] || m.role} | ${m.joinedAt || m.createdAt ? formatDate(m.joinedAt || m.createdAt!) : '—'} |`\n );\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n\n lines.push(`## 💬 Discussion (${messages.length} messages)`);\n lines.push('');\n\n if (messages.length === 0) {\n lines.push('_Aucun message dans ce workspace._');\n } else {\n let currentDay = '';\n for (const msg of messages) {\n const day = formatDate(msg.createdAt);\n if (day !== currentDay) {\n currentDay = day;\n lines.push(`### 📅 ${day}`);\n lines.push('');\n }\n const timeStr = new Date(msg.createdAt).toLocaleTimeString('fr-FR', {\n hour: '2-digit',\n minute: '2-digit',\n });\n const senderIcon = msg.senderType === 'agent' ? '🤖' : '👤';\n lines.push(`**${senderIcon} ${msg.senderName}** — _${timeStr}_`);\n lines.push('');\n lines.push(msg.content);\n lines.push('');\n if (msg.artefacts && msg.artefacts.length > 0) {\n lines.push('> 📎 Pièces jointes :');\n for (const art of msg.artefacts) {\n lines.push(`> - \\`${fixMojibake(art.file.originalName)}\\` (${art.type})`);\n }\n lines.push('');\n }\n lines.push('---');\n lines.push('');\n }\n }\n\n lines.push('');\n lines.push(`_Fin de l'export — ${workspace.name}_`);\n\n return lines.join('\\n');\n}\n","import React, { useEffect, useId, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { X } from 'lucide-react';\nimport { cn } from './cn';\n\n/** Preset width for the centered panel */\nexport type ModalSize =\n | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | 'full';\n\nexport type ModalHeaderVariant = 'strip' | 'plain';\n\nconst MODAL_SIZE_CLASS: Record<ModalSize, string> = {\n sm: 'w-full min-w-0 max-w-sm',\n md: 'w-full min-w-0 max-w-md',\n lg: 'w-full min-w-0 max-w-lg',\n xl: 'w-full min-w-0 max-w-xl',\n '2xl': 'w-full min-w-0 max-w-2xl',\n '3xl': 'w-full min-w-0 max-w-3xl',\n '4xl': 'w-full min-w-0 max-w-4xl',\n '5xl': 'w-full min-w-0 max-w-5xl',\n '6xl': 'w-full min-w-0 max-w-6xl',\n '7xl': 'w-full min-w-0 max-w-7xl',\n full: 'w-full min-w-0 max-w-[calc(100vw-2rem)] sm:max-w-[min(96vw,90rem)]',\n};\n\nexport interface ModalProps {\n open: boolean;\n onClose: () => void;\n children: React.ReactNode;\n zIndexClass?: string;\n backdropClassName?: string;\n size?: ModalSize;\n panelClassName?: string;\n className?: string;\n closeOnBackdropClick?: boolean;\n closeOnEscape?: boolean;\n ariaLabelledBy?: string;\n ariaDescribedBy?: string;\n title?: React.ReactNode;\n description?: React.ReactNode;\n titleIcon?: React.ReactNode;\n headingId?: string;\n modalHeaderVariant?: ModalHeaderVariant;\n hideCloseButton?: boolean;\n headerTrailing?: React.ReactNode;\n closeButtonAriaLabel?: string;\n closeButtonDisabled?: boolean;\n closeButtonClassName?: string;\n closeIconSize?: number;\n headerClassName?: string;\n titleClassName?: string;\n descriptionClassName?: string;\n}\n\nexport function Modal({\n open,\n onClose,\n children,\n zIndexClass = 'z-[100]',\n backdropClassName = 'bg-black/40 backdrop-blur-sm',\n size,\n panelClassName,\n className,\n closeOnBackdropClick = false,\n closeOnEscape = true,\n ariaLabelledBy: ariaLabelledByProp,\n ariaDescribedBy: ariaDescribedByProp,\n title,\n description,\n titleIcon,\n headingId,\n modalHeaderVariant = 'strip',\n hideCloseButton = false,\n headerTrailing,\n closeButtonAriaLabel = 'Fermer',\n closeButtonDisabled = false,\n closeButtonClassName,\n closeIconSize = 20,\n headerClassName,\n titleClassName,\n descriptionClassName = 'text-text-secondary mt-1 text-sm',\n}: ModalProps) {\n const [mounted, setMounted] = useState(false);\n const autoHeadingId = useId();\n const autoDescIdByModal = useId();\n\n const hasHeader = title != null;\n const resolvedHeadingId = headingId ?? ariaLabelledByProp ?? autoHeadingId;\n\n const assignAutoDescriptionId =\n hasHeader &&\n description != null &&\n ariaDescribedByProp === undefined &&\n (typeof description === 'string' || typeof description === 'number');\n\n const resolvedAriaDescribedBy = assignAutoDescriptionId\n ? autoDescIdByModal\n : ariaDescribedByProp;\n\n const resolvedAriaLabelledBy = hasHeader\n ? ariaLabelledByProp ?? resolvedHeadingId\n : ariaLabelledByProp;\n\n useEffect(() => { setMounted(true); }, []);\n\n useEffect(() => {\n if (!open) return;\n const prevOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n return () => { document.body.style.overflow = prevOverflow; };\n }, [open]);\n\n useEffect(() => {\n if (!open || !closeOnEscape) return;\n const onKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [open, closeOnEscape, onClose]);\n\n const defaultCloseClasses =\n closeButtonClassName ?? 'text-text-secondary hover:text-text rounded p-1 transition-colors';\n\n const trailing =\n headerTrailing ??\n (!hideCloseButton ? (\n <button\n type=\"button\"\n disabled={closeButtonDisabled}\n onClick={onClose}\n className={cn(defaultCloseClasses, closeButtonDisabled && 'opacity-40')}\n aria-label={closeButtonAriaLabel}\n >\n <X size={closeIconSize} />\n </button>\n ) : null);\n\n const descriptionSlot =\n description == null ? null : typeof description === 'string' ||\n typeof description === 'number' ? (\n <p\n id={assignAutoDescriptionId ? autoDescIdByModal : undefined}\n className={descriptionClassName}\n >\n {description}\n </p>\n ) : (\n description\n );\n\n const headerShellClass =\n modalHeaderVariant === 'strip'\n ? 'border-border flex shrink-0 items-start justify-between gap-3 border-b px-6 py-4'\n : 'mb-4 flex shrink-0 items-start justify-between gap-3';\n\n const modalHeaderMarkup = hasHeader ? (\n <div className={cn(headerShellClass, headerClassName)}>\n <div className=\"flex min-w-0 flex-1 items-start gap-3\">\n {titleIcon != null ? <div className=\"mt-0.5 shrink-0\">{titleIcon}</div> : null}\n <div className=\"min-w-0 flex-1\">\n <h2\n id={resolvedHeadingId}\n className={cn('text-text text-lg font-semibold', titleClassName)}\n >\n {title}\n </h2>\n {descriptionSlot}\n </div>\n </div>\n {trailing ? <div className=\"flex shrink-0 items-start\">{trailing}</div> : null}\n </div>\n ) : null;\n\n if (!mounted || !open) return null;\n\n return createPortal(\n <div\n className={cn(\n 'fixed inset-0 flex items-center justify-center p-4',\n zIndexClass,\n backdropClassName,\n className,\n )}\n onClick={closeOnBackdropClick ? onClose : undefined}\n aria-hidden={false}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={resolvedAriaLabelledBy}\n aria-describedby={resolvedAriaDescribedBy}\n className={cn(size ? MODAL_SIZE_CLASS[size] : undefined, panelClassName)}\n onClick={(e) => e.stopPropagation()}\n >\n {modalHeaderMarkup}\n {children}\n </div>\n </div>,\n document.body,\n );\n}\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import React from 'react';\nimport { Brain } from 'lucide-react';\nimport { cn } from './ui/cn';\nimport { getInitials } from '../utils/constants';\n\ntype AvatarSize = 'xs' | 'sm' | 'md' | 'lg';\n\nconst SIZES: Record<AvatarSize, { container: string; text: string; icon: number }> = {\n xs: { container: 'h-6 w-6', text: 'text-[9px]', icon: 10 },\n sm: { container: 'h-7 w-7', text: 'text-[10px]', icon: 12 },\n md: { container: 'h-9 w-9', text: 'text-xs', icon: 16 },\n lg: { container: 'h-10 w-10', text: 'text-sm', icon: 18 },\n};\n\nexport interface MemberAvatarProps {\n memberName: string;\n memberType: 'user' | 'agent';\n avatarUrl?: string | null;\n size?: AvatarSize;\n className?: string;\n variant?: 'primary' | 'owner' | 'currentUser';\n}\n\nexport const MemberAvatar: React.FC<MemberAvatarProps> = ({\n memberName, memberType, avatarUrl, size = 'md', className, variant = 'primary',\n}) => {\n const s = SIZES[size];\n if (memberType === 'agent') {\n return (\n <span className={cn('flex flex-shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-violet-100 to-indigo-100 ring-1 ring-indigo-200/60', s.container, className)}>\n <Brain size={s.icon} className=\"text-indigo-600\" />\n </span>\n );\n }\n if (avatarUrl) {\n return <img src={avatarUrl} alt={memberName} className={cn('flex-shrink-0 rounded-full object-cover ring-2 ring-white', s.container, className)} />;\n }\n return (\n <span className={cn('flex flex-shrink-0 items-center justify-center rounded-full font-semibold', s.container, s.text, variant === 'currentUser' ? 'bg-primary text-white shadow-md' : variant === 'owner' ? 'bg-warning-light text-warning' : 'bg-primary-light text-primary', className)}>\n {getInitials(memberName)}\n </span>\n );\n};\n","import React, { useState, useEffect, useMemo } from 'react';\nimport { UserPlus, Crown, Eye, Users, X, Search, Plus, Brain, Loader2, Check } from 'lucide-react';\nimport type { WorkspaceMember, MemberRole, MemberType, WorkspaceAgent } from '../types';\nimport { useWorkspaceContext } from '../provider';\nimport { useWorkspaceApi } from '../hooks/useWorkspaceApi';\nimport { getInitials, ROLE_LABELS } from '../utils/constants';\nimport { MemberAvatar } from './MemberAvatar';\n\nexport interface AvatarUser { email: string; avatarUrl?: string }\n\ninterface MembersPanelProps {\n members: WorkspaceMember[];\n avatarUsers?: AvatarUser[];\n onAddMember?: (payload: { memberId: string; memberName: string; memberType: MemberType; role?: MemberRole }) => void;\n onRemoveMember?: (memberId: string) => void;\n onUpdateRole?: (memberId: string, role: MemberRole) => void;\n readonly?: boolean;\n}\n\nconst roleIcon = (role: MemberRole) => {\n switch (role) {\n case 'owner': return <Crown size={11} className=\"text-warning\" />;\n case 'viewer': return <Eye size={11} className=\"text-text-muted\" />;\n default: return <Users size={11} className=\"text-primary\" />;\n }\n};\n\nexport const MembersPanel: React.FC<MembersPanelProps> = ({\n members, avatarUsers, onAddMember, onRemoveMember, onUpdateRole, readonly,\n}) => {\n const { config } = useWorkspaceContext();\n const apis = useWorkspaceApi();\n const [showUserSearch, setShowUserSearch] = useState(false);\n const [search, setSearch] = useState('');\n const [searchResults, setSearchResults] = useState<{ id: string; email: string; displayName: string; avatarUrl?: string }[]>([]);\n const [searchingUsers, setSearchingUsers] = useState(false);\n const [allAgents, setAllAgents] = useState<WorkspaceAgent[]>([]);\n\n useEffect(() => {\n apis.agentApi.list().then(setAllAgents).catch(() => setAllAgents([]));\n }, []);\n\n // User search via injected searchUsers callback\n useEffect(() => {\n if (search.length < 2 || !showUserSearch || !config.searchUsers) {\n setSearchResults([]);\n return;\n }\n let cancelled = false;\n setSearchingUsers(true);\n config.searchUsers(search).then((results) => {\n if (!cancelled) setSearchResults(results);\n }).catch(() => {\n if (!cancelled) setSearchResults([]);\n }).finally(() => {\n if (!cancelled) setSearchingUsers(false);\n });\n return () => { cancelled = true; };\n }, [search, showUserSearch, config.searchUsers]);\n\n const filteredUsers = useMemo(() => {\n return searchResults.filter(\n (u) => u.email !== config.currentUserId && !members.some((m) => m.memberId === u.email)\n );\n }, [searchResults, members, config.currentUserId]);\n\n const userMembers = members.filter((m) => m.memberType === 'user');\n const agentMembers = members.filter((m) => m.memberType === 'agent');\n const agentMemberIds = useMemo(() => new Set(agentMembers.map((m) => m.memberId)), [agentMembers]);\n const agentMemberIdMap = useMemo(() => new Map(agentMembers.map((m) => [m.memberId, m._id])), [agentMembers]);\n\n const handleAddUser = (user: { email: string; displayName: string }) => {\n onAddMember?.({ memberId: user.email, memberName: user.displayName, memberType: 'user', role: 'participant' });\n setSearch('');\n setShowUserSearch(false);\n };\n\n const handleAddAgent = (agent: WorkspaceAgent) => {\n onAddMember?.({ memberId: agent.agentId, memberName: agent.agentName, memberType: 'agent', role: 'participant' });\n };\n\n return (\n <div className=\"flex flex-col gap-4\">\n {/* Users section */}\n <div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase\">\n <Users size={14} className=\"text-primary\" /> Utilisateurs\n </span>\n <span className=\"flex items-center gap-1\">\n <span className=\"bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold\">{userMembers.length}</span>\n {!readonly && (\n <button className=\"text-primary hover:bg-primary-light flex items-center gap-1 rounded px-2 py-1 text-xs transition-colors\" onClick={() => setShowUserSearch(!showUserSearch)}>\n <UserPlus size={12} /> Inviter\n </button>\n )}\n </span>\n </div>\n {showUserSearch && (\n <>\n <div className=\"relative mt-2\">\n <Search size={12} className=\"text-text-muted absolute top-1/2 left-2 -translate-y-1/2\" />\n <input className=\"border-border bg-surface text-text focus:border-primary w-full rounded-lg border py-1.5 pr-2 pl-7 text-xs focus:outline-none\" placeholder=\"Rechercher par nom ou email...\" value={search} onChange={(e) => setSearch(e.target.value)} autoFocus />\n </div>\n {search.length >= 2 && searchingUsers && (\n <div className=\"flex items-center justify-center py-3\"><Loader2 size={14} className=\"text-primary animate-spin\" /></div>\n )}\n {filteredUsers.length > 0 && !searchingUsers && (\n <div className=\"bg-surface border-border mt-1 flex flex-col rounded-lg border shadow-sm\">\n {filteredUsers.map((u) => (\n <div key={u.id} className=\"hover:bg-primary-light flex cursor-pointer items-center gap-2 px-3 py-2 text-xs transition-colors first:rounded-t-lg last:rounded-b-lg\" onClick={() => handleAddUser(u)}>\n <span className=\"bg-primary-light text-primary flex h-6 w-6 items-center justify-center rounded-full text-[10px] font-semibold\">{getInitials(u.displayName)}</span>\n <span className=\"text-text\">{u.displayName}</span>\n <Plus size={12} className=\"text-primary ml-auto\" />\n </div>\n ))}\n </div>\n )}\n </>\n )}\n <div className=\"mt-2 flex flex-col gap-1\">\n {userMembers.map((m) => (\n <div key={m._id} className=\"bg-bg group flex items-center gap-2 rounded-lg p-2\">\n <MemberAvatar memberName={m.memberName} memberType={m.memberType} avatarUrl={avatarUsers?.find((u) => u.email.toLowerCase() === m.memberId.toLowerCase())?.avatarUrl} size=\"sm\" variant={m.role === 'owner' ? 'owner' : 'primary'} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-text truncate text-xs font-medium\">{m.memberName}</div>\n <div className=\"text-text-muted flex items-center gap-1 text-[10px]\">{roleIcon(m.role)} {ROLE_LABELS[m.role] ?? m.role}</div>\n </div>\n {!(readonly || (m.role === 'owner' && members.filter((x) => x.role === 'owner').length === 1)) && (\n <select className=\"border-border bg-surface text-text-muted rounded border px-1 py-0.5 text-[10px] opacity-0 transition-opacity group-hover:opacity-100 focus:opacity-100\" value={m.role} onChange={(e) => { e.stopPropagation(); onUpdateRole?.(m._id, e.target.value as MemberRole); }} disabled={readonly || (m.role === 'owner' && members.filter((x) => x.role === 'owner').length === 1)}>\n <option value=\"owner\">Propriétaire</option>\n <option value=\"participant\">Participant</option>\n <option value=\"viewer\">Observateur</option>\n </select>\n )}\n {m.role !== 'owner' && !readonly && (\n <button className=\"text-text-muted hover:text-danger rounded p-0.5 opacity-0 transition-all group-hover:opacity-100\" onClick={(e) => { e.stopPropagation(); onRemoveMember?.(m._id); }}>\n <X size={14} />\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n {/* Agents section */}\n <div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase\">\n <Brain size={14} className=\"text-primary\" /> Agents IA\n </span>\n <span className=\"bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold\">{agentMembers.length}/{allAgents.length}</span>\n </div>\n <div className=\"mt-2 flex flex-col gap-1\">\n {allAgents.map((agent) => {\n const isMember = agentMemberIds.has(agent.agentId);\n const memberId = agentMemberIdMap.get(agent.agentId);\n return (\n <div key={agent.agentId} className=\"bg-bg group flex items-center gap-2 rounded-lg p-2\">\n <span className=\"bg-surface border-border flex h-7 w-7 items-center justify-center rounded-full border\"><Brain size={14} className=\"text-primary\" /></span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-text truncate text-xs font-medium\">{agent.agentName}</div>\n <div className=\"text-text-muted text-[10px]\">Agent IA</div>\n </div>\n {!readonly && (\n isMember ? (\n <button className=\"relative flex h-6 w-6 items-center justify-center rounded-full transition-colors\" onClick={(e) => { e.stopPropagation(); if (memberId) onRemoveMember?.(memberId); }}>\n <Check size={14} className=\"text-success absolute transition-opacity group-hover:opacity-0\" />\n <X size={14} className=\"text-danger absolute opacity-0 transition-opacity group-hover:opacity-100\" />\n </button>\n ) : (\n <button className=\"text-text-muted hover:text-primary hover:bg-primary-light flex h-6 w-6 items-center justify-center rounded-full transition-colors\" onClick={(e) => { e.stopPropagation(); handleAddAgent(agent); }}>\n <Plus size={14} />\n </button>\n )\n )}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n};\n","import React, { useState, useEffect, useMemo, useId, useRef } from 'react';\nimport { X, ArrowRight, ArrowLeft, Plus, Trash2, Check, Users, Brain, Loader2, Lock, Unlock, Slack } from 'lucide-react';\nimport { cn } from './ui/cn';\nimport { useWorkspaceContext } from '../provider';\nimport { useWorkspaceApi } from '../hooks/useWorkspaceApi';\nimport type { WorkspaceType, CreateWorkspacePayload, MemberType, WorkspaceAgent, EntityWithSecret } from '../types';\nimport { getInitials } from '../utils/constants';\nimport { Modal } from './ui/Modal';\nimport { MemberAvatar } from './MemberAvatar';\n\ninterface CreateWorkspaceModalProps {\n open: boolean;\n onClose: () => void;\n onCreated?: (workspace: unknown) => void;\n}\n\ninterface MemberEntry {\n memberId: string;\n memberName: string;\n memberType: MemberType;\n role: string;\n}\n\nconst STEP_TITLES = ['Type de workspace', 'Contexte', 'Membres', 'Confirmation'];\n\nexport const CreateWorkspaceModal: React.FC<CreateWorkspaceModalProps> = ({ open, onClose, onCreated }) => {\n const titleId = useId();\n const stepDescriptionId = useId();\n const { config } = useWorkspaceContext();\n const apis = useWorkspaceApi();\n\n const [step, setStep] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Step 0: Type\n const [types, setTypes] = useState<WorkspaceType[]>([]);\n const [typesLoading, setTypesLoading] = useState(false);\n const [selectedTypeId, setSelectedTypeId] = useState<string | null>(null);\n\n // Step 1: Context\n const [name, setName] = useState('');\n const [scope, setScope] = useState('');\n const [entities, setEntities] = useState<{ key: string; value: string; isSecret: boolean }[]>([]);\n const [syncWithSlack, setSyncWithSlack] = useState(false);\n const [slackAvailable, setSlackAvailable] = useState(false);\n\n // Step 2: Members\n const [memberSearch, setMemberSearch] = useState('');\n const [members, setMembers] = useState<MemberEntry[]>([]);\n const [agents, setAgents] = useState<WorkspaceAgent[]>([]);\n const [searchResults, setSearchResults] = useState<{ id: string; email: string; displayName: string; avatarUrl?: string }[]>([]);\n const [searchingUsers, setSearchingUsers] = useState(false);\n const [avatarMap, setAvatarMap] = useState<Record<string, string>>({});\n\n // Agent autocomplete\n const [agentSearch, setAgentSearch] = useState('');\n const [showAgentDropdown, setShowAgentDropdown] = useState(false);\n const [agentSearchFocused, setAgentSearchFocused] = useState(false);\n const agentSearchInputRef = useRef<HTMLInputElement>(null);\n\n const invitedUsers = useMemo(() => members.filter((m) => m.memberType === 'user'), [members]);\n const invitedAgents = useMemo(() => members.filter((m) => m.memberType === 'agent'), [members]);\n const unselectedAgents = useMemo(() => agents.filter((a) => !members.some((m) => m.memberId === a.agentId) && (agentSearch.trim() === '' || a.agentName.toLowerCase().includes(agentSearch.toLowerCase()))), [agents, members, agentSearch]);\n\n // Resolve avatars when members change\n useEffect(() => {\n if (!config.resolveAvatars || invitedUsers.length === 0) return;\n config.resolveAvatars(invitedUsers.map((m) => m.memberId)).then(setAvatarMap).catch(() => {});\n }, [invitedUsers.length]);\n\n // User search via injected searchUsers\n useEffect(() => {\n if (memberSearch.length < 2 || !config.searchUsers) { setSearchResults([]); return; }\n let cancelled = false;\n setSearchingUsers(true);\n config.searchUsers(memberSearch).then((r) => { if (!cancelled) setSearchResults(r); }).catch(() => { if (!cancelled) setSearchResults([]); }).finally(() => { if (!cancelled) setSearchingUsers(false); });\n return () => { cancelled = true; };\n }, [memberSearch]);\n\n const filteredUsers = useMemo(() => searchResults.filter((u) => u.email !== config.currentUserId && !members.some((m) => m.memberId === u.email)), [searchResults, members, config.currentUserId]);\n\n // Load types on mount\n useEffect(() => {\n if (!open) return;\n setTypesLoading(true);\n Promise.all([apis.workspaceTypeApi.list(), apis.agentApi.list()])\n .then(([wt, ag]) => { setTypes(wt); setAgents(ag); })\n .catch(() => { setTypes([]); setAgents([]); })\n .finally(() => setTypesLoading(false));\n apis.syncApi.getAvailableProviders().then((providers) => setSlackAvailable(providers.some((p) => p.id === 'slack' && p.enabled))).catch(() => setSlackAvailable(false));\n }, [open]);\n\n // Pre-fill entities when type changes\n useEffect(() => {\n if (!selectedTypeId) return;\n const t = types.find((tp) => tp._id === selectedTypeId);\n if (t?.entitiesWithSecrets && t.entitiesWithSecrets.length > 0) {\n setEntities(t.entitiesWithSecrets.map((e) => ({ key: e.key, value: e.value, isSecret: e.isSecret })));\n }\n }, [selectedTypeId, types]);\n\n // Reset on close\n useEffect(() => {\n if (!open) { setStep(0); setSelectedTypeId(null); setName(''); setScope(''); setEntities([]); setSyncWithSlack(false); setMembers([]); setMemberSearch(''); setError(null); }\n }, [open]);\n\n const selectedType = types.find((t) => t._id === selectedTypeId);\n const canAdvance = () => { switch (step) { case 0: return !!selectedTypeId; case 1: return name.trim().length > 0; default: return true; } };\n\n const addMember = (memberId: string, memberName: string, memberType: MemberType) => {\n if (members.some((m) => m.memberId === memberId)) return;\n setMembers((prev) => [...prev, { memberId, memberName, memberType, role: 'participant' }]);\n setMemberSearch('');\n };\n\n const removeMember = (memberId: string) => setMembers((prev) => prev.filter((m) => m.memberId !== memberId));\n\n const handleCreate = async () => {\n setLoading(true); setError(null);\n try {\n const entitiesWithSecrets: EntityWithSecret[] = entities.filter((e) => e.key.trim()).map((e) => ({ key: e.key.trim(), value: e.value, isSecret: e.isSecret }));\n const payload: CreateWorkspacePayload = {\n name: name.trim(), type: selectedTypeId || undefined, scope: scope.trim() || undefined,\n entitiesWithSecrets: entitiesWithSecrets.length > 0 ? entitiesWithSecrets : undefined,\n members: members.length > 0 ? members.map((m) => ({ memberId: m.memberId, memberName: m.memberName, memberType: m.memberType, role: m.role })) : undefined,\n syncWithSlack: syncWithSlack || undefined,\n };\n const ws = await apis.workspaceApi.create(payload);\n onCreated?.(ws); onClose();\n } catch (err) { setError((err as Error).message); }\n finally { setLoading(false); }\n };\n\n return (\n <Modal open={open} onClose={onClose} zIndexClass=\"z-50\" size=\"md\" closeOnBackdropClick={false} backdropClassName=\"bg-black/40\" panelClassName=\"bg-surface border-border flex h-[600px] max-h-[min(90dvh,100vh)] flex-col overflow-hidden rounded-2xl border shadow-xl\" headingId={titleId} ariaLabelledBy={titleId} ariaDescribedBy={stepDescriptionId} title=\"Nouveau Workspace\" description={<p id={stepDescriptionId} className=\"text-text-muted text-xs\">Étape {step + 1}/4 — {STEP_TITLES[step]}</p>} headerClassName=\"items-center\" closeButtonClassName=\"text-text-muted hover:text-text transition-colors\">\n {/* Step progress bar */}\n <div className=\"flex shrink-0 gap-1 px-6 pt-4\">\n {[0, 1, 2, 3].map((s) => (<div key={s} className={cn('h-1 flex-1 rounded-full transition-colors', s <= step ? 'bg-primary' : 'bg-border-light')} />))}\n </div>\n\n {/* Content */}\n <div className=\"min-h-0 flex-1 overflow-y-auto px-6 py-4\">\n {/* Step 0: Type */}\n {step === 0 && (typesLoading ? (<div className=\"flex h-[220px] items-center justify-center\"><Loader2 size={20} className=\"text-primary animate-spin\" /></div>) : types.length === 0 ? (<p className=\"text-text-muted py-8 text-center text-sm\">Aucun type disponible</p>) : (\n <div className=\"grid grid-cols-2 gap-2\">\n {types.map((t) => (<button key={t._id} className={cn('flex flex-col items-start gap-1 rounded-xl border p-3 text-left transition-all', selectedTypeId === t._id ? 'border-primary bg-primary-light shadow-sm' : 'border-border hover:border-primary/50 hover:bg-bg')} onClick={() => setSelectedTypeId(t._id)}><span className=\"text-text text-sm font-medium\">{t.name}</span></button>))}\n </div>\n ))}\n\n {/* Step 1: Context */}\n {step === 1 && (\n <div className=\"flex flex-col gap-4\">\n <div>\n <label className=\"text-text-muted mb-1 block text-xs font-medium\">Nom du workspace</label>\n <input className=\"border-border bg-bg text-text focus:border-primary w-full rounded-lg border px-3 py-2 text-sm focus:outline-none\" placeholder={`Ex: ${selectedType?.name ?? 'Workspace'} - ...`} value={name} onChange={(e) => setName(e.target.value)} autoFocus />\n </div>\n <div>\n <label className=\"text-text-muted mb-1 block text-xs font-medium\">Scope</label>\n <input className=\"border-border bg-bg text-text focus:border-primary w-full rounded-lg border px-3 py-2 text-sm focus:outline-none\" placeholder=\"Ex: production, engineering...\" value={scope} onChange={(e) => setScope(e.target.value)} />\n </div>\n <div>\n <label className=\"text-text-muted mb-1 block text-xs font-medium\">Entités</label>\n <div className=\"flex flex-col gap-2\">\n {entities.map((e, idx) => (\n <div key={idx} className=\"flex items-center gap-2\">\n <input className=\"border-border bg-bg text-text focus:border-primary w-28 rounded border px-2 py-1 text-xs focus:outline-none\" value={e.key} onChange={(ev) => { const arr = [...entities]; arr[idx].key = ev.target.value; setEntities(arr); }} placeholder=\"Clé\" />\n <input className=\"border-border bg-bg text-text focus:border-primary flex-1 rounded border px-2 py-1 text-xs focus:outline-none\" value={e.value} onChange={(ev) => { const arr = [...entities]; arr[idx].value = ev.target.value; setEntities(arr); }} placeholder=\"Valeur\" />\n <button type=\"button\" className={`rounded p-1 transition-colors ${e.isSecret ? 'bg-warning/15 text-warning' : 'text-text-muted hover:text-text hover:bg-bg'}`} onClick={() => { const arr = [...entities]; arr[idx].isSecret = !arr[idx].isSecret; setEntities(arr); }}>{e.isSecret ? <Lock size={12} /> : <Unlock size={12} />}</button>\n <button className=\"text-text-muted hover:text-danger\" onClick={() => setEntities(entities.filter((_, i) => i !== idx))}><Trash2 size={14} /></button>\n </div>\n ))}\n <button className=\"text-primary hover:bg-primary-light flex items-center gap-1 rounded px-2 py-1 text-xs transition-colors\" onClick={() => setEntities([...entities, { key: '', value: '', isSecret: false }])}><Plus size={12} /> Ajouter une entité</button>\n </div>\n </div>\n {slackAvailable && (\n <label className={cn('border-border bg-bg hover:border-primary/50 flex cursor-pointer items-start gap-3 rounded-xl border p-3 transition-colors', syncWithSlack && 'border-primary bg-primary-light/40')}>\n <input type=\"checkbox\" className=\"accent-primary mt-0.5 h-4 w-4 shrink-0 cursor-pointer\" checked={syncWithSlack} onChange={(e) => setSyncWithSlack(e.target.checked)} />\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <span className=\"text-text flex items-center gap-1.5 text-sm font-medium\"><Slack size={14} className=\"text-primary\" /> Synchroniser avec Slack</span>\n <span className=\"text-text-muted text-[11px] leading-snug\">Un canal Slack privé sera créé et les membres utilisateurs y seront invités automatiquement.</span>\n </div>\n </label>\n )}\n </div>\n )}\n\n {/* Step 2: Members */}\n {step === 2 && (\n <div className=\"flex flex-col gap-5\">\n {/* USER INVITATIONS */}\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between\">\n <label className=\"text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase\"><Users size={14} className=\"text-primary\" /> Membres Utilisateurs</label>\n {invitedUsers.length > 0 && <span className=\"bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold\">{invitedUsers.length} invité{invitedUsers.length > 1 ? 's' : ''}</span>}\n </div>\n <div className=\"relative\">\n <input type=\"search\" name=\"workspace-member-search\" autoComplete=\"off\" data-lpignore=\"true\" data-1p-ignore=\"true\" className=\"border-border bg-bg text-text focus:border-primary focus:ring-primary/10 placeholder:text-text-muted/65 w-full rounded-xl border px-3.5 py-2.5 text-sm transition-all focus:ring-2 focus:outline-none\" placeholder=\"Rechercher un membre par nom ou identifiant...\" value={memberSearch} onChange={(e) => setMemberSearch(e.target.value)} />\n {memberSearch.length >= 2 && searchingUsers && (<div className=\"absolute top-1/2 right-3.5 flex -translate-y-1/2 items-center justify-center py-3\"><Loader2 size={16} className=\"text-primary animate-spin\" /></div>)}\n {filteredUsers.length > 0 && memberSearch.length >= 2 && !searchingUsers && (\n <div className=\"border-border bg-surface divide-border/30 absolute top-full left-0 z-20 mt-1 flex max-h-48 w-full flex-col divide-y overflow-y-auto rounded-xl border shadow-md\">\n {filteredUsers.slice(0, 5).map((u) => (\n <div key={u.id} className=\"hover:bg-primary-light/50 flex cursor-pointer items-center justify-between px-3.5 py-2.5 text-xs transition-colors\" onClick={() => addMember(u.email, u.displayName, 'user')}>\n <div className=\"flex items-center gap-2.5\">\n <span className=\"bg-primary-light text-primary ring-primary/10 flex h-7 w-7 items-center justify-center rounded-full text-[10px] font-semibold ring-1\">{getInitials(u.displayName)}</span>\n <div className=\"flex flex-col\"><span className=\"text-text font-medium\">{u.displayName}</span><span className=\"text-text-muted text-[10px]\">{u.email}</span></div>\n </div>\n <Plus size={14} className=\"text-primary/75\" />\n </div>\n ))}\n </div>\n )}\n </div>\n <div className=\"mt-1 flex flex-col gap-1.5\">\n {invitedUsers.length === 0 ? (\n <div className=\"bg-bg/40 border-border/40 flex items-center justify-center rounded-xl border border-dashed py-4 text-center\"><p className=\"text-text-muted text-xs italic\">Aucun utilisateur invité pour le moment.</p></div>\n ) : invitedUsers.map((m) => (\n <div key={m.memberId} className=\"bg-bg-subtle hover:bg-bg border-border/30 flex items-center gap-3 rounded-xl border p-2.5 transition-all duration-200\">\n <MemberAvatar memberName={m.memberName} memberType=\"user\" avatarUrl={avatarMap[m.memberId.toLowerCase()]} size=\"sm\" variant={m.role === 'owner' ? 'owner' : 'primary'} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-text truncate text-xs font-semibold\">{m.memberName}</div>\n <div className=\"text-text-muted truncate text-[10px]\">{m.memberId}</div>\n </div>\n <div className=\"flex items-center gap-2\">\n <select className=\"border-border bg-surface text-text focus:border-primary rounded-lg border px-2 py-1 text-[10px] font-medium focus:outline-none\" value={m.role} onChange={(e) => setMembers(members.map((x) => x.memberId === m.memberId ? { ...x, role: e.target.value } : x))}>\n <option value=\"owner\">Propriétaire</option><option value=\"participant\">Participant</option><option value=\"viewer\">Observateur</option>\n </select>\n <button type=\"button\" className=\"text-text-muted hover:text-danger hover:bg-danger-light/20 rounded-lg p-1.5 transition-colors\" onClick={() => removeMember(m.memberId)}><X size={14} /></button>\n </div>\n </div>\n ))}\n </div>\n </div>\n {/* AGENT INVITATIONS */}\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between\">\n <label className=\"text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase\"><Brain size={14} className=\"text-primary\" /> Agents IA</label>\n <span className=\"bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold\">{invitedAgents.length}/{agents.length}</span>\n </div>\n <div className=\"relative\">\n <div className={cn('border-border bg-bg focus-within:border-primary focus-within:ring-primary/10 flex min-h-[44px] cursor-text flex-wrap items-center gap-1.5 rounded-xl border px-3 py-1.5 text-sm transition-all focus-within:ring-2', agentSearchFocused && 'border-primary ring-primary/10 ring-2')} onClick={() => agentSearchInputRef.current?.focus()}>\n {invitedAgents.map((m) => (\n <span key={m.memberId} className=\"bg-primary-light/50 border-primary/20 text-primary flex items-center gap-1 rounded-lg border py-1 pr-1.5 pl-2 text-xs font-medium\">\n <Brain size={10} className=\"text-primary/80\" />{m.memberName}\n <button type=\"button\" className=\"hover:bg-primary-light text-primary rounded-md p-0.5 transition-colors\" onClick={(e) => { e.stopPropagation(); removeMember(m.memberId); }}><X size={10} /></button>\n </span>\n ))}\n <input ref={agentSearchInputRef} type=\"search\" name=\"workspace-agent-search\" autoComplete=\"off\" data-lpignore=\"true\" data-1p-ignore=\"true\" className=\"text-text placeholder:text-text-muted/65 min-w-[100px] flex-1 border-none bg-transparent p-0.5 text-xs focus:ring-0 focus:outline-none\" placeholder={invitedAgents.length === 0 ? 'Rechercher et inviter des agents...' : ''} value={agentSearch} onChange={(e) => { setAgentSearch(e.target.value); setShowAgentDropdown(true); }} onFocus={() => { setAgentSearchFocused(true); setShowAgentDropdown(true); }} onBlur={() => setTimeout(() => { setAgentSearchFocused(false); setShowAgentDropdown(false); }, 200)} />\n </div>\n {showAgentDropdown && (\n <div className=\"border-border bg-surface divide-border/30 absolute z-20 mt-1.5 flex max-h-48 w-full flex-col divide-y overflow-y-auto rounded-xl border shadow-lg\">\n {unselectedAgents.length === 0 ? (<p className=\"text-text-muted p-3 text-center text-xs italic\">{agentSearch.trim().length > 0 ? 'Aucun agent ne correspond.' : 'Tous les agents ont été invités.'}</p>) : unselectedAgents.map((agent) => (\n <div key={agent.agentId} className=\"hover:bg-primary-light/50 flex cursor-pointer items-center justify-between px-3.5 py-2.5 text-xs transition-colors\" onClick={() => { addMember(agent.agentId, agent.agentName, 'agent'); setAgentSearch(''); }}>\n <div className=\"flex items-center gap-2.5\"><span className=\"bg-surface border-border flex h-7 w-7 items-center justify-center rounded-full border\"><Brain size={12} className=\"text-primary\" /></span><span className=\"text-text font-medium\">{agent.agentName}</span></div>\n <Plus size={14} className=\"text-primary/75\" />\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n\n {/* Step 3: Confirmation */}\n {step === 3 && (\n <div className=\"flex flex-col gap-3\">\n <div className=\"bg-bg rounded-xl p-4\">\n <div className=\"mb-3 flex items-center gap-2\"><div><div className=\"text-text text-sm font-semibold\">{name || 'Sans nom'}</div><div className=\"text-text-muted text-xs\">{selectedType?.name ?? '—'} • {scope || 'Sans scope'}</div></div></div>\n {entities.filter((e) => e.key.trim() && e.value.trim()).length > 0 && (\n <div className=\"mb-2 flex flex-wrap gap-1\">\n {entities.filter((e) => e.key.trim() && e.value.trim()).map((e, i) => (\n <span key={i} className=\"border-border inline-flex items-center gap-1 rounded border px-2 py-0.5 text-xs\">\n {e.isSecret && <Lock size={10} className=\"text-warning shrink-0\" />}\n <span className=\"text-text-muted mr-1 font-medium\">{e.key}:</span>\n <span className=\"text-text\">{e.isSecret ? '••••••' : e.value}</span>\n </span>\n ))}\n </div>\n )}\n <div className=\"text-text-muted flex items-center gap-3 text-xs\">\n <span className=\"flex items-center gap-1\"><Users size={12} /> {members.length} membre{members.length > 1 ? 's' : ''}</span>\n {syncWithSlack && <span className=\"text-primary flex items-center gap-1 font-medium\"><Slack size={12} /> Synchronisé avec Slack</span>}\n </div>\n {members.length > 0 && (\n <div className=\"border-border/30 mt-3 border-t pt-3\">\n <span className=\"text-text-muted mb-2 block text-[10px] font-bold tracking-wider uppercase\">Membres et Agents invités ({members.length})</span>\n <div className=\"flex max-h-40 flex-col gap-1.5 overflow-y-auto pr-1\">\n {members.map((m) => (\n <div key={m.memberId} className=\"bg-bg-subtle/50 flex items-center gap-2.5 rounded-lg p-2 text-xs\">\n <MemberAvatar memberName={m.memberName} memberType={m.memberType} avatarUrl={m.memberType === 'user' ? avatarMap[m.memberId.toLowerCase()] : undefined} size=\"xs\" variant={m.role === 'owner' ? 'owner' : 'primary'} />\n <div className=\"min-w-0 flex-1\"><span className=\"text-text truncate font-medium\">{m.memberName}</span><span className=\"text-text-muted ml-2 text-[10px]\">({m.memberType === 'agent' ? 'Agent' : m.role === 'owner' ? 'Propriétaire' : m.role === 'viewer' ? 'Observateur' : 'Participant'})</span></div>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n {error && <div className=\"bg-danger-light text-danger rounded-lg px-3 py-2 text-xs\">{error}</div>}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"border-border flex shrink-0 items-center justify-between border-t px-6 py-4\">\n <button type=\"button\" className={cn('text-text-muted hover:text-text flex items-center gap-1 text-sm transition-colors', step === 0 && 'invisible')} onClick={() => setStep((s) => s - 1)} disabled={loading}><ArrowLeft size={14} /> Précédent</button>\n {step < 3 ? (\n <button type=\"button\" className={cn('flex items-center gap-1 rounded-lg px-4 py-2 text-sm font-medium text-white transition-colors', canAdvance() ? 'bg-primary hover:bg-primary-hover' : 'bg-border cursor-not-allowed')} onClick={() => setStep((s) => s + 1)} disabled={!canAdvance()}>Suivant <ArrowRight size={14} /></button>\n ) : (\n <button type=\"button\" className=\"bg-primary hover:bg-primary-hover flex items-center gap-1 rounded-lg px-4 py-2 text-sm font-medium text-white transition-colors disabled:opacity-50\" onClick={handleCreate} disabled={loading}>{loading ? <Loader2 size={14} className=\"animate-spin\" /> : <Check size={14} />} Créer le workspace</button>\n )}\n </div>\n </Modal>\n );\n};\n","import React, { useState, useEffect, useMemo, useId, useRef } from 'react';\nimport { X, Loader2, Lock, MessageSquare, Search } from 'lucide-react';\nimport { cn } from './ui/cn';\nimport { useWorkspaceContext } from '../provider';\nimport { useWorkspaceApi } from '../hooks/useWorkspaceApi';\nimport type { CreateWorkspacePayload } from '../types';\nimport { getInitials } from '../utils/constants';\nimport { Modal } from './ui/Modal';\nimport { MemberAvatar } from './MemberAvatar';\n\ninterface CreatePrivateWorkspaceModalProps {\n open: boolean;\n onClose: () => void;\n onCreated?: (workspace: unknown) => void;\n}\n\nexport const CreatePrivateWorkspaceModal: React.FC<CreatePrivateWorkspaceModalProps> = ({ open, onClose, onCreated }) => {\n const titleId = useId();\n const { config } = useWorkspaceContext();\n const apis = useWorkspaceApi();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [search, setSearch] = useState('');\n const [searchResults, setSearchResults] = useState<{ id: string; email: string; displayName: string; avatarUrl?: string }[]>([]);\n const [searchingUsers, setSearchingUsers] = useState(false);\n const [selectedUser, setSelectedUser] = useState<{ id: string; email: string; displayName: string; avatarUrl?: string } | null>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\n // User search via injected searchUsers\n useEffect(() => {\n if (search.length < 2 || !config.searchUsers) { setSearchResults([]); return; }\n let cancelled = false;\n setSearchingUsers(true);\n config.searchUsers(search).then((r) => { if (!cancelled) setSearchResults(r); }).catch(() => { if (!cancelled) setSearchResults([]); }).finally(() => { if (!cancelled) setSearchingUsers(false); });\n return () => { cancelled = true; };\n }, [search]);\n\n const filteredUsers = useMemo(() => searchResults.filter((u) => u.email !== config.currentUserId), [searchResults, config.currentUserId]);\n\n // Reset on close\n useEffect(() => {\n if (!open) { setSearch(''); setSelectedUser(null); setError(null); setLoading(false); }\n else { setTimeout(() => searchInputRef.current?.focus(), 100); }\n }, [open]);\n\n const handleCreate = async () => {\n if (!selectedUser || !config.currentUserId) return;\n setLoading(true); setError(null);\n try {\n const payload: CreateWorkspacePayload = {\n name: `${config.currentUserName ?? config.currentUserId} ↔ ${selectedUser.displayName}`,\n isPrivate: true,\n members: [{ memberId: selectedUser.email, memberName: selectedUser.displayName, memberType: 'user', role: 'participant' }],\n };\n const ws = await apis.workspaceApi.create(payload);\n onCreated?.(ws); onClose();\n } catch (err) { setError((err as Error).message); }\n finally { setLoading(false); }\n };\n\n return (\n <Modal open={open} onClose={onClose} zIndexClass=\"z-50\" size=\"sm\" closeOnBackdropClick={false} backdropClassName=\"bg-black/40\" panelClassName=\"bg-surface border-border flex max-h-[min(70dvh,500px)] flex-col overflow-hidden rounded-2xl border shadow-xl\" headingId={titleId} ariaLabelledBy={titleId} title=\"Conversation Privée\" description={<p className=\"text-text-muted text-xs\">Choisissez un utilisateur pour démarrer une conversation privée.</p>} headerClassName=\"items-center\" closeButtonClassName=\"text-text-muted hover:text-text transition-colors\" titleIcon={<span className=\"bg-primary-light text-primary flex h-8 w-8 items-center justify-center rounded-lg\"><Lock size={16} /></span>}>\n <div className=\"min-h-0 flex-1 overflow-y-auto px-6 py-4\">\n {/* Selected user */}\n {selectedUser ? (\n <div className=\"mb-4\">\n <div className=\"bg-primary-light/30 border-primary/20 flex items-center gap-3 rounded-xl border p-3\">\n <MemberAvatar memberName={selectedUser.displayName} memberType=\"user\" avatarUrl={selectedUser.avatarUrl} size=\"md\" variant=\"primary\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-text text-sm font-semibold\">{selectedUser.displayName}</div>\n <div className=\"text-text-muted text-xs\">{selectedUser.email}</div>\n </div>\n <button type=\"button\" className=\"text-text-muted hover:text-danger rounded p-1 transition-colors\" onClick={() => setSelectedUser(null)}><X size={16} /></button>\n </div>\n </div>\n ) : (\n <div>\n <div className=\"relative\">\n <Search size={14} className=\"text-text-muted absolute top-1/2 left-3 -translate-y-1/2\" />\n <input ref={searchInputRef} type=\"search\" autoComplete=\"off\" data-lpignore=\"true\" data-1p-ignore=\"true\" className=\"border-border bg-bg text-text focus:border-primary focus:ring-primary/10 placeholder:text-text-muted/65 w-full rounded-xl border py-2.5 pr-3 pl-9 text-sm transition-all focus:ring-2 focus:outline-none\" placeholder=\"Rechercher un utilisateur...\" value={search} onChange={(e) => setSearch(e.target.value)} />\n {search.length >= 2 && searchingUsers && <div className=\"absolute top-1/2 right-3 -translate-y-1/2\"><Loader2 size={16} className=\"text-primary animate-spin\" /></div>}\n </div>\n {search.length >= 2 && !searchingUsers && filteredUsers.length > 0 && (\n <div className=\"border-border bg-surface mt-2 flex max-h-48 flex-col overflow-y-auto rounded-xl border shadow-sm\">\n {filteredUsers.slice(0, 8).map((u) => (\n <button key={u.id} type=\"button\" className=\"hover:bg-primary-light/50 flex items-center gap-3 px-3.5 py-2.5 text-left transition-colors first:rounded-t-xl last:rounded-b-xl\" onClick={() => { setSelectedUser(u); setSearch(''); }}>\n <span className=\"bg-primary-light text-primary flex h-8 w-8 items-center justify-center rounded-full text-xs font-semibold\">{getInitials(u.displayName)}</span>\n <div className=\"min-w-0 flex-1\"><div className=\"text-text text-sm font-medium\">{u.displayName}</div><div className=\"text-text-muted text-[11px]\">{u.email}</div></div>\n </button>\n ))}\n </div>\n )}\n {search.length >= 2 && !searchingUsers && filteredUsers.length === 0 && <p className=\"text-text-muted mt-3 text-center text-xs italic\">Aucun utilisateur trouvé.</p>}\n {search.length < 2 && <p className=\"text-text-muted mt-4 text-center text-xs\">Saisissez au moins 2 caractères pour rechercher.</p>}\n </div>\n )}\n {error && <div className=\"bg-danger-light text-danger mt-3 rounded-lg px-3 py-2 text-xs\">{error}</div>}\n </div>\n <div className=\"border-border flex shrink-0 items-center justify-end gap-2 border-t px-6 py-4\">\n <button type=\"button\" className=\"text-text-muted hover:text-text text-sm transition-colors\" onClick={onClose} disabled={loading}>Annuler</button>\n <button type=\"button\" className={cn('flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-medium text-white transition-colors disabled:opacity-50', selectedUser ? 'bg-primary hover:bg-primary-hover' : 'bg-border cursor-not-allowed')} onClick={handleCreate} disabled={!selectedUser || loading}>\n {loading ? <Loader2 size={14} className=\"animate-spin\" /> : <MessageSquare size={14} />} Démarrer\n </button>\n </div>\n </Modal>\n );\n};\n","\n\nimport React, { useState, useEffect, useCallback } from 'react';\nimport {\n RefreshCw,\n ExternalLink,\n Info,\n CheckCircle2,\n XCircle,\n Loader2,\n Hash,\n AlertTriangle,\n} from 'lucide-react';\nimport { type SyncLink, type SyncStatus } from '../api';\nimport { useWorkspaceApi } from '../hooks/useWorkspaceApi';\nimport { cn } from './ui/cn';\n\n// ─── Slack brand color ────────────────────────────────────────────────────────\nconst SLACK_COLOR = '#4A154B';\n\n// ─── Sync info texts ──────────────────────────────────────────────────────────\nconst SYNC_INFO = {\n title: 'Comment fonctionne la synchronisation ?',\n description:\n 'La synchronisation bidirectionnelle relie ce workspace à un canal externe (Slack, Teams…). Les messages, fichiers et membres sont automatiquement répliqués dans les deux sens.',\n features: [\n 'Messages envoyés depuis le workspace sont répliqués vers Slack',\n 'Messages envoyés depuis Slack sont répliqués vers le workspace',\n 'Fichiers et artefacts sont synchronisés dans les deux sens',\n 'Les nouveaux membres ajoutés au workspace sont invités dans Slack',\n 'Les mentions Slack sont converties en mentions workspace',\n 'Désactiver la synchronisation conserve le canal Slack ouvert (pas d\\'archivage)',\n ],\n limitations: [\n 'Les messages initialement postés par un utilisateur réel dans Slack ne peuvent pas être modifiés/supprimés depuis le workspace (limitation API Slack)',\n 'Le bot Slack doit avoir les scopes nécessaires (channels:*, chat:write, files:read, users:read.email)',\n 'Le listener Socket Mode doit tourner sur une seule instance en production',\n 'Seuls les utilisateurs ayant le même email dans Slack et le workspace sont synchronisés',\n ],\n};\n\ninterface SyncPanelProps {\n workspaceId: string;\n syncWithSlack?: boolean;\n isOwner: boolean;\n /** Whether Slack sync is configured and enabled on the server */\n slackConfigured?: boolean;\n /** Called after a sync toggle — the parent page will get the updated workspace via real-time. */\n onToggleSync?: (provider: string, enabled: boolean) => Promise<void>;\n}\n\nexport const SyncPanel: React.FC<SyncPanelProps> = ({\n workspaceId,\n syncWithSlack,\n isOwner,\n slackConfigured = true,\n onToggleSync,\n}) => {\n const [syncStatus, setSyncStatus] = useState<SyncStatus | null>(null);\n const [loading, setLoading] = useState(true);\n const [toggling, setToggling] = useState(false);\n const [infoOpen, setInfoOpen] = useState(false);\n const apis = useWorkspaceApi();\n\n const fetchSyncStatus = useCallback(async () => {\n try {\n const status = await apis.syncApi.getStatus(workspaceId);\n setSyncStatus(status);\n } catch (err) {\n console.error('Failed to fetch sync status:', err);\n } finally {\n setLoading(false);\n }\n }, [workspaceId]);\n\n useEffect(() => {\n fetchSyncStatus();\n }, [fetchSyncStatus]);\n\n // Also re-sync state when workspace.syncWithSlack changes (via real-time)\n useEffect(() => {\n if (syncStatus) {\n setSyncStatus((prev) =>\n prev ? { ...prev, syncWithSlack: syncWithSlack ?? false } : prev,\n );\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [syncWithSlack]);\n\n const handleToggle = async (provider: string, enabled: boolean) => {\n setToggling(true);\n try {\n await onToggleSync?.(provider, enabled);\n // Refresh the sync links after toggle\n await fetchSyncStatus();\n } catch (err) {\n console.error('Failed to toggle sync:', err);\n } finally {\n setToggling(false);\n }\n };\n\n const slackLink = syncStatus?.links?.find((l) => l.provider === 'slack');\n const isSlackActive = syncStatus?.syncWithSlack ?? syncWithSlack ?? false;\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 size={20} className=\"text-primary animate-spin\" />\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-4\">\n {/* Section header */}\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-muted text-xs font-semibold tracking-wider uppercase\">\n Synchronisation\n </span>\n <button\n className=\"text-text-muted hover:text-primary flex items-center gap-1 text-xs transition-colors\"\n onClick={() => fetchSyncStatus()}\n title=\"Rafraîchir\"\n >\n <RefreshCw size={11} /> Rafraîchir\n </button>\n </div>\n\n {/* ── Slack sync card ─────────────────────────────────────────────── */}\n <div className={cn('bg-bg border-border rounded-lg border', !slackConfigured && 'opacity-60')}>\n <div className=\"flex items-center justify-between p-3\">\n <div className=\"flex items-center gap-2.5\">\n {/* Slack icon */}\n <div\n className=\"flex h-8 w-8 items-center justify-center rounded-lg\"\n style={{ backgroundColor: SLACK_COLOR }}\n >\n <Hash size={16} className=\"text-white\" />\n </div>\n <div>\n <div className=\"text-text flex items-center gap-1.5 text-sm font-medium\">\n Slack\n {!slackConfigured ? (\n <XCircle size={14} className=\"text-text-muted\" />\n ) : isSlackActive ? (\n <CheckCircle2 size={14} className=\"text-success\" />\n ) : (\n <XCircle size={14} className=\"text-text-muted\" />\n )}\n </div>\n <span className=\"text-text-muted text-[10px]\">\n {!slackConfigured\n ? 'Non configuré'\n : isSlackActive\n ? 'Synchronisation active'\n : 'Non synchronisé'}\n </span>\n </div>\n </div>\n\n {slackConfigured && isOwner && (\n <button\n className={`rounded-lg px-3 py-1.5 text-xs font-medium transition-colors ${\n isSlackActive\n ? 'bg-danger-light text-danger hover:bg-danger/20'\n : 'bg-success-light text-success hover:bg-success/20'\n }`}\n onClick={() => handleToggle('slack', !isSlackActive)}\n disabled={toggling}\n >\n {toggling ? (\n <Loader2 size={12} className=\"animate-spin\" />\n ) : isSlackActive ? (\n 'Désactiver'\n ) : (\n 'Activer'\n )}\n </button>\n )}\n\n {!slackConfigured && (\n <span className=\"bg-bg border-border rounded border px-2 py-1 text-[10px] font-medium text-text-muted\">\n Non disponible\n </span>\n )}\n </div>\n\n {!slackConfigured && (\n <div className=\"border-border border-t px-3 py-2.5\">\n <div className=\"text-text-muted flex items-center gap-2 text-xs\">\n <AlertTriangle size={14} className=\"flex-shrink-0 text-warning\" />\n <span>\n La synchronisation Slack n'est pas configurée sur le serveur.\n Contactez un administrateur pour l'activer.\n </span>\n </div>\n </div>\n )}\n\n {/* Slack link details (always show when link exists) */}\n {slackConfigured && slackLink && (\n <div className=\"border-border border-t px-3 py-2.5\">\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-muted text-[10px] font-medium uppercase tracking-wider\">\n Canal externe\n </span>\n <ExternalLink size={10} className=\"text-text-muted\" />\n </div>\n <div className=\"bg-surface border-border rounded border p-2\">\n <div className=\"flex items-center gap-2 text-xs\">\n <Hash size={12} className=\"text-text-muted flex-shrink-0\" />\n <span className=\"text-text font-medium\">\n {slackLink.externalName || slackLink.externalId}\n </span>\n </div>\n <div className=\"text-text-muted mt-1 flex items-center gap-2 text-[10px]\">\n <span>ID: {slackLink.externalId}</span>\n {slackLink.externalTeamId && (\n <>\n <span>•</span>\n <span>Team: {slackLink.externalTeamId}</span>\n </>\n )}\n </div>\n <div className=\"text-text-muted mt-1 flex items-center gap-2 text-[10px]\">\n <span\n className={`inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-[9px] font-medium ${\n isSlackActive\n ? 'bg-success-light text-success'\n : 'bg-warning-light text-warning'\n }`}\n >\n {isSlackActive ? 'Sync active' : 'Sync en pause'}\n </span>\n <span>\n Créé le{' '}\n {new Date(slackLink.createdAt).toLocaleDateString('fr-FR')}\n </span>\n </div>\n {!isSlackActive && (\n <div className=\"text-text-muted mt-1.5 text-[10px] italic\">\n Le canal Slack reste ouvert — seule la synchronisation est en pause.\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n\n {slackConfigured && isSlackActive && !slackLink && (\n <div className=\"border-border border-t px-3 py-2.5\">\n <div className=\"text-warning bg-warning-light flex items-center gap-2 rounded-lg p-2 text-xs\">\n <AlertTriangle size={14} className=\"flex-shrink-0\" />\n <span>\n La synchronisation est activée mais aucun canal Slack n'est\n encore lié. Le canal sera créé automatiquement.\n </span>\n </div>\n </div>\n )}\n </div>\n\n {/* ── Teams sync card (future) ────────────────────────────────────── */}\n <div className=\"bg-bg border-border rounded-lg border opacity-50\">\n <div className=\"flex items-center justify-between p-3\">\n <div className=\"flex items-center gap-2.5\">\n <div className=\"bg-info flex h-8 w-8 items-center justify-center rounded-lg\">\n <span className=\"text-xs font-bold text-white\">T</span>\n </div>\n <div>\n <div className=\"text-text flex items-center gap-1.5 text-sm font-medium\">\n Microsoft Teams\n <XCircle size={14} className=\"text-text-muted\" />\n </div>\n <span className=\"text-text-muted text-[10px]\">\n Bientôt disponible\n </span>\n </div>\n </div>\n <span className=\"bg-bg border-border rounded border px-2 py-1 text-[10px] font-medium text-text-muted\">\n Prochainement\n </span>\n </div>\n </div>\n\n {/* ── Info section ────────────────────────────────────────────────── */}\n <div className=\"bg-bg border-border rounded-lg border\">\n <button\n className=\"flex w-full items-center gap-2 p-3 text-left\"\n onClick={() => setInfoOpen(!infoOpen)}\n >\n <Info size={14} className=\"text-info flex-shrink-0\" />\n <span className=\"text-text text-xs font-medium\">\n {SYNC_INFO.title}\n </span>\n <span\n className={`text-text-muted ml-auto text-[10px] transition-transform ${\n infoOpen ? 'rotate-180' : ''\n }`}\n >\n ▾\n </span>\n </button>\n\n {infoOpen && (\n <div className=\"border-border border-t px-3 pb-3 pt-2\">\n <p className=\"text-text-muted mb-3 text-xs leading-relaxed\">\n {SYNC_INFO.description}\n </p>\n\n <div className=\"mb-3\">\n <span className=\"text-text mb-1.5 block text-[10px] font-semibold uppercase tracking-wider\">\n Fonctionnalités\n </span>\n <ul className=\"flex flex-col gap-1\">\n {SYNC_INFO.features.map((f, i) => (\n <li\n key={i}\n className=\"text-text-muted flex items-start gap-1.5 text-xs\"\n >\n <CheckCircle2\n size={12}\n className=\"text-success mt-0.5 flex-shrink-0\"\n />\n {f}\n </li>\n ))}\n </ul>\n </div>\n\n <div>\n <span className=\"text-text mb-1.5 block text-[10px] font-semibold uppercase tracking-wider\">\n Limitations connues\n </span>\n <ul className=\"flex flex-col gap-1\">\n {SYNC_INFO.limitations.map((l, i) => (\n <li\n key={i}\n className=\"text-text-muted flex items-start gap-1.5 text-xs\"\n >\n <AlertTriangle\n size={12}\n className=\"text-warning mt-0.5 flex-shrink-0\"\n />\n {l}\n </li>\n ))}\n </ul>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n};\n","\n\nimport React from 'react';\nimport {\n ChevronsLeft,\n ChevronLeft,\n ChevronRight,\n ChevronsRight,\n} from 'lucide-react';\nimport { cn } from './ui/cn';\n\ninterface NavButtonProps {\n onClick: () => void;\n disabled: boolean;\n children: React.ReactNode;\n title: string;\n}\n\nconst NavButton: React.FC<NavButtonProps> = ({\n onClick,\n disabled,\n children,\n title,\n}) => (\n <button\n onClick={onClick}\n disabled={disabled}\n title={title}\n className={cn(\n 'flex h-9 w-9 items-center justify-center rounded-lg border text-sm transition-all duration-200',\n disabled\n ? 'border-border-light text-text-placeholder cursor-not-allowed opacity-40'\n : 'border-border bg-surface text-text-secondary hover:bg-primary/8 hover:border-primary/30 hover:text-primary active:scale-95',\n )}\n >\n {children}\n </button>\n);\n\ninterface PaginationProps {\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n /** Show a subtle loading indicator when fetching */\n loading?: boolean;\n}\n\nexport const Pagination: React.FC<PaginationProps> = ({\n currentPage,\n totalPages,\n onPageChange,\n loading = false,\n}) => {\n if (totalPages <= 1) return null;\n\n // Build a window of page numbers to display\n const getVisiblePages = (): (number | 'ellipsis')[] => {\n const pages: (number | 'ellipsis')[] = [];\n const maxVisible = 5;\n\n if (totalPages <= maxVisible + 2) {\n for (let i = 1; i <= totalPages; i++) pages.push(i);\n return pages;\n }\n\n // Always show first page\n pages.push(1);\n\n const start = Math.max(2, currentPage - 1);\n const end = Math.min(totalPages - 1, currentPage + 1);\n\n if (start > 2) pages.push('ellipsis');\n\n for (let i = start; i <= end; i++) pages.push(i);\n\n if (end < totalPages - 1) pages.push('ellipsis');\n\n // Always show last page\n pages.push(totalPages);\n\n return pages;\n };\n\n const pages = getVisiblePages();\n\n return (\n <div className=\"mt-6 flex items-center justify-center gap-1.5\">\n {/* First page */}\n <NavButton\n onClick={() => onPageChange(1)}\n disabled={currentPage === 1 || loading}\n title=\"Première page\"\n >\n <ChevronsLeft size={16} />\n </NavButton>\n\n {/* Previous */}\n <NavButton\n onClick={() => onPageChange(currentPage - 1)}\n disabled={currentPage === 1 || loading}\n title=\"Page précédente\"\n >\n <ChevronLeft size={16} />\n </NavButton>\n\n {/* Page numbers */}\n {pages.map((p, idx) =>\n p === 'ellipsis' ? (\n <span\n key={`ellipsis-${idx}`}\n className=\"text-text-muted flex h-9 w-9 items-center justify-center text-sm\"\n >\n …\n </span>\n ) : (\n <button\n key={p}\n onClick={() => onPageChange(p)}\n disabled={loading}\n className={cn(\n 'flex h-9 w-9 items-center justify-center rounded-lg text-sm font-medium transition-all duration-200',\n p === currentPage\n ? 'bg-primary text-white shadow-sm shadow-primary/30'\n : 'border-border bg-surface text-text-secondary hover:bg-primary/8 hover:border-primary/30 hover:text-primary border active:scale-95',\n )}\n >\n {p}\n </button>\n ),\n )}\n\n {/* Next */}\n <NavButton\n onClick={() => onPageChange(currentPage + 1)}\n disabled={currentPage === totalPages || loading}\n title=\"Page suivante\"\n >\n <ChevronRight size={16} />\n </NavButton>\n\n {/* Last page */}\n <NavButton\n onClick={() => onPageChange(totalPages)}\n disabled={currentPage === totalPages || loading}\n title=\"Dernière page\"\n >\n <ChevronsRight size={16} />\n </NavButton>\n </div>\n );\n};\n"],"mappings":"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","names":["WorkspaceEvent","import_react","ROLE_LABELS","import_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","pages"]}
|