@openhands/agent-canvas 1.0.0-alpha.5 → 1.0.0-alpha.7

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.
Files changed (70) hide show
  1. package/README.md +41 -7
  2. package/bin/agent-canvas.mjs +9 -2
  3. package/build/assets/automation-detail-D7GEU0vR.js +1 -0
  4. package/build/assets/automations-list-CkVNsgzm.js +1 -0
  5. package/build/assets/conversation-COZAKz_K.js +1 -0
  6. package/build/assets/{conversation-D8scXOe7.js → conversation-DWcvnmds.js} +3 -1
  7. package/build/assets/conversation-panel-CZDStT0b.js +1 -0
  8. package/build/assets/conversation-websocket-context-DulnrIHh.js +3 -0
  9. package/build/assets/edit-automation-modal-C3bFxS2f.js +1 -0
  10. package/build/assets/git-control-bar-branch-button-Bm6rzSpo.js +27 -0
  11. package/build/assets/{home-D9fJfhQA.js → home-DR11ejqB.js} +1 -1
  12. package/build/assets/{manifest-f141dc70.js → manifest-f041e61a.js} +1 -1
  13. package/build/assets/{messages-BfaEAG2q.js → messages-v-q35ObG.js} +1 -1
  14. package/build/assets/{root-luPHQiBx.js → root-D2PVd51i.js} +1 -1
  15. package/build/assets/root-layout-B4QioBS6.js +2 -0
  16. package/build/assets/{shared-conversation-BfZNCsvo.js → shared-conversation-DQlzwdpo.js} +1 -1
  17. package/build/index.html +3 -3
  18. package/config/defaults.json +38 -0
  19. package/dist/components/features/backends/backend-selector.cjs +1 -1
  20. package/dist/components/features/backends/backend-selector.cjs.map +1 -1
  21. package/dist/components/features/backends/backend-selector.js +95 -95
  22. package/dist/components/features/backends/backend-selector.js.map +1 -1
  23. package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
  24. package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
  25. package/dist/components/features/chat/components/chat-input-actions.js +118 -118
  26. package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
  27. package/dist/components/features/chat/components/slash-command-menu.cjs +1 -1
  28. package/dist/components/features/chat/components/slash-command-menu.cjs.map +1 -1
  29. package/dist/components/features/chat/components/slash-command-menu.js +1 -1
  30. package/dist/components/features/chat/components/slash-command-menu.js.map +1 -1
  31. package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
  32. package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
  33. package/dist/components/features/sidebar/sidebar-rail-body.d.ts +1 -2
  34. package/dist/components/features/sidebar/sidebar-rail-body.js +104 -104
  35. package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
  36. package/dist/components/features/sidebar/sidebar.cjs +1 -1
  37. package/dist/components/features/sidebar/sidebar.cjs.map +1 -1
  38. package/dist/components/features/sidebar/sidebar.js +82 -83
  39. package/dist/components/features/sidebar/sidebar.js.map +1 -1
  40. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  41. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  42. package/dist/contexts/conversation-websocket-context.js +36 -36
  43. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  44. package/dist/hooks/query/use-local-git-info.cjs +3 -1
  45. package/dist/hooks/query/use-local-git-info.cjs.map +1 -1
  46. package/dist/hooks/query/use-local-git-info.d.ts +2 -2
  47. package/dist/hooks/query/use-local-git-info.js +27 -24
  48. package/dist/hooks/query/use-local-git-info.js.map +1 -1
  49. package/dist/package.cjs +1 -1
  50. package/dist/package.cjs.map +1 -1
  51. package/dist/package.js +2 -1
  52. package/dist/package.js.map +1 -1
  53. package/dist/stores/error-message-store.cjs +1 -1
  54. package/dist/stores/error-message-store.cjs.map +1 -1
  55. package/dist/stores/error-message-store.d.ts +10 -1
  56. package/dist/stores/error-message-store.js +16 -3
  57. package/dist/stores/error-message-store.js.map +1 -1
  58. package/package.json +2 -1
  59. package/scripts/dev-static.mjs +8 -1
  60. package/scripts/dev-with-automation.mjs +30 -49
  61. package/scripts/static-build.mjs +2 -6
  62. package/scripts/static-server.mjs +85 -4
  63. package/build/assets/automation-detail-ZQs6D2d3.js +0 -1
  64. package/build/assets/automations-list-CqHXGwSw.js +0 -1
  65. package/build/assets/conversation-CeGMBOyB.js +0 -1
  66. package/build/assets/conversation-panel-DMz46ji-.js +0 -1
  67. package/build/assets/conversation-websocket-context-B0Gd3yiT.js +0 -3
  68. package/build/assets/edit-automation-modal-DgW0Q8vr.js +0 -1
  69. package/build/assets/git-control-bar-branch-button-DhpPgadK.js +0 -27
  70. package/build/assets/root-layout-DvYGxAnr.js +0 -2
@@ -7,100 +7,101 @@ import { Plus as a } from "../../../node_modules/lucide-react/dist/esm/icons/plu
7
7
  import { Server as o } from "../../../node_modules/lucide-react/dist/esm/icons/server.js";
8
8
  import { Settings as s } from "../../../node_modules/lucide-react/dist/esm/icons/settings.js";
9
9
  import { StyledTooltip as c } from "../../shared/buttons/styled-tooltip.js";
10
- import { SIDEBAR_COLLAPSED_LOGO_WRAPPER_CLASS as l, SIDEBAR_COLLAPSE_TOGGLE_OVERLAY_CLASS as u, SIDEBAR_ICON_BUTTON_CLASS as d, SIDEBAR_ICON_SLOT_CLASS as f, sidebarHeaderRowClassName as p, sidebarNavLabelClassName as m, sidebarNavListClassName as h, sidebarNavRowClassName as g } from "./sidebar-layout.js";
11
- import { SidebarCollapsedIconSlot as _ } from "./sidebar-collapsed-icon-slot.js";
12
- import { SidebarNavLink as v } from "./sidebar-nav-link.js";
13
- import { OpenHandsLogoButton as y } from "../../shared/buttons/openhands-logo-button.js";
14
- import { BackendStatusDot as b } from "../backends/backend-status-dot.js";
15
- import { BackendSelector as x } from "../backends/backend-selector.js";
16
- import { SidebarConversationList as S } from "./sidebar-conversation-list.js";
17
- import C from "../../../icons/automations.js";
10
+ import { NavigationLink as l } from "../../shared/navigation-link.js";
11
+ import { SIDEBAR_COLLAPSED_LOGO_WRAPPER_CLASS as u, SIDEBAR_COLLAPSE_TOGGLE_OVERLAY_CLASS as d, SIDEBAR_ICON_BUTTON_CLASS as f, SIDEBAR_ICON_SLOT_CLASS as p, sidebarHeaderRowClassName as m, sidebarNavLabelClassName as h, sidebarNavListClassName as g, sidebarNavRowClassName as _ } from "./sidebar-layout.js";
12
+ import { SidebarCollapsedIconSlot as v } from "./sidebar-collapsed-icon-slot.js";
13
+ import { SidebarNavLink as y } from "./sidebar-nav-link.js";
14
+ import { OpenHandsLogoButton as b } from "../../shared/buttons/openhands-logo-button.js";
15
+ import { BackendStatusDot as x } from "../backends/backend-status-dot.js";
16
+ import { BackendSelector as S } from "../backends/backend-selector.js";
17
+ import { SidebarConversationList as C } from "./sidebar-conversation-list.js";
18
+ import w from "../../../icons/automations.js";
18
19
  import "react";
19
- import { jsx as w, jsxs as T } from "react/jsx-runtime";
20
+ import { jsx as T, jsxs as E } from "react/jsx-runtime";
20
21
  //#region src/components/features/sidebar/sidebar-rail-body.tsx
