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