@workspace-platform/ui 0.2.0 → 0.2.1

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/index.mjs CHANGED
@@ -540,6 +540,14 @@ var STATUS_LABELS = {
540
540
  function getInitials(name) {
541
541
  return name.split(/\s+/).map((w) => w[0]).join("").toUpperCase().slice(0, 2);
542
542
  }
543
+ function fixMojibake(str) {
544
+ try {
545
+ const bytes = new Uint8Array(str.split("").map((c) => c.charCodeAt(0)));
546
+ return new TextDecoder("utf-8").decode(bytes);
547
+ } catch {
548
+ return str;
549
+ }
550
+ }
543
551
 
544
552
  // src/utils/formatExport.ts
545
553
  var ROLE_LABELS2 = {
@@ -573,7 +581,7 @@ function getTypeName(workspace) {
573
581
  if (typeof workspace.type === "object") return workspace.type.name;
574
582
  return workspace.type;
575
583
  }
576
- function fixMojibake(text) {
584
+ function fixMojibake2(text) {
577
585
  return text.replace(/é/g, "\xE9").replace(/è/g, "\xE8").replace(/à /g, "\xE0").replace(/ç/g, "\xE7").replace(/ô/g, "\xF4").replace(/î/g, "\xEE").replace(/â/g, "\xE2").replace(/ë/g, "\xEB").replace(/ü/g, "\xFC");
578
586
  }
579
587
  function formatWorkspaceExport(data) {
@@ -648,7 +656,7 @@ function formatWorkspaceExport(data) {
648
656
  if (msg.artefacts && msg.artefacts.length > 0) {
649
657
  lines.push("> \u{1F4CE} Pi\xE8ces jointes :");
650
658
  for (const art of msg.artefacts) {
651
- lines.push(`> - \`${fixMojibake(art.file.originalName)}\` (${art.type})`);
659
+ lines.push(`> - \`${fixMojibake2(art.file.originalName)}\` (${art.type})`);
652
660
  }
653
661
  lines.push("");
654
662
  }
@@ -815,9 +823,204 @@ function Modal({
815
823
  );
816
824
  }
817
825
 
826
+ // src/components/ui/Badge.tsx
827
+ import { jsx as jsx3 } from "react/jsx-runtime";
828
+ var VARIANT_CLASSES = {
829
+ default: "bg-[var(--color-bg,#f1f5f9)] text-[var(--color-text-muted,#64748b)] border-[var(--color-border,#e2e8f0)]",
830
+ primary: "bg-[var(--color-primary-light,#eff6ff)] text-[var(--color-primary,#3b82f6)] border-[var(--color-primary,#3b82f6)]/30",
831
+ success: "bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-500/10 dark:text-emerald-400 dark:border-emerald-500/20",
832
+ warning: "bg-amber-50 text-amber-700 border-amber-200 dark:bg-amber-500/10 dark:text-amber-400 dark:border-amber-500/20",
833
+ danger: "bg-red-50 text-red-700 border-red-200 dark:bg-red-500/10 dark:text-red-400 dark:border-red-500/20",
834
+ info: "bg-sky-50 text-sky-700 border-sky-200 dark:bg-sky-500/10 dark:text-sky-400 dark:border-sky-500/20"
835
+ };
836
+ var SIZE_CLASSES = {
837
+ xs: "px-1.5 py-0.5 text-[10px] font-medium",
838
+ sm: "px-2 py-0.5 text-[11px] font-medium",
839
+ md: "px-2.5 py-1 text-xs font-semibold"
840
+ };
841
+ var Badge = ({
842
+ variant = "default",
843
+ size = "sm",
844
+ className,
845
+ children,
846
+ title
847
+ }) => /* @__PURE__ */ jsx3(
848
+ "span",
849
+ {
850
+ title,
851
+ className: cn(
852
+ "inline-flex items-center rounded-full border leading-none",
853
+ VARIANT_CLASSES[variant],
854
+ SIZE_CLASSES[size],
855
+ className
856
+ ),
857
+ children
858
+ }
859
+ );
860
+
861
+ // src/components/ui/Tooltip.tsx
862
+ import { useState as useState2, useRef, useEffect as useEffect2 } from "react";
863
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
864
+ var POSITION = {
865
+ top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
866
+ bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
867
+ left: "right-full top-1/2 -translate-y-1/2 mr-2",
868
+ right: "left-full top-1/2 -translate-y-1/2 ml-2"
869
+ };
870
+ var Tooltip = ({
871
+ text,
872
+ children,
873
+ position = "top",
874
+ className,
875
+ delay = 400
876
+ }) => {
877
+ const [visible, setVisible] = useState2(false);
878
+ const timerRef = useRef(null);
879
+ const show = () => {
880
+ timerRef.current = setTimeout(() => setVisible(true), delay);
881
+ };
882
+ const hide = () => {
883
+ if (timerRef.current) clearTimeout(timerRef.current);
884
+ setVisible(false);
885
+ };
886
+ useEffect2(() => () => {
887
+ if (timerRef.current) clearTimeout(timerRef.current);
888
+ }, []);
889
+ return /* @__PURE__ */ jsxs2(
890
+ "div",
891
+ {
892
+ className: "relative inline-flex",
893
+ onMouseEnter: show,
894
+ onMouseLeave: hide,
895
+ onFocus: show,
896
+ onBlur: hide,
897
+ children: [
898
+ children,
899
+ visible && text && /* @__PURE__ */ jsx4(
900
+ "div",
901
+ {
902
+ role: "tooltip",
903
+ className: cn(
904
+ "pointer-events-none absolute z-50 max-w-xs rounded-lg px-2.5 py-1.5",
905
+ "bg-[#1e293b] text-white text-[11px] leading-snug whitespace-nowrap shadow-lg",
906
+ POSITION[position],
907
+ className
908
+ ),
909
+ children: text
910
+ }
911
+ )
912
+ ]
913
+ }
914
+ );
915
+ };
916
+
917
+ // src/components/ui/ConfirmModal.tsx
918
+ import React4, { useEffect as useEffect3 } from "react";
919
+ import { AlertTriangle, Loader2, X as X2 } from "lucide-react";
920
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
921
+ var ConfirmModal = ({
922
+ open,
923
+ onClose,
924
+ onConfirm,
925
+ title,
926
+ description,
927
+ confirmText = "Confirmer",
928
+ cancelText = "Annuler",
929
+ danger = false
930
+ }) => {
931
+ const [loading, setLoading] = React4.useState(false);
932
+ useEffect3(() => {
933
+ if (!open) return;
934
+ const handler = (e) => {
935
+ if (e.key === "Escape" && !loading) onClose();
936
+ };
937
+ document.addEventListener("keydown", handler);
938
+ return () => document.removeEventListener("keydown", handler);
939
+ }, [open, loading, onClose]);
940
+ if (!open) return null;
941
+ const handleConfirm = async () => {
942
+ setLoading(true);
943
+ try {
944
+ await onConfirm();
945
+ } finally {
946
+ setLoading(false);
947
+ onClose();
948
+ }
949
+ };
950
+ return /* @__PURE__ */ jsx5(
951
+ "div",
952
+ {
953
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
954
+ style: { backgroundColor: "rgba(0,0,0,0.5)" },
955
+ onClick: (e) => {
956
+ if (e.target === e.currentTarget && !loading) onClose();
957
+ },
958
+ children: /* @__PURE__ */ jsxs3(
959
+ "div",
960
+ {
961
+ className: cn(
962
+ "relative flex w-full max-w-sm flex-col gap-4 rounded-2xl border p-6 shadow-2xl",
963
+ "bg-[var(--color-surface,#fff)] border-[var(--color-border,#e2e8f0)]"
964
+ ),
965
+ role: "dialog",
966
+ "aria-modal": "true",
967
+ "aria-labelledby": "confirm-title",
968
+ children: [
969
+ /* @__PURE__ */ jsx5(
970
+ "button",
971
+ {
972
+ onClick: onClose,
973
+ disabled: loading,
974
+ className: "absolute top-4 right-4 rounded-full p-1 text-[var(--color-text-muted,#94a3b8)] hover:text-[var(--color-text,#0f172a)] transition-colors",
975
+ children: /* @__PURE__ */ jsx5(X2, { size: 16 })
976
+ }
977
+ ),
978
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-start gap-3", children: [
979
+ /* @__PURE__ */ jsx5("div", { className: cn(
980
+ "flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full",
981
+ danger ? "bg-red-100 dark:bg-red-500/10" : "bg-[var(--color-bg,#f1f5f9)]"
982
+ ), children: /* @__PURE__ */ jsx5(AlertTriangle, { size: 18, className: danger ? "text-red-500" : "text-[var(--color-text-muted,#94a3b8)]" }) }),
983
+ /* @__PURE__ */ jsxs3("div", { className: "min-w-0 flex-1 pt-0.5", children: [
984
+ /* @__PURE__ */ jsx5("h3", { id: "confirm-title", className: "text-sm font-semibold text-[var(--color-text,#0f172a)]", children: title }),
985
+ description && /* @__PURE__ */ jsx5("div", { className: "mt-1 text-xs text-[var(--color-text-secondary,#64748b)] leading-relaxed", children: description })
986
+ ] })
987
+ ] }),
988
+ /* @__PURE__ */ jsxs3("div", { className: "flex justify-end gap-2", children: [
989
+ /* @__PURE__ */ jsx5(
990
+ "button",
991
+ {
992
+ onClick: onClose,
993
+ disabled: loading,
994
+ className: "rounded-lg border border-[var(--color-border,#e2e8f0)] px-4 py-1.5 text-xs font-medium text-[var(--color-text-muted,#64748b)] hover:text-[var(--color-text,#0f172a)] transition-colors disabled:opacity-50",
995
+ children: cancelText
996
+ }
997
+ ),
998
+ /* @__PURE__ */ jsxs3(
999
+ "button",
1000
+ {
1001
+ onClick: handleConfirm,
1002
+ disabled: loading,
1003
+ className: cn(
1004
+ "flex items-center gap-1.5 rounded-lg px-4 py-1.5 text-xs font-medium text-white transition-colors disabled:opacity-70",
1005
+ danger ? "bg-red-500 hover:bg-red-600" : "bg-[var(--color-primary,#3b82f6)] hover:bg-[var(--color-primary-hover,#2563eb)]"
1006
+ ),
1007
+ children: [
1008
+ loading && /* @__PURE__ */ jsx5(Loader2, { size: 12, className: "animate-spin" }),
1009
+ confirmText
1010
+ ]
1011
+ }
1012
+ )
1013
+ ] })
1014
+ ]
1015
+ }
1016
+ )
1017
+ }
1018
+ );
1019
+ };
1020
+
818
1021
  // src/components/MemberAvatar.tsx
819
1022
  import { Brain } from "lucide-react";
820
- import { jsx as jsx3 } from "react/jsx-runtime";
1023
+ import { jsx as jsx6 } from "react/jsx-runtime";
821
1024
  var SIZES = {
822
1025
  xs: { container: "h-6 w-6", text: "text-[9px]", icon: 10 },
823
1026
  sm: { container: "h-7 w-7", text: "text-[10px]", icon: 12 },
@@ -834,174 +1037,474 @@ var MemberAvatar = ({
834
1037
  }) => {
835
1038
  const s = SIZES[size];
836
1039
  if (memberType === "agent") {
837
- return /* @__PURE__ */ jsx3("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), children: /* @__PURE__ */ jsx3(Brain, { size: s.icon, className: "text-indigo-600" }) });
1040
+ return /* @__PURE__ */ jsx6("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), children: /* @__PURE__ */ jsx6(Brain, { size: s.icon, className: "text-indigo-600" }) });
838
1041
  }
839
1042
  if (avatarUrl) {
840
- return /* @__PURE__ */ jsx3("img", { src: avatarUrl, alt: memberName, className: cn("flex-shrink-0 rounded-full object-cover ring-2 ring-white", s.container, className) });
1043
+ return /* @__PURE__ */ jsx6("img", { src: avatarUrl, alt: memberName, className: cn("flex-shrink-0 rounded-full object-cover ring-2 ring-white", s.container, className) });
841
1044
  }
842
- return /* @__PURE__ */ jsx3("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), children: getInitials(memberName) });
1045
+ return /* @__PURE__ */ jsx6("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), children: getInitials(memberName) });
843
1046
  };
844
1047
 
845
- // src/components/MembersPanel.tsx
846
- import { useState as useState2, useEffect as useEffect2, useMemo as useMemo3 } from "react";
847
- import { UserPlus, Crown, Eye, Users, X as X2, Search, Plus, Brain as Brain2, Loader2, Check } from "lucide-react";
848
- import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
849
- var roleIcon = (role) => {
850
- switch (role) {
851
- case "owner":
852
- return /* @__PURE__ */ jsx4(Crown, { size: 11, className: "text-warning" });
853
- case "viewer":
854
- return /* @__PURE__ */ jsx4(Eye, { size: 11, className: "text-text-muted" });
855
- default:
856
- return /* @__PURE__ */ jsx4(Users, { size: 11, className: "text-primary" });
1048
+ // src/components/Pagination.tsx
1049
+ import {
1050
+ ChevronsLeft,
1051
+ ChevronLeft,
1052
+ ChevronRight,
1053
+ ChevronsRight
1054
+ } from "lucide-react";
1055
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
1056
+ var NavButton = ({
1057
+ onClick,
1058
+ disabled,
1059
+ children,
1060
+ title
1061
+ }) => /* @__PURE__ */ jsx7(
1062
+ "button",
1063
+ {
1064
+ onClick,
1065
+ disabled,
1066
+ title,
1067
+ className: cn(
1068
+ "flex h-9 w-9 items-center justify-center rounded-lg border text-sm transition-all duration-200",
1069
+ disabled ? "border-border-light text-text-placeholder cursor-not-allowed opacity-40" : "border-border bg-surface text-text-secondary hover:bg-primary/8 hover:border-primary/30 hover:text-primary active:scale-95"
1070
+ ),
1071
+ children
857
1072
  }
1073
+ );
1074
+ var Pagination = ({
1075
+ currentPage,
1076
+ totalPages,
1077
+ onPageChange,
1078
+ loading = false
1079
+ }) => {
1080
+ if (totalPages <= 1) return null;
1081
+ const getVisiblePages = () => {
1082
+ const pages2 = [];
1083
+ const maxVisible = 5;
1084
+ if (totalPages <= maxVisible + 2) {
1085
+ for (let i = 1; i <= totalPages; i++) pages2.push(i);
1086
+ return pages2;
1087
+ }
1088
+ pages2.push(1);
1089
+ const start = Math.max(2, currentPage - 1);
1090
+ const end = Math.min(totalPages - 1, currentPage + 1);
1091
+ if (start > 2) pages2.push("ellipsis");
1092
+ for (let i = start; i <= end; i++) pages2.push(i);
1093
+ if (end < totalPages - 1) pages2.push("ellipsis");
1094
+ pages2.push(totalPages);
1095
+ return pages2;
1096
+ };
1097
+ const pages = getVisiblePages();
1098
+ return /* @__PURE__ */ jsxs4("div", { className: "mt-6 flex items-center justify-center gap-1.5", children: [
1099
+ /* @__PURE__ */ jsx7(
1100
+ NavButton,
1101
+ {
1102
+ onClick: () => onPageChange(1),
1103
+ disabled: currentPage === 1 || loading,
1104
+ title: "Premi\xE8re page",
1105
+ children: /* @__PURE__ */ jsx7(ChevronsLeft, { size: 16 })
1106
+ }
1107
+ ),
1108
+ /* @__PURE__ */ jsx7(
1109
+ NavButton,
1110
+ {
1111
+ onClick: () => onPageChange(currentPage - 1),
1112
+ disabled: currentPage === 1 || loading,
1113
+ title: "Page pr\xE9c\xE9dente",
1114
+ children: /* @__PURE__ */ jsx7(ChevronLeft, { size: 16 })
1115
+ }
1116
+ ),
1117
+ pages.map(
1118
+ (p, idx) => p === "ellipsis" ? /* @__PURE__ */ jsx7(
1119
+ "span",
1120
+ {
1121
+ className: "text-text-muted flex h-9 w-9 items-center justify-center text-sm",
1122
+ children: "\u2026"
1123
+ },
1124
+ `ellipsis-${idx}`
1125
+ ) : /* @__PURE__ */ jsx7(
1126
+ "button",
1127
+ {
1128
+ onClick: () => onPageChange(p),
1129
+ disabled: loading,
1130
+ className: cn(
1131
+ "flex h-9 w-9 items-center justify-center rounded-lg text-sm font-medium transition-all duration-200",
1132
+ p === currentPage ? "bg-primary text-white shadow-sm shadow-primary/30" : "border-border bg-surface text-text-secondary hover:bg-primary/8 hover:border-primary/30 hover:text-primary border active:scale-95"
1133
+ ),
1134
+ children: p
1135
+ },
1136
+ p
1137
+ )
1138
+ ),
1139
+ /* @__PURE__ */ jsx7(
1140
+ NavButton,
1141
+ {
1142
+ onClick: () => onPageChange(currentPage + 1),
1143
+ disabled: currentPage === totalPages || loading,
1144
+ title: "Page suivante",
1145
+ children: /* @__PURE__ */ jsx7(ChevronRight, { size: 16 })
1146
+ }
1147
+ ),
1148
+ /* @__PURE__ */ jsx7(
1149
+ NavButton,
1150
+ {
1151
+ onClick: () => onPageChange(totalPages),
1152
+ disabled: currentPage === totalPages || loading,
1153
+ title: "Derni\xE8re page",
1154
+ children: /* @__PURE__ */ jsx7(ChevronsRight, { size: 16 })
1155
+ }
1156
+ )
1157
+ ] });
858
1158
  };
859
- var MembersPanel = ({
860
- members,
1159
+
1160
+ // src/components/WorkspaceCard.tsx
1161
+ import { Brain as Brain2, Lock, Calendar, ArrowUpRight, MessageSquare } from "lucide-react";
1162
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1163
+ var WorkspaceCard = ({
1164
+ workspace,
1165
+ members = [],
861
1166
  avatarUsers,
862
- onAddMember,
863
- onRemoveMember,
864
- onUpdateRole,
865
- readonly,
866
- hideAgents = false
1167
+ onClick,
1168
+ currentUserId
867
1169
  }) => {
868
- const { config } = useWorkspaceContext();
869
- const apis = useWorkspaceApi();
870
- const [showUserSearch, setShowUserSearch] = useState2(false);
871
- const [search, setSearch] = useState2("");
872
- const [searchResults, setSearchResults] = useState2([]);
873
- const [searchingUsers, setSearchingUsers] = useState2(false);
874
- const [allAgents, setAllAgents] = useState2([]);
875
- useEffect2(() => {
876
- apis.agentApi.list().then(setAllAgents).catch(() => setAllAgents([]));
877
- }, []);
878
- useEffect2(() => {
879
- if (search.length < 2 || !showUserSearch || !config.searchUsers) {
880
- setSearchResults([]);
881
- return;
882
- }
883
- let cancelled = false;
884
- setSearchingUsers(true);
885
- config.searchUsers(search).then((results) => {
886
- if (!cancelled) setSearchResults(results);
887
- }).catch(() => {
888
- if (!cancelled) setSearchResults([]);
889
- }).finally(() => {
890
- if (!cancelled) setSearchingUsers(false);
891
- });
892
- return () => {
893
- cancelled = true;
894
- };
895
- }, [search, showUserSearch, config.searchUsers]);
896
- const filteredUsers = useMemo3(() => {
897
- return searchResults.filter(
898
- (u) => u.email !== config.currentUserId && !members.some((m) => m.memberId === u.email)
899
- );
900
- }, [searchResults, members, config.currentUserId]);
1170
+ const isPrivate = workspace.isPrivate === true;
1171
+ const typeName = typeof workspace.type === "object" && workspace.type !== null ? workspace.type.name : workspace.type;
1172
+ const userRole = currentUserId ? members.find((m) => m.memberId === currentUserId)?.role : void 0;
901
1173
  const userMembers = members.filter((m) => m.memberType === "user");
902
1174
  const agentMembers = members.filter((m) => m.memberType === "agent");
903
- const agentMemberIds = useMemo3(() => new Set(agentMembers.map((m) => m.memberId)), [agentMembers]);
904
- const agentMemberIdMap = useMemo3(() => new Map(agentMembers.map((m) => [m.memberId, m._id])), [agentMembers]);
905
- const handleAddUser = (user) => {
906
- onAddMember?.({ memberId: user.email, memberName: user.displayName, memberType: "user", role: "participant" });
907
- setSearch("");
908
- setShowUserSearch(false);
909
- };
910
- const handleAddAgent = (agent) => {
911
- onAddMember?.({ memberId: agent.agentId, memberName: agent.agentName, memberType: "agent", role: "participant" });
912
- };
913
- return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-4", children: [
914
- /* @__PURE__ */ jsxs2("div", { children: [
915
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between", children: [
916
- /* @__PURE__ */ jsxs2("span", { className: "text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase", children: [
917
- /* @__PURE__ */ jsx4(Users, { size: 14, className: "text-primary" }),
918
- " Utilisateurs"
1175
+ const otherMember = isPrivate ? members.find((m) => m.memberId !== currentUserId) : null;
1176
+ const otherAvatarUrl = otherMember ? avatarUsers?.find((u) => u.email.toLowerCase() === otherMember.memberId.toLowerCase())?.avatarUrl : void 0;
1177
+ const displayEntities = workspace.entitiesWithSecrets ?? [];
1178
+ const isActive = workspace.status === "ACTIVE";
1179
+ const cardClass = cn(
1180
+ "group bg-[var(--color-surface,#fff)] border-[var(--color-border,#e2e8f0)] relative flex cursor-pointer flex-col rounded-2xl border p-5 transition-all duration-300",
1181
+ "shadow-sm hover:shadow-md hover:-translate-y-1 overflow-hidden"
1182
+ );
1183
+ if (isPrivate) {
1184
+ return /* @__PURE__ */ jsxs5("div", { className: cardClass, onClick, children: [
1185
+ /* @__PURE__ */ jsxs5("div", { className: "mb-4 flex items-center justify-between", children: [
1186
+ /* @__PURE__ */ jsxs5("span", { className: "bg-[var(--color-primary-light,#eff6ff)] text-[var(--color-primary,#3b82f6)] flex items-center gap-1.5 rounded-lg px-2.5 py-1 text-[11px] font-semibold tracking-wide uppercase", children: [
1187
+ /* @__PURE__ */ jsx8(MessageSquare, { size: 11 }),
1188
+ " Priv\xE9"
919
1189
  ] }),
920
- /* @__PURE__ */ jsxs2("span", { className: "flex items-center gap-1", children: [
921
- /* @__PURE__ */ jsx4("span", { className: "bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold", children: userMembers.length }),
922
- !readonly && /* @__PURE__ */ jsxs2("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), children: [
923
- /* @__PURE__ */ jsx4(UserPlus, { size: 12 }),
924
- " Inviter"
925
- ] })
926
- ] })
1190
+ /* @__PURE__ */ jsx8(ArrowUpRight, { size: 14, className: "text-[var(--color-text-muted,#94a3b8)] group-hover:text-[var(--color-primary,#3b82f6)] transition-all duration-200 group-hover:translate-x-0.5 group-hover:-translate-y-0.5" })
927
1191
  ] }),
928
- showUserSearch && /* @__PURE__ */ jsxs2(Fragment, { children: [
929
- /* @__PURE__ */ jsxs2("div", { className: "relative mt-2", children: [
930
- /* @__PURE__ */ jsx4(Search, { size: 12, className: "text-text-muted absolute top-1/2 left-2 -translate-y-1/2" }),
931
- /* @__PURE__ */ jsx4("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: true })
932
- ] }),
933
- search.length >= 2 && searchingUsers && /* @__PURE__ */ jsx4("div", { className: "flex items-center justify-center py-3", children: /* @__PURE__ */ jsx4(Loader2, { size: 14, className: "text-primary animate-spin" }) }),
934
- filteredUsers.length > 0 && !searchingUsers && /* @__PURE__ */ jsx4("div", { className: "bg-surface border-border mt-1 flex flex-col rounded-lg border shadow-sm", children: filteredUsers.map((u) => /* @__PURE__ */ jsxs2("div", { 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), children: [
935
- /* @__PURE__ */ jsx4("span", { className: "bg-primary-light text-primary flex h-6 w-6 items-center justify-center rounded-full text-[10px] font-semibold", children: getInitials(u.displayName) }),
936
- /* @__PURE__ */ jsx4("span", { className: "text-text", children: u.displayName }),
937
- /* @__PURE__ */ jsx4(Plus, { size: 12, className: "text-primary ml-auto" })
938
- ] }, u.id)) })
1192
+ /* @__PURE__ */ jsxs5("div", { className: "mb-4 flex items-center gap-3", children: [
1193
+ /* @__PURE__ */ jsx8(MemberAvatar, { memberName: otherMember?.memberName ?? "Inconnu", memberType: "user", avatarUrl: otherAvatarUrl, size: "lg" }),
1194
+ /* @__PURE__ */ jsxs5("div", { className: "min-w-0 flex-1", children: [
1195
+ /* @__PURE__ */ jsx8("h4", { className: "text-[var(--color-text,#0f172a)] group-hover:text-[var(--color-primary,#3b82f6)] text-[15px] leading-snug font-bold transition-colors duration-200", children: otherMember?.memberName ?? "Utilisateur inconnu" }),
1196
+ /* @__PURE__ */ jsx8("p", { className: "text-[var(--color-text-muted,#94a3b8)] truncate text-xs", children: otherMember?.memberId ?? "" })
1197
+ ] })
939
1198
  ] }),
940
- /* @__PURE__ */ jsx4("div", { className: "mt-2 flex flex-col gap-1", children: userMembers.map((m) => /* @__PURE__ */ jsxs2("div", { className: "bg-bg group flex items-center gap-2 rounded-lg p-2", children: [
941
- /* @__PURE__ */ jsx4(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" }),
942
- /* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
943
- /* @__PURE__ */ jsx4("div", { className: "text-text truncate text-xs font-medium", children: m.memberName }),
944
- /* @__PURE__ */ jsxs2("div", { className: "text-text-muted flex items-center gap-1 text-[10px]", children: [
945
- roleIcon(m.role),
946
- " ",
947
- ROLE_LABELS[m.role] ?? m.role
948
- ] })
949
- ] }),
950
- !(readonly || m.role === "owner" && members.filter((x) => x.role === "owner").length === 1) && /* @__PURE__ */ jsxs2("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) => {
951
- e.stopPropagation();
952
- onUpdateRole?.(m._id, e.target.value);
953
- }, disabled: readonly || m.role === "owner" && members.filter((x) => x.role === "owner").length === 1, children: [
954
- /* @__PURE__ */ jsx4("option", { value: "owner", children: "Propri\xE9taire" }),
955
- /* @__PURE__ */ jsx4("option", { value: "participant", children: "Participant" }),
956
- /* @__PURE__ */ jsx4("option", { value: "viewer", children: "Observateur" })
1199
+ /* @__PURE__ */ jsxs5("div", { className: "mt-auto", children: [
1200
+ /* @__PURE__ */ jsx8("div", { className: "border-[var(--color-border,#e2e8f0)] mb-3 border-t" }),
1201
+ /* @__PURE__ */ jsx8("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ jsxs5("span", { className: "text-[var(--color-text-muted,#94a3b8)] flex items-center gap-1 text-[11px]", children: [
1202
+ /* @__PURE__ */ jsx8(Calendar, { size: 11, className: "opacity-50" }),
1203
+ new Date(workspace.updatedAt).toLocaleDateString("fr-FR")
1204
+ ] }) })
1205
+ ] })
1206
+ ] });
1207
+ }
1208
+ return /* @__PURE__ */ jsxs5("div", { className: cardClass, onClick, children: [
1209
+ /* @__PURE__ */ jsxs5("div", { className: "mb-3 flex items-center justify-between", children: [
1210
+ /* @__PURE__ */ jsx8("div", { className: "flex items-center gap-2", children: typeName && /* @__PURE__ */ jsx8("span", { className: "bg-[var(--color-primary-light,#eff6ff)] text-[var(--color-primary,#3b82f6)] rounded-lg px-2.5 py-1 text-[11px] font-semibold tracking-wide uppercase", children: typeName }) }),
1211
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1.5", children: [
1212
+ userRole && /* @__PURE__ */ jsx8("span", { className: cn(
1213
+ "rounded-lg px-2 py-0.5 text-[10px] font-semibold",
1214
+ userRole === "owner" ? "bg-amber-50 text-amber-600 dark:bg-amber-500/10 dark:text-amber-400" : userRole === "participant" ? "bg-[var(--color-primary-light,#eff6ff)] text-[var(--color-primary,#3b82f6)]" : "bg-[var(--color-bg,#f8fafc)] text-[var(--color-text-muted,#94a3b8)]"
1215
+ ), children: ROLE_LABELS[userRole] ?? userRole }),
1216
+ /* @__PURE__ */ jsx8(Badge, { variant: isActive ? "success" : "default", size: "xs", children: STATUS_LABELS[workspace.status] ?? workspace.status })
1217
+ ] })
1218
+ ] }),
1219
+ /* @__PURE__ */ jsxs5("div", { className: "mb-3", children: [
1220
+ /* @__PURE__ */ jsx8("h4", { className: "text-[var(--color-text,#0f172a)] group-hover:text-[var(--color-primary,#3b82f6)] mb-1 text-[15px] leading-snug font-bold transition-colors duration-200", children: workspace.name }),
1221
+ workspace.scope && /* @__PURE__ */ jsx8("p", { className: "text-[var(--color-text-secondary,#475569)] line-clamp-2 text-[13px] leading-relaxed", children: workspace.scope })
1222
+ ] }),
1223
+ displayEntities.length > 0 && /* @__PURE__ */ jsxs5("div", { className: "mb-3 flex flex-wrap gap-1.5", children: [
1224
+ displayEntities.slice(0, 3).map((ent) => /* @__PURE__ */ jsxs5("span", { className: "bg-[var(--color-bg,#f8fafc)] border-[var(--color-border,#e2e8f0)] inline-flex items-center gap-1 rounded-lg border px-2 py-1 text-[10px]", children: [
1225
+ ent.isSecret && /* @__PURE__ */ jsx8(Lock, { size: 9, className: "text-amber-500 shrink-0" }),
1226
+ /* @__PURE__ */ jsxs5("span", { className: "text-[var(--color-text-muted,#94a3b8)] font-medium", children: [
1227
+ ent.key,
1228
+ ":"
957
1229
  ] }),
958
- m.role !== "owner" && !readonly && /* @__PURE__ */ jsx4("button", { className: "text-text-muted hover:text-danger rounded p-0.5 opacity-0 transition-all group-hover:opacity-100", onClick: (e) => {
959
- e.stopPropagation();
960
- onRemoveMember?.(m._id);
961
- }, children: /* @__PURE__ */ jsx4(X2, { size: 14 }) })
962
- ] }, m._id)) })
1230
+ /* @__PURE__ */ jsx8("span", { className: "text-[var(--color-text,#0f172a)]", children: ent.isSecret ? "\u2022\u2022\u2022\u2022\u2022\u2022" : ent.value })
1231
+ ] }, ent.key)),
1232
+ displayEntities.length > 3 && /* @__PURE__ */ jsxs5("span", { className: "text-[var(--color-text-muted,#94a3b8)] self-center text-[10px]", children: [
1233
+ "+",
1234
+ displayEntities.length - 3
1235
+ ] })
963
1236
  ] }),
964
- !hideAgents && /* @__PURE__ */ jsxs2("div", { children: [
965
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between", children: [
966
- /* @__PURE__ */ jsxs2("span", { className: "text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase", children: [
967
- /* @__PURE__ */ jsx4(Brain2, { size: 14, className: "text-primary" }),
968
- " Agents IA"
1237
+ /* @__PURE__ */ jsxs5("div", { className: "mt-auto", children: [
1238
+ /* @__PURE__ */ jsx8("div", { className: "border-[var(--color-border,#e2e8f0)] mb-3 border-t" }),
1239
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between", children: [
1240
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3", children: [
1241
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center", children: [
1242
+ /* @__PURE__ */ jsx8("div", { className: "flex -space-x-2", children: userMembers.slice(0, 4).map((m) => /* @__PURE__ */ jsx8(Tooltip, { text: `${m.memberName} (${ROLE_LABELS[m.role] ?? m.role})`, children: /* @__PURE__ */ jsx8(
1243
+ MemberAvatar,
1244
+ {
1245
+ memberName: m.memberName,
1246
+ memberType: m.memberType,
1247
+ avatarUrl: avatarUsers?.find((u) => u.email.toLowerCase() === m.memberId.toLowerCase())?.avatarUrl,
1248
+ size: "xs"
1249
+ }
1250
+ ) }, m._id)) }),
1251
+ userMembers.length > 4 && /* @__PURE__ */ jsxs5("span", { className: "text-[var(--color-text-muted,#94a3b8)] ml-1.5 text-[11px] font-medium", children: [
1252
+ "+",
1253
+ userMembers.length - 4
1254
+ ] })
1255
+ ] }),
1256
+ agentMembers.length > 0 && /* @__PURE__ */ jsx8(Tooltip, { text: `${agentMembers.length} agent(s): ${agentMembers.map((a) => a.memberName).join(", ")}`, children: /* @__PURE__ */ jsxs5("span", { className: "bg-[var(--color-primary-light,#eff6ff)] text-[var(--color-primary,#3b82f6)] flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[11px] font-medium", children: [
1257
+ /* @__PURE__ */ jsx8(Brain2, { size: 12 }),
1258
+ " ",
1259
+ agentMembers.length
1260
+ ] }) })
969
1261
  ] }),
970
- /* @__PURE__ */ jsxs2("span", { className: "bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold", children: [
971
- agentMembers.length,
972
- "/",
973
- allAgents.length
974
- ] })
975
- ] }),
976
- /* @__PURE__ */ jsx4("div", { className: "mt-2 flex flex-col gap-1", children: allAgents.map((agent) => {
977
- const isMember = agentMemberIds.has(agent.agentId);
978
- const memberId = agentMemberIdMap.get(agent.agentId);
979
- return /* @__PURE__ */ jsxs2("div", { className: "bg-bg group flex items-center gap-2 rounded-lg p-2", children: [
980
- /* @__PURE__ */ jsx4("span", { className: "bg-surface border-border flex h-7 w-7 items-center justify-center rounded-full border", children: /* @__PURE__ */ jsx4(Brain2, { size: 14, className: "text-primary" }) }),
981
- /* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
982
- /* @__PURE__ */ jsx4("div", { className: "text-text truncate text-xs font-medium", children: agent.agentName }),
983
- /* @__PURE__ */ jsx4("div", { className: "text-text-muted text-[10px]", children: "Agent IA" })
1262
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
1263
+ /* @__PURE__ */ jsxs5("span", { className: "text-[var(--color-text-muted,#94a3b8)] flex items-center gap-1 text-[11px]", children: [
1264
+ /* @__PURE__ */ jsx8(Calendar, { size: 11, className: "opacity-50" }),
1265
+ new Date(workspace.updatedAt).toLocaleDateString("fr-FR")
984
1266
  ] }),
985
- !readonly && (isMember ? /* @__PURE__ */ jsxs2("button", { className: "relative flex h-6 w-6 items-center justify-center rounded-full transition-colors", onClick: (e) => {
986
- e.stopPropagation();
987
- if (memberId) onRemoveMember?.(memberId);
988
- }, children: [
989
- /* @__PURE__ */ jsx4(Check, { size: 14, className: "text-success absolute transition-opacity group-hover:opacity-0" }),
990
- /* @__PURE__ */ jsx4(X2, { size: 14, className: "text-danger absolute opacity-0 transition-opacity group-hover:opacity-100" })
991
- ] }) : /* @__PURE__ */ jsx4("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) => {
992
- e.stopPropagation();
993
- handleAddAgent(agent);
994
- }, children: /* @__PURE__ */ jsx4(Plus, { size: 14 }) }))
995
- ] }, agent.agentId);
996
- }) })
1267
+ /* @__PURE__ */ jsx8(ArrowUpRight, { size: 14, className: "text-[var(--color-text-muted,#94a3b8)] group-hover:text-[var(--color-primary,#3b82f6)] transition-all duration-200 group-hover:translate-x-0.5 group-hover:-translate-y-0.5" })
1268
+ ] })
1269
+ ] })
1270
+ ] })
1271
+ ] });
1272
+ };
1273
+
1274
+ // src/components/WorkspaceRow.tsx
1275
+ import { Brain as Brain3 } from "lucide-react";
1276
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
1277
+ var WorkspaceRow = ({
1278
+ workspace,
1279
+ members = [],
1280
+ avatarUsers,
1281
+ onClick,
1282
+ currentUserId
1283
+ }) => {
1284
+ const typeName = typeof workspace.type === "object" && workspace.type !== null ? workspace.type.name : workspace.type;
1285
+ const userRole = currentUserId ? members.find((m) => m.memberId === currentUserId)?.role : void 0;
1286
+ const userMembers = members.filter((m) => m.memberType === "user");
1287
+ const agentMembers = members.filter((m) => m.memberType === "agent");
1288
+ return /* @__PURE__ */ jsxs6(
1289
+ "div",
1290
+ {
1291
+ className: "bg-[var(--color-surface,#fff)] border-[var(--color-border,#e2e8f0)] hover:bg-[var(--color-primary-light,#eff6ff)]/30 flex cursor-pointer items-center gap-4 rounded-lg border px-4 py-3 transition-colors",
1292
+ onClick,
1293
+ children: [
1294
+ /* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
1295
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
1296
+ /* @__PURE__ */ jsx9("span", { className: "text-[var(--color-text,#0f172a)] truncate font-semibold", children: workspace.name }),
1297
+ typeName && /* @__PURE__ */ jsx9(Badge, { size: "xs", title: typeName, children: typeName })
1298
+ ] }),
1299
+ workspace.scope && /* @__PURE__ */ jsx9("p", { className: "text-[var(--color-text-muted,#94a3b8)] mt-0.5 truncate text-xs", children: workspace.scope })
1300
+ ] }),
1301
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
1302
+ /* @__PURE__ */ jsx9("div", { className: "flex -space-x-1.5", children: userMembers.slice(0, 3).map((m) => /* @__PURE__ */ jsx9(Tooltip, { text: m.memberName, children: /* @__PURE__ */ jsx9(
1303
+ MemberAvatar,
1304
+ {
1305
+ memberName: m.memberName,
1306
+ memberType: m.memberType,
1307
+ avatarUrl: avatarUsers?.find((u) => u.email.toLowerCase() === m.memberId.toLowerCase())?.avatarUrl,
1308
+ size: "xs"
1309
+ }
1310
+ ) }, m._id)) }),
1311
+ agentMembers.length > 0 && /* @__PURE__ */ jsxs6("span", { className: "text-[var(--color-text-muted,#94a3b8)] flex items-center gap-0.5 text-[10px]", children: [
1312
+ /* @__PURE__ */ jsx9(Brain3, { size: 10 }),
1313
+ " ",
1314
+ agentMembers.length
1315
+ ] })
1316
+ ] }),
1317
+ userRole && /* @__PURE__ */ jsx9("span", { className: cn(
1318
+ "rounded-full px-2 py-0.5 text-[10px] font-medium",
1319
+ userRole === "owner" ? "bg-amber-50 text-amber-600 dark:bg-amber-500/10 dark:text-amber-400" : "bg-[var(--color-primary-light,#eff6ff)] text-[var(--color-primary,#3b82f6)]"
1320
+ ), children: ROLE_LABELS[userRole] ?? userRole }),
1321
+ /* @__PURE__ */ jsx9(Badge, { variant: workspace.status === "ACTIVE" ? "success" : "default", size: "xs", children: STATUS_LABELS[workspace.status] ?? workspace.status }),
1322
+ /* @__PURE__ */ jsx9("span", { className: "text-[var(--color-text-muted,#94a3b8)] text-[10px] whitespace-nowrap", children: new Date(workspace.updatedAt).toLocaleDateString("fr-FR") })
1323
+ ]
1324
+ }
1325
+ );
1326
+ };
1327
+
1328
+ // src/components/WorkspaceList.tsx
1329
+ import React5 from "react";
1330
+ import { Search, Filter, LayoutGrid, List, Layers } from "lucide-react";
1331
+ import { Fragment, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
1332
+ var SkeletonCard = () => /* @__PURE__ */ jsxs7("div", { className: "bg-[var(--color-surface,#fff)] border-[var(--color-border,#e2e8f0)] animate-pulse rounded-2xl border p-5", children: [
1333
+ /* @__PURE__ */ jsxs7("div", { className: "mb-3 flex items-center justify-between", children: [
1334
+ /* @__PURE__ */ jsx10("div", { className: "bg-[var(--color-border,#e2e8f0)] h-5 w-20 rounded-lg" }),
1335
+ /* @__PURE__ */ jsx10("div", { className: "bg-[var(--color-border,#e2e8f0)] h-4 w-14 rounded-lg" })
1336
+ ] }),
1337
+ /* @__PURE__ */ jsxs7("div", { className: "mb-3", children: [
1338
+ /* @__PURE__ */ jsx10("div", { className: "bg-[var(--color-border,#e2e8f0)] mb-2 h-4 w-3/4 rounded" }),
1339
+ /* @__PURE__ */ jsx10("div", { className: "bg-[var(--color-border,#e2e8f0)] h-3 w-1/2 rounded" })
1340
+ ] }),
1341
+ /* @__PURE__ */ jsxs7("div", { className: "mt-auto", children: [
1342
+ /* @__PURE__ */ jsx10("div", { className: "border-[var(--color-border,#e2e8f0)] mb-3 border-t" }),
1343
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between", children: [
1344
+ /* @__PURE__ */ jsx10("div", { className: "flex -space-x-2", children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx10("div", { className: "bg-[var(--color-border,#e2e8f0)] h-6 w-6 rounded-full" }, i)) }),
1345
+ /* @__PURE__ */ jsx10("div", { className: "bg-[var(--color-border,#e2e8f0)] h-3 w-16 rounded" })
1346
+ ] })
1347
+ ] })
1348
+ ] });
1349
+ var WorkspaceList = ({
1350
+ workspaces,
1351
+ total,
1352
+ membersMap = {},
1353
+ avatarUsers,
1354
+ types = [],
1355
+ loading = false,
1356
+ fetching = false,
1357
+ onOpen,
1358
+ title = "Workspaces",
1359
+ showViewToggle = true,
1360
+ currentUserId,
1361
+ headerActions,
1362
+ hideHeader = false,
1363
+ hideFilters = false,
1364
+ filters,
1365
+ onFiltersChange,
1366
+ currentPage = 1,
1367
+ totalPages = 1,
1368
+ onPageChange
1369
+ }) => {
1370
+ const [viewMode, setViewMode] = React5.useState("grid");
1371
+ const search = filters?.search ?? "";
1372
+ const statusFilter = filters?.status ?? "ACTIVE";
1373
+ const typeFilter = filters?.type ?? "all";
1374
+ const statusOptions = [
1375
+ { value: "all", label: "Tous" },
1376
+ { value: "ACTIVE", label: "Actifs" },
1377
+ { value: "ARCHIVED", label: "Archiv\xE9s" }
1378
+ ];
1379
+ const showSkeletons = loading || fetching && workspaces.length === 0;
1380
+ const Header = () => /* @__PURE__ */ jsxs7("div", { className: "mb-5 flex items-center justify-between", children: [
1381
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
1382
+ /* @__PURE__ */ jsx10("div", { className: "bg-[var(--color-primary-light,#eff6ff)] flex h-9 w-9 items-center justify-center rounded-xl", children: /* @__PURE__ */ jsx10(Layers, { size: 18, className: "text-[var(--color-primary,#3b82f6)]" }) }),
1383
+ /* @__PURE__ */ jsxs7("div", { children: [
1384
+ /* @__PURE__ */ jsx10("h2", { className: "text-[var(--color-text,#0f172a)] text-lg font-bold tracking-tight", children: title }),
1385
+ total != null && !showSkeletons && /* @__PURE__ */ jsxs7("p", { className: "text-[var(--color-text-muted,#94a3b8)] text-xs", children: [
1386
+ total,
1387
+ " workspace",
1388
+ total !== 1 ? "s" : ""
1389
+ ] })
1390
+ ] })
1391
+ ] }),
1392
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
1393
+ showViewToggle && /* @__PURE__ */ jsxs7("div", { className: "bg-[var(--color-bg,#f8fafc)] border-[var(--color-border,#e2e8f0)] flex rounded-lg border p-0.5", children: [
1394
+ /* @__PURE__ */ jsx10(
1395
+ "button",
1396
+ {
1397
+ className: cn(
1398
+ "rounded-md p-1.5 transition-all duration-200",
1399
+ viewMode === "grid" ? "bg-[var(--color-primary,#3b82f6)] text-white shadow-sm" : "text-[var(--color-text-muted,#94a3b8)] hover:text-[var(--color-text,#0f172a)]"
1400
+ ),
1401
+ onClick: () => setViewMode("grid"),
1402
+ title: "Vue grille",
1403
+ children: /* @__PURE__ */ jsx10(LayoutGrid, { size: 14 })
1404
+ }
1405
+ ),
1406
+ /* @__PURE__ */ jsx10(
1407
+ "button",
1408
+ {
1409
+ className: cn(
1410
+ "rounded-md p-1.5 transition-all duration-200",
1411
+ viewMode === "list" ? "bg-[var(--color-primary,#3b82f6)] text-white shadow-sm" : "text-[var(--color-text-muted,#94a3b8)] hover:text-[var(--color-text,#0f172a)]"
1412
+ ),
1413
+ onClick: () => setViewMode("list"),
1414
+ title: "Vue liste",
1415
+ children: /* @__PURE__ */ jsx10(List, { size: 14 })
1416
+ }
1417
+ )
1418
+ ] }),
1419
+ headerActions
1420
+ ] })
1421
+ ] });
1422
+ if (showSkeletons) {
1423
+ return /* @__PURE__ */ jsxs7("div", { children: [
1424
+ !hideHeader && /* @__PURE__ */ jsx10(Header, {}),
1425
+ /* @__PURE__ */ jsx10("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx10(SkeletonCard, {}, i)) })
1426
+ ] });
1427
+ }
1428
+ return /* @__PURE__ */ jsxs7("div", { children: [
1429
+ !hideHeader && /* @__PURE__ */ jsx10(Header, {}),
1430
+ /* @__PURE__ */ jsxs7("div", { className: "mb-5 flex flex-wrap items-center gap-3", children: [
1431
+ /* @__PURE__ */ jsxs7("div", { className: "relative min-w-[220px] flex-1", children: [
1432
+ /* @__PURE__ */ jsx10(Search, { size: 15, className: "text-[var(--color-text-muted,#94a3b8)] absolute top-1/2 left-3.5 -translate-y-1/2" }),
1433
+ /* @__PURE__ */ jsx10(
1434
+ "input",
1435
+ {
1436
+ className: "border-[var(--color-border,#e2e8f0)] bg-[var(--color-surface,#fff)] text-[var(--color-text,#0f172a)] w-full rounded-xl border py-2.5 pr-3 pl-10 text-sm transition-all duration-200 focus:border-[var(--color-primary,#3b82f6)]/50 focus:outline-none focus:ring-2 focus:ring-[var(--color-primary,#3b82f6)]/10 placeholder:text-[var(--color-text-muted,#94a3b8)]",
1437
+ placeholder: "Rechercher un workspace\u2026",
1438
+ value: search,
1439
+ onChange: (e) => onFiltersChange?.({ search: e.target.value, status: statusFilter, type: typeFilter })
1440
+ }
1441
+ )
1442
+ ] }),
1443
+ !hideFilters && /* @__PURE__ */ jsxs7(Fragment, { children: [
1444
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1.5", children: [
1445
+ /* @__PURE__ */ jsx10(Filter, { size: 13, className: "text-[var(--color-text-muted,#94a3b8)] mr-0.5" }),
1446
+ statusOptions.map(({ value, label }) => /* @__PURE__ */ jsx10(
1447
+ "button",
1448
+ {
1449
+ className: cn(
1450
+ "rounded-full px-3 py-1.5 text-xs font-medium transition-all duration-200",
1451
+ statusFilter === value ? "bg-[var(--color-primary,#3b82f6)] text-white shadow-sm" : "bg-[var(--color-surface,#fff)] border-[var(--color-border,#e2e8f0)] text-[var(--color-text-muted,#94a3b8)] hover:bg-[var(--color-primary-light,#eff6ff)] hover:text-[var(--color-primary,#3b82f6)] border"
1452
+ ),
1453
+ onClick: () => onFiltersChange?.({ search, status: value, type: typeFilter }),
1454
+ children: label
1455
+ },
1456
+ value
1457
+ ))
1458
+ ] }),
1459
+ types.length > 0 && /* @__PURE__ */ jsxs7(
1460
+ "select",
1461
+ {
1462
+ className: "border-[var(--color-border,#e2e8f0)] bg-[var(--color-surface,#fff)] text-[var(--color-text,#0f172a)] rounded-xl border px-3 py-2 text-xs transition-all duration-200 focus:border-[var(--color-primary,#3b82f6)]/50 focus:outline-none focus:ring-2 focus:ring-[var(--color-primary,#3b82f6)]/10",
1463
+ value: typeFilter,
1464
+ onChange: (e) => onFiltersChange?.({ search, status: statusFilter, type: e.target.value }),
1465
+ children: [
1466
+ /* @__PURE__ */ jsx10("option", { value: "all", children: "Tous les types" }),
1467
+ types.map((t) => /* @__PURE__ */ jsx10("option", { value: t._id, children: t.name }, t._id))
1468
+ ]
1469
+ }
1470
+ )
1471
+ ] })
1472
+ ] }),
1473
+ /* @__PURE__ */ jsxs7("div", { className: cn("transition-opacity duration-300", fetching ? "opacity-60" : "opacity-100"), children: [
1474
+ workspaces.length === 0 ? /* @__PURE__ */ jsxs7("div", { className: "text-[var(--color-text-muted,#94a3b8)] border-[var(--color-border,#e2e8f0)] flex flex-col items-center justify-center rounded-2xl border border-dashed py-12 text-center", children: [
1475
+ /* @__PURE__ */ jsx10("div", { className: "bg-[var(--color-bg,#f8fafc)] mb-3 flex h-12 w-12 items-center justify-center rounded-full", children: /* @__PURE__ */ jsx10(Layers, { size: 22, className: "opacity-40" }) }),
1476
+ /* @__PURE__ */ jsx10("p", { className: "mb-1 text-sm font-medium", children: "Aucun workspace trouv\xE9" }),
1477
+ /* @__PURE__ */ jsx10("p", { className: "text-xs", children: search || statusFilter !== "all" || typeFilter !== "all" ? "Modifiez vos filtres pour voir plus de r\xE9sultats" : "Cr\xE9ez un workspace pour commencer \xE0 collaborer" })
1478
+ ] }) : viewMode === "grid" ? /* @__PURE__ */ jsx10("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: workspaces.map((ws) => /* @__PURE__ */ jsx10(
1479
+ WorkspaceCard,
1480
+ {
1481
+ workspace: ws,
1482
+ members: membersMap[ws._id],
1483
+ avatarUsers,
1484
+ onClick: () => onOpen(ws._id),
1485
+ currentUserId
1486
+ },
1487
+ ws._id
1488
+ )) }) : /* @__PURE__ */ jsx10("div", { className: "flex flex-col gap-2", children: workspaces.map((ws) => /* @__PURE__ */ jsx10(
1489
+ WorkspaceRow,
1490
+ {
1491
+ workspace: ws,
1492
+ members: membersMap[ws._id],
1493
+ avatarUsers,
1494
+ onClick: () => onOpen(ws._id),
1495
+ currentUserId
1496
+ },
1497
+ ws._id
1498
+ )) }),
1499
+ onPageChange && totalPages > 1 && /* @__PURE__ */ jsx10(Pagination, { currentPage, totalPages, onPageChange, loading: fetching })
997
1500
  ] })