21
- var E = 18, D = 34, O = Math.round(D * 30 / 46);
22
- function k({ collapsed: k, showCollapseToggle: A, showMobileCloseButton: j = !1, onCloseMobile: M, linkDisabled: N, collapseToggleLabel: P, onCollapse: F, onExpand: I, showCollapsedExpandButton: L, isExtensionsActive: R, currentPath: z, navigate: B, activeBackendHealth: V, collapsedBackendPopoverOpen: H, setCollapsedBackendPopoverOpen: U, collapsedBackendPopoverRef: W, collapsedBackendCloseTimer: G, onOpenAddBackend: K, onOpenManageBackends: q }) {
22
+ var D = 18, O = 34, k = Math.round(O * 30 / 46);
23
+ function A({ collapsed: A, showCollapseToggle: j, showMobileCloseButton: M = !1, onCloseMobile: N, linkDisabled: P, collapseToggleLabel: F, onCollapse: I, onExpand: L, showCollapsedExpandButton: R, isExtensionsActive: z, currentPath: B, activeBackendHealth: V, collapsedBackendPopoverOpen: H, setCollapsedBackendPopoverOpen: U, collapsedBackendPopoverRef: W, collapsedBackendCloseTimer: G, onOpenAddBackend: K, onOpenManageBackends: q }) {
23
24
  let { t: J } = e("openhands"), Y = G;
24
- return /* @__PURE__ */ T("div", {
25
+ return /* @__PURE__ */ E("div", {
25
26
  className: "flex min-h-0 flex-1 flex-col",
26
27
  children: [
27
- /* @__PURE__ */ T("div", {
28
- className: p(k),
28
+ /* @__PURE__ */ E("div", {
29
+ className: m(A),
29
30
  children: [
30
- /* @__PURE__ */ T("div", {
31
- className: n(k && A ? l : "flex min-w-0 shrink-0 items-center"),
32
- children: [/* @__PURE__ */ w("div", {
33
- className: n(k && A && "flex h-full w-full items-center justify-start pl-2.5 transition-opacity duration-150", k && L && "opacity-0"),
34
- children: /* @__PURE__ */ w(y, {
35
- logoWidth: D,
36
- logoHeight: O,
31
+ /* @__PURE__ */ E("div", {
32
+ className: n(A && j ? u : "flex min-w-0 shrink-0 items-center"),
33
+ children: [/* @__PURE__ */ T("div", {
34
+ className: n(A && j && "flex h-full w-full items-center justify-start pl-2.5 transition-opacity duration-150", A && R && "opacity-0"),
35
+ children: /* @__PURE__ */ T(b, {
36
+ logoWidth: O,
37
+ logoHeight: k,
37
38
  logoClassName: "max-w-none",
38
- className: n(f, "overflow-visible")
39
+ className: n(p, "overflow-visible")
39
40
  })
40
- }), k && A ? /* @__PURE__ */ w("button", {
41
+ }), A && j ? /* @__PURE__ */ T("button", {
41
42
  type: "button",
42
43
  "data-testid": "sidebar-collapse-toggle",
43
- "aria-pressed": k,
44
- "aria-label": P,
45
- onClick: I,
46
- className: n(u, L ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"),
47
- children: /* @__PURE__ */ w(i, {
44
+ "aria-pressed": A,
45
+ "aria-label": F,
46
+ onClick: L,
47
+ className: n(d, R ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"),
48
+ children: /* @__PURE__ */ T(i, {
48
49
  width: 14,
49
50
  height: 14
50
51
  })
51
52
  }) : null]
52
53
  }),
53
- !k && A ? /* @__PURE__ */ w("button", {
54
+ !A && j ? /* @__PURE__ */ T("button", {
54
55
  type: "button",
55
56
  "data-testid": "sidebar-collapse-toggle",
56
- "aria-pressed": k,
57
- "aria-label": P,
58
- onClick: F,
59
- className: n("hidden md:inline-flex ml-auto", d, "text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]"),
60
- children: /* @__PURE__ */ w(r, {
57
+ "aria-pressed": A,
58
+ "aria-label": F,
59
+ onClick: I,
60
+ className: n("hidden md:inline-flex ml-auto", f, "text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]"),
61
+ children: /* @__PURE__ */ T(r, {
61
62
  width: 14,
62
63
  height: 14
63
64
  })
64
65
  }) : null,
65
- !k && j ? /* @__PURE__ */ w("button", {
66
+ !A && M ? /* @__PURE__ */ T("button", {
66
67
  type: "button",
67
68
  "data-testid": "sidebar-mobile-drawer-close",
68
- onClick: M,
69
+ onClick: N,
69
70
  "aria-label": J(t.SIDEBAR$CLOSE_MENU),
70
- className: n("inline-flex ml-auto", d, "text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]"),
71
- children: /* @__PURE__ */ w(r, {
71
+ className: n("inline-flex ml-auto", f, "text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]"),
72
+ children: /* @__PURE__ */ T(r, {
72
73
  width: 14,
73
74
  height: 14
74
75
  })
75
76
  }) : null
76
77
  ]
77
78
  }),
78
- /* @__PURE__ */ T("nav", {
79
- className: h(k),
79
+ /* @__PURE__ */ E("nav", {
80
+ className: g(A),
80
81
  children: [
81
- /* @__PURE__ */ w(v, {
82
+ /* @__PURE__ */ T(y, {
82
83
  to: "/conversations",
83
84
  end: !0,
84
85
  label: "New Chat",
85
86
  testId: "sidebar-conversations-link",
86
- disabled: N,
87
- collapsed: k,
88
- icon: /* @__PURE__ */ w(a, {
89
- width: E,
90
- height: E
87
+ disabled: P,
88
+ collapsed: A,
89
+ icon: /* @__PURE__ */ T(a, {
90
+ width: D,
91
+ height: D
91
92
  })
92
93
  }),
93
- /* @__PURE__ */ w(v, {
94
+ /* @__PURE__ */ T(y, {
94
95
  to: "/customize",
95
96
  label: "Customize",
96
97
  testId: "sidebar-skills-link",
97
- disabled: N,
98
- collapsed: k,
99
- forceActive: R,
100
- icon: /* @__PURE__ */ T("svg", {
98
+ disabled: P,
99
+ collapsed: A,
100
+ forceActive: z,
101
+ icon: /* @__PURE__ */ E("svg", {
101
102
  xmlns: "http://www.w3.org/2000/svg",
102
- width: E,
103
- height: E,
103
+ width: D,
104
+ height: D,
104
105
  viewBox: "0 0 24 24",
105
106
  fill: "none",
106
107
  stroke: "currentColor",
@@ -109,58 +110,57 @@ function k({ collapsed: k, showCollapseToggle: A, showMobileCloseButton: j = !1,
109
110
  strokeLinejoin: "round",
110
111
  "aria-hidden": "true",
111
112
  children: [
112
- /* @__PURE__ */ w("path", { d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" }),
113
- /* @__PURE__ */ w("path", { d: "m7 16.5-4.74-2.85" }),
114
- /* @__PURE__ */ w("path", { d: "m7 16.5 5-3" }),
115
- /* @__PURE__ */ w("path", { d: "M7 16.5v5.17" }),
116
- /* @__PURE__ */ w("path", { d: "M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" }),
117
- /* @__PURE__ */ w("path", { d: "m17 16.5-5-3" }),
118
- /* @__PURE__ */ w("path", { d: "m17 16.5 4.74-2.85" }),
119
- /* @__PURE__ */ w("path", { d: "m17 16.5v5.17" }),
120
- /* @__PURE__ */ w("path", { d: "M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" }),
121
- /* @__PURE__ */ w("path", { d: "M12 8 7.26 5.15" }),
122
- /* @__PURE__ */ w("path", { d: "m12 8 4.74-2.85" }),
123
- /* @__PURE__ */ w("path", { d: "M12 13.5V8" })
113
+ /* @__PURE__ */ T("path", { d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" }),
114
+ /* @__PURE__ */ T("path", { d: "m7 16.5-4.74-2.85" }),
115
+ /* @__PURE__ */ T("path", { d: "m7 16.5 5-3" }),
116
+ /* @__PURE__ */ T("path", { d: "M7 16.5v5.17" }),
117
+ /* @__PURE__ */ T("path", { d: "M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" }),
118
+ /* @__PURE__ */ T("path", { d: "m17 16.5-5-3" }),
119
+ /* @__PURE__ */ T("path", { d: "m17 16.5 4.74-2.85" }),
120
+ /* @__PURE__ */ T("path", { d: "m17 16.5v5.17" }),
121
+ /* @__PURE__ */ T("path", { d: "M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" }),
122
+ /* @__PURE__ */ T("path", { d: "M12 8 7.26 5.15" }),
123
+ /* @__PURE__ */ T("path", { d: "m12 8 4.74-2.85" }),
124
+ /* @__PURE__ */ T("path", { d: "M12 13.5V8" })
124
125
  ]
125
126
  })
126
127
  }),
127
- /* @__PURE__ */ w(v, {
128
+ /* @__PURE__ */ T(y, {
128
129
  to: "/automations",
129
130
  label: J(t.SIDEBAR$AUTOMATIONS),
130
131
  testId: "sidebar-automations-link",
131
- disabled: N,
132
- collapsed: k,
133
- icon: /* @__PURE__ */ w(C, {
134
- width: E,
135
- height: E
132
+ disabled: P,
133
+ collapsed: A,
134
+ icon: /* @__PURE__ */ T(w, {
135
+ width: D,
136
+ height: D
136
137
  })
137
138
  })
138
139
  ]
139
140
  }),
140
- /* @__PURE__ */ w(S, { collapsed: k }),
141
- k && A ? /* @__PURE__ */ T("nav", {
142
- className: n(h(k), "mt-auto pb-2 cursor-pointer"),
143
- children: [/* @__PURE__ */ w(c, {
141
+ /* @__PURE__ */ T(C, { collapsed: A }),
142
+ A && j ? /* @__PURE__ */ E("nav", {
143
+ className: n(g(A), "mt-auto pb-2 cursor-pointer"),
144
+ children: [/* @__PURE__ */ T(c, {
144
145
  content: J(t.SIDEBAR$SETTINGS),
145
146
  placement: "right",
146
- children: /* @__PURE__ */ T("button", {
147
- type: "button",
147
+ children: /* @__PURE__ */ E(l, {
148
+ to: "/settings",
148
149
  "data-testid": "collapsed-settings-link",
149
150
  "aria-label": J(t.SIDEBAR$SETTINGS),
150
- onClick: () => B("/settings"),
151
- className: g({ collapsed: !0 }),
152
- children: [/* @__PURE__ */ w(_, {
153
- active: z.startsWith("/settings"),
154
- children: /* @__PURE__ */ w(s, {
155
- width: E,
156
- height: E
151
+ className: _({ collapsed: !0 }),
152
+ children: [/* @__PURE__ */ T(v, {
153
+ active: B.startsWith("/settings"),
154
+ children: /* @__PURE__ */ T(s, {
155
+ width: D,
156
+ height: D
157
157
  })
158
- }), /* @__PURE__ */ w("span", {
159
- className: m(!0),
158
+ }), /* @__PURE__ */ T("span", {
159
+ className: h(!0),
160
160
  children: J(t.SIDEBAR$SETTINGS)
161
161
  })]
162
162
  })
163
- }), /* @__PURE__ */ T("div", {
163
+ }), /* @__PURE__ */ E("div", {
164
164
  className: "relative",
165
165
  ref: W,
166
166
  onMouseEnter: () => {
@@ -169,7 +169,7 @@ function k({ collapsed: k, showCollapseToggle: A, showMobileCloseButton: j = !1,
169
169
  onMouseLeave: () => {
170
170
  Y.current = setTimeout(() => U(!1), 150);
171
171
  },
172
- children: [/* @__PURE__ */ T("button", {
172
+ children: [/* @__PURE__ */ E("button", {
173
173
  type: "button",
174
174
  "data-testid": "collapsed-backend-selector-link",
175
175
  "aria-label": J(t.BACKEND$MANAGE),
@@ -178,28 +178,28 @@ function k({ collapsed: k, showCollapseToggle: A, showMobileCloseButton: j = !1,
178
178
  e.preventDefault(), e.stopPropagation();
179
179
  },
180
180
  onMouseUp: (e) => e.stopPropagation(),
181
- className: n(g({ collapsed: !0 }), "relative"),
182
- children: [/* @__PURE__ */ w(_, {
181
+ className: n(_({ collapsed: !0 }), "relative"),
182
+ children: [/* @__PURE__ */ T(v, {
183
183
  active: H,
184
- children: /* @__PURE__ */ T("span", {
184
+ children: /* @__PURE__ */ E("span", {
185
185
  className: "relative inline-flex size-[18px] shrink-0 items-center justify-center",
186
- children: [/* @__PURE__ */ w(b, {
186
+ children: [/* @__PURE__ */ T(x, {
187
187
  isConnected: V?.isConnected ?? null,
188
188
  className: "absolute -left-0.5 -top-0.5 z-[1] pointer-events-none"
189
- }), /* @__PURE__ */ w(o, {
190
- width: E,
191
- height: E
189
+ }), /* @__PURE__ */ T(o, {
190
+ width: D,
191
+ height: D
192
192
  })]
193
193
  })
194
- }), /* @__PURE__ */ w("span", {
195
- className: m(!0),
194
+ }), /* @__PURE__ */ T("span", {
195
+ className: h(!0),
196
196
  children: J(t.BACKEND$MANAGE)
197
197
  })]
198
- }), H ? /* @__PURE__ */ w("div", {
198
+ }), H ? /* @__PURE__ */ T("div", {
199
199
  className: "absolute bottom-[-4px] left-full pl-2.5 z-40 w-[272px]",
200
200
  onClick: (e) => e.stopPropagation(),
201
- children: /* @__PURE__ */ w(x, {
202
- sidebarCollapsed: k,
201
+ children: /* @__PURE__ */ T(S, {
202
+ sidebarCollapsed: A,
203
203
  hideTrigger: !0,
204
204
  defaultOpen: !0,
205
205
  openUpward: !0,
@@ -210,10 +210,10 @@ function k({ collapsed: k, showCollapseToggle: A, showMobileCloseButton: j = !1,
210
210
  }) : null]
211
211
  })]
212
212
  }) : null,
213
- k ? null : /* @__PURE__ */ w("div", {
213
+ A ? null : /* @__PURE__ */ T("div", {
214
214
  className: n("flex flex-col items-stretch max-w-none box-border shrink-0", "-ml-2.5 w-[calc(100%+0.625rem)] border-t border-[var(--oh-border)] pt-2 px-2.5"),
215
- children: /* @__PURE__ */ w(x, {
216
- sidebarCollapsed: k,
215
+ children: /* @__PURE__ */ T(S, {
216
+ sidebarCollapsed: A,
217
217
  openUpward: !0
218
218
  })
219
219
  })
@@ -221,6 +221,6 @@ function k({ collapsed: k, showCollapseToggle: A, showMobileCloseButton: j = !1,
221
221
  });
222
222
  }
223
223
  //#endregion
224
- export { k as SidebarRailBody };
224
+ export { A as SidebarRailBody };
225
225
 
226
226
  //# sourceMappingURL=sidebar-rail-body.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar-rail-body.js","names":[],"sources":["../../../../src/components/features/sidebar/sidebar-rail-body.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n ChevronLeft,\n ChevronRight,\n Plus,\n Server,\n Settings,\n} from \"lucide-react\";\nimport { OpenHandsLogoButton } from \"#/components/shared/buttons/openhands-logo-button\";\nimport { SidebarCollapsedIconSlot } from \"./sidebar-collapsed-icon-slot\";\nimport { SidebarNavLink } from \"./sidebar-nav-link\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { BackendSelector } from \"#/components/features/backends/backend-selector\";\nimport { BackendStatusDot } from \"#/components/features/backends/backend-status-dot\";\nimport { SidebarConversationList } from \"./sidebar-conversation-list\";\nimport AutomationsIcon from \"#/icons/automations.svg?react\";\nimport {\n SIDEBAR_COLLAPSE_TOGGLE_OVERLAY_CLASS,\n SIDEBAR_COLLAPSED_LOGO_WRAPPER_CLASS,\n SIDEBAR_ICON_BUTTON_CLASS,\n SIDEBAR_ICON_SLOT_CLASS,\n sidebarHeaderRowClassName,\n sidebarNavLabelClassName,\n sidebarNavListClassName,\n sidebarNavRowClassName,\n} from \"./sidebar-layout\";\n\nconst ICON_SIZE = 18;\nconst SIDEBAR_LOGO_WIDTH = 34;\nconst SIDEBAR_LOGO_HEIGHT = Math.round((SIDEBAR_LOGO_WIDTH * 30) / 46);\n\nexport interface SidebarRailBodyProps {\n collapsed: boolean;\n showCollapseToggle: boolean;\n showMobileCloseButton?: boolean;\n onCloseMobile?: () => void;\n linkDisabled: boolean;\n collapseToggleLabel: string;\n onCollapse: () => void;\n onExpand: () => void;\n showCollapsedExpandButton: boolean;\n isExtensionsActive: boolean;\n currentPath: string;\n navigate: (path: string) => void;\n activeBackendHealth: { isConnected: boolean | null } | undefined;\n collapsedBackendPopoverOpen: boolean;\n setCollapsedBackendPopoverOpen: (open: boolean) => void;\n collapsedBackendPopoverRef: React.RefObject<HTMLDivElement | null>;\n collapsedBackendCloseTimer: React.MutableRefObject<ReturnType<\n typeof setTimeout\n > | null>;\n onOpenAddBackend: () => void;\n onOpenManageBackends: () => void;\n}\n\nexport function SidebarRailBody({\n collapsed,\n showCollapseToggle,\n showMobileCloseButton = false,\n onCloseMobile,\n linkDisabled,\n collapseToggleLabel,\n onCollapse,\n onExpand,\n showCollapsedExpandButton,\n isExtensionsActive,\n currentPath,\n navigate,\n activeBackendHealth,\n collapsedBackendPopoverOpen,\n setCollapsedBackendPopoverOpen,\n collapsedBackendPopoverRef,\n collapsedBackendCloseTimer,\n onOpenAddBackend,\n onOpenManageBackends,\n}: SidebarRailBodyProps) {\n const { t } = useTranslation(\"openhands\");\n const backendCloseTimerRef = collapsedBackendCloseTimer;\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className={sidebarHeaderRowClassName(collapsed)}>\n <div\n className={cn(\n collapsed && showCollapseToggle\n ? SIDEBAR_COLLAPSED_LOGO_WRAPPER_CLASS\n : \"flex min-w-0 shrink-0 items-center\",\n )}\n >\n <div\n className={cn(\n collapsed &&\n showCollapseToggle &&\n \"flex h-full w-full items-center justify-start pl-2.5 transition-opacity duration-150\",\n collapsed && showCollapsedExpandButton && \"opacity-0\",\n )}\n >\n <OpenHandsLogoButton\n logoWidth={SIDEBAR_LOGO_WIDTH}\n logoHeight={SIDEBAR_LOGO_HEIGHT}\n logoClassName=\"max-w-none\"\n className={cn(SIDEBAR_ICON_SLOT_CLASS, \"overflow-visible\")}\n />\n </div>\n {collapsed && showCollapseToggle ? (\n <button\n type=\"button\"\n data-testid=\"sidebar-collapse-toggle\"\n aria-pressed={collapsed}\n aria-label={collapseToggleLabel}\n onClick={onExpand}\n className={cn(\n SIDEBAR_COLLAPSE_TOGGLE_OVERLAY_CLASS,\n showCollapsedExpandButton\n ? \"opacity-100 pointer-events-auto\"\n : \"opacity-0 pointer-events-none\",\n )}\n >\n <ChevronRight width={14} height={14} />\n </button>\n ) : null}\n </div>\n {!collapsed && showCollapseToggle ? (\n <button\n type=\"button\"\n data-testid=\"sidebar-collapse-toggle\"\n aria-pressed={collapsed}\n aria-label={collapseToggleLabel}\n onClick={onCollapse}\n className={cn(\n \"hidden md:inline-flex ml-auto\",\n SIDEBAR_ICON_BUTTON_CLASS,\n \"text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]\",\n )}\n >\n <ChevronLeft width={14} height={14} />\n </button>\n ) : null}\n {!collapsed && showMobileCloseButton ? (\n <button\n type=\"button\"\n data-testid=\"sidebar-mobile-drawer-close\"\n onClick={onCloseMobile}\n aria-label={t(I18nKey.SIDEBAR$CLOSE_MENU)}\n className={cn(\n \"inline-flex ml-auto\",\n SIDEBAR_ICON_BUTTON_CLASS,\n \"text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]\",\n )}\n >\n <ChevronLeft width={14} height={14} />\n </button>\n ) : null}\n </div>\n\n <nav className={sidebarNavListClassName(collapsed)}>\n <SidebarNavLink\n to=\"/conversations\"\n end\n label=\"New Chat\"\n testId=\"sidebar-conversations-link\"\n disabled={linkDisabled}\n collapsed={collapsed}\n icon={<Plus width={ICON_SIZE} height={ICON_SIZE} />}\n />\n <SidebarNavLink\n to=\"/customize\"\n label=\"Customize\"\n testId=\"sidebar-skills-link\"\n disabled={linkDisabled}\n collapsed={collapsed}\n forceActive={isExtensionsActive}\n icon={\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={ICON_SIZE}\n height={ICON_SIZE}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z\" />\n <path d=\"m7 16.5-4.74-2.85\" />\n <path d=\"m7 16.5 5-3\" />\n <path d=\"M7 16.5v5.17\" />\n <path d=\"M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z\" />\n <path d=\"m17 16.5-5-3\" />\n <path d=\"m17 16.5 4.74-2.85\" />\n <path d=\"m17 16.5v5.17\" />\n <path d=\"M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z\" />\n <path d=\"M12 8 7.26 5.15\" />\n <path d=\"m12 8 4.74-2.85\" />\n <path d=\"M12 13.5V8\" />\n </svg>\n }\n />\n <SidebarNavLink\n to=\"/automations\"\n label={t(I18nKey.SIDEBAR$AUTOMATIONS)}\n testId=\"sidebar-automations-link\"\n disabled={linkDisabled}\n collapsed={collapsed}\n icon={<AutomationsIcon width={ICON_SIZE} height={ICON_SIZE} />}\n />\n </nav>\n\n <SidebarConversationList collapsed={collapsed} />\n\n {collapsed && showCollapseToggle ? (\n <nav\n className={cn(\n sidebarNavListClassName(collapsed),\n \"mt-auto pb-2 cursor-pointer\",\n )}\n >\n <StyledTooltip\n content={t(I18nKey.SIDEBAR$SETTINGS)}\n placement=\"right\"\n >\n <button\n type=\"button\"\n data-testid=\"collapsed-settings-link\"\n aria-label={t(I18nKey.SIDEBAR$SETTINGS)}\n onClick={() => navigate(\"/settings\")}\n className={sidebarNavRowClassName({ collapsed: true })}\n >\n <SidebarCollapsedIconSlot\n active={currentPath.startsWith(\"/settings\")}\n >\n <Settings width={ICON_SIZE} height={ICON_SIZE} />\n </SidebarCollapsedIconSlot>\n <span className={sidebarNavLabelClassName(true)}>\n {t(I18nKey.SIDEBAR$SETTINGS)}\n </span>\n </button>\n </StyledTooltip>\n <div\n className=\"relative\"\n ref={collapsedBackendPopoverRef}\n onMouseEnter={() => {\n if (backendCloseTimerRef.current) {\n clearTimeout(backendCloseTimerRef.current);\n backendCloseTimerRef.current = null;\n }\n setCollapsedBackendPopoverOpen(true);\n }}\n onMouseLeave={() => {\n backendCloseTimerRef.current = setTimeout(\n () => setCollapsedBackendPopoverOpen(false),\n 150,\n );\n }}\n >\n <button\n type=\"button\"\n data-testid=\"collapsed-backend-selector-link\"\n aria-label={t(I18nKey.BACKEND$MANAGE)}\n aria-expanded={collapsedBackendPopoverOpen}\n onMouseDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onMouseUp={(event) => event.stopPropagation()}\n className={cn(\n sidebarNavRowClassName({ collapsed: true }),\n \"relative\",\n )}\n >\n <SidebarCollapsedIconSlot active={collapsedBackendPopoverOpen}>\n <span className=\"relative inline-flex size-[18px] shrink-0 items-center justify-center\">\n <BackendStatusDot\n isConnected={activeBackendHealth?.isConnected ?? null}\n className=\"absolute -left-0.5 -top-0.5 z-[1] pointer-events-none\"\n />\n <Server width={ICON_SIZE} height={ICON_SIZE} />\n </span>\n </SidebarCollapsedIconSlot>\n <span className={sidebarNavLabelClassName(true)}>\n {t(I18nKey.BACKEND$MANAGE)}\n </span>\n </button>\n {collapsedBackendPopoverOpen ? (\n <div\n className=\"absolute bottom-[-4px] left-full pl-2.5 z-40 w-[272px]\"\n onClick={(event) => event.stopPropagation()}\n >\n <BackendSelector\n sidebarCollapsed={collapsed}\n hideTrigger\n defaultOpen\n openUpward\n onSelectOption={() => setCollapsedBackendPopoverOpen(false)}\n onOpenAddBackend={onOpenAddBackend}\n onOpenManageBackends={onOpenManageBackends}\n />\n </div>\n ) : null}\n </div>\n </nav>\n ) : null}\n\n {!collapsed ? (\n <div\n className={cn(\n \"flex flex-col items-stretch max-w-none box-border shrink-0\",\n \"-ml-2.5 w-[calc(100%+0.625rem)] border-t border-[var(--oh-border)] pt-2 px-2.5\",\n )}\n >\n <BackendSelector sidebarCollapsed={collapsed} openUpward />\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sidebar-rail-body.js","names":[],"sources":["../../../../src/components/features/sidebar/sidebar-rail-body.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n ChevronLeft,\n ChevronRight,\n Plus,\n Server,\n Settings,\n} from \"lucide-react\";\nimport { OpenHandsLogoButton } from \"#/components/shared/buttons/openhands-logo-button\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { SidebarCollapsedIconSlot } from \"./sidebar-collapsed-icon-slot\";\nimport { SidebarNavLink } from \"./sidebar-nav-link\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { BackendSelector } from \"#/components/features/backends/backend-selector\";\nimport { BackendStatusDot } from \"#/components/features/backends/backend-status-dot\";\nimport { SidebarConversationList } from \"./sidebar-conversation-list\";\nimport AutomationsIcon from \"#/icons/automations.svg?react\";\nimport {\n SIDEBAR_COLLAPSE_TOGGLE_OVERLAY_CLASS,\n SIDEBAR_COLLAPSED_LOGO_WRAPPER_CLASS,\n SIDEBAR_ICON_BUTTON_CLASS,\n SIDEBAR_ICON_SLOT_CLASS,\n sidebarHeaderRowClassName,\n sidebarNavLabelClassName,\n sidebarNavListClassName,\n sidebarNavRowClassName,\n} from \"./sidebar-layout\";\n\nconst ICON_SIZE = 18;\nconst SIDEBAR_LOGO_WIDTH = 34;\nconst SIDEBAR_LOGO_HEIGHT = Math.round((SIDEBAR_LOGO_WIDTH * 30) / 46);\n\nexport interface SidebarRailBodyProps {\n collapsed: boolean;\n showCollapseToggle: boolean;\n showMobileCloseButton?: boolean;\n onCloseMobile?: () => void;\n linkDisabled: boolean;\n collapseToggleLabel: string;\n onCollapse: () => void;\n onExpand: () => void;\n showCollapsedExpandButton: boolean;\n isExtensionsActive: boolean;\n currentPath: string;\n activeBackendHealth: { isConnected: boolean | null } | undefined;\n collapsedBackendPopoverOpen: boolean;\n setCollapsedBackendPopoverOpen: (open: boolean) => void;\n collapsedBackendPopoverRef: React.RefObject<HTMLDivElement | null>;\n collapsedBackendCloseTimer: React.MutableRefObject<ReturnType<\n typeof setTimeout\n > | null>;\n onOpenAddBackend: () => void;\n onOpenManageBackends: () => void;\n}\n\nexport function SidebarRailBody({\n collapsed,\n showCollapseToggle,\n showMobileCloseButton = false,\n onCloseMobile,\n linkDisabled,\n collapseToggleLabel,\n onCollapse,\n onExpand,\n showCollapsedExpandButton,\n isExtensionsActive,\n currentPath,\n activeBackendHealth,\n collapsedBackendPopoverOpen,\n setCollapsedBackendPopoverOpen,\n collapsedBackendPopoverRef,\n collapsedBackendCloseTimer,\n onOpenAddBackend,\n onOpenManageBackends,\n}: SidebarRailBodyProps) {\n const { t } = useTranslation(\"openhands\");\n const backendCloseTimerRef = collapsedBackendCloseTimer;\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className={sidebarHeaderRowClassName(collapsed)}>\n <div\n className={cn(\n collapsed && showCollapseToggle\n ? SIDEBAR_COLLAPSED_LOGO_WRAPPER_CLASS\n : \"flex min-w-0 shrink-0 items-center\",\n )}\n >\n <div\n className={cn(\n collapsed &&\n showCollapseToggle &&\n \"flex h-full w-full items-center justify-start pl-2.5 transition-opacity duration-150\",\n collapsed && showCollapsedExpandButton && \"opacity-0\",\n )}\n >\n <OpenHandsLogoButton\n logoWidth={SIDEBAR_LOGO_WIDTH}\n logoHeight={SIDEBAR_LOGO_HEIGHT}\n logoClassName=\"max-w-none\"\n className={cn(SIDEBAR_ICON_SLOT_CLASS, \"overflow-visible\")}\n />\n </div>\n {collapsed && showCollapseToggle ? (\n <button\n type=\"button\"\n data-testid=\"sidebar-collapse-toggle\"\n aria-pressed={collapsed}\n aria-label={collapseToggleLabel}\n onClick={onExpand}\n className={cn(\n SIDEBAR_COLLAPSE_TOGGLE_OVERLAY_CLASS,\n showCollapsedExpandButton\n ? \"opacity-100 pointer-events-auto\"\n : \"opacity-0 pointer-events-none\",\n )}\n >\n <ChevronRight width={14} height={14} />\n </button>\n ) : null}\n </div>\n {!collapsed && showCollapseToggle ? (\n <button\n type=\"button\"\n data-testid=\"sidebar-collapse-toggle\"\n aria-pressed={collapsed}\n aria-label={collapseToggleLabel}\n onClick={onCollapse}\n className={cn(\n \"hidden md:inline-flex ml-auto\",\n SIDEBAR_ICON_BUTTON_CLASS,\n \"text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]\",\n )}\n >\n <ChevronLeft width={14} height={14} />\n </button>\n ) : null}\n {!collapsed && showMobileCloseButton ? (\n <button\n type=\"button\"\n data-testid=\"sidebar-mobile-drawer-close\"\n onClick={onCloseMobile}\n aria-label={t(I18nKey.SIDEBAR$CLOSE_MENU)}\n className={cn(\n \"inline-flex ml-auto\",\n SIDEBAR_ICON_BUTTON_CLASS,\n \"text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]\",\n )}\n >\n <ChevronLeft width={14} height={14} />\n </button>\n ) : null}\n </div>\n\n <nav className={sidebarNavListClassName(collapsed)}>\n <SidebarNavLink\n to=\"/conversations\"\n end\n label=\"New Chat\"\n testId=\"sidebar-conversations-link\"\n disabled={linkDisabled}\n collapsed={collapsed}\n icon={<Plus width={ICON_SIZE} height={ICON_SIZE} />}\n />\n <SidebarNavLink\n to=\"/customize\"\n label=\"Customize\"\n testId=\"sidebar-skills-link\"\n disabled={linkDisabled}\n collapsed={collapsed}\n forceActive={isExtensionsActive}\n icon={\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={ICON_SIZE}\n height={ICON_SIZE}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z\" />\n <path d=\"m7 16.5-4.74-2.85\" />\n <path d=\"m7 16.5 5-3\" />\n <path d=\"M7 16.5v5.17\" />\n <path d=\"M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z\" />\n <path d=\"m17 16.5-5-3\" />\n <path d=\"m17 16.5 4.74-2.85\" />\n <path d=\"m17 16.5v5.17\" />\n <path d=\"M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z\" />\n <path d=\"M12 8 7.26 5.15\" />\n <path d=\"m12 8 4.74-2.85\" />\n <path d=\"M12 13.5V8\" />\n </svg>\n }\n />\n <SidebarNavLink\n to=\"/automations\"\n label={t(I18nKey.SIDEBAR$AUTOMATIONS)}\n testId=\"sidebar-automations-link\"\n disabled={linkDisabled}\n collapsed={collapsed}\n icon={<AutomationsIcon width={ICON_SIZE} height={ICON_SIZE} />}\n />\n </nav>\n\n <SidebarConversationList collapsed={collapsed} />\n\n {collapsed && showCollapseToggle ? (\n <nav\n className={cn(\n sidebarNavListClassName(collapsed),\n \"mt-auto pb-2 cursor-pointer\",\n )}\n >\n <StyledTooltip\n content={t(I18nKey.SIDEBAR$SETTINGS)}\n placement=\"right\"\n >\n <NavigationLink\n to=\"/settings\"\n data-testid=\"collapsed-settings-link\"\n aria-label={t(I18nKey.SIDEBAR$SETTINGS)}\n className={sidebarNavRowClassName({ collapsed: true })}\n >\n <SidebarCollapsedIconSlot\n active={currentPath.startsWith(\"/settings\")}\n >\n <Settings width={ICON_SIZE} height={ICON_SIZE} />\n </SidebarCollapsedIconSlot>\n <span className={sidebarNavLabelClassName(true)}>\n {t(I18nKey.SIDEBAR$SETTINGS)}\n </span>\n </NavigationLink>\n </StyledTooltip>\n <div\n className=\"relative\"\n ref={collapsedBackendPopoverRef}\n onMouseEnter={() => {\n if (backendCloseTimerRef.current) {\n clearTimeout(backendCloseTimerRef.current);\n backendCloseTimerRef.current = null;\n }\n setCollapsedBackendPopoverOpen(true);\n }}\n onMouseLeave={() => {\n backendCloseTimerRef.current = setTimeout(\n () => setCollapsedBackendPopoverOpen(false),\n 150,\n );\n }}\n >\n <button\n type=\"button\"\n data-testid=\"collapsed-backend-selector-link\"\n aria-label={t(I18nKey.BACKEND$MANAGE)}\n aria-expanded={collapsedBackendPopoverOpen}\n onMouseDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onMouseUp={(event) => event.stopPropagation()}\n className={cn(\n sidebarNavRowClassName({ collapsed: true }),\n \"relative\",\n )}\n >\n <SidebarCollapsedIconSlot active={collapsedBackendPopoverOpen}>\n <span className=\"relative inline-flex size-[18px] shrink-0 items-center justify-center\">\n <BackendStatusDot\n isConnected={activeBackendHealth?.isConnected ?? null}\n className=\"absolute -left-0.5 -top-0.5 z-[1] pointer-events-none\"\n />\n <Server width={ICON_SIZE} height={ICON_SIZE} />\n </span>\n </SidebarCollapsedIconSlot>\n <span className={sidebarNavLabelClassName(true)}>\n {t(I18nKey.BACKEND$MANAGE)}\n </span>\n </button>\n {collapsedBackendPopoverOpen ? (\n <div\n className=\"absolute bottom-[-4px] left-full pl-2.5 z-40 w-[272px]\"\n onClick={(event) => event.stopPropagation()}\n >\n <BackendSelector\n sidebarCollapsed={collapsed}\n hideTrigger\n defaultOpen\n openUpward\n onSelectOption={() => setCollapsedBackendPopoverOpen(false)}\n onOpenAddBackend={onOpenAddBackend}\n onOpenManageBackends={onOpenManageBackends}\n />\n </div>\n ) : null}\n </div>\n </nav>\n ) : null}\n\n {!collapsed ? (\n <div\n className={cn(\n \"flex flex-col items-stretch max-w-none box-border shrink-0\",\n \"-ml-2.5 w-[calc(100%+0.625rem)] border-t border-[var(--oh-border)] pt-2 px-2.5\",\n )}\n >\n <BackendSelector sidebarCollapsed={collapsed} openUpward />\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/utils.cjs`),i=require(`../../../context/navigation-context.cjs`),a=require(`../../../contexts/active-backend-context.cjs`),o=require(`../../../utils/custom-toast-handlers.cjs`),s=require(`../../../hooks/query/use-settings.cjs`),c=require(`../../../hooks/use-click-outside-element.cjs`),l=require(`../../../hooks/query/use-config.cjs`),u=require(`./sidebar-mobile-nav-context.cjs`),d=require(`../../../stores/sidebar-store.cjs`),f=require(`../../../hooks/query/use-backends-health.cjs`),p=require(`./sidebar-rail-body.cjs`);let m=require(`react`);m=e.__toESM(m,1);let h=require(`react/jsx-runtime`);var g=m.default.lazy(()=>Promise.resolve().then(()=>require(`../../shared/modals/settings/settings-modal.cjs`)).then(e=>({default:e.SettingsModal}))),_=m.default.lazy(()=>Promise.resolve().then(()=>require(`../backends/add-backend-modal.cjs`)).then(e=>({default:e.AddBackendModal}))),v=m.default.lazy(()=>Promise.resolve().then(()=>require(`../backends/manage-backends-modal.cjs`)).then(e=>({default:e.ManageBackendsModal}))),y=250;function b(){let{t:e}=t.useTranslation(`openhands`),{currentPath:b,navigate:x}=i.useNavigation(),{data:S}=l.useConfig(),{data:C,error:w,isError:T,isFetching:E}=s.useSettings(),{backends:D,active:O}=a.useActiveBackendContext(),k=f.useBackendsHealth(D)[O.backend.id],A=d.useSidebarStore(e=>e.collapsed),j=d.useSidebarStore(e=>e.setCollapsed),[ee,M]=m.default.useState(!1),[N,P]=m.default.useState(!1),F=m.default.useRef(null),[I,L]=m.default.useState(!1),[R,z]=m.default.useState(!1),[B,V]=m.default.useState(!1),H=m.default.useRef(!1),[,U]=m.default.useReducer(e=>e+1,0),{isOpen:W,close:G}=u.useSidebarMobileNav(),[K,q]=m.default.useState(!1),[J,Y]=m.default.useState(!1),X=c.useClickOutsideElement(()=>P(!1)),Z=s.getErrorStatus(w);m.default.useEffect(()=>{G()},[b,G]),m.default.useEffect(()=>{if(W){q(!0);let e=requestAnimationFrame(()=>{Y(!0)});return()=>cancelAnimationFrame(e)}Y(!1);let e=window.setTimeout(()=>{q(!1)},y);return()=>window.clearTimeout(e)},[W]),m.default.useEffect(()=>{if(!W)return;let e=e=>{e.key===`Escape`&&G()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[W,G]),m.default.useEffect(()=>{b===`/settings`?M(!1):!E&&T&&Z!==404?o.displayErrorToast(`Something went wrong while fetching settings. Please reload the page.`):Z===404&&!S?.feature_flags?.hide_llm_settings&&M(!0)},[b,E,T,Z,S?.feature_flags?.hide_llm_settings]);let Q=C?.email_verified===!1,te=e(A?n.I18nKey.SIDEBAR$EXPAND:n.I18nKey.SIDEBAR$COLLAPSE),ne=m.default.useCallback(e=>{if(!A)return;let t=e.target;t instanceof HTMLElement&&(t.closest(`a,button,input,textarea,select,[role='button'],[role='link']`)||j(!1))},[A,j]),$={linkDisabled:Q,collapseToggleLabel:te,onCollapse:m.default.useCallback(()=>{V(!1),H.current=!0,U(),j(!0),window.setTimeout(()=>{H.current=!1,U()},250)},[j]),onExpand:()=>j(!1),showCollapsedExpandButton:A&&B&&!H.current,isExtensionsActive:b===`/customize`||b.startsWith(`/skills`)||b===`/plugins`||b===`/mcp`,currentPath:b,navigate:x,activeBackendHealth:k,collapsedBackendPopoverOpen:N,setCollapsedBackendPopoverOpen:P,collapsedBackendPopoverRef:X,collapsedBackendCloseTimer:F,onOpenAddBackend:()=>L(!0),onOpenManageBackends:()=>z(!0)};return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`aside`,{"aria-label":e(n.I18nKey.SIDEBAR$NAVIGATION_LABEL),"data-collapsed":A?`true`:`false`,onClick:ne,onMouseEnter:()=>{A&&V(!0)},onMouseLeave:()=>{V(!1)},className:r.cn(`max-md:hidden flex bg-base flex-col min-h-0 transition-[width,min-width] duration-200`,`md:border-r md:border-[var(--oh-border)] md:h-full`,A?`md:w-[60px] md:min-w-[60px] md:px-2.5`:`md:w-[300px] md:min-w-[300px] pb-2 md:pl-2.5 md:pr-0`,b===`/`&&`md:pb-3`),children:(0,h.jsx)(p.SidebarRailBody,{collapsed:A,showCollapseToggle:!0,...$})}),K?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`div`,{className:r.cn(`fixed inset-0 z-40 bg-black/50 md:hidden`,`transition-opacity ease-in-out motion-reduce:transition-none`,J?`opacity-100`:`pointer-events-none opacity-0`),style:{transitionDuration:`${y}ms`},onClick:G,"aria-hidden":!J}),(0,h.jsx)(`aside`,{"aria-label":e(n.I18nKey.SIDEBAR$NAVIGATION_LABEL),"data-testid":`sidebar-mobile-drawer`,"aria-hidden":!J,className:r.cn(`fixed inset-y-0 left-0 z-50 flex min-h-0 w-[min(300px,85vw)] flex-col bg-base`,`border-r border-[var(--oh-border)] pb-2 pl-2.5 pr-0 md:hidden`,`transition-transform ease-in-out motion-reduce:transition-none`,J?`translate-x-0`:`-translate-x-full`),style:{transitionDuration:`${y}ms`},children:(0,h.jsx)(p.SidebarRailBody,{collapsed:!1,showCollapseToggle:!1,showMobileCloseButton:!0,onCloseMobile:G,...$})})]}):null,ee&&(0,h.jsx)(m.default.Suspense,{fallback:null,children:(0,h.jsx)(g,{settings:C,onClose:()=>M(!1)})}),I&&(0,h.jsx)(m.default.Suspense,{fallback:null,children:(0,h.jsx)(_,{onClose:()=>L(!1)})}),R&&(0,h.jsx)(m.default.Suspense,{fallback:null,children:(0,h.jsx)(v,{onClose:()=>z(!1)})})]})}exports.Sidebar=b;
1
+ const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/utils.cjs`),i=require(`../../../context/navigation-context.cjs`),a=require(`../../../contexts/active-backend-context.cjs`),o=require(`../../../utils/custom-toast-handlers.cjs`),s=require(`../../../hooks/query/use-settings.cjs`),c=require(`../../../hooks/use-click-outside-element.cjs`),l=require(`../../../hooks/query/use-config.cjs`),ee=require(`./sidebar-mobile-nav-context.cjs`),u=require(`../../../stores/sidebar-store.cjs`),d=require(`../../../hooks/query/use-backends-health.cjs`),f=require(`./sidebar-rail-body.cjs`);let p=require(`react`);p=e.__toESM(p,1);let m=require(`react/jsx-runtime`);var h=p.default.lazy(()=>Promise.resolve().then(()=>require(`../../shared/modals/settings/settings-modal.cjs`)).then(e=>({default:e.SettingsModal}))),g=p.default.lazy(()=>Promise.resolve().then(()=>require(`../backends/add-backend-modal.cjs`)).then(e=>({default:e.AddBackendModal}))),_=p.default.lazy(()=>Promise.resolve().then(()=>require(`../backends/manage-backends-modal.cjs`)).then(e=>({default:e.ManageBackendsModal}))),v=250;function y(){let{t:e}=t.useTranslation(`openhands`),{currentPath:y}=i.useNavigation(),{data:b}=l.useConfig(),{data:x,error:S,isError:C,isFetching:w}=s.useSettings(),{backends:T,active:E}=a.useActiveBackendContext(),D=d.useBackendsHealth(T)[E.backend.id],O=u.useSidebarStore(e=>e.collapsed),k=u.useSidebarStore(e=>e.setCollapsed),[A,j]=p.default.useState(!1),[M,N]=p.default.useState(!1),P=p.default.useRef(null),[F,I]=p.default.useState(!1),[L,R]=p.default.useState(!1),[z,B]=p.default.useState(!1),V=p.default.useRef(!1),[,H]=p.default.useReducer(e=>e+1,0),{isOpen:U,close:W}=ee.useSidebarMobileNav(),[G,K]=p.default.useState(!1),[q,J]=p.default.useState(!1),Y=c.useClickOutsideElement(()=>N(!1)),X=s.getErrorStatus(S);p.default.useEffect(()=>{W()},[y,W]),p.default.useEffect(()=>{if(U){K(!0);let e=requestAnimationFrame(()=>{J(!0)});return()=>cancelAnimationFrame(e)}J(!1);let e=window.setTimeout(()=>{K(!1)},v);return()=>window.clearTimeout(e)},[U]),p.default.useEffect(()=>{if(!U)return;let e=e=>{e.key===`Escape`&&W()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[U,W]),p.default.useEffect(()=>{y===`/settings`?j(!1):!w&&C&&X!==404?o.displayErrorToast(`Something went wrong while fetching settings. Please reload the page.`):X===404&&!b?.feature_flags?.hide_llm_settings&&j(!0)},[y,w,C,X,b?.feature_flags?.hide_llm_settings]);let Z=x?.email_verified===!1,Q=e(O?n.I18nKey.SIDEBAR$EXPAND:n.I18nKey.SIDEBAR$COLLAPSE),te=p.default.useCallback(e=>{if(!O)return;let t=e.target;t instanceof HTMLElement&&(t.closest(`a,button,input,textarea,select,[role='button'],[role='link']`)||k(!1))},[O,k]),$={linkDisabled:Z,collapseToggleLabel:Q,onCollapse:p.default.useCallback(()=>{B(!1),V.current=!0,H(),k(!0),window.setTimeout(()=>{V.current=!1,H()},250)},[k]),onExpand:()=>k(!1),showCollapsedExpandButton:O&&z&&!V.current,isExtensionsActive:y===`/customize`||y.startsWith(`/skills`)||y===`/plugins`||y===`/mcp`,currentPath:y,activeBackendHealth:D,collapsedBackendPopoverOpen:M,setCollapsedBackendPopoverOpen:N,collapsedBackendPopoverRef:Y,collapsedBackendCloseTimer:P,onOpenAddBackend:()=>I(!0),onOpenManageBackends:()=>R(!0)};return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`aside`,{"aria-label":e(n.I18nKey.SIDEBAR$NAVIGATION_LABEL),"data-collapsed":O?`true`:`false`,onClick:te,onMouseEnter:()=>{O&&B(!0)},onMouseLeave:()=>{B(!1)},className:r.cn(`max-md:hidden flex bg-base flex-col min-h-0 transition-[width,min-width] duration-200`,`md:border-r md:border-[var(--oh-border)] md:h-full`,O?`md:w-[60px] md:min-w-[60px] md:px-2.5`:`md:w-[300px] md:min-w-[300px] pb-2 md:pl-2.5 md:pr-0`,y===`/`&&`md:pb-3`),children:(0,m.jsx)(f.SidebarRailBody,{collapsed:O,showCollapseToggle:!0,...$})}),G?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`div`,{className:r.cn(`fixed inset-0 z-40 bg-black/50 md:hidden`,`transition-opacity ease-in-out motion-reduce:transition-none`,q?`opacity-100`:`pointer-events-none opacity-0`),style:{transitionDuration:`${v}ms`},onClick:W,"aria-hidden":!q}),(0,m.jsx)(`aside`,{"aria-label":e(n.I18nKey.SIDEBAR$NAVIGATION_LABEL),"data-testid":`sidebar-mobile-drawer`,"aria-hidden":!q,className:r.cn(`fixed inset-y-0 left-0 z-50 flex min-h-0 w-[min(300px,85vw)] flex-col bg-base`,`border-r border-[var(--oh-border)] pb-2 pl-2.5 pr-0 md:hidden`,`transition-transform ease-in-out motion-reduce:transition-none`,q?`translate-x-0`:`-translate-x-full`),style:{transitionDuration:`${v}ms`},children:(0,m.jsx)(f.SidebarRailBody,{collapsed:!1,showCollapseToggle:!1,showMobileCloseButton:!0,onCloseMobile:W,...$})})]}):null,A&&(0,m.jsx)(p.default.Suspense,{fallback:null,children:(0,m.jsx)(h,{settings:x,onClose:()=>j(!1)})}),F&&(0,m.jsx)(p.default.Suspense,{fallback:null,children:(0,m.jsx)(g,{onClose:()=>I(!1)})}),L&&(0,m.jsx)(p.default.Suspense,{fallback:null,children:(0,m.jsx)(_,{onClose:()=>R(!1)})})]})}exports.Sidebar=y;
2
2
  //# sourceMappingURL=sidebar.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.cjs","names":[],"sources":["../../../../src/components/features/sidebar/sidebar.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { SidebarRailBody } from \"./sidebar-rail-body\";\nimport { getErrorStatus, useSettings } from \"#/hooks/query/use-settings\";\nimport { useConfig } from \"#/hooks/query/use-config\";\nimport { displayErrorToast } from \"#/utils/custom-toast-handlers\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { cn } from \"#/utils/utils\";\nimport { useSidebarMobileNav } from \"./sidebar-mobile-nav-context\";\nimport { useSidebarStore } from \"#/stores/sidebar-store\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { useBackendsHealth } from \"#/hooks/query/use-backends-health\";\n// The LLM settings modal is only mounted when the settings query 404s and\n// LLM settings aren't hidden — keep it out of the sidebar's eager graph.\nconst SettingsModal = React.lazy(() =>\n import(\"#/components/shared/modals/settings/settings-modal\").then((m) => ({\n default: m.SettingsModal,\n })),\n);\n\n// Add/Manage backend modals are lifted into the sidebar (instead of living\n// inside BackendSelector) so they survive the collapsed popover unmounting\n// when the user moves the cursor out of the popover toward the modal.\nconst AddBackendModal = React.lazy(() =>\n import(\"#/components/features/backends/add-backend-modal\").then((m) => ({\n default: m.AddBackendModal,\n })),\n);\nconst ManageBackendsModal = React.lazy(() =>\n import(\"#/components/features/backends/manage-backends-modal\").then((m) => ({\n default: m.ManageBackendsModal,\n })),\n);\n\nconst MOBILE_DRAWER_TRANSITION_MS = 250;\n\nexport function Sidebar() {\n const { t } = useTranslation(\"openhands\");\n const { currentPath, navigate } = useNavigation();\n const { data: config } = useConfig();\n const {\n data: settings,\n error: settingsError,\n isError: settingsIsError,\n isFetching: isFetchingSettings,\n } = useSettings();\n const { backends, active } = useActiveBackendContext();\n const healthByBackendId = useBackendsHealth(backends);\n const activeBackendHealth = healthByBackendId[active.backend.id];\n const collapsed = useSidebarStore((state) => state.collapsed);\n const setCollapsed = useSidebarStore((state) => state.setCollapsed);\n const [settingsModalIsOpen, setSettingsModalIsOpen] = React.useState(false);\n const [collapsedBackendPopoverOpen, setCollapsedBackendPopoverOpen] =\n React.useState(false);\n const collapsedBackendCloseTimer = React.useRef<ReturnType<\n typeof setTimeout\n > | null>(null);\n // Lifted out of BackendSelector so opening these modals from the\n // collapsed-sidebar popover doesn't lose state when the popover unmounts\n // (cursor moving toward the modal triggers onMouseLeave -> close).\n const [addBackendModalOpen, setAddBackendModalOpen] = React.useState(false);\n const [manageBackendsModalOpen, setManageBackendsModalOpen] =\n React.useState(false);\n const [collapsedRailHovered, setCollapsedRailHovered] = React.useState(false);\n const suppressCollapsedExpandRef = React.useRef(false);\n const [, refreshCollapsedExpandGate] = React.useReducer((n) => n + 1, 0);\n const { isOpen: isMobileNavOpen, close: closeMobileNav } =\n useSidebarMobileNav();\n const [mobileDrawerMounted, setMobileDrawerMounted] = React.useState(false);\n const [mobileDrawerVisible, setMobileDrawerVisible] = React.useState(false);\n const collapsedBackendPopoverRef = useClickOutsideElement<HTMLDivElement>(\n () => setCollapsedBackendPopoverOpen(false),\n );\n const settingsErrorStatus = getErrorStatus(settingsError);\n\n React.useEffect(() => {\n closeMobileNav();\n }, [currentPath, closeMobileNav]);\n\n React.useEffect(() => {\n if (isMobileNavOpen) {\n setMobileDrawerMounted(true);\n const frame = requestAnimationFrame(() => {\n setMobileDrawerVisible(true);\n });\n return () => cancelAnimationFrame(frame);\n }\n\n setMobileDrawerVisible(false);\n const timer = window.setTimeout(() => {\n setMobileDrawerMounted(false);\n }, MOBILE_DRAWER_TRANSITION_MS);\n return () => window.clearTimeout(timer);\n }, [isMobileNavOpen]);\n\n React.useEffect(() => {\n if (!isMobileNavOpen) {\n return undefined;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n closeMobileNav();\n }\n };\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [isMobileNavOpen, closeMobileNav]);\n\n React.useEffect(() => {\n if (currentPath === \"/settings\") {\n setSettingsModalIsOpen(false);\n } else if (\n !isFetchingSettings &&\n settingsIsError &&\n settingsErrorStatus !== 404\n ) {\n // We don't show toast errors for settings in the global error handler\n // because we have a special case for 404 errors\n displayErrorToast(\n \"Something went wrong while fetching settings. Please reload the page.\",\n );\n } else if (\n settingsErrorStatus === 404 &&\n !config?.feature_flags?.hide_llm_settings\n ) {\n setSettingsModalIsOpen(true);\n }\n }, [\n currentPath,\n isFetchingSettings,\n settingsIsError,\n settingsErrorStatus,\n config?.feature_flags?.hide_llm_settings,\n ]);\n\n const linkDisabled = settings?.email_verified === false;\n\n const collapseToggleLabel = t(\n collapsed ? I18nKey.SIDEBAR$EXPAND : I18nKey.SIDEBAR$COLLAPSE,\n );\n const handleCollapsedRailClick = React.useCallback(\n (event: React.MouseEvent<HTMLElement>) => {\n if (!collapsed) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n\n // Keep existing behavior for explicit controls/links and only use\n // this as a convenience hit-area for empty collapsed-rail space.\n if (\n target.closest(\n \"a,button,input,textarea,select,[role='button'],[role='link']\",\n )\n ) {\n return;\n }\n\n setCollapsed(false);\n },\n [collapsed, setCollapsed],\n );\n const handleCollapse = React.useCallback(() => {\n setCollapsedRailHovered(false);\n suppressCollapsedExpandRef.current = true;\n refreshCollapsedExpandGate();\n setCollapsed(true);\n window.setTimeout(() => {\n suppressCollapsedExpandRef.current = false;\n refreshCollapsedExpandGate();\n }, 250);\n }, [setCollapsed]);\n const showCollapsedExpandButton =\n collapsed && collapsedRailHovered && !suppressCollapsedExpandRef.current;\n\n const isExtensionsActive =\n currentPath === \"/customize\" ||\n currentPath.startsWith(\"/skills\") ||\n currentPath === \"/plugins\" ||\n currentPath === \"/mcp\";\n\n const railBodyProps = {\n linkDisabled,\n collapseToggleLabel,\n onCollapse: handleCollapse,\n onExpand: () => setCollapsed(false),\n showCollapsedExpandButton,\n isExtensionsActive,\n currentPath,\n navigate,\n activeBackendHealth,\n collapsedBackendPopoverOpen,\n setCollapsedBackendPopoverOpen,\n collapsedBackendPopoverRef,\n collapsedBackendCloseTimer,\n onOpenAddBackend: () => setAddBackendModalOpen(true),\n onOpenManageBackends: () => setManageBackendsModalOpen(true),\n };\n\n return (\n <>\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- the aside acts as a hit-area for the collapsed rail; nested controls handle their own keyboard interactions. */}\n <aside\n aria-label={t(I18nKey.SIDEBAR$NAVIGATION_LABEL)}\n data-collapsed={collapsed ? \"true\" : \"false\"}\n onClick={handleCollapsedRailClick}\n onMouseEnter={() => {\n if (collapsed) {\n setCollapsedRailHovered(true);\n }\n }}\n onMouseLeave={() => {\n setCollapsedRailHovered(false);\n }}\n className={cn(\n \"max-md:hidden flex bg-base flex-col min-h-0 transition-[width,min-width] duration-200\",\n \"md:border-r md:border-[var(--oh-border)] md:h-full\",\n collapsed\n ? \"md:w-[60px] md:min-w-[60px] md:px-2.5\"\n : \"md:w-[300px] md:min-w-[300px] pb-2 md:pl-2.5 md:pr-0\",\n currentPath === \"/\" && \"md:pb-3\",\n )}\n >\n <SidebarRailBody\n collapsed={collapsed}\n showCollapseToggle\n {...railBodyProps}\n />\n </aside>\n\n {mobileDrawerMounted ? (\n <>\n <div\n className={cn(\n \"fixed inset-0 z-40 bg-black/50 md:hidden\",\n \"transition-opacity ease-in-out motion-reduce:transition-none\",\n mobileDrawerVisible\n ? \"opacity-100\"\n : \"pointer-events-none opacity-0\",\n )}\n style={{ transitionDuration: `${MOBILE_DRAWER_TRANSITION_MS}ms` }}\n onClick={closeMobileNav}\n aria-hidden={!mobileDrawerVisible}\n />\n <aside\n aria-label={t(I18nKey.SIDEBAR$NAVIGATION_LABEL)}\n data-testid=\"sidebar-mobile-drawer\"\n aria-hidden={!mobileDrawerVisible}\n className={cn(\n \"fixed inset-y-0 left-0 z-50 flex min-h-0 w-[min(300px,85vw)] flex-col bg-base\",\n \"border-r border-[var(--oh-border)] pb-2 pl-2.5 pr-0 md:hidden\",\n \"transition-transform ease-in-out motion-reduce:transition-none\",\n mobileDrawerVisible ? \"translate-x-0\" : \"-translate-x-full\",\n )}\n style={{ transitionDuration: `${MOBILE_DRAWER_TRANSITION_MS}ms` }}\n >\n <SidebarRailBody\n collapsed={false}\n showCollapseToggle={false}\n showMobileCloseButton\n onCloseMobile={closeMobileNav}\n {...railBodyProps}\n />\n </aside>\n </>\n ) : null}\n\n {settingsModalIsOpen && (\n <React.Suspense fallback={null}>\n <SettingsModal\n settings={settings}\n onClose={() => setSettingsModalIsOpen(false)}\n />\n </React.Suspense>\n )}\n {addBackendModalOpen && (\n <React.Suspense fallback={null}>\n <AddBackendModal onClose={() => setAddBackendModalOpen(false)} />\n </React.Suspense>\n )}\n {manageBackendsModalOpen && (\n <React.Suspense fallback={null}>\n <ManageBackendsModal\n onClose={() => setManageBackendsModalOpen(false)}\n />\n </React.Suspense>\n )}\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sidebar.cjs","names":[],"sources":["../../../../src/components/features/sidebar/sidebar.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { SidebarRailBody } from \"./sidebar-rail-body\";\nimport { getErrorStatus, useSettings } from \"#/hooks/query/use-settings\";\nimport { useConfig } from \"#/hooks/query/use-config\";\nimport { displayErrorToast } from \"#/utils/custom-toast-handlers\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { cn } from \"#/utils/utils\";\nimport { useSidebarMobileNav } from \"./sidebar-mobile-nav-context\";\nimport { useSidebarStore } from \"#/stores/sidebar-store\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { useBackendsHealth } from \"#/hooks/query/use-backends-health\";\n// The LLM settings modal is only mounted when the settings query 404s and\n// LLM settings aren't hidden — keep it out of the sidebar's eager graph.\nconst SettingsModal = React.lazy(() =>\n import(\"#/components/shared/modals/settings/settings-modal\").then((m) => ({\n default: m.SettingsModal,\n })),\n);\n\n// Add/Manage backend modals are lifted into the sidebar (instead of living\n// inside BackendSelector) so they survive the collapsed popover unmounting\n// when the user moves the cursor out of the popover toward the modal.\nconst AddBackendModal = React.lazy(() =>\n import(\"#/components/features/backends/add-backend-modal\").then((m) => ({\n default: m.AddBackendModal,\n })),\n);\nconst ManageBackendsModal = React.lazy(() =>\n import(\"#/components/features/backends/manage-backends-modal\").then((m) => ({\n default: m.ManageBackendsModal,\n })),\n);\n\nconst MOBILE_DRAWER_TRANSITION_MS = 250;\n\nexport function Sidebar() {\n const { t } = useTranslation(\"openhands\");\n const { currentPath } = useNavigation();\n const { data: config } = useConfig();\n const {\n data: settings,\n error: settingsError,\n isError: settingsIsError,\n isFetching: isFetchingSettings,\n } = useSettings();\n const { backends, active } = useActiveBackendContext();\n const healthByBackendId = useBackendsHealth(backends);\n const activeBackendHealth = healthByBackendId[active.backend.id];\n const collapsed = useSidebarStore((state) => state.collapsed);\n const setCollapsed = useSidebarStore((state) => state.setCollapsed);\n const [settingsModalIsOpen, setSettingsModalIsOpen] = React.useState(false);\n const [collapsedBackendPopoverOpen, setCollapsedBackendPopoverOpen] =\n React.useState(false);\n const collapsedBackendCloseTimer = React.useRef<ReturnType<\n typeof setTimeout\n > | null>(null);\n // Lifted out of BackendSelector so opening these modals from the\n // collapsed-sidebar popover doesn't lose state when the popover unmounts\n // (cursor moving toward the modal triggers onMouseLeave -> close).\n const [addBackendModalOpen, setAddBackendModalOpen] = React.useState(false);\n const [manageBackendsModalOpen, setManageBackendsModalOpen] =\n React.useState(false);\n const [collapsedRailHovered, setCollapsedRailHovered] = React.useState(false);\n const suppressCollapsedExpandRef = React.useRef(false);\n const [, refreshCollapsedExpandGate] = React.useReducer((n) => n + 1, 0);\n const { isOpen: isMobileNavOpen, close: closeMobileNav } =\n useSidebarMobileNav();\n const [mobileDrawerMounted, setMobileDrawerMounted] = React.useState(false);\n const [mobileDrawerVisible, setMobileDrawerVisible] = React.useState(false);\n const collapsedBackendPopoverRef = useClickOutsideElement<HTMLDivElement>(\n () => setCollapsedBackendPopoverOpen(false),\n );\n const settingsErrorStatus = getErrorStatus(settingsError);\n\n React.useEffect(() => {\n closeMobileNav();\n }, [currentPath, closeMobileNav]);\n\n React.useEffect(() => {\n if (isMobileNavOpen) {\n setMobileDrawerMounted(true);\n const frame = requestAnimationFrame(() => {\n setMobileDrawerVisible(true);\n });\n return () => cancelAnimationFrame(frame);\n }\n\n setMobileDrawerVisible(false);\n const timer = window.setTimeout(() => {\n setMobileDrawerMounted(false);\n }, MOBILE_DRAWER_TRANSITION_MS);\n return () => window.clearTimeout(timer);\n }, [isMobileNavOpen]);\n\n React.useEffect(() => {\n if (!isMobileNavOpen) {\n return undefined;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n closeMobileNav();\n }\n };\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [isMobileNavOpen, closeMobileNav]);\n\n React.useEffect(() => {\n if (currentPath === \"/settings\") {\n setSettingsModalIsOpen(false);\n } else if (\n !isFetchingSettings &&\n settingsIsError &&\n settingsErrorStatus !== 404\n ) {\n // We don't show toast errors for settings in the global error handler\n // because we have a special case for 404 errors\n displayErrorToast(\n \"Something went wrong while fetching settings. Please reload the page.\",\n );\n } else if (\n settingsErrorStatus === 404 &&\n !config?.feature_flags?.hide_llm_settings\n ) {\n setSettingsModalIsOpen(true);\n }\n }, [\n currentPath,\n isFetchingSettings,\n settingsIsError,\n settingsErrorStatus,\n config?.feature_flags?.hide_llm_settings,\n ]);\n\n const linkDisabled = settings?.email_verified === false;\n\n const collapseToggleLabel = t(\n collapsed ? I18nKey.SIDEBAR$EXPAND : I18nKey.SIDEBAR$COLLAPSE,\n );\n const handleCollapsedRailClick = React.useCallback(\n (event: React.MouseEvent<HTMLElement>) => {\n if (!collapsed) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n\n // Keep existing behavior for explicit controls/links and only use\n // this as a convenience hit-area for empty collapsed-rail space.\n if (\n target.closest(\n \"a,button,input,textarea,select,[role='button'],[role='link']\",\n )\n ) {\n return;\n }\n\n setCollapsed(false);\n },\n [collapsed, setCollapsed],\n );\n const handleCollapse = React.useCallback(() => {\n setCollapsedRailHovered(false);\n suppressCollapsedExpandRef.current = true;\n refreshCollapsedExpandGate();\n setCollapsed(true);\n window.setTimeout(() => {\n suppressCollapsedExpandRef.current = false;\n refreshCollapsedExpandGate();\n }, 250);\n }, [setCollapsed]);\n const showCollapsedExpandButton =\n collapsed && collapsedRailHovered && !suppressCollapsedExpandRef.current;\n\n const isExtensionsActive =\n currentPath === \"/customize\" ||\n currentPath.startsWith(\"/skills\") ||\n currentPath === \"/plugins\" ||\n currentPath === \"/mcp\";\n\n const railBodyProps = {\n linkDisabled,\n collapseToggleLabel,\n onCollapse: handleCollapse,\n onExpand: () => setCollapsed(false),\n showCollapsedExpandButton,\n isExtensionsActive,\n currentPath,\n activeBackendHealth,\n collapsedBackendPopoverOpen,\n setCollapsedBackendPopoverOpen,\n collapsedBackendPopoverRef,\n collapsedBackendCloseTimer,\n onOpenAddBackend: () => setAddBackendModalOpen(true),\n onOpenManageBackends: () => setManageBackendsModalOpen(true),\n };\n\n return (\n <>\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- the aside acts as a hit-area for the collapsed rail; nested controls handle their own keyboard interactions. */}\n <aside\n aria-label={t(I18nKey.SIDEBAR$NAVIGATION_LABEL)}\n data-collapsed={collapsed ? \"true\" : \"false\"}\n onClick={handleCollapsedRailClick}\n onMouseEnter={() => {\n if (collapsed) {\n setCollapsedRailHovered(true);\n }\n }}\n onMouseLeave={() => {\n setCollapsedRailHovered(false);\n }}\n className={cn(\n \"max-md:hidden flex bg-base flex-col min-h-0 transition-[width,min-width] duration-200\",\n \"md:border-r md:border-[var(--oh-border)] md:h-full\",\n collapsed\n ? \"md:w-[60px] md:min-w-[60px] md:px-2.5\"\n : \"md:w-[300px] md:min-w-[300px] pb-2 md:pl-2.5 md:pr-0\",\n currentPath === \"/\" && \"md:pb-3\",\n )}\n >\n <SidebarRailBody\n collapsed={collapsed}\n showCollapseToggle\n {...railBodyProps}\n />\n </aside>\n\n {mobileDrawerMounted ? (\n <>\n <div\n className={cn(\n \"fixed inset-0 z-40 bg-black/50 md:hidden\",\n \"transition-opacity ease-in-out motion-reduce:transition-none\",\n mobileDrawerVisible\n ? \"opacity-100\"\n : \"pointer-events-none opacity-0\",\n )}\n style={{ transitionDuration: `${MOBILE_DRAWER_TRANSITION_MS}ms` }}\n onClick={closeMobileNav}\n aria-hidden={!mobileDrawerVisible}\n />\n <aside\n aria-label={t(I18nKey.SIDEBAR$NAVIGATION_LABEL)}\n data-testid=\"sidebar-mobile-drawer\"\n aria-hidden={!mobileDrawerVisible}\n className={cn(\n \"fixed inset-y-0 left-0 z-50 flex min-h-0 w-[min(300px,85vw)] flex-col bg-base\",\n \"border-r border-[var(--oh-border)] pb-2 pl-2.5 pr-0 md:hidden\",\n \"transition-transform ease-in-out motion-reduce:transition-none\",\n mobileDrawerVisible ? \"translate-x-0\" : \"-translate-x-full\",\n )}\n style={{ transitionDuration: `${MOBILE_DRAWER_TRANSITION_MS}ms` }}\n >\n <SidebarRailBody\n collapsed={false}\n showCollapseToggle={false}\n showMobileCloseButton\n onCloseMobile={closeMobileNav}\n {...railBodyProps}\n />\n </aside>\n </>\n ) : null}\n\n {settingsModalIsOpen && (\n <React.Suspense fallback={null}>\n <SettingsModal\n settings={settings}\n onClose={() => setSettingsModalIsOpen(false)}\n />\n </React.Suspense>\n )}\n {addBackendModalOpen && (\n <React.Suspense fallback={null}>\n <AddBackendModal onClose={() => setAddBackendModalOpen(false)} />\n </React.Suspense>\n )}\n {manageBackendsModalOpen && (\n <React.Suspense fallback={null}>\n <ManageBackendsModal\n onClose={() => setManageBackendsModalOpen(false)}\n />\n </React.Suspense>\n )}\n </>\n );\n}\n"],"mappings":"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"}