@axiom-lattice/react-sdk 2.1.97 → 2.1.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -97,8 +97,8 @@ var AuthProvider = ({
97
97
  onLoginSuccess?.(userData, tenantList || []);
98
98
  return { requiresTenantSelection, hasTenants };
99
99
  } catch (err) {
100
- const message28 = err instanceof Error ? err.message : "Login failed";
101
- setError(message28);
100
+ const message30 = err instanceof Error ? err.message : "Login failed";
101
+ setError(message30);
102
102
  throw err;
103
103
  } finally {
104
104
  setIsLoading(false);
@@ -122,8 +122,8 @@ var AuthProvider = ({
122
122
  }
123
123
  return { message: data.message || "Registration successful!", token: data.data?.token };
124
124
  } catch (err) {
125
- const message28 = err instanceof Error ? err.message : "Registration failed";
126
- setError(message28);
125
+ const message30 = err instanceof Error ? err.message : "Registration failed";
126
+ setError(message30);
127
127
  throw err;
128
128
  } finally {
129
129
  setIsLoading(false);
@@ -182,8 +182,8 @@ var AuthProvider = ({
182
182
  }
183
183
  onTenantSelected?.(tenantData);
184
184
  } catch (err) {
185
- const message28 = err instanceof Error ? err.message : "Failed to select tenant";
186
- setError(message28);
185
+ const message30 = err instanceof Error ? err.message : "Failed to select tenant";
186
+ setError(message30);
187
187
  throw err;
188
188
  } finally {
189
189
  setIsLoading(false);
@@ -222,8 +222,8 @@ var AuthProvider = ({
222
222
  setTenants(tenantList);
223
223
  sessionStorage.setItem("lattice_tenants", JSON.stringify(tenantList));
224
224
  } catch (err) {
225
- const message28 = err instanceof Error ? err.message : "Failed to fetch tenants";
226
- setError(message28);
225
+ const message30 = err instanceof Error ? err.message : "Failed to fetch tenants";
226
+ setError(message30);
227
227
  } finally {
228
228
  setIsLoading(false);
229
229
  }
@@ -253,8 +253,8 @@ var AuthProvider = ({
253
253
  setUser(data);
254
254
  sessionStorage.setItem("lattice_user", JSON.stringify(data));
255
255
  } catch (err) {
256
- const message28 = err instanceof Error ? err.message : "Failed to refresh user";
257
- setError(message28);
256
+ const message30 = err instanceof Error ? err.message : "Failed to refresh user";
257
+ setError(message30);
258
258
  } finally {
259
259
  setIsLoading(false);
260
260
  }
@@ -290,8 +290,8 @@ var AuthProvider = ({
290
290
  const result = await response.json();
291
291
  return result;
292
292
  } catch (err) {
293
- const message28 = err instanceof Error ? err.message : "Failed to change password";
294
- setError(message28);
293
+ const message30 = err instanceof Error ? err.message : "Failed to change password";
294
+ setError(message30);
295
295
  throw err;
296
296
  } finally {
297
297
  setIsLoading(false);
@@ -510,7 +510,7 @@ function useChat(threadId, assistantId, options = {}) {
510
510
  throw new Error("Thread ID is required to send messages");
511
511
  }
512
512
  const { input, command, streaming = true } = data;
513
- const { message: message28, files, ...rest } = input || {};
513
+ const { message: message30, files, ...rest } = input || {};
514
514
  setState((prev) => ({
515
515
  ...prev,
516
516
  isLoading: true,
@@ -519,7 +519,7 @@ function useChat(threadId, assistantId, options = {}) {
519
519
  }));
520
520
  const userMessage = {
521
521
  id: uuidv4(),
522
- content: message28 || command?.resume?.message || "",
522
+ content: message30 || command?.resume?.message || "",
523
523
  files,
524
524
  role: "human"
525
525
  };
@@ -1555,8 +1555,8 @@ function convertThreadToConversationThread(thread, label) {
1555
1555
  function getThreadMetadata(label) {
1556
1556
  return label ? { label } : {};
1557
1557
  }
1558
- function generateLabelFromMessage(message28) {
1559
- const cleanMessage = message28.replace(/```attachments[\s\S]*?```/g, "").trim();
1558
+ function generateLabelFromMessage(message30) {
1559
+ const cleanMessage = message30.replace(/```attachments[\s\S]*?```/g, "").trim();
1560
1560
  if (!cleanMessage) {
1561
1561
  return "";
1562
1562
  }
@@ -2029,7 +2029,7 @@ function AgentThreadProvider({
2029
2029
  throw new Error("Thread ID is required to send messages");
2030
2030
  }
2031
2031
  const { input, command, streaming = true, mode } = data;
2032
- const { message: message28, files, ...rest } = input || {};
2032
+ const { message: message30, files, ...rest } = input || {};
2033
2033
  setState((prev) => ({
2034
2034
  ...prev,
2035
2035
  isLoading: true,
@@ -2038,7 +2038,7 @@ function AgentThreadProvider({
2038
2038
  }));
2039
2039
  const userMessage = {
2040
2040
  id: uuidv42(),
2041
- content: message28 || command?.resume?.message || "",
2041
+ content: message30 || command?.resume?.message || "",
2042
2042
  files,
2043
2043
  role: "human"
2044
2044
  };
@@ -2056,8 +2056,8 @@ function AgentThreadProvider({
2056
2056
  ]
2057
2057
  }));
2058
2058
  const isFirstMessage = messageCountRef.current === 0;
2059
- if (isFirstMessage && message28 && conversationContext) {
2060
- const label = generateLabelFromMessage(message28);
2059
+ if (isFirstMessage && message30 && conversationContext) {
2060
+ const label = generateLabelFromMessage(message30);
2061
2061
  if (label) {
2062
2062
  conversationContext.updateThread({
2063
2063
  id: threadId,
@@ -3954,8 +3954,8 @@ function useTenants(options) {
3954
3954
  const { data } = await response.json();
3955
3955
  setTenants(data || []);
3956
3956
  } catch (err) {
3957
- const message28 = err instanceof Error ? err.message : "Failed to fetch tenants";
3958
- setError(message28);
3957
+ const message30 = err instanceof Error ? err.message : "Failed to fetch tenants";
3958
+ setError(message30);
3959
3959
  } finally {
3960
3960
  setIsLoading(false);
3961
3961
  }
@@ -3997,8 +3997,8 @@ function useUsers(options) {
3997
3997
  const { data } = await response.json();
3998
3998
  setUsers(data || []);
3999
3999
  } catch (err) {
4000
- const message28 = err instanceof Error ? err.message : "Failed to fetch users";
4001
- setError(message28);
4000
+ const message30 = err instanceof Error ? err.message : "Failed to fetch users";
4001
+ setError(message30);
4002
4002
  } finally {
4003
4003
  setIsLoading(false);
4004
4004
  }
@@ -4235,8 +4235,8 @@ var FilePanelToggle = () => {
4235
4235
  };
4236
4236
 
4237
4237
  // src/components/Chat/PinToMenuButton.tsx
4238
- import React74, { useState as useState82, useEffect as useEffect57, useCallback as useCallback42 } from "react";
4239
- import { Button as Button60, Input as Input19, Modal as Modal24, Tooltip as Tooltip26, message as message22 } from "antd";
4238
+ import React74, { useState as useState82, useCallback as useCallback43, useEffect as useEffect57 } from "react";
4239
+ import { Button as Button60, Input as Input19, Modal as Modal24, Tooltip as Tooltip26, AutoComplete, message as message23 } from "antd";
4240
4240
  import { Pin } from "lucide-react";
4241
4241
 
4242
4242
  // src/context/WorkspaceContext.tsx
@@ -4244,16 +4244,16 @@ import React73, {
4244
4244
  createContext as createContext9,
4245
4245
  useContext as useContext11,
4246
4246
  useState as useState81,
4247
- useCallback as useCallback41,
4247
+ useCallback as useCallback42,
4248
4248
  useEffect as useEffect56,
4249
4249
  useRef as useRef30
4250
4250
  } from "react";
4251
4251
  import { WorkspaceClient, Client as Client3 } from "@axiom-lattice/client-sdk";
4252
4252
 
4253
4253
  // src/components/Chat/WorkspaceResourceManager.tsx
4254
- import { useMemo as useMemo35, useEffect as useEffect55, useRef as useRef29, useState as useState80 } from "react";
4255
- import { FolderOpen as FolderOpen3, Activity as Activity4, Database as Database7, Plug as Plug2, Bot as Bot5, Wrench as Wrench2, Zap as Zap2, LogOut as LogOut3, Building2 as Building23, Key, Share2, History, Inbox as Inbox3, FlaskConical as FlaskConical3 } from "lucide-react";
4256
- import { Modal as Modal23, Avatar as Avatar12, Popover as Popover3, Button as Button59 } from "antd";
4254
+ import React72, { useMemo as useMemo35, useEffect as useEffect55, useRef as useRef29, useState as useState80, useCallback as useCallback41 } from "react";
4255
+ import { FolderOpen as FolderOpen3, Activity as Activity4, Database as Database7, Plug as Plug2, Bot as Bot5, Wrench as Wrench2, Zap as Zap2, LogOut as LogOut3, Building2 as Building23, Key, Share2, History, Inbox as Inbox3, FlaskConical as FlaskConical3, PinOff } from "lucide-react";
4256
+ import { Modal as Modal23, Avatar as Avatar12, Popover as Popover3, Button as Button59, message as message22 } from "antd";
4257
4257
 
4258
4258
  // src/components/Chat/ColumnLayout.tsx
4259
4259
  import { PanelLeft, X } from "lucide-react";
@@ -5277,7 +5277,7 @@ var ColumnLayout = ({
5277
5277
 
5278
5278
  // src/components/Chat/Menu.tsx
5279
5279
  import React8, { useState as useState22, useEffect as useEffect15, useMemo as useMemo3, useCallback as useCallback18 } from "react";
5280
- import { Drawer } from "antd";
5280
+ import { Drawer, Dropdown } from "antd";
5281
5281
  import { Plus, ChevronRight, ChevronDown, Cpu, PanelLeftClose } from "lucide-react";
5282
5282
  import { createStyles as createStyles4 } from "antd-style";
5283
5283
  import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
@@ -5383,7 +5383,8 @@ var Menu = ({
5383
5383
  onCollapsedChange,
5384
5384
  className,
5385
5385
  style,
5386
- footer
5386
+ footer,
5387
+ getContextMenuItems
5387
5388
  }) => {
5388
5389
  const { styles: menuStyles } = useMenuStyles();
5389
5390
  const { styles } = useStyle();
@@ -5450,17 +5451,21 @@ var Menu = ({
5450
5451
  /* @__PURE__ */ jsx15("div", { className: styles.iconModeLogo, children: logo || logoIcon || /* @__PURE__ */ jsx15(Cpu, { size: 28, color: "#1677ff" }) }),
5451
5452
  /* @__PURE__ */ jsx15("div", { className: styles.iconModeContainer, children: groupedItems.map(({ group, items: items2 }, groupIndex) => /* @__PURE__ */ jsxs6(React8.Fragment, { children: [
5452
5453
  groupIndex > 0 && /* @__PURE__ */ jsx15("div", { className: styles.iconModeDivider }),
5453
- /* @__PURE__ */ jsx15("div", { className: styles.iconModeGroup, children: items2.map((item) => /* @__PURE__ */ jsx15(
5454
- "button",
5455
- {
5456
- className: styles.iconModeButton,
5457
- onClick: () => handleItemClick(item),
5458
- title: item.name,
5459
- "aria-label": item.name,
5460
- children: /* @__PURE__ */ jsx15("span", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "100%", height: "100%" }, children: item.icon })
5461
- },
5462
- item.id
5463
- )) })
5454
+ /* @__PURE__ */ jsx15("div", { className: styles.iconModeGroup, children: items2.map((item) => {
5455
+ const ctxItems = getContextMenuItems?.(item);
5456
+ const btn = /* @__PURE__ */ jsx15(
5457
+ "button",
5458
+ {
5459
+ className: styles.iconModeButton,
5460
+ onClick: () => handleItemClick(item),
5461
+ title: item.name,
5462
+ "aria-label": item.name,
5463
+ children: /* @__PURE__ */ jsx15("span", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "100%", height: "100%" }, children: item.icon })
5464
+ },
5465
+ item.id
5466
+ );
5467
+ return ctxItems ? /* @__PURE__ */ jsx15(Dropdown, { menu: { items: ctxItems }, trigger: ["contextMenu"], children: btn }, item.id) : btn;
5468
+ }) })
5464
5469
  ] }, group || `group-${groupIndex}`)) }),
5465
5470
  showToggle && /* @__PURE__ */ jsx15(
5466
5471
  "button",
@@ -5499,22 +5504,25 @@ var Menu = ({
5499
5504
  items2.map((item) => {
5500
5505
  const isInline = item.inline ?? false;
5501
5506
  const isExpanded2 = expandedInlineDrawers.has(item.id);
5507
+ const ctxItems = getContextMenuItems?.(item);
5508
+ const btn = /* @__PURE__ */ jsxs6(
5509
+ "button",
5510
+ {
5511
+ className: `${styles.menuItemExpanded} ${isCollapsed ? "collapsed" : ""} ${isExpanded2 ? styles.menuItemExpandedActive : ""}`,
5512
+ onClick: () => handleItemClick(item),
5513
+ title: isCollapsed ? item.name : void 0,
5514
+ "aria-label": item.name,
5515
+ "aria-expanded": isExpanded2,
5516
+ children: [
5517
+ /* @__PURE__ */ jsx15("span", { className: "menu-icon", children: item.icon }),
5518
+ /* @__PURE__ */ jsx15("span", { className: "menu-label", children: item.name }),
5519
+ isInline && !isCollapsed && /* @__PURE__ */ jsx15("span", { className: styles.inlineDrawerIndicator, children: isExpanded2 ? /* @__PURE__ */ jsx15(ChevronDown, { size: 16 }) : /* @__PURE__ */ jsx15(ChevronRight, { size: 16 }) })
5520
+ ]
5521
+ }
5522
+ );
5523
+ const buttonWithContextMenu = ctxItems ? /* @__PURE__ */ jsx15(Dropdown, { menu: { items: ctxItems }, trigger: ["contextMenu"], children: btn }, item.id) : /* @__PURE__ */ jsx15(React8.Fragment, { children: btn }, item.id);
5502
5524
  return /* @__PURE__ */ jsxs6(React8.Fragment, { children: [
5503
- /* @__PURE__ */ jsxs6(
5504
- "button",
5505
- {
5506
- className: `${styles.menuItemExpanded} ${isCollapsed ? "collapsed" : ""} ${isExpanded2 ? styles.menuItemExpandedActive : ""}`,
5507
- onClick: () => handleItemClick(item),
5508
- title: isCollapsed ? item.name : void 0,
5509
- "aria-label": item.name,
5510
- "aria-expanded": isExpanded2,
5511
- children: [
5512
- /* @__PURE__ */ jsx15("span", { className: "menu-icon", children: item.icon }),
5513
- /* @__PURE__ */ jsx15("span", { className: "menu-label", children: item.name }),
5514
- isInline && !isCollapsed && /* @__PURE__ */ jsx15("span", { className: styles.inlineDrawerIndicator, children: isExpanded2 ? /* @__PURE__ */ jsx15(ChevronDown, { size: 16 }) : /* @__PURE__ */ jsx15(ChevronRight, { size: 16 }) })
5515
- ]
5516
- }
5517
- ),
5525
+ buttonWithContextMenu,
5518
5526
  isInline && isExpanded2 && !isCollapsed && /* @__PURE__ */ jsx15("div", { className: styles.inlineDrawerContainer, children: item.content })
5519
5527
  ] }, item.id);
5520
5528
  })
@@ -5677,7 +5685,8 @@ function encodeId(contentType, contentConfig, itemId) {
5677
5685
  const projectId = contentConfig.projectId || "";
5678
5686
  const assistantId = contentConfig.assistantId || "";
5679
5687
  const fileName = encodeURIComponent(contentConfig.fileName || "");
5680
- return `${CUSTOM_MENU_ID_PREFIX}:file:${resourcePath}:${workspaceId}:${projectId}:${assistantId}:${fileName}:${itemId}`;
5688
+ const tenantId = contentConfig.tenantId || "";
5689
+ return `${CUSTOM_MENU_ID_PREFIX}:file:${resourcePath}:${workspaceId}:${projectId}:${assistantId}:${fileName}:${tenantId}:${itemId}`;
5681
5690
  }
5682
5691
  return `${CUSTOM_MENU_ID_PREFIX}:unknown::${itemId}`;
5683
5692
  }
@@ -5696,14 +5705,23 @@ function parseCustomMenuId(id) {
5696
5705
  };
5697
5706
  }
5698
5707
  if (contentType === "file" && parts.length >= 8) {
5708
+ const payload = decodeURIComponent(parts[2]);
5709
+ const workspaceId = parts[3] ?? void 0;
5710
+ const projectId = parts[4] ?? void 0;
5711
+ const assistantId = parts[5] ?? void 0;
5712
+ const fileName = decodeURIComponent(parts[6] || "");
5713
+ const hasTenantId = parts.length >= 9;
5714
+ const tenantId = hasTenantId ? parts[7] ?? void 0 : void 0;
5715
+ const dbId = parts.slice(hasTenantId ? 8 : 7).join(":");
5699
5716
  return {
5700
5717
  contentType,
5701
- payload: decodeURIComponent(parts[2]),
5702
- workspaceId: parts[3] ?? void 0,
5703
- projectId: parts[4] ?? void 0,
5704
- assistantId: parts[5] ?? void 0,
5705
- fileName: decodeURIComponent(parts[6] || ""),
5706
- dbId: parts.slice(7).join(":")
5718
+ payload,
5719
+ workspaceId,
5720
+ projectId,
5721
+ assistantId,
5722
+ fileName,
5723
+ tenantId,
5724
+ dbId
5707
5725
  };
5708
5726
  }
5709
5727
  return {
@@ -5713,7 +5731,8 @@ function parseCustomMenuId(id) {
5713
5731
  };
5714
5732
  }
5715
5733
  function menuItemToSideMenuItemConfig(item) {
5716
- const encodedId = encodeId(item.contentType, item.contentConfig, item.id);
5734
+ const contentConfigWithTenant = item.tenantId ? { ...item.contentConfig, tenantId: item.tenantId } : item.contentConfig;
5735
+ const encodedId = encodeId(item.contentType, contentConfigWithTenant, item.id);
5717
5736
  return {
5718
5737
  id: encodedId,
5719
5738
  type: "route",
@@ -13499,11 +13518,11 @@ var ConfirmFeedback = ({
13499
13518
  data,
13500
13519
  interactive = true
13501
13520
  }) => {
13502
- const { message: message28, type, config, feedback, options } = data ?? {};
13521
+ const { message: message30, type, config, feedback, options } = data ?? {};
13503
13522
  const { sendMessage } = useAgentChat();
13504
13523
  const [clicked, setClicked] = useState36(false);
13505
13524
  return /* @__PURE__ */ jsxs22(Space9, { direction: "vertical", style: { width: "100%" }, children: [
13506
- /* @__PURE__ */ jsx31(MDResponse, { content: message28 }),
13525
+ /* @__PURE__ */ jsx31(MDResponse, { content: message30 }),
13507
13526
  options ? /* @__PURE__ */ jsx31(Space9, { style: { justifyContent: "flex-end", width: "100%" }, children: options?.map((option) => /* @__PURE__ */ jsx31(
13508
13527
  Button17,
13509
13528
  {
@@ -13826,7 +13845,7 @@ var useSideAppOpener = () => {
13826
13845
  import { jsx as jsx33, jsxs as jsxs24 } from "react/jsx-runtime";
13827
13846
  var { Text: Text16 } = Typography16;
13828
13847
  var GenericDataTable = ({ data, interactive = true, default_open_in_side_app = true }) => {
13829
- const { dataSource, message: message28 } = data ?? {};
13848
+ const { dataSource, message: message30 } = data ?? {};
13830
13849
  const [expandedRowKeys, setExpandedRowKeys] = useState38([]);
13831
13850
  const openSideApp = useSideAppOpener();
13832
13851
  const processedData = dataSource?.map((item, index) => ({
@@ -13925,7 +13944,7 @@ var GenericDataTable = ({ data, interactive = true, default_open_in_side_app = t
13925
13944
  type: "text/csv;charset=utf-8;"
13926
13945
  });
13927
13946
  const link = document.createElement("a");
13928
- const filename = `${message28 || "data"}_${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.csv`;
13947
+ const filename = `${message30 || "data"}_${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.csv`;
13929
13948
  link.href = URL.createObjectURL(blob);
13930
13949
  link.download = filename;
13931
13950
  document.body.appendChild(link);
@@ -13946,7 +13965,7 @@ var GenericDataTable = ({ data, interactive = true, default_open_in_side_app = t
13946
13965
  tableLayout: "fixed",
13947
13966
  style: { width: "100% !important" },
13948
13967
  title: () => /* @__PURE__ */ jsxs24(Flex, { justify: "space-between", align: "center", children: [
13949
- /* @__PURE__ */ jsx33(Space11, { children: /* @__PURE__ */ jsx33(Text16, { strong: true, style: { fontSize: 16 }, children: message28 || "" }) }),
13968
+ /* @__PURE__ */ jsx33(Space11, { children: /* @__PURE__ */ jsx33(Text16, { strong: true, style: { fontSize: 16 }, children: message30 || "" }) }),
13950
13969
  /* @__PURE__ */ jsxs24(Space11, { children: [
13951
13970
  /* @__PURE__ */ jsx33(
13952
13971
  Button19,
@@ -13968,8 +13987,8 @@ var GenericDataTable = ({ data, interactive = true, default_open_in_side_app = t
13968
13987
  onClick: () => {
13969
13988
  openSideApp({
13970
13989
  component_key: "generic_data_table",
13971
- message: message28 || "",
13972
- data: { dataSource, message: message28 }
13990
+ message: message30 || "",
13991
+ data: { dataSource, message: message30 }
13973
13992
  });
13974
13993
  },
13975
13994
  children: /* @__PURE__ */ jsx33(ExpandAltOutlined, {})
@@ -16645,7 +16664,7 @@ import {
16645
16664
  } from "react";
16646
16665
  import { jsx as jsx53 } from "react/jsx-runtime";
16647
16666
  var LazyBubble = ({
16648
- message: message28,
16667
+ message: message30,
16649
16668
  renderContent,
16650
16669
  autoLoadRightPanel
16651
16670
  }) => {
@@ -16676,10 +16695,10 @@ var LazyBubble = ({
16676
16695
  autoLoadRightPanel?.();
16677
16696
  }, []);
16678
16697
  const getPlaceholder = () => {
16679
- const estimatedHeight = message28.content ? Math.min(100, message28.content.length / 5) : 100;
16698
+ const estimatedHeight = message30.content ? Math.min(100, message30.content.length / 5) : 100;
16680
16699
  return /* @__PURE__ */ jsx53("div", { style: { height: `${estimatedHeight}px`, minHeight: "50px" } });
16681
16700
  };
16682
- return /* @__PURE__ */ jsx53(ErrorBoundary, { children: /* @__PURE__ */ jsx53("div", { ref, style: { width: "100%" }, children: isVisible || wasEverVisible ? renderContent(message28) : getPlaceholder() }) });
16701
+ return /* @__PURE__ */ jsx53(ErrorBoundary, { children: /* @__PURE__ */ jsx53("div", { ref, style: { width: "100%" }, children: isVisible || wasEverVisible ? renderContent(message30) : getPlaceholder() }) });
16683
16702
  };
16684
16703
  var MemoizedBubbleList = memo(
16685
16704
  ({
@@ -16710,8 +16729,8 @@ var MessageList = ({
16710
16729
  messageLengthRef.current = messages?.length;
16711
16730
  }
16712
16731
  }, [messages?.length]);
16713
- const renderContent = useCallback25((message28) => {
16714
- const { content } = message28;
16732
+ const renderContent = useCallback25((message30) => {
16733
+ const { content } = message30;
16715
16734
  try {
16716
16735
  const json = JSON.parse(content);
16717
16736
  if (json.action && json.message) {
@@ -16719,7 +16738,7 @@ var MessageList = ({
16719
16738
  }
16720
16739
  } catch (error) {
16721
16740
  }
16722
- const tool_calls_md = message28.tool_calls?.map((tool_call) => {
16741
+ const tool_calls_md = message30.tool_calls?.map((tool_call) => {
16723
16742
  return `\`\`\`tool_call
16724
16743
  ${JSON.stringify(tool_call)}
16725
16744
  \`\`\``;
@@ -16728,17 +16747,17 @@ ${JSON.stringify(tool_call)}
16728
16747
  return /* @__PURE__ */ jsx53(Space21, { direction: "vertical", style: { width: "100%" }, children: /* @__PURE__ */ jsx53(MDResponse, { content: content_md }) });
16729
16748
  }, []);
16730
16749
  const items = useMemo11(
16731
- () => messages.map((message28, index) => ({
16732
- key: message28.id,
16733
- role: message28.role,
16750
+ () => messages.map((message30, index) => ({
16751
+ key: message30.id,
16752
+ role: message30.role,
16734
16753
  typing: false,
16735
16754
  content: /* @__PURE__ */ jsx53(
16736
16755
  LazyBubble,
16737
16756
  {
16738
- message: message28,
16757
+ message: message30,
16739
16758
  renderContent,
16740
16759
  autoLoadRightPanel: () => {
16741
- const { content, role: role2 } = message28;
16760
+ const { content, role: role2 } = message30;
16742
16761
  const isNewAddedMessage = messageLengthRef.current > 1 && messageLengthRef.current + 1 === messages.length;
16743
16762
  if (index === messages.length - 1 && isNewAddedMessage && role2 === "ai") {
16744
16763
  try {
@@ -17763,7 +17782,7 @@ var AgentHeader = ({
17763
17782
 
17764
17783
  // src/components/Chat/ThreadManagementButtons.tsx
17765
17784
  import { useCallback as useCallback27, useContext as useContext9 } from "react";
17766
- import { Tooltip as Tooltip12, Button as Button35, Dropdown } from "antd";
17785
+ import { Tooltip as Tooltip12, Button as Button35, Dropdown as Dropdown2 } from "antd";
17767
17786
  import { HistoryOutlined, PlusOutlined as PlusOutlined8 } from "@ant-design/icons";
17768
17787
  import { Fragment as Fragment11, jsx as jsx66, jsxs as jsxs45 } from "react/jsx-runtime";
17769
17788
  var CreateThreadButton = () => {
@@ -17835,7 +17854,7 @@ var ThreadListButton = () => {
17835
17854
  ] : []
17836
17855
  ];
17837
17856
  return /* @__PURE__ */ jsx66(Tooltip12, { title: "Conversation History", children: /* @__PURE__ */ jsx66(
17838
- Dropdown,
17857
+ Dropdown2,
17839
17858
  {
17840
17859
  menu: { items },
17841
17860
  trigger: ["click"],
@@ -23225,12 +23244,12 @@ var formatDate3 = (timestamp) => {
23225
23244
  });
23226
23245
  };
23227
23246
  var MailboxDetailModal = ({
23228
- message: message28,
23247
+ message: message30,
23229
23248
  visible,
23230
23249
  onClose
23231
23250
  }) => {
23232
23251
  const { styles } = useStyles14();
23233
- if (!message28) return null;
23252
+ if (!message30) return null;
23234
23253
  return /* @__PURE__ */ jsx87(
23235
23254
  Modal16,
23236
23255
  {
@@ -23253,12 +23272,12 @@ var MailboxDetailModal = ({
23253
23272
  children: /* @__PURE__ */ jsxs64("div", { className: styles.modalContent, children: [
23254
23273
  /* @__PURE__ */ jsxs64("div", { className: styles.header, children: [
23255
23274
  /* @__PURE__ */ jsx87("div", { className: styles.messageIcon, children: /* @__PURE__ */ jsx87(Mail2, { size: 20 }) }),
23256
- /* @__PURE__ */ jsx87(Text36, { className: styles.messageId, children: message28.id }),
23257
- !message28.read && /* @__PURE__ */ jsx87(Tag21, { color: "red", children: "Unread" })
23275
+ /* @__PURE__ */ jsx87(Text36, { className: styles.messageId, children: message30.id }),
23276
+ !message30.read && /* @__PURE__ */ jsx87(Tag21, { color: "red", children: "Unread" })
23258
23277
  ] }),
23259
23278
  /* @__PURE__ */ jsxs64(Title12, { level: 4, className: styles.title, children: [
23260
23279
  "Message from ",
23261
- message28.from
23280
+ message30.from
23262
23281
  ] }),
23263
23282
  /* @__PURE__ */ jsxs64("div", { className: styles.metaSection, children: [
23264
23283
  /* @__PURE__ */ jsxs64("div", { className: styles.metaItem, children: [
@@ -23268,11 +23287,11 @@ var MailboxDetailModal = ({
23268
23287
  "div",
23269
23288
  {
23270
23289
  className: styles.avatar,
23271
- style: { background: getAvatarColor7(message28.from) },
23272
- children: getInitials7(message28.from)
23290
+ style: { background: getAvatarColor7(message30.from) },
23291
+ children: getInitials7(message30.from)
23273
23292
  }
23274
23293
  ),
23275
- /* @__PURE__ */ jsx87("span", { children: message28.from })
23294
+ /* @__PURE__ */ jsx87("span", { children: message30.from })
23276
23295
  ] })
23277
23296
  ] }),
23278
23297
  /* @__PURE__ */ jsxs64("div", { className: styles.metaItem, children: [
@@ -23282,29 +23301,29 @@ var MailboxDetailModal = ({
23282
23301
  "div",
23283
23302
  {
23284
23303
  className: styles.avatar,
23285
- style: { background: getAvatarColor7(message28.to) },
23286
- children: getInitials7(message28.to)
23304
+ style: { background: getAvatarColor7(message30.to) },
23305
+ children: getInitials7(message30.to)
23287
23306
  }
23288
23307
  ),
23289
- /* @__PURE__ */ jsx87("span", { children: message28.to })
23308
+ /* @__PURE__ */ jsx87("span", { children: message30.to })
23290
23309
  ] })
23291
23310
  ] }),
23292
23311
  /* @__PURE__ */ jsxs64("div", { className: styles.metaItem, children: [
23293
23312
  /* @__PURE__ */ jsx87(Text36, { className: styles.metaLabel, children: "Time" }),
23294
23313
  /* @__PURE__ */ jsxs64("div", { className: styles.metaValue, children: [
23295
23314
  /* @__PURE__ */ jsx87(Calendar2, { size: 14 }),
23296
- /* @__PURE__ */ jsx87("span", { children: formatDate3(message28.timestamp) })
23315
+ /* @__PURE__ */ jsx87("span", { children: formatDate3(message30.timestamp) })
23297
23316
  ] })
23298
23317
  ] }),
23299
23318
  /* @__PURE__ */ jsxs64("div", { className: styles.metaItem, children: [
23300
23319
  /* @__PURE__ */ jsx87(Text36, { className: styles.metaLabel, children: "Type" }),
23301
- /* @__PURE__ */ jsx87("div", { className: styles.metaValue, children: /* @__PURE__ */ jsx87(Tag21, { color: message28.type === "broadcast" ? "blue" : "default", children: message28.type }) })
23320
+ /* @__PURE__ */ jsx87("div", { className: styles.metaValue, children: /* @__PURE__ */ jsx87(Tag21, { color: message30.type === "broadcast" ? "blue" : "default", children: message30.type }) })
23302
23321
  ] })
23303
23322
  ] }),
23304
23323
  /* @__PURE__ */ jsx87(Divider8, {}),
23305
23324
  /* @__PURE__ */ jsxs64("div", { className: styles.contentSection, children: [
23306
23325
  /* @__PURE__ */ jsx87(Text36, { className: styles.contentLabel, children: "Message Content" }),
23307
- /* @__PURE__ */ jsx87("div", { className: styles.contentBox, children: /* @__PURE__ */ jsx87(Paragraph2, { className: styles.messageContent, children: message28.content }) })
23326
+ /* @__PURE__ */ jsx87("div", { className: styles.contentBox, children: /* @__PURE__ */ jsx87(Paragraph2, { className: styles.messageContent, children: message30.content }) })
23308
23327
  ] })
23309
23328
  ] })
23310
23329
  }
@@ -23533,26 +23552,26 @@ var MessageGroupComponent = ({ group, styles, defaultExpanded = true, onMessageC
23533
23552
  ]
23534
23553
  }
23535
23554
  ),
23536
- isExpanded && /* @__PURE__ */ jsx88("div", { className: styles.listGroupContent, children: group.messages.map((message28) => /* @__PURE__ */ jsxs65(
23555
+ isExpanded && /* @__PURE__ */ jsx88("div", { className: styles.listGroupContent, children: group.messages.map((message30) => /* @__PURE__ */ jsxs65(
23537
23556
  "div",
23538
23557
  {
23539
- className: `${styles.listItem} ${!message28.read ? styles.listItemUnread : ""}`,
23540
- onClick: () => onMessageClick(message28),
23558
+ className: `${styles.listItem} ${!message30.read ? styles.listItemUnread : ""}`,
23559
+ onClick: () => onMessageClick(message30),
23541
23560
  children: [
23542
- /* @__PURE__ */ jsx88("div", { className: styles.listItemIcon, children: !message28.read ? /* @__PURE__ */ jsx88("div", { className: styles.unreadBadge }) : /* @__PURE__ */ jsx88(Circle2, { size: 8, style: { color: "#d9d9d9" } }) }),
23561
+ /* @__PURE__ */ jsx88("div", { className: styles.listItemIcon, children: !message30.read ? /* @__PURE__ */ jsx88("div", { className: styles.unreadBadge }) : /* @__PURE__ */ jsx88(Circle2, { size: 8, style: { color: "#d9d9d9" } }) }),
23543
23562
  /* @__PURE__ */ jsxs65("div", { className: styles.listItemContent, children: [
23544
- /* @__PURE__ */ jsx88("span", { className: styles.listItemPreview, children: getMessagePreview(message28.content) }),
23563
+ /* @__PURE__ */ jsx88("span", { className: styles.listItemPreview, children: getMessagePreview(message30.content) }),
23545
23564
  /* @__PURE__ */ jsxs65("span", { className: styles.listItemMeta, children: [
23546
23565
  "To: ",
23547
- message28.to,
23566
+ message30.to,
23548
23567
  " \u2022 ",
23549
- message28.type
23568
+ message30.type
23550
23569
  ] })
23551
23570
  ] }),
23552
- /* @__PURE__ */ jsx88("div", { className: styles.listItemRight, children: /* @__PURE__ */ jsx88("span", { className: styles.listItemDate, children: formatDate4(message28.timestamp) }) })
23571
+ /* @__PURE__ */ jsx88("div", { className: styles.listItemRight, children: /* @__PURE__ */ jsx88("span", { className: styles.listItemDate, children: formatDate4(message30.timestamp) }) })
23553
23572
  ]
23554
23573
  },
23555
- message28.id
23574
+ message30.id
23556
23575
  )) })
23557
23576
  ] });
23558
23577
  };
@@ -23563,12 +23582,12 @@ var MailboxPanel = ({ data }) => {
23563
23582
  const { teamMailbox = [] } = data || {};
23564
23583
  const messageGroups = useMemo17(() => {
23565
23584
  const groupsMap = /* @__PURE__ */ new Map();
23566
- teamMailbox.forEach((message28) => {
23567
- const sender = message28.from;
23585
+ teamMailbox.forEach((message30) => {
23586
+ const sender = message30.from;
23568
23587
  if (!groupsMap.has(sender)) {
23569
23588
  groupsMap.set(sender, []);
23570
23589
  }
23571
- groupsMap.get(sender).push(message28);
23590
+ groupsMap.get(sender).push(message30);
23572
23591
  });
23573
23592
  const groups = Array.from(groupsMap.entries()).map(([sender, messages]) => ({
23574
23593
  sender,
@@ -23585,8 +23604,8 @@ var MailboxPanel = ({ data }) => {
23585
23604
  return groups;
23586
23605
  }, [teamMailbox]);
23587
23606
  const totalUnread = teamMailbox.filter((m) => !m.read).length;
23588
- const handleMessageClick = (message28) => {
23589
- setSelectedMessage(message28);
23607
+ const handleMessageClick = (message30) => {
23608
+ setSelectedMessage(message30);
23590
23609
  setModalVisible(true);
23591
23610
  };
23592
23611
  const handleCloseModal = () => {
@@ -25430,11 +25449,11 @@ var StreamingHTMLRenderer = ({
25430
25449
  if (!iframe || event.source !== iframe.contentWindow) {
25431
25450
  return;
25432
25451
  }
25433
- const message28 = event.data;
25434
- if (!message28 || typeof message28 !== "object") {
25452
+ const message30 = event.data;
25453
+ if (!message30 || typeof message30 !== "object") {
25435
25454
  return;
25436
25455
  }
25437
- switch (message28.type) {
25456
+ switch (message30.type) {
25438
25457
  case "iframe-ready":
25439
25458
  console.log("[StreamingHTMLRenderer] Iframe ready");
25440
25459
  isReadyRef.current = true;
@@ -25449,26 +25468,26 @@ var StreamingHTMLRenderer = ({
25449
25468
  }
25450
25469
  break;
25451
25470
  case "iframe-height":
25452
- if (typeof message28.height === "number" && message28.height > 0) {
25453
- setIframeHeight(message28.height);
25471
+ if (typeof message30.height === "number" && message30.height > 0) {
25472
+ setIframeHeight(message30.height);
25454
25473
  }
25455
25474
  break;
25456
25475
  case "iframe-error": {
25457
25476
  const streamingError = {
25458
25477
  type: "RENDER_ERROR",
25459
- message: message28.error || "Unknown iframe error"
25478
+ message: message30.error || "Unknown iframe error"
25460
25479
  };
25461
25480
  onError?.(streamingError);
25462
25481
  break;
25463
25482
  }
25464
25483
  case "widget-prompt":
25465
- if (typeof message28.text === "string") {
25466
- onPrompt?.(message28.text);
25484
+ if (typeof message30.text === "string") {
25485
+ onPrompt?.(message30.text);
25467
25486
  }
25468
25487
  break;
25469
25488
  case "widget-open-link":
25470
- if (typeof message28.url === "string") {
25471
- window.open(message28.url, "_blank", "noopener,noreferrer");
25489
+ if (typeof message30.url === "string") {
25490
+ window.open(message30.url, "_blank", "noopener,noreferrer");
25472
25491
  }
25473
25492
  break;
25474
25493
  }
@@ -28607,8 +28626,8 @@ var TopologyRuntimeView = () => {
28607
28626
  setRuns((prev) => prev.filter((r) => r.id !== runId));
28608
28627
  setSelectedRun((prev) => prev?.id === runId ? null : prev);
28609
28628
  } catch (err) {
28610
- const message28 = err instanceof Error ? err.message : "Failed to delete run";
28611
- setError(message28);
28629
+ const message30 = err instanceof Error ? err.message : "Failed to delete run";
28630
+ setError(message30);
28612
28631
  }
28613
28632
  }, [del]);
28614
28633
  const refreshRuns = useCallback37(async () => {
@@ -30187,7 +30206,7 @@ var WorkflowAutomationView = () => {
30187
30206
  // src/components/Eval/EvalPanel.tsx
30188
30207
  import React66, { useState as useState75, useMemo as useMemo31 } from "react";
30189
30208
  import { createStyles as createStyles34 } from "antd-style";
30190
- import { Button as Button55, Card as Card28, Typography as Typography59, Row as Row4, Col as Col4, Tag as Tag29, theme as theme15, Dropdown as Dropdown2, Popconfirm as Popconfirm11, message as message18 } from "antd";
30209
+ import { Button as Button55, Card as Card28, Typography as Typography59, Row as Row4, Col as Col4, Tag as Tag29, theme as theme15, Dropdown as Dropdown3, Popconfirm as Popconfirm11, message as message18 } from "antd";
30191
30210
  import { Play as Play2, FlaskConical as FlaskConical2, TestTube2 as TestTube26, TrendingUp, CheckCircle as CheckCircle4, XCircle as XCircle3, ArrowRight as ArrowRight3, ChevronDown as ChevronDown5, Trash2 as Trash27, Clock as Clock5 } from "lucide-react";
30192
30211
 
30193
30212
  // src/components/Eval/EvalSuiteCardList.tsx
@@ -31021,7 +31040,7 @@ var EvalPanel = () => {
31021
31040
  ] }),
31022
31041
  /* @__PURE__ */ jsxs85("div", { className: styles.topRight, children: [
31023
31042
  /* @__PURE__ */ jsx117(
31024
- Dropdown2,
31043
+ Dropdown3,
31025
31044
  {
31026
31045
  menu: {
31027
31046
  items: projects.map((p) => ({
@@ -31244,7 +31263,7 @@ var EvalPanel = () => {
31244
31263
 
31245
31264
  // src/components/Chat/PersonalAssistantPage.tsx
31246
31265
  import { useEffect as useEffect52, useState as useState77, useCallback as useCallback40, useRef as useRef28 } from "react";
31247
- import { Card as Card29, Button as Button57, Input as Input18, Typography as Typography61, message as message20, Dropdown as Dropdown3, Modal as Modal21 } from "antd";
31266
+ import { Card as Card29, Button as Button57, Input as Input18, Typography as Typography61, message as message20, Dropdown as Dropdown4, Modal as Modal21 } from "antd";
31248
31267
  import { createStyles as createStyles36 } from "antd-style";
31249
31268
  import { Bot as Bot4, Sparkles as Sparkles3, ArrowRight as ArrowRight4, ArrowLeft as ArrowLeft3, Smile, Zap, Heart, Lightbulb, Edit3, MoreHorizontal, MessagesSquare as MessagesSquare2, Trash2 as Trash29 } from "lucide-react";
31250
31269
  import { Client as Client2 } from "@axiom-lattice/client-sdk";
@@ -31495,6 +31514,7 @@ var PersonalAssistantChannelModal = ({
31495
31514
  const [selectedId, setSelectedId] = useState76(null);
31496
31515
  const [formMode, setFormMode] = useState76("view");
31497
31516
  const [selectedChannel, setSelectedChannel] = useState76("lark");
31517
+ const [hasPickedChannel, setHasPickedChannel] = useState76(false);
31498
31518
  const [form] = Form9.useForm();
31499
31519
  const [allowOthers, setAllowOthers] = useState76(true);
31500
31520
  const [saving, setSaving] = useState76(false);
@@ -31509,6 +31529,7 @@ var PersonalAssistantChannelModal = ({
31509
31529
  const [qrCountdown, setQrCountdown] = useState76(0);
31510
31530
  const qrCodeRef = useRef27(null);
31511
31531
  const qrCountdownRef = useRef27(null);
31532
+ const bindingsLoadIdRef = useRef27(null);
31512
31533
  const clearQrCountdown = useCallback39(() => {
31513
31534
  if (qrCountdownRef.current) {
31514
31535
  clearInterval(qrCountdownRef.current);
@@ -31607,19 +31628,25 @@ var PersonalAssistantChannelModal = ({
31607
31628
  }
31608
31629
  }, [get]);
31609
31630
  const loadBindings = useCallback39(async (installationId) => {
31631
+ const requestId = installationId;
31632
+ bindingsLoadIdRef.current = requestId;
31610
31633
  setBindingsLoading(true);
31611
31634
  try {
31612
31635
  const res = await get(`/api/channel-bindings?channelInstallationId=${installationId}`);
31636
+ if (bindingsLoadIdRef.current !== requestId) return;
31613
31637
  if (res.success) {
31614
31638
  setBindings(res.data?.records ?? []);
31615
31639
  } else {
31616
31640
  message19.error(res.message || "Failed to load bindings");
31617
31641
  }
31618
31642
  } catch (error) {
31643
+ if (bindingsLoadIdRef.current !== requestId) return;
31619
31644
  console.error("Failed to load bindings:", error);
31620
31645
  message19.error("Failed to load bindings");
31621
31646
  } finally {
31622
- setBindingsLoading(false);
31647
+ if (bindingsLoadIdRef.current === requestId) {
31648
+ setBindingsLoading(false);
31649
+ }
31623
31650
  }
31624
31651
  }, [get]);
31625
31652
  useEffect51(() => {
@@ -31632,6 +31659,7 @@ var PersonalAssistantChannelModal = ({
31632
31659
  setSelectedId(null);
31633
31660
  setFormMode("view");
31634
31661
  setSelectedChannel("lark");
31662
+ setHasPickedChannel(false);
31635
31663
  form.resetFields();
31636
31664
  bindingForm.resetFields();
31637
31665
  setBindings([]);
@@ -31665,7 +31693,8 @@ var PersonalAssistantChannelModal = ({
31665
31693
  setSelectedId(installation.id);
31666
31694
  setFormMode("edit");
31667
31695
  setSelectedChannel(installation.channel);
31668
- setAllowOthers(!installation.rejectWhenNoBinding);
31696
+ setAllowOthers(installation.channel === "wechat" ? true : !installation.rejectWhenNoBinding);
31697
+ form.resetFields();
31669
31698
  if (installation.channel === "lark") {
31670
31699
  form.setFieldsValue({
31671
31700
  name: installation.name,
@@ -31687,6 +31716,7 @@ var PersonalAssistantChannelModal = ({
31687
31716
  setSelectedId(null);
31688
31717
  setFormMode("create");
31689
31718
  setSelectedChannel("lark");
31719
+ setHasPickedChannel(false);
31690
31720
  setBindings([]);
31691
31721
  setAllowOthers(true);
31692
31722
  form.resetFields();
@@ -31699,6 +31729,7 @@ var PersonalAssistantChannelModal = ({
31699
31729
  setSelectedId(null);
31700
31730
  }
31701
31731
  setFormMode("view");
31732
+ setHasPickedChannel(false);
31702
31733
  setBindings([]);
31703
31734
  form.resetFields();
31704
31735
  bindingForm.resetFields();
@@ -31784,7 +31815,7 @@ var PersonalAssistantChannelModal = ({
31784
31815
  const res = await post(
31785
31816
  "/api/channel-installations",
31786
31817
  {
31787
- channel: "lark",
31818
+ channel: selectedChannel,
31788
31819
  name: values.name,
31789
31820
  config,
31790
31821
  rejectWhenNoBinding: !allowOthers,
@@ -31797,6 +31828,7 @@ var PersonalAssistantChannelModal = ({
31797
31828
  setSelectedId(res.data.id);
31798
31829
  setFormMode("edit");
31799
31830
  setBindings([]);
31831
+ loadInstallations();
31800
31832
  message19.info("Now add users who can access this channel");
31801
31833
  } else {
31802
31834
  cancelForm();
@@ -31897,20 +31929,54 @@ var PersonalAssistantChannelModal = ({
31897
31929
  /* @__PURE__ */ jsx119(Text49, { style: { fontSize: 14, color: "var(--color-text-secondary, #666)" }, children: "Select a channel from the left or add a new one" })
31898
31930
  ] });
31899
31931
  }
31932
+ if (formMode === "create" && !hasPickedChannel) {
31933
+ return /* @__PURE__ */ jsxs86("div", { className: styles.rightBody, children: [
31934
+ /* @__PURE__ */ jsx119("div", { className: styles.formSectionTitle, children: "Choose Channel Type" }),
31935
+ /* @__PURE__ */ jsx119("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: channelOptions.map((opt) => /* @__PURE__ */ jsxs86(
31936
+ "div",
31937
+ {
31938
+ onClick: () => {
31939
+ setSelectedChannel(opt.value);
31940
+ setHasPickedChannel(true);
31941
+ form.resetFields();
31942
+ },
31943
+ style: {
31944
+ padding: "16px 20px",
31945
+ border: "2px solid var(--color-border, #d9d9d9)",
31946
+ borderRadius: 12,
31947
+ cursor: "pointer",
31948
+ display: "flex",
31949
+ alignItems: "center",
31950
+ gap: 12,
31951
+ transition: "border-color 0.2s, background 0.2s"
31952
+ },
31953
+ onMouseEnter: (e) => {
31954
+ e.currentTarget.style.borderColor = "var(--color-primary, #6366f1)";
31955
+ e.currentTarget.style.background = "var(--color-primary-bg, #f0f0ff)";
31956
+ },
31957
+ onMouseLeave: (e) => {
31958
+ e.currentTarget.style.borderColor = "var(--color-border, #d9d9d9)";
31959
+ e.currentTarget.style.background = "transparent";
31960
+ },
31961
+ children: [
31962
+ /* @__PURE__ */ jsx119(MessagesSquare, { size: 22, style: { opacity: 0.6 } }),
31963
+ /* @__PURE__ */ jsx119("div", { children: /* @__PURE__ */ jsx119(Text49, { strong: true, style: { fontSize: 14 }, children: opt.label }) })
31964
+ ]
31965
+ },
31966
+ opt.value
31967
+ )) })
31968
+ ] });
31969
+ }
31900
31970
  const isEdit = formMode === "edit" && selectedId !== null;
31901
31971
  return /* @__PURE__ */ jsxs86("div", { className: styles.rightBody, children: [
31902
- /* @__PURE__ */ jsx119("div", { className: styles.formSectionTitle, children: isEdit ? "Edit Channel" : "New Channel" }),
31972
+ /* @__PURE__ */ jsx119("div", { className: styles.formSectionTitle, children: isEdit ? "Edit Channel" : `New ${CHANNEL_LABEL_MAP[selectedChannel] || selectedChannel}` }),
31903
31973
  /* @__PURE__ */ jsxs86(Form9, { form, layout: "vertical", children: [
31904
- /* @__PURE__ */ jsx119(Form9.Item, { label: "Channel Type", children: /* @__PURE__ */ jsx119(
31974
+ isEdit && /* @__PURE__ */ jsx119(Form9.Item, { label: "Channel Type", children: /* @__PURE__ */ jsx119(
31905
31975
  Select9,
31906
31976
  {
31907
31977
  options: channelOptions,
31908
31978
  value: selectedChannel,
31909
- onChange: (val) => {
31910
- setSelectedChannel(val);
31911
- form.resetFields();
31912
- },
31913
- disabled: isEdit
31979
+ disabled: true
31914
31980
  }
31915
31981
  ) }),
31916
31982
  selectedChannel === "lark" && /* @__PURE__ */ jsxs86(Fragment23, { children: [
@@ -32055,7 +32121,7 @@ var PersonalAssistantChannelModal = ({
32055
32121
  }
32056
32122
  )
32057
32123
  ] }),
32058
- /* @__PURE__ */ jsxs86("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 16 }, children: [
32124
+ selectedChannel !== "wechat" && /* @__PURE__ */ jsxs86("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 16 }, children: [
32059
32125
  /* @__PURE__ */ jsxs86("div", { children: [
32060
32126
  /* @__PURE__ */ jsx119(Text49, { strong: true, style: { fontSize: 14 }, children: "Anyone can message" }),
32061
32127
  /* @__PURE__ */ jsx119("br", {}),
@@ -32064,7 +32130,7 @@ var PersonalAssistantChannelModal = ({
32064
32130
  /* @__PURE__ */ jsx119(Switch4, { checked: allowOthers, onChange: setAllowOthers })
32065
32131
  ] })
32066
32132
  ] }),
32067
- !allowOthers && isEdit && /* @__PURE__ */ jsxs86("div", { className: styles.bindingSection, children: [
32133
+ selectedChannel !== "wechat" && !allowOthers && isEdit && /* @__PURE__ */ jsxs86("div", { className: styles.bindingSection, children: [
32068
32134
  /* @__PURE__ */ jsx119("div", { className: styles.bindingHeader, children: "Who can chat" }),
32069
32135
  /* @__PURE__ */ jsx119("div", { className: styles.bindingHint, children: "Only people you add here can message your assistant" }),
32070
32136
  bindingsLoading ? /* @__PURE__ */ jsx119(Spin20, { size: "small", style: { display: "block", margin: "12px 0" } }) : bindings.length === 0 ? /* @__PURE__ */ jsx119(Text49, { type: "secondary", style: { fontSize: 12 }, children: "No contacts added yet" }) : /* @__PURE__ */ jsx119("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: bindings.map((b) => /* @__PURE__ */ jsxs86("div", { className: styles.contactItem, children: [
@@ -32098,7 +32164,7 @@ var PersonalAssistantChannelModal = ({
32098
32164
  name: "senderId",
32099
32165
  rules: [{ required: true, message: "Required" }],
32100
32166
  style: { flex: 1, marginBottom: 0 },
32101
- children: /* @__PURE__ */ jsx119(Input17, { size: "small", placeholder: "Feishu Open ID" })
32167
+ children: /* @__PURE__ */ jsx119(Input17, { size: "small", placeholder: selectedChannel === "wechat" ? "WeChat Open ID" : "Feishu Open ID" })
32102
32168
  }
32103
32169
  ),
32104
32170
  /* @__PURE__ */ jsx119(
@@ -32136,12 +32202,13 @@ var PersonalAssistantChannelModal = ({
32136
32202
  }
32137
32203
  )
32138
32204
  ] }),
32139
- !allowOthers && !isEdit && /* @__PURE__ */ jsx119("div", { className: styles.bindingSection, children: /* @__PURE__ */ jsx119(Text49, { type: "secondary", style: { fontSize: 12 }, children: "Once saved, come back here to add the people you'd like to chat with." }) })
32205
+ selectedChannel !== "wechat" && !allowOthers && !isEdit && /* @__PURE__ */ jsx119("div", { className: styles.bindingSection, children: /* @__PURE__ */ jsx119(Text49, { type: "secondary", style: { fontSize: 12 }, children: "Once saved, come back here to add the people you'd like to chat with." }) })
32140
32206
  ] });
32141
32207
  };
32142
32208
  const renderFooter = () => {
32143
32209
  if (formMode === "view") return null;
32144
32210
  const isEdit = formMode === "edit" && selectedId !== null;
32211
+ const isPicking = formMode === "create" && !hasPickedChannel;
32145
32212
  return /* @__PURE__ */ jsxs86("div", { className: styles.footer, children: [
32146
32213
  /* @__PURE__ */ jsx119("div", { children: isEdit && /* @__PURE__ */ jsx119(
32147
32214
  Popconfirm12,
@@ -32157,7 +32224,7 @@ var PersonalAssistantChannelModal = ({
32157
32224
  ) }),
32158
32225
  /* @__PURE__ */ jsxs86("div", { style: { display: "flex", gap: 8 }, children: [
32159
32226
  /* @__PURE__ */ jsx119(Button56, { onClick: cancelForm, children: "Cancel" }),
32160
- /* @__PURE__ */ jsx119(Button56, { type: "primary", loading: saving, onClick: handleSave, children: isEdit ? "Save" : "Create" })
32227
+ !isPicking && /* @__PURE__ */ jsx119(Button56, { type: "primary", loading: saving, onClick: handleSave, children: isEdit ? "Save" : "Create" })
32161
32228
  ] })
32162
32229
  ] });
32163
32230
  };
@@ -32310,31 +32377,28 @@ var PersonalAssistantPage = () => {
32310
32377
  enter();
32311
32378
  return () => clearTimeout(timer);
32312
32379
  }, [assistantId, resolveThread]);
32313
- const handleDelete = useCallback40(async () => {
32314
- Modal21.confirm({
32315
- title: "Delete your personal assistant?",
32316
- content: "This will permanently delete your assistant, all chat history, and your personal project. This action cannot be undone.",
32317
- okText: "Delete Everything",
32318
- okType: "danger",
32319
- cancelText: "Cancel",
32320
- onOk: async () => {
32321
- try {
32322
- await del("/api/personal-assistant");
32323
- setPersonalAssistant(null);
32324
- setChatMode(false);
32325
- setStep(0);
32326
- setName("");
32327
- setPersonalityKey(null);
32328
- setCustomPersonality("");
32329
- message20.success("Personal assistant deleted");
32330
- } catch {
32331
- message20.error("Network error");
32332
- }
32333
- }
32334
- });
32380
+ const [deleteModalOpen, setDeleteModalOpen] = useState77(false);
32381
+ const [deleting, setDeleting] = useState77(false);
32382
+ const handleDeleteConfirm = useCallback40(async () => {
32383
+ try {
32384
+ setDeleting(true);
32385
+ await del("/api/personal-assistant");
32386
+ setPersonalAssistant(null);
32387
+ setChatMode(false);
32388
+ setStep(0);
32389
+ setName("");
32390
+ setPersonalityKey(null);
32391
+ setCustomPersonality("");
32392
+ message20.success("Personal assistant deleted");
32393
+ setDeleteModalOpen(false);
32394
+ } catch {
32395
+ message20.error("Network error");
32396
+ } finally {
32397
+ setDeleting(false);
32398
+ }
32335
32399
  }, [del, setPersonalAssistant]);
32336
32400
  const moreItems = [
32337
- { key: "delete", icon: /* @__PURE__ */ jsx120(Trash29, { size: 16 }), label: "Delete", danger: true, onClick: handleDelete }
32401
+ { key: "delete", icon: /* @__PURE__ */ jsx120(Trash29, { size: 16 }), label: "Delete", danger: true, onClick: () => setDeleteModalOpen(true) }
32338
32402
  ];
32339
32403
  if (chatMode && assistantId && threadId) {
32340
32404
  return /* @__PURE__ */ jsxs87(Fragment24, { children: [
@@ -32376,7 +32440,7 @@ var PersonalAssistantPage = () => {
32376
32440
  }
32377
32441
  ),
32378
32442
  /* @__PURE__ */ jsx120(FilePanelToggle, {}),
32379
- /* @__PURE__ */ jsx120(Dropdown3, { menu: { items: moreItems }, trigger: ["click"], placement: "bottomRight", children: /* @__PURE__ */ jsx120(Button57, { type: "text", icon: /* @__PURE__ */ jsx120(MoreHorizontal, { size: 18 }) }) })
32443
+ /* @__PURE__ */ jsx120(Dropdown4, { menu: { items: moreItems }, trigger: ["click"], placement: "bottomRight", children: /* @__PURE__ */ jsx120(Button57, { type: "text", icon: /* @__PURE__ */ jsx120(MoreHorizontal, { size: 18 }) }) })
32380
32444
  ] })
32381
32445
  }
32382
32446
  ),
@@ -32387,6 +32451,19 @@ var PersonalAssistantPage = () => {
32387
32451
  open: channelModalOpen,
32388
32452
  onClose: () => setChannelModalOpen(false)
32389
32453
  }
32454
+ ),
32455
+ /* @__PURE__ */ jsx120(
32456
+ Modal21,
32457
+ {
32458
+ title: "Delete your personal assistant?",
32459
+ open: deleteModalOpen,
32460
+ onCancel: () => setDeleteModalOpen(false),
32461
+ onOk: handleDeleteConfirm,
32462
+ okText: "Delete Everything",
32463
+ okButtonProps: { danger: true, loading: deleting },
32464
+ cancelText: "Cancel",
32465
+ children: /* @__PURE__ */ jsx120(Text50, { children: "This will permanently delete your assistant, all chat history, and your personal project. This action cannot be undone." })
32466
+ }
32390
32467
  )
32391
32468
  ] });
32392
32469
  }
@@ -32564,15 +32641,10 @@ var FileView = ({ parsed }) => {
32564
32641
  path: resourcePath.startsWith("/") ? resourcePath : `/${resourcePath}`
32565
32642
  });
32566
32643
  if (parsed.assistantId) params.set("assistantId", parsed.assistantId);
32644
+ if (parsed.tenantId) params.set("tenantId", parsed.tenantId);
32567
32645
  const url = `${baseURL}/api/workspaces/${parsed.workspaceId}/projects/${parsed.projectId}/viewfile?${params}`;
32568
- return /* @__PURE__ */ jsx122(
32569
- "iframe",
32570
- {
32571
- src: url,
32572
- style: IFRAME_STYLE,
32573
- title: parsed.fileName || resourcePath.split("/").pop() || "File"
32574
- }
32575
- );
32646
+ const fileName = parsed.fileName || resourcePath.split("/").pop() || "File";
32647
+ return /* @__PURE__ */ jsx122("div", { style: { width: "100%", height: "100%", overflow: "hidden" }, children: /* @__PURE__ */ jsx122(FileRenderer, { fileUrl: url, fileName, showHeader: true }) });
32576
32648
  };
32577
32649
  var CustomMenuPage = ({ component_key }) => {
32578
32650
  const parsed = parseCustomMenuId(component_key);
@@ -32630,7 +32702,7 @@ var CustomMenuPage = ({ component_key }) => {
32630
32702
 
32631
32703
  // src/components/Chat/SharesPage.tsx
32632
32704
  import { useEffect as useEffect53, useState as useState78 } from "react";
32633
- import { Table as Table5, Button as Button58, Dropdown as Dropdown4, message as message21, Modal as Modal22, Tag as Tag30, Typography as Typography62 } from "antd";
32705
+ import { Table as Table5, Button as Button58, Dropdown as Dropdown5, message as message21, Modal as Modal22, Tag as Tag30, Typography as Typography62 } from "antd";
32634
32706
  import { CopyOutlined as CopyOutlined4, StopOutlined as StopOutlined3, MoreOutlined as MoreOutlined3 } from "@ant-design/icons";
32635
32707
  import { jsx as jsx123, jsxs as jsxs89 } from "react/jsx-runtime";
32636
32708
  var { Text: Text51 } = Typography62;
@@ -32706,7 +32778,7 @@ ${pwdText}`.trim());
32706
32778
  {
32707
32779
  title: "Actions",
32708
32780
  key: "actions",
32709
- render: (_, r) => /* @__PURE__ */ jsx123(Dropdown4, { trigger: ["click"], menu: { items: [
32781
+ render: (_, r) => /* @__PURE__ */ jsx123(Dropdown5, { trigger: ["click"], menu: { items: [
32710
32782
  {
32711
32783
  key: "copy",
32712
32784
  icon: /* @__PURE__ */ jsx123(CopyOutlined4, {}),
@@ -32737,7 +32809,7 @@ import {
32737
32809
  AppstoreOutlined,
32738
32810
  MoreOutlined as MoreOutlined4
32739
32811
  } from "@ant-design/icons";
32740
- import { Dropdown as Dropdown5, Tooltip as Tooltip25 } from "antd";
32812
+ import { Dropdown as Dropdown6, Tooltip as Tooltip25 } from "antd";
32741
32813
  import { createStyles as createStyles37 } from "antd-style";
32742
32814
  import { useEffect as useEffect54, useMemo as useMemo34, useState as useState79 } from "react";
32743
32815
  import { Fragment as Fragment25, jsx as jsx124, jsxs as jsxs90 } from "react/jsx-runtime";
@@ -33061,7 +33133,7 @@ var SideAppViewBrowser = ({ region = "side" }) => {
33061
33133
  /* @__PURE__ */ jsxs90("div", { className: styles.actions, children: [
33062
33134
  items.length > 0 && /* @__PURE__ */ jsx124("div", { className: styles.tabCounter, children: items.length }),
33063
33135
  items.length > 1 && /* @__PURE__ */ jsx124(
33064
- Dropdown5,
33136
+ Dropdown6,
33065
33137
  {
33066
33138
  menu: { items: dropdownItems },
33067
33139
  placement: "bottomRight",
@@ -33282,19 +33354,27 @@ var WorkspaceResourceManager = ({
33282
33354
  const [tenantModalOpen, setTenantModalOpen] = useState80(false);
33283
33355
  const [changePasswordOpen, setChangePasswordOpen] = useState80(false);
33284
33356
  const [fetchedCustomMenuItems, setFetchedCustomMenuItems] = useState80([]);
33285
- useEffect55(() => {
33286
- const fetchCustomMenu = async () => {
33287
- try {
33288
- const json = await get("/api/menu-items?menuTarget=workspace");
33289
- if (json.success && json.data?.records) {
33290
- const items = json.data.records.map(menuItemToSideMenuItemConfig);
33291
- setFetchedCustomMenuItems(items);
33292
- }
33293
- } catch {
33357
+ const { unpin: unpinMenuItem } = usePinMenuActions();
33358
+ const fetchCustomMenu = useCallback41(async () => {
33359
+ try {
33360
+ const json = await get("/api/menu-items?menuTarget=workspace");
33361
+ if (json.success && json.data?.records) {
33362
+ const items = json.data.records.map(menuItemToSideMenuItemConfig);
33363
+ setFetchedCustomMenuItems(items);
33294
33364
  }
33295
- };
33296
- fetchCustomMenu();
33365
+ } catch {
33366
+ }
33297
33367
  }, [get]);
33368
+ useEffect55(() => {
33369
+ fetchCustomMenu();
33370
+ }, [fetchCustomMenu]);
33371
+ useEffect55(() => {
33372
+ const handler = () => {
33373
+ fetchCustomMenu();
33374
+ };
33375
+ window.addEventListener("menu:refresh", handler);
33376
+ return () => window.removeEventListener("menu:refresh", handler);
33377
+ }, [fetchCustomMenu]);
33298
33378
  useEffect55(() => {
33299
33379
  for (const item of fetchedCustomMenuItems) {
33300
33380
  regsiterElement(item.id, {
@@ -33311,6 +33391,31 @@ var WorkspaceResourceManager = ({
33311
33391
  const merged = fetchedCustomMenuItems.length > 0 ? mergeMenuItems(DEFAULT_WORKSPACE_MENU_ITEMS, fetchedCustomMenuItems) : [...DEFAULT_WORKSPACE_MENU_ITEMS];
33312
33392
  return merged;
33313
33393
  }, [config.workspaceMenuItems, fetchedCustomMenuItems]);
33394
+ const getContextMenuItems = useCallback41(
33395
+ (item) => {
33396
+ if (!item.id.startsWith(CUSTOM_MENU_ID_PREFIX)) return null;
33397
+ const parts = item.id.split(":");
33398
+ const dbId = parts[parts.length - 1];
33399
+ if (!dbId) return null;
33400
+ return [
33401
+ {
33402
+ key: "unpin",
33403
+ icon: React72.createElement(PinOff, { size: 14 }),
33404
+ label: "Unpin from Menu",
33405
+ onClick: async () => {
33406
+ try {
33407
+ await unpinMenuItem(dbId);
33408
+ message22.success("Unpinned from menu");
33409
+ window.dispatchEvent(new CustomEvent("menu:refresh"));
33410
+ } catch (err) {
33411
+ message22.error(err.message || "Failed to unpin");
33412
+ }
33413
+ }
33414
+ }
33415
+ ];
33416
+ },
33417
+ [unpinMenuItem]
33418
+ );
33314
33419
  const handleItemClick = (item) => {
33315
33420
  if (item.type === "action" && item.builtin === "switch-tenant") {
33316
33421
  setTenantModalOpen(true);
@@ -33400,6 +33505,7 @@ var WorkspaceResourceManager = ({
33400
33505
  {
33401
33506
  items: menuItems,
33402
33507
  onItemClick: handleItemClick,
33508
+ getContextMenuItems,
33403
33509
  logo,
33404
33510
  logoText: workspaceName || "Workspace",
33405
33511
  showToggle: true,
@@ -33580,14 +33686,14 @@ var WorkspaceContextProvider = ({
33580
33686
  transport: "sse"
33581
33687
  }, tenantId);
33582
33688
  }, [config.baseURL, config.apiKey, tenantId, isAuthenticated]);
33583
- const resetSelectedWorkspace = useCallback41(() => {
33689
+ const resetSelectedWorkspace = useCallback42(() => {
33584
33690
  setProjects([]);
33585
33691
  setWorkspaceId(null);
33586
33692
  sessionStorage.removeItem("workspaceId");
33587
33693
  setProjectId(defaultProjectId ?? null);
33588
33694
  sessionStorage.removeItem("projectId");
33589
33695
  }, [setProjects, setWorkspaceId, setProjectId, defaultProjectId]);
33590
- const resetWS = useCallback41(() => {
33696
+ const resetWS = useCallback42(() => {
33591
33697
  setWorkspaces([]);
33592
33698
  resetSelectedWorkspace();
33593
33699
  }, [resetSelectedWorkspace, setWorkspaces]);
@@ -33595,7 +33701,7 @@ var WorkspaceContextProvider = ({
33595
33701
  resetWS();
33596
33702
  refreshWorkspaces();
33597
33703
  }, [tenantId]);
33598
- const refreshWorkspaces = useCallback41(async () => {
33704
+ const refreshWorkspaces = useCallback42(async () => {
33599
33705
  setLoading(true);
33600
33706
  setError(null);
33601
33707
  try {
@@ -33607,7 +33713,7 @@ var WorkspaceContextProvider = ({
33607
33713
  setLoading(false);
33608
33714
  }
33609
33715
  }, [client]);
33610
- const refreshProjects = useCallback41(async (wsId) => {
33716
+ const refreshProjects = useCallback42(async (wsId) => {
33611
33717
  const targetWorkspaceId = wsId || workspaceId;
33612
33718
  if (!targetWorkspaceId) {
33613
33719
  setProjects([]);
@@ -33657,7 +33763,7 @@ var WorkspaceContextProvider = ({
33657
33763
  }
33658
33764
  prevWorkspaceId.current = workspaceId;
33659
33765
  }, [workspaceId, refreshProjects]);
33660
- const createWorkspace = useCallback41(async (data) => {
33766
+ const createWorkspace = useCallback42(async (data) => {
33661
33767
  setLoading(true);
33662
33768
  setError(null);
33663
33769
  try {
@@ -33672,7 +33778,7 @@ var WorkspaceContextProvider = ({
33672
33778
  setLoading(false);
33673
33779
  }
33674
33780
  }, [client, refreshWorkspaces]);
33675
- const updateWorkspace = useCallback41(async (id, updates) => {
33781
+ const updateWorkspace = useCallback42(async (id, updates) => {
33676
33782
  setLoading(true);
33677
33783
  setError(null);
33678
33784
  try {
@@ -33687,7 +33793,7 @@ var WorkspaceContextProvider = ({
33687
33793
  setLoading(false);
33688
33794
  }
33689
33795
  }, [client, refreshWorkspaces]);
33690
- const deleteWorkspace = useCallback41(async (id) => {
33796
+ const deleteWorkspace = useCallback42(async (id) => {
33691
33797
  setLoading(true);
33692
33798
  setError(null);
33693
33799
  try {
@@ -33704,7 +33810,7 @@ var WorkspaceContextProvider = ({
33704
33810
  setLoading(false);
33705
33811
  }
33706
33812
  }, [client, workspaceId, refreshWorkspaces]);
33707
- const createProject = useCallback41(async (wsId, data) => {
33813
+ const createProject = useCallback42(async (wsId, data) => {
33708
33814
  setLoading(true);
33709
33815
  setError(null);
33710
33816
  try {
@@ -33719,7 +33825,7 @@ var WorkspaceContextProvider = ({
33719
33825
  setLoading(false);
33720
33826
  }
33721
33827
  }, [client, refreshProjects]);
33722
- const updateProject = useCallback41(async (wsId, id, updates) => {
33828
+ const updateProject = useCallback42(async (wsId, id, updates) => {
33723
33829
  setLoading(true);
33724
33830
  setError(null);
33725
33831
  try {
@@ -33734,7 +33840,7 @@ var WorkspaceContextProvider = ({
33734
33840
  setLoading(false);
33735
33841
  }
33736
33842
  }, [client, refreshProjects]);
33737
- const deleteProject = useCallback41(async (wsId, id) => {
33843
+ const deleteProject = useCallback42(async (wsId, id) => {
33738
33844
  setLoading(true);
33739
33845
  setError(null);
33740
33846
  try {
@@ -33751,7 +33857,7 @@ var WorkspaceContextProvider = ({
33751
33857
  setLoading(false);
33752
33858
  }
33753
33859
  }, [client, projectId, refreshProjects]);
33754
- const listPath = useCallback41(
33860
+ const listPath = useCallback42(
33755
33861
  async (path = "/", assistantId) => {
33756
33862
  if (!workspaceId || !projectId) {
33757
33863
  return [];
@@ -33770,7 +33876,7 @@ var WorkspaceContextProvider = ({
33770
33876
  },
33771
33877
  [client, workspaceId, projectId]
33772
33878
  );
33773
- const listPathByFolder = useCallback41(
33879
+ const listPathByFolder = useCallback42(
33774
33880
  async (folder, assistantId) => {
33775
33881
  let normalizedPath = folder;
33776
33882
  if (normalizedPath.startsWith("~/")) {
@@ -33783,7 +33889,7 @@ var WorkspaceContextProvider = ({
33783
33889
  },
33784
33890
  [listPath]
33785
33891
  );
33786
- const uploadFile = useCallback41(
33892
+ const uploadFile = useCallback42(
33787
33893
  async (path, file, assistantId) => {
33788
33894
  if (!workspaceId || !projectId) {
33789
33895
  throw new Error("Workspace and project must be selected before uploading files");
@@ -33803,7 +33909,7 @@ var WorkspaceContextProvider = ({
33803
33909
  },
33804
33910
  [client, workspaceId, projectId]
33805
33911
  );
33806
- const uploadFileToFolder = useCallback41(
33912
+ const uploadFileToFolder = useCallback42(
33807
33913
  async (folder, file, assistantId) => {
33808
33914
  let normalizedFolder = folder;
33809
33915
  if (normalizedFolder.startsWith("~/")) {
@@ -33813,7 +33919,7 @@ var WorkspaceContextProvider = ({
33813
33919
  },
33814
33920
  [uploadFile]
33815
33921
  );
33816
- const getFileViewUrl = useCallback41(
33922
+ const getFileViewUrl = useCallback42(
33817
33923
  (filePath, assistantId) => {
33818
33924
  if (!workspaceId || !projectId) {
33819
33925
  return "";
@@ -33822,7 +33928,7 @@ var WorkspaceContextProvider = ({
33822
33928
  },
33823
33929
  [client, workspaceId, projectId]
33824
33930
  );
33825
- const shareFile = useCallback41(
33931
+ const shareFile = useCallback42(
33826
33932
  async (filePath, assistantId, options) => {
33827
33933
  if (!workspaceId || !projectId) {
33828
33934
  throw new Error("Workspace and project must be selected");
@@ -33835,13 +33941,13 @@ var WorkspaceContextProvider = ({
33835
33941
  },
33836
33942
  [client, workspaceId, projectId]
33837
33943
  );
33838
- const listShares = useCallback41(
33944
+ const listShares = useCallback42(
33839
33945
  async () => {
33840
33946
  return client.resources.listShares();
33841
33947
  },
33842
33948
  [client]
33843
33949
  );
33844
- const unshareFile = useCallback41(
33950
+ const unshareFile = useCallback42(
33845
33951
  async (token) => {
33846
33952
  await client.resources.unshare(token);
33847
33953
  },
@@ -33894,6 +34000,122 @@ var WorkspaceContextProvider = ({
33894
34000
 
33895
34001
  // src/components/Chat/PinToMenuButton.tsx
33896
34002
  import { Fragment as Fragment26, jsx as jsx127, jsxs as jsxs92 } from "react/jsx-runtime";
34003
+ function buildPinContentConfig(params) {
34004
+ const { contentType, assistantId, contentConfig, workspaceId, projectId } = params;
34005
+ if (contentType === "agent") {
34006
+ return {
34007
+ agentId: assistantId,
34008
+ workspaceId: workspaceId || void 0,
34009
+ projectId: projectId || void 0
34010
+ };
34011
+ }
34012
+ return {
34013
+ ...contentConfig,
34014
+ workspaceId: workspaceId || void 0,
34015
+ projectId: projectId || void 0
34016
+ };
34017
+ }
34018
+ async function checkPinStatus(get, params, enableCustomMenu) {
34019
+ const { contentType, assistantId, contentConfig, isMatch } = params;
34020
+ const hasTarget = contentType === "agent" ? !!assistantId : !!contentConfig;
34021
+ if (!hasTarget || !enableCustomMenu) {
34022
+ return { isPinned: false, pinnedId: null };
34023
+ }
34024
+ const json = await get("/api/menu-items?menuTarget=workspace");
34025
+ if (json.success && json.data?.records) {
34026
+ const matchFn = isMatch ?? ((cfg) => contentType === "agent" && cfg.agentId === assistantId);
34027
+ const pinned = json.data.records.find(
34028
+ (item) => item.contentType === contentType && matchFn(item.contentConfig)
34029
+ );
34030
+ if (pinned) {
34031
+ return { isPinned: true, pinnedId: pinned.id };
34032
+ }
34033
+ }
34034
+ return { isPinned: false, pinnedId: null };
34035
+ }
34036
+ async function pinItem(post, params) {
34037
+ const { contentType, name, group } = params;
34038
+ const contentConfig = buildPinContentConfig(params);
34039
+ const body = {
34040
+ menuTarget: "workspace",
34041
+ contentType,
34042
+ contentConfig,
34043
+ group: group?.trim() || void 0,
34044
+ name: name.trim(),
34045
+ sortOrder: 0
34046
+ };
34047
+ const json = await post(
34048
+ "/api/menu-items",
34049
+ body
34050
+ );
34051
+ if (!json.success) {
34052
+ throw new Error(json.message || "Failed to pin");
34053
+ }
34054
+ return { id: json.data.id };
34055
+ }
34056
+ async function unpinItem(del, pinnedId) {
34057
+ const json = await del(`/api/menu-items/${pinnedId}`);
34058
+ if (!json.success) {
34059
+ throw new Error(json.message || "Failed to unpin");
34060
+ }
34061
+ }
34062
+ function usePinMenuActions() {
34063
+ const workspaceCtx = React74.useContext(WorkspaceContext);
34064
+ const { config } = useLatticeChatShellContext();
34065
+ const { post, get, del } = useApi();
34066
+ const enableCustomMenu = config.enableCustomMenu ?? false;
34067
+ const check = useCallback43(
34068
+ async (params) => checkPinStatus(get, params, enableCustomMenu),
34069
+ [get, enableCustomMenu]
34070
+ );
34071
+ const pin = useCallback43(
34072
+ async (params) => pinItem(post, {
34073
+ ...params,
34074
+ workspaceId: workspaceCtx?.workspaceId,
34075
+ projectId: workspaceCtx?.projectId
34076
+ }),
34077
+ [post, workspaceCtx]
34078
+ );
34079
+ const unpin = useCallback43(
34080
+ async (pinnedId) => unpinItem(del, pinnedId),
34081
+ [del]
34082
+ );
34083
+ return { check, pin, unpin, enableCustomMenu, get };
34084
+ }
34085
+ function extractGroups(items) {
34086
+ const groups = /* @__PURE__ */ new Set();
34087
+ for (const item of items) {
34088
+ if (item.group?.trim()) {
34089
+ groups.add(item.group.trim());
34090
+ }
34091
+ }
34092
+ return Array.from(groups).sort();
34093
+ }
34094
+ function useMenuGroups() {
34095
+ const { config } = useLatticeChatShellContext();
34096
+ const defaultGroups = React74.useMemo(() => extractGroups(DEFAULT_WORKSPACE_MENU_ITEMS), []);
34097
+ const configGroups = React74.useMemo(
34098
+ () => extractGroups(config.workspaceMenuItems ?? []),
34099
+ [config.workspaceMenuItems]
34100
+ );
34101
+ return React74.useMemo(
34102
+ () => Array.from(/* @__PURE__ */ new Set([...defaultGroups, ...configGroups])).sort(),
34103
+ [defaultGroups, configGroups]
34104
+ );
34105
+ }
34106
+ async function fetchExistingGroups(get) {
34107
+ const json = await get("/api/menu-items?menuTarget=workspace");
34108
+ if (json.success && json.data?.records) {
34109
+ const groups = /* @__PURE__ */ new Set();
34110
+ for (const item of json.data.records) {
34111
+ if (item.group?.trim()) {
34112
+ groups.add(item.group.trim());
34113
+ }
34114
+ }
34115
+ return Array.from(groups).sort();
34116
+ }
34117
+ return [];
34118
+ }
33897
34119
  var MODAL_BODY_STYLE = {
33898
34120
  display: "flex",
33899
34121
  flexDirection: "column",
@@ -33908,9 +34130,7 @@ var PinToMenuButton = ({
33908
34130
  label,
33909
34131
  block
33910
34132
  }) => {
33911
- const workspaceCtx = React74.useContext(WorkspaceContext);
33912
- const { config } = useLatticeChatShellContext();
33913
- const { post, get, del } = useApi();
34133
+ const { check, pin, unpin, enableCustomMenu, get } = usePinMenuActions();
33914
34134
  const [open, setOpen] = useState82(false);
33915
34135
  const [group, setGroup] = useState82("");
33916
34136
  const [name, setName] = useState82("");
@@ -33918,77 +34138,61 @@ var PinToMenuButton = ({
33918
34138
  const [isPinned, setIsPinned] = useState82(false);
33919
34139
  const [pinnedItemId, setPinnedItemId] = useState82(null);
33920
34140
  const [checking, setChecking] = useState82(true);
34141
+ const staticGroups = useMenuGroups();
34142
+ const [existingGroups, setExistingGroups] = useState82(staticGroups);
34143
+ useEffect57(() => {
34144
+ setExistingGroups(staticGroups);
34145
+ }, [staticGroups]);
34146
+ useEffect57(() => {
34147
+ if (open) {
34148
+ fetchExistingGroups(get).then((apiGroups) => {
34149
+ setExistingGroups(Array.from(/* @__PURE__ */ new Set([...staticGroups, ...apiGroups])).sort());
34150
+ });
34151
+ }
34152
+ }, [open]);
33921
34153
  const hasTarget = contentType === "agent" ? !!assistantId : !!externalContentConfig;
33922
- const checkPinned = useCallback42(async () => {
33923
- if (!hasTarget || !config.enableCustomMenu) {
34154
+ const checkPinned = useCallback43(async () => {
34155
+ if (!hasTarget || !enableCustomMenu) {
33924
34156
  setChecking(false);
33925
34157
  return;
33926
34158
  }
33927
34159
  setChecking(true);
33928
34160
  try {
33929
- const json = await get(
33930
- "/api/menu-items?menuTarget=workspace"
33931
- );
33932
- if (json.success && json.data?.records) {
33933
- const matchFn = isMatch ?? ((cfg) => {
33934
- return contentType === "agent" && cfg.agentId === assistantId;
33935
- });
33936
- const pinned = json.data.records.find(
33937
- (item) => item.contentType === contentType && matchFn(item.contentConfig)
33938
- );
33939
- if (pinned) {
33940
- setIsPinned(true);
33941
- setPinnedItemId(pinned.id);
33942
- } else {
33943
- setIsPinned(false);
33944
- setPinnedItemId(null);
33945
- }
33946
- }
34161
+ const result = await check({ contentType, assistantId, contentConfig: externalContentConfig, isMatch });
34162
+ setIsPinned(result.isPinned);
34163
+ setPinnedItemId(result.pinnedId);
33947
34164
  } catch {
33948
34165
  } finally {
33949
34166
  setChecking(false);
33950
34167
  }
33951
- }, [hasTarget, config.enableCustomMenu, get, contentType, assistantId, isMatch]);
34168
+ }, [hasTarget, enableCustomMenu, check, contentType, assistantId, externalContentConfig, isMatch]);
33952
34169
  useEffect57(() => {
33953
34170
  checkPinned();
33954
34171
  }, [checkPinned]);
33955
- if (!hasTarget || !config.enableCustomMenu) return null;
34172
+ if (!hasTarget || !enableCustomMenu) return null;
33956
34173
  const handlePin = async () => {
33957
34174
  if (!name.trim()) {
33958
- message22.warning("Please enter a menu name");
34175
+ message23.warning("Please enter a menu name");
33959
34176
  return;
33960
34177
  }
33961
34178
  setLoading(true);
33962
34179
  try {
33963
- const contentConfig = contentType === "agent" ? {
33964
- agentId: assistantId,
33965
- workspaceId: workspaceCtx?.workspaceId || void 0,
33966
- projectId: workspaceCtx?.projectId || void 0
33967
- } : {
33968
- ...externalContentConfig,
33969
- workspaceId: workspaceCtx?.workspaceId || void 0,
33970
- projectId: workspaceCtx?.projectId || void 0
33971
- };
33972
- const body = {
33973
- menuTarget: "workspace",
34180
+ await pin({
33974
34181
  contentType,
33975
- contentConfig,
33976
- group: group.trim() || void 0,
34182
+ assistantId,
34183
+ contentConfig: externalContentConfig,
34184
+ isMatch,
33977
34185
  name: name.trim(),
33978
- sortOrder: 0
33979
- };
33980
- const json = await post("/api/menu-items", body);
33981
- if (json.success) {
33982
- message22.success("Pinned to menu");
33983
- setOpen(false);
33984
- setGroup("");
33985
- setName("");
33986
- checkPinned();
33987
- } else {
33988
- message22.error(json.message || "Failed to pin");
33989
- }
33990
- } catch {
33991
- message22.error("Failed to pin to menu");
34186
+ group: group.trim() || void 0
34187
+ });
34188
+ message23.success("Pinned to menu");
34189
+ window.dispatchEvent(new CustomEvent("menu:refresh"));
34190
+ setOpen(false);
34191
+ setGroup("");
34192
+ setName("");
34193
+ checkPinned();
34194
+ } catch (err) {
34195
+ message23.error(err.message || "Failed to pin to menu");
33992
34196
  } finally {
33993
34197
  setLoading(false);
33994
34198
  }
@@ -33997,16 +34201,13 @@ var PinToMenuButton = ({
33997
34201
  if (!pinnedItemId) return;
33998
34202
  setLoading(true);
33999
34203
  try {
34000
- const json = await del(`/api/menu-items/${pinnedItemId}`);
34001
- if (json.success) {
34002
- message22.success("Unpinned from menu");
34003
- setIsPinned(false);
34004
- setPinnedItemId(null);
34005
- } else {
34006
- message22.error(json.message || "Failed to unpin");
34007
- }
34008
- } catch {
34009
- message22.error("Failed to unpin from menu");
34204
+ await unpin(pinnedItemId);
34205
+ message23.success("Unpinned from menu");
34206
+ window.dispatchEvent(new CustomEvent("menu:refresh"));
34207
+ setIsPinned(false);
34208
+ setPinnedItemId(null);
34209
+ } catch (err) {
34210
+ message23.error(err.message || "Failed to unpin from menu");
34010
34211
  } finally {
34011
34212
  setLoading(false);
34012
34213
  }
@@ -34060,11 +34261,13 @@ var PinToMenuButton = ({
34060
34261
  }
34061
34262
  ),
34062
34263
  /* @__PURE__ */ jsx127(
34063
- Input19,
34264
+ AutoComplete,
34064
34265
  {
34065
- placeholder: "Group (optional, e.g. Process)",
34266
+ placeholder: "Group (optional, select or type new)",
34066
34267
  value: group,
34067
- onChange: (e) => setGroup(e.target.value)
34268
+ options: existingGroups.map((g) => ({ value: g })),
34269
+ onChange: (val) => setGroup(val),
34270
+ filterOption: (inputValue, option) => option?.value?.toUpperCase().includes(inputValue.toUpperCase()) ?? false
34068
34271
  }
34069
34272
  )
34070
34273
  ] })
@@ -34077,8 +34280,8 @@ var PinToMenuButton = ({
34077
34280
  import { createStyles as createStyles40 } from "antd-style";
34078
34281
 
34079
34282
  // src/components/Chat/ProjectSelector.tsx
34080
- import { useState as useState83, useCallback as useCallback43, useMemo as useMemo36, useRef as useRef31 } from "react";
34081
- import { Modal as Modal25, Input as Input20, Button as Button61, message as message23 } from "antd";
34283
+ import { useState as useState83, useCallback as useCallback44, useMemo as useMemo36, useRef as useRef31 } from "react";
34284
+ import { Modal as Modal25, Input as Input20, Button as Button61, message as message24 } from "antd";
34082
34285
  import { createStyles as createStyles38 } from "antd-style";
34083
34286
  import { Folder, ChevronDown as ChevronDown6, Building2 as Building24 } from "lucide-react";
34084
34287
  import { Fragment as Fragment27, jsx as jsx128, jsxs as jsxs93 } from "react/jsx-runtime";
@@ -34327,20 +34530,20 @@ var ProjectSelector = ({
34327
34530
  const currentWorkspace = useMemo36(() => {
34328
34531
  return workspaces.find((w) => w.id === workspaceId);
34329
34532
  }, [workspaces, workspaceId]);
34330
- const handleSelectProject = useCallback43((selectedProjectId) => {
34533
+ const handleSelectProject = useCallback44((selectedProjectId) => {
34331
34534
  setProject(selectedProjectId);
34332
34535
  setIsProjectListOpen(false);
34333
34536
  }, [setProject]);
34334
- const handleWorkspaceClick = useCallback43(() => {
34537
+ const handleWorkspaceClick = useCallback44(() => {
34335
34538
  setProject(null);
34336
34539
  }, [setProject]);
34337
- const toggleProjectList = useCallback43(() => {
34540
+ const toggleProjectList = useCallback44(() => {
34338
34541
  setIsProjectListOpen((prev) => !prev);
34339
34542
  }, []);
34340
- const toggleWorkspaceList = useCallback43(() => {
34543
+ const toggleWorkspaceList = useCallback44(() => {
34341
34544
  setIsWorkspaceListOpen((prev) => !prev);
34342
34545
  }, []);
34343
- const validateProjectName = useCallback43((name) => {
34546
+ const validateProjectName = useCallback44((name) => {
34344
34547
  const trimmed = name.trim();
34345
34548
  if (!trimmed) return "Project name is required";
34346
34549
  if (trimmed.length > PROJECT_NAME_MAX_LENGTH) {
@@ -34348,10 +34551,10 @@ var ProjectSelector = ({
34348
34551
  }
34349
34552
  return null;
34350
34553
  }, []);
34351
- const handleOpenModal = useCallback43((e) => {
34554
+ const handleOpenModal = useCallback44((e) => {
34352
34555
  e.stopPropagation();
34353
34556
  if (!workspaceId) {
34354
- message23.warning("Please select a workspace first");
34557
+ message24.warning("Please select a workspace first");
34355
34558
  return;
34356
34559
  }
34357
34560
  setProjectName("");
@@ -34359,7 +34562,7 @@ var ProjectSelector = ({
34359
34562
  setIsModalOpen(true);
34360
34563
  setTimeout(() => projectNameInputRef.current?.input?.focus(), 100);
34361
34564
  }, [workspaceId]);
34362
- const handleCloseModal = useCallback43(() => {
34565
+ const handleCloseModal = useCallback44(() => {
34363
34566
  setIsModalOpen(false);
34364
34567
  setProjectName("");
34365
34568
  setValidationError(null);
@@ -34369,7 +34572,7 @@ var ProjectSelector = ({
34369
34572
  setProjectName(value);
34370
34573
  setValidationError(validateProjectName(value));
34371
34574
  };
34372
- const handleCreateProject = useCallback43(async () => {
34575
+ const handleCreateProject = useCallback44(async () => {
34373
34576
  if (!workspaceId) return;
34374
34577
  const trimmed = projectName.trim();
34375
34578
  const error = validateProjectName(trimmed);
@@ -34385,7 +34588,7 @@ var ProjectSelector = ({
34385
34588
  setProjectName("");
34386
34589
  setValidationError(null);
34387
34590
  setProject(project.id);
34388
- message23.success(`Project "${project.name}" created`);
34591
+ message24.success(`Project "${project.name}" created`);
34389
34592
  } catch (err) {
34390
34593
  const errMsg = err instanceof Error ? err.message : "Failed to create project";
34391
34594
  setValidationError(errMsg);
@@ -34488,13 +34691,13 @@ var ProjectSelector = ({
34488
34691
  };
34489
34692
 
34490
34693
  // src/components/Chat/ToolPanelFiles.tsx
34491
- import { useCallback as useCallback44, useEffect as useEffect58, useMemo as useMemo37, useState as useState85 } from "react";
34492
- import { message as message24 } from "antd";
34694
+ import { useCallback as useCallback46, useEffect as useEffect59, useMemo as useMemo37, useState as useState85 } from "react";
34695
+ import { message as message26 } from "antd";
34493
34696
 
34494
34697
  // src/components/Chat/FileDirectoryPanel.tsx
34495
- import React76, { useState as useState84 } from "react";
34496
- import { Spin as Spin23, Dropdown as Dropdown6, Button as Button62 } from "antd";
34497
- import { ChevronRight as ChevronRight8, FolderOpen as FolderOpen4, Upload } from "lucide-react";
34698
+ import React76, { useState as useState84, useCallback as useCallback45, useEffect as useEffect58 } from "react";
34699
+ import { Spin as Spin23, Dropdown as Dropdown7, Button as Button62, Input as Input21, Modal as Modal26, AutoComplete as AutoComplete2, message as message25 } from "antd";
34700
+ import { ChevronRight as ChevronRight8, FolderOpen as FolderOpen4, Upload, Pin as Pin2 } from "lucide-react";
34498
34701
  import { createStyles as createStyles39 } from "antd-style";
34499
34702
  import { MoreOutlined as MoreOutlined5, LinkOutlined as LinkOutlined5, DownloadOutlined as DownloadOutlined4, EyeOutlined } from "@ant-design/icons";
34500
34703
  import { Fragment as Fragment28, jsx as jsx129, jsxs as jsxs94 } from "react/jsx-runtime";
@@ -34711,6 +34914,11 @@ var getFileName = (path) => {
34711
34914
  return parts[parts.length - 1];
34712
34915
  };
34713
34916
  var getEntryName = (entry) => getFileName(entry.name || entry.path);
34917
+ var MODAL_BODY_STYLE2 = {
34918
+ display: "flex",
34919
+ flexDirection: "column",
34920
+ gap: 12
34921
+ };
34714
34922
  var FileDirectoryPanel = ({
34715
34923
  workspaceId,
34716
34924
  projectId,
@@ -34730,6 +34938,116 @@ var FileDirectoryPanel = ({
34730
34938
  const { currentAssistant } = useAssistantContext();
34731
34939
  const { getFileViewUrl } = useWorkspaceContext();
34732
34940
  const [sharePath, setSharePath] = useState84(null);
34941
+ const { check: checkPin, pin: doPin, unpin: doUnpin, enableCustomMenu, get } = usePinMenuActions();
34942
+ const staticGroups = useMenuGroups();
34943
+ const [existingGroups, setExistingGroups] = useState84(staticGroups);
34944
+ useEffect58(() => {
34945
+ setExistingGroups(staticGroups);
34946
+ }, [staticGroups]);
34947
+ const [pinStates, setPinStates] = useState84({});
34948
+ const [pinModalPath, setPinModalPath] = useState84(null);
34949
+ const [pinName, setPinName] = useState84("");
34950
+ const [pinGroup, setPinGroup] = useState84("");
34951
+ const [pinLoading, setPinLoading] = useState84(false);
34952
+ useEffect58(() => {
34953
+ if (pinModalPath) {
34954
+ fetchExistingGroups(get).then((apiGroups) => {
34955
+ setExistingGroups(Array.from(/* @__PURE__ */ new Set([...staticGroups, ...apiGroups])).sort());
34956
+ });
34957
+ }
34958
+ }, [pinModalPath]);
34959
+ const handleDropdownOpen = useCallback45(
34960
+ (filePath, open) => {
34961
+ if (!open || !enableCustomMenu) return;
34962
+ setPinStates((prev) => {
34963
+ if (prev[filePath]) return prev;
34964
+ return {
34965
+ ...prev,
34966
+ [filePath]: { isPinned: false, pinnedId: null, loading: true }
34967
+ };
34968
+ });
34969
+ const params = {
34970
+ contentType: "file",
34971
+ contentConfig: {
34972
+ resourcePath: filePath,
34973
+ assistantId: currentAssistant?.id || "",
34974
+ fileName: filePath.split("/").pop() || filePath
34975
+ },
34976
+ isMatch: (cfg) => cfg.resourcePath === filePath
34977
+ };
34978
+ checkPin(params).then((result) => {
34979
+ setPinStates((prev) => ({
34980
+ ...prev,
34981
+ [filePath]: { ...result, loading: false }
34982
+ }));
34983
+ }).catch(() => {
34984
+ setPinStates((prev) => ({
34985
+ ...prev,
34986
+ [filePath]: { isPinned: false, pinnedId: null, loading: false }
34987
+ }));
34988
+ });
34989
+ },
34990
+ [enableCustomMenu, checkPin, currentAssistant?.id]
34991
+ );
34992
+ const handlePinSubmit = async () => {
34993
+ if (!pinModalPath || !pinName.trim()) {
34994
+ message25.warning("Please enter a menu name");
34995
+ return;
34996
+ }
34997
+ setPinLoading(true);
34998
+ try {
34999
+ const fileName = pinModalPath.split("/").pop() || pinModalPath;
35000
+ await doPin({
35001
+ contentType: "file",
35002
+ name: pinName.trim(),
35003
+ group: pinGroup.trim() || void 0,
35004
+ contentConfig: {
35005
+ resourcePath: pinModalPath,
35006
+ assistantId: currentAssistant?.id || "",
35007
+ fileName
35008
+ },
35009
+ isMatch: (cfg) => cfg.resourcePath === pinModalPath
35010
+ });
35011
+ message25.success("Pinned to menu");
35012
+ window.dispatchEvent(new CustomEvent("menu:refresh"));
35013
+ setPinModalPath(null);
35014
+ setPinName("");
35015
+ setPinGroup("");
35016
+ setPinStates((prev) => {
35017
+ const copy = { ...prev };
35018
+ delete copy[pinModalPath];
35019
+ return copy;
35020
+ });
35021
+ } catch (err) {
35022
+ message25.error(err.message || "Failed to pin");
35023
+ } finally {
35024
+ setPinLoading(false);
35025
+ }
35026
+ };
35027
+ const handleUnpin = useCallback45(
35028
+ async (filePath, pinnedId) => {
35029
+ setPinStates((prev) => ({
35030
+ ...prev,
35031
+ [filePath]: { ...prev[filePath], loading: true }
35032
+ }));
35033
+ try {
35034
+ await doUnpin(pinnedId);
35035
+ message25.success("Unpinned from menu");
35036
+ window.dispatchEvent(new CustomEvent("menu:refresh"));
35037
+ setPinStates((prev) => ({
35038
+ ...prev,
35039
+ [filePath]: { isPinned: false, pinnedId: null, loading: false }
35040
+ }));
35041
+ } catch (err) {
35042
+ message25.error(err.message || "Failed to unpin");
35043
+ setPinStates((prev) => ({
35044
+ ...prev,
35045
+ [filePath]: { ...prev[filePath], loading: false }
35046
+ }));
35047
+ }
35048
+ },
35049
+ [doUnpin]
35050
+ );
34733
35051
  const renderEntry = React76.useCallback((entry, depth) => {
34734
35052
  const entryName = getEntryName(entry);
34735
35053
  if (entry.is_dir) {
@@ -34788,23 +35106,34 @@ var FileDirectoryPanel = ({
34788
35106
  }
34789
35107
  ),
34790
35108
  /* @__PURE__ */ jsx129(
34791
- PinToMenuButton,
34792
- {
34793
- contentType: "file",
34794
- contentConfig: {
34795
- resourcePath: entry.path,
34796
- assistantId: currentAssistant?.id || "",
34797
- fileName: entry.path.split("/").pop() || entry.path
34798
- },
34799
- isMatch: (cfg) => cfg.resourcePath === entry.path
34800
- }
34801
- ),
34802
- /* @__PURE__ */ jsx129(
34803
- Dropdown6,
35109
+ Dropdown7,
34804
35110
  {
34805
35111
  trigger: ["click"],
35112
+ onOpenChange: (open) => handleDropdownOpen(entry.path, open),
34806
35113
  menu: {
34807
35114
  items: [
35115
+ ...enableCustomMenu ? pinStates[entry.path]?.isPinned ? [
35116
+ {
35117
+ key: "unpin",
35118
+ icon: /* @__PURE__ */ jsx129(Pin2, { size: 14 }),
35119
+ label: "Unpin from Menu",
35120
+ onClick: () => {
35121
+ const state = pinStates[entry.path];
35122
+ if (state?.pinnedId) handleUnpin(entry.path, state.pinnedId);
35123
+ }
35124
+ }
35125
+ ] : [
35126
+ {
35127
+ key: "pin",
35128
+ icon: /* @__PURE__ */ jsx129(Pin2, { size: 14 }),
35129
+ label: "Pin to Menu",
35130
+ onClick: () => {
35131
+ setPinModalPath(entry.path);
35132
+ setPinName("");
35133
+ setPinGroup("");
35134
+ }
35135
+ }
35136
+ ] : [],
34808
35137
  {
34809
35138
  key: "preview",
34810
35139
  icon: /* @__PURE__ */ jsx129(EyeOutlined, {}),
@@ -34842,7 +35171,7 @@ var FileDirectoryPanel = ({
34842
35171
  }
34843
35172
  )
34844
35173
  ] }, entry.path);
34845
- }, [directoryChildren, directoryExpanded, directoryLoading, onAssetClick, onToggleDirectory, styles, getFileViewUrl, currentAssistant?.id]);
35174
+ }, [directoryChildren, directoryExpanded, directoryLoading, onAssetClick, onToggleDirectory, styles, getFileViewUrl, currentAssistant?.id, enableCustomMenu, pinStates, handleDropdownOpen, handleUnpin]);
34846
35175
  if (!projectId) {
34847
35176
  return /* @__PURE__ */ jsx129("div", { className: styles.emptyState, children: "Please select a project to browse files" });
34848
35177
  }
@@ -34899,6 +35228,37 @@ var FileDirectoryPanel = ({
34899
35228
  fileName: sharePath.split("/").pop(),
34900
35229
  onClose: () => setSharePath(null)
34901
35230
  }
35231
+ ),
35232
+ /* @__PURE__ */ jsx129(
35233
+ Modal26,
35234
+ {
35235
+ title: "Pin to Menu",
35236
+ open: !!pinModalPath,
35237
+ onOk: handlePinSubmit,
35238
+ onCancel: () => setPinModalPath(null),
35239
+ confirmLoading: pinLoading,
35240
+ okText: "Pin",
35241
+ children: /* @__PURE__ */ jsxs94("div", { style: MODAL_BODY_STYLE2, children: [
35242
+ /* @__PURE__ */ jsx129(
35243
+ Input21,
35244
+ {
35245
+ placeholder: "Menu name (required)",
35246
+ value: pinName,
35247
+ onChange: (e) => setPinName(e.target.value)
35248
+ }
35249
+ ),
35250
+ /* @__PURE__ */ jsx129(
35251
+ AutoComplete2,
35252
+ {
35253
+ placeholder: "Group (optional, select or type new)",
35254
+ value: pinGroup,
35255
+ options: existingGroups.map((g) => ({ value: g })),
35256
+ onChange: (val) => setPinGroup(val),
35257
+ filterOption: (inputValue, option) => option?.value?.toUpperCase().includes(inputValue.toUpperCase()) ?? false
35258
+ }
35259
+ )
35260
+ ] })
35261
+ }
34902
35262
  )
34903
35263
  ] });
34904
35264
  };
@@ -34926,7 +35286,7 @@ var ToolPanelFiles = () => {
34926
35286
  const resourceFolders = useMemo37(() => {
34927
35287
  return config.resourceFolders && config.resourceFolders.length > 0 ? config.resourceFolders : [{ name: "/", displayName: "Project Assets", allowUpload: true }];
34928
35288
  }, [config.resourceFolders]);
34929
- const loadAssetsForFolder = useCallback44(
35289
+ const loadAssetsForFolder = useCallback46(
34930
35290
  async (folder, clearSubdirectoryCache = true) => {
34931
35291
  if (!workspaceId || !projectId) {
34932
35292
  setFolderEntries((prev) => ({ ...prev, [folder.name]: [] }));
@@ -34966,7 +35326,7 @@ var ToolPanelFiles = () => {
34966
35326
  },
34967
35327
  [workspaceId, projectId, listPathByFolder, currentAssistant?.id]
34968
35328
  );
34969
- const handleToggleDirectory = useCallback44(async (path) => {
35329
+ const handleToggleDirectory = useCallback46(async (path) => {
34970
35330
  const isExpanded = directoryExpanded[path] || false;
34971
35331
  if (isExpanded) {
34972
35332
  setDirectoryExpanded((prev) => ({ ...prev, [path]: false }));
@@ -34984,15 +35344,15 @@ var ToolPanelFiles = () => {
34984
35344
  setDirectoryLoading((prev) => ({ ...prev, [path]: false }));
34985
35345
  }
34986
35346
  }, [directoryExpanded, listPath, currentAssistant?.id]);
34987
- useEffect58(() => {
35347
+ useEffect59(() => {
34988
35348
  resourceFolders.forEach((folder) => {
34989
35349
  void loadAssetsForFolder(folder, false);
34990
35350
  });
34991
35351
  }, [resourceFolders, loadAssetsForFolder]);
34992
- const handleAssetClick = useCallback44((asset) => {
35352
+ const handleAssetClick = useCallback46((asset) => {
34993
35353
  const fileUrl = getFileViewUrl(asset.path, currentAssistant?.id);
34994
35354
  if (!fileUrl) {
34995
- message24.warning("Please select a workspace and project first.");
35355
+ message26.warning("Please select a workspace and project first.");
34996
35356
  return;
34997
35357
  }
34998
35358
  openSideApp({
@@ -35005,9 +35365,9 @@ var ToolPanelFiles = () => {
35005
35365
  message: `Preview: ${asset.name || asset.path}`
35006
35366
  });
35007
35367
  }, [getFileViewUrl, openSideApp, currentAssistant?.id]);
35008
- const handleUploadFolder = useCallback44(async (folderName) => {
35368
+ const handleUploadFolder = useCallback46(async (folderName) => {
35009
35369
  if (!workspaceId || !projectId) {
35010
- message24.warning("Please select a workspace and project before uploading.");
35370
+ message26.warning("Please select a workspace and project before uploading.");
35011
35371
  return;
35012
35372
  }
35013
35373
  const input = document.createElement("input");
@@ -35021,14 +35381,14 @@ var ToolPanelFiles = () => {
35021
35381
  setUploadingFolder(folderName);
35022
35382
  try {
35023
35383
  await uploadFileToFolder(folderName, file, currentAssistant?.id);
35024
- message24.success(`Uploaded "${file.name}" successfully`);
35384
+ message26.success(`Uploaded "${file.name}" successfully`);
35025
35385
  const folder = resourceFolders.find((item) => item.name === folderName);
35026
35386
  if (folder) {
35027
35387
  await loadAssetsForFolder(folder);
35028
35388
  }
35029
35389
  } catch (error) {
35030
35390
  const errMsg = error instanceof Error ? error.message : "Failed to upload file";
35031
- message24.error(errMsg);
35391
+ message26.error(errMsg);
35032
35392
  } finally {
35033
35393
  setUploadingFolder(null);
35034
35394
  input.remove();
@@ -35131,7 +35491,7 @@ var LatticeChat = (props) => {
35131
35491
  import { useContext as useContext12 } from "react";
35132
35492
 
35133
35493
  // src/components/Chat/ChatSidebar.tsx
35134
- import { useState as useState86, useMemo as useMemo38, useCallback as useCallback46 } from "react";
35494
+ import { useState as useState86, useMemo as useMemo38, useCallback as useCallback48 } from "react";
35135
35495
  import { Drawer as Drawer3, Avatar as Avatar13, Popover as Popover4, Button as Button63 } from "antd";
35136
35496
  import {
35137
35497
  History as History2,
@@ -35142,10 +35502,10 @@ import {
35142
35502
  } from "lucide-react";
35143
35503
 
35144
35504
  // src/components/Chat/ThreadHistoryMenuContent.tsx
35145
- import React78, { useCallback as useCallback45 } from "react";
35505
+ import React78, { useCallback as useCallback47 } from "react";
35146
35506
  import { createStyles as createStyles41 } from "antd-style";
35147
35507
  import { MessageSquare as MessageSquare4, Trash2 as Trash210 } from "lucide-react";
35148
- import { message as message25, Modal as Modal26 } from "antd";
35508
+ import { message as message27, Modal as Modal27 } from "antd";
35149
35509
  import { jsx as jsx132, jsxs as jsxs96 } from "react/jsx-runtime";
35150
35510
  var useStyles24 = createStyles41(({ token, css }) => ({
35151
35511
  container: css`
@@ -35256,10 +35616,10 @@ var ThreadHistoryMenuContent = () => {
35256
35616
  deleteThread,
35257
35617
  isLoading
35258
35618
  } = useConversationContext();
35259
- const handleDeleteThread = useCallback45(
35619
+ const handleDeleteThread = useCallback47(
35260
35620
  async (e, threadIdToDelete) => {
35261
35621
  e.stopPropagation();
35262
- Modal26.confirm({
35622
+ Modal27.confirm({
35263
35623
  title: "Delete Conversation",
35264
35624
  content: "Are you sure you want to delete this conversation? This action cannot be undone.",
35265
35625
  okText: "Delete",
@@ -35268,9 +35628,9 @@ var ThreadHistoryMenuContent = () => {
35268
35628
  onOk: async () => {
35269
35629
  try {
35270
35630
  await deleteThread(threadIdToDelete);
35271
- message25.success("Conversation deleted");
35631
+ message27.success("Conversation deleted");
35272
35632
  } catch (error) {
35273
- message25.error("Failed to delete conversation");
35633
+ message27.error("Failed to delete conversation");
35274
35634
  }
35275
35635
  }
35276
35636
  });
@@ -35383,7 +35743,7 @@ var ChatSidebar = ({
35383
35743
  const items = customMenuItems.length > 0 ? [...customMenuItems] : [...DEFAULT_MENU_ITEMS];
35384
35744
  return items.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
35385
35745
  }, [customMenuItems]);
35386
- const handleMenuClick = useCallback46(async (item) => {
35746
+ const handleMenuClick = useCallback48(async (item) => {
35387
35747
  if (item.builtin === "settings") {
35388
35748
  setSettingsModalOpen(true);
35389
35749
  onSettingsClick?.();
@@ -35406,17 +35766,17 @@ var ChatSidebar = ({
35406
35766
  }
35407
35767
  }
35408
35768
  }, [onSettingsClick, setSettingsModalOpen, createThread, logout]);
35409
- const handleCloseDrawer = useCallback46((itemId) => {
35769
+ const handleCloseDrawer = useCallback48((itemId) => {
35410
35770
  setDrawerStates((prev) => ({ ...prev, [itemId]: false }));
35411
35771
  }, []);
35412
- const handleNewAnalysis = useCallback46(async () => {
35772
+ const handleNewAnalysis = useCallback48(async () => {
35413
35773
  try {
35414
35774
  await createThread("New Analysis");
35415
35775
  } catch (error) {
35416
35776
  console.error("Failed to create new thread:", error);
35417
35777
  }
35418
35778
  }, [createThread]);
35419
- const renderDrawerContent = useCallback46((item) => {
35779
+ const renderDrawerContent = useCallback48((item) => {
35420
35780
  switch (item.builtin) {
35421
35781
  case "thread-history":
35422
35782
  return /* @__PURE__ */ jsx133(ThreadHistoryMenuContent, {});
@@ -35629,12 +35989,12 @@ var LatticeChatView = (props) => {
35629
35989
  };
35630
35990
 
35631
35991
  // src/components/Chat/SettingsModal.tsx
35632
- import { useState as useState87, useEffect as useEffect59, useRef as useRef32 } from "react";
35992
+ import { useState as useState87, useEffect as useEffect60, useRef as useRef32 } from "react";
35633
35993
  import {
35634
- Modal as Modal27,
35635
- Input as Input21,
35994
+ Modal as Modal28,
35995
+ Input as Input22,
35636
35996
  Button as Button64,
35637
- message as message26,
35997
+ message as message28,
35638
35998
  notification as notification5,
35639
35999
  Typography as Typography63,
35640
36000
  Alert as Alert9,
@@ -35658,7 +36018,7 @@ import {
35658
36018
  import { createStyles as createStyles42 } from "antd-style";
35659
36019
  import { Fragment as Fragment31, jsx as jsx135, jsxs as jsxs98 } from "react/jsx-runtime";
35660
36020
  var { Text: Text52, Title: Title18 } = Typography63;
35661
- var { TextArea: TextArea9 } = Input21;
36021
+ var { TextArea: TextArea9 } = Input22;
35662
36022
  var useStyles25 = createStyles42(({ token, css }) => ({
35663
36023
  // settingsModal: css`
35664
36024
  // .ant-modal {
@@ -36043,7 +36403,7 @@ var SettingsModal = ({
36043
36403
  });
36044
36404
  const [serverConfigs, setServerConfigs] = useState87({});
36045
36405
  const connectionsRef = useRef32(connections);
36046
- useEffect59(() => {
36406
+ useEffect60(() => {
36047
36407
  connectionsRef.current = connections;
36048
36408
  }, [connections]);
36049
36409
  const [activeTabKey, setActiveTabKey] = useState87(
@@ -36194,7 +36554,7 @@ var SettingsModal = ({
36194
36554
  }
36195
36555
  } catch (error) {
36196
36556
  console.error("Failed to load configuration:", error);
36197
- message26.error("Failed to load current configuration");
36557
+ message28.error("Failed to load current configuration");
36198
36558
  }
36199
36559
  };
36200
36560
  const loadModelsConfig = async (serverId) => {
@@ -36245,7 +36605,7 @@ var SettingsModal = ({
36245
36605
  console.error("Failed to load models configuration:", error);
36246
36606
  }
36247
36607
  };
36248
- useEffect59(() => {
36608
+ useEffect60(() => {
36249
36609
  if (open && activeTabKey) {
36250
36610
  initializeServerConfig(activeTabKey);
36251
36611
  const connection = connections.find((c) => c.id === activeTabKey);
@@ -36254,7 +36614,7 @@ var SettingsModal = ({
36254
36614
  }
36255
36615
  }
36256
36616
  }, [open, activeTabKey]);
36257
- useEffect59(() => {
36617
+ useEffect60(() => {
36258
36618
  if (open && activeTabKey) {
36259
36619
  const connection = connections.find((c) => c.id === activeTabKey);
36260
36620
  if (connection?.connected) {
@@ -36268,7 +36628,7 @@ var SettingsModal = ({
36268
36628
  }, [open, activeTabKey, activeMenu]);
36269
36629
  const handleAddServer = async () => {
36270
36630
  if (!newServerUrl.trim()) {
36271
- message26.error("Please enter a server URL");
36631
+ message28.error("Please enter a server URL");
36272
36632
  return;
36273
36633
  }
36274
36634
  let normalizedUrl = newServerUrl.trim();
@@ -36331,12 +36691,12 @@ var SettingsModal = ({
36331
36691
  const handleSave = async () => {
36332
36692
  const connection = connections.find((c) => c.id === activeTabKey);
36333
36693
  if (!connection || !connection.connected) {
36334
- message26.error("Please connect to a server first");
36694
+ message28.error("Please connect to a server first");
36335
36695
  return;
36336
36696
  }
36337
36697
  const url = connection.url;
36338
36698
  if (!url) {
36339
- message26.error("Please connect to a server first");
36699
+ message28.error("Please connect to a server first");
36340
36700
  return;
36341
36701
  }
36342
36702
  try {
@@ -36400,7 +36760,7 @@ var SettingsModal = ({
36400
36760
  const data = await response.json();
36401
36761
  if (response.ok && data.success) {
36402
36762
  if (data.requiresRestart && data.requiresRestart.length > 0) {
36403
- message26.warning(
36763
+ message28.warning(
36404
36764
  `Configuration saved. Please restart the server for ${data.requiresRestart.join(
36405
36765
  ", "
36406
36766
  )} to take effect.`,
@@ -36414,12 +36774,12 @@ var SettingsModal = ({
36414
36774
  }
36415
36775
  if (data.warnings && data.warnings.length > 0) {
36416
36776
  data.warnings.forEach((warning) => {
36417
- message26.warning(warning, 5);
36777
+ message28.warning(warning, 5);
36418
36778
  });
36419
36779
  }
36420
36780
  onClose();
36421
36781
  } else {
36422
- message26.error(data.error || "Failed to save configuration");
36782
+ message28.error(data.error || "Failed to save configuration");
36423
36783
  }
36424
36784
  } else if (activeMenu === "models") {
36425
36785
  const validModels = config.models.filter(
@@ -36444,12 +36804,12 @@ var SettingsModal = ({
36444
36804
  });
36445
36805
  onClose();
36446
36806
  } else {
36447
- message26.error(data.error || "Failed to save model configuration");
36807
+ message28.error(data.error || "Failed to save model configuration");
36448
36808
  }
36449
36809
  }
36450
36810
  } catch (error) {
36451
36811
  console.error("Failed to save configuration:", error);
36452
- message26.error(error.message || "Failed to save configuration");
36812
+ message28.error(error.message || "Failed to save configuration");
36453
36813
  } finally {
36454
36814
  setLoading(false);
36455
36815
  }
@@ -36624,7 +36984,7 @@ QUEUE_NAME=tasks`,
36624
36984
  /* @__PURE__ */ jsxs98("div", { children: [
36625
36985
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "Key *" }),
36626
36986
  /* @__PURE__ */ jsx135(
36627
- Input21,
36987
+ Input22,
36628
36988
  {
36629
36989
  placeholder: "e.g., default, gpt-4, claude",
36630
36990
  value: model.key,
@@ -36655,7 +37015,7 @@ QUEUE_NAME=tasks`,
36655
37015
  /* @__PURE__ */ jsxs98("div", { children: [
36656
37016
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "Model Name *" }),
36657
37017
  /* @__PURE__ */ jsx135(
36658
- Input21,
37018
+ Input22,
36659
37019
  {
36660
37020
  placeholder: "e.g., gpt-4, claude-3-opus, kimi-k2-250905",
36661
37021
  value: model.model,
@@ -36667,7 +37027,7 @@ QUEUE_NAME=tasks`,
36667
37027
  /* @__PURE__ */ jsxs98("div", { children: [
36668
37028
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "API Key" }),
36669
37029
  /* @__PURE__ */ jsx135(
36670
- Input21.Password,
37030
+ Input22.Password,
36671
37031
  {
36672
37032
  placeholder: "Enter your API key",
36673
37033
  value: model.apiKey,
@@ -36680,7 +37040,7 @@ QUEUE_NAME=tasks`,
36680
37040
  /* @__PURE__ */ jsxs98("div", { children: [
36681
37041
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "Base URL" }),
36682
37042
  /* @__PURE__ */ jsx135(
36683
- Input21,
37043
+ Input22,
36684
37044
  {
36685
37045
  placeholder: "e.g., https://api.openai.com/v1",
36686
37046
  value: model.baseURL,
@@ -36704,7 +37064,7 @@ QUEUE_NAME=tasks`,
36704
37064
  /* @__PURE__ */ jsxs98("div", { style: { flex: 1 }, children: [
36705
37065
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "Max Tokens" }),
36706
37066
  /* @__PURE__ */ jsx135(
36707
- Input21,
37067
+ Input22,
36708
37068
  {
36709
37069
  type: "number",
36710
37070
  placeholder: "e.g., 4096",
@@ -36721,7 +37081,7 @@ QUEUE_NAME=tasks`,
36721
37081
  /* @__PURE__ */ jsxs98("div", { style: { flex: 1 }, children: [
36722
37082
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "Temperature" }),
36723
37083
  /* @__PURE__ */ jsx135(
36724
- Input21,
37084
+ Input22,
36725
37085
  {
36726
37086
  type: "number",
36727
37087
  step: "0.1",
@@ -36881,7 +37241,7 @@ QUEUE_NAME=tasks`,
36881
37241
  }));
36882
37242
  return /* @__PURE__ */ jsxs98(Fragment31, { children: [
36883
37243
  /* @__PURE__ */ jsx135(
36884
- Modal27,
37244
+ Modal28,
36885
37245
  {
36886
37246
  open,
36887
37247
  onCancel: onClose,
@@ -36923,7 +37283,7 @@ QUEUE_NAME=tasks`,
36923
37283
  }
36924
37284
  ),
36925
37285
  /* @__PURE__ */ jsx135(
36926
- Modal27,
37286
+ Modal28,
36927
37287
  {
36928
37288
  title: "Add New Server",
36929
37289
  open: showAddServerModal,
@@ -36940,7 +37300,7 @@ QUEUE_NAME=tasks`,
36940
37300
  /* @__PURE__ */ jsxs98("div", { children: [
36941
37301
  /* @__PURE__ */ jsx135(Text52, { strong: true, style: { display: "block", marginBottom: 8 }, children: "Server Name" }),
36942
37302
  /* @__PURE__ */ jsx135(
36943
- Input21,
37303
+ Input22,
36944
37304
  {
36945
37305
  placeholder: "e.g., Production Server",
36946
37306
  value: newServerName,
@@ -36953,7 +37313,7 @@ QUEUE_NAME=tasks`,
36953
37313
  /* @__PURE__ */ jsxs98("div", { children: [
36954
37314
  /* @__PURE__ */ jsx135(Text52, { strong: true, style: { display: "block", marginBottom: 8 }, children: "Server URL *" }),
36955
37315
  /* @__PURE__ */ jsx135(
36956
- Input21,
37316
+ Input22,
36957
37317
  {
36958
37318
  placeholder: "e.g., http://localhost:4001",
36959
37319
  value: newServerUrl,
@@ -36966,7 +37326,7 @@ QUEUE_NAME=tasks`,
36966
37326
  /* @__PURE__ */ jsxs98("div", { children: [
36967
37327
  /* @__PURE__ */ jsx135(Text52, { strong: true, style: { display: "block", marginBottom: 8 }, children: "API Key" }),
36968
37328
  /* @__PURE__ */ jsx135(
36969
- Input21.Password,
37329
+ Input22.Password,
36970
37330
  {
36971
37331
  placeholder: "Optional: Enter API key for authentication",
36972
37332
  value: newServerApiKey,
@@ -37034,20 +37394,20 @@ var LatticeChatShell = (props) => {
37034
37394
  };
37035
37395
 
37036
37396
  // src/components/Chat/ChannelInstallationsDrawerContent.tsx
37037
- import { useEffect as useEffect60, useState as useState88 } from "react";
37397
+ import { useEffect as useEffect61, useState as useState88 } from "react";
37038
37398
  import {
37039
37399
  Button as Button65,
37040
37400
  Card as Card30,
37041
37401
  Form as Form10,
37042
- Input as Input22,
37043
- Modal as Modal28,
37402
+ Input as Input23,
37403
+ Modal as Modal29,
37044
37404
  Popconfirm as Popconfirm14,
37045
37405
  Spin as Spin24,
37046
37406
  Tag as Tag32,
37047
37407
  Typography as Typography64,
37048
- message as message27
37408
+ message as message29
37049
37409
  } from "antd";
37050
- import { Edit2 as Edit24, Plus as Plus10, RadioTower, Trash2 as Trash211 } from "lucide-react";
37410
+ import { Edit2 as Edit24, Plus as Plus9, RadioTower, Trash2 as Trash211 } from "lucide-react";
37051
37411
  import { jsx as jsx138, jsxs as jsxs100 } from "react/jsx-runtime";
37052
37412
  var { Text: Text53, Title: Title19 } = Typography64;
37053
37413
  var ChannelInstallationsDrawerContent = () => {
@@ -37066,17 +37426,17 @@ var ChannelInstallationsDrawerContent = () => {
37066
37426
  setInstallations(result.data?.records ?? []);
37067
37427
  } else {
37068
37428
  setInstallations([]);
37069
- message27.error(result.message || "Failed to load channel installations");
37429
+ message29.error(result.message || "Failed to load channel installations");
37070
37430
  }
37071
37431
  } catch (error) {
37072
37432
  console.error("Failed to load channel installations:", error);
37073
37433
  setInstallations([]);
37074
- message27.error("Failed to load channel installations");
37434
+ message29.error("Failed to load channel installations");
37075
37435
  } finally {
37076
37436
  setLoading(false);
37077
37437
  }
37078
37438
  };
37079
- useEffect60(() => {
37439
+ useEffect61(() => {
37080
37440
  loadInstallations();
37081
37441
  }, []);
37082
37442
  const handleDelete = async (installation) => {
@@ -37088,13 +37448,13 @@ var ChannelInstallationsDrawerContent = () => {
37088
37448
  setInstallations(
37089
37449
  (current) => current.filter((item) => item.id !== installation.id)
37090
37450
  );
37091
- message27.success("Installation deleted");
37451
+ message29.success("Installation deleted");
37092
37452
  } else {
37093
- message27.error(result.message || "Failed to delete installation");
37453
+ message29.error(result.message || "Failed to delete installation");
37094
37454
  }
37095
37455
  } catch (error) {
37096
37456
  console.error("Failed to delete channel installation:", error);
37097
- message27.error("Failed to delete installation");
37457
+ message29.error("Failed to delete installation");
37098
37458
  }
37099
37459
  };
37100
37460
  return /* @__PURE__ */ jsxs100("div", { style: { height: "100%", display: "flex", flexDirection: "column" }, children: [
@@ -37112,7 +37472,7 @@ var ChannelInstallationsDrawerContent = () => {
37112
37472
  Button65,
37113
37473
  {
37114
37474
  type: "primary",
37115
- icon: /* @__PURE__ */ jsx138(Plus10, { size: 16 }),
37475
+ icon: /* @__PURE__ */ jsx138(Plus9, { size: 16 }),
37116
37476
  onClick: () => {
37117
37477
  setEditingInstallation(null);
37118
37478
  setFormModalOpen(true);
@@ -37224,7 +37584,7 @@ var ChannelInstallationsDrawerContent = () => {
37224
37584
  };
37225
37585
  var LarkChannelInstallationFormModal = ({ installation, open, post, put, onCancel, onSave }) => {
37226
37586
  const [form] = Form10.useForm();
37227
- useEffect60(() => {
37587
+ useEffect61(() => {
37228
37588
  if (installation) {
37229
37589
  const config = installation.config;
37230
37590
  form.setFieldsValue({
@@ -37257,10 +37617,10 @@ var LarkChannelInstallationFormModal = ({ installation, open, post, put, onCance
37257
37617
  payload2
37258
37618
  );
37259
37619
  if (result2.success) {
37260
- message27.success("Installation updated");
37620
+ message29.success("Installation updated");
37261
37621
  onSave();
37262
37622
  } else {
37263
- message27.error(result2.message || "Failed to update installation");
37623
+ message29.error(result2.message || "Failed to update installation");
37264
37624
  }
37265
37625
  return;
37266
37626
  }
@@ -37274,20 +37634,20 @@ var LarkChannelInstallationFormModal = ({ installation, open, post, put, onCance
37274
37634
  payload
37275
37635
  );
37276
37636
  if (result.success) {
37277
- message27.success("Installation created");
37637
+ message29.success("Installation created");
37278
37638
  onSave();
37279
37639
  } else {
37280
- message27.error(result.message || "Failed to create installation");
37640
+ message29.error(result.message || "Failed to create installation");
37281
37641
  }
37282
37642
  } catch (error) {
37283
37643
  console.error("Failed to save channel installation:", error);
37284
- message27.error(
37644
+ message29.error(
37285
37645
  installation ? "Failed to update installation" : "Failed to create installation"
37286
37646
  );
37287
37647
  }
37288
37648
  };
37289
37649
  return /* @__PURE__ */ jsx138(
37290
- Modal28,
37650
+ Modal29,
37291
37651
  {
37292
37652
  open,
37293
37653
  title: installation ? "Edit Installation" : "Add Installation",
@@ -37296,15 +37656,15 @@ var LarkChannelInstallationFormModal = ({ installation, open, post, put, onCance
37296
37656
  okText: installation ? "Save" : "Create",
37297
37657
  destroyOnHidden: true,
37298
37658
  children: /* @__PURE__ */ jsxs100(Form10, { form, layout: "vertical", children: [
37299
- /* @__PURE__ */ jsx138(Form10.Item, { label: "Channel", children: /* @__PURE__ */ jsx138(Input22, { value: "lark", disabled: true }) }),
37300
- /* @__PURE__ */ jsx138(Form10.Item, { name: "name", label: "Name", children: /* @__PURE__ */ jsx138(Input22, {}) }),
37659
+ /* @__PURE__ */ jsx138(Form10.Item, { label: "Channel", children: /* @__PURE__ */ jsx138(Input23, { value: "lark", disabled: true }) }),
37660
+ /* @__PURE__ */ jsx138(Form10.Item, { name: "name", label: "Name", children: /* @__PURE__ */ jsx138(Input23, {}) }),
37301
37661
  /* @__PURE__ */ jsx138(
37302
37662
  Form10.Item,
37303
37663
  {
37304
37664
  name: "appId",
37305
37665
  label: "App ID",
37306
37666
  rules: [{ required: true, message: "App ID is required" }],
37307
- children: /* @__PURE__ */ jsx138(Input22, {})
37667
+ children: /* @__PURE__ */ jsx138(Input23, {})
37308
37668
  }
37309
37669
  ),
37310
37670
  /* @__PURE__ */ jsx138(
@@ -37313,11 +37673,11 @@ var LarkChannelInstallationFormModal = ({ installation, open, post, put, onCance
37313
37673
  name: "appSecret",
37314
37674
  label: "App Secret",
37315
37675
  rules: [{ required: true, message: "App Secret is required" }],
37316
- children: /* @__PURE__ */ jsx138(Input22, {})
37676
+ children: /* @__PURE__ */ jsx138(Input23, {})
37317
37677
  }
37318
37678
  ),
37319
- /* @__PURE__ */ jsx138(Form10.Item, { name: "verificationToken", label: "Verification Token", children: /* @__PURE__ */ jsx138(Input22, {}) }),
37320
- /* @__PURE__ */ jsx138(Form10.Item, { name: "encryptKey", label: "Encrypt Key", children: /* @__PURE__ */ jsx138(Input22, {}) })
37679
+ /* @__PURE__ */ jsx138(Form10.Item, { name: "verificationToken", label: "Verification Token", children: /* @__PURE__ */ jsx138(Input23, {}) }),
37680
+ /* @__PURE__ */ jsx138(Form10.Item, { name: "encryptKey", label: "Encrypt Key", children: /* @__PURE__ */ jsx138(Input23, {}) })
37321
37681
  ] })
37322
37682
  }
37323
37683
  );