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