@upstash/react-redis-browser 0.2.4 → 0.2.6
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.css +149 -5
- package/dist/index.js +505 -63
- package/dist/index.mjs +528 -86
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// src/components/databrowser/index.tsx
|
|
2
|
-
import { useEffect as useEffect14, useMemo as
|
|
2
|
+
import { useEffect as useEffect14, useMemo as useMemo9, useRef as useRef6 } from "react";
|
|
3
3
|
|
|
4
4
|
// src/redis-context.tsx
|
|
5
5
|
import { createContext, useContext, useMemo } from "react";
|
|
6
6
|
|
|
7
7
|
// src/lib/clients.ts
|
|
8
8
|
import { MutationCache, QueryCache, QueryClient } from "@tanstack/react-query";
|
|
9
|
-
import { Redis } from "@upstash/redis";
|
|
9
|
+
import { Redis } from "@upstash/redis/cloudflare";
|
|
10
10
|
|
|
11
11
|
// src/components/ui/use-toast.ts
|
|
12
12
|
import * as React from "react";
|
|
@@ -219,7 +219,8 @@ import { jsx as jsx2 } from "react/jsx-runtime";
|
|
|
219
219
|
var DatabrowserContext = createContext2(void 0);
|
|
220
220
|
var DatabrowserProvider = ({
|
|
221
221
|
children,
|
|
222
|
-
storage
|
|
222
|
+
storage,
|
|
223
|
+
rootRef
|
|
223
224
|
}) => {
|
|
224
225
|
const store = useMemo2(() => {
|
|
225
226
|
if (!storage) return create(storeCreator);
|
|
@@ -241,18 +242,29 @@ var DatabrowserProvider = ({
|
|
|
241
242
|
removeItem: () => {
|
|
242
243
|
}
|
|
243
244
|
},
|
|
244
|
-
version:
|
|
245
|
+
version: 2,
|
|
245
246
|
// @ts-expect-error Reset the store for < v1
|
|
246
|
-
migrate: (
|
|
247
|
+
migrate: (originalState, version) => {
|
|
248
|
+
const state = originalState;
|
|
247
249
|
if (version === 0) {
|
|
248
250
|
return;
|
|
249
251
|
}
|
|
252
|
+
if (version === 1) {
|
|
253
|
+
return {
|
|
254
|
+
...state,
|
|
255
|
+
tabs: state.tabs.map(([id, data]) => [id, { ...data, id }])
|
|
256
|
+
};
|
|
257
|
+
}
|
|
250
258
|
return state;
|
|
251
259
|
}
|
|
252
260
|
})
|
|
253
261
|
);
|
|
254
262
|
}, []);
|
|
255
|
-
return /* @__PURE__ */ jsx2(DatabrowserContext.Provider, { value: { store }, children });
|
|
263
|
+
return /* @__PURE__ */ jsx2(DatabrowserContext.Provider, { value: { store, rootRef }, children });
|
|
264
|
+
};
|
|
265
|
+
var useDatabrowserRootRef = () => {
|
|
266
|
+
const { rootRef } = useDatabrowser();
|
|
267
|
+
return rootRef;
|
|
256
268
|
};
|
|
257
269
|
var useDatabrowser = () => {
|
|
258
270
|
const context = useContext2(DatabrowserContext);
|
|
@@ -271,8 +283,10 @@ var storeCreator = (set, get) => ({
|
|
|
271
283
|
addTab: () => {
|
|
272
284
|
const id = crypto.randomUUID();
|
|
273
285
|
const newTabData = {
|
|
286
|
+
id,
|
|
274
287
|
selectedKey: void 0,
|
|
275
|
-
search: { key: "", type: void 0 }
|
|
288
|
+
search: { key: "", type: void 0 },
|
|
289
|
+
pinned: false
|
|
276
290
|
};
|
|
277
291
|
set((old) => ({
|
|
278
292
|
tabs: [...old.tabs, [id, newTabData]],
|
|
@@ -282,6 +296,9 @@ var storeCreator = (set, get) => ({
|
|
|
282
296
|
},
|
|
283
297
|
reorderTabs: (oldIndex, newIndex) => {
|
|
284
298
|
set((old) => {
|
|
299
|
+
const [, oldTabData] = old.tabs[oldIndex];
|
|
300
|
+
const [, newTabData] = old.tabs[newIndex];
|
|
301
|
+
if (oldTabData.pinned || newTabData.pinned) return old;
|
|
285
302
|
const newTabs = [...old.tabs];
|
|
286
303
|
const [movedTab] = newTabs.splice(oldIndex, 1);
|
|
287
304
|
newTabs.splice(newIndex, 0, movedTab);
|
|
@@ -289,6 +306,22 @@ var storeCreator = (set, get) => ({
|
|
|
289
306
|
});
|
|
290
307
|
},
|
|
291
308
|
removeTab: (id) => {
|
|
309
|
+
set((old) => {
|
|
310
|
+
const tabIndex = old.tabs.findIndex(([tabId]) => tabId === id);
|
|
311
|
+
if (tabIndex === -1) return old;
|
|
312
|
+
const [, tabData] = old.tabs[tabIndex];
|
|
313
|
+
if (tabData.pinned) return old;
|
|
314
|
+
const newTabs = [...old.tabs];
|
|
315
|
+
newTabs.splice(tabIndex, 1);
|
|
316
|
+
let selectedTab = old.selectedTab;
|
|
317
|
+
if (selectedTab === id) {
|
|
318
|
+
const [newId] = newTabs[tabIndex - 1] ?? newTabs[tabIndex];
|
|
319
|
+
selectedTab = newTabs.length > 0 ? newId : void 0;
|
|
320
|
+
}
|
|
321
|
+
return { tabs: newTabs, selectedTab };
|
|
322
|
+
});
|
|
323
|
+
},
|
|
324
|
+
forceRemoveTab: (id) => {
|
|
292
325
|
set((old) => {
|
|
293
326
|
const tabIndex = old.tabs.findIndex(([tabId]) => tabId === id);
|
|
294
327
|
if (tabIndex === -1) return old;
|
|
@@ -302,6 +335,45 @@ var storeCreator = (set, get) => ({
|
|
|
302
335
|
return { tabs: newTabs, selectedTab };
|
|
303
336
|
});
|
|
304
337
|
},
|
|
338
|
+
togglePinTab: (id) => {
|
|
339
|
+
set((old) => {
|
|
340
|
+
const tabIndex = old.tabs.findIndex(([tabId2]) => tabId2 === id);
|
|
341
|
+
if (tabIndex === -1) return old;
|
|
342
|
+
const newTabs = [...old.tabs];
|
|
343
|
+
const [tabId, tabData] = newTabs[tabIndex];
|
|
344
|
+
newTabs[tabIndex] = [tabId, { ...tabData, pinned: !tabData.pinned }];
|
|
345
|
+
return { ...old, tabs: newTabs };
|
|
346
|
+
});
|
|
347
|
+
},
|
|
348
|
+
duplicateTab: (id) => {
|
|
349
|
+
let newId;
|
|
350
|
+
set((old) => {
|
|
351
|
+
const tabIndex = old.tabs.findIndex(([tabId]) => tabId === id);
|
|
352
|
+
if (tabIndex === -1) return old;
|
|
353
|
+
const newTabs = [...old.tabs];
|
|
354
|
+
const [, tabData] = newTabs[tabIndex];
|
|
355
|
+
newId = crypto.randomUUID();
|
|
356
|
+
const duplicated = [newId, { ...tabData, id: newId }];
|
|
357
|
+
newTabs.splice(tabIndex + 1, 0, duplicated);
|
|
358
|
+
return { ...old, tabs: newTabs, selectedTab: newId };
|
|
359
|
+
});
|
|
360
|
+
return newId;
|
|
361
|
+
},
|
|
362
|
+
closeOtherTabs: (id) => {
|
|
363
|
+
set((old) => {
|
|
364
|
+
const exists = old.tabs.some(([tabId]) => tabId === id);
|
|
365
|
+
if (!exists) return old;
|
|
366
|
+
const newTabs = old.tabs.filter(([tabId]) => tabId === id);
|
|
367
|
+
return { ...old, tabs: newTabs, selectedTab: id };
|
|
368
|
+
});
|
|
369
|
+
},
|
|
370
|
+
closeAllButPinned: () => {
|
|
371
|
+
set((old) => {
|
|
372
|
+
const newTabs = old.tabs.filter(([, data]) => data.pinned);
|
|
373
|
+
const newSelected = newTabs.length > 0 ? newTabs[0][0] : void 0;
|
|
374
|
+
return { ...old, tabs: newTabs, selectedTab: newSelected };
|
|
375
|
+
});
|
|
376
|
+
},
|
|
305
377
|
selectTab: (id) => {
|
|
306
378
|
set({ selectedTab: id });
|
|
307
379
|
},
|
|
@@ -410,6 +482,7 @@ var useTab = () => {
|
|
|
410
482
|
selectedKey: tabData.selectedKey,
|
|
411
483
|
selectedListItem: tabData.selectedListItem,
|
|
412
484
|
search: tabData.search,
|
|
485
|
+
pinned: tabData.pinned,
|
|
413
486
|
setSelectedKey: (key) => setSelectedKey(tabId, key),
|
|
414
487
|
setSelectedListItem: (item) => setSelectedListItem(tabId, item),
|
|
415
488
|
setSearch: (search) => setSearch(tabId, search),
|
|
@@ -3234,7 +3307,7 @@ var useKeyType = (key) => {
|
|
|
3234
3307
|
|
|
3235
3308
|
// src/components/databrowser/components/display/display-list.tsx
|
|
3236
3309
|
import { useMemo as useMemo7 } from "react";
|
|
3237
|
-
import { IconTrash } from "@tabler/icons-react";
|
|
3310
|
+
import { IconTrash as IconTrash2 } from "@tabler/icons-react";
|
|
3238
3311
|
|
|
3239
3312
|
// src/components/ui/button.tsx
|
|
3240
3313
|
import * as React3 from "react";
|
|
@@ -3334,8 +3407,7 @@ var useAddKey = () => {
|
|
|
3334
3407
|
}
|
|
3335
3408
|
case "hash": {
|
|
3336
3409
|
await redis.hset(key, {
|
|
3337
|
-
field: "
|
|
3338
|
-
value: "value"
|
|
3410
|
+
field: "value"
|
|
3339
3411
|
});
|
|
3340
3412
|
break;
|
|
3341
3413
|
}
|
|
@@ -4150,6 +4222,7 @@ var useSetTTL = () => {
|
|
|
4150
4222
|
|
|
4151
4223
|
// src/components/databrowser/components/item-context-menu.tsx
|
|
4152
4224
|
import { useState as useState5 } from "react";
|
|
4225
|
+
import { IconCopy, IconExternalLink, IconTrash } from "@tabler/icons-react";
|
|
4153
4226
|
import { ContextMenuSeparator as ContextMenuSeparator2 } from "@radix-ui/react-context-menu";
|
|
4154
4227
|
|
|
4155
4228
|
// src/components/ui/context-menu.tsx
|
|
@@ -4448,7 +4521,7 @@ var ItemContextMenu = ({
|
|
|
4448
4521
|
}
|
|
4449
4522
|
),
|
|
4450
4523
|
/* @__PURE__ */ jsxs11(ContextMenuContent, { children: [
|
|
4451
|
-
/* @__PURE__ */
|
|
4524
|
+
/* @__PURE__ */ jsxs11(
|
|
4452
4525
|
ContextMenuItem,
|
|
4453
4526
|
{
|
|
4454
4527
|
onClick: () => {
|
|
@@ -4458,10 +4531,14 @@ var ItemContextMenu = ({
|
|
|
4458
4531
|
description: "Key copied to clipboard"
|
|
4459
4532
|
});
|
|
4460
4533
|
},
|
|
4461
|
-
|
|
4534
|
+
className: "gap-2",
|
|
4535
|
+
children: [
|
|
4536
|
+
/* @__PURE__ */ jsx20(IconCopy, { size: 16 }),
|
|
4537
|
+
"Copy key"
|
|
4538
|
+
]
|
|
4462
4539
|
}
|
|
4463
4540
|
),
|
|
4464
|
-
data?.value && /* @__PURE__ */
|
|
4541
|
+
data?.value && /* @__PURE__ */ jsxs11(
|
|
4465
4542
|
ContextMenuItem,
|
|
4466
4543
|
{
|
|
4467
4544
|
onClick: () => {
|
|
@@ -4470,10 +4547,14 @@ var ItemContextMenu = ({
|
|
|
4470
4547
|
description: "Value copied to clipboard"
|
|
4471
4548
|
});
|
|
4472
4549
|
},
|
|
4473
|
-
|
|
4550
|
+
className: "gap-2",
|
|
4551
|
+
children: [
|
|
4552
|
+
/* @__PURE__ */ jsx20(IconCopy, { size: 16 }),
|
|
4553
|
+
"Copy value"
|
|
4554
|
+
]
|
|
4474
4555
|
}
|
|
4475
4556
|
),
|
|
4476
|
-
/* @__PURE__ */
|
|
4557
|
+
/* @__PURE__ */ jsxs11(
|
|
4477
4558
|
ContextMenuItem,
|
|
4478
4559
|
{
|
|
4479
4560
|
onClick: () => {
|
|
@@ -4485,11 +4566,26 @@ var ItemContextMenu = ({
|
|
|
4485
4566
|
key: data.key
|
|
4486
4567
|
});
|
|
4487
4568
|
},
|
|
4488
|
-
|
|
4569
|
+
className: "gap-2",
|
|
4570
|
+
children: [
|
|
4571
|
+
/* @__PURE__ */ jsx20(IconExternalLink, { size: 16 }),
|
|
4572
|
+
"Open in new tab"
|
|
4573
|
+
]
|
|
4489
4574
|
}
|
|
4490
4575
|
),
|
|
4491
4576
|
/* @__PURE__ */ jsx20(ContextMenuSeparator2, {}),
|
|
4492
|
-
/* @__PURE__ */
|
|
4577
|
+
/* @__PURE__ */ jsxs11(
|
|
4578
|
+
ContextMenuItem,
|
|
4579
|
+
{
|
|
4580
|
+
disabled: type === "stream",
|
|
4581
|
+
onClick: () => setAlertOpen(true),
|
|
4582
|
+
className: "gap-2",
|
|
4583
|
+
children: [
|
|
4584
|
+
/* @__PURE__ */ jsx20(IconTrash, { size: 16 }),
|
|
4585
|
+
"Delete item"
|
|
4586
|
+
]
|
|
4587
|
+
}
|
|
4588
|
+
)
|
|
4493
4589
|
] })
|
|
4494
4590
|
] })
|
|
4495
4591
|
] });
|
|
@@ -4982,7 +5078,7 @@ import { Editor, useMonaco } from "@monaco-editor/react";
|
|
|
4982
5078
|
|
|
4983
5079
|
// src/components/databrowser/copy-button.tsx
|
|
4984
5080
|
import { useState as useState6 } from "react";
|
|
4985
|
-
import { IconCheck, IconCopy } from "@tabler/icons-react";
|
|
5081
|
+
import { IconCheck, IconCopy as IconCopy2 } from "@tabler/icons-react";
|
|
4986
5082
|
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
4987
5083
|
function CopyButton({ value, ...props }) {
|
|
4988
5084
|
const [copied, setCopied] = useState6(false);
|
|
@@ -5003,7 +5099,7 @@ function CopyButton({ value, ...props }) {
|
|
|
5003
5099
|
variant: "secondary",
|
|
5004
5100
|
size: "icon-sm",
|
|
5005
5101
|
...props,
|
|
5006
|
-
children: copied ? /* @__PURE__ */ jsx30(IconCheck, { className: "size-4 text-green-500" }) : /* @__PURE__ */ jsx30(
|
|
5102
|
+
children: copied ? /* @__PURE__ */ jsx30(IconCheck, { className: "size-4 text-green-500" }) : /* @__PURE__ */ jsx30(IconCopy2, { className: "size-4 text-zinc-500" })
|
|
5007
5103
|
}
|
|
5008
5104
|
);
|
|
5009
5105
|
}
|
|
@@ -5067,7 +5163,8 @@ var CustomEditor = ({
|
|
|
5067
5163
|
lineDecorationsWidth: 0,
|
|
5068
5164
|
automaticLayout: true,
|
|
5069
5165
|
scrollBeyondLastLine: false,
|
|
5070
|
-
renderLineHighlight: "none"
|
|
5166
|
+
renderLineHighlight: "none",
|
|
5167
|
+
unusualLineTerminators: "auto"
|
|
5071
5168
|
}
|
|
5072
5169
|
}
|
|
5073
5170
|
);
|
|
@@ -5417,7 +5514,7 @@ var ListItems = ({
|
|
|
5417
5514
|
size: "icon-sm",
|
|
5418
5515
|
variant: "secondary",
|
|
5419
5516
|
onClick: (e) => e.stopPropagation(),
|
|
5420
|
-
children: /* @__PURE__ */ jsx35(
|
|
5517
|
+
children: /* @__PURE__ */ jsx35(IconTrash2, { className: "size-4 text-zinc-500" })
|
|
5421
5518
|
}
|
|
5422
5519
|
)
|
|
5423
5520
|
}
|
|
@@ -5695,6 +5792,7 @@ var Empty = () => {
|
|
|
5695
5792
|
|
|
5696
5793
|
// src/components/databrowser/components/sidebar-context-menu.tsx
|
|
5697
5794
|
import { useState as useState10 } from "react";
|
|
5795
|
+
import { IconCopy as IconCopy3, IconExternalLink as IconExternalLink2, IconTrash as IconTrash3 } from "@tabler/icons-react";
|
|
5698
5796
|
import { ContextMenuSeparator as ContextMenuSeparator3 } from "@radix-ui/react-context-menu";
|
|
5699
5797
|
import { Fragment as Fragment8, jsx as jsx41, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
5700
5798
|
var SidebarContextMenu = ({ children }) => {
|
|
@@ -5734,7 +5832,7 @@ var SidebarContextMenu = ({ children }) => {
|
|
|
5734
5832
|
}
|
|
5735
5833
|
),
|
|
5736
5834
|
/* @__PURE__ */ jsxs26(ContextMenuContent, { children: [
|
|
5737
|
-
/* @__PURE__ */
|
|
5835
|
+
/* @__PURE__ */ jsxs26(
|
|
5738
5836
|
ContextMenuItem,
|
|
5739
5837
|
{
|
|
5740
5838
|
onClick: () => {
|
|
@@ -5743,10 +5841,14 @@ var SidebarContextMenu = ({ children }) => {
|
|
|
5743
5841
|
description: "Key copied to clipboard"
|
|
5744
5842
|
});
|
|
5745
5843
|
},
|
|
5746
|
-
|
|
5844
|
+
className: "gap-2",
|
|
5845
|
+
children: [
|
|
5846
|
+
/* @__PURE__ */ jsx41(IconCopy3, { size: 16 }),
|
|
5847
|
+
"Copy key"
|
|
5848
|
+
]
|
|
5747
5849
|
}
|
|
5748
5850
|
),
|
|
5749
|
-
/* @__PURE__ */
|
|
5851
|
+
/* @__PURE__ */ jsxs26(
|
|
5750
5852
|
ContextMenuItem,
|
|
5751
5853
|
{
|
|
5752
5854
|
onClick: () => {
|
|
@@ -5755,11 +5857,18 @@ var SidebarContextMenu = ({ children }) => {
|
|
|
5755
5857
|
setSearch(newTabId, currentSearch);
|
|
5756
5858
|
selectTab(newTabId);
|
|
5757
5859
|
},
|
|
5758
|
-
|
|
5860
|
+
className: "gap-2",
|
|
5861
|
+
children: [
|
|
5862
|
+
/* @__PURE__ */ jsx41(IconExternalLink2, { size: 16 }),
|
|
5863
|
+
"Open in new tab"
|
|
5864
|
+
]
|
|
5759
5865
|
}
|
|
5760
5866
|
),
|
|
5761
5867
|
/* @__PURE__ */ jsx41(ContextMenuSeparator3, {}),
|
|
5762
|
-
/* @__PURE__ */
|
|
5868
|
+
/* @__PURE__ */ jsxs26(ContextMenuItem, { onClick: () => setAlertOpen(true), className: "gap-2", children: [
|
|
5869
|
+
/* @__PURE__ */ jsx41(IconTrash3, { size: 16 }),
|
|
5870
|
+
"Delete key"
|
|
5871
|
+
] })
|
|
5763
5872
|
] })
|
|
5764
5873
|
] })
|
|
5765
5874
|
] });
|
|
@@ -5833,7 +5942,7 @@ var SearchInput = () => {
|
|
|
5833
5942
|
setState(value);
|
|
5834
5943
|
};
|
|
5835
5944
|
const filteredHistory = dedupeSearchHistory(
|
|
5836
|
-
searchHistory.filter((item) => item.includes(state) && item !== state)
|
|
5945
|
+
searchHistory.filter((item) => item.trim() !== "" && item.trim() !== "*").filter((item) => item.includes(state) && item !== state)
|
|
5837
5946
|
).slice(0, 5).map((item) => item.endsWith("*") ? item.slice(0, -1) : item);
|
|
5838
5947
|
useEffect11(() => {
|
|
5839
5948
|
setFocusedIndex(-1);
|
|
@@ -6036,7 +6145,7 @@ var DatabrowserInstance = ({ hidden }) => {
|
|
|
6036
6145
|
};
|
|
6037
6146
|
|
|
6038
6147
|
// src/components/databrowser/components/databrowser-tabs.tsx
|
|
6039
|
-
import { useEffect as useEffect13, useRef as useRef5, useState as useState13 } from "react";
|
|
6148
|
+
import { useCallback as useCallback3, useEffect as useEffect13, useMemo as useMemo8, useRef as useRef5, useState as useState13 } from "react";
|
|
6040
6149
|
import {
|
|
6041
6150
|
closestCenter,
|
|
6042
6151
|
DndContext,
|
|
@@ -6048,18 +6157,125 @@ import {
|
|
|
6048
6157
|
import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
|
|
6049
6158
|
import { horizontalListSortingStrategy, SortableContext, useSortable } from "@dnd-kit/sortable";
|
|
6050
6159
|
import { CSS } from "@dnd-kit/utilities";
|
|
6051
|
-
import { IconPlus as IconPlus2 } from "@tabler/icons-react";
|
|
6160
|
+
import { IconChevronDown as IconChevronDown2, IconPlus as IconPlus2 } from "@tabler/icons-react";
|
|
6161
|
+
|
|
6162
|
+
// src/components/ui/command.tsx
|
|
6163
|
+
import * as React13 from "react";
|
|
6164
|
+
import { Command as CommandPrimitive } from "cmdk";
|
|
6165
|
+
import { MagnifyingGlassIcon } from "@radix-ui/react-icons";
|
|
6166
|
+
import { jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
6167
|
+
var Command = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx48(
|
|
6168
|
+
CommandPrimitive,
|
|
6169
|
+
{
|
|
6170
|
+
ref,
|
|
6171
|
+
className: cn(
|
|
6172
|
+
"flex h-full w-full flex-col overflow-hidden rounded-md bg-white text-neutral-950 dark:bg-neutral-950 dark:text-neutral-50",
|
|
6173
|
+
className
|
|
6174
|
+
),
|
|
6175
|
+
...props
|
|
6176
|
+
}
|
|
6177
|
+
));
|
|
6178
|
+
Command.displayName = CommandPrimitive.displayName;
|
|
6179
|
+
var CommandInput = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs33("div", { className: "flex items-center border-b px-3", "cmdk-input-wrapper": "", children: [
|
|
6180
|
+
/* @__PURE__ */ jsx48(MagnifyingGlassIcon, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
|
|
6181
|
+
/* @__PURE__ */ jsx48(
|
|
6182
|
+
CommandPrimitive.Input,
|
|
6183
|
+
{
|
|
6184
|
+
ref,
|
|
6185
|
+
className: cn(
|
|
6186
|
+
"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-neutral-500 disabled:cursor-not-allowed disabled:opacity-50 dark:placeholder:text-neutral-400",
|
|
6187
|
+
className
|
|
6188
|
+
),
|
|
6189
|
+
...props
|
|
6190
|
+
}
|
|
6191
|
+
)
|
|
6192
|
+
] }));
|
|
6193
|
+
CommandInput.displayName = CommandPrimitive.Input.displayName;
|
|
6194
|
+
var CommandList = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx48(
|
|
6195
|
+
CommandPrimitive.List,
|
|
6196
|
+
{
|
|
6197
|
+
ref,
|
|
6198
|
+
className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className),
|
|
6199
|
+
...props
|
|
6200
|
+
}
|
|
6201
|
+
));
|
|
6202
|
+
CommandList.displayName = CommandPrimitive.List.displayName;
|
|
6203
|
+
var CommandEmpty = React13.forwardRef((props, ref) => /* @__PURE__ */ jsx48(
|
|
6204
|
+
CommandPrimitive.Empty,
|
|
6205
|
+
{
|
|
6206
|
+
ref,
|
|
6207
|
+
className: "py-6 text-center text-sm",
|
|
6208
|
+
...props
|
|
6209
|
+
}
|
|
6210
|
+
));
|
|
6211
|
+
CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
|
|
6212
|
+
var CommandGroup = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx48(
|
|
6213
|
+
CommandPrimitive.Group,
|
|
6214
|
+
{
|
|
6215
|
+
ref,
|
|
6216
|
+
className: cn(
|
|
6217
|
+
"overflow-hidden p-1 text-neutral-950 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-neutral-500 dark:text-neutral-50 dark:[&_[cmdk-group-heading]]:text-neutral-400",
|
|
6218
|
+
className
|
|
6219
|
+
),
|
|
6220
|
+
...props
|
|
6221
|
+
}
|
|
6222
|
+
));
|
|
6223
|
+
CommandGroup.displayName = CommandPrimitive.Group.displayName;
|
|
6224
|
+
var CommandSeparator = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx48(
|
|
6225
|
+
CommandPrimitive.Separator,
|
|
6226
|
+
{
|
|
6227
|
+
ref,
|
|
6228
|
+
className: cn("-mx-1 h-px bg-neutral-200 dark:bg-neutral-800", className),
|
|
6229
|
+
...props
|
|
6230
|
+
}
|
|
6231
|
+
));
|
|
6232
|
+
CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
|
|
6233
|
+
var CommandItem = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx48(
|
|
6234
|
+
CommandPrimitive.Item,
|
|
6235
|
+
{
|
|
6236
|
+
ref,
|
|
6237
|
+
className: cn(
|
|
6238
|
+
"relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-neutral-100 data-[selected=true]:text-neutral-900 data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:data-[selected=true]:bg-neutral-800 dark:data-[selected=true]:text-neutral-50",
|
|
6239
|
+
className
|
|
6240
|
+
),
|
|
6241
|
+
...props
|
|
6242
|
+
}
|
|
6243
|
+
));
|
|
6244
|
+
CommandItem.displayName = CommandPrimitive.Item.displayName;
|
|
6245
|
+
var CommandShortcut = ({
|
|
6246
|
+
className,
|
|
6247
|
+
...props
|
|
6248
|
+
}) => {
|
|
6249
|
+
return /* @__PURE__ */ jsx48(
|
|
6250
|
+
"span",
|
|
6251
|
+
{
|
|
6252
|
+
className: cn(
|
|
6253
|
+
"ml-auto text-xs tracking-widest text-neutral-500 dark:text-neutral-400",
|
|
6254
|
+
className
|
|
6255
|
+
),
|
|
6256
|
+
...props
|
|
6257
|
+
}
|
|
6258
|
+
);
|
|
6259
|
+
};
|
|
6260
|
+
CommandShortcut.displayName = "CommandShortcut";
|
|
6052
6261
|
|
|
6053
6262
|
// src/components/databrowser/components/tab.tsx
|
|
6054
|
-
import {
|
|
6263
|
+
import {
|
|
6264
|
+
IconArrowsMinimize,
|
|
6265
|
+
IconCopyPlus,
|
|
6266
|
+
IconPin,
|
|
6267
|
+
IconSearch,
|
|
6268
|
+
IconSquareX,
|
|
6269
|
+
IconX as IconX2
|
|
6270
|
+
} from "@tabler/icons-react";
|
|
6055
6271
|
|
|
6056
6272
|
// src/components/databrowser/components/tab-type-icon.tsx
|
|
6057
|
-
import { jsx as
|
|
6273
|
+
import { jsx as jsx49 } from "react/jsx-runtime";
|
|
6058
6274
|
function TabTypeIcon({ selectedKey }) {
|
|
6059
6275
|
const { data: keyType, isLoading } = useFetchKeyType(selectedKey);
|
|
6060
|
-
if (isLoading) return /* @__PURE__ */
|
|
6276
|
+
if (isLoading) return /* @__PURE__ */ jsx49(Skeleton, { className: "h-5 w-5 rounded" });
|
|
6061
6277
|
if (!keyType || keyType === "none") return;
|
|
6062
|
-
return /* @__PURE__ */
|
|
6278
|
+
return /* @__PURE__ */ jsx49(TypeTag, { variant: keyType, type: "icon" });
|
|
6063
6279
|
}
|
|
6064
6280
|
|
|
6065
6281
|
// src/hooks/use-overflow.ts
|
|
@@ -6089,25 +6305,46 @@ var useOverflow = () => {
|
|
|
6089
6305
|
};
|
|
6090
6306
|
|
|
6091
6307
|
// src/components/databrowser/components/tab.tsx
|
|
6092
|
-
import { jsx as
|
|
6093
|
-
var Tab = ({ id }) => {
|
|
6094
|
-
const { active, search, selectedKey } = useTab();
|
|
6095
|
-
const {
|
|
6308
|
+
import { jsx as jsx50, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
6309
|
+
var Tab = ({ id, isList }) => {
|
|
6310
|
+
const { active, search, selectedKey, pinned } = useTab();
|
|
6311
|
+
const {
|
|
6312
|
+
selectTab,
|
|
6313
|
+
removeTab,
|
|
6314
|
+
forceRemoveTab,
|
|
6315
|
+
tabs,
|
|
6316
|
+
togglePinTab,
|
|
6317
|
+
duplicateTab,
|
|
6318
|
+
closeOtherTabs,
|
|
6319
|
+
closeAllButPinned
|
|
6320
|
+
} = useDatabrowserStore();
|
|
6321
|
+
const hasPinnedTabs = tabs.some(([, data]) => data.pinned);
|
|
6096
6322
|
const { ref, isOverflow } = useOverflow();
|
|
6097
6323
|
const label = search.key || selectedKey;
|
|
6098
|
-
const iconNode = search.key ? /* @__PURE__ */
|
|
6099
|
-
const tabNode = /* @__PURE__ */
|
|
6324
|
+
const iconNode = search.key ? /* @__PURE__ */ jsx50(IconSearch, { size: 15 }) : selectedKey ? /* @__PURE__ */ jsx50(TabTypeIcon, { selectedKey }) : void 0;
|
|
6325
|
+
const tabNode = /* @__PURE__ */ jsxs34(
|
|
6100
6326
|
"div",
|
|
6101
6327
|
{
|
|
6328
|
+
id: isList ? `list-tab-${id}` : `tab-${id}`,
|
|
6102
6329
|
onClick: () => selectTab(id),
|
|
6103
6330
|
className: cn(
|
|
6104
|
-
"flex h-9 cursor-pointer items-center gap-2
|
|
6105
|
-
|
|
6331
|
+
"flex h-9 w-full cursor-pointer items-center gap-2 px-3 text-[13px] transition-colors",
|
|
6332
|
+
isList && "max-w-[370px]",
|
|
6333
|
+
!isList && "rounded-t-lg border border-zinc-200",
|
|
6334
|
+
!isList && (active ? "border-b-white bg-white text-zinc-900" : "bg-zinc-100 hover:bg-zinc-50")
|
|
6106
6335
|
),
|
|
6107
6336
|
children: [
|
|
6108
6337
|
iconNode,
|
|
6109
|
-
/* @__PURE__ */
|
|
6110
|
-
|
|
6338
|
+
/* @__PURE__ */ jsx50(
|
|
6339
|
+
"span",
|
|
6340
|
+
{
|
|
6341
|
+
ref,
|
|
6342
|
+
className: cn("min-w-0 grow truncate whitespace-nowrap", !isList && "max-w-32"),
|
|
6343
|
+
children: label || "New Tab"
|
|
6344
|
+
}
|
|
6345
|
+
),
|
|
6346
|
+
pinned && /* @__PURE__ */ jsx50(IconPin, { size: 14, className: "text-zinc-500" }),
|
|
6347
|
+
tabs.length > 1 && !pinned && /* @__PURE__ */ jsx50(
|
|
6111
6348
|
"button",
|
|
6112
6349
|
{
|
|
6113
6350
|
onClick: (e) => {
|
|
@@ -6115,22 +6352,67 @@ var Tab = ({ id }) => {
|
|
|
6115
6352
|
removeTab(id);
|
|
6116
6353
|
},
|
|
6117
6354
|
className: "p-1 text-zinc-300 transition-colors hover:text-zinc-500",
|
|
6118
|
-
children: /* @__PURE__ */
|
|
6355
|
+
children: /* @__PURE__ */ jsx50(IconX2, { size: 16 })
|
|
6119
6356
|
}
|
|
6120
6357
|
)
|
|
6121
6358
|
]
|
|
6122
6359
|
}
|
|
6123
6360
|
);
|
|
6124
|
-
return /* @__PURE__ */
|
|
6361
|
+
return /* @__PURE__ */ jsxs34(ContextMenu, { children: [
|
|
6362
|
+
/* @__PURE__ */ jsx50(SimpleTooltip, { content: isOverflow ? label : void 0, children: /* @__PURE__ */ jsx50(ContextMenuTrigger, { asChild: true, children: tabNode }) }),
|
|
6363
|
+
/* @__PURE__ */ jsxs34(
|
|
6364
|
+
ContextMenuContent,
|
|
6365
|
+
{
|
|
6366
|
+
onClick: (e) => {
|
|
6367
|
+
e.stopPropagation();
|
|
6368
|
+
},
|
|
6369
|
+
children: [
|
|
6370
|
+
/* @__PURE__ */ jsxs34(ContextMenuItem, { onSelect: () => togglePinTab(id), className: "gap-2", children: [
|
|
6371
|
+
/* @__PURE__ */ jsx50(IconPin, { size: 16 }),
|
|
6372
|
+
pinned ? "Unpin Tab" : "Pin Tab"
|
|
6373
|
+
] }),
|
|
6374
|
+
/* @__PURE__ */ jsxs34(ContextMenuItem, { onSelect: () => duplicateTab(id), className: "gap-2", children: [
|
|
6375
|
+
/* @__PURE__ */ jsx50(IconCopyPlus, { size: 16 }),
|
|
6376
|
+
"Duplicate Tab"
|
|
6377
|
+
] }),
|
|
6378
|
+
/* @__PURE__ */ jsx50(ContextMenuSeparator, {}),
|
|
6379
|
+
/* @__PURE__ */ jsxs34(ContextMenuItem, { onSelect: () => forceRemoveTab(id), className: "gap-2", children: [
|
|
6380
|
+
/* @__PURE__ */ jsx50(IconX2, { size: 16 }),
|
|
6381
|
+
"Close Tab"
|
|
6382
|
+
] }),
|
|
6383
|
+
/* @__PURE__ */ jsxs34(ContextMenuItem, { onSelect: () => closeOtherTabs(id), className: "gap-2", children: [
|
|
6384
|
+
/* @__PURE__ */ jsx50(IconSquareX, { size: 16 }),
|
|
6385
|
+
"Close Other Tabs"
|
|
6386
|
+
] }),
|
|
6387
|
+
/* @__PURE__ */ jsxs34(
|
|
6388
|
+
ContextMenuItem,
|
|
6389
|
+
{
|
|
6390
|
+
onSelect: () => closeAllButPinned(),
|
|
6391
|
+
className: "gap-2",
|
|
6392
|
+
disabled: !hasPinnedTabs,
|
|
6393
|
+
children: [
|
|
6394
|
+
/* @__PURE__ */ jsx50(IconArrowsMinimize, { size: 16 }),
|
|
6395
|
+
"Close All But Pinned"
|
|
6396
|
+
]
|
|
6397
|
+
}
|
|
6398
|
+
)
|
|
6399
|
+
]
|
|
6400
|
+
}
|
|
6401
|
+
)
|
|
6402
|
+
] });
|
|
6125
6403
|
};
|
|
6126
6404
|
|
|
6127
6405
|
// src/components/databrowser/components/databrowser-tabs.tsx
|
|
6128
|
-
import { jsx as
|
|
6406
|
+
import { jsx as jsx51, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
6129
6407
|
var SortableTab = ({ id }) => {
|
|
6130
6408
|
const [originalWidth, setOriginalWidth] = useState13(null);
|
|
6131
6409
|
const textRef = useRef5(null);
|
|
6410
|
+
const { tabs } = useDatabrowserStore();
|
|
6411
|
+
const tabData = tabs.find(([tabId]) => tabId === id)?.[1];
|
|
6412
|
+
const isPinned = tabData?.pinned;
|
|
6132
6413
|
const { attributes, listeners: listeners2, setNodeRef, transform, transition, isDragging } = useSortable({
|
|
6133
6414
|
id,
|
|
6415
|
+
disabled: isPinned,
|
|
6134
6416
|
resizeObserverConfig: {
|
|
6135
6417
|
disabled: true
|
|
6136
6418
|
}
|
|
@@ -6189,20 +6471,74 @@ var SortableTab = ({ id }) => {
|
|
|
6189
6471
|
minWidth: originalWidth ? `${originalWidth}px` : void 0
|
|
6190
6472
|
} : {}
|
|
6191
6473
|
};
|
|
6192
|
-
return /* @__PURE__ */
|
|
6474
|
+
return /* @__PURE__ */ jsx51(
|
|
6193
6475
|
"div",
|
|
6194
6476
|
{
|
|
6195
6477
|
ref: measureRef,
|
|
6196
6478
|
style,
|
|
6197
|
-
className: isDragging ? "cursor-grabbing" : "cursor-grab",
|
|
6479
|
+
className: isDragging ? "cursor-grabbing" : isPinned ? "cursor-default" : "cursor-grab",
|
|
6198
6480
|
...attributes,
|
|
6199
|
-
...listeners2,
|
|
6200
|
-
children: /* @__PURE__ */
|
|
6481
|
+
...isPinned ? {} : listeners2,
|
|
6482
|
+
children: /* @__PURE__ */ jsx51(TabIdProvider, { value: id, children: /* @__PURE__ */ jsx51(Tab, { id }) })
|
|
6201
6483
|
}
|
|
6202
6484
|
);
|
|
6203
6485
|
};
|
|
6204
6486
|
var DatabrowserTabs = () => {
|
|
6205
|
-
const { tabs,
|
|
6487
|
+
const { tabs, reorderTabs, selectedTab, selectTab } = useDatabrowserStore();
|
|
6488
|
+
const sortedTabs = useMemo8(() => {
|
|
6489
|
+
return [...tabs].sort(([, a], [, b]) => {
|
|
6490
|
+
if (a.pinned && !b.pinned) return -1;
|
|
6491
|
+
if (!a.pinned && b.pinned) return 1;
|
|
6492
|
+
return 0;
|
|
6493
|
+
});
|
|
6494
|
+
}, [tabs]);
|
|
6495
|
+
const scrollRef = useRef5(null);
|
|
6496
|
+
const [hasLeftShadow, setHasLeftShadow] = useState13(false);
|
|
6497
|
+
const [hasRightShadow, setHasRightShadow] = useState13(false);
|
|
6498
|
+
const [isOverflow, setIsOverflow] = useState13(false);
|
|
6499
|
+
useEffect13(() => {
|
|
6500
|
+
const el = scrollRef.current;
|
|
6501
|
+
if (!el) return;
|
|
6502
|
+
const onWheel = (event) => {
|
|
6503
|
+
if (el.scrollWidth <= el.clientWidth) return;
|
|
6504
|
+
const primaryDelta = Math.abs(event.deltaY) > Math.abs(event.deltaX) ? event.deltaY : event.deltaX;
|
|
6505
|
+
if (primaryDelta !== 0) {
|
|
6506
|
+
el.scrollLeft += primaryDelta;
|
|
6507
|
+
event.preventDefault();
|
|
6508
|
+
requestAnimationFrame(() => {
|
|
6509
|
+
const { scrollLeft, scrollWidth, clientWidth } = el;
|
|
6510
|
+
setHasLeftShadow(scrollLeft > 0);
|
|
6511
|
+
setHasRightShadow(scrollLeft + clientWidth < scrollWidth - 1);
|
|
6512
|
+
setIsOverflow(scrollWidth > clientWidth + 1);
|
|
6513
|
+
});
|
|
6514
|
+
}
|
|
6515
|
+
};
|
|
6516
|
+
el.addEventListener("wheel", onWheel, { passive: false });
|
|
6517
|
+
return () => {
|
|
6518
|
+
el.removeEventListener("wheel", onWheel);
|
|
6519
|
+
};
|
|
6520
|
+
}, []);
|
|
6521
|
+
const recomputeShadows = useCallback3(() => {
|
|
6522
|
+
const el = scrollRef.current;
|
|
6523
|
+
if (!el) return;
|
|
6524
|
+
const { scrollLeft, scrollWidth, clientWidth } = el;
|
|
6525
|
+
setHasLeftShadow(scrollLeft > 0);
|
|
6526
|
+
setHasRightShadow(scrollLeft + clientWidth < scrollWidth - 1);
|
|
6527
|
+
setIsOverflow(scrollWidth > clientWidth + 1);
|
|
6528
|
+
}, []);
|
|
6529
|
+
useEffect13(() => {
|
|
6530
|
+
recomputeShadows();
|
|
6531
|
+
const el = scrollRef.current;
|
|
6532
|
+
if (!el) return;
|
|
6533
|
+
const onResize = () => recomputeShadows();
|
|
6534
|
+
window.addEventListener("resize", onResize);
|
|
6535
|
+
const obs = new ResizeObserver(onResize);
|
|
6536
|
+
obs.observe(el);
|
|
6537
|
+
return () => {
|
|
6538
|
+
window.removeEventListener("resize", onResize);
|
|
6539
|
+
obs.disconnect();
|
|
6540
|
+
};
|
|
6541
|
+
}, [recomputeShadows]);
|
|
6206
6542
|
const sensors = useSensors(
|
|
6207
6543
|
useSensor(PointerSensor, {
|
|
6208
6544
|
activationConstraint: {
|
|
@@ -6218,59 +6554,165 @@ var DatabrowserTabs = () => {
|
|
|
6218
6554
|
reorderTabs(oldIndex, newIndex);
|
|
6219
6555
|
}
|
|
6220
6556
|
};
|
|
6221
|
-
return /* @__PURE__ */
|
|
6222
|
-
/* @__PURE__ */
|
|
6223
|
-
/* @__PURE__ */
|
|
6224
|
-
/* @__PURE__ */
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
}
|
|
6235
|
-
}
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6557
|
+
return /* @__PURE__ */ jsxs35("div", { className: "relative mb-2 shrink-0", children: [
|
|
6558
|
+
/* @__PURE__ */ jsx51("div", { className: "absolute bottom-0 left-0 right-0 -z-10 h-[1px] w-full bg-zinc-200" }),
|
|
6559
|
+
/* @__PURE__ */ jsxs35("div", { className: "flex translate-y-[1px] items-center gap-1", children: [
|
|
6560
|
+
/* @__PURE__ */ jsxs35("div", { className: "relative min-w-0 flex-1", children: [
|
|
6561
|
+
/* @__PURE__ */ jsx51(
|
|
6562
|
+
"div",
|
|
6563
|
+
{
|
|
6564
|
+
className: `tabs-shadow-left pointer-events-none absolute left-0 top-0 z-10 h-full w-6 transition-opacity duration-200 ${hasLeftShadow ? "opacity-100" : "opacity-0"}`
|
|
6565
|
+
}
|
|
6566
|
+
),
|
|
6567
|
+
/* @__PURE__ */ jsx51(
|
|
6568
|
+
"div",
|
|
6569
|
+
{
|
|
6570
|
+
className: `tabs-shadow-right pointer-events-none absolute right-0 top-0 z-10 h-full w-6 transition-opacity duration-200 ${hasRightShadow ? "opacity-100" : "opacity-0"}`
|
|
6571
|
+
}
|
|
6572
|
+
),
|
|
6573
|
+
/* @__PURE__ */ jsxs35(
|
|
6574
|
+
"div",
|
|
6575
|
+
{
|
|
6576
|
+
ref: scrollRef,
|
|
6577
|
+
onScroll: recomputeShadows,
|
|
6578
|
+
className: "scrollbar-hide flex min-w-0 flex-1 items-center gap-1 overflow-x-auto pb-[1px] [&::-webkit-scrollbar]:hidden",
|
|
6579
|
+
children: [
|
|
6580
|
+
/* @__PURE__ */ jsx51(
|
|
6581
|
+
DndContext,
|
|
6582
|
+
{
|
|
6583
|
+
sensors,
|
|
6584
|
+
collisionDetection: closestCenter,
|
|
6585
|
+
onDragEnd: handleDragEnd,
|
|
6586
|
+
modifiers: [restrictToHorizontalAxis],
|
|
6587
|
+
measuring: {
|
|
6588
|
+
droppable: {
|
|
6589
|
+
strategy: MeasuringStrategy.Always
|
|
6590
|
+
}
|
|
6591
|
+
},
|
|
6592
|
+
children: /* @__PURE__ */ jsx51(
|
|
6593
|
+
SortableContext,
|
|
6594
|
+
{
|
|
6595
|
+
items: sortedTabs.map(([id]) => id),
|
|
6596
|
+
strategy: horizontalListSortingStrategy,
|
|
6597
|
+
children: selectedTab && sortedTabs.map(([id]) => /* @__PURE__ */ jsx51(SortableTab, { id }, id))
|
|
6598
|
+
}
|
|
6599
|
+
)
|
|
6600
|
+
}
|
|
6601
|
+
),
|
|
6602
|
+
!isOverflow && /* @__PURE__ */ jsx51("div", { className: "flex items-center gap-1 pl-1 pr-1", children: /* @__PURE__ */ jsx51(AddTabButton, {}) })
|
|
6603
|
+
]
|
|
6604
|
+
}
|
|
6605
|
+
)
|
|
6606
|
+
] }),
|
|
6607
|
+
/* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-1 pl-1", children: [
|
|
6608
|
+
isOverflow && /* @__PURE__ */ jsx51(AddTabButton, {}),
|
|
6609
|
+
tabs.length > 1 && /* @__PURE__ */ jsx51(TabsListButton, { tabs, onSelectTab: selectTab })
|
|
6610
|
+
] })
|
|
6250
6611
|
] })
|
|
6251
6612
|
] });
|
|
6252
6613
|
};
|
|
6614
|
+
function AddTabButton() {
|
|
6615
|
+
const { addTab, selectTab } = useDatabrowserStore();
|
|
6616
|
+
const rootRef = useDatabrowserRootRef();
|
|
6617
|
+
const handleAddTab = () => {
|
|
6618
|
+
const tabsId = addTab();
|
|
6619
|
+
selectTab(tabsId);
|
|
6620
|
+
setTimeout(() => {
|
|
6621
|
+
const tab = rootRef?.current?.querySelector(`#tab-${tabsId}`);
|
|
6622
|
+
if (!tab) return;
|
|
6623
|
+
tab.scrollIntoView({ behavior: "smooth" });
|
|
6624
|
+
}, 20);
|
|
6625
|
+
};
|
|
6626
|
+
return /* @__PURE__ */ jsx51(
|
|
6627
|
+
Button,
|
|
6628
|
+
{
|
|
6629
|
+
"aria-label": "Add new tab",
|
|
6630
|
+
variant: "secondary",
|
|
6631
|
+
size: "icon-sm",
|
|
6632
|
+
onClick: handleAddTab,
|
|
6633
|
+
className: "flex-shrink-0",
|
|
6634
|
+
children: /* @__PURE__ */ jsx51(IconPlus2, { className: "text-zinc-500", size: 16 })
|
|
6635
|
+
}
|
|
6636
|
+
);
|
|
6637
|
+
}
|
|
6638
|
+
function TabsListButton({
|
|
6639
|
+
tabs,
|
|
6640
|
+
onSelectTab
|
|
6641
|
+
}) {
|
|
6642
|
+
const [open, setOpen] = useState13(false);
|
|
6643
|
+
const sorted = useMemo8(() => {
|
|
6644
|
+
return [...tabs].sort(([, a], [, b]) => {
|
|
6645
|
+
if (a.pinned && !b.pinned) return -1;
|
|
6646
|
+
if (!a.pinned && b.pinned) return 1;
|
|
6647
|
+
return 0;
|
|
6648
|
+
});
|
|
6649
|
+
}, [tabs]);
|
|
6650
|
+
const rootRef = useDatabrowserRootRef();
|
|
6651
|
+
const handleSelectTab = (id) => {
|
|
6652
|
+
onSelectTab(id);
|
|
6653
|
+
setOpen(false);
|
|
6654
|
+
setTimeout(() => {
|
|
6655
|
+
const tab = rootRef?.current?.querySelector(`#tab-${id}`);
|
|
6656
|
+
if (!tab) return;
|
|
6657
|
+
tab.scrollIntoView({ behavior: "smooth" });
|
|
6658
|
+
}, 20);
|
|
6659
|
+
};
|
|
6660
|
+
return /* @__PURE__ */ jsxs35(Popover, { open, onOpenChange: setOpen, children: [
|
|
6661
|
+
/* @__PURE__ */ jsx51(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs35(
|
|
6662
|
+
Button,
|
|
6663
|
+
{
|
|
6664
|
+
variant: "secondary",
|
|
6665
|
+
size: "sm",
|
|
6666
|
+
className: "h-7 gap-1 px-2",
|
|
6667
|
+
"aria-label": "Search in tabs",
|
|
6668
|
+
children: [
|
|
6669
|
+
/* @__PURE__ */ jsx51("span", { className: "text-xs text-zinc-600", children: tabs.length }),
|
|
6670
|
+
/* @__PURE__ */ jsx51(IconChevronDown2, { className: "text-zinc-500", size: 16 })
|
|
6671
|
+
]
|
|
6672
|
+
}
|
|
6673
|
+
) }),
|
|
6674
|
+
/* @__PURE__ */ jsx51(PopoverContent, { className: "w-96 p-0", align: "end", children: /* @__PURE__ */ jsx51(Command, { children: /* @__PURE__ */ jsxs35(CommandList, { children: [
|
|
6675
|
+
/* @__PURE__ */ jsx51(CommandEmpty, { children: "No tabs" }),
|
|
6676
|
+
/* @__PURE__ */ jsx51(CommandGroup, { children: sorted.map(([_id, item]) => /* @__PURE__ */ jsx51(
|
|
6677
|
+
CommandItem,
|
|
6678
|
+
{
|
|
6679
|
+
style: {
|
|
6680
|
+
padding: 0
|
|
6681
|
+
},
|
|
6682
|
+
value: item.id,
|
|
6683
|
+
onSelect: () => {
|
|
6684
|
+
handleSelectTab(item.id);
|
|
6685
|
+
},
|
|
6686
|
+
children: /* @__PURE__ */ jsx51(TabIdProvider, { value: _id, children: /* @__PURE__ */ jsx51(Tab, { id: _id, isList: true }) })
|
|
6687
|
+
},
|
|
6688
|
+
item.id
|
|
6689
|
+
)) })
|
|
6690
|
+
] }) }) })
|
|
6691
|
+
] });
|
|
6692
|
+
}
|
|
6253
6693
|
|
|
6254
6694
|
// src/components/databrowser/index.tsx
|
|
6255
|
-
import { jsx as
|
|
6695
|
+
import { jsx as jsx52, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
6256
6696
|
var RedisBrowser = ({
|
|
6257
6697
|
token,
|
|
6258
6698
|
url,
|
|
6259
6699
|
hideTabs,
|
|
6260
6700
|
storage
|
|
6261
6701
|
}) => {
|
|
6262
|
-
const credentials =
|
|
6702
|
+
const credentials = useMemo9(() => ({ token, url }), [token, url]);
|
|
6703
|
+
const rootRef = useRef6(null);
|
|
6263
6704
|
useEffect14(() => {
|
|
6264
6705
|
queryClient.resetQueries();
|
|
6265
6706
|
}, [credentials.url]);
|
|
6266
|
-
return /* @__PURE__ */
|
|
6707
|
+
return /* @__PURE__ */ jsx52(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx52(RedisProvider, { redisCredentials: credentials, children: /* @__PURE__ */ jsx52(DatabrowserProvider, { storage, rootRef, children: /* @__PURE__ */ jsx52(TooltipProvider, { children: /* @__PURE__ */ jsxs36(
|
|
6267
6708
|
"div",
|
|
6268
6709
|
{
|
|
6269
6710
|
className: "ups-db",
|
|
6270
6711
|
style: { height: "100%", display: "flex", flexDirection: "column" },
|
|
6712
|
+
ref: rootRef,
|
|
6271
6713
|
children: [
|
|
6272
|
-
!hideTabs && /* @__PURE__ */
|
|
6273
|
-
/* @__PURE__ */
|
|
6714
|
+
!hideTabs && /* @__PURE__ */ jsx52(DatabrowserTabs, {}),
|
|
6715
|
+
/* @__PURE__ */ jsx52(DatabrowserInstances, {})
|
|
6274
6716
|
]
|
|
6275
6717
|
}
|
|
6276
6718
|
) }) }) }) });
|
|
@@ -6282,7 +6724,7 @@ var DatabrowserInstances = () => {
|
|
|
6282
6724
|
else if (!selectedTab) selectTab(tabs[0][0]);
|
|
6283
6725
|
}, [tabs, selectedTab, addTab, selectTab]);
|
|
6284
6726
|
if (!selectedTab) return;
|
|
6285
|
-
return tabs.map(([id]) => /* @__PURE__ */
|
|
6727
|
+
return tabs.map(([id]) => /* @__PURE__ */ jsx52(TabIdProvider, { value: id, children: /* @__PURE__ */ jsx52(DatabrowserInstance, { hidden: id !== selectedTab }) }, id));
|
|
6286
6728
|
};
|
|
6287
6729
|
export {
|
|
6288
6730
|
RedisBrowser
|