998
1501
  ] });
999
1502
  };
1000
1503
 
1001
1504
  // src/components/CreateWorkspaceModal.tsx
1002
- import { useState as useState3, useEffect as useEffect3, useMemo as useMemo4, useId as useId2, useRef } from "react";
1003
- import { X as X3, ArrowRight, ArrowLeft, Plus as Plus2, Trash2, Check as Check2, Users as Users2, Brain as Brain3, Loader2 as Loader22, Lock, Unlock, Slack } from "lucide-react";
1004
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1505
+ import { useState as useState3, useEffect as useEffect4, useMemo as useMemo3, useId as useId2, useRef as useRef2 } from "react";
1506
+ import { X as X3, ArrowRight, ArrowLeft, Plus, Trash2, Check, Users, Brain as Brain4, Loader2 as Loader22, Lock as Lock2, Unlock, Slack } from "lucide-react";
1507
+ import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
1005
1508
  var STEP_TITLES = ["Type de workspace", "Contexte", "Membres", "Confirmation"];
1006
1509
  var CreateWorkspaceModal = ({ open, onClose, onCreated }) => {
1007
1510
  const titleId = useId2();
@@ -1028,16 +1531,16 @@ var CreateWorkspaceModal = ({ open, onClose, onCreated }) => {
1028
1531
  const [agentSearch, setAgentSearch] = useState3("");
1029
1532
  const [showAgentDropdown, setShowAgentDropdown] = useState3(false);
1030
1533
  const [agentSearchFocused, setAgentSearchFocused] = useState3(false);
1031
- const agentSearchInputRef = useRef(null);
1032
- const invitedUsers = useMemo4(() => members.filter((m) => m.memberType === "user"), [members]);
1033
- const invitedAgents = useMemo4(() => members.filter((m) => m.memberType === "agent"), [members]);
1034
- const unselectedAgents = useMemo4(() => agents.filter((a) => !members.some((m) => m.memberId === a.agentId) && (agentSearch.trim() === "" || a.agentName.toLowerCase().includes(agentSearch.toLowerCase()))), [agents, members, agentSearch]);
1035
- useEffect3(() => {
1534
+ const agentSearchInputRef = useRef2(null);
1535
+ const invitedUsers = useMemo3(() => members.filter((m) => m.memberType === "user"), [members]);
1536
+ const invitedAgents = useMemo3(() => members.filter((m) => m.memberType === "agent"), [members]);
1537
+ const unselectedAgents = useMemo3(() => agents.filter((a) => !members.some((m) => m.memberId === a.agentId) && (agentSearch.trim() === "" || a.agentName.toLowerCase().includes(agentSearch.toLowerCase()))), [agents, members, agentSearch]);
1538
+ useEffect4(() => {
1036
1539
  if (!config.resolveAvatars || invitedUsers.length === 0) return;
1037
1540
  config.resolveAvatars(invitedUsers.map((m) => m.memberId)).then(setAvatarMap).catch(() => {
1038
1541
  });
1039
1542
  }, [invitedUsers.length]);
1040
- useEffect3(() => {
1543
+ useEffect4(() => {
1041
1544
  if (memberSearch.length < 2 || !config.searchUsers) {
1042
1545
  setSearchResults([]);
1043
1546
  return;
@@ -1055,8 +1558,8 @@ var CreateWorkspaceModal = ({ open, onClose, onCreated }) => {
1055
1558
  cancelled = true;
1056
1559
  };
1057
1560
  }, [memberSearch]);
1058
- const filteredUsers = useMemo4(() => searchResults.filter((u) => u.email !== config.currentUserId && !members.some((m) => m.memberId === u.email)), [searchResults, members, config.currentUserId]);
1059
- useEffect3(() => {
1561
+ const filteredUsers = useMemo3(() => searchResults.filter((u) => u.email !== config.currentUserId && !members.some((m) => m.memberId === u.email)), [searchResults, members, config.currentUserId]);
1562
+ useEffect4(() => {
1060
1563
  if (!open) return;
1061
1564
  setTypesLoading(true);
1062
1565
  Promise.all([apis.workspaceTypeApi.list(), apis.agentApi.list()]).then(([wt, ag]) => {
@@ -1068,14 +1571,14 @@ var CreateWorkspaceModal = ({ open, onClose, onCreated }) => {
1068
1571
  }).finally(() => setTypesLoading(false));
1069
1572
  apis.syncApi.getAvailableProviders().then((providers) => setSlackAvailable(providers.some((p) => p.id === "slack" && p.enabled))).catch(() => setSlackAvailable(false));
1070
1573
  }, [open]);
1071
- useEffect3(() => {
1574
+ useEffect4(() => {
1072
1575
  if (!selectedTypeId) return;
1073
1576
  const t = types.find((tp) => tp._id === selectedTypeId);
1074
1577
  if (t?.entitiesWithSecrets && t.entitiesWithSecrets.length > 0) {
1075
1578
  setEntities(t.entitiesWithSecrets.map((e) => ({ key: e.key, value: e.value, isSecret: e.isSecret })));
1076
1579
  }
1077
1580
  }, [selectedTypeId, types]);
1078
- useEffect3(() => {
1581
+ useEffect4(() => {
1079
1582
  if (!open) {
1080
1583
  setStep(0);
1081
1584
  setSelectedTypeId(null);
@@ -1127,128 +1630,128 @@ var CreateWorkspaceModal = ({ open, onClose, onCreated }) => {
1127
1630
  setLoading(false);
1128
1631
  }
1129
1632
  };
1130
- return /* @__PURE__ */ jsxs3(Modal, { open, 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: /* @__PURE__ */ jsxs3("p", { id: stepDescriptionId, className: "text-text-muted text-xs", children: [
1633
+ return /* @__PURE__ */ jsxs8(Modal, { open, 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: /* @__PURE__ */ jsxs8("p", { id: stepDescriptionId, className: "text-text-muted text-xs", children: [
1131
1634
  "\xC9tape ",
1132
1635
  step + 1,
1133
1636
  "/4 \u2014 ",
1134
1637
  STEP_TITLES[step]
1135
1638
  ] }), headerClassName: "items-center", closeButtonClassName: "text-text-muted hover:text-text transition-colors", children: [
1136
- /* @__PURE__ */ jsx5("div", { className: "flex shrink-0 gap-1 px-6 pt-4", children: [0, 1, 2, 3].map((s) => /* @__PURE__ */ jsx5("div", { className: cn("h-1 flex-1 rounded-full transition-colors", s <= step ? "bg-primary" : "bg-border-light") }, s)) }),
1137
- /* @__PURE__ */ jsxs3("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: [
1138
- step === 0 && (typesLoading ? /* @__PURE__ */ jsx5("div", { className: "flex h-[220px] items-center justify-center", children: /* @__PURE__ */ jsx5(Loader22, { size: 20, className: "text-primary animate-spin" }) }) : types.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "text-text-muted py-8 text-center text-sm", children: "Aucun type disponible" }) : /* @__PURE__ */ jsx5("div", { className: "grid grid-cols-2 gap-2", children: types.map((t) => /* @__PURE__ */ jsx5("button", { 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), children: /* @__PURE__ */ jsx5("span", { className: "text-text text-sm font-medium", children: t.name }) }, t._id)) })),
1139
- step === 1 && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-4", children: [
1140
- /* @__PURE__ */ jsxs3("div", { children: [
1141
- /* @__PURE__ */ jsx5("label", { className: "text-text-muted mb-1 block text-xs font-medium", children: "Nom du workspace" }),
1142
- /* @__PURE__ */ jsx5("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: true })
1639
+ /* @__PURE__ */ jsx11("div", { className: "flex shrink-0 gap-1 px-6 pt-4", children: [0, 1, 2, 3].map((s) => /* @__PURE__ */ jsx11("div", { className: cn("h-1 flex-1 rounded-full transition-colors", s <= step ? "bg-primary" : "bg-border-light") }, s)) }),
1640
+ /* @__PURE__ */ jsxs8("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: [
1641
+ step === 0 && (typesLoading ? /* @__PURE__ */ jsx11("div", { className: "flex h-[220px] items-center justify-center", children: /* @__PURE__ */ jsx11(Loader22, { size: 20, className: "text-primary animate-spin" }) }) : types.length === 0 ? /* @__PURE__ */ jsx11("p", { className: "text-text-muted py-8 text-center text-sm", children: "Aucun type disponible" }) : /* @__PURE__ */ jsx11("div", { className: "grid grid-cols-2 gap-2", children: types.map((t) => /* @__PURE__ */ jsx11("button", { 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), children: /* @__PURE__ */ jsx11("span", { className: "text-text text-sm font-medium", children: t.name }) }, t._id)) })),
1642
+ step === 1 && /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-4", children: [
1643
+ /* @__PURE__ */ jsxs8("div", { children: [
1644
+ /* @__PURE__ */ jsx11("label", { className: "text-text-muted mb-1 block text-xs font-medium", children: "Nom du workspace" }),
1645
+ /* @__PURE__ */ jsx11("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: true })
1143
1646
  ] }),
1144
- /* @__PURE__ */ jsxs3("div", { children: [
1145
- /* @__PURE__ */ jsx5("label", { className: "text-text-muted mb-1 block text-xs font-medium", children: "Scope" }),
1146
- /* @__PURE__ */ jsx5("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) })
1647
+ /* @__PURE__ */ jsxs8("div", { children: [
1648
+ /* @__PURE__ */ jsx11("label", { className: "text-text-muted mb-1 block text-xs font-medium", children: "Scope" }),
1649
+ /* @__PURE__ */ jsx11("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) })
1147
1650
  ] }),
1148
- /* @__PURE__ */ jsxs3("div", { children: [
1149
- /* @__PURE__ */ jsx5("label", { className: "text-text-muted mb-1 block text-xs font-medium", children: "Entit\xE9s" }),
1150
- /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
1151
- entities.map((e, idx) => /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
1152
- /* @__PURE__ */ jsx5("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) => {
1651
+ /* @__PURE__ */ jsxs8("div", { children: [
1652
+ /* @__PURE__ */ jsx11("label", { className: "text-text-muted mb-1 block text-xs font-medium", children: "Entit\xE9s" }),
1653
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2", children: [
1654
+ entities.map((e, idx) => /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
1655
+ /* @__PURE__ */ jsx11("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) => {
1153
1656
  const arr = [...entities];
1154
1657
  arr[idx].key = ev.target.value;
1155
1658
  setEntities(arr);
1156
1659
  }, placeholder: "Cl\xE9" }),
1157
- /* @__PURE__ */ jsx5("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) => {
1660
+ /* @__PURE__ */ jsx11("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) => {
1158
1661
  const arr = [...entities];
1159
1662
  arr[idx].value = ev.target.value;
1160
1663
  setEntities(arr);
1161
1664
  }, placeholder: "Valeur" }),
1162
- /* @__PURE__ */ jsx5("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: () => {
1665
+ /* @__PURE__ */ jsx11("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: () => {
1163
1666
  const arr = [...entities];
1164
1667
  arr[idx].isSecret = !arr[idx].isSecret;
1165
1668
  setEntities(arr);
1166
- }, children: e.isSecret ? /* @__PURE__ */ jsx5(Lock, { size: 12 }) : /* @__PURE__ */ jsx5(Unlock, { size: 12 }) }),
1167
- /* @__PURE__ */ jsx5("button", { className: "text-text-muted hover:text-danger", onClick: () => setEntities(entities.filter((_, i) => i !== idx)), children: /* @__PURE__ */ jsx5(Trash2, { size: 14 }) })
1669
+ }, children: e.isSecret ? /* @__PURE__ */ jsx11(Lock2, { size: 12 }) : /* @__PURE__ */ jsx11(Unlock, { size: 12 }) }),
1670
+ /* @__PURE__ */ jsx11("button", { className: "text-text-muted hover:text-danger", onClick: () => setEntities(entities.filter((_, i) => i !== idx)), children: /* @__PURE__ */ jsx11(Trash2, { size: 14 }) })
1168
1671
  ] }, idx)),
1169
- /* @__PURE__ */ jsxs3("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 }]), children: [
1170
- /* @__PURE__ */ jsx5(Plus2, { size: 12 }),
1672
+ /* @__PURE__ */ jsxs8("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 }]), children: [
1673
+ /* @__PURE__ */ jsx11(Plus, { size: 12 }),
1171
1674
  " Ajouter une entit\xE9"
1172
1675
  ] })
1173
1676
  ] })
1174
1677
  ] }),
1175
- slackAvailable && /* @__PURE__ */ jsxs3("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"), children: [
1176
- /* @__PURE__ */ jsx5("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) }),
1177
- /* @__PURE__ */ jsxs3("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
1178
- /* @__PURE__ */ jsxs3("span", { className: "text-text flex items-center gap-1.5 text-sm font-medium", children: [
1179
- /* @__PURE__ */ jsx5(Slack, { size: 14, className: "text-primary" }),
1678
+ slackAvailable && /* @__PURE__ */ jsxs8("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"), children: [
1679
+ /* @__PURE__ */ jsx11("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) }),
1680
+ /* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
1681
+ /* @__PURE__ */ jsxs8("span", { className: "text-text flex items-center gap-1.5 text-sm font-medium", children: [
1682
+ /* @__PURE__ */ jsx11(Slack, { size: 14, className: "text-primary" }),
1180
1683
  " Synchroniser avec Slack"
1181
1684
  ] }),
1182
- /* @__PURE__ */ jsx5("span", { className: "text-text-muted text-[11px] leading-snug", children: "Un canal Slack priv\xE9 sera cr\xE9\xE9 et les membres utilisateurs y seront invit\xE9s automatiquement." })
1685
+ /* @__PURE__ */ jsx11("span", { className: "text-text-muted text-[11px] leading-snug", children: "Un canal Slack priv\xE9 sera cr\xE9\xE9 et les membres utilisateurs y seront invit\xE9s automatiquement." })
1183
1686
  ] })
1184
1687
  ] })
1185
1688
  ] }),
1186
- step === 2 && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-5", children: [
1187
- /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
1188
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
1189
- /* @__PURE__ */ jsxs3("label", { className: "text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase", children: [
1190
- /* @__PURE__ */ jsx5(Users2, { size: 14, className: "text-primary" }),
1689
+ step === 2 && /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-5", children: [
1690
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2", children: [
1691
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between", children: [
1692
+ /* @__PURE__ */ jsxs8("label", { className: "text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase", children: [
1693
+ /* @__PURE__ */ jsx11(Users, { size: 14, className: "text-primary" }),
1191
1694
  " Membres Utilisateurs"
1192
1695
  ] }),
1193
- invitedUsers.length > 0 && /* @__PURE__ */ jsxs3("span", { className: "bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold", children: [
1696
+ invitedUsers.length > 0 && /* @__PURE__ */ jsxs8("span", { className: "bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold", children: [
1194
1697
  invitedUsers.length,
1195
1698
  " invit\xE9",
1196
1699
  invitedUsers.length > 1 ? "s" : ""
1197
1700
  ] })
1198
1701
  ] }),
1199
- /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
1200
- /* @__PURE__ */ jsx5("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) }),
1201
- memberSearch.length >= 2 && searchingUsers && /* @__PURE__ */ jsx5("div", { className: "absolute top-1/2 right-3.5 flex -translate-y-1/2 items-center justify-center py-3", children: /* @__PURE__ */ jsx5(Loader22, { size: 16, className: "text-primary animate-spin" }) }),
1202
- filteredUsers.length > 0 && memberSearch.length >= 2 && !searchingUsers && /* @__PURE__ */ jsx5("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", children: filteredUsers.slice(0, 5).map((u) => /* @__PURE__ */ jsxs3("div", { 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"), children: [
1203
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2.5", children: [
1204
- /* @__PURE__ */ jsx5("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", children: getInitials(u.displayName) }),
1205
- /* @__PURE__ */ jsxs3("div", { className: "flex flex-col", children: [
1206
- /* @__PURE__ */ jsx5("span", { className: "text-text font-medium", children: u.displayName }),
1207
- /* @__PURE__ */ jsx5("span", { className: "text-text-muted text-[10px]", children: u.email })
1702
+ /* @__PURE__ */ jsxs8("div", { className: "relative", children: [
1703
+ /* @__PURE__ */ jsx11("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) }),
1704
+ memberSearch.length >= 2 && searchingUsers && /* @__PURE__ */ jsx11("div", { className: "absolute top-1/2 right-3.5 flex -translate-y-1/2 items-center justify-center py-3", children: /* @__PURE__ */ jsx11(Loader22, { size: 16, className: "text-primary animate-spin" }) }),
1705
+ filteredUsers.length > 0 && memberSearch.length >= 2 && !searchingUsers && /* @__PURE__ */ jsx11("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", children: filteredUsers.slice(0, 5).map((u) => /* @__PURE__ */ jsxs8("div", { 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"), children: [
1706
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2.5", children: [
1707
+ /* @__PURE__ */ jsx11("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", children: getInitials(u.displayName) }),
1708
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
1709
+ /* @__PURE__ */ jsx11("span", { className: "text-text font-medium", children: u.displayName }),
1710
+ /* @__PURE__ */ jsx11("span", { className: "text-text-muted text-[10px]", children: u.email })
1208
1711
  ] })
1209
1712
  ] }),
1210
- /* @__PURE__ */ jsx5(Plus2, { size: 14, className: "text-primary/75" })
1713
+ /* @__PURE__ */ jsx11(Plus, { size: 14, className: "text-primary/75" })
1211
1714
  ] }, u.id)) })
1212
1715
  ] }),
1213
- /* @__PURE__ */ jsx5("div", { className: "mt-1 flex flex-col gap-1.5", children: invitedUsers.length === 0 ? /* @__PURE__ */ jsx5("div", { className: "bg-bg/40 border-border/40 flex items-center justify-center rounded-xl border border-dashed py-4 text-center", children: /* @__PURE__ */ jsx5("p", { className: "text-text-muted text-xs italic", children: "Aucun utilisateur invit\xE9 pour le moment." }) }) : invitedUsers.map((m) => /* @__PURE__ */ jsxs3("div", { 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", children: [
1214
- /* @__PURE__ */ jsx5(MemberAvatar, { memberName: m.memberName, memberType: "user", avatarUrl: avatarMap[m.memberId.toLowerCase()], size: "sm", variant: m.role === "owner" ? "owner" : "primary" }),
1215
- /* @__PURE__ */ jsxs3("div", { className: "min-w-0 flex-1", children: [
1216
- /* @__PURE__ */ jsx5("div", { className: "text-text truncate text-xs font-semibold", children: m.memberName }),
1217
- /* @__PURE__ */ jsx5("div", { className: "text-text-muted truncate text-[10px]", children: m.memberId })
1716
+ /* @__PURE__ */ jsx11("div", { className: "mt-1 flex flex-col gap-1.5", children: invitedUsers.length === 0 ? /* @__PURE__ */ jsx11("div", { className: "bg-bg/40 border-border/40 flex items-center justify-center rounded-xl border border-dashed py-4 text-center", children: /* @__PURE__ */ jsx11("p", { className: "text-text-muted text-xs italic", children: "Aucun utilisateur invit\xE9 pour le moment." }) }) : invitedUsers.map((m) => /* @__PURE__ */ jsxs8("div", { 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", children: [
1717
+ /* @__PURE__ */ jsx11(MemberAvatar, { memberName: m.memberName, memberType: "user", avatarUrl: avatarMap[m.memberId.toLowerCase()], size: "sm", variant: m.role === "owner" ? "owner" : "primary" }),
1718
+ /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
1719
+ /* @__PURE__ */ jsx11("div", { className: "text-text truncate text-xs font-semibold", children: m.memberName }),
1720
+ /* @__PURE__ */ jsx11("div", { className: "text-text-muted truncate text-[10px]", children: m.memberId })
1218
1721
  ] }),
1219
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
1220
- /* @__PURE__ */ jsxs3("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)), children: [
1221
- /* @__PURE__ */ jsx5("option", { value: "owner", children: "Propri\xE9taire" }),
1222
- /* @__PURE__ */ jsx5("option", { value: "participant", children: "Participant" }),
1223
- /* @__PURE__ */ jsx5("option", { value: "viewer", children: "Observateur" })
1722
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
1723
+ /* @__PURE__ */ jsxs8("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)), children: [
1724
+ /* @__PURE__ */ jsx11("option", { value: "owner", children: "Propri\xE9taire" }),
1725
+ /* @__PURE__ */ jsx11("option", { value: "participant", children: "Participant" }),
1726
+ /* @__PURE__ */ jsx11("option", { value: "viewer", children: "Observateur" })
1224
1727
  ] }),
1225
- /* @__PURE__ */ jsx5("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), children: /* @__PURE__ */ jsx5(X3, { size: 14 }) })
1728
+ /* @__PURE__ */ jsx11("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), children: /* @__PURE__ */ jsx11(X3, { size: 14 }) })
1226
1729
  ] })
1227
1730
  ] }, m.memberId)) })
1228
1731
  ] }),
1229
- /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
1230
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
1231
- /* @__PURE__ */ jsxs3("label", { className: "text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase", children: [
1232
- /* @__PURE__ */ jsx5(Brain3, { size: 14, className: "text-primary" }),
1732
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2", children: [
1733
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between", children: [
1734
+ /* @__PURE__ */ jsxs8("label", { className: "text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase", children: [
1735
+ /* @__PURE__ */ jsx11(Brain4, { size: 14, className: "text-primary" }),
1233
1736
  " Agents IA"
1234
1737
  ] }),
1235
- /* @__PURE__ */ jsxs3("span", { className: "bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold", children: [
1738
+ /* @__PURE__ */ jsxs8("span", { className: "bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold", children: [
1236
1739
  invitedAgents.length,
1237
1740
  "/",
1238
1741
  agents.length
1239
1742
  ] })
1240
1743
  ] }),
1241
- /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
1242
- /* @__PURE__ */ jsxs3("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(), children: [
1243
- invitedAgents.map((m) => /* @__PURE__ */ jsxs3("span", { 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", children: [
1244
- /* @__PURE__ */ jsx5(Brain3, { size: 10, className: "text-primary/80" }),
1744
+ /* @__PURE__ */ jsxs8("div", { className: "relative", children: [
1745
+ /* @__PURE__ */ jsxs8("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(), children: [
1746
+ invitedAgents.map((m) => /* @__PURE__ */ jsxs8("span", { 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", children: [
1747
+ /* @__PURE__ */ jsx11(Brain4, { size: 10, className: "text-primary/80" }),
1245
1748
  m.memberName,
1246
- /* @__PURE__ */ jsx5("button", { type: "button", className: "hover:bg-primary-light text-primary rounded-md p-0.5 transition-colors", onClick: (e) => {
1749
+ /* @__PURE__ */ jsx11("button", { type: "button", className: "hover:bg-primary-light text-primary rounded-md p-0.5 transition-colors", onClick: (e) => {
1247
1750
  e.stopPropagation();
1248
1751
  removeMember(m.memberId);
1249
- }, children: /* @__PURE__ */ jsx5(X3, { size: 10 }) })
1752
+ }, children: /* @__PURE__ */ jsx11(X3, { size: 10 }) })
1250
1753
  ] }, m.memberId)),
1251
- /* @__PURE__ */ jsx5("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) => {
1754
+ /* @__PURE__ */ jsx11("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) => {
1252
1755
  setAgentSearch(e.target.value);
1253
1756
  setShowAgentDropdown(true);
1254
1757
  }, onFocus: () => {
@@ -1259,61 +1762,61 @@ var CreateWorkspaceModal = ({ open, onClose, onCreated }) => {
1259
1762
  setShowAgentDropdown(false);
1260
1763
  }, 200) })
1261
1764
  ] }),
1262
- showAgentDropdown && /* @__PURE__ */ jsx5("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", children: unselectedAgents.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "text-text-muted p-3 text-center text-xs italic", children: agentSearch.trim().length > 0 ? "Aucun agent ne correspond." : "Tous les agents ont \xE9t\xE9 invit\xE9s." }) : unselectedAgents.map((agent) => /* @__PURE__ */ jsxs3("div", { className: "hover:bg-primary-light/50 flex cursor-pointer items-center justify-between px-3.5 py-2.5 text-xs transition-colors", onClick: () => {
1765
+ showAgentDropdown && /* @__PURE__ */ jsx11("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", children: unselectedAgents.length === 0 ? /* @__PURE__ */ jsx11("p", { className: "text-text-muted p-3 text-center text-xs italic", children: agentSearch.trim().length > 0 ? "Aucun agent ne correspond." : "Tous les agents ont \xE9t\xE9 invit\xE9s." }) : unselectedAgents.map((agent) => /* @__PURE__ */ jsxs8("div", { className: "hover:bg-primary-light/50 flex cursor-pointer items-center justify-between px-3.5 py-2.5 text-xs transition-colors", onClick: () => {
1263
1766
  addMember(agent.agentId, agent.agentName, "agent");
1264
1767
  setAgentSearch("");
1265
1768
  }, children: [
1266
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2.5", children: [
1267
- /* @__PURE__ */ jsx5("span", { className: "bg-surface border-border flex h-7 w-7 items-center justify-center rounded-full border", children: /* @__PURE__ */ jsx5(Brain3, { size: 12, className: "text-primary" }) }),
1268
- /* @__PURE__ */ jsx5("span", { className: "text-text font-medium", children: agent.agentName })
1769
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2.5", children: [
1770
+ /* @__PURE__ */ jsx11("span", { className: "bg-surface border-border flex h-7 w-7 items-center justify-center rounded-full border", children: /* @__PURE__ */ jsx11(Brain4, { size: 12, className: "text-primary" }) }),
1771
+ /* @__PURE__ */ jsx11("span", { className: "text-text font-medium", children: agent.agentName })
1269
1772
  ] }),
1270
- /* @__PURE__ */ jsx5(Plus2, { size: 14, className: "text-primary/75" })
1773
+ /* @__PURE__ */ jsx11(Plus, { size: 14, className: "text-primary/75" })
1271
1774
  ] }, agent.agentId)) })
1272
1775
  ] })
1273
1776
  ] })
1274
1777
  ] }),
1275
- step === 3 && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-3", children: [
1276
- /* @__PURE__ */ jsxs3("div", { className: "bg-bg rounded-xl p-4", children: [
1277
- /* @__PURE__ */ jsx5("div", { className: "mb-3 flex items-center gap-2", children: /* @__PURE__ */ jsxs3("div", { children: [
1278
- /* @__PURE__ */ jsx5("div", { className: "text-text text-sm font-semibold", children: name || "Sans nom" }),
1279
- /* @__PURE__ */ jsxs3("div", { className: "text-text-muted text-xs", children: [
1778
+ step === 3 && /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-3", children: [
1779
+ /* @__PURE__ */ jsxs8("div", { className: "bg-bg rounded-xl p-4", children: [
1780
+ /* @__PURE__ */ jsx11("div", { className: "mb-3 flex items-center gap-2", children: /* @__PURE__ */ jsxs8("div", { children: [
1781
+ /* @__PURE__ */ jsx11("div", { className: "text-text text-sm font-semibold", children: name || "Sans nom" }),
1782
+ /* @__PURE__ */ jsxs8("div", { className: "text-text-muted text-xs", children: [
1280
1783
  selectedType?.name ?? "\u2014",
1281
1784
  " \u2022 ",
1282
1785
  scope || "Sans scope"
1283
1786
  ] })
1284
1787
  ] }) }),
1285
- entities.filter((e) => e.key.trim() && e.value.trim()).length > 0 && /* @__PURE__ */ jsx5("div", { className: "mb-2 flex flex-wrap gap-1", children: entities.filter((e) => e.key.trim() && e.value.trim()).map((e, i) => /* @__PURE__ */ jsxs3("span", { className: "border-border inline-flex items-center gap-1 rounded border px-2 py-0.5 text-xs", children: [
1286
- e.isSecret && /* @__PURE__ */ jsx5(Lock, { size: 10, className: "text-warning shrink-0" }),
1287
- /* @__PURE__ */ jsxs3("span", { className: "text-text-muted mr-1 font-medium", children: [
1788
+ entities.filter((e) => e.key.trim() && e.value.trim()).length > 0 && /* @__PURE__ */ jsx11("div", { className: "mb-2 flex flex-wrap gap-1", children: entities.filter((e) => e.key.trim() && e.value.trim()).map((e, i) => /* @__PURE__ */ jsxs8("span", { className: "border-border inline-flex items-center gap-1 rounded border px-2 py-0.5 text-xs", children: [
1789
+ e.isSecret && /* @__PURE__ */ jsx11(Lock2, { size: 10, className: "text-warning shrink-0" }),
1790
+ /* @__PURE__ */ jsxs8("span", { className: "text-text-muted mr-1 font-medium", children: [
1288
1791
  e.key,
1289
1792
  ":"
1290
1793
  ] }),
1291
- /* @__PURE__ */ jsx5("span", { className: "text-text", children: e.isSecret ? "\u2022\u2022\u2022\u2022\u2022\u2022" : e.value })
1794
+ /* @__PURE__ */ jsx11("span", { className: "text-text", children: e.isSecret ? "\u2022\u2022\u2022\u2022\u2022\u2022" : e.value })
1292
1795
  ] }, i)) }),
1293
- /* @__PURE__ */ jsxs3("div", { className: "text-text-muted flex items-center gap-3 text-xs", children: [
1294
- /* @__PURE__ */ jsxs3("span", { className: "flex items-center gap-1", children: [
1295
- /* @__PURE__ */ jsx5(Users2, { size: 12 }),
1796
+ /* @__PURE__ */ jsxs8("div", { className: "text-text-muted flex items-center gap-3 text-xs", children: [
1797
+ /* @__PURE__ */ jsxs8("span", { className: "flex items-center gap-1", children: [
1798
+ /* @__PURE__ */ jsx11(Users, { size: 12 }),
1296
1799
  " ",
1297
1800
  members.length,
1298
1801
  " membre",
1299
1802
  members.length > 1 ? "s" : ""
1300
1803
  ] }),
1301
- syncWithSlack && /* @__PURE__ */ jsxs3("span", { className: "text-primary flex items-center gap-1 font-medium", children: [
1302
- /* @__PURE__ */ jsx5(Slack, { size: 12 }),
1804
+ syncWithSlack && /* @__PURE__ */ jsxs8("span", { className: "text-primary flex items-center gap-1 font-medium", children: [
1805
+ /* @__PURE__ */ jsx11(Slack, { size: 12 }),
1303
1806
  " Synchronis\xE9 avec Slack"
1304
1807
  ] })
1305
1808
  ] }),
1306
- members.length > 0 && /* @__PURE__ */ jsxs3("div", { className: "border-border/30 mt-3 border-t pt-3", children: [
1307
- /* @__PURE__ */ jsxs3("span", { className: "text-text-muted mb-2 block text-[10px] font-bold tracking-wider uppercase", children: [
1809
+ members.length > 0 && /* @__PURE__ */ jsxs8("div", { className: "border-border/30 mt-3 border-t pt-3", children: [
1810
+ /* @__PURE__ */ jsxs8("span", { className: "text-text-muted mb-2 block text-[10px] font-bold tracking-wider uppercase", children: [
1308
1811
  "Membres et Agents invit\xE9s (",
1309
1812
  members.length,
1310
1813
  ")"
1311
1814
  ] }),
1312
- /* @__PURE__ */ jsx5("div", { className: "flex max-h-40 flex-col gap-1.5 overflow-y-auto pr-1", children: members.map((m) => /* @__PURE__ */ jsxs3("div", { className: "bg-bg-subtle/50 flex items-center gap-2.5 rounded-lg p-2 text-xs", children: [
1313
- /* @__PURE__ */ jsx5(MemberAvatar, { memberName: m.memberName, memberType: m.memberType, avatarUrl: m.memberType === "user" ? avatarMap[m.memberId.toLowerCase()] : void 0, size: "xs", variant: m.role === "owner" ? "owner" : "primary" }),
1314
- /* @__PURE__ */ jsxs3("div", { className: "min-w-0 flex-1", children: [
1315
- /* @__PURE__ */ jsx5("span", { className: "text-text truncate font-medium", children: m.memberName }),
1316
- /* @__PURE__ */ jsxs3("span", { className: "text-text-muted ml-2 text-[10px]", children: [
1815
+ /* @__PURE__ */ jsx11("div", { className: "flex max-h-40 flex-col gap-1.5 overflow-y-auto pr-1", children: members.map((m) => /* @__PURE__ */ jsxs8("div", { className: "bg-bg-subtle/50 flex items-center gap-2.5 rounded-lg p-2 text-xs", children: [
1816
+ /* @__PURE__ */ jsx11(MemberAvatar, { memberName: m.memberName, memberType: m.memberType, avatarUrl: m.memberType === "user" ? avatarMap[m.memberId.toLowerCase()] : void 0, size: "xs", variant: m.role === "owner" ? "owner" : "primary" }),
1817
+ /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
1818
+ /* @__PURE__ */ jsx11("span", { className: "text-text truncate font-medium", children: m.memberName }),
1819
+ /* @__PURE__ */ jsxs8("span", { className: "text-text-muted ml-2 text-[10px]", children: [
1317
1820
  "(",
1318
1821
  m.memberType === "agent" ? "Agent" : m.role === "owner" ? "Propri\xE9taire" : m.role === "viewer" ? "Observateur" : "Participant",
1319
1822
  ")"
@@ -1322,19 +1825,19 @@ var CreateWorkspaceModal = ({ open, onClose, onCreated }) => {
1322
1825
  ] }, m.memberId)) })
1323
1826
  ] })
1324
1827
  ] }),
1325
- error && /* @__PURE__ */ jsx5("div", { className: "bg-danger-light text-danger rounded-lg px-3 py-2 text-xs", children: error })
1828
+ error && /* @__PURE__ */ jsx11("div", { className: "bg-danger-light text-danger rounded-lg px-3 py-2 text-xs", children: error })
1326
1829
  ] })
1327
1830
  ] }),
1328
- /* @__PURE__ */ jsxs3("div", { className: "border-border flex shrink-0 items-center justify-between border-t px-6 py-4", children: [
1329
- /* @__PURE__ */ jsxs3("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, children: [
1330
- /* @__PURE__ */ jsx5(ArrowLeft, { size: 14 }),
1831
+ /* @__PURE__ */ jsxs8("div", { className: "border-border flex shrink-0 items-center justify-between border-t px-6 py-4", children: [
1832
+ /* @__PURE__ */ jsxs8("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, children: [
1833
+ /* @__PURE__ */ jsx11(ArrowLeft, { size: 14 }),
1331
1834
  " Pr\xE9c\xE9dent"
1332
1835
  ] }),
1333
- step < 3 ? /* @__PURE__ */ jsxs3("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(), children: [
1836
+ step < 3 ? /* @__PURE__ */ jsxs8("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(), children: [
1334
1837
  "Suivant ",
1335
- /* @__PURE__ */ jsx5(ArrowRight, { size: 14 })
1336
- ] }) : /* @__PURE__ */ jsxs3("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, children: [
1337
- loading ? /* @__PURE__ */ jsx5(Loader22, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx5(Check2, { size: 14 }),
1838
+ /* @__PURE__ */ jsx11(ArrowRight, { size: 14 })
1839
+ ] }) : /* @__PURE__ */ jsxs8("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, children: [
1840
+ loading ? /* @__PURE__ */ jsx11(Loader22, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx11(Check, { size: 14 }),
1338
1841
  " Cr\xE9er le workspace"
1339
1842
  ] })
1340
1843
  ] })
@@ -1342,9 +1845,9 @@ var CreateWorkspaceModal = ({ open, onClose, onCreated }) => {
1342
1845
  };
1343
1846
 
1344
1847
  // src/components/CreatePrivateWorkspaceModal.tsx
1345
- import { useState as useState4, useEffect as useEffect4, useMemo as useMemo5, useId as useId3, useRef as useRef2 } from "react";
1346
- import { X as X4, Loader2 as Loader23, Lock as Lock2, MessageSquare, Search as Search2 } from "lucide-react";
1347
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1848
+ import { useState as useState4, useEffect as useEffect5, useMemo as useMemo4, useId as useId3, useRef as useRef3 } from "react";
1849
+ import { X as X4, Loader2 as Loader23, Lock as Lock3, MessageSquare as MessageSquare2, Search as Search2 } from "lucide-react";
1850
+ import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
1348
1851
  var CreatePrivateWorkspaceModal = ({ open, onClose, onCreated }) => {
1349
1852
  const titleId = useId3();
1350
1853
  const { config } = useWorkspaceContext();
@@ -1355,8 +1858,8 @@ var CreatePrivateWorkspaceModal = ({ open, onClose, onCreated }) => {
1355
1858
  const [searchResults, setSearchResults] = useState4([]);
1356
1859
  const [searchingUsers, setSearchingUsers] = useState4(false);
1357
1860
  const [selectedUser, setSelectedUser] = useState4(null);
1358
- const searchInputRef = useRef2(null);
1359
- useEffect4(() => {
1861
+ const searchInputRef = useRef3(null);
1862
+ useEffect5(() => {
1360
1863
  if (search.length < 2 || !config.searchUsers) {
1361
1864
  setSearchResults([]);
1362
1865
  return;
@@ -1374,8 +1877,8 @@ var CreatePrivateWorkspaceModal = ({ open, onClose, onCreated }) => {
1374
1877
  cancelled = true;
1375
1878
  };
1376
1879
  }, [search]);
1377
- const filteredUsers = useMemo5(() => searchResults.filter((u) => u.email !== config.currentUserId), [searchResults, config.currentUserId]);
1378
- useEffect4(() => {
1880
+ const filteredUsers = useMemo4(() => searchResults.filter((u) => u.email !== config.currentUserId), [searchResults, config.currentUserId]);
1881
+ useEffect5(() => {
1379
1882
  if (!open) {
1380
1883
  setSearch("");
1381
1884
  setSelectedUser(null);
@@ -1404,59 +1907,405 @@ var CreatePrivateWorkspaceModal = ({ open, onClose, onCreated }) => {
1404
1907
  setLoading(false);
1405
1908
  }
1406
1909
  };
1407
- return /* @__PURE__ */ jsxs4(Modal, { open, 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\xE9e", description: /* @__PURE__ */ jsx6("p", { className: "text-text-muted text-xs", children: "Choisissez un utilisateur pour d\xE9marrer une conversation priv\xE9e." }), headerClassName: "items-center", closeButtonClassName: "text-text-muted hover:text-text transition-colors", titleIcon: /* @__PURE__ */ jsx6("span", { className: "bg-primary-light text-primary flex h-8 w-8 items-center justify-center rounded-lg", children: /* @__PURE__ */ jsx6(Lock2, { size: 16 }) }), children: [
1408
- /* @__PURE__ */ jsxs4("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: [
1409
- selectedUser ? /* @__PURE__ */ jsx6("div", { className: "mb-4", children: /* @__PURE__ */ jsxs4("div", { className: "bg-primary-light/30 border-primary/20 flex items-center gap-3 rounded-xl border p-3", children: [
1410
- /* @__PURE__ */ jsx6(MemberAvatar, { memberName: selectedUser.displayName, memberType: "user", avatarUrl: selectedUser.avatarUrl, size: "md", variant: "primary" }),
1411
- /* @__PURE__ */ jsxs4("div", { className: "min-w-0 flex-1", children: [
1412
- /* @__PURE__ */ jsx6("div", { className: "text-text text-sm font-semibold", children: selectedUser.displayName }),
1413
- /* @__PURE__ */ jsx6("div", { className: "text-text-muted text-xs", children: selectedUser.email })
1910
+ return /* @__PURE__ */ jsxs9(Modal, { open, 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\xE9e", description: /* @__PURE__ */ jsx12("p", { className: "text-text-muted text-xs", children: "Choisissez un utilisateur pour d\xE9marrer une conversation priv\xE9e." }), headerClassName: "items-center", closeButtonClassName: "text-text-muted hover:text-text transition-colors", titleIcon: /* @__PURE__ */ jsx12("span", { className: "bg-primary-light text-primary flex h-8 w-8 items-center justify-center rounded-lg", children: /* @__PURE__ */ jsx12(Lock3, { size: 16 }) }), children: [
1911
+ /* @__PURE__ */ jsxs9("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: [
1912
+ selectedUser ? /* @__PURE__ */ jsx12("div", { className: "mb-4", children: /* @__PURE__ */ jsxs9("div", { className: "bg-primary-light/30 border-primary/20 flex items-center gap-3 rounded-xl border p-3", children: [
1913
+ /* @__PURE__ */ jsx12(MemberAvatar, { memberName: selectedUser.displayName, memberType: "user", avatarUrl: selectedUser.avatarUrl, size: "md", variant: "primary" }),
1914
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
1915
+ /* @__PURE__ */ jsx12("div", { className: "text-text text-sm font-semibold", children: selectedUser.displayName }),
1916
+ /* @__PURE__ */ jsx12("div", { className: "text-text-muted text-xs", children: selectedUser.email })
1414
1917
  ] }),
1415
- /* @__PURE__ */ jsx6("button", { type: "button", className: "text-text-muted hover:text-danger rounded p-1 transition-colors", onClick: () => setSelectedUser(null), children: /* @__PURE__ */ jsx6(X4, { size: 16 }) })
1416
- ] }) }) : /* @__PURE__ */ jsxs4("div", { children: [
1417
- /* @__PURE__ */ jsxs4("div", { className: "relative", children: [
1418
- /* @__PURE__ */ jsx6(Search2, { size: 14, className: "text-text-muted absolute top-1/2 left-3 -translate-y-1/2" }),
1419
- /* @__PURE__ */ jsx6("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) }),
1420
- search.length >= 2 && searchingUsers && /* @__PURE__ */ jsx6("div", { className: "absolute top-1/2 right-3 -translate-y-1/2", children: /* @__PURE__ */ jsx6(Loader23, { size: 16, className: "text-primary animate-spin" }) })
1918
+ /* @__PURE__ */ jsx12("button", { type: "button", className: "text-text-muted hover:text-danger rounded p-1 transition-colors", onClick: () => setSelectedUser(null), children: /* @__PURE__ */ jsx12(X4, { size: 16 }) })
1919
+ ] }) }) : /* @__PURE__ */ jsxs9("div", { children: [
1920
+ /* @__PURE__ */ jsxs9("div", { className: "relative", children: [
1921
+ /* @__PURE__ */ jsx12(Search2, { size: 14, className: "text-text-muted absolute top-1/2 left-3 -translate-y-1/2" }),
1922
+ /* @__PURE__ */ jsx12("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) }),
1923
+ search.length >= 2 && searchingUsers && /* @__PURE__ */ jsx12("div", { className: "absolute top-1/2 right-3 -translate-y-1/2", children: /* @__PURE__ */ jsx12(Loader23, { size: 16, className: "text-primary animate-spin" }) })
1421
1924
  ] }),
1422
- search.length >= 2 && !searchingUsers && filteredUsers.length > 0 && /* @__PURE__ */ jsx6("div", { className: "border-border bg-surface mt-2 flex max-h-48 flex-col overflow-y-auto rounded-xl border shadow-sm", children: filteredUsers.slice(0, 8).map((u) => /* @__PURE__ */ jsxs4("button", { 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: () => {
1925
+ search.length >= 2 && !searchingUsers && filteredUsers.length > 0 && /* @__PURE__ */ jsx12("div", { className: "border-border bg-surface mt-2 flex max-h-48 flex-col overflow-y-auto rounded-xl border shadow-sm", children: filteredUsers.slice(0, 8).map((u) => /* @__PURE__ */ jsxs9("button", { 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: () => {
1423
1926
  setSelectedUser(u);
1424
1927
  setSearch("");
1425
1928
  }, children: [
1426
- /* @__PURE__ */ jsx6("span", { className: "bg-primary-light text-primary flex h-8 w-8 items-center justify-center rounded-full text-xs font-semibold", children: getInitials(u.displayName) }),
1427
- /* @__PURE__ */ jsxs4("div", { className: "min-w-0 flex-1", children: [
1428
- /* @__PURE__ */ jsx6("div", { className: "text-text text-sm font-medium", children: u.displayName }),
1429
- /* @__PURE__ */ jsx6("div", { className: "text-text-muted text-[11px]", children: u.email })
1929
+ /* @__PURE__ */ jsx12("span", { className: "bg-primary-light text-primary flex h-8 w-8 items-center justify-center rounded-full text-xs font-semibold", children: getInitials(u.displayName) }),
1930
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
1931
+ /* @__PURE__ */ jsx12("div", { className: "text-text text-sm font-medium", children: u.displayName }),
1932
+ /* @__PURE__ */ jsx12("div", { className: "text-text-muted text-[11px]", children: u.email })
1430
1933
  ] })
1431
1934
  ] }, u.id)) }),
1432
- search.length >= 2 && !searchingUsers && filteredUsers.length === 0 && /* @__PURE__ */ jsx6("p", { className: "text-text-muted mt-3 text-center text-xs italic", children: "Aucun utilisateur trouv\xE9." }),
1433
- search.length < 2 && /* @__PURE__ */ jsx6("p", { className: "text-text-muted mt-4 text-center text-xs", children: "Saisissez au moins 2 caract\xE8res pour rechercher." })
1935
+ search.length >= 2 && !searchingUsers && filteredUsers.length === 0 && /* @__PURE__ */ jsx12("p", { className: "text-text-muted mt-3 text-center text-xs italic", children: "Aucun utilisateur trouv\xE9." }),
1936
+ search.length < 2 && /* @__PURE__ */ jsx12("p", { className: "text-text-muted mt-4 text-center text-xs", children: "Saisissez au moins 2 caract\xE8res pour rechercher." })
1434
1937
  ] }),
1435
- error && /* @__PURE__ */ jsx6("div", { className: "bg-danger-light text-danger mt-3 rounded-lg px-3 py-2 text-xs", children: error })
1938
+ error && /* @__PURE__ */ jsx12("div", { className: "bg-danger-light text-danger mt-3 rounded-lg px-3 py-2 text-xs", children: error })
1436
1939
  ] }),
1437
- /* @__PURE__ */ jsxs4("div", { className: "border-border flex shrink-0 items-center justify-end gap-2 border-t px-6 py-4", children: [
1438
- /* @__PURE__ */ jsx6("button", { type: "button", className: "text-text-muted hover:text-text text-sm transition-colors", onClick: onClose, disabled: loading, children: "Annuler" }),
1439
- /* @__PURE__ */ jsxs4("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, children: [
1440
- loading ? /* @__PURE__ */ jsx6(Loader23, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx6(MessageSquare, { size: 14 }),
1940
+ /* @__PURE__ */ jsxs9("div", { className: "border-border flex shrink-0 items-center justify-end gap-2 border-t px-6 py-4", children: [
1941
+ /* @__PURE__ */ jsx12("button", { type: "button", className: "text-text-muted hover:text-text text-sm transition-colors", onClick: onClose, disabled: loading, children: "Annuler" }),
1942
+ /* @__PURE__ */ jsxs9("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, children: [
1943
+ loading ? /* @__PURE__ */ jsx12(Loader23, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx12(MessageSquare2, { size: 14 }),
1441
1944
  " D\xE9marrer"
1442
1945
  ] })
1443
1946
  ] })
1444
1947
  ] });
1445
1948
  };
1446
1949
 
1950
+ // src/components/ContextPanel.tsx
1951
+ import { useState as useState5 } from "react";
1952
+ import { Edit2, Check as Check2, X as X5, Brain as Brain5, Plus as Plus2, Trash2 as Trash22, Lock as Lock4, Unlock as Unlock2 } from "lucide-react";
1953
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1954
+ function toEditableEntities(ws) {
1955
+ return (ws.entitiesWithSecrets ?? []).map((e) => ({ key: e.key, value: e.value, isSecret: e.isSecret }));
1956
+ }
1957
+ function getDisplayEntities(ws) {
1958
+ return ws.entitiesWithSecrets ?? [];
1959
+ }
1960
+ var ContextPanel = ({
1961
+ workspace,
1962
+ types = [],
1963
+ onUpdateContext,
1964
+ readonly
1965
+ }) => {
1966
+ const [editing, setEditing] = useState5(false);
1967
+ const [editName, setEditName] = useState5(workspace.name ?? "");
1968
+ const [editType, setEditType] = useState5("");
1969
+ const [editScope, setEditScope] = useState5(workspace.scope ?? "");
1970
+ const [editEntities, setEditEntities] = useState5(toEditableEntities(workspace));
1971
+ const currentTypeId = typeof workspace.type === "object" && workspace.type !== null ? workspace.type._id : workspace.type;
1972
+ const typeName = typeof workspace.type === "object" && workspace.type !== null ? workspace.type.name : workspace.type;
1973
+ const handleEdit = () => {
1974
+ setEditName(workspace.name ?? "");
1975
+ setEditType(currentTypeId ?? "");
1976
+ setEditScope(workspace.scope ?? "");
1977
+ setEditEntities(toEditableEntities(workspace));
1978
+ setEditing(true);
1979
+ };
1980
+ const handleSave = () => {
1981
+ const entitiesWithSecrets = editEntities.filter((e) => e.key.trim()).map((e) => ({ key: e.key.trim(), value: e.value, isSecret: e.isSecret }));
1982
+ onUpdateContext?.({ name: editName.trim() || void 0, type: editType || void 0, scope: editScope, entitiesWithSecrets });
1983
+ setEditing(false);
1984
+ };
1985
+ const handleCancel = () => {
1986
+ setEditName(workspace.name ?? "");
1987
+ setEditType(currentTypeId ?? "");
1988
+ setEditScope(workspace.scope ?? "");
1989
+ setEditEntities(toEditableEntities(workspace));
1990
+ setEditing(false);
1991
+ };
1992
+ const handleTypeChange = (id) => {
1993
+ setEditType(id);
1994
+ const sel = types.find((t) => t._id === id);
1995
+ if (sel?.entitiesWithSecrets?.length) {
1996
+ setEditEntities(sel.entitiesWithSecrets.map((e) => ({ key: e.key, value: e.value, isSecret: e.isSecret })));
1997
+ }
1998
+ };
1999
+ const displayEntities = getDisplayEntities(workspace);
2000
+ return /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-3", children: [
2001
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between", children: [
2002
+ /* @__PURE__ */ jsx13("span", { className: "text-[var(--color-text-muted,#94a3b8)] text-xs font-semibold tracking-wider uppercase", children: "Contexte" }),
2003
+ !editing && !readonly && /* @__PURE__ */ jsxs10("button", { className: "text-[var(--color-text-muted,#94a3b8)] hover:text-[var(--color-primary,#3b82f6)] flex items-center gap-1 text-xs transition-colors", onClick: handleEdit, children: [
2004
+ /* @__PURE__ */ jsx13(Edit2, { size: 11 }),
2005
+ " Modifier"
2006
+ ] })
2007
+ ] }),
2008
+ /* @__PURE__ */ jsxs10("div", { className: "bg-[var(--color-bg,#f8fafc)] flex items-center gap-2 rounded-lg p-2", children: [
2009
+ /* @__PURE__ */ jsx13("span", { className: "text-[var(--color-text-muted,#94a3b8)] text-xs", children: "Nom :" }),
2010
+ editing ? /* @__PURE__ */ jsx13(
2011
+ "input",
2012
+ {
2013
+ className: "border-[var(--color-border,#e2e8f0)] bg-[var(--color-surface,#fff)] text-[var(--color-text,#0f172a)] focus:border-[var(--color-primary,#3b82f6)] w-48 rounded border px-2 py-1 text-xs focus:outline-none",
2014
+ value: editName,
2015
+ onChange: (e) => setEditName(e.target.value),
2016
+ placeholder: "Nom du workspace"
2017
+ }
2018
+ ) : /* @__PURE__ */ jsx13("span", { className: "text-[var(--color-text,#0f172a)] text-sm font-medium", children: workspace.name ?? "\u2014" })
2019
+ ] }),
2020
+ /* @__PURE__ */ jsxs10("div", { className: "bg-[var(--color-bg,#f8fafc)] flex items-center gap-2 rounded-lg p-2", children: [
2021
+ /* @__PURE__ */ jsx13("span", { className: "text-[var(--color-text-muted,#94a3b8)] text-xs", children: "Type :" }),
2022
+ editing && types.length > 0 ? /* @__PURE__ */ jsxs10(
2023
+ "select",
2024
+ {
2025
+ className: "border-[var(--color-border,#e2e8f0)] bg-[var(--color-surface,#fff)] text-[var(--color-text,#0f172a)] focus:border-[var(--color-primary,#3b82f6)] rounded border px-2 py-1 text-xs focus:outline-none",
2026
+ value: editType,
2027
+ onChange: (e) => handleTypeChange(e.target.value),
2028
+ children: [
2029
+ /* @__PURE__ */ jsx13("option", { value: "", children: "\u2014 Aucun \u2014" }),
2030
+ types.map((t) => /* @__PURE__ */ jsx13("option", { value: t._id, children: t.name }, t._id))
2031
+ ]
2032
+ }
2033
+ ) : /* @__PURE__ */ jsx13("span", { className: "text-[var(--color-text,#0f172a)] text-sm font-medium", children: typeName ?? "\u2014" })
2034
+ ] }),
2035
+ /* @__PURE__ */ jsxs10("div", { className: "bg-[var(--color-bg,#f8fafc)] flex items-center gap-2 rounded-lg p-2", children: [
2036
+ /* @__PURE__ */ jsx13("span", { className: "text-[var(--color-text-muted,#94a3b8)] text-xs", children: "Scope :" }),
2037
+ editing ? /* @__PURE__ */ jsx13(
2038
+ "input",
2039
+ {
2040
+ className: "border-[var(--color-border,#e2e8f0)] bg-[var(--color-surface,#fff)] text-[var(--color-text,#0f172a)] focus:border-[var(--color-primary,#3b82f6)] w-36 rounded border px-2 py-1 text-xs focus:outline-none",
2041
+ value: editScope,
2042
+ onChange: (e) => setEditScope(e.target.value),
2043
+ placeholder: "Saisir..."
2044
+ }
2045
+ ) : /* @__PURE__ */ jsx13("span", { className: "text-[var(--color-text,#0f172a)] text-sm font-medium", children: workspace.scope ?? "\u2014" })
2046
+ ] }),
2047
+ /* @__PURE__ */ jsxs10("div", { children: [
2048
+ /* @__PURE__ */ jsx13("span", { className: "text-[var(--color-text-muted,#94a3b8)] text-xs", children: "Entit\xE9s" }),
2049
+ editing ? /* @__PURE__ */ jsxs10("div", { className: "mt-1 flex flex-col gap-1", children: [
2050
+ editEntities.map((e, idx) => /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
2051
+ /* @__PURE__ */ jsx13(
2052
+ "input",
2053
+ {
2054
+ className: "border-[var(--color-border,#e2e8f0)] bg-[var(--color-surface,#fff)] text-[var(--color-text,#0f172a)] focus:border-[var(--color-primary,#3b82f6)] w-20 rounded border px-2 py-1 text-xs focus:outline-none",
2055
+ value: e.key,
2056
+ onChange: (ev) => {
2057
+ const arr = [...editEntities];
2058
+ arr[idx].key = ev.target.value;
2059
+ setEditEntities(arr);
2060
+ },
2061
+ placeholder: "Cl\xE9"
2062
+ }
2063
+ ),
2064
+ /* @__PURE__ */ jsx13(
2065
+ "input",
2066
+ {
2067
+ className: "border-[var(--color-border,#e2e8f0)] bg-[var(--color-surface,#fff)] text-[var(--color-text,#0f172a)] focus:border-[var(--color-primary,#3b82f6)] flex-1 rounded border px-2 py-1 text-xs focus:outline-none",
2068
+ value: e.value,
2069
+ onChange: (ev) => {
2070
+ const arr = [...editEntities];
2071
+ arr[idx].value = ev.target.value;
2072
+ setEditEntities(arr);
2073
+ },
2074
+ placeholder: "Valeur"
2075
+ }
2076
+ ),
2077
+ /* @__PURE__ */ jsx13(
2078
+ "button",
2079
+ {
2080
+ type: "button",
2081
+ className: `rounded p-0.5 transition-colors ${e.isSecret ? "bg-amber-100 text-amber-600 dark:bg-amber-500/10 dark:text-amber-400" : "text-[var(--color-text-muted,#94a3b8)] hover:text-[var(--color-text,#0f172a)] hover:bg-[var(--color-bg,#f8fafc)]"}`,
2082
+ onClick: () => {
2083
+ const arr = [...editEntities];
2084
+ arr[idx].isSecret = !arr[idx].isSecret;
2085
+ setEditEntities(arr);
2086
+ },
2087
+ title: e.isSecret ? "Secret (cliquer pour rendre public)" : "Public (cliquer pour rendre secret)",
2088
+ children: e.isSecret ? /* @__PURE__ */ jsx13(Lock4, { size: 12 }) : /* @__PURE__ */ jsx13(Unlock2, { size: 12 })
2089
+ }
2090
+ ),
2091
+ /* @__PURE__ */ jsx13(
2092
+ "button",
2093
+ {
2094
+ className: "text-red-500 hover:bg-red-50 dark:hover:bg-red-500/10 rounded p-0.5 transition-colors",
2095
+ onClick: () => setEditEntities(editEntities.filter((_, i) => i !== idx)),
2096
+ children: /* @__PURE__ */ jsx13(Trash22, { size: 12 })
2097
+ }
2098
+ )
2099
+ ] }, idx)),
2100
+ /* @__PURE__ */ jsxs10(
2101
+ "button",
2102
+ {
2103
+ className: "text-[var(--color-primary,#3b82f6)] hover:bg-[var(--color-primary-light,#eff6ff)] mt-1 flex items-center gap-1 rounded px-2 py-1 text-xs transition-colors",
2104
+ onClick: () => setEditEntities([...editEntities, { key: "", value: "", isSecret: false }]),
2105
+ children: [
2106
+ /* @__PURE__ */ jsx13(Plus2, { size: 12 }),
2107
+ " Ajouter"
2108
+ ]
2109
+ }
2110
+ )
2111
+ ] }) : /* @__PURE__ */ jsxs10("div", { className: "mt-1 flex flex-wrap gap-1", children: [
2112
+ displayEntities.map((ent) => /* @__PURE__ */ jsxs10("span", { className: "bg-[var(--color-bg,#f8fafc)] border-[var(--color-border,#e2e8f0)] inline-flex items-center gap-1 rounded border px-2 py-0.5 text-xs", children: [
2113
+ ent.isSecret && /* @__PURE__ */ jsx13(Lock4, { size: 10, className: "text-amber-500 shrink-0" }),
2114
+ /* @__PURE__ */ jsxs10("span", { className: "text-[var(--color-text-muted,#94a3b8)] mr-1 font-medium", children: [
2115
+ ent.key,
2116
+ ":"
2117
+ ] }),
2118
+ /* @__PURE__ */ jsx13("span", { className: "text-[var(--color-text,#0f172a)]", children: ent.isSecret ? "\u2022\u2022\u2022\u2022\u2022\u2022" : ent.value })
2119
+ ] }, ent.key)),
2120
+ displayEntities.length === 0 && /* @__PURE__ */ jsx13("span", { className: "text-[var(--color-text-muted,#94a3b8)] text-xs", children: "Aucune entit\xE9" })
2121
+ ] })
2122
+ ] }),
2123
+ editing && /* @__PURE__ */ jsxs10("div", { className: "flex justify-end gap-2", children: [
2124
+ /* @__PURE__ */ jsxs10("button", { className: "text-[var(--color-text-muted,#94a3b8)] hover:text-[var(--color-text,#0f172a)] flex items-center gap-1 text-xs transition-colors", onClick: handleCancel, children: [
2125
+ /* @__PURE__ */ jsx13(X5, { size: 11 }),
2126
+ " Annuler"
2127
+ ] }),
2128
+ /* @__PURE__ */ jsxs10("button", { className: "text-emerald-600 hover:bg-emerald-50 dark:hover:bg-emerald-500/10 flex items-center gap-1 rounded px-2 py-1 text-xs font-medium transition-colors", onClick: handleSave, children: [
2129
+ /* @__PURE__ */ jsx13(Check2, { size: 11 }),
2130
+ " Enregistrer"
2131
+ ] })
2132
+ ] }),
2133
+ /* @__PURE__ */ jsxs10("div", { className: "text-[var(--color-text-muted,#94a3b8)] bg-[var(--color-bg,#f8fafc)] mt-2 flex items-center gap-2 rounded-lg p-2 text-xs italic", children: [
2134
+ /* @__PURE__ */ jsx13(Brain5, { size: 14 }),
2135
+ " Ce contexte est inject\xE9 dans les requ\xEAtes IA (RAG)"
2136
+ ] })
2137
+ ] });
2138
+ };
2139
+
2140
+ // src/components/MembersPanel.tsx
2141
+ import { useState as useState6, useEffect as useEffect6, useMemo as useMemo5 } from "react";
2142
+ import { UserPlus, Crown, Eye, Users as Users2, X as X6, Search as Search3, Plus as Plus3, Brain as Brain6, Loader2 as Loader24, Check as Check3 } from "lucide-react";
2143
+ import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
2144
+ var roleIcon = (role) => {
2145
+ switch (role) {
2146
+ case "owner":
2147
+ return /* @__PURE__ */ jsx14(Crown, { size: 11, className: "text-warning" });
2148
+ case "viewer":
2149
+ return /* @__PURE__ */ jsx14(Eye, { size: 11, className: "text-text-muted" });
2150
+ default:
2151
+ return /* @__PURE__ */ jsx14(Users2, { size: 11, className: "text-primary" });
2152
+ }
2153
+ };
2154
+ var MembersPanel = ({
2155
+ members,
2156
+ avatarUsers,
2157
+ onAddMember,
2158
+ onRemoveMember,
2159
+ onUpdateRole,
2160
+ readonly,
2161
+ hideAgents = false
2162
+ }) => {
2163
+ const { config } = useWorkspaceContext();
2164
+ const apis = useWorkspaceApi();
2165
+ const [showUserSearch, setShowUserSearch] = useState6(false);
2166
+ const [search, setSearch] = useState6("");
2167
+ const [searchResults, setSearchResults] = useState6([]);
2168
+ const [searchingUsers, setSearchingUsers] = useState6(false);
2169
+ const [allAgents, setAllAgents] = useState6([]);
2170
+ useEffect6(() => {
2171
+ apis.agentApi.list().then(setAllAgents).catch(() => setAllAgents([]));
2172
+ }, []);
2173
+ useEffect6(() => {
2174
+ if (search.length < 2 || !showUserSearch || !config.searchUsers) {
2175
+ setSearchResults([]);
2176
+ return;
2177
+ }
2178
+ let cancelled = false;
2179
+ setSearchingUsers(true);
2180
+ config.searchUsers(search).then((results) => {
2181
+ if (!cancelled) setSearchResults(results);
2182
+ }).catch(() => {
2183
+ if (!cancelled) setSearchResults([]);
2184
+ }).finally(() => {
2185
+ if (!cancelled) setSearchingUsers(false);
2186
+ });
2187
+ return () => {
2188
+ cancelled = true;
2189
+ };
2190
+ }, [search, showUserSearch, config.searchUsers]);
2191
+ const filteredUsers = useMemo5(() => {
2192
+ return searchResults.filter(
2193
+ (u) => u.email !== config.currentUserId && !members.some((m) => m.memberId === u.email)
2194
+ );
2195
+ }, [searchResults, members, config.currentUserId]);
2196
+ const userMembers = members.filter((m) => m.memberType === "user");
2197
+ const agentMembers = members.filter((m) => m.memberType === "agent");
2198
+ const agentMemberIds = useMemo5(() => new Set(agentMembers.map((m) => m.memberId)), [agentMembers]);
2199
+ const agentMemberIdMap = useMemo5(() => new Map(agentMembers.map((m) => [m.memberId, m._id])), [agentMembers]);
2200
+ const handleAddUser = (user) => {
2201
+ onAddMember?.({ memberId: user.email, memberName: user.displayName, memberType: "user", role: "participant" });
2202
+ setSearch("");
2203
+ setShowUserSearch(false);
2204
+ };
2205
+ const handleAddAgent = (agent) => {
2206
+ onAddMember?.({ memberId: agent.agentId, memberName: agent.agentName, memberType: "agent", role: "participant" });
2207
+ };
2208
+ return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-4", children: [
2209
+ /* @__PURE__ */ jsxs11("div", { children: [
2210
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between", children: [
2211
+ /* @__PURE__ */ jsxs11("span", { className: "text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase", children: [
2212
+ /* @__PURE__ */ jsx14(Users2, { size: 14, className: "text-primary" }),
2213
+ " Utilisateurs"
2214
+ ] }),
2215
+ /* @__PURE__ */ jsxs11("span", { className: "flex items-center gap-1", children: [
2216
+ /* @__PURE__ */ jsx14("span", { className: "bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold", children: userMembers.length }),
2217
+ !readonly && /* @__PURE__ */ jsxs11("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), children: [
2218
+ /* @__PURE__ */ jsx14(UserPlus, { size: 12 }),
2219
+ " Inviter"
2220
+ ] })
2221
+ ] })
2222
+ ] }),
2223
+ showUserSearch && /* @__PURE__ */ jsxs11(Fragment2, { children: [
2224
+ /* @__PURE__ */ jsxs11("div", { className: "relative mt-2", children: [
2225
+ /* @__PURE__ */ jsx14(Search3, { size: 12, className: "text-text-muted absolute top-1/2 left-2 -translate-y-1/2" }),
2226
+ /* @__PURE__ */ jsx14("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: true })
2227
+ ] }),
2228
+ search.length >= 2 && searchingUsers && /* @__PURE__ */ jsx14("div", { className: "flex items-center justify-center py-3", children: /* @__PURE__ */ jsx14(Loader24, { size: 14, className: "text-primary animate-spin" }) }),
2229
+ filteredUsers.length > 0 && !searchingUsers && /* @__PURE__ */ jsx14("div", { className: "bg-surface border-border mt-1 flex flex-col rounded-lg border shadow-sm", children: filteredUsers.map((u) => /* @__PURE__ */ jsxs11("div", { 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), children: [
2230
+ /* @__PURE__ */ jsx14("span", { className: "bg-primary-light text-primary flex h-6 w-6 items-center justify-center rounded-full text-[10px] font-semibold", children: getInitials(u.displayName) }),
2231
+ /* @__PURE__ */ jsx14("span", { className: "text-text", children: u.displayName }),
2232
+ /* @__PURE__ */ jsx14(Plus3, { size: 12, className: "text-primary ml-auto" })
2233
+ ] }, u.id)) })
2234
+ ] }),
2235
+ /* @__PURE__ */ jsx14("div", { className: "mt-2 flex flex-col gap-1", children: userMembers.map((m) => /* @__PURE__ */ jsxs11("div", { className: "bg-bg group flex items-center gap-2 rounded-lg p-2", children: [
2236
+ /* @__PURE__ */ jsx14(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" }),
2237
+ /* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
2238
+ /* @__PURE__ */ jsx14("div", { className: "text-text truncate text-xs font-medium", children: m.memberName }),
2239
+ /* @__PURE__ */ jsxs11("div", { className: "text-text-muted flex items-center gap-1 text-[10px]", children: [
2240
+ roleIcon(m.role),
2241
+ " ",
2242
+ ROLE_LABELS[m.role] ?? m.role
2243
+ ] })
2244
+ ] }),
2245
+ !(readonly || m.role === "owner" && members.filter((x) => x.role === "owner").length === 1) && /* @__PURE__ */ jsxs11("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) => {
2246
+ e.stopPropagation();
2247
+ onUpdateRole?.(m._id, e.target.value);
2248
+ }, disabled: readonly || m.role === "owner" && members.filter((x) => x.role === "owner").length === 1, children: [
2249
+ /* @__PURE__ */ jsx14("option", { value: "owner", children: "Propri\xE9taire" }),
2250
+ /* @__PURE__ */ jsx14("option", { value: "participant", children: "Participant" }),
2251
+ /* @__PURE__ */ jsx14("option", { value: "viewer", children: "Observateur" })
2252
+ ] }),
2253
+ m.role !== "owner" && !readonly && /* @__PURE__ */ jsx14("button", { className: "text-text-muted hover:text-danger rounded p-0.5 opacity-0 transition-all group-hover:opacity-100", onClick: (e) => {
2254
+ e.stopPropagation();
2255
+ onRemoveMember?.(m._id);
2256
+ }, children: /* @__PURE__ */ jsx14(X6, { size: 14 }) })
2257
+ ] }, m._id)) })
2258
+ ] }),
2259
+ !hideAgents && /* @__PURE__ */ jsxs11("div", { children: [
2260
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between", children: [
2261
+ /* @__PURE__ */ jsxs11("span", { className: "text-text-muted flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase", children: [
2262
+ /* @__PURE__ */ jsx14(Brain6, { size: 14, className: "text-primary" }),
2263
+ " Agents IA"
2264
+ ] }),
2265
+ /* @__PURE__ */ jsxs11("span", { className: "bg-primary-light text-primary rounded-full px-2 py-0.5 text-[10px] font-bold", children: [
2266
+ agentMembers.length,
2267
+ "/",
2268
+ allAgents.length
2269
+ ] })
2270
+ ] }),
2271
+ /* @__PURE__ */ jsx14("div", { className: "mt-2 flex flex-col gap-1", children: allAgents.map((agent) => {
2272
+ const isMember = agentMemberIds.has(agent.agentId);
2273
+ const memberId = agentMemberIdMap.get(agent.agentId);
2274
+ return /* @__PURE__ */ jsxs11("div", { className: "bg-bg group flex items-center gap-2 rounded-lg p-2", children: [
2275
+ /* @__PURE__ */ jsx14("span", { className: "bg-surface border-border flex h-7 w-7 items-center justify-center rounded-full border", children: /* @__PURE__ */ jsx14(Brain6, { size: 14, className: "text-primary" }) }),
2276
+ /* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
2277
+ /* @__PURE__ */ jsx14("div", { className: "text-text truncate text-xs font-medium", children: agent.agentName }),
2278
+ /* @__PURE__ */ jsx14("div", { className: "text-text-muted text-[10px]", children: "Agent IA" })
2279
+ ] }),
2280
+ !readonly && (isMember ? /* @__PURE__ */ jsxs11("button", { className: "relative flex h-6 w-6 items-center justify-center rounded-full transition-colors", onClick: (e) => {
2281
+ e.stopPropagation();
2282
+ if (memberId) onRemoveMember?.(memberId);
2283
+ }, children: [
2284
+ /* @__PURE__ */ jsx14(Check3, { size: 14, className: "text-success absolute transition-opacity group-hover:opacity-0" }),
2285
+ /* @__PURE__ */ jsx14(X6, { size: 14, className: "text-danger absolute opacity-0 transition-opacity group-hover:opacity-100" })
2286
+ ] }) : /* @__PURE__ */ jsx14("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) => {
2287
+ e.stopPropagation();
2288
+ handleAddAgent(agent);
2289
+ }, children: /* @__PURE__ */ jsx14(Plus3, { size: 14 }) }))
2290
+ ] }, agent.agentId);
2291
+ }) })
2292
+ ] })
2293
+ ] });
2294
+ };
2295
+
1447
2296
  // src/components/SyncPanel.tsx
1448
- import { useState as useState5, useEffect as useEffect5, useCallback } from "react";
2297
+ import { useState as useState7, useEffect as useEffect7, useCallback } from "react";
1449
2298
  import {
1450
2299
  RefreshCw,
1451
2300
  ExternalLink,
1452
2301
  Info,
1453
2302
  CheckCircle2,
1454
2303
  XCircle,
1455
- Loader2 as Loader24,
2304
+ Loader2 as Loader25,
1456
2305
  Hash,
1457
- AlertTriangle
2306
+ AlertTriangle as AlertTriangle2
1458
2307
  } from "lucide-react";
1459
- import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
2308
+ import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
1460
2309
  var SLACK_COLOR = "#4A154B";
1461
2310
  var SYNC_INFO = {
1462
2311
  title: "Comment fonctionne la synchronisation ?",
@@ -1483,10 +2332,10 @@ var SyncPanel = ({
1483
2332
  slackConfigured = true,
1484
2333
  onToggleSync
1485
2334
  }) => {
1486
- const [syncStatus, setSyncStatus] = useState5(null);
1487
- const [loading, setLoading] = useState5(true);
1488
- const [toggling, setToggling] = useState5(false);
1489
- const [infoOpen, setInfoOpen] = useState5(false);
2335
+ const [syncStatus, setSyncStatus] = useState7(null);
2336
+ const [loading, setLoading] = useState7(true);
2337
+ const [toggling, setToggling] = useState7(false);
2338
+ const [infoOpen, setInfoOpen] = useState7(false);
1490
2339
  const apis = useWorkspaceApi();
1491
2340
  const fetchSyncStatus = useCallback(async () => {
1492
2341
  try {
@@ -1498,10 +2347,10 @@ var SyncPanel = ({
1498
2347
  setLoading(false);
1499
2348
  }
1500
2349
  }, [workspaceId]);
1501
- useEffect5(() => {
2350
+ useEffect7(() => {
1502
2351
  fetchSyncStatus();
1503
2352
  }, [fetchSyncStatus]);
1504
- useEffect5(() => {
2353
+ useEffect7(() => {
1505
2354
  if (syncStatus) {
1506
2355
  setSyncStatus(
1507
2356
  (prev) => prev ? { ...prev, syncWithSlack: syncWithSlack ?? false } : prev
@@ -1522,126 +2371,126 @@ var SyncPanel = ({
1522
2371
  const slackLink = syncStatus?.links?.find((l) => l.provider === "slack");
1523
2372
  const isSlackActive = syncStatus?.syncWithSlack ?? syncWithSlack ?? false;
1524
2373
  if (loading) {
1525
- return /* @__PURE__ */ jsx7("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx7(Loader24, { size: 20, className: "text-primary animate-spin" }) });
2374
+ return /* @__PURE__ */ jsx15("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx15(Loader25, { size: 20, className: "text-primary animate-spin" }) });
1526
2375
  }
1527
- return /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-4", children: [
1528
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between", children: [
1529
- /* @__PURE__ */ jsx7("span", { className: "text-text-muted text-xs font-semibold tracking-wider uppercase", children: "Synchronisation" }),
1530
- /* @__PURE__ */ jsxs5(
2376
+ return /* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-4", children: [
2377
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between", children: [
2378
+ /* @__PURE__ */ jsx15("span", { className: "text-text-muted text-xs font-semibold tracking-wider uppercase", children: "Synchronisation" }),
2379
+ /* @__PURE__ */ jsxs12(
1531
2380
  "button",
1532
2381
  {
1533
2382
  className: "text-text-muted hover:text-primary flex items-center gap-1 text-xs transition-colors",
1534
2383
  onClick: () => fetchSyncStatus(),
1535
2384
  title: "Rafra\xEEchir",
1536
2385
  children: [
1537
- /* @__PURE__ */ jsx7(RefreshCw, { size: 11 }),
2386
+ /* @__PURE__ */ jsx15(RefreshCw, { size: 11 }),
1538
2387
  " Rafra\xEEchir"
1539
2388
  ]
1540
2389
  }
1541
2390
  )
1542
2391
  ] }),
1543
- /* @__PURE__ */ jsxs5("div", { className: cn("bg-bg border-border rounded-lg border", !slackConfigured && "opacity-60"), children: [
1544
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between p-3", children: [
1545
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2.5", children: [
1546
- /* @__PURE__ */ jsx7(
2392
+ /* @__PURE__ */ jsxs12("div", { className: cn("bg-bg border-border rounded-lg border", !slackConfigured && "opacity-60"), children: [
2393
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between p-3", children: [
2394
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2.5", children: [
2395
+ /* @__PURE__ */ jsx15(
1547
2396
  "div",
1548
2397
  {
1549
2398
  className: "flex h-8 w-8 items-center justify-center rounded-lg",
1550
2399
  style: { backgroundColor: SLACK_COLOR },
1551
- children: /* @__PURE__ */ jsx7(Hash, { size: 16, className: "text-white" })
2400
+ children: /* @__PURE__ */ jsx15(Hash, { size: 16, className: "text-white" })
1552
2401
  }
1553
2402
  ),
1554
- /* @__PURE__ */ jsxs5("div", { children: [
1555
- /* @__PURE__ */ jsxs5("div", { className: "text-text flex items-center gap-1.5 text-sm font-medium", children: [
2403
+ /* @__PURE__ */ jsxs12("div", { children: [
2404
+ /* @__PURE__ */ jsxs12("div", { className: "text-text flex items-center gap-1.5 text-sm font-medium", children: [
1556
2405
  "Slack",
1557
- !slackConfigured ? /* @__PURE__ */ jsx7(XCircle, { size: 14, className: "text-text-muted" }) : isSlackActive ? /* @__PURE__ */ jsx7(CheckCircle2, { size: 14, className: "text-success" }) : /* @__PURE__ */ jsx7(XCircle, { size: 14, className: "text-text-muted" })
2406
+ !slackConfigured ? /* @__PURE__ */ jsx15(XCircle, { size: 14, className: "text-text-muted" }) : isSlackActive ? /* @__PURE__ */ jsx15(CheckCircle2, { size: 14, className: "text-success" }) : /* @__PURE__ */ jsx15(XCircle, { size: 14, className: "text-text-muted" })
1558
2407
  ] }),
1559
- /* @__PURE__ */ jsx7("span", { className: "text-text-muted text-[10px]", children: !slackConfigured ? "Non configur\xE9" : isSlackActive ? "Synchronisation active" : "Non synchronis\xE9" })
2408
+ /* @__PURE__ */ jsx15("span", { className: "text-text-muted text-[10px]", children: !slackConfigured ? "Non configur\xE9" : isSlackActive ? "Synchronisation active" : "Non synchronis\xE9" })
1560
2409
  ] })
1561
2410
  ] }),
1562
- slackConfigured && isOwner && /* @__PURE__ */ jsx7(
2411
+ slackConfigured && isOwner && /* @__PURE__ */ jsx15(
1563
2412
  "button",
1564
2413
  {
1565
2414
  className: `rounded-lg px-3 py-1.5 text-xs font-medium transition-colors ${isSlackActive ? "bg-danger-light text-danger hover:bg-danger/20" : "bg-success-light text-success hover:bg-success/20"}`,
1566
2415
  onClick: () => handleToggle("slack", !isSlackActive),
1567
2416
  disabled: toggling,
1568
- children: toggling ? /* @__PURE__ */ jsx7(Loader24, { size: 12, className: "animate-spin" }) : isSlackActive ? "D\xE9sactiver" : "Activer"
2417
+ children: toggling ? /* @__PURE__ */ jsx15(Loader25, { size: 12, className: "animate-spin" }) : isSlackActive ? "D\xE9sactiver" : "Activer"
1569
2418
  }
1570
2419
  ),
1571
- !slackConfigured && /* @__PURE__ */ jsx7("span", { className: "bg-bg border-border rounded border px-2 py-1 text-[10px] font-medium text-text-muted", children: "Non disponible" })
2420
+ !slackConfigured && /* @__PURE__ */ jsx15("span", { className: "bg-bg border-border rounded border px-2 py-1 text-[10px] font-medium text-text-muted", children: "Non disponible" })
1572
2421
  ] }),
1573
- !slackConfigured && /* @__PURE__ */ jsx7("div", { className: "border-border border-t px-3 py-2.5", children: /* @__PURE__ */ jsxs5("div", { className: "text-text-muted flex items-center gap-2 text-xs", children: [
1574
- /* @__PURE__ */ jsx7(AlertTriangle, { size: 14, className: "flex-shrink-0 text-warning" }),
1575
- /* @__PURE__ */ jsx7("span", { children: "La synchronisation Slack n'est pas configur\xE9e sur le serveur. Contactez un administrateur pour l'activer." })
2422
+ !slackConfigured && /* @__PURE__ */ jsx15("div", { className: "border-border border-t px-3 py-2.5", children: /* @__PURE__ */ jsxs12("div", { className: "text-text-muted flex items-center gap-2 text-xs", children: [
2423
+ /* @__PURE__ */ jsx15(AlertTriangle2, { size: 14, className: "flex-shrink-0 text-warning" }),
2424
+ /* @__PURE__ */ jsx15("span", { children: "La synchronisation Slack n'est pas configur\xE9e sur le serveur. Contactez un administrateur pour l'activer." })
1576
2425
  ] }) }),
1577
- slackConfigured && slackLink && /* @__PURE__ */ jsx7("div", { className: "border-border border-t px-3 py-2.5", children: /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-1.5", children: [
1578
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between", children: [
1579
- /* @__PURE__ */ jsx7("span", { className: "text-text-muted text-[10px] font-medium uppercase tracking-wider", children: "Canal externe" }),
1580
- /* @__PURE__ */ jsx7(ExternalLink, { size: 10, className: "text-text-muted" })
2426
+ slackConfigured && slackLink && /* @__PURE__ */ jsx15("div", { className: "border-border border-t px-3 py-2.5", children: /* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-1.5", children: [
2427
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between", children: [
2428
+ /* @__PURE__ */ jsx15("span", { className: "text-text-muted text-[10px] font-medium uppercase tracking-wider", children: "Canal externe" }),
2429
+ /* @__PURE__ */ jsx15(ExternalLink, { size: 10, className: "text-text-muted" })
1581
2430
  ] }),
1582
- /* @__PURE__ */ jsxs5("div", { className: "bg-surface border-border rounded border p-2", children: [
1583
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 text-xs", children: [
1584
- /* @__PURE__ */ jsx7(Hash, { size: 12, className: "text-text-muted flex-shrink-0" }),
1585
- /* @__PURE__ */ jsx7("span", { className: "text-text font-medium", children: slackLink.externalName || slackLink.externalId })
2431
+ /* @__PURE__ */ jsxs12("div", { className: "bg-surface border-border rounded border p-2", children: [
2432
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 text-xs", children: [
2433
+ /* @__PURE__ */ jsx15(Hash, { size: 12, className: "text-text-muted flex-shrink-0" }),
2434
+ /* @__PURE__ */ jsx15("span", { className: "text-text font-medium", children: slackLink.externalName || slackLink.externalId })
1586
2435
  ] }),
1587
- /* @__PURE__ */ jsxs5("div", { className: "text-text-muted mt-1 flex items-center gap-2 text-[10px]", children: [
1588
- /* @__PURE__ */ jsxs5("span", { children: [
2436
+ /* @__PURE__ */ jsxs12("div", { className: "text-text-muted mt-1 flex items-center gap-2 text-[10px]", children: [
2437
+ /* @__PURE__ */ jsxs12("span", { children: [
1589
2438
  "ID: ",
1590
2439
  slackLink.externalId
1591
2440
  ] }),
1592
- slackLink.externalTeamId && /* @__PURE__ */ jsxs5(Fragment2, { children: [
1593
- /* @__PURE__ */ jsx7("span", { children: "\u2022" }),
1594
- /* @__PURE__ */ jsxs5("span", { children: [
2441
+ slackLink.externalTeamId && /* @__PURE__ */ jsxs12(Fragment3, { children: [
2442
+ /* @__PURE__ */ jsx15("span", { children: "\u2022" }),
2443
+ /* @__PURE__ */ jsxs12("span", { children: [
1595
2444
  "Team: ",
1596
2445
  slackLink.externalTeamId
1597
2446
  ] })
1598
2447
  ] })
1599
2448
  ] }),
1600
- /* @__PURE__ */ jsxs5("div", { className: "text-text-muted mt-1 flex items-center gap-2 text-[10px]", children: [
1601
- /* @__PURE__ */ jsx7(
2449
+ /* @__PURE__ */ jsxs12("div", { className: "text-text-muted mt-1 flex items-center gap-2 text-[10px]", children: [
2450
+ /* @__PURE__ */ jsx15(
1602
2451
  "span",
1603
2452
  {
1604
2453
  className: `inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-[9px] font-medium ${isSlackActive ? "bg-success-light text-success" : "bg-warning-light text-warning"}`,
1605
2454
  children: isSlackActive ? "Sync active" : "Sync en pause"
1606
2455
  }
1607
2456
  ),
1608
- /* @__PURE__ */ jsxs5("span", { children: [
2457
+ /* @__PURE__ */ jsxs12("span", { children: [
1609
2458
  "Cr\xE9\xE9 le",
1610
2459
  " ",
1611
2460
  new Date(slackLink.createdAt).toLocaleDateString("fr-FR")
1612
2461
  ] })
1613
2462
  ] }),
1614
- !isSlackActive && /* @__PURE__ */ jsx7("div", { className: "text-text-muted mt-1.5 text-[10px] italic", children: "Le canal Slack reste ouvert \u2014 seule la synchronisation est en pause." })
2463
+ !isSlackActive && /* @__PURE__ */ jsx15("div", { className: "text-text-muted mt-1.5 text-[10px] italic", children: "Le canal Slack reste ouvert \u2014 seule la synchronisation est en pause." })
1615
2464
  ] })
1616
2465
  ] }) }),
1617
- slackConfigured && isSlackActive && !slackLink && /* @__PURE__ */ jsx7("div", { className: "border-border border-t px-3 py-2.5", children: /* @__PURE__ */ jsxs5("div", { className: "text-warning bg-warning-light flex items-center gap-2 rounded-lg p-2 text-xs", children: [
1618
- /* @__PURE__ */ jsx7(AlertTriangle, { size: 14, className: "flex-shrink-0" }),
1619
- /* @__PURE__ */ jsx7("span", { children: "La synchronisation est activ\xE9e mais aucun canal Slack n'est encore li\xE9. Le canal sera cr\xE9\xE9 automatiquement." })
2466
+ slackConfigured && isSlackActive && !slackLink && /* @__PURE__ */ jsx15("div", { className: "border-border border-t px-3 py-2.5", children: /* @__PURE__ */ jsxs12("div", { className: "text-warning bg-warning-light flex items-center gap-2 rounded-lg p-2 text-xs", children: [
2467
+ /* @__PURE__ */ jsx15(AlertTriangle2, { size: 14, className: "flex-shrink-0" }),
2468
+ /* @__PURE__ */ jsx15("span", { children: "La synchronisation est activ\xE9e mais aucun canal Slack n'est encore li\xE9. Le canal sera cr\xE9\xE9 automatiquement." })
1620
2469
  ] }) })
1621
2470
  ] }),
1622
- /* @__PURE__ */ jsx7("div", { className: "bg-bg border-border rounded-lg border opacity-50", children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between p-3", children: [
1623
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2.5", children: [
1624
- /* @__PURE__ */ jsx7("div", { className: "bg-info flex h-8 w-8 items-center justify-center rounded-lg", children: /* @__PURE__ */ jsx7("span", { className: "text-xs font-bold text-white", children: "T" }) }),
1625
- /* @__PURE__ */ jsxs5("div", { children: [
1626
- /* @__PURE__ */ jsxs5("div", { className: "text-text flex items-center gap-1.5 text-sm font-medium", children: [
2471
+ /* @__PURE__ */ jsx15("div", { className: "bg-bg border-border rounded-lg border opacity-50", children: /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between p-3", children: [
2472
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2.5", children: [
2473
+ /* @__PURE__ */ jsx15("div", { className: "bg-info flex h-8 w-8 items-center justify-center rounded-lg", children: /* @__PURE__ */ jsx15("span", { className: "text-xs font-bold text-white", children: "T" }) }),
2474
+ /* @__PURE__ */ jsxs12("div", { children: [
2475
+ /* @__PURE__ */ jsxs12("div", { className: "text-text flex items-center gap-1.5 text-sm font-medium", children: [
1627
2476
  "Microsoft Teams",
1628
- /* @__PURE__ */ jsx7(XCircle, { size: 14, className: "text-text-muted" })
2477
+ /* @__PURE__ */ jsx15(XCircle, { size: 14, className: "text-text-muted" })
1629
2478
  ] }),
1630
- /* @__PURE__ */ jsx7("span", { className: "text-text-muted text-[10px]", children: "Bient\xF4t disponible" })
2479
+ /* @__PURE__ */ jsx15("span", { className: "text-text-muted text-[10px]", children: "Bient\xF4t disponible" })
1631
2480
  ] })
1632
2481
  ] }),
1633
- /* @__PURE__ */ jsx7("span", { className: "bg-bg border-border rounded border px-2 py-1 text-[10px] font-medium text-text-muted", children: "Prochainement" })
2482
+ /* @__PURE__ */ jsx15("span", { className: "bg-bg border-border rounded border px-2 py-1 text-[10px] font-medium text-text-muted", children: "Prochainement" })
1634
2483
  ] }) }),
1635
- /* @__PURE__ */ jsxs5("div", { className: "bg-bg border-border rounded-lg border", children: [
1636
- /* @__PURE__ */ jsxs5(
2484
+ /* @__PURE__ */ jsxs12("div", { className: "bg-bg border-border rounded-lg border", children: [
2485
+ /* @__PURE__ */ jsxs12(
1637
2486
  "button",
1638
2487
  {
1639
2488
  className: "flex w-full items-center gap-2 p-3 text-left",
1640
2489
  onClick: () => setInfoOpen(!infoOpen),
1641
2490
  children: [
1642
- /* @__PURE__ */ jsx7(Info, { size: 14, className: "text-info flex-shrink-0" }),
1643
- /* @__PURE__ */ jsx7("span", { className: "text-text text-xs font-medium", children: SYNC_INFO.title }),
1644
- /* @__PURE__ */ jsx7(
2491
+ /* @__PURE__ */ jsx15(Info, { size: 14, className: "text-info flex-shrink-0" }),
2492
+ /* @__PURE__ */ jsx15("span", { className: "text-text text-xs font-medium", children: SYNC_INFO.title }),
2493
+ /* @__PURE__ */ jsx15(
1645
2494
  "span",
1646
2495
  {
1647
2496
  className: `text-text-muted ml-auto text-[10px] transition-transform ${infoOpen ? "rotate-180" : ""}`,
@@ -1651,16 +2500,16 @@ var SyncPanel = ({
1651
2500
  ]
1652
2501
  }
1653
2502
  ),
1654
- infoOpen && /* @__PURE__ */ jsxs5("div", { className: "border-border border-t px-3 pb-3 pt-2", children: [
1655
- /* @__PURE__ */ jsx7("p", { className: "text-text-muted mb-3 text-xs leading-relaxed", children: SYNC_INFO.description }),
1656
- /* @__PURE__ */ jsxs5("div", { className: "mb-3", children: [
1657
- /* @__PURE__ */ jsx7("span", { className: "text-text mb-1.5 block text-[10px] font-semibold uppercase tracking-wider", children: "Fonctionnalit\xE9s" }),
1658
- /* @__PURE__ */ jsx7("ul", { className: "flex flex-col gap-1", children: SYNC_INFO.features.map((f, i) => /* @__PURE__ */ jsxs5(
2503
+ infoOpen && /* @__PURE__ */ jsxs12("div", { className: "border-border border-t px-3 pb-3 pt-2", children: [
2504
+ /* @__PURE__ */ jsx15("p", { className: "text-text-muted mb-3 text-xs leading-relaxed", children: SYNC_INFO.description }),
2505
+ /* @__PURE__ */ jsxs12("div", { className: "mb-3", children: [
2506
+ /* @__PURE__ */ jsx15("span", { className: "text-text mb-1.5 block text-[10px] font-semibold uppercase tracking-wider", children: "Fonctionnalit\xE9s" }),
2507
+ /* @__PURE__ */ jsx15("ul", { className: "flex flex-col gap-1", children: SYNC_INFO.features.map((f, i) => /* @__PURE__ */ jsxs12(
1659
2508
  "li",
1660
2509
  {
1661
2510
  className: "text-text-muted flex items-start gap-1.5 text-xs",
1662
2511
  children: [
1663
- /* @__PURE__ */ jsx7(
2512
+ /* @__PURE__ */ jsx15(
1664
2513
  CheckCircle2,
1665
2514
  {
1666
2515
  size: 12,
@@ -1673,15 +2522,15 @@ var SyncPanel = ({
1673
2522
  i
1674
2523
  )) })
1675
2524
  ] }),
1676
- /* @__PURE__ */ jsxs5("div", { children: [
1677
- /* @__PURE__ */ jsx7("span", { className: "text-text mb-1.5 block text-[10px] font-semibold uppercase tracking-wider", children: "Limitations connues" }),
1678
- /* @__PURE__ */ jsx7("ul", { className: "flex flex-col gap-1", children: SYNC_INFO.limitations.map((l, i) => /* @__PURE__ */ jsxs5(
2525
+ /* @__PURE__ */ jsxs12("div", { children: [
2526
+ /* @__PURE__ */ jsx15("span", { className: "text-text mb-1.5 block text-[10px] font-semibold uppercase tracking-wider", children: "Limitations connues" }),
2527
+ /* @__PURE__ */ jsx15("ul", { className: "flex flex-col gap-1", children: SYNC_INFO.limitations.map((l, i) => /* @__PURE__ */ jsxs12(
1679
2528
  "li",
1680
2529
  {
1681
2530
  className: "text-text-muted flex items-start gap-1.5 text-xs",
1682
2531
  children: [
1683
- /* @__PURE__ */ jsx7(
1684
- AlertTriangle,
2532
+ /* @__PURE__ */ jsx15(
2533
+ AlertTriangle2,
1685
2534
  {
1686
2535
  size: 12,
1687
2536
  className: "text-warning mt-0.5 flex-shrink-0"
@@ -1698,145 +2547,1568 @@ var SyncPanel = ({
1698
2547
  ] });
1699
2548
  };
1700
2549
 
1701
- // src/components/Pagination.tsx
2550
+ // src/components/MessageFeed.tsx
2551
+ import { useRef as useRef6, useEffect as useEffect12, useCallback as useCallback2, useState as useState12, useMemo as useMemo7 } from "react";
2552
+ import { Brain as Brain7, Loader2 as Loader28, ArrowDown, ChevronDown as ChevronDown2, ChevronRight as ChevronRight2 } from "lucide-react";
2553
+ import { format, isToday, isYesterday, parseISO } from "date-fns";
2554
+ import { fr } from "date-fns/locale";
2555
+
2556
+ // src/components/MessageItem.tsx
2557
+ import React15, { useState as useState11, useEffect as useEffect11, useRef as useRef5 } from "react";
1702
2558
  import {
1703
- ChevronsLeft,
1704
- ChevronLeft,
1705
- ChevronRight,
1706
- ChevronsRight
2559
+ Paperclip,
2560
+ Eye as Eye2,
2561
+ Download,
2562
+ Trash2 as Trash23,
2563
+ Loader2 as Loader27,
2564
+ FileIcon as FileIcon2,
2565
+ ImageIcon,
2566
+ Reply,
2567
+ MoreVertical,
2568
+ Pencil,
2569
+ SmilePlus,
2570
+ ThumbsUp,
2571
+ ThumbsDown,
2572
+ Heart,
2573
+ Laugh,
2574
+ Frown,
2575
+ CheckCircle2 as CheckCircle22,
2576
+ Pin,
2577
+ PinOff,
2578
+ ChevronDown,
2579
+ ChevronUp
1707
2580
  } from "lucide-react";
1708
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1709
- var NavButton = ({
1710
- onClick,
1711
- disabled,
1712
- children,
1713
- title
1714
- }) => /* @__PURE__ */ jsx8(
1715
- "button",
1716
- {
1717
- onClick,
1718
- disabled,
1719
- title,
1720
- className: cn(
1721
- "flex h-9 w-9 items-center justify-center rounded-lg border text-sm transition-all duration-200",
1722
- disabled ? "border-border-light text-text-placeholder cursor-not-allowed opacity-40" : "border-border bg-surface text-text-secondary hover:bg-primary/8 hover:border-primary/30 hover:text-primary active:scale-95"
1723
- ),
1724
- children
1725
- }
1726
- );
1727
- var Pagination = ({
1728
- currentPage,
1729
- totalPages,
1730
- onPageChange,
1731
- loading = false
1732
- }) => {
1733
- if (totalPages <= 1) return null;
1734
- const getVisiblePages = () => {
1735
- const pages2 = [];
1736
- const maxVisible = 5;
1737
- if (totalPages <= maxVisible + 2) {
1738
- for (let i = 1; i <= totalPages; i++) pages2.push(i);
1739
- return pages2;
2581
+
2582
+ // src/components/ArtefactViewerDialog.tsx
2583
+ import { useState as useState8, useEffect as useEffect8 } from "react";
2584
+ import { Loader2 as Loader26, FileIcon } from "lucide-react";
2585
+ import { Streamdown } from "streamdown";
2586
+ import "streamdown/styles.css";
2587
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
2588
+ function ArtefactViewerDialog({ artefact, onClose }) {
2589
+ const { artefactApi } = useWorkspaceApi();
2590
+ const [url, setUrl] = useState8(null);
2591
+ const [textContent, setTextContent] = useState8(null);
2592
+ const [htmlContent, setHtmlContent] = useState8(null);
2593
+ const [loading, setLoading] = useState8(true);
2594
+ const mimetype = artefact.file?.mimetype ?? "";
2595
+ const fileName = fixMojibake(artefact.file?.originalName ?? "");
2596
+ const isImage = mimetype.startsWith("image/");
2597
+ const isMarkdown = fileName.endsWith(".md") || mimetype === "text/markdown";
2598
+ const isJson = fileName.endsWith(".json") || mimetype === "application/json";
2599
+ const isDocx = fileName.endsWith(".docx") || mimetype === "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
2600
+ const isText = !isMarkdown && !isJson && !isDocx && (mimetype === "text/plain" || mimetype.startsWith("text/"));
2601
+ useEffect8(() => {
2602
+ if (!artefact.file?._id) {
2603
+ setLoading(false);
2604
+ return;
2605
+ }
2606
+ let cancelled = false;
2607
+ setLoading(true);
2608
+ (async () => {
2609
+ try {
2610
+ if (isImage) {
2611
+ const { url: signedUrl } = await artefactApi.getSignedUrl(artefact.file._id);
2612
+ if (!cancelled) setUrl(signedUrl);
2613
+ } else if (isText || isMarkdown || isJson) {
2614
+ const blob = await artefactApi.getDownloadBlob(artefact.file._id);
2615
+ const text = await blob.text();
2616
+ if (!cancelled) setTextContent(text);
2617
+ } else if (isDocx) {
2618
+ const blob = await artefactApi.getDownloadBlob(artefact.file._id);
2619
+ const arrayBuffer = await blob.arrayBuffer();
2620
+ const mammoth = await import("mammoth");
2621
+ const result = await mammoth.convertToHtml({ arrayBuffer });
2622
+ if (!cancelled) setHtmlContent(result.value);
2623
+ }
2624
+ } catch (err) {
2625
+ console.error("Failed to load artefact preview:", err);
2626
+ } finally {
2627
+ if (!cancelled) setLoading(false);
2628
+ }
2629
+ })();
2630
+ return () => {
2631
+ cancelled = true;
2632
+ };
2633
+ }, [artefact.file?._id, isImage, isText, isMarkdown, isJson, isDocx, artefactApi]);
2634
+ return /* @__PURE__ */ jsx16(
2635
+ Modal,
2636
+ {
2637
+ open: true,
2638
+ onClose,
2639
+ size: "full",
2640
+ panelClassName: "bg-[var(--color-surface,#fff)] border-[var(--color-border,#e2e8f0)] flex max-h-[95vh] h-[95vh] w-full flex-col overflow-hidden rounded-2xl border shadow-2xl",
2641
+ className: "p-2 sm:p-4",
2642
+ closeOnBackdropClick: true,
2643
+ title: fileName,
2644
+ titleClassName: "truncate text-sm font-semibold",
2645
+ headerClassName: "items-center px-5 py-3",
2646
+ closeIconSize: 18,
2647
+ children: /* @__PURE__ */ jsx16("div", { className: "flex min-h-0 flex-1 flex-col overflow-auto p-4 sm:p-6", children: loading ? /* @__PURE__ */ jsx16("div", { className: "flex w-full flex-1 items-center justify-center", children: /* @__PURE__ */ jsx16(Loader26, { size: 28, className: "text-[var(--color-primary,#3b82f6)] animate-spin" }) }) : isImage && url ? /* @__PURE__ */ jsx16("div", { className: "flex h-full w-full flex-1 items-center justify-center", children: /* @__PURE__ */ jsx16("img", { src: url, alt: fileName, className: "max-h-full max-w-full rounded-lg object-contain" }) }) : isMarkdown && textContent !== null ? /* @__PURE__ */ jsx16("div", { className: "w-full overflow-auto", children: /* @__PURE__ */ jsx16(Streamdown, { mode: "static", children: textContent }) }) : isJson && textContent !== null ? /* @__PURE__ */ jsx16("pre", { className: "bg-[var(--color-bg,#f8fafc)] text-[var(--color-text,#0f172a)] w-full flex-1 overflow-auto rounded-lg p-6 text-sm leading-relaxed whitespace-pre-wrap", children: (() => {
2648
+ try {
2649
+ return JSON.stringify(JSON.parse(textContent), null, 2);
2650
+ } catch {
2651
+ return textContent;
2652
+ }
2653
+ })() }) : isDocx && htmlContent !== null ? /* @__PURE__ */ jsx16(
2654
+ "div",
2655
+ {
2656
+ className: "bg-[var(--color-bg,#f8fafc)] text-[var(--color-text,#0f172a)] w-full flex-1 overflow-auto rounded-lg p-6 text-sm leading-relaxed",
2657
+ dangerouslySetInnerHTML: { __html: htmlContent }
2658
+ }
2659
+ ) : isText && textContent !== null ? /* @__PURE__ */ jsx16("pre", { className: "bg-[var(--color-bg,#f8fafc)] text-[var(--color-text,#0f172a)] w-full flex-1 overflow-auto rounded-lg p-6 text-sm leading-relaxed whitespace-pre-wrap", children: textContent }) : /* @__PURE__ */ jsxs13("div", { className: "text-[var(--color-text-muted,#94a3b8)] flex w-full flex-1 flex-col items-center justify-center gap-2 py-12 text-center", children: [
2660
+ /* @__PURE__ */ jsx16(FileIcon, { size: 48, className: "opacity-30" }),
2661
+ /* @__PURE__ */ jsx16("p", { className: "text-sm", children: "Aper\xE7u non disponible pour ce type de fichier" }),
2662
+ /* @__PURE__ */ jsx16("p", { className: "text-[10px]", children: mimetype })
2663
+ ] }) })
2664
+ }
2665
+ );
2666
+ }
2667
+
2668
+ // src/components/MessageItem.tsx
2669
+ import { Streamdown as Streamdown2 } from "streamdown";
2670
+ import { cjk } from "@streamdown/cjk";
2671
+ import { createCodePlugin } from "@streamdown/code";
2672
+ import { math } from "@streamdown/math";
2673
+ import { mermaid } from "@streamdown/mermaid";
2674
+ import "katex/dist/katex.min.css";
2675
+ import "streamdown/styles.css";
2676
+
2677
+ // src/components/streamdownCustomComponents.tsx
2678
+ import React14 from "react";
2679
+
2680
+ // src/components/ChartRenderer.tsx
2681
+ import React12, { useEffect as useEffect9, useMemo as useMemo6, useRef as useRef4, useState as useState9 } from "react";
2682
+ import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
2683
+ var ChartJS = null;
2684
+ var loadChartJS = async () => {
2685
+ if (ChartJS) return ChartJS;
2686
+ const mod = await import("chart.js");
2687
+ ChartJS = mod.Chart;
2688
+ ChartJS.register(...mod.registerables);
2689
+ return ChartJS;
2690
+ };
2691
+ var ChartRenderer = React12.memo(({ chartConfig }) => {
2692
+ const containerRef = useRef4(null);
2693
+ const chartInstanceRef = useRef4(null);
2694
+ const [isLoading, setIsLoading] = useState9(true);
2695
+ const [error, setError] = useState9(null);
2696
+ const [canvasKey, setCanvasKey] = useState9(() => `canvas-${Date.now()}-${Math.random().toString(16).slice(2)}`);
2697
+ const chartData = useMemo6(() => chartConfig.chartConfig.data, [chartConfig]);
2698
+ const chartOptions = useMemo6(() => ({
2699
+ ...chartConfig.chartConfig.options,
2700
+ responsive: true,
2701
+ maintainAspectRatio: false,
2702
+ animation: { duration: 0 },
2703
+ interaction: { intersect: false, mode: "index" },
2704
+ plugins: {
2705
+ ...chartConfig.chartConfig.options?.plugins,
2706
+ legend: { ...chartConfig.chartConfig.options?.plugins?.legend, labels: { usePointStyle: true, padding: 15, font: { size: 12 } } }
2707
+ }
2708
+ }), [chartConfig]);
2709
+ useEffect9(() => {
2710
+ const timer = setTimeout(async () => {
2711
+ try {
2712
+ setIsLoading(true);
2713
+ setError(null);
2714
+ if (chartInstanceRef.current) {
2715
+ try {
2716
+ chartInstanceRef.current.destroy();
2717
+ } catch {
2718
+ }
2719
+ chartInstanceRef.current = null;
2720
+ }
2721
+ setCanvasKey(`canvas-${Date.now()}-${Math.random().toString(16).slice(2)}`);
2722
+ await new Promise((r) => setTimeout(r, 50));
2723
+ const CJS = await loadChartJS();
2724
+ if (containerRef.current) {
2725
+ const canvas = containerRef.current.querySelector("canvas");
2726
+ if (canvas) {
2727
+ const existing = CJS.getChart(canvas);
2728
+ if (existing) existing.destroy();
2729
+ const ctx = canvas.getContext("2d");
2730
+ if (ctx) {
2731
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
2732
+ chartInstanceRef.current = new CJS(ctx, { type: chartConfig.chartConfig.type, data: chartData, options: chartOptions });
2733
+ setIsLoading(false);
2734
+ }
2735
+ }
2736
+ }
2737
+ } catch (err) {
2738
+ setError("\xC9chec du graphique : " + (err.message || "Erreur inconnue"));
2739
+ setIsLoading(false);
2740
+ }
2741
+ }, 10);
2742
+ return () => {
2743
+ clearTimeout(timer);
2744
+ if (chartInstanceRef.current) {
2745
+ try {
2746
+ chartInstanceRef.current.destroy();
2747
+ } catch {
2748
+ }
2749
+ chartInstanceRef.current = null;
2750
+ }
2751
+ };
2752
+ }, [chartConfig, chartData, chartOptions]);
2753
+ if (error) return /* @__PURE__ */ jsxs14("div", { className: "my-4 rounded-lg border px-4 py-3 text-sm", style: { borderColor: "#ef4444", backgroundColor: "rgba(239,68,68,0.08)", color: "#b91c1c" }, children: [
2754
+ /* @__PURE__ */ jsx17("strong", { className: "mb-1 block", children: "Erreur de graphique" }),
2755
+ error
2756
+ ] });
2757
+ return /* @__PURE__ */ jsx17("div", { className: "my-4 w-full", style: { height: 500, position: "relative" }, children: /* @__PURE__ */ jsxs14("div", { ref: containerRef, className: "relative h-[calc(100%-40px)] p-2", children: [
2758
+ isLoading && /* @__PURE__ */ jsx17("div", { className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-sm", style: { color: "var(--color-text-secondary,#64748b)" }, children: "Chargement du graphique..." }),
2759
+ /* @__PURE__ */ jsx17("canvas", { style: { width: "100%", height: "100%", display: isLoading ? "none" : "block" } }, canvasKey)
2760
+ ] }) });
2761
+ });
2762
+ ChartRenderer.displayName = "ChartRenderer";
2763
+
2764
+ // src/components/TableRenderer.tsx
2765
+ import React13, { useEffect as useEffect10, useState as useState10 } from "react";
2766
+ import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
2767
+ var TableRenderer = React13.memo(({ tableConfig }) => {
2768
+ const [error, setError] = useState10(null);
2769
+ useEffect10(() => {
2770
+ try {
2771
+ if (!tableConfig.headers || !Array.isArray(tableConfig.headers)) throw new Error("Headers must be an array");
2772
+ if (!tableConfig.rows || !Array.isArray(tableConfig.rows)) throw new Error("Rows must be an array");
2773
+ setError(null);
2774
+ } catch (err) {
2775
+ setError(err.message || "Configuration de tableau invalide");
2776
+ }
2777
+ }, [tableConfig]);
2778
+ if (error) return /* @__PURE__ */ jsxs15("div", { className: "my-4 rounded-lg border px-4 py-3 text-sm", style: { borderColor: "#ef4444", backgroundColor: "rgba(239,68,68,0.08)", color: "#b91c1c" }, children: [
2779
+ /* @__PURE__ */ jsx18("strong", { className: "mb-1 block", children: "Erreur de tableau" }),
2780
+ error
2781
+ ] });
2782
+ return /* @__PURE__ */ jsxs15("div", { className: "my-4 w-full overflow-x-auto rounded-lg border", style: { backgroundColor: "var(--color-surface,#fff)", borderColor: "var(--color-border,#e2e8f0)" }, children: [
2783
+ tableConfig.caption && /* @__PURE__ */ jsx18("p", { className: "mb-3 text-center text-sm font-semibold", style: { color: "var(--color-text,#0f172a)" }, children: tableConfig.caption }),
2784
+ /* @__PURE__ */ jsxs15("table", { className: "min-w-full border-collapse text-sm", children: [
2785
+ /* @__PURE__ */ jsx18("thead", { children: /* @__PURE__ */ jsx18("tr", { children: tableConfig.headers.map((header, i) => /* @__PURE__ */ jsx18(
2786
+ "th",
2787
+ {
2788
+ className: "border-b px-3 py-2 text-left text-xs font-semibold tracking-wide uppercase",
2789
+ style: { backgroundColor: "var(--color-bg,#f8fafc)", borderColor: "var(--color-border,#e2e8f0)", color: "var(--color-text-secondary,#475569)", whiteSpace: "nowrap" },
2790
+ children: header
2791
+ },
2792
+ i
2793
+ )) }) }),
2794
+ /* @__PURE__ */ jsx18("tbody", { children: tableConfig.rows.map((row, rowIdx) => /* @__PURE__ */ jsx18("tr", { style: { backgroundColor: rowIdx % 2 === 1 ? "var(--color-bg,#f8fafc)" : void 0 }, children: row.map((cell, cellIdx) => /* @__PURE__ */ jsx18(
2795
+ "td",
2796
+ {
2797
+ className: "border-b px-3 py-2 align-top",
2798
+ style: { borderColor: "var(--color-border,#e2e8f0)", maxWidth: "260px", wordBreak: "break-word", color: "var(--color-text,#0f172a)" },
2799
+ children: String(cell)
2800
+ },
2801
+ cellIdx
2802
+ )) }, rowIdx)) })
2803
+ ] })
2804
+ ] });
2805
+ });
2806
+ TableRenderer.displayName = "TableRenderer";
2807
+
2808
+ // src/components/streamdownCustomComponents.tsx
2809
+ import { jsx as jsx19 } from "react/jsx-runtime";
2810
+ var CUSTOM_LANGUAGES = /* @__PURE__ */ new Set(["chart", "tabledata", "optionsblock", "table"]);
2811
+ var workspaceStreamdownComponents = {
2812
+ pre: ({ children }) => {
2813
+ const codeChild = React14.Children.toArray(children)[0];
2814
+ if (codeChild && typeof codeChild === "object" && "props" in codeChild) {
2815
+ const codeProps = codeChild.props || {};
2816
+ const className = codeProps.className || "";
2817
+ const match = /language-(\w+)/.exec(className);
2818
+ const language = match ? match[1] : "";
2819
+ const codeContent = codeProps.children;
2820
+ if (language === "chart" && codeContent) {
2821
+ try {
2822
+ const cfg = JSON.parse(String(codeContent).replace(/\n$/, ""));
2823
+ if (cfg.type === "chartjs" && cfg.chartConfig) return /* @__PURE__ */ jsx19(ChartRenderer, { chartConfig: cfg });
2824
+ } catch {
2825
+ return /* @__PURE__ */ jsx19("pre", { children });
2826
+ }
2827
+ }
2828
+ if (language === "tabledata" && codeContent) {
2829
+ try {
2830
+ const cfg = JSON.parse(String(codeContent).replace(/\n$/, ""));
2831
+ return /* @__PURE__ */ jsx19(TableRenderer, { tableConfig: cfg });
2832
+ } catch {
2833
+ return /* @__PURE__ */ jsx19("pre", { children });
2834
+ }
2835
+ }
2836
+ if (CUSTOM_LANGUAGES.has(language)) return /* @__PURE__ */ jsx19("pre", { children });
2837
+ if (React14.isValidElement(codeChild)) {
2838
+ return React14.cloneElement(codeChild, { "data-block": true });
2839
+ }
2840
+ }
2841
+ return children;
2842
+ }
2843
+ };
2844
+
2845
+ // src/components/MessageItem.tsx
2846
+ import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
2847
+ var MAX_LINES = 12;
2848
+ var COLLAPSED_MAX_HEIGHT = MAX_LINES * 23 + 20;
2849
+ var MAX_VISIBLE_ARTEFACTS = 3;
2850
+ var REACTION_OPTIONS = [
2851
+ { key: "like", emoji: "\u{1F44D}", label: "J\u2019aime", icon: ThumbsUp },
2852
+ { key: "dislike", emoji: "\u{1F44E}", label: "Pas d\u2019accord", icon: ThumbsDown },
2853
+ { key: "heart", emoji: "\u2764\uFE0F", label: "J\u2019adore", icon: Heart },
2854
+ { key: "laugh", emoji: "\u{1F602}", label: "Dr\xF4le", icon: Laugh },
2855
+ { key: "sad", emoji: "\u{1F622}", label: "Triste", icon: Frown },
2856
+ { key: "check", emoji: "\u2705", label: "Fait", icon: CheckCircle22 }
2857
+ ];
2858
+ var REACTION_EMOJI_MAP = Object.fromEntries(
2859
+ REACTION_OPTIONS.map((r) => [r.key, r.emoji])
2860
+ );
2861
+ function preprocessMentions(content, members) {
2862
+ let result = content;
2863
+ const globalMentions = ["@Tous le monde et agents", "@Tous le monde"];
2864
+ for (const token of globalMentions) {
2865
+ const escaped = token.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2866
+ const regex = new RegExp(`(${escaped})`, "gi");
2867
+ result = result.replace(regex, "**$1**");
2868
+ }
2869
+ if (!members.length) return result;
2870
+ const sorted = [...members].sort(
2871
+ (a, b) => b.memberName.length - a.memberName.length
2872
+ );
2873
+ for (const member of sorted) {
2874
+ const mentionByName = `@${member.memberName}`;
2875
+ const mentionById = `@${member.memberId}`;
2876
+ const escapedName = mentionByName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2877
+ const escapedId = mentionById.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2878
+ const regex = new RegExp(`(${escapedName}|${escapedId})`, "gi");
2879
+ result = result.replace(regex, "**$1**");
2880
+ }
2881
+ return result;
2882
+ }
2883
+ function formatTime(iso) {
2884
+ return new Date(iso).toLocaleTimeString("fr-FR", {
2885
+ hour: "2-digit",
2886
+ minute: "2-digit"
2887
+ });
2888
+ }
2889
+ function InlineImagePreview({ artefact }) {
2890
+ const { artefactApi } = useWorkspaceApi();
2891
+ const [url, setUrl] = useState11(null);
2892
+ const [loading, setLoading] = useState11(true);
2893
+ useEffect11(() => {
2894
+ let cancelled = false;
2895
+ artefactApi.getSignedUrl(artefact.file._id).then(({ url: signedUrl }) => {
2896
+ if (!cancelled) setUrl(signedUrl);
2897
+ }).catch(() => {
2898
+ }).finally(() => {
2899
+ if (!cancelled) setLoading(false);
2900
+ });
2901
+ return () => {
2902
+ cancelled = true;
2903
+ };
2904
+ }, [artefact.file._id, artefactApi]);
2905
+ if (loading) {
2906
+ return /* @__PURE__ */ jsx20("div", { className: "bg-bg flex h-32 w-full items-center justify-center rounded-lg", children: /* @__PURE__ */ jsx20(Loader27, { size: 16, className: "text-text-muted animate-spin" }) });
2907
+ }
2908
+ if (!url) {
2909
+ return /* @__PURE__ */ jsxs16("div", { className: "bg-bg flex h-24 w-full items-center justify-center gap-2 rounded-lg", children: [
2910
+ /* @__PURE__ */ jsx20(ImageIcon, { size: 16, className: "text-text-muted" }),
2911
+ /* @__PURE__ */ jsx20("span", { className: "text-text-muted text-xs", children: "Image indisponible" })
2912
+ ] });
2913
+ }
2914
+ return (
2915
+ // eslint-disable-next-line @next/next/no-img-element
2916
+ /* @__PURE__ */ jsx20(
2917
+ "img",
2918
+ {
2919
+ src: url,
2920
+ alt: fixMojibake(artefact.file.originalName),
2921
+ className: "max-h-48 w-full rounded-lg object-contain"
2922
+ }
2923
+ )
2924
+ );
2925
+ }
2926
+ function ArtefactCard({
2927
+ artefact,
2928
+ isUserMessage,
2929
+ workspaceId,
2930
+ onView,
2931
+ onDeleted,
2932
+ canDelete = false
2933
+ }) {
2934
+ const { artefactApi } = useWorkspaceApi();
2935
+ const isImage = artefact.file.mimetype.startsWith("image/");
2936
+ const [confirmOpen, setConfirmOpen] = useState11(false);
2937
+ const handleDownload = async (e) => {
2938
+ e.stopPropagation();
2939
+ try {
2940
+ const blob = await artefactApi.getDownloadBlob(artefact.file._id);
2941
+ const blobUrl = URL.createObjectURL(blob);
2942
+ const a = document.createElement("a");
2943
+ a.href = blobUrl;
2944
+ a.download = fixMojibake(artefact.file.originalName);
2945
+ document.body.appendChild(a);
2946
+ a.click();
2947
+ a.remove();
2948
+ URL.revokeObjectURL(blobUrl);
2949
+ } catch (err) {
2950
+ console.error("Download failed:", err);
1740
2951
  }
1741
- pages2.push(1);
1742
- const start = Math.max(2, currentPage - 1);
1743
- const end = Math.min(totalPages - 1, currentPage + 1);
1744
- if (start > 2) pages2.push("ellipsis");
1745
- for (let i = start; i <= end; i++) pages2.push(i);
1746
- if (end < totalPages - 1) pages2.push("ellipsis");
1747
- pages2.push(totalPages);
1748
- return pages2;
1749
2952
  };
1750
- const pages = getVisiblePages();
1751
- return /* @__PURE__ */ jsxs6("div", { className: "mt-6 flex items-center justify-center gap-1.5", children: [
1752
- /* @__PURE__ */ jsx8(
1753
- NavButton,
2953
+ const handleDeleteConfirmed = async () => {
2954
+ if (!workspaceId) return;
2955
+ try {
2956
+ await artefactApi.delete(workspaceId, artefact._id);
2957
+ onDeleted?.(artefact._id);
2958
+ } catch (err) {
2959
+ console.error("Delete failed:", err);
2960
+ }
2961
+ };
2962
+ return /* @__PURE__ */ jsxs16(Fragment4, { children: [
2963
+ /* @__PURE__ */ jsxs16(
2964
+ "div",
1754
2965
  {
1755
- onClick: () => onPageChange(1),
1756
- disabled: currentPage === 1 || loading,
1757
- title: "Premi\xE8re page",
1758
- children: /* @__PURE__ */ jsx8(ChevronsLeft, { size: 16 })
2966
+ className: cn(
2967
+ "group/art flex flex-col overflow-hidden rounded-xl border transition-shadow hover:shadow-md",
2968
+ isUserMessage ? "border-white/20 bg-white/10" : "border-border bg-bg"
2969
+ ),
2970
+ children: [
2971
+ isImage && /* @__PURE__ */ jsx20("div", { className: "cursor-pointer", onClick: onView, children: /* @__PURE__ */ jsx20(InlineImagePreview, { artefact }) }),
2972
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 px-3 py-2", children: [
2973
+ /* @__PURE__ */ jsx20(
2974
+ "div",
2975
+ {
2976
+ className: cn(
2977
+ "flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-lg",
2978
+ isUserMessage ? "bg-white/15" : "bg-primary-light"
2979
+ ),
2980
+ children: isImage ? /* @__PURE__ */ jsx20(
2981
+ ImageIcon,
2982
+ {
2983
+ size: 14,
2984
+ className: isUserMessage ? "text-white/80" : "text-primary"
2985
+ }
2986
+ ) : /* @__PURE__ */ jsx20(
2987
+ FileIcon2,
2988
+ {
2989
+ size: 14,
2990
+ className: isUserMessage ? "text-white/80" : "text-primary"
2991
+ }
2992
+ )
2993
+ }
2994
+ ),
2995
+ /* @__PURE__ */ jsxs16("div", { className: "min-w-0 flex-1", children: [
2996
+ /* @__PURE__ */ jsx20(
2997
+ "div",
2998
+ {
2999
+ className: cn(
3000
+ "truncate text-xs font-medium",
3001
+ isUserMessage ? "text-white" : "text-text"
3002
+ ),
3003
+ children: fixMojibake(artefact.file.originalName)
3004
+ }
3005
+ ),
3006
+ artefact.file.size > 0 && /* @__PURE__ */ jsx20(
3007
+ "div",
3008
+ {
3009
+ className: cn(
3010
+ "text-[10px]",
3011
+ isUserMessage ? "text-white/60" : "text-text-muted"
3012
+ ),
3013
+ children: artefact.file.size > 1024 * 1024 ? `${(artefact.file.size / (1024 * 1024)).toFixed(1)} MB` : `${(artefact.file.size / 1024).toFixed(0)} KB`
3014
+ }
3015
+ )
3016
+ ] }),
3017
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-0.5 opacity-0 transition-opacity group-hover/art:opacity-100", children: [
3018
+ /* @__PURE__ */ jsx20(
3019
+ "button",
3020
+ {
3021
+ onClick: (e) => {
3022
+ e.stopPropagation();
3023
+ onView();
3024
+ },
3025
+ className: cn(
3026
+ "rounded-md p-1.5 transition-colors",
3027
+ isUserMessage ? "text-white/70 hover:bg-white/15 hover:text-white" : "text-info hover:bg-info-light"
3028
+ ),
3029
+ title: "Visualiser",
3030
+ children: /* @__PURE__ */ jsx20(Eye2, { size: 13 })
3031
+ }
3032
+ ),
3033
+ /* @__PURE__ */ jsx20(
3034
+ "button",
3035
+ {
3036
+ onClick: handleDownload,
3037
+ className: cn(
3038
+ "rounded-md p-1.5 transition-colors",
3039
+ isUserMessage ? "text-white/70 hover:bg-white/15 hover:text-white" : "text-primary hover:bg-primary-light"
3040
+ ),
3041
+ title: "T\xE9l\xE9charger",
3042
+ children: /* @__PURE__ */ jsx20(Download, { size: 13 })
3043
+ }
3044
+ ),
3045
+ workspaceId && canDelete && /* @__PURE__ */ jsx20(
3046
+ "button",
3047
+ {
3048
+ onClick: (e) => {
3049
+ e.stopPropagation();
3050
+ setConfirmOpen(true);
3051
+ },
3052
+ className: cn(
3053
+ "rounded-md p-1.5 transition-colors",
3054
+ isUserMessage ? "text-white/70 hover:bg-white/15 hover:text-white" : "text-danger hover:bg-danger-light"
3055
+ ),
3056
+ title: "Supprimer",
3057
+ children: /* @__PURE__ */ jsx20(Trash23, { size: 13 })
3058
+ }
3059
+ )
3060
+ ] })
3061
+ ] })
3062
+ ]
1759
3063
  }
1760
3064
  ),
1761
- /* @__PURE__ */ jsx8(
1762
- NavButton,
3065
+ /* @__PURE__ */ jsx20(
3066
+ ConfirmModal,
1763
3067
  {
1764
- onClick: () => onPageChange(currentPage - 1),
1765
- disabled: currentPage === 1 || loading,
1766
- title: "Page pr\xE9c\xE9dente",
1767
- children: /* @__PURE__ */ jsx8(ChevronLeft, { size: 16 })
3068
+ open: confirmOpen,
3069
+ onClose: () => setConfirmOpen(false),
3070
+ onConfirm: handleDeleteConfirmed,
3071
+ title: "Supprimer l'artefact",
3072
+ description: /* @__PURE__ */ jsxs16(Fragment4, { children: [
3073
+ "Voulez-vous vraiment supprimer",
3074
+ " ",
3075
+ /* @__PURE__ */ jsx20("strong", { children: fixMojibake(artefact.file.originalName) }),
3076
+ " ? Cette action est irr\xE9versible."
3077
+ ] }),
3078
+ confirmText: "Supprimer",
3079
+ danger: true
3080
+ }
3081
+ )
3082
+ ] });
3083
+ }
3084
+ function MessageActionsMenu({
3085
+ isUser,
3086
+ onEdit,
3087
+ onDelete
3088
+ }) {
3089
+ const [open, setOpen] = useState11(false);
3090
+ const menuRef = useRef5(null);
3091
+ useEffect11(() => {
3092
+ if (!open) return;
3093
+ const handler = (e) => {
3094
+ if (menuRef.current && !menuRef.current.contains(e.target)) {
3095
+ setOpen(false);
3096
+ }
3097
+ };
3098
+ document.addEventListener("mousedown", handler);
3099
+ return () => document.removeEventListener("mousedown", handler);
3100
+ }, [open]);
3101
+ return /* @__PURE__ */ jsxs16("div", { className: "relative", ref: menuRef, children: [
3102
+ /* @__PURE__ */ jsx20(
3103
+ "button",
3104
+ {
3105
+ onClick: (e) => {
3106
+ e.stopPropagation();
3107
+ setOpen((v) => !v);
3108
+ },
3109
+ className: cn(
3110
+ "rounded-full p-1 shadow-sm transition-all",
3111
+ "bg-surface border-border text-text-muted hover:text-text border"
3112
+ ),
3113
+ title: "Actions",
3114
+ children: /* @__PURE__ */ jsx20(MoreVertical, { size: 14 })
1768
3115
  }
1769
3116
  ),
1770
- pages.map(
1771
- (p, idx) => p === "ellipsis" ? /* @__PURE__ */ jsx8(
1772
- "span",
1773
- {
1774
- className: "text-text-muted flex h-9 w-9 items-center justify-center text-sm",
1775
- children: "\u2026"
3117
+ open && /* @__PURE__ */ jsxs16(
3118
+ "div",
3119
+ {
3120
+ className: cn(
3121
+ "bg-surface border-border absolute z-30 min-w-[140px] overflow-hidden rounded-lg border shadow-lg",
3122
+ isUser ? "right-0 bottom-full mb-1" : "bottom-full left-0 mb-1"
3123
+ ),
3124
+ children: [
3125
+ /* @__PURE__ */ jsxs16(
3126
+ "button",
3127
+ {
3128
+ onClick: (e) => {
3129
+ e.stopPropagation();
3130
+ setOpen(false);
3131
+ onEdit();
3132
+ },
3133
+ className: "text-text hover:bg-primary-light hover:text-primary flex w-full items-center gap-2 px-3 py-2 text-xs transition-colors",
3134
+ children: [
3135
+ /* @__PURE__ */ jsx20(Pencil, { size: 13 }),
3136
+ "Modifier"
3137
+ ]
3138
+ }
3139
+ ),
3140
+ /* @__PURE__ */ jsxs16(
3141
+ "button",
3142
+ {
3143
+ onClick: (e) => {
3144
+ e.stopPropagation();
3145
+ setOpen(false);
3146
+ onDelete();
3147
+ },
3148
+ className: "text-danger hover:bg-danger-light flex w-full items-center gap-2 px-3 py-2 text-xs transition-colors",
3149
+ children: [
3150
+ /* @__PURE__ */ jsx20(Trash23, { size: 13 }),
3151
+ "Supprimer"
3152
+ ]
3153
+ }
3154
+ )
3155
+ ]
3156
+ }
3157
+ )
3158
+ ] });
3159
+ }
3160
+ function ReactionPicker({
3161
+ isUser,
3162
+ onSelect
3163
+ }) {
3164
+ const [open, setOpen] = useState11(false);
3165
+ const pickerRef = useRef5(null);
3166
+ useEffect11(() => {
3167
+ if (!open) return;
3168
+ const handler = (e) => {
3169
+ if (pickerRef.current && !pickerRef.current.contains(e.target)) {
3170
+ setOpen(false);
3171
+ }
3172
+ };
3173
+ document.addEventListener("mousedown", handler);
3174
+ return () => document.removeEventListener("mousedown", handler);
3175
+ }, [open]);
3176
+ return /* @__PURE__ */ jsxs16("div", { className: "relative", ref: pickerRef, children: [
3177
+ /* @__PURE__ */ jsx20(
3178
+ "button",
3179
+ {
3180
+ onClick: (e) => {
3181
+ e.stopPropagation();
3182
+ setOpen((v) => !v);
1776
3183
  },
1777
- `ellipsis-${idx}`
1778
- ) : /* @__PURE__ */ jsx8(
3184
+ className: cn(
3185
+ "rounded-full p-1 shadow-sm transition-all",
3186
+ "bg-surface border-border text-text-muted hover:text-text border"
3187
+ ),
3188
+ title: "R\xE9agir",
3189
+ children: /* @__PURE__ */ jsx20(SmilePlus, { size: 14 })
3190
+ }
3191
+ ),
3192
+ open && /* @__PURE__ */ jsx20(
3193
+ "div",
3194
+ {
3195
+ className: cn(
3196
+ "bg-surface border-border absolute z-30 flex items-center gap-0.5 rounded-full border px-1.5 py-1 shadow-lg",
3197
+ isUser ? "right-0 bottom-full mb-1" : "bottom-full left-0 mb-1"
3198
+ ),
3199
+ children: REACTION_OPTIONS.map((opt) => /* @__PURE__ */ jsx20(
3200
+ "button",
3201
+ {
3202
+ onClick: (e) => {
3203
+ e.stopPropagation();
3204
+ setOpen(false);
3205
+ onSelect(opt.key);
3206
+ },
3207
+ className: "hover:bg-bg flex h-7 w-7 items-center justify-center rounded-full text-base transition-all hover:scale-125",
3208
+ title: opt.label,
3209
+ children: opt.emoji
3210
+ },
3211
+ opt.key
3212
+ ))
3213
+ }
3214
+ )
3215
+ ] });
3216
+ }
3217
+ function groupReactions(reactions, currentUserId) {
3218
+ const map = /* @__PURE__ */ new Map();
3219
+ for (const r of reactions) {
3220
+ if (!map.has(r.reaction)) {
3221
+ map.set(r.reaction, { count: 0, members: [], hasMine: false });
3222
+ }
3223
+ const group = map.get(r.reaction);
3224
+ group.count++;
3225
+ if (r.memberName) group.members.push(r.memberName);
3226
+ if (r.memberId === currentUserId) group.hasMine = true;
3227
+ }
3228
+ return Array.from(map.entries()).map(([key, val]) => ({
3229
+ reaction: key,
3230
+ emoji: REACTION_EMOJI_MAP[key] ?? key,
3231
+ count: val.count,
3232
+ members: val.members,
3233
+ hasMine: val.hasMine
3234
+ }));
3235
+ }
3236
+ function ReactionBar({
3237
+ reactions,
3238
+ currentUserId,
3239
+ isUser,
3240
+ onToggle
3241
+ }) {
3242
+ const grouped = groupReactions(reactions, currentUserId);
3243
+ if (grouped.length === 0) return null;
3244
+ return /* @__PURE__ */ jsx20(
3245
+ "div",
3246
+ {
3247
+ className: cn(
3248
+ "mt-1 flex flex-wrap gap-1 px-1",
3249
+ isUser ? "justify-end" : "justify-start"
3250
+ ),
3251
+ children: grouped.map((g) => /* @__PURE__ */ jsxs16(
1779
3252
  "button",
1780
3253
  {
1781
- onClick: () => onPageChange(p),
1782
- disabled: loading,
3254
+ onClick: () => onToggle(g.reaction),
1783
3255
  className: cn(
1784
- "flex h-9 w-9 items-center justify-center rounded-lg text-sm font-medium transition-all duration-200",
1785
- p === currentPage ? "bg-primary text-white shadow-sm shadow-primary/30" : "border-border bg-surface text-text-secondary hover:bg-primary/8 hover:border-primary/30 hover:text-primary border active:scale-95"
3256
+ "group/reaction relative flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs transition-all hover:shadow-sm",
3257
+ g.hasMine ? "border-primary bg-primary-light text-primary font-medium" : "border-border bg-surface text-text-secondary hover:border-primary/40 hover:bg-primary-light/50"
1786
3258
  ),
1787
- children: p
3259
+ title: g.members.join(", "),
3260
+ children: [
3261
+ /* @__PURE__ */ jsx20("span", { className: "text-sm", children: g.emoji }),
3262
+ /* @__PURE__ */ jsx20("span", { children: g.count }),
3263
+ /* @__PURE__ */ jsx20(
3264
+ "div",
3265
+ {
3266
+ className: cn(
3267
+ "pointer-events-none absolute z-40 min-w-max rounded-lg px-2.5 py-1.5 text-[11px] leading-relaxed opacity-0 shadow-lg transition-opacity group-hover/reaction:opacity-100",
3268
+ "bg-[#1e293b] text-white",
3269
+ isUser ? "right-0 bottom-full mb-2" : "bottom-full left-0 mb-2"
3270
+ ),
3271
+ children: g.members.length > 0 ? g.members.join(", ") : "R\xE9action anonyme"
3272
+ }
3273
+ )
3274
+ ]
1788
3275
  },
1789
- p
1790
- )
3276
+ g.reaction
3277
+ ))
3278
+ }
3279
+ );
3280
+ }
3281
+ var MessageItem = ({
3282
+ message,
3283
+ role,
3284
+ members = [],
3285
+ workspaceId,
3286
+ currentUserId,
3287
+ isOwner = false,
3288
+ avatarUsers,
3289
+ onArtefactDeleted,
3290
+ onReply,
3291
+ onEditMessage,
3292
+ onDeleteMessage,
3293
+ onToggleReaction,
3294
+ onTogglePin
3295
+ }) => {
3296
+ const isAgent = message.senderType === "agent";
3297
+ const isUser = role === "user";
3298
+ const isDeleted = message.deleted === true;
3299
+ const processedContent = isDeleted ? "" : preprocessMentions(message.content, members);
3300
+ const artefacts = isDeleted ? [] : "artefacts" in message ? message.artefacts : [];
3301
+ const reactions = isDeleted ? [] : "reactions" in message ? message.reactions ?? [] : [];
3302
+ const time = formatTime(message.createdAt);
3303
+ const isPinned = !isDeleted && message.pinned === true;
3304
+ const [isExpanded, setIsExpanded] = useState11(false);
3305
+ const [artefactsExpanded, setArtefactsExpanded] = useState11(false);
3306
+ const [isLong, setIsLong] = useState11(false);
3307
+ const contentRef = useRef5(null);
3308
+ useEffect11(() => {
3309
+ if (isDeleted) return;
3310
+ const el = contentRef.current;
3311
+ if (!el) return;
3312
+ const checkHeight = () => {
3313
+ if (el.scrollHeight > COLLAPSED_MAX_HEIGHT) {
3314
+ setIsLong(true);
3315
+ } else {
3316
+ setIsLong(false);
3317
+ }
3318
+ };
3319
+ checkHeight();
3320
+ const timer1 = setTimeout(checkHeight, 100);
3321
+ const timer2 = setTimeout(checkHeight, 500);
3322
+ let observer = null;
3323
+ if (typeof ResizeObserver !== "undefined") {
3324
+ observer = new ResizeObserver(checkHeight);
3325
+ observer.observe(el);
3326
+ }
3327
+ return () => {
3328
+ clearTimeout(timer1);
3329
+ clearTimeout(timer2);
3330
+ if (observer) observer.disconnect();
3331
+ };
3332
+ }, [message.content, isDeleted]);
3333
+ const isDark = typeof document !== "undefined" && document.documentElement.getAttribute("data-theme") === "dark";
3334
+ const codePlugin = React15.useMemo(
3335
+ () => createCodePlugin({
3336
+ themes: isDark ? ["min-dark", "min-dark"] : ["min-light", "min-light"]
3337
+ }),
3338
+ [isDark]
3339
+ );
3340
+ const [viewingArtefact, setViewingArtefact] = useState11(null);
3341
+ const [confirmDeleteOpen, setConfirmDeleteOpen] = useState11(false);
3342
+ const memberName = message.sender?.memberName || message.senderName;
3343
+ if (isDeleted) {
3344
+ return /* @__PURE__ */ jsxs16(
3345
+ "div",
3346
+ {
3347
+ className: cn(
3348
+ "group flex max-w-[85%] gap-3",
3349
+ isUser ? "flex-row-reverse self-end" : "self-start"
3350
+ ),
3351
+ children: [
3352
+ /* @__PURE__ */ jsx20(
3353
+ MemberAvatar,
3354
+ {
3355
+ memberName,
3356
+ memberType: message.senderType,
3357
+ avatarUrl: avatarUsers?.find(
3358
+ (u) => u.email.toLowerCase() === message.senderId.toLowerCase()
3359
+ )?.avatarUrl,
3360
+ size: "md",
3361
+ variant: isUser ? "currentUser" : "primary",
3362
+ className: "opacity-50 shadow-sm"
3363
+ }
3364
+ ),
3365
+ /* @__PURE__ */ jsxs16("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
3366
+ !isUser && /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 px-1", children: [
3367
+ /* @__PURE__ */ jsx20("span", { className: "text-text-muted text-[11px] font-semibold", children: memberName }),
3368
+ /* @__PURE__ */ jsx20("span", { className: "text-text-placeholder text-[10px]", children: time })
3369
+ ] }),
3370
+ /* @__PURE__ */ jsx20(
3371
+ "div",
3372
+ {
3373
+ className: cn(
3374
+ "rounded-2xl px-4 py-2.5 italic",
3375
+ isUser ? "bg-primary/80 rounded-tr-sm text-white/80" : "bg-surface border-border text-text-muted rounded-tl-sm border"
3376
+ ),
3377
+ children: /* @__PURE__ */ jsx20("span", { className: "text-xs", children: "\u{1F5D1}\uFE0F Ce message a \xE9t\xE9 supprim\xE9" })
3378
+ }
3379
+ ),
3380
+ isUser && /* @__PURE__ */ jsx20("div", { className: "flex items-center gap-1 self-end px-1", children: /* @__PURE__ */ jsx20("span", { className: "text-text-placeholder text-[10px]", children: time }) })
3381
+ ] })
3382
+ ]
3383
+ }
3384
+ );
3385
+ }
3386
+ return /* @__PURE__ */ jsxs16(Fragment4, { children: [
3387
+ /* @__PURE__ */ jsxs16(
3388
+ "div",
3389
+ {
3390
+ className: cn(
3391
+ "group flex max-w-[85%] gap-3",
3392
+ isUser ? "flex-row-reverse self-end" : "self-start"
3393
+ ),
3394
+ children: [
3395
+ /* @__PURE__ */ jsx20(
3396
+ MemberAvatar,
3397
+ {
3398
+ memberName,
3399
+ memberType: message.senderType,
3400
+ avatarUrl: avatarUsers?.find(
3401
+ (u) => u.email.toLowerCase() === message.senderId.toLowerCase()
3402
+ )?.avatarUrl,
3403
+ size: "md",
3404
+ variant: isUser ? "currentUser" : "primary",
3405
+ className: "mt-1 flex-shrink-0 self-start shadow-sm"
3406
+ }
3407
+ ),
3408
+ /* @__PURE__ */ jsxs16("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
3409
+ !isUser && /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 px-1", children: [
3410
+ /* @__PURE__ */ jsx20(
3411
+ "span",
3412
+ {
3413
+ className: cn(
3414
+ "text-[11px] font-semibold",
3415
+ isAgent ? "text-indigo-600" : "text-text-secondary"
3416
+ ),
3417
+ children: memberName
3418
+ }
3419
+ ),
3420
+ /* @__PURE__ */ jsx20("span", { className: "text-text-placeholder text-[10px]", children: time }),
3421
+ message.editedAt && /* @__PURE__ */ jsx20("span", { className: "text-text-placeholder text-[10px] italic", children: "(modifi\xE9)" }),
3422
+ onReply && /* @__PURE__ */ jsx20(
3423
+ "button",
3424
+ {
3425
+ onClick: () => onReply(message),
3426
+ className: "text-text-muted hover:text-primary ml-auto rounded p-0.5 opacity-0 transition-all group-hover:opacity-100",
3427
+ title: "R\xE9pondre",
3428
+ children: /* @__PURE__ */ jsx20(Reply, { size: 13 })
3429
+ }
3430
+ )
3431
+ ] }),
3432
+ isPinned && /* @__PURE__ */ jsxs16(
3433
+ "div",
3434
+ {
3435
+ className: cn(
3436
+ "flex items-center gap-1 px-2 py-0.5 text-[10px] font-medium",
3437
+ isUser ? "self-end text-amber-200" : "text-amber-600 dark:text-amber-400"
3438
+ ),
3439
+ children: [
3440
+ /* @__PURE__ */ jsx20(Pin, { size: 10, className: "rotate-45" }),
3441
+ /* @__PURE__ */ jsx20("span", { children: "\xC9pingl\xE9" })
3442
+ ]
3443
+ }
3444
+ ),
3445
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-start gap-1.5", children: [
3446
+ isUser && /* @__PURE__ */ jsxs16("div", { className: "flex flex-shrink-0 items-center gap-0.5 self-center opacity-0 transition-opacity group-hover:opacity-100", children: [
3447
+ onTogglePin && /* @__PURE__ */ jsx20(
3448
+ "button",
3449
+ {
3450
+ onClick: (e) => {
3451
+ e.stopPropagation();
3452
+ onTogglePin(message._id);
3453
+ },
3454
+ className: cn(
3455
+ "rounded-full p-1 shadow-sm transition-all",
3456
+ "bg-surface border-border border",
3457
+ isPinned ? "text-amber-500 hover:text-amber-600" : "text-text-muted hover:text-text"
3458
+ ),
3459
+ title: isPinned ? "D\xE9s\xE9pingler" : "\xC9pingler",
3460
+ children: isPinned ? /* @__PURE__ */ jsx20(PinOff, { size: 14 }) : /* @__PURE__ */ jsx20(Pin, { size: 14 })
3461
+ }
3462
+ ),
3463
+ onToggleReaction && /* @__PURE__ */ jsx20(
3464
+ ReactionPicker,
3465
+ {
3466
+ isUser,
3467
+ onSelect: (r) => onToggleReaction(message._id, r)
3468
+ }
3469
+ ),
3470
+ onEditMessage && onDeleteMessage && /* @__PURE__ */ jsx20(
3471
+ MessageActionsMenu,
3472
+ {
3473
+ isUser,
3474
+ onEdit: () => onEditMessage(message),
3475
+ onDelete: () => setConfirmDeleteOpen(true)
3476
+ }
3477
+ )
3478
+ ] }),
3479
+ /* @__PURE__ */ jsxs16(
3480
+ "div",
3481
+ {
3482
+ className: cn(
3483
+ "relative rounded-2xl px-4 py-2.5 shadow-sm transition-shadow group-hover:shadow-md",
3484
+ isUser ? "bg-primary rounded-tr-sm text-white" : isAgent ? "rounded-tl-sm border border-indigo-100 bg-gradient-to-br from-white to-indigo-50/40 dark:border-indigo-800/60 dark:from-indigo-900/20 dark:to-indigo-800/10" : "bg-surface border-border rounded-tl-sm border"
3485
+ ),
3486
+ children: [
3487
+ message.replyToMessage && typeof message.replyToMessage === "object" && "content" in message.replyToMessage && /* @__PURE__ */ jsxs16(
3488
+ "div",
3489
+ {
3490
+ className: cn(
3491
+ "mb-2 rounded-lg border-l-3 px-3 py-1.5",
3492
+ isUser ? "border-l-white/50 bg-white/15" : "border-l-[var(--color-primary)] bg-[var(--color-primary-light)]/60"
3493
+ ),
3494
+ children: [
3495
+ /* @__PURE__ */ jsx20(
3496
+ "div",
3497
+ {
3498
+ className: cn(
3499
+ "text-[10px] font-semibold",
3500
+ isUser ? "text-white/80" : "text-primary"
3501
+ ),
3502
+ children: message.replyToMessage.senderName
3503
+ }
3504
+ ),
3505
+ /* @__PURE__ */ jsx20(
3506
+ "div",
3507
+ {
3508
+ className: cn(
3509
+ "truncate text-[11px]",
3510
+ isUser ? "text-white/60" : "text-text-muted",
3511
+ message.replyToMessage.deleted && "italic"
3512
+ ),
3513
+ children: message.replyToMessage.deleted ? "\u{1F5D1}\uFE0F Ce message a \xE9t\xE9 supprim\xE9" : message.replyToMessage.content.length > 100 ? message.replyToMessage.content.slice(0, 100) + "\u2026" : message.replyToMessage.content
3514
+ }
3515
+ )
3516
+ ]
3517
+ }
3518
+ ),
3519
+ /* @__PURE__ */ jsx20(
3520
+ "div",
3521
+ {
3522
+ ref: contentRef,
3523
+ className: cn(
3524
+ "streamdown-message overflow-hidden text-sm leading-relaxed transition-all duration-300 ease-in-out",
3525
+ isUser && "text-white [&_a]:text-white/80 [&_a]:underline [&_code]:bg-white/15 [&_code]:text-white [&_strong]:text-white/90"
3526
+ ),
3527
+ style: !isExpanded && isLong ? {
3528
+ maxHeight: `${COLLAPSED_MAX_HEIGHT}px`,
3529
+ maskImage: "linear-gradient(to bottom, black 70%, transparent 100%)",
3530
+ WebkitMaskImage: "linear-gradient(to bottom, black 70%, transparent 100%)"
3531
+ } : void 0,
3532
+ children: /* @__PURE__ */ jsx20(
3533
+ Streamdown2,
3534
+ {
3535
+ mode: "static",
3536
+ plugins: { code: codePlugin, mermaid, math, cjk },
3537
+ components: workspaceStreamdownComponents,
3538
+ children: processedContent
3539
+ }
3540
+ )
3541
+ }
3542
+ ),
3543
+ isLong && /* @__PURE__ */ jsx20(
3544
+ "button",
3545
+ {
3546
+ onClick: () => setIsExpanded((prev) => !prev),
3547
+ className: cn(
3548
+ "mt-2 flex cursor-pointer items-center gap-0.5 self-start text-[10px] font-semibold transition-colors select-none",
3549
+ isUser ? "text-white/85 hover:text-white" : "text-primary hover:text-primary-hover"
3550
+ ),
3551
+ type: "button",
3552
+ children: isExpanded ? /* @__PURE__ */ jsxs16(Fragment4, { children: [
3553
+ /* @__PURE__ */ jsx20(ChevronUp, { size: 12 }),
3554
+ "Voir moins"
3555
+ ] }) : /* @__PURE__ */ jsxs16(Fragment4, { children: [
3556
+ /* @__PURE__ */ jsx20(ChevronDown, { size: 12 }),
3557
+ "Voir plus"
3558
+ ] })
3559
+ }
3560
+ ),
3561
+ artefacts.length > 0 && (() => {
3562
+ const hasMany = artefacts.length > MAX_VISIBLE_ARTEFACTS;
3563
+ const visibleArtefacts = artefactsExpanded || !hasMany ? artefacts : artefacts.slice(0, MAX_VISIBLE_ARTEFACTS);
3564
+ const hiddenCount = artefacts.length - MAX_VISIBLE_ARTEFACTS;
3565
+ return /* @__PURE__ */ jsxs16(
3566
+ "div",
3567
+ {
3568
+ className: cn(
3569
+ "mt-3 flex flex-col gap-2 border-t pt-2.5",
3570
+ isUser ? "border-white/20" : "border-border-light"
3571
+ ),
3572
+ children: [
3573
+ /* @__PURE__ */ jsxs16(
3574
+ "div",
3575
+ {
3576
+ className: cn(
3577
+ "flex items-center gap-1 text-[10px] font-medium",
3578
+ isUser ? "text-white/60" : "text-text-muted"
3579
+ ),
3580
+ children: [
3581
+ /* @__PURE__ */ jsx20(Paperclip, { size: 10 }),
3582
+ artefacts.length,
3583
+ " pi\xE8ce",
3584
+ artefacts.length > 1 ? "s" : "",
3585
+ " jointe",
3586
+ artefacts.length > 1 ? "s" : ""
3587
+ ]
3588
+ }
3589
+ ),
3590
+ visibleArtefacts.map((art) => /* @__PURE__ */ jsx20(
3591
+ ArtefactCard,
3592
+ {
3593
+ artefact: art,
3594
+ isUserMessage: isUser,
3595
+ workspaceId,
3596
+ onView: () => setViewingArtefact(art),
3597
+ onDeleted: onArtefactDeleted,
3598
+ canDelete: isOwner || art.createdBy === currentUserId
3599
+ },
3600
+ art._id
3601
+ )),
3602
+ hasMany && /* @__PURE__ */ jsx20(
3603
+ "button",
3604
+ {
3605
+ onClick: () => setArtefactsExpanded((prev) => !prev),
3606
+ className: cn(
3607
+ "mt-0.5 flex cursor-pointer items-center gap-1 self-start rounded-md px-2 py-1 text-[10px] font-semibold transition-all select-none",
3608
+ isUser ? "text-white/80 hover:bg-white/10 hover:text-white" : "text-primary hover:bg-primary-light hover:text-primary-hover"
3609
+ ),
3610
+ type: "button",
3611
+ children: artefactsExpanded ? /* @__PURE__ */ jsxs16(Fragment4, { children: [
3612
+ /* @__PURE__ */ jsx20(ChevronUp, { size: 12 }),
3613
+ "Voir moins"
3614
+ ] }) : /* @__PURE__ */ jsxs16(Fragment4, { children: [
3615
+ /* @__PURE__ */ jsx20(ChevronDown, { size: 12 }),
3616
+ "+",
3617
+ hiddenCount,
3618
+ " autre",
3619
+ hiddenCount > 1 ? "s" : "",
3620
+ " pi\xE8ce",
3621
+ hiddenCount > 1 ? "s" : "",
3622
+ " jointe",
3623
+ hiddenCount > 1 ? "s" : ""
3624
+ ] })
3625
+ }
3626
+ )
3627
+ ]
3628
+ }
3629
+ );
3630
+ })()
3631
+ ]
3632
+ }
3633
+ ),
3634
+ !isUser && /* @__PURE__ */ jsxs16("div", { className: "flex flex-shrink-0 items-center gap-0.5 self-center opacity-0 transition-opacity group-hover:opacity-100", children: [
3635
+ onToggleReaction && /* @__PURE__ */ jsx20(
3636
+ ReactionPicker,
3637
+ {
3638
+ isUser,
3639
+ onSelect: (r) => onToggleReaction(message._id, r)
3640
+ }
3641
+ ),
3642
+ onTogglePin && /* @__PURE__ */ jsx20(
3643
+ "button",
3644
+ {
3645
+ onClick: (e) => {
3646
+ e.stopPropagation();
3647
+ onTogglePin(message._id);
3648
+ },
3649
+ className: cn(
3650
+ "rounded-full p-1 shadow-sm transition-all",
3651
+ "bg-surface border-border border",
3652
+ isPinned ? "text-amber-500 hover:text-amber-600" : "text-text-muted hover:text-text"
3653
+ ),
3654
+ title: isPinned ? "D\xE9s\xE9pingler" : "\xC9pingler",
3655
+ children: isPinned ? /* @__PURE__ */ jsx20(PinOff, { size: 14 }) : /* @__PURE__ */ jsx20(Pin, { size: 14 })
3656
+ }
3657
+ )
3658
+ ] })
3659
+ ] }),
3660
+ onToggleReaction && reactions.length > 0 && /* @__PURE__ */ jsx20(
3661
+ ReactionBar,
3662
+ {
3663
+ reactions,
3664
+ currentUserId,
3665
+ isUser,
3666
+ onToggle: (r) => onToggleReaction(message._id, r)
3667
+ }
3668
+ ),
3669
+ isUser && /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1 self-end px-1", children: [
3670
+ message.editedAt && /* @__PURE__ */ jsx20("span", { className: "text-text-placeholder text-[10px] italic", children: "(modifi\xE9)" }),
3671
+ onReply && /* @__PURE__ */ jsx20(
3672
+ "button",
3673
+ {
3674
+ onClick: () => onReply(message),
3675
+ className: "text-text-muted hover:text-primary rounded p-0.5 opacity-0 transition-all group-hover:opacity-100",
3676
+ title: "R\xE9pondre",
3677
+ children: /* @__PURE__ */ jsx20(Reply, { size: 13 })
3678
+ }
3679
+ ),
3680
+ /* @__PURE__ */ jsx20("span", { className: "text-text-placeholder text-[10px]", children: time })
3681
+ ] })
3682
+ ] })
3683
+ ]
3684
+ }
1791
3685
  ),
1792
- /* @__PURE__ */ jsx8(
1793
- NavButton,
3686
+ /* @__PURE__ */ jsx20(
3687
+ ConfirmModal,
1794
3688
  {
1795
- onClick: () => onPageChange(currentPage + 1),
1796
- disabled: currentPage === totalPages || loading,
1797
- title: "Page suivante",
1798
- children: /* @__PURE__ */ jsx8(ChevronRight, { size: 16 })
3689
+ open: confirmDeleteOpen,
3690
+ onClose: () => setConfirmDeleteOpen(false),
3691
+ onConfirm: () => {
3692
+ onDeleteMessage?.(message._id);
3693
+ setConfirmDeleteOpen(false);
3694
+ },
3695
+ title: "Supprimer le message",
3696
+ description: "Voulez-vous vraiment supprimer ce message ? Cette action est irr\xE9versible.",
3697
+ confirmText: "Supprimer",
3698
+ danger: true
1799
3699
  }
1800
3700
  ),
1801
- /* @__PURE__ */ jsx8(
1802
- NavButton,
3701
+ viewingArtefact && /* @__PURE__ */ jsx20(
3702
+ ArtefactViewerDialog,
1803
3703
  {
1804
- onClick: () => onPageChange(totalPages),
1805
- disabled: currentPage === totalPages || loading,
1806
- title: "Derni\xE8re page",
1807
- children: /* @__PURE__ */ jsx8(ChevronsRight, { size: 16 })
3704
+ artefact: viewingArtefact,
3705
+ onClose: () => setViewingArtefact(null)
1808
3706
  }
1809
3707
  )
1810
3708
  ] });
1811
3709
  };
3710
+
3711
+ // src/components/MessageFeed.tsx
3712
+ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
3713
+ function getRole(msg, currentUserId) {
3714
+ if (msg.senderType === "agent") return "assistant";
3715
+ if (currentUserId && msg.senderId === currentUserId) return "user";
3716
+ return "participant";
3717
+ }
3718
+ function getDateKey(dateStr) {
3719
+ const d = typeof dateStr === "string" ? parseISO(dateStr) : new Date(dateStr);
3720
+ return format(d, "yyyy-MM-dd");
3721
+ }
3722
+ function formatDateLabel(dateStr) {
3723
+ const d = typeof dateStr === "string" ? parseISO(dateStr) : new Date(dateStr);
3724
+ if (isToday(d)) return "Aujourd'hui";
3725
+ if (isYesterday(d)) return "Hier";
3726
+ return format(d, "EEEE d MMMM yyyy", { locale: fr });
3727
+ }
3728
+ function DateSeparator({ date, isCollapsed, onToggle, messageCount }) {
3729
+ return /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-3 py-2 select-none", role: "separator", children: [
3730
+ /* @__PURE__ */ jsx21("div", { className: "bg-[var(--color-border,#e2e8f0)] h-px flex-1" }),
3731
+ /* @__PURE__ */ jsxs17(
3732
+ "button",
3733
+ {
3734
+ onClick: onToggle,
3735
+ className: "bg-[var(--color-surface,#fff)] border-[var(--color-border,#e2e8f0)] text-[var(--color-text-muted,#94a3b8)] hover:text-[var(--color-text,#0f172a)] hover:bg-[var(--color-bg,#f8fafc)] flex cursor-pointer items-center gap-1.5 rounded-full border px-3 py-1 text-[11px] font-medium capitalize shadow-sm transition-colors",
3736
+ type: "button",
3737
+ children: [
3738
+ /* @__PURE__ */ jsx21("span", { children: formatDateLabel(date) }),
3739
+ isCollapsed && /* @__PURE__ */ jsx21("span", { className: "bg-[var(--color-primary,#3b82f6)] flex h-4 min-w-[16px] items-center justify-center rounded-full px-1 text-[9px] leading-none font-bold text-white", children: messageCount }),
3740
+ isCollapsed ? /* @__PURE__ */ jsx21(ChevronRight2, { size: 12, className: "text-[var(--color-text-muted,#94a3b8)] shrink-0" }) : /* @__PURE__ */ jsx21(ChevronDown2, { size: 12, className: "text-[var(--color-text-muted,#94a3b8)] shrink-0" })
3741
+ ]
3742
+ }
3743
+ ),
3744
+ /* @__PURE__ */ jsx21("div", { className: "bg-[var(--color-border,#e2e8f0)] h-px flex-1" })
3745
+ ] });
3746
+ }
3747
+ var BOTTOM_THRESHOLD = 80;
3748
+ var MessageFeed = ({
3749
+ messages,
3750
+ members = [],
3751
+ currentUserId,
3752
+ workspaceId,
3753
+ avatarUsers,
3754
+ isTyping,
3755
+ typingText,
3756
+ hasMore = false,
3757
+ loadingMore = false,
3758
+ onLoadMore,
3759
+ onArtefactDeleted,
3760
+ onReply,
3761
+ onEditMessage,
3762
+ onDeleteMessage,
3763
+ onToggleReaction,
3764
+ onTogglePin,
3765
+ isOwner = false
3766
+ }) => {
3767
+ const feedRef = useRef6(null);
3768
+ const initialScrollDone = useRef6(false);
3769
+ const prevScrollHeight = useRef6(0);
3770
+ const prevMessageCount = useRef6(0);
3771
+ const isAtBottom = useRef6(true);
3772
+ const [newMessageCount, setNewMessageCount] = useState12(0);
3773
+ const [collapsedDates, setCollapsedDates] = useState12({});
3774
+ const toggleDateCollapse = useCallback2((dateKey) => {
3775
+ setCollapsedDates((prev) => ({ ...prev, [dateKey]: !prev[dateKey] }));
3776
+ }, []);
3777
+ const checkIsAtBottom = useCallback2(() => {
3778
+ const el = feedRef.current;
3779
+ if (!el) return true;
3780
+ return el.scrollHeight - el.scrollTop - el.clientHeight < BOTTOM_THRESHOLD;
3781
+ }, []);
3782
+ const scrollToBottom = useCallback2(() => {
3783
+ const el = feedRef.current;
3784
+ if (!el) return;
3785
+ el.scrollTo({ top: el.scrollHeight, behavior: "smooth" });
3786
+ isAtBottom.current = true;
3787
+ setNewMessageCount(0);
3788
+ }, []);
3789
+ const feedItems = useMemo7(() => {
3790
+ const counts = {};
3791
+ for (const msg of messages) {
3792
+ const k = getDateKey(msg.createdAt);
3793
+ counts[k] = (counts[k] || 0) + 1;
3794
+ }
3795
+ const items = [];
3796
+ let lastDateKey = "";
3797
+ for (const msg of messages) {
3798
+ const dateKey = getDateKey(msg.createdAt);
3799
+ if (dateKey !== lastDateKey) {
3800
+ items.push({ type: "separator", dateKey, date: msg.createdAt, messageCount: counts[dateKey] || 0 });
3801
+ lastDateKey = dateKey;
3802
+ }
3803
+ items.push({ type: "message", dateKey, msg });
3804
+ }
3805
+ return items;
3806
+ }, [messages]);
3807
+ useEffect12(() => {
3808
+ const el = feedRef.current;
3809
+ if (!el) return;
3810
+ const messageCountGrew = messages.length > prevMessageCount.current;
3811
+ const prependedOlder = messageCountGrew && prevScrollHeight.current > 0 && initialScrollDone.current;
3812
+ if (!initialScrollDone.current) {
3813
+ el.scrollTop = el.scrollHeight;
3814
+ initialScrollDone.current = true;
3815
+ } else if (prependedOlder) {
3816
+ el.scrollTop = el.scrollHeight - prevScrollHeight.current;
3817
+ } else if (messageCountGrew) {
3818
+ if (isAtBottom.current) {
3819
+ el.scrollTop = el.scrollHeight;
3820
+ } else {
3821
+ setNewMessageCount((prev) => prev + messages.length - prevMessageCount.current);
3822
+ }
3823
+ }
3824
+ prevMessageCount.current = messages.length;
3825
+ prevScrollHeight.current = 0;
3826
+ }, [messages]);
3827
+ useEffect12(() => {
3828
+ if (isTyping && feedRef.current && isAtBottom.current) feedRef.current.scrollTop = feedRef.current.scrollHeight;
3829
+ }, [isTyping]);
3830
+ const handleScroll = useCallback2(() => {
3831
+ const el = feedRef.current;
3832
+ if (!el) return;
3833
+ const atBottom = checkIsAtBottom();
3834
+ isAtBottom.current = atBottom;
3835
+ if (atBottom && newMessageCount > 0) setNewMessageCount(0);
3836
+ if (!hasMore || loadingMore || !onLoadMore) return;
3837
+ if (el.scrollTop <= 50) {
3838
+ prevScrollHeight.current = el.scrollHeight;
3839
+ onLoadMore();
3840
+ }
3841
+ }, [hasMore, loadingMore, onLoadMore, checkIsAtBottom, newMessageCount]);
3842
+ if (messages.length === 0) return /* @__PURE__ */ jsxs17("div", { className: "flex flex-1 flex-col items-center justify-center gap-2 text-center", ref: feedRef, children: [
3843
+ /* @__PURE__ */ jsx21(Brain7, { size: 32, className: "text-[var(--color-text-muted,#94a3b8)]" }),
3844
+ /* @__PURE__ */ jsx21("p", { className: "text-[var(--color-text-muted,#94a3b8)] text-sm", children: "Aucun message pour le moment." }),
3845
+ /* @__PURE__ */ jsx21("p", { className: "text-[var(--color-text-muted,#94a3b8)] text-xs", children: "Commencez par envoyer un message pour d\xE9marrer la conversation." })
3846
+ ] });
3847
+ return /* @__PURE__ */ jsxs17("div", { className: "relative flex flex-1 flex-col overflow-hidden", children: [
3848
+ /* @__PURE__ */ jsxs17("div", { className: "flex flex-1 flex-col gap-4 overflow-y-auto p-4", ref: feedRef, onScroll: handleScroll, children: [
3849
+ loadingMore && /* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-center gap-2 py-3", children: [
3850
+ /* @__PURE__ */ jsx21(Loader28, { size: 16, className: "text-[var(--color-primary,#3b82f6)] animate-spin" }),
3851
+ /* @__PURE__ */ jsx21("span", { className: "text-[var(--color-text-muted,#94a3b8)] text-xs", children: "Chargement des messages pr\xE9c\xE9dents\u2026" })
3852
+ ] }),
3853
+ !hasMore && messages.length > 0 && /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-center py-2", children: /* @__PURE__ */ jsx21("span", { className: "text-[var(--color-text-muted,#94a3b8)] text-[10px] italic", children: "D\xE9but de la conversation" }) }),
3854
+ feedItems.map(
3855
+ (item) => item.type === "separator" ? /* @__PURE__ */ jsx21(
3856
+ DateSeparator,
3857
+ {
3858
+ date: item.date,
3859
+ isCollapsed: !!collapsedDates[item.dateKey],
3860
+ onToggle: () => toggleDateCollapse(item.dateKey),
3861
+ messageCount: item.messageCount
3862
+ },
3863
+ `sep-${item.dateKey}`
3864
+ ) : !collapsedDates[item.dateKey] ? /* @__PURE__ */ jsx21(
3865
+ MessageItem,
3866
+ {
3867
+ message: item.msg,
3868
+ role: getRole(item.msg, currentUserId),
3869
+ members,
3870
+ workspaceId,
3871
+ currentUserId,
3872
+ isOwner,
3873
+ avatarUsers,
3874
+ onArtefactDeleted,
3875
+ onReply,
3876
+ onEditMessage,
3877
+ onDeleteMessage,
3878
+ onToggleReaction,
3879
+ onTogglePin
3880
+ },
3881
+ item.msg._id
3882
+ ) : null
3883
+ ),
3884
+ isTyping && /* @__PURE__ */ jsxs17("div", { className: "text-[var(--color-text-muted,#94a3b8)] flex items-center gap-2 self-start text-xs", children: [
3885
+ /* @__PURE__ */ jsx21("div", { className: "flex gap-0.5", children: [0, 150, 300].map((delay) => /* @__PURE__ */ jsx21("div", { className: "bg-[var(--color-primary,#3b82f6)] h-1.5 w-1.5 animate-bounce rounded-full", style: { animationDelay: `${delay}ms` } }, delay)) }),
3886
+ /* @__PURE__ */ jsx21("span", { children: typingText || "Assistant IA est en train d'\xE9crire\u2026" })
3887
+ ] })
3888
+ ] }),
3889
+ newMessageCount > 0 && /* @__PURE__ */ jsxs17(
3890
+ "button",
3891
+ {
3892
+ onClick: scrollToBottom,
3893
+ className: "bg-[var(--color-primary,#3b82f6)] hover:bg-[var(--color-primary-hover,#2563eb)] absolute bottom-4 left-1/2 z-10 flex -translate-x-1/2 items-center gap-2 rounded-full px-4 py-2 text-xs font-medium text-white shadow-lg transition-all hover:scale-105 active:scale-95",
3894
+ children: [
3895
+ /* @__PURE__ */ jsx21(ArrowDown, { size: 14 }),
3896
+ /* @__PURE__ */ jsxs17("span", { children: [
3897
+ newMessageCount,
3898
+ " nouveau",
3899
+ newMessageCount > 1 ? "x" : "",
3900
+ " message",
3901
+ newMessageCount > 1 ? "s" : ""
3902
+ ] })
3903
+ ]
3904
+ }
3905
+ )
3906
+ ] });
3907
+ };
3908
+
3909
+ // src/components/MessageFilterDialog.tsx
3910
+ import { useState as useState13, useEffect as useEffect13 } from "react";
3911
+ import { RotateCcw, Loader2 as Loader29, Filter as Filter2 } from "lucide-react";
3912
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
3913
+ var EMPTY_FILTERS = { concernsMe: false, members: [] };
3914
+ var MessageFilterDialog = ({
3915
+ open,
3916
+ onClose,
3917
+ onApply,
3918
+ currentFilters,
3919
+ members,
3920
+ avatarUsers = [],
3921
+ hideAgents = false
3922
+ }) => {
3923
+ const displayedMembers = hideAgents ? members.filter((m) => m.memberType !== "agent") : members;
3924
+ const [draft, setDraft] = useState13({ ...currentFilters });
3925
+ const [applying, setApplying] = useState13(false);
3926
+ useEffect13(() => {
3927
+ if (open) setDraft({ ...currentFilters });
3928
+ }, [open, currentFilters]);
3929
+ const handleToggleConcernsMe = () => setDraft((prev) => ({
3930
+ concernsMe: !prev.concernsMe,
3931
+ members: !prev.concernsMe ? [] : prev.members
3932
+ }));
3933
+ const handleToggleMember = (memberId) => setDraft((prev) => {
3934
+ const isSelected = prev.members.includes(memberId);
3935
+ return { ...prev, members: isSelected ? prev.members.filter((id) => id !== memberId) : [...prev.members, memberId] };
3936
+ });
3937
+ const handleApply = async () => {
3938
+ setApplying(true);
3939
+ try {
3940
+ await onApply(draft);
3941
+ } finally {
3942
+ setApplying(false);
3943
+ onClose();
3944
+ }
3945
+ };
3946
+ const getAvatarForMember = (m) => avatarUsers.find((u) => u.email === m.memberId);
3947
+ return /* @__PURE__ */ jsxs18(
3948
+ Modal,
3949
+ {
3950
+ open,
3951
+ onClose,
3952
+ size: "md",
3953
+ title: "Filtrer les messages",
3954
+ description: "Affinez les messages affich\xE9s dans la discussion.",
3955
+ titleIcon: /* @__PURE__ */ jsx22("div", { className: "bg-[var(--color-primary-light,#eff6ff)] text-[var(--color-primary,#3b82f6)] flex h-8 w-8 items-center justify-center rounded-lg", children: /* @__PURE__ */ jsx22(Filter2, { size: 16 }) }),
3956
+ closeOnBackdropClick: true,
3957
+ closeOnEscape: !applying,
3958
+ closeButtonDisabled: applying,
3959
+ children: [
3960
+ /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-5 px-6 py-5", children: [
3961
+ /* @__PURE__ */ jsxs18(
3962
+ "button",
3963
+ {
3964
+ type: "button",
3965
+ disabled: applying,
3966
+ onClick: handleToggleConcernsMe,
3967
+ className: cn(
3968
+ "flex items-center justify-between rounded-xl border px-4 py-3 text-left transition-all",
3969
+ draft.concernsMe ? "border-[var(--color-primary,#3b82f6)] bg-[var(--color-primary-light,#eff6ff)]" : "border-[var(--color-border,#e2e8f0)] hover:border-[var(--color-primary,#3b82f6)]/40"
3970
+ ),
3971
+ children: [
3972
+ /* @__PURE__ */ jsxs18("div", { className: "flex flex-col", children: [
3973
+ /* @__PURE__ */ jsx22("span", { className: cn("text-sm font-medium", draft.concernsMe ? "text-[var(--color-primary,#3b82f6)]" : "text-[var(--color-text,#0f172a)]"), children: "Messages qui me concernent" }),
3974
+ /* @__PURE__ */ jsx22("span", { className: "text-[var(--color-text-muted,#94a3b8)] text-[11px]", children: "Messages envoy\xE9s par moi ou dans lesquels je suis mentionn\xE9" })
3975
+ ] }),
3976
+ /* @__PURE__ */ jsx22("div", { className: cn(
3977
+ "relative h-6 w-11 flex-shrink-0 rounded-full transition-colors",
3978
+ draft.concernsMe ? "bg-[var(--color-primary,#3b82f6)]" : "bg-[var(--color-border,#e2e8f0)]"
3979
+ ), children: /* @__PURE__ */ jsx22("div", { className: cn(
3980
+ "absolute top-0.5 h-5 w-5 rounded-full bg-white shadow-sm transition-transform",
3981
+ draft.concernsMe ? "translate-x-[22px]" : "translate-x-0.5"
3982
+ ) }) })
3983
+ ]
3984
+ }
3985
+ ),
3986
+ /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-2", children: [
3987
+ /* @__PURE__ */ jsx22("span", { className: "text-[var(--color-text-muted,#94a3b8)] text-xs font-semibold tracking-wider uppercase", children: "Filtrer par membres" }),
3988
+ /* @__PURE__ */ jsxs18("div", { className: cn(
3989
+ "flex max-h-52 flex-col gap-1 overflow-y-auto rounded-xl border p-2 transition-opacity",
3990
+ draft.concernsMe ? "pointer-events-none border-[var(--color-border,#e2e8f0)]/50 opacity-50" : "border-[var(--color-border,#e2e8f0)]"
3991
+ ), children: [
3992
+ displayedMembers.map((member) => {
3993
+ const isSelected = draft.members.includes(member.memberId);
3994
+ const avatar = getAvatarForMember(member);
3995
+ return /* @__PURE__ */ jsxs18(
3996
+ "button",
3997
+ {
3998
+ type: "button",
3999
+ disabled: draft.concernsMe || applying,
4000
+ onClick: () => handleToggleMember(member.memberId),
4001
+ className: cn(
4002
+ "flex items-center gap-2.5 rounded-lg px-3 py-2 text-left transition-all",
4003
+ isSelected ? "border-[var(--color-primary,#3b82f6)] bg-[var(--color-primary-light,#eff6ff)] border" : "border border-transparent hover:bg-[var(--color-bg,#f8fafc)]"
4004
+ ),
4005
+ children: [
4006
+ /* @__PURE__ */ jsx22("div", { className: cn(
4007
+ "flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full text-[10px] font-semibold overflow-hidden",
4008
+ isSelected ? "bg-[var(--color-primary,#3b82f6)] text-white" : "bg-[var(--color-bg,#f8fafc)] text-[var(--color-text-muted,#94a3b8)]"
4009
+ ), children: avatar?.avatarUrl ? /* @__PURE__ */ jsx22("img", { src: avatar.avatarUrl, alt: member.memberName, className: "h-full w-full object-cover" }) : getInitials(member.memberName) }),
4010
+ /* @__PURE__ */ jsxs18("div", { className: "min-w-0 flex-1", children: [
4011
+ /* @__PURE__ */ jsx22("div", { className: cn("truncate text-xs font-medium", isSelected ? "text-[var(--color-primary,#3b82f6)]" : "text-[var(--color-text,#0f172a)]"), children: member.memberName }),
4012
+ /* @__PURE__ */ jsx22("div", { className: "text-[var(--color-text-muted,#94a3b8)] text-[10px]", children: member.memberType === "agent" ? "Agent IA" : "Utilisateur" })
4013
+ ] }),
4014
+ isSelected && /* @__PURE__ */ jsx22("svg", { className: "text-[var(--color-primary,#3b82f6)] flex-shrink-0", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx22("path", { d: "M3 8.5L6 11.5L13 4.5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
4015
+ ]
4016
+ },
4017
+ member._id
4018
+ );
4019
+ }),
4020
+ displayedMembers.length === 0 && /* @__PURE__ */ jsx22("div", { className: "text-[var(--color-text-muted,#94a3b8)] py-4 text-center text-xs italic", children: "Aucun membre dans ce workspace" })
4021
+ ] })
4022
+ ] })
4023
+ ] }),
4024
+ /* @__PURE__ */ jsxs18("div", { className: "border-[var(--color-border,#e2e8f0)] flex items-center justify-between border-t px-6 py-3", children: [
4025
+ /* @__PURE__ */ jsxs18(
4026
+ "button",
4027
+ {
4028
+ type: "button",
4029
+ onClick: () => setDraft({ ...EMPTY_FILTERS }),
4030
+ disabled: applying,
4031
+ className: "text-[var(--color-text-muted,#94a3b8)] hover:text-[var(--color-text,#0f172a)] flex items-center gap-1.5 text-xs transition-colors disabled:opacity-50",
4032
+ children: [
4033
+ /* @__PURE__ */ jsx22(RotateCcw, { size: 12 }),
4034
+ " R\xE9initialiser"
4035
+ ]
4036
+ }
4037
+ ),
4038
+ /* @__PURE__ */ jsxs18("div", { className: "flex gap-2", children: [
4039
+ /* @__PURE__ */ jsx22(
4040
+ "button",
4041
+ {
4042
+ type: "button",
4043
+ onClick: onClose,
4044
+ disabled: applying,
4045
+ className: "border-[var(--color-border,#e2e8f0)] text-[var(--color-text-muted,#94a3b8)] hover:text-[var(--color-text,#0f172a)] rounded-lg border px-4 py-1.5 text-xs font-medium transition-colors disabled:opacity-50",
4046
+ children: "Annuler"
4047
+ }
4048
+ ),
4049
+ /* @__PURE__ */ jsxs18(
4050
+ "button",
4051
+ {
4052
+ type: "button",
4053
+ onClick: handleApply,
4054
+ disabled: applying,
4055
+ className: "bg-[var(--color-primary,#3b82f6)] hover:bg-[var(--color-primary-hover,#2563eb)] flex items-center gap-1.5 rounded-lg px-4 py-1.5 text-xs font-medium text-white transition-colors disabled:opacity-70",
4056
+ children: [
4057
+ applying && /* @__PURE__ */ jsx22(Loader29, { size: 12, className: "animate-spin" }),
4058
+ applying ? "Application..." : "Appliquer"
4059
+ ]
4060
+ }
4061
+ )
4062
+ ] })
4063
+ ] })
4064
+ ]
4065
+ }
4066
+ );
4067
+ };
1812
4068
  export {
1813
4069
  AVAILABLE_AGENTS,
4070
+ ArtefactViewerDialog,
4071
+ Badge,
1814
4072
  CATEGORY_STYLES,
4073
+ ChartRenderer,
4074
+ ConfirmModal,
4075
+ ContextPanel,
1815
4076
  CreatePrivateWorkspaceModal,
1816
4077
  CreateWorkspaceModal,
4078
+ EMPTY_FILTERS,
1817
4079
  FILTER_PILLS,
1818
4080
  ICON_COLOR,
1819
4081
  IGNORED_FIELDS,
1820
4082
  MEMBER_ROLE_LABELS,
1821
4083
  MemberAvatar,
1822
4084
  MembersPanel,
4085
+ MessageFeed,
4086
+ MessageFilterDialog,
4087
+ MessageItem,
1823
4088
  Modal,
1824
4089
  Pagination,
1825
4090
  ROLE_LABELS,
1826
4091
  STATUS_LABELS,
1827
4092
  SyncPanel,
4093
+ TableRenderer,
4094
+ Tooltip,
1828
4095
  WORKSPACE_FIELD_LABELS,
1829
4096
  WORKSPACE_STATUS_LABELS,
4097
+ WorkspaceCard,
1830
4098
  WorkspaceEvent,
4099
+ WorkspaceList,
1831
4100
  WorkspaceProvider,
4101
+ WorkspaceRow,
1832
4102
  cn,
1833
4103
  createWorkspaceApis,
1834
4104
  createWorkspaceClient,
1835
4105
  createWorkspaceListStore,
1836
4106
  createWorkspaceSocket,
4107
+ fixMojibake,
1837
4108
  formatWorkspaceExport,
1838
4109
  getInitials,
1839
4110
  useWorkspaceApi,
1840
- useWorkspaceContext
4111
+ useWorkspaceContext,
4112
+ workspaceStreamdownComponents
1841
4113
  };
1842
4114
  //# sourceMappingURL=index.mjs.map