@upstash/react-redis-browser 0.1.6 → 0.1.8
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 +19 -4
- package/dist/index.js +1073 -899
- package/dist/index.mjs +1284 -1110
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2808,7 +2808,7 @@ function formatTime(seconds) {
|
|
|
2808
2808
|
if (parts.length === 0) {
|
|
2809
2809
|
parts.push("0s");
|
|
2810
2810
|
}
|
|
2811
|
-
return parts.slice(0,
|
|
2811
|
+
return parts.slice(0, 1).join(" ");
|
|
2812
2812
|
}
|
|
2813
2813
|
|
|
2814
2814
|
// src/components/ui/toast.tsx
|
|
@@ -2923,6 +2923,20 @@ import {
|
|
|
2923
2923
|
} from "react";
|
|
2924
2924
|
import { useInfiniteQuery } from "@tanstack/react-query";
|
|
2925
2925
|
|
|
2926
|
+
// src/components/databrowser/hooks/use-fetch-key-type.tsx
|
|
2927
|
+
import { useQuery } from "@tanstack/react-query";
|
|
2928
|
+
var FETCH_KEY_TYPE_QUERY_KEY = "fetch-key-type";
|
|
2929
|
+
var useFetchKeyType = (key) => {
|
|
2930
|
+
const { redisNoPipeline: redis } = useDatabrowser();
|
|
2931
|
+
return useQuery({
|
|
2932
|
+
queryKey: [FETCH_KEY_TYPE_QUERY_KEY, key],
|
|
2933
|
+
queryFn: async () => {
|
|
2934
|
+
if (!key) return "none";
|
|
2935
|
+
return await redis.type(key);
|
|
2936
|
+
}
|
|
2937
|
+
});
|
|
2938
|
+
};
|
|
2939
|
+
|
|
2926
2940
|
// src/components/databrowser/hooks/use-fetch-keys.ts
|
|
2927
2941
|
import { useCallback, useRef } from "react";
|
|
2928
2942
|
|
|
@@ -3050,6 +3064,8 @@ var KeysContext = createContext2(void 0);
|
|
|
3050
3064
|
var FETCH_KEYS_QUERY_KEY = "use-fetch-keys";
|
|
3051
3065
|
var KeysProvider = ({ children }) => {
|
|
3052
3066
|
const { search } = useDatabrowserStore();
|
|
3067
|
+
const cleanSearchKey = search.key.replace("*", "");
|
|
3068
|
+
const { data: exactMatchType, isFetching, isLoading } = useFetchKeyType(cleanSearchKey);
|
|
3053
3069
|
const { fetchKeys, resetCache } = useFetchKeys(search);
|
|
3054
3070
|
const pageRef = useRef2(0);
|
|
3055
3071
|
const query = useInfiniteQuery({
|
|
@@ -3064,6 +3080,7 @@ var KeysProvider = ({ children }) => {
|
|
|
3064
3080
|
getNextPageParam: (lastPage, __, lastPageIndex) => {
|
|
3065
3081
|
return lastPage.hasNextPage ? lastPageIndex + 1 : void 0;
|
|
3066
3082
|
},
|
|
3083
|
+
enabled: !isFetching,
|
|
3067
3084
|
refetchOnMount: false
|
|
3068
3085
|
});
|
|
3069
3086
|
const refetch = useCallback2(() => {
|
|
@@ -3072,6 +3089,9 @@ var KeysProvider = ({ children }) => {
|
|
|
3072
3089
|
}, [query, resetCache]);
|
|
3073
3090
|
const keys = useMemo2(() => {
|
|
3074
3091
|
const keys2 = query.data?.pages.flatMap((page) => page.keys) ?? [];
|
|
3092
|
+
if (exactMatchType && exactMatchType !== "none" && (search.type === void 0 || search.type === exactMatchType)) {
|
|
3093
|
+
keys2.push([cleanSearchKey, exactMatchType]);
|
|
3094
|
+
}
|
|
3075
3095
|
const keysSet = /* @__PURE__ */ new Set();
|
|
3076
3096
|
const dedupedKeys = [];
|
|
3077
3097
|
for (const key of keys2) {
|
|
@@ -3080,13 +3100,18 @@ var KeysProvider = ({ children }) => {
|
|
|
3080
3100
|
dedupedKeys.push(key);
|
|
3081
3101
|
}
|
|
3082
3102
|
return dedupedKeys;
|
|
3083
|
-
}, [query.data]);
|
|
3103
|
+
}, [query.data, cleanSearchKey, exactMatchType]);
|
|
3084
3104
|
return /* @__PURE__ */ jsx4(
|
|
3085
3105
|
KeysContext.Provider,
|
|
3086
3106
|
{
|
|
3087
3107
|
value: {
|
|
3088
3108
|
keys,
|
|
3089
|
-
|
|
3109
|
+
// @ts-expect-error Ignore the error with spread syntax
|
|
3110
|
+
query: {
|
|
3111
|
+
...query,
|
|
3112
|
+
isLoading: isLoading || query.isLoading,
|
|
3113
|
+
isFetching: isFetching || query.isFetching
|
|
3114
|
+
},
|
|
3090
3115
|
refetch
|
|
3091
3116
|
},
|
|
3092
3117
|
children
|
|
@@ -3154,7 +3179,7 @@ Button.displayName = "Button";
|
|
|
3154
3179
|
import { useMutation } from "@tanstack/react-query";
|
|
3155
3180
|
|
|
3156
3181
|
// src/components/databrowser/components/sidebar/db-size.tsx
|
|
3157
|
-
import { useQuery } from "@tanstack/react-query";
|
|
3182
|
+
import { useQuery as useQuery2 } from "@tanstack/react-query";
|
|
3158
3183
|
|
|
3159
3184
|
// src/components/ui/skeleton.tsx
|
|
3160
3185
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
@@ -3173,7 +3198,7 @@ import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
|
3173
3198
|
var FETCH_DB_SIZE_QUERY_KEY = "fetch-db-size";
|
|
3174
3199
|
var DisplayDbSize = () => {
|
|
3175
3200
|
const { redis } = useDatabrowser();
|
|
3176
|
-
const { data: keyCount } =
|
|
3201
|
+
const { data: keyCount } = useQuery2({
|
|
3177
3202
|
queryKey: [FETCH_DB_SIZE_QUERY_KEY],
|
|
3178
3203
|
queryFn: async () => {
|
|
3179
3204
|
return await redis.dbsize();
|
|
@@ -3270,76 +3295,6 @@ import { useMutation as useMutation2 } from "@tanstack/react-query";
|
|
|
3270
3295
|
// src/components/databrowser/hooks/use-delete-key-cache.ts
|
|
3271
3296
|
import { useCallback as useCallback3 } from "react";
|
|
3272
3297
|
|
|
3273
|
-
// src/components/databrowser/hooks/use-fetch-simple-key.tsx
|
|
3274
|
-
import { useQuery as useQuery2 } from "@tanstack/react-query";
|
|
3275
|
-
var FETCH_SIMPLE_KEY_QUERY_KEY = "fetch-simple-key";
|
|
3276
|
-
var useFetchSimpleKey = (dataKey, type) => {
|
|
3277
|
-
const { redisNoPipeline: redis } = useDatabrowser();
|
|
3278
|
-
const { deleteKeyCache } = useDeleteKeyCache();
|
|
3279
|
-
return useQuery2({
|
|
3280
|
-
queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY, dataKey],
|
|
3281
|
-
queryFn: async () => {
|
|
3282
|
-
let result;
|
|
3283
|
-
if (type === "string") result = await redis.get(dataKey);
|
|
3284
|
-
else if (type === "json") result = await redis.json.get(dataKey);
|
|
3285
|
-
else throw new Error(`Invalid type when fetching simple key: ${type}`);
|
|
3286
|
-
if (type === "json" && result !== null)
|
|
3287
|
-
result = JSON.stringify(sortObject(JSON.parse(result)));
|
|
3288
|
-
if (result === null) deleteKeyCache(dataKey);
|
|
3289
|
-
return result;
|
|
3290
|
-
}
|
|
3291
|
-
});
|
|
3292
|
-
};
|
|
3293
|
-
var sortObject = (obj) => {
|
|
3294
|
-
if (typeof obj !== "object" || obj === null) return obj;
|
|
3295
|
-
return Object.fromEntries(
|
|
3296
|
-
Object.entries(obj).sort((a, b) => a[0].localeCompare(b[0])).map(
|
|
3297
|
-
([key, value]) => typeof value === "object" && !Array.isArray(value) && value !== null ? [key, sortObject(value)] : [key, value]
|
|
3298
|
-
)
|
|
3299
|
-
);
|
|
3300
|
-
};
|
|
3301
|
-
|
|
3302
|
-
// src/components/databrowser/hooks/use-delete-key-cache.ts
|
|
3303
|
-
var useDeleteKeyCache = () => {
|
|
3304
|
-
const { setSelectedKey } = useDatabrowserStore();
|
|
3305
|
-
const { refetch } = useKeys();
|
|
3306
|
-
const deleteKeyCache = useCallback3(
|
|
3307
|
-
(key) => {
|
|
3308
|
-
setSelectedKey(void 0);
|
|
3309
|
-
queryClient.invalidateQueries({
|
|
3310
|
-
queryKey: [FETCH_KEYS_QUERY_KEY]
|
|
3311
|
-
});
|
|
3312
|
-
queryClient.invalidateQueries({
|
|
3313
|
-
queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY, key]
|
|
3314
|
-
});
|
|
3315
|
-
refetch();
|
|
3316
|
-
},
|
|
3317
|
-
[setSelectedKey, refetch]
|
|
3318
|
-
);
|
|
3319
|
-
return { deleteKeyCache };
|
|
3320
|
-
};
|
|
3321
|
-
|
|
3322
|
-
// src/components/databrowser/hooks/use-delete-key.ts
|
|
3323
|
-
var useDeleteKey = () => {
|
|
3324
|
-
const { redis } = useDatabrowser();
|
|
3325
|
-
const { deleteKeyCache } = useDeleteKeyCache();
|
|
3326
|
-
const deleteKey = useMutation2({
|
|
3327
|
-
mutationFn: async (key) => {
|
|
3328
|
-
return Boolean(await redis.del(key));
|
|
3329
|
-
},
|
|
3330
|
-
onSuccess: (_, key) => {
|
|
3331
|
-
deleteKeyCache(key);
|
|
3332
|
-
queryClient.invalidateQueries({
|
|
3333
|
-
queryKey: [FETCH_DB_SIZE_QUERY_KEY]
|
|
3334
|
-
});
|
|
3335
|
-
}
|
|
3336
|
-
});
|
|
3337
|
-
return deleteKey;
|
|
3338
|
-
};
|
|
3339
|
-
|
|
3340
|
-
// src/components/databrowser/hooks/use-edit-list-item.tsx
|
|
3341
|
-
import { useMutation as useMutation3 } from "@tanstack/react-query";
|
|
3342
|
-
|
|
3343
3298
|
// src/components/databrowser/hooks/use-fetch-list-items.tsx
|
|
3344
3299
|
import { useInfiniteQuery as useInfiniteQuery2 } from "@tanstack/react-query";
|
|
3345
3300
|
var LIST_DISPLAY_PAGE_SIZE = 50;
|
|
@@ -3365,13 +3320,15 @@ var useFetchListItems = ({ dataKey, type }) => {
|
|
|
3365
3320
|
enabled: type === "zset",
|
|
3366
3321
|
queryKey: [FETCH_LIST_ITEMS_QUERY_KEY, dataKey, "zset"],
|
|
3367
3322
|
initialPageParam: 0,
|
|
3368
|
-
queryFn: async ({ pageParam:
|
|
3369
|
-
const
|
|
3323
|
+
queryFn: async ({ pageParam: page }) => {
|
|
3324
|
+
const start = page * LIST_DISPLAY_PAGE_SIZE;
|
|
3325
|
+
const end = start + LIST_DISPLAY_PAGE_SIZE - 1;
|
|
3326
|
+
const res = await redis.zrange(dataKey, start, end, {
|
|
3370
3327
|
withScores: true,
|
|
3371
3328
|
rev: true
|
|
3372
3329
|
});
|
|
3373
3330
|
return {
|
|
3374
|
-
cursor: res.length < LIST_DISPLAY_PAGE_SIZE ? void 0 :
|
|
3331
|
+
cursor: res.length < LIST_DISPLAY_PAGE_SIZE ? void 0 : page + 1,
|
|
3375
3332
|
keys: transformArray(res)
|
|
3376
3333
|
};
|
|
3377
3334
|
},
|
|
@@ -3396,13 +3353,14 @@ var useFetchListItems = ({ dataKey, type }) => {
|
|
|
3396
3353
|
enabled: type === "list",
|
|
3397
3354
|
queryKey: [FETCH_LIST_ITEMS_QUERY_KEY, dataKey, "list"],
|
|
3398
3355
|
initialPageParam: 0,
|
|
3399
|
-
queryFn: async ({ pageParam }) => {
|
|
3400
|
-
const
|
|
3401
|
-
const
|
|
3356
|
+
queryFn: async ({ pageParam: page }) => {
|
|
3357
|
+
const start = page * LIST_DISPLAY_PAGE_SIZE;
|
|
3358
|
+
const end = start + LIST_DISPLAY_PAGE_SIZE - 1;
|
|
3359
|
+
const values = await redis.lrange(dataKey, start, end);
|
|
3402
3360
|
return {
|
|
3403
|
-
cursor: values.length < LIST_DISPLAY_PAGE_SIZE ? void 0 :
|
|
3361
|
+
cursor: values.length < LIST_DISPLAY_PAGE_SIZE ? void 0 : page + 1,
|
|
3404
3362
|
keys: values.map((value, i) => ({
|
|
3405
|
-
key: (
|
|
3363
|
+
key: (start + i).toString(),
|
|
3406
3364
|
value
|
|
3407
3365
|
}))
|
|
3408
3366
|
};
|
|
@@ -3453,7 +3411,81 @@ function transformArray(inputArray) {
|
|
|
3453
3411
|
}, []);
|
|
3454
3412
|
}
|
|
3455
3413
|
|
|
3414
|
+
// src/components/databrowser/hooks/use-fetch-simple-key.tsx
|
|
3415
|
+
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
3416
|
+
var FETCH_SIMPLE_KEY_QUERY_KEY = "fetch-simple-key";
|
|
3417
|
+
var useFetchSimpleKey = (dataKey, type) => {
|
|
3418
|
+
const { redisNoPipeline: redis } = useDatabrowser();
|
|
3419
|
+
const { deleteKeyCache } = useDeleteKeyCache();
|
|
3420
|
+
return useQuery3({
|
|
3421
|
+
queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY, dataKey],
|
|
3422
|
+
queryFn: async () => {
|
|
3423
|
+
let result;
|
|
3424
|
+
if (type === "string") result = await redis.get(dataKey);
|
|
3425
|
+
else if (type === "json") result = await redis.json.get(dataKey);
|
|
3426
|
+
else throw new Error(`Invalid type when fetching simple key: ${type}`);
|
|
3427
|
+
if (type === "json" && result !== null)
|
|
3428
|
+
result = JSON.stringify(sortObject(JSON.parse(result)));
|
|
3429
|
+
if (result === null) deleteKeyCache(dataKey);
|
|
3430
|
+
return result;
|
|
3431
|
+
}
|
|
3432
|
+
});
|
|
3433
|
+
};
|
|
3434
|
+
var sortObject = (obj) => {
|
|
3435
|
+
if (typeof obj !== "object" || obj === null) return obj;
|
|
3436
|
+
return Object.fromEntries(
|
|
3437
|
+
Object.entries(obj).sort((a, b) => a[0].localeCompare(b[0])).map(
|
|
3438
|
+
([key, value]) => typeof value === "object" && !Array.isArray(value) && value !== null ? [key, sortObject(value)] : [key, value]
|
|
3439
|
+
)
|
|
3440
|
+
);
|
|
3441
|
+
};
|
|
3442
|
+
|
|
3443
|
+
// src/components/databrowser/hooks/use-delete-key-cache.ts
|
|
3444
|
+
var useDeleteKeyCache = () => {
|
|
3445
|
+
const { setSelectedKey } = useDatabrowserStore();
|
|
3446
|
+
const { refetch } = useKeys();
|
|
3447
|
+
const deleteKeyCache = useCallback3(
|
|
3448
|
+
(key) => {
|
|
3449
|
+
setSelectedKey(void 0);
|
|
3450
|
+
queryClient.invalidateQueries({
|
|
3451
|
+
queryKey: [FETCH_KEYS_QUERY_KEY]
|
|
3452
|
+
});
|
|
3453
|
+
queryClient.invalidateQueries({
|
|
3454
|
+
queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY, key]
|
|
3455
|
+
});
|
|
3456
|
+
queryClient.invalidateQueries({
|
|
3457
|
+
queryKey: [FETCH_LIST_ITEMS_QUERY_KEY, key]
|
|
3458
|
+
});
|
|
3459
|
+
queryClient.invalidateQueries({
|
|
3460
|
+
queryKey: [FETCH_KEY_TYPE_QUERY_KEY, key]
|
|
3461
|
+
});
|
|
3462
|
+
refetch();
|
|
3463
|
+
},
|
|
3464
|
+
[setSelectedKey, refetch]
|
|
3465
|
+
);
|
|
3466
|
+
return { deleteKeyCache };
|
|
3467
|
+
};
|
|
3468
|
+
|
|
3469
|
+
// src/components/databrowser/hooks/use-delete-key.ts
|
|
3470
|
+
var useDeleteKey = () => {
|
|
3471
|
+
const { redis } = useDatabrowser();
|
|
3472
|
+
const { deleteKeyCache } = useDeleteKeyCache();
|
|
3473
|
+
const deleteKey = useMutation2({
|
|
3474
|
+
mutationFn: async (key) => {
|
|
3475
|
+
return Boolean(await redis.del(key));
|
|
3476
|
+
},
|
|
3477
|
+
onSuccess: (_, key) => {
|
|
3478
|
+
deleteKeyCache(key);
|
|
3479
|
+
queryClient.invalidateQueries({
|
|
3480
|
+
queryKey: [FETCH_DB_SIZE_QUERY_KEY]
|
|
3481
|
+
});
|
|
3482
|
+
}
|
|
3483
|
+
});
|
|
3484
|
+
return deleteKey;
|
|
3485
|
+
};
|
|
3486
|
+
|
|
3456
3487
|
// src/components/databrowser/hooks/use-edit-list-item.tsx
|
|
3488
|
+
import { useMutation as useMutation3 } from "@tanstack/react-query";
|
|
3457
3489
|
var useEditListItem = () => {
|
|
3458
3490
|
const { redis } = useDatabrowser();
|
|
3459
3491
|
return useMutation3({
|
|
@@ -3534,914 +3566,940 @@ var useEditListItem = () => {
|
|
|
3534
3566
|
};
|
|
3535
3567
|
|
|
3536
3568
|
// src/components/databrowser/hooks/use-fetch-ttl.ts
|
|
3537
|
-
import { useEffect as
|
|
3538
|
-
import { useQuery as
|
|
3539
|
-
|
|
3540
|
-
|
|
3569
|
+
import { useEffect as useEffect5 } from "react";
|
|
3570
|
+
import { useQuery as useQuery6 } from "@tanstack/react-query";
|
|
3571
|
+
|
|
3572
|
+
// src/components/databrowser/components/display/ttl-badge.tsx
|
|
3573
|
+
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
3574
|
+
import { IconChevronDown } from "@tabler/icons-react";
|
|
3575
|
+
|
|
3576
|
+
// src/components/databrowser/components/display/header-badges.tsx
|
|
3577
|
+
import bytes from "bytes";
|
|
3578
|
+
|
|
3579
|
+
// src/components/databrowser/hooks/use-fetch-key-length.ts
|
|
3580
|
+
import { useQuery as useQuery4 } from "@tanstack/react-query";
|
|
3581
|
+
var FETCH_KEY_LENGTH_QUERY_KEY = "fetch-key-length";
|
|
3582
|
+
var useFetchKeyLength = ({ dataKey, type }) => {
|
|
3541
3583
|
const { redis } = useDatabrowser();
|
|
3542
|
-
|
|
3543
|
-
queryKey: [
|
|
3584
|
+
return useQuery4({
|
|
3585
|
+
queryKey: [FETCH_KEY_LENGTH_QUERY_KEY, dataKey],
|
|
3544
3586
|
queryFn: async () => {
|
|
3545
|
-
|
|
3587
|
+
switch (type) {
|
|
3588
|
+
case "set": {
|
|
3589
|
+
return await redis.scard(dataKey);
|
|
3590
|
+
}
|
|
3591
|
+
case "zset": {
|
|
3592
|
+
return await redis.zcard(dataKey);
|
|
3593
|
+
}
|
|
3594
|
+
case "list": {
|
|
3595
|
+
return await redis.llen(dataKey);
|
|
3596
|
+
}
|
|
3597
|
+
case "hash": {
|
|
3598
|
+
return await redis.hlen(dataKey);
|
|
3599
|
+
}
|
|
3600
|
+
case "stream": {
|
|
3601
|
+
return await redis.xlen(dataKey);
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
return null;
|
|
3546
3605
|
}
|
|
3547
3606
|
});
|
|
3548
|
-
useEffect3(() => {
|
|
3549
|
-
if (data === -2) {
|
|
3550
|
-
queryClient.invalidateQueries({
|
|
3551
|
-
queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY, dataKey]
|
|
3552
|
-
});
|
|
3553
|
-
}
|
|
3554
|
-
}, [data === -2]);
|
|
3555
|
-
return { isLoading, error, data };
|
|
3556
3607
|
};
|
|
3557
3608
|
|
|
3558
|
-
// src/components/databrowser/hooks/use-
|
|
3559
|
-
import {
|
|
3560
|
-
var
|
|
3609
|
+
// src/components/databrowser/hooks/use-fetch-key-size.ts
|
|
3610
|
+
import { useQuery as useQuery5 } from "@tanstack/react-query";
|
|
3611
|
+
var FETCH_KEY_SIZE_QUERY_KEY = "fetch-key-size";
|
|
3612
|
+
var useFetchKeySize = (dataKey) => {
|
|
3561
3613
|
const { redis } = useDatabrowser();
|
|
3562
|
-
return
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
} else if (type === "json") {
|
|
3567
|
-
await redis.json.set(dataKey, "$", JSON.parse(value));
|
|
3568
|
-
} else {
|
|
3569
|
-
throw new Error(`Invalid type when setting simple key: ${type}`);
|
|
3570
|
-
}
|
|
3571
|
-
},
|
|
3572
|
-
onSuccess: (_, value) => {
|
|
3573
|
-
queryClient.setQueryData([FETCH_SIMPLE_KEY_QUERY_KEY, dataKey], value);
|
|
3574
|
-
queryClient.invalidateQueries({
|
|
3575
|
-
queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY, dataKey]
|
|
3576
|
-
});
|
|
3614
|
+
return useQuery5({
|
|
3615
|
+
queryKey: [FETCH_KEY_SIZE_QUERY_KEY, dataKey],
|
|
3616
|
+
queryFn: async () => {
|
|
3617
|
+
return await redis.eval(`return redis.call("MEMORY", "USAGE", KEYS[1])`, [dataKey], []);
|
|
3577
3618
|
}
|
|
3578
3619
|
});
|
|
3579
3620
|
};
|
|
3580
3621
|
|
|
3581
|
-
// src/components/databrowser/
|
|
3582
|
-
import {
|
|
3583
|
-
var
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3622
|
+
// src/components/databrowser/components/display/header-badges.tsx
|
|
3623
|
+
import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3624
|
+
var LengthBadge = ({
|
|
3625
|
+
dataKey,
|
|
3626
|
+
type,
|
|
3627
|
+
content
|
|
3628
|
+
}) => {
|
|
3629
|
+
const { data, isLoading } = useFetchKeyLength({ dataKey, type });
|
|
3630
|
+
const length = content?.length ?? data;
|
|
3631
|
+
return /* @__PURE__ */ jsx8(Badge, { label: "Length:", children: isLoading ? /* @__PURE__ */ jsx8(Skeleton, { className: "ml-1 h-3 w-10 rounded-md opacity-50" }) : length });
|
|
3632
|
+
};
|
|
3633
|
+
var SizeBadge = ({ dataKey }) => {
|
|
3634
|
+
const { data: size } = useFetchKeySize(dataKey);
|
|
3635
|
+
return /* @__PURE__ */ jsx8(Badge, { label: "Size:", children: size === void 0 || size === null ? /* @__PURE__ */ jsx8(Skeleton, { className: "ml-1 h-3 w-10 rounded-md opacity-50" }) : bytes(size, {
|
|
3636
|
+
unitSeparator: " "
|
|
3637
|
+
}) });
|
|
3638
|
+
};
|
|
3639
|
+
var HeaderTTLBadge = ({ dataKey }) => {
|
|
3640
|
+
const { data: expireAt } = useFetchKeyExpire(dataKey);
|
|
3641
|
+
const { mutate: setTTL, isPending } = useSetTTL();
|
|
3642
|
+
return /* @__PURE__ */ jsx8(
|
|
3643
|
+
TTLBadge,
|
|
3644
|
+
{
|
|
3645
|
+
expireAt,
|
|
3646
|
+
setTTL: (ttl) => setTTL({ dataKey, ttl }),
|
|
3647
|
+
isPending
|
|
3596
3648
|
}
|
|
3597
|
-
|
|
3598
|
-
return updateTTL;
|
|
3649
|
+
);
|
|
3599
3650
|
};
|
|
3651
|
+
var Badge = ({ children, label }) => /* @__PURE__ */ jsxs3("div", { className: "flex h-6 items-center gap-0.5 rounded-md bg-white px-2 text-xs text-zinc-700", children: [
|
|
3652
|
+
/* @__PURE__ */ jsx8("span", { className: "text-zinc-500", children: label }),
|
|
3653
|
+
/* @__PURE__ */ jsx8("span", { className: "font-medium", children })
|
|
3654
|
+
] });
|
|
3600
3655
|
|
|
3601
|
-
// src/components/databrowser/components/
|
|
3602
|
-
import { useState as useState4 } from "react";
|
|
3603
|
-
import {
|
|
3656
|
+
// src/components/databrowser/components/display/ttl-popover.tsx
|
|
3657
|
+
import { useEffect as useEffect3, useMemo as useMemo3, useState as useState4 } from "react";
|
|
3658
|
+
import { Controller, useForm } from "react-hook-form";
|
|
3604
3659
|
|
|
3605
|
-
// src/components/ui/
|
|
3660
|
+
// src/components/ui/input.tsx
|
|
3606
3661
|
import * as React4 from "react";
|
|
3607
|
-
import
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
children: [
|
|
3623
|
-
children,
|
|
3624
|
-
/* @__PURE__ */ jsx8(ChevronRightIcon, { className: "ml-auto h-4 w-4" })
|
|
3625
|
-
]
|
|
3626
|
-
}
|
|
3627
|
-
));
|
|
3628
|
-
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
|
|
3629
|
-
var ContextMenuSubContent = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
|
|
3630
|
-
ContextMenuPrimitive.SubContent,
|
|
3631
|
-
{
|
|
3632
|
-
ref,
|
|
3633
|
-
className: cn(
|
|
3634
|
-
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-neutral-200 bg-white p-1 text-neutral-950 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50",
|
|
3635
|
-
className
|
|
3636
|
-
),
|
|
3637
|
-
...props
|
|
3662
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
3663
|
+
var Input = React4.forwardRef(
|
|
3664
|
+
({ className, type, ...props }, ref) => {
|
|
3665
|
+
return /* @__PURE__ */ jsx9(
|
|
3666
|
+
"input",
|
|
3667
|
+
{
|
|
3668
|
+
type,
|
|
3669
|
+
className: cn(
|
|
3670
|
+
"flex h-8 w-full rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-zinc-950 disabled:cursor-not-allowed disabled:opacity-50",
|
|
3671
|
+
className
|
|
3672
|
+
),
|
|
3673
|
+
ref,
|
|
3674
|
+
...props
|
|
3675
|
+
}
|
|
3676
|
+
);
|
|
3638
3677
|
}
|
|
3639
|
-
)
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3678
|
+
);
|
|
3679
|
+
Input.displayName = "Input";
|
|
3680
|
+
|
|
3681
|
+
// src/components/ui/popover.tsx
|
|
3682
|
+
import * as React5 from "react";
|
|
3683
|
+
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
3684
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
3685
|
+
var Popover = PopoverPrimitive.Root;
|
|
3686
|
+
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
3687
|
+
var PopoverContent = React5.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx10(PopoverPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ jsx10(
|
|
3688
|
+
PopoverPrimitive.Content,
|
|
3643
3689
|
{
|
|
3644
3690
|
ref,
|
|
3691
|
+
align,
|
|
3692
|
+
sideOffset,
|
|
3645
3693
|
className: cn(
|
|
3646
|
-
"
|
|
3694
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border border-zinc-200 bg-white p-4 text-zinc-950 shadow-md outline-none dark:border-zinc-800 mt-0.5 dark:bg-zinc-950 dark:text-zinc-50",
|
|
3647
3695
|
className
|
|
3648
3696
|
),
|
|
3649
3697
|
...props
|
|
3650
3698
|
}
|
|
3651
3699
|
) }));
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
}
|
|
3664
|
-
));
|
|
3665
|
-
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
|
|
3666
|
-
var ContextMenuCheckboxItem = React4.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs3(
|
|
3667
|
-
ContextMenuPrimitive.CheckboxItem,
|
|
3700
|
+
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
3701
|
+
|
|
3702
|
+
// src/components/ui/select.tsx
|
|
3703
|
+
import * as React6 from "react";
|
|
3704
|
+
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
3705
|
+
import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3706
|
+
var Select = SelectPrimitive.Root;
|
|
3707
|
+
var SelectGroup = SelectPrimitive.Group;
|
|
3708
|
+
var SelectValue = SelectPrimitive.Value;
|
|
3709
|
+
var SelectTrigger = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs4(
|
|
3710
|
+
SelectPrimitive.Trigger,
|
|
3668
3711
|
{
|
|
3669
3712
|
ref,
|
|
3670
3713
|
className: cn(
|
|
3671
|
-
"relative flex
|
|
3714
|
+
"relative flex h-8 w-full items-center justify-between rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-zinc-500 focus:ring-zinc-950 disabled:cursor-not-allowed disabled:opacity-50 dark:border-zinc-800 dark:bg-zinc-950 dark:ring-offset-zinc-950 dark:placeholder:text-zinc-400 dark:focus:ring-zinc-300",
|
|
3672
3715
|
className
|
|
3673
3716
|
),
|
|
3674
|
-
checked,
|
|
3675
3717
|
...props,
|
|
3676
3718
|
children: [
|
|
3677
|
-
|
|
3678
|
-
children
|
|
3719
|
+
children,
|
|
3720
|
+
/* @__PURE__ */ jsx11(SelectPrimitive.Icon, { asChild: true, className: "absolute right-2", children: /* @__PURE__ */ jsx11(
|
|
3721
|
+
"svg",
|
|
3722
|
+
{
|
|
3723
|
+
width: "16",
|
|
3724
|
+
height: "16",
|
|
3725
|
+
viewBox: "0 0 16 16",
|
|
3726
|
+
fill: "none",
|
|
3727
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3728
|
+
children: /* @__PURE__ */ jsx11(
|
|
3729
|
+
"path",
|
|
3730
|
+
{
|
|
3731
|
+
d: "M4 6L8 10L12 6",
|
|
3732
|
+
stroke: "black",
|
|
3733
|
+
strokeOpacity: "0.4",
|
|
3734
|
+
strokeWidth: "1.4",
|
|
3735
|
+
strokeLinecap: "round",
|
|
3736
|
+
strokeLinejoin: "round"
|
|
3737
|
+
}
|
|
3738
|
+
)
|
|
3739
|
+
}
|
|
3740
|
+
) })
|
|
3679
3741
|
]
|
|
3680
3742
|
}
|
|
3681
3743
|
));
|
|
3682
|
-
|
|
3683
|
-
var
|
|
3684
|
-
|
|
3744
|
+
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
3745
|
+
var SelectContent = React6.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx11(SelectPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ jsx11(
|
|
3746
|
+
SelectPrimitive.Content,
|
|
3685
3747
|
{
|
|
3686
3748
|
ref,
|
|
3687
3749
|
className: cn(
|
|
3688
|
-
"relative
|
|
3750
|
+
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border border-zinc-200 bg-white text-zinc-950 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-zinc-800 dark:bg-zinc-950 dark:text-neutral-50",
|
|
3751
|
+
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
3689
3752
|
className
|
|
3690
3753
|
),
|
|
3754
|
+
position,
|
|
3691
3755
|
...props,
|
|
3692
|
-
children:
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3756
|
+
children: /* @__PURE__ */ jsx11(
|
|
3757
|
+
SelectPrimitive.Viewport,
|
|
3758
|
+
{
|
|
3759
|
+
className: cn(
|
|
3760
|
+
"p-1",
|
|
3761
|
+
position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
|
3762
|
+
),
|
|
3763
|
+
children
|
|
3764
|
+
}
|
|
3765
|
+
)
|
|
3696
3766
|
}
|
|
3697
|
-
));
|
|
3698
|
-
|
|
3699
|
-
var
|
|
3700
|
-
|
|
3767
|
+
) }));
|
|
3768
|
+
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
3769
|
+
var SelectLabel = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
|
|
3770
|
+
SelectPrimitive.Label,
|
|
3701
3771
|
{
|
|
3702
3772
|
ref,
|
|
3703
|
-
className: cn(
|
|
3704
|
-
"px-2 py-1.5 text-sm font-semibold text-neutral-950 dark:text-neutral-50",
|
|
3705
|
-
inset && "pl-8",
|
|
3706
|
-
className
|
|
3707
|
-
),
|
|
3773
|
+
className: cn("px-2 py-1.5 text-sm font-semibold", className),
|
|
3708
3774
|
...props
|
|
3709
3775
|
}
|
|
3710
3776
|
));
|
|
3711
|
-
|
|
3712
|
-
var
|
|
3713
|
-
|
|
3777
|
+
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
3778
|
+
var SelectItem = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs4(
|
|
3779
|
+
SelectPrimitive.Item,
|
|
3714
3780
|
{
|
|
3715
3781
|
ref,
|
|
3716
|
-
className: cn("-mx-1 my-1 h-px bg-neutral-200 dark:bg-neutral-800", className),
|
|
3717
|
-
...props
|
|
3718
|
-
}
|
|
3719
|
-
));
|
|
3720
|
-
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
|
|
3721
|
-
var ContextMenuShortcut = ({ className, ...props }) => {
|
|
3722
|
-
return /* @__PURE__ */ jsx8(
|
|
3723
|
-
"span",
|
|
3724
|
-
{
|
|
3725
|
-
className: cn(
|
|
3726
|
-
"ml-auto text-xs tracking-widest text-neutral-500 dark:text-neutral-400",
|
|
3727
|
-
className
|
|
3728
|
-
),
|
|
3729
|
-
...props
|
|
3730
|
-
}
|
|
3731
|
-
);
|
|
3732
|
-
};
|
|
3733
|
-
ContextMenuShortcut.displayName = "ContextMenuShortcut";
|
|
3734
|
-
|
|
3735
|
-
// src/components/ui/alert-dialog.tsx
|
|
3736
|
-
import * as React5 from "react";
|
|
3737
|
-
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
3738
|
-
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3739
|
-
var AlertDialog = AlertDialogPrimitive.Root;
|
|
3740
|
-
var AlertDialogTrigger = AlertDialogPrimitive.Trigger;
|
|
3741
|
-
var AlertDialogPortal = ({ ...props }) => /* @__PURE__ */ jsx9(AlertDialogPrimitive.Portal, { container: portalRoot, ...props });
|
|
3742
|
-
AlertDialogPortal.displayName = AlertDialogPrimitive.Portal.displayName;
|
|
3743
|
-
var AlertDialogOverlay = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx9(
|
|
3744
|
-
AlertDialogPrimitive.Overlay,
|
|
3745
|
-
{
|
|
3746
3782
|
className: cn(
|
|
3747
|
-
"
|
|
3783
|
+
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-neutral-100 focus:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
|
3748
3784
|
className
|
|
3749
3785
|
),
|
|
3750
3786
|
...props,
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
{
|
|
3775
|
-
className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
|
|
3776
|
-
...props
|
|
3777
|
-
}
|
|
3778
|
-
);
|
|
3779
|
-
AlertDialogFooter.displayName = "AlertDialogFooter";
|
|
3780
|
-
var AlertDialogTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx9(
|
|
3781
|
-
AlertDialogPrimitive.Title,
|
|
3782
|
-
{
|
|
3783
|
-
ref,
|
|
3784
|
-
className: cn("text-lg font-semibold", className),
|
|
3785
|
-
...props
|
|
3786
|
-
}
|
|
3787
|
-
));
|
|
3788
|
-
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
|
3789
|
-
var AlertDialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx9(
|
|
3790
|
-
AlertDialogPrimitive.Description,
|
|
3791
|
-
{
|
|
3792
|
-
ref,
|
|
3793
|
-
className: cn("text-sm text-zinc-500 dark:text-zinc-400", className),
|
|
3794
|
-
...props
|
|
3787
|
+
children: [
|
|
3788
|
+
/* @__PURE__ */ jsx11("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx11(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx11(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx11(
|
|
3789
|
+
"svg",
|
|
3790
|
+
{
|
|
3791
|
+
width: "15",
|
|
3792
|
+
height: "15",
|
|
3793
|
+
viewBox: "0 0 15 15",
|
|
3794
|
+
fill: "none",
|
|
3795
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3796
|
+
className: "h-4 w-4",
|
|
3797
|
+
children: /* @__PURE__ */ jsx11(
|
|
3798
|
+
"path",
|
|
3799
|
+
{
|
|
3800
|
+
d: "M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z",
|
|
3801
|
+
fill: "currentColor",
|
|
3802
|
+
fillRule: "evenodd",
|
|
3803
|
+
clipRule: "evenodd"
|
|
3804
|
+
}
|
|
3805
|
+
)
|
|
3806
|
+
}
|
|
3807
|
+
) }) }) }),
|
|
3808
|
+
/* @__PURE__ */ jsx11(SelectPrimitive.ItemText, { children })
|
|
3809
|
+
]
|
|
3795
3810
|
}
|
|
3796
3811
|
));
|
|
3797
|
-
|
|
3798
|
-
var
|
|
3799
|
-
|
|
3800
|
-
var AlertDialogCancel = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx9(
|
|
3801
|
-
AlertDialogPrimitive.Cancel,
|
|
3812
|
+
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
3813
|
+
var SelectSeparator = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
|
|
3814
|
+
SelectPrimitive.Separator,
|
|
3802
3815
|
{
|
|
3803
3816
|
ref,
|
|
3804
|
-
className: cn(
|
|
3817
|
+
className: cn("-mx-1 my-1 h-px bg-neutral-100 dark:bg-neutral-800", className),
|
|
3805
3818
|
...props
|
|
3806
3819
|
}
|
|
3807
3820
|
));
|
|
3808
|
-
|
|
3821
|
+
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
3809
3822
|
|
|
3810
|
-
// src/components/
|
|
3811
|
-
import { jsx as
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
deletionType
|
|
3818
|
-
}) {
|
|
3819
|
-
return /* @__PURE__ */ jsxs5(AlertDialog, { open, onOpenChange, children: [
|
|
3820
|
-
children && /* @__PURE__ */ jsx10(AlertDialogTrigger, { asChild: true, children }),
|
|
3821
|
-
/* @__PURE__ */ jsxs5(AlertDialogContent, { children: [
|
|
3822
|
-
/* @__PURE__ */ jsxs5(AlertDialogHeader, { children: [
|
|
3823
|
-
/* @__PURE__ */ jsx10(AlertDialogTitle, { children: deletionType === "item" ? "Delete Item" : "Delete Key" }),
|
|
3824
|
-
/* @__PURE__ */ jsxs5(AlertDialogDescription, { className: "mt-5", children: [
|
|
3825
|
-
"Are you sure you want to delete this ",
|
|
3826
|
-
deletionType,
|
|
3827
|
-
"?",
|
|
3828
|
-
/* @__PURE__ */ jsx10("br", {}),
|
|
3829
|
-
"This action cannot be undone."
|
|
3830
|
-
] })
|
|
3831
|
-
] }),
|
|
3832
|
-
/* @__PURE__ */ jsxs5(AlertDialogFooter, { children: [
|
|
3833
|
-
/* @__PURE__ */ jsx10(AlertDialogCancel, { type: "button", children: "Cancel" }),
|
|
3834
|
-
/* @__PURE__ */ jsx10(
|
|
3835
|
-
AlertDialogAction,
|
|
3836
|
-
{
|
|
3837
|
-
className: "bg-red-500 text-gray-50 hover:bg-red-600",
|
|
3838
|
-
onClick: onDeleteConfirm,
|
|
3839
|
-
children: "Yes, Delete"
|
|
3840
|
-
}
|
|
3841
|
-
)
|
|
3842
|
-
] })
|
|
3843
|
-
] })
|
|
3844
|
-
] });
|
|
3845
|
-
}
|
|
3846
|
-
|
|
3847
|
-
// src/components/databrowser/components/item-context-menu.tsx
|
|
3848
|
-
import { Fragment, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3849
|
-
var ItemContextMenu = ({
|
|
3850
|
-
children,
|
|
3851
|
-
dataKey,
|
|
3852
|
-
type
|
|
3823
|
+
// src/components/ui/spinner.tsx
|
|
3824
|
+
import { Fragment, jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3825
|
+
var Spinner = ({
|
|
3826
|
+
isLoading,
|
|
3827
|
+
className,
|
|
3828
|
+
isLoadingText,
|
|
3829
|
+
children
|
|
3853
3830
|
}) => {
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
/* @__PURE__ */ jsx11(
|
|
3859
|
-
DeleteAlertDialog,
|
|
3860
|
-
{
|
|
3861
|
-
deletionType: "item",
|
|
3862
|
-
open: isAlertOpen,
|
|
3863
|
-
onOpenChange: setAlertOpen,
|
|
3864
|
-
onDeleteConfirm: (e) => {
|
|
3865
|
-
e.stopPropagation();
|
|
3866
|
-
if (data) {
|
|
3867
|
-
editItem({
|
|
3868
|
-
type,
|
|
3869
|
-
dataKey,
|
|
3870
|
-
itemKey: data?.key,
|
|
3871
|
-
// For deletion
|
|
3872
|
-
newKey: void 0
|
|
3873
|
-
});
|
|
3874
|
-
}
|
|
3875
|
-
setAlertOpen(false);
|
|
3876
|
-
}
|
|
3877
|
-
}
|
|
3878
|
-
),
|
|
3879
|
-
/* @__PURE__ */ jsxs6(ContextMenu, { children: [
|
|
3880
|
-
/* @__PURE__ */ jsx11(
|
|
3881
|
-
ContextMenuTrigger,
|
|
3882
|
-
{
|
|
3883
|
-
asChild: true,
|
|
3884
|
-
onContextMenu: (e) => {
|
|
3885
|
-
const el = e.target;
|
|
3886
|
-
const item = el.closest("[data-item-key]");
|
|
3887
|
-
if (item && item instanceof HTMLElement && item.dataset.itemKey !== void 0) {
|
|
3888
|
-
setData({
|
|
3889
|
-
key: item.dataset.itemKey,
|
|
3890
|
-
value: item.dataset.itemValue
|
|
3891
|
-
});
|
|
3892
|
-
} else {
|
|
3893
|
-
throw new Error("Key not found");
|
|
3894
|
-
}
|
|
3895
|
-
},
|
|
3896
|
-
children
|
|
3897
|
-
}
|
|
3898
|
-
),
|
|
3899
|
-
/* @__PURE__ */ jsxs6(ContextMenuContent, { children: [
|
|
3900
|
-
/* @__PURE__ */ jsx11(
|
|
3901
|
-
ContextMenuItem,
|
|
3902
|
-
{
|
|
3903
|
-
onClick: () => {
|
|
3904
|
-
if (!data) return;
|
|
3905
|
-
navigator.clipboard.writeText(data?.key);
|
|
3906
|
-
toast({
|
|
3907
|
-
description: "Key copied to clipboard"
|
|
3908
|
-
});
|
|
3909
|
-
},
|
|
3910
|
-
children: "Copy key"
|
|
3911
|
-
}
|
|
3912
|
-
),
|
|
3913
|
-
data?.value && /* @__PURE__ */ jsx11(
|
|
3914
|
-
ContextMenuItem,
|
|
3915
|
-
{
|
|
3916
|
-
onClick: () => {
|
|
3917
|
-
navigator.clipboard.writeText(data?.value ?? "");
|
|
3918
|
-
toast({
|
|
3919
|
-
description: "Value copied to clipboard"
|
|
3920
|
-
});
|
|
3921
|
-
},
|
|
3922
|
-
children: "Copy value"
|
|
3923
|
-
}
|
|
3924
|
-
),
|
|
3925
|
-
/* @__PURE__ */ jsx11(ContextMenuSeparator2, {}),
|
|
3926
|
-
/* @__PURE__ */ jsx11(ContextMenuItem, { disabled: type === "stream", onClick: () => setAlertOpen(true), children: "Delete item" })
|
|
3927
|
-
] })
|
|
3928
|
-
] })
|
|
3929
|
-
] });
|
|
3930
|
-
};
|
|
3931
|
-
|
|
3932
|
-
// src/components/databrowser/components/sidebar/infinite-scroll.tsx
|
|
3933
|
-
import { IconLoader2 } from "@tabler/icons-react";
|
|
3934
|
-
|
|
3935
|
-
// src/components/ui/scroll-area.tsx
|
|
3936
|
-
import * as React6 from "react";
|
|
3937
|
-
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
3938
|
-
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3939
|
-
var ScrollArea = React6.forwardRef(({ className, children, onScroll, ...props }, ref) => /* @__PURE__ */ jsxs7(
|
|
3940
|
-
ScrollAreaPrimitive.Root,
|
|
3941
|
-
{
|
|
3942
|
-
ref,
|
|
3943
|
-
className: cn("relative overflow-hidden", className),
|
|
3944
|
-
...props,
|
|
3945
|
-
children: [
|
|
3946
|
-
/* @__PURE__ */ jsx12(
|
|
3947
|
-
ScrollAreaPrimitive.Viewport,
|
|
3948
|
-
{
|
|
3949
|
-
onScroll,
|
|
3950
|
-
className: "h-full w-full rounded-[inherit] [&>div]:!block",
|
|
3951
|
-
children
|
|
3952
|
-
}
|
|
3953
|
-
),
|
|
3954
|
-
/* @__PURE__ */ jsx12(ScrollBar, {}),
|
|
3955
|
-
/* @__PURE__ */ jsx12(ScrollAreaPrimitive.Corner, {})
|
|
3956
|
-
]
|
|
3957
|
-
}
|
|
3958
|
-
));
|
|
3959
|
-
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
3960
|
-
var ScrollBar = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx12(
|
|
3961
|
-
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
3962
|
-
{
|
|
3963
|
-
ref,
|
|
3964
|
-
orientation: "vertical",
|
|
3965
|
-
className: cn("flex h-full w-2 touch-none select-none transition-colors", className),
|
|
3966
|
-
...props,
|
|
3967
|
-
children: /* @__PURE__ */ jsx12(
|
|
3968
|
-
ScrollAreaPrimitive.ScrollAreaThumb,
|
|
3831
|
+
return /* @__PURE__ */ jsx12("div", { className: className ?? "flex items-center", children: isLoading ? /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
3832
|
+
isLoadingText,
|
|
3833
|
+
/* @__PURE__ */ jsx12(
|
|
3834
|
+
"svg",
|
|
3969
3835
|
{
|
|
3970
|
-
|
|
3836
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3837
|
+
width: "24",
|
|
3838
|
+
height: "24",
|
|
3839
|
+
viewBox: "0 0 24 24",
|
|
3840
|
+
fill: "none",
|
|
3841
|
+
stroke: "currentColor",
|
|
3842
|
+
strokeWidth: "2",
|
|
3843
|
+
strokeLinecap: "round",
|
|
3844
|
+
strokeLinejoin: "round",
|
|
3845
|
+
className: cn("h-4 w-4 animate-spin", isLoadingText ? "ml-2" : ""),
|
|
3846
|
+
children: /* @__PURE__ */ jsx12("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
|
|
3971
3847
|
}
|
|
3972
3848
|
)
|
|
3973
|
-
}
|
|
3974
|
-
|
|
3975
|
-
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
3849
|
+
] }) : children });
|
|
3850
|
+
};
|
|
3976
3851
|
|
|
3977
|
-
// src/components/databrowser/components/
|
|
3978
|
-
import { jsx as jsx13, jsxs as
|
|
3979
|
-
var
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3852
|
+
// src/components/databrowser/components/display/ttl-popover.tsx
|
|
3853
|
+
import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3854
|
+
var timeUnits = [
|
|
3855
|
+
{ label: "Seconds", value: 1 },
|
|
3856
|
+
{ label: "Minutes", value: 60 },
|
|
3857
|
+
{ label: "Hours", value: 60 * 60 },
|
|
3858
|
+
{ label: "Days", value: 60 * 60 * 24 }
|
|
3859
|
+
];
|
|
3860
|
+
function TTLPopover({
|
|
3861
|
+
children,
|
|
3862
|
+
ttl,
|
|
3863
|
+
setTTL,
|
|
3864
|
+
isPending
|
|
3865
|
+
}) {
|
|
3866
|
+
const [open, setOpen] = useState4(false);
|
|
3867
|
+
const defaultValues = useMemo3(() => {
|
|
3868
|
+
return { type: "Seconds", value: ttl };
|
|
3869
|
+
}, [ttl]);
|
|
3870
|
+
const { control, handleSubmit, formState, reset } = useForm({
|
|
3871
|
+
defaultValues
|
|
3872
|
+
});
|
|
3873
|
+
useEffect3(() => {
|
|
3874
|
+
reset(defaultValues, {
|
|
3875
|
+
keepValues: true
|
|
3876
|
+
});
|
|
3877
|
+
}, [defaultValues]);
|
|
3878
|
+
const onSubmit = handleSubmit(async ({ value, type }) => {
|
|
3879
|
+
await setTTL(value * timeUnits.find((unit) => unit.label === type).value);
|
|
3880
|
+
setOpen(false);
|
|
3881
|
+
});
|
|
3882
|
+
const handlePersist = async () => {
|
|
3883
|
+
await setTTL(TTL_INFINITE);
|
|
3884
|
+
setOpen(false);
|
|
3991
3885
|
};
|
|
3992
|
-
return /* @__PURE__ */
|
|
3993
|
-
|
|
3886
|
+
return /* @__PURE__ */ jsxs6(
|
|
3887
|
+
Popover,
|
|
3994
3888
|
{
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3889
|
+
open,
|
|
3890
|
+
onOpenChange: (isOpen) => {
|
|
3891
|
+
if (isOpen) reset();
|
|
3892
|
+
setOpen(isOpen);
|
|
3893
|
+
},
|
|
3998
3894
|
children: [
|
|
3999
|
-
children,
|
|
4000
|
-
/* @__PURE__ */ jsx13(
|
|
3895
|
+
/* @__PURE__ */ jsx13(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx13("button", { children }) }),
|
|
3896
|
+
/* @__PURE__ */ jsx13(PopoverContent, { className: "w-[300px]", align: "end", children: /* @__PURE__ */ jsxs6(
|
|
3897
|
+
"form",
|
|
3898
|
+
{
|
|
3899
|
+
className: "space-y-4",
|
|
3900
|
+
onSubmit: (e) => {
|
|
3901
|
+
onSubmit(e);
|
|
3902
|
+
e.stopPropagation();
|
|
3903
|
+
},
|
|
3904
|
+
children: [
|
|
3905
|
+
/* @__PURE__ */ jsx13("h4", { className: "font-medium leading-none", children: "Expiration" }),
|
|
3906
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
3907
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center", children: [
|
|
3908
|
+
/* @__PURE__ */ jsx13(
|
|
3909
|
+
Controller,
|
|
3910
|
+
{
|
|
3911
|
+
rules: {
|
|
3912
|
+
required: "Please enter an expiration time",
|
|
3913
|
+
min: { value: -1, message: "TTL can't be lower than -1" }
|
|
3914
|
+
},
|
|
3915
|
+
control,
|
|
3916
|
+
name: "value",
|
|
3917
|
+
render: ({ field }) => /* @__PURE__ */ jsx13(Input, { min: "-1", ...field, className: "grow rounded-r-none" })
|
|
3918
|
+
}
|
|
3919
|
+
),
|
|
3920
|
+
/* @__PURE__ */ jsx13(
|
|
3921
|
+
Controller,
|
|
3922
|
+
{
|
|
3923
|
+
control,
|
|
3924
|
+
name: "type",
|
|
3925
|
+
render: ({ field }) => /* @__PURE__ */ jsxs6(Select, { value: field.value, onValueChange: field.onChange, children: [
|
|
3926
|
+
/* @__PURE__ */ jsx13(SelectTrigger, { className: "w-auto rounded-l-none border-l-0 pr-8", children: /* @__PURE__ */ jsx13(SelectValue, {}) }),
|
|
3927
|
+
/* @__PURE__ */ jsx13(SelectContent, { children: timeUnits.map((unit) => /* @__PURE__ */ jsx13(SelectItem, { value: unit.label, children: unit.label }, unit.label)) })
|
|
3928
|
+
] })
|
|
3929
|
+
}
|
|
3930
|
+
)
|
|
3931
|
+
] }),
|
|
3932
|
+
formState.errors.value && /* @__PURE__ */ jsx13("p", { className: "mt-2 text-xs text-red-500", children: formState.errors.value.message }),
|
|
3933
|
+
/* @__PURE__ */ jsx13("p", { className: "mt-2 text-xs text-zinc-500", children: "TTL sets a timer to automatically delete keys after a defined period." })
|
|
3934
|
+
] }),
|
|
3935
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex justify-between", children: [
|
|
3936
|
+
/* @__PURE__ */ jsx13(
|
|
3937
|
+
Button,
|
|
3938
|
+
{
|
|
3939
|
+
type: "button",
|
|
3940
|
+
variant: "outline",
|
|
3941
|
+
disabled: ttl === TTL_INFINITE,
|
|
3942
|
+
onClick: handlePersist,
|
|
3943
|
+
children: "Persist"
|
|
3944
|
+
}
|
|
3945
|
+
),
|
|
3946
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex gap-2", children: [
|
|
3947
|
+
/* @__PURE__ */ jsx13(Button, { variant: "outline", onClick: () => setOpen(false), type: "button", children: "Cancel" }),
|
|
3948
|
+
/* @__PURE__ */ jsx13(Button, { variant: "primary", type: "submit", children: /* @__PURE__ */ jsx13(Spinner, { isLoading: isPending, isLoadingText: "Saving", children: "Save" }) })
|
|
3949
|
+
] })
|
|
3950
|
+
] })
|
|
3951
|
+
]
|
|
3952
|
+
}
|
|
3953
|
+
) })
|
|
4001
3954
|
]
|
|
4002
3955
|
}
|
|
4003
3956
|
);
|
|
4004
|
-
};
|
|
4005
|
-
|
|
4006
|
-
// src/components/databrowser/components/display/display-header.tsx
|
|
4007
|
-
import { IconPlus } from "@tabler/icons-react";
|
|
4008
|
-
|
|
4009
|
-
// src/components/databrowser/components/type-tag.tsx
|
|
4010
|
-
import {
|
|
4011
|
-
IconArrowsSort,
|
|
4012
|
-
IconCodeDots,
|
|
4013
|
-
IconHash,
|
|
4014
|
-
IconLayersIntersect,
|
|
4015
|
-
IconList,
|
|
4016
|
-
IconQuote
|
|
4017
|
-
} from "@tabler/icons-react";
|
|
4018
|
-
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
4019
|
-
var iconsMap = {
|
|
4020
|
-
string: /* @__PURE__ */ jsx14(IconQuote, { size: 15, stroke: 1.3 }),
|
|
4021
|
-
set: /* @__PURE__ */ jsx14(IconLayersIntersect, { size: 15, stroke: 1.3 }),
|
|
4022
|
-
hash: /* @__PURE__ */ jsx14(IconHash, { size: 15, stroke: 1.3 }),
|
|
4023
|
-
json: /* @__PURE__ */ jsx14(IconCodeDots, { size: 15, stroke: 1.3 }),
|
|
4024
|
-
zset: /* @__PURE__ */ jsx14(IconArrowsSort, { size: 15, stroke: 1.3 }),
|
|
4025
|
-
list: /* @__PURE__ */ jsx14(IconList, { size: 15, stroke: 1.3 }),
|
|
4026
|
-
stream: /* @__PURE__ */ jsx14(IconList, { size: 15, stroke: 1.3 })
|
|
4027
|
-
};
|
|
4028
|
-
var tagVariants = cva("inline-flex shrink-0 items-center rounded-md justify-center", {
|
|
4029
|
-
variants: {
|
|
4030
|
-
variant: {
|
|
4031
|
-
string: "bg-sky-200 text-sky-800",
|
|
4032
|
-
hash: "bg-amber-200 text-amber-800",
|
|
4033
|
-
set: "bg-indigo-200 text-indigo-800",
|
|
4034
|
-
zset: "bg-pink-200 text-pink-800",
|
|
4035
|
-
json: "bg-purple-200 text-purple-800",
|
|
4036
|
-
list: "bg-orange-200 text-orange-800",
|
|
4037
|
-
stream: "bg-green-200 text-green-800"
|
|
4038
|
-
},
|
|
4039
|
-
type: {
|
|
4040
|
-
icon: "size-5",
|
|
4041
|
-
badge: "h-6 px-2 uppercase whitespace-nowrap text-xs font-medium leading-none tracking-wide"
|
|
4042
|
-
}
|
|
4043
|
-
},
|
|
4044
|
-
defaultVariants: {
|
|
4045
|
-
variant: "string",
|
|
4046
|
-
type: "icon"
|
|
4047
|
-
}
|
|
4048
|
-
});
|
|
4049
|
-
function TypeTag({ className, variant, type }) {
|
|
4050
|
-
return /* @__PURE__ */ jsx14("span", { className: cn(tagVariants({ variant, type, className })), children: type === "icon" ? iconsMap[variant] : DATA_TYPE_NAMES[variant] });
|
|
4051
3957
|
}
|
|
4052
3958
|
|
|
4053
|
-
// src/components/databrowser/components/display/
|
|
4054
|
-
import {
|
|
4055
|
-
|
|
4056
|
-
|
|
3959
|
+
// src/components/databrowser/components/display/ttl-badge.tsx
|
|
3960
|
+
import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3961
|
+
var TTL_INFINITE = -1;
|
|
3962
|
+
var TTL_NOT_FOUND = -2;
|
|
3963
|
+
var calculateTTL = (expireAt) => {
|
|
3964
|
+
if (!expireAt) return;
|
|
3965
|
+
if (expireAt === TTL_INFINITE) return TTL_INFINITE;
|
|
3966
|
+
return Math.max(0, Math.floor((expireAt - Date.now()) / 1e3));
|
|
3967
|
+
};
|
|
3968
|
+
var TTLBadge = ({
|
|
3969
|
+
label = "TTL:",
|
|
3970
|
+
expireAt,
|
|
3971
|
+
setTTL,
|
|
3972
|
+
isPending
|
|
3973
|
+
}) => {
|
|
3974
|
+
const [ttl, setTTLLabel] = useState5(() => calculateTTL(expireAt));
|
|
3975
|
+
useEffect4(() => {
|
|
3976
|
+
setTTLLabel(calculateTTL(expireAt));
|
|
3977
|
+
const interval = setInterval(() => {
|
|
3978
|
+
setTTLLabel(calculateTTL(expireAt));
|
|
3979
|
+
}, 1e3);
|
|
3980
|
+
return () => clearInterval(interval);
|
|
3981
|
+
}, [expireAt]);
|
|
3982
|
+
return /* @__PURE__ */ jsx14(Badge, { label, children: ttl === void 0 ? /* @__PURE__ */ jsx14(Skeleton, { className: "ml-1 h-3 w-10 rounded-md opacity-50" }) : /* @__PURE__ */ jsx14(TTLPopover, { ttl, setTTL, isPending, children: /* @__PURE__ */ jsxs7("div", { className: "flex gap-[2px]", children: [
|
|
3983
|
+
ttl === TTL_INFINITE ? "Forever" : formatTime(ttl),
|
|
3984
|
+
/* @__PURE__ */ jsx14(IconChevronDown, { className: "mt-[1px] text-zinc-400", size: 12 })
|
|
3985
|
+
] }) }) });
|
|
3986
|
+
};
|
|
4057
3987
|
|
|
4058
|
-
// src/components/databrowser/hooks/use-fetch-
|
|
4059
|
-
|
|
4060
|
-
var
|
|
4061
|
-
var useFetchKeyLength = ({ dataKey, type }) => {
|
|
3988
|
+
// src/components/databrowser/hooks/use-fetch-ttl.ts
|
|
3989
|
+
var FETCH_TTL_QUERY_KEY = "fetch-ttl";
|
|
3990
|
+
var useFetchKeyExpire = (dataKey) => {
|
|
4062
3991
|
const { redis } = useDatabrowser();
|
|
4063
|
-
|
|
4064
|
-
queryKey: [
|
|
3992
|
+
const { isLoading, error, data } = useQuery6({
|
|
3993
|
+
queryKey: [FETCH_TTL_QUERY_KEY, dataKey],
|
|
4065
3994
|
queryFn: async () => {
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
3995
|
+
const ttl = await redis.ttl(dataKey);
|
|
3996
|
+
return ttl === TTL_INFINITE || ttl === TTL_NOT_FOUND ? ttl : Date.now() + ttl * 1e3;
|
|
3997
|
+
}
|
|
3998
|
+
});
|
|
3999
|
+
useEffect5(() => {
|
|
4000
|
+
if (data === TTL_NOT_FOUND) {
|
|
4001
|
+
queryClient.invalidateQueries({
|
|
4002
|
+
queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY, dataKey]
|
|
4003
|
+
});
|
|
4004
|
+
}
|
|
4005
|
+
}, [data === TTL_NOT_FOUND]);
|
|
4006
|
+
return { isLoading, error, data };
|
|
4007
|
+
};
|
|
4008
|
+
|
|
4009
|
+
// src/components/databrowser/hooks/use-set-simple-key.tsx
|
|
4010
|
+
import { useMutation as useMutation4 } from "@tanstack/react-query";
|
|
4011
|
+
var useSetSimpleKey = (dataKey, type) => {
|
|
4012
|
+
const { redis } = useDatabrowser();
|
|
4013
|
+
return useMutation4({
|
|
4014
|
+
mutationFn: async (value) => {
|
|
4015
|
+
if (type === "string") {
|
|
4016
|
+
await redis.set(dataKey, value);
|
|
4017
|
+
} else if (type === "json") {
|
|
4018
|
+
await redis.json.set(dataKey, "$", JSON.parse(value));
|
|
4019
|
+
} else {
|
|
4020
|
+
throw new Error(`Invalid type when setting simple key: ${type}`);
|
|
4082
4021
|
}
|
|
4083
|
-
|
|
4022
|
+
},
|
|
4023
|
+
onSuccess: (_, value) => {
|
|
4024
|
+
queryClient.setQueryData([FETCH_SIMPLE_KEY_QUERY_KEY, dataKey], value);
|
|
4025
|
+
queryClient.invalidateQueries({
|
|
4026
|
+
queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY, dataKey]
|
|
4027
|
+
});
|
|
4084
4028
|
}
|
|
4085
4029
|
});
|
|
4086
4030
|
};
|
|
4087
4031
|
|
|
4088
|
-
// src/components/databrowser/hooks/use-
|
|
4089
|
-
import {
|
|
4090
|
-
var
|
|
4091
|
-
var useFetchKeySize = (dataKey) => {
|
|
4032
|
+
// src/components/databrowser/hooks/use-set-ttl.ts
|
|
4033
|
+
import { useMutation as useMutation5 } from "@tanstack/react-query";
|
|
4034
|
+
var useSetTTL = () => {
|
|
4092
4035
|
const { redis } = useDatabrowser();
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4036
|
+
const updateTTL = useMutation5({
|
|
4037
|
+
mutationFn: async ({ dataKey, ttl }) => {
|
|
4038
|
+
await (ttl === void 0 || ttl === TTL_INFINITE ? redis.persist(dataKey) : redis.expire(dataKey, ttl));
|
|
4039
|
+
},
|
|
4040
|
+
onSuccess: (_, { dataKey }) => {
|
|
4041
|
+
queryClient.removeQueries({
|
|
4042
|
+
queryKey: [FETCH_TTL_QUERY_KEY, dataKey]
|
|
4043
|
+
});
|
|
4044
|
+
queryClient.invalidateQueries({
|
|
4045
|
+
queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY, dataKey]
|
|
4046
|
+
});
|
|
4097
4047
|
}
|
|
4098
4048
|
});
|
|
4049
|
+
return updateTTL;
|
|
4099
4050
|
};
|
|
4100
4051
|
|
|
4101
|
-
// src/components/databrowser/components/
|
|
4102
|
-
import {
|
|
4103
|
-
import {
|
|
4052
|
+
// src/components/databrowser/components/item-context-menu.tsx
|
|
4053
|
+
import { useState as useState6 } from "react";
|
|
4054
|
+
import { ContextMenuSeparator as ContextMenuSeparator2 } from "@radix-ui/react-context-menu";
|
|
4104
4055
|
|
|
4105
|
-
// src/components/ui/
|
|
4056
|
+
// src/components/ui/context-menu.tsx
|
|
4106
4057
|
import * as React7 from "react";
|
|
4107
|
-
import
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4058
|
+
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
|
|
4059
|
+
import { CheckIcon, ChevronRightIcon, DotFilledIcon } from "@radix-ui/react-icons";
|
|
4060
|
+
import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
4061
|
+
var ContextMenu = ContextMenuPrimitive.Root;
|
|
4062
|
+
var ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
|
4063
|
+
var ContextMenuSubTrigger = React7.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs8(
|
|
4064
|
+
ContextMenuPrimitive.SubTrigger,
|
|
4065
|
+
{
|
|
4066
|
+
ref,
|
|
4067
|
+
className: cn(
|
|
4068
|
+
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-neutral-100 focus:text-neutral-900 data-[state=open]:bg-neutral-100 data-[state=open]:text-neutral-900 dark:focus:bg-neutral-800 dark:focus:text-neutral-50 dark:data-[state=open]:bg-neutral-800 dark:data-[state=open]:text-neutral-50",
|
|
4069
|
+
inset && "pl-8",
|
|
4070
|
+
className
|
|
4071
|
+
),
|
|
4072
|
+
...props,
|
|
4073
|
+
children: [
|
|
4074
|
+
children,
|
|
4075
|
+
/* @__PURE__ */ jsx15(ChevronRightIcon, { className: "ml-auto h-4 w-4" })
|
|
4076
|
+
]
|
|
4122
4077
|
}
|
|
4123
|
-
);
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
import * as React8 from "react";
|
|
4128
|
-
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
4129
|
-
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
4130
|
-
var Popover = PopoverPrimitive.Root;
|
|
4131
|
-
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
4132
|
-
var PopoverContent = React8.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx16(PopoverPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ jsx16(
|
|
4133
|
-
PopoverPrimitive.Content,
|
|
4078
|
+
));
|
|
4079
|
+
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
|
|
4080
|
+
var ContextMenuSubContent = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx15(
|
|
4081
|
+
ContextMenuPrimitive.SubContent,
|
|
4134
4082
|
{
|
|
4135
4083
|
ref,
|
|
4136
|
-
align,
|
|
4137
|
-
sideOffset,
|
|
4138
4084
|
className: cn(
|
|
4139
|
-
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2
|
|
4085
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-neutral-200 bg-white p-1 text-neutral-950 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50",
|
|
4086
|
+
className
|
|
4087
|
+
),
|
|
4088
|
+
...props
|
|
4089
|
+
}
|
|
4090
|
+
));
|
|
4091
|
+
ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
|
|
4092
|
+
var ContextMenuContent = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx15(ContextMenuPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ jsx15(
|
|
4093
|
+
ContextMenuPrimitive.Content,
|
|
4094
|
+
{
|
|
4095
|
+
ref,
|
|
4096
|
+
className: cn(
|
|
4097
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-neutral-200 bg-white p-1 text-neutral-950 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50",
|
|
4140
4098
|
className
|
|
4141
4099
|
),
|
|
4142
4100
|
...props
|
|
4143
4101
|
}
|
|
4144
4102
|
) }));
|
|
4145
|
-
|
|
4103
|
+
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
|
|
4104
|
+
var ContextMenuItem = React7.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx15(
|
|
4105
|
+
ContextMenuPrimitive.Item,
|
|
4106
|
+
{
|
|
4107
|
+
ref,
|
|
4108
|
+
className: cn(
|
|
4109
|
+
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-neutral-100 focus:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
|
4110
|
+
inset && "pl-8",
|
|
4111
|
+
className
|
|
4112
|
+
),
|
|
4113
|
+
...props
|
|
4114
|
+
}
|
|
4115
|
+
));
|
|
4116
|
+
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
|
|
4117
|
+
var ContextMenuCheckboxItem = React7.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs8(
|
|
4118
|
+
ContextMenuPrimitive.CheckboxItem,
|
|
4119
|
+
{
|
|
4120
|
+
ref,
|
|
4121
|
+
className: cn(
|
|
4122
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-neutral-100 focus:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
|
4123
|
+
className
|
|
4124
|
+
),
|
|
4125
|
+
checked,
|
|
4126
|
+
...props,
|
|
4127
|
+
children: [
|
|
4128
|
+
/* @__PURE__ */ jsx15("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx15(ContextMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx15(CheckIcon, { className: "h-4 w-4" }) }) }),
|
|
4129
|
+
children
|
|
4130
|
+
]
|
|
4131
|
+
}
|
|
4132
|
+
));
|
|
4133
|
+
ContextMenuCheckboxItem.displayName = ContextMenuPrimitive.CheckboxItem.displayName;
|
|
4134
|
+
var ContextMenuRadioItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs8(
|
|
4135
|
+
ContextMenuPrimitive.RadioItem,
|
|
4136
|
+
{
|
|
4137
|
+
ref,
|
|
4138
|
+
className: cn(
|
|
4139
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-neutral-100 focus:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
|
4140
|
+
className
|
|
4141
|
+
),
|
|
4142
|
+
...props,
|
|
4143
|
+
children: [
|
|
4144
|
+
/* @__PURE__ */ jsx15("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx15(ContextMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx15(DotFilledIcon, { className: "h-4 w-4 fill-current" }) }) }),
|
|
4145
|
+
children
|
|
4146
|
+
]
|
|
4147
|
+
}
|
|
4148
|
+
));
|
|
4149
|
+
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
|
|
4150
|
+
var ContextMenuLabel = React7.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx15(
|
|
4151
|
+
ContextMenuPrimitive.Label,
|
|
4152
|
+
{
|
|
4153
|
+
ref,
|
|
4154
|
+
className: cn(
|
|
4155
|
+
"px-2 py-1.5 text-sm font-semibold text-neutral-950 dark:text-neutral-50",
|
|
4156
|
+
inset && "pl-8",
|
|
4157
|
+
className
|
|
4158
|
+
),
|
|
4159
|
+
...props
|
|
4160
|
+
}
|
|
4161
|
+
));
|
|
4162
|
+
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
|
|
4163
|
+
var ContextMenuSeparator = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx15(
|
|
4164
|
+
ContextMenuPrimitive.Separator,
|
|
4165
|
+
{
|
|
4166
|
+
ref,
|
|
4167
|
+
className: cn("-mx-1 my-1 h-px bg-neutral-200 dark:bg-neutral-800", className),
|
|
4168
|
+
...props
|
|
4169
|
+
}
|
|
4170
|
+
));
|
|
4171
|
+
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
|
|
4172
|
+
var ContextMenuShortcut = ({ className, ...props }) => {
|
|
4173
|
+
return /* @__PURE__ */ jsx15(
|
|
4174
|
+
"span",
|
|
4175
|
+
{
|
|
4176
|
+
className: cn(
|
|
4177
|
+
"ml-auto text-xs tracking-widest text-neutral-500 dark:text-neutral-400",
|
|
4178
|
+
className
|
|
4179
|
+
),
|
|
4180
|
+
...props
|
|
4181
|
+
}
|
|
4182
|
+
);
|
|
4183
|
+
};
|
|
4184
|
+
ContextMenuShortcut.displayName = "ContextMenuShortcut";
|
|
4146
4185
|
|
|
4147
|
-
// src/components/ui/
|
|
4148
|
-
import * as
|
|
4149
|
-
import * as
|
|
4150
|
-
import { jsx as
|
|
4151
|
-
var
|
|
4152
|
-
var
|
|
4153
|
-
var
|
|
4154
|
-
|
|
4155
|
-
|
|
4186
|
+
// src/components/ui/alert-dialog.tsx
|
|
4187
|
+
import * as React8 from "react";
|
|
4188
|
+
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
4189
|
+
import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4190
|
+
var AlertDialog = AlertDialogPrimitive.Root;
|
|
4191
|
+
var AlertDialogTrigger = AlertDialogPrimitive.Trigger;
|
|
4192
|
+
var AlertDialogPortal = ({ ...props }) => /* @__PURE__ */ jsx16(AlertDialogPrimitive.Portal, { container: portalRoot, ...props });
|
|
4193
|
+
AlertDialogPortal.displayName = AlertDialogPrimitive.Portal.displayName;
|
|
4194
|
+
var AlertDialogOverlay = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx16(
|
|
4195
|
+
AlertDialogPrimitive.Overlay,
|
|
4156
4196
|
{
|
|
4157
|
-
ref,
|
|
4158
4197
|
className: cn(
|
|
4159
|
-
"
|
|
4198
|
+
"fixed inset-0 z-50 bg-white/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 dark:bg-zinc-950/80",
|
|
4160
4199
|
className
|
|
4161
4200
|
),
|
|
4162
4201
|
...props,
|
|
4163
|
-
|
|
4164
|
-
children,
|
|
4165
|
-
/* @__PURE__ */ jsx17(SelectPrimitive.Icon, { asChild: true, className: "absolute right-2", children: /* @__PURE__ */ jsx17(
|
|
4166
|
-
"svg",
|
|
4167
|
-
{
|
|
4168
|
-
width: "16",
|
|
4169
|
-
height: "16",
|
|
4170
|
-
viewBox: "0 0 16 16",
|
|
4171
|
-
fill: "none",
|
|
4172
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
4173
|
-
children: /* @__PURE__ */ jsx17(
|
|
4174
|
-
"path",
|
|
4175
|
-
{
|
|
4176
|
-
d: "M4 6L8 10L12 6",
|
|
4177
|
-
stroke: "black",
|
|
4178
|
-
strokeOpacity: "0.4",
|
|
4179
|
-
strokeWidth: "1.4",
|
|
4180
|
-
strokeLinecap: "round",
|
|
4181
|
-
strokeLinejoin: "round"
|
|
4182
|
-
}
|
|
4183
|
-
)
|
|
4184
|
-
}
|
|
4185
|
-
) })
|
|
4186
|
-
]
|
|
4202
|
+
ref
|
|
4187
4203
|
}
|
|
4188
4204
|
));
|
|
4189
|
-
|
|
4190
|
-
var
|
|
4191
|
-
|
|
4205
|
+
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
|
|
4206
|
+
var AlertDialogContent = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs9(AlertDialogPortal, { children: [
|
|
4207
|
+
/* @__PURE__ */ jsx16(AlertDialogOverlay, {}),
|
|
4208
|
+
/* @__PURE__ */ jsx16(
|
|
4209
|
+
AlertDialogPrimitive.Content,
|
|
4210
|
+
{
|
|
4211
|
+
ref,
|
|
4212
|
+
className: cn(
|
|
4213
|
+
"antialiased data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-zinc-200 bg-white p-6 shadow-lg duration-200 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] dark:border-zinc-800 dark:bg-zinc-950 sm:rounded-lg md:w-full",
|
|
4214
|
+
className
|
|
4215
|
+
),
|
|
4216
|
+
...props
|
|
4217
|
+
}
|
|
4218
|
+
)
|
|
4219
|
+
] }));
|
|
4220
|
+
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
|
|
4221
|
+
var AlertDialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx16("div", { className: cn("flex flex-col space-y-2 text-center sm:text-left", className), ...props });
|
|
4222
|
+
AlertDialogHeader.displayName = "AlertDialogHeader";
|
|
4223
|
+
var AlertDialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx16(
|
|
4224
|
+
"div",
|
|
4225
|
+
{
|
|
4226
|
+
className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
|
|
4227
|
+
...props
|
|
4228
|
+
}
|
|
4229
|
+
);
|
|
4230
|
+
AlertDialogFooter.displayName = "AlertDialogFooter";
|
|
4231
|
+
var AlertDialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx16(
|
|
4232
|
+
AlertDialogPrimitive.Title,
|
|
4192
4233
|
{
|
|
4193
4234
|
ref,
|
|
4194
|
-
className: cn(
|
|
4195
|
-
|
|
4196
|
-
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
4197
|
-
className
|
|
4198
|
-
),
|
|
4199
|
-
position,
|
|
4200
|
-
...props,
|
|
4201
|
-
children: /* @__PURE__ */ jsx17(
|
|
4202
|
-
SelectPrimitive.Viewport,
|
|
4203
|
-
{
|
|
4204
|
-
className: cn(
|
|
4205
|
-
"p-1",
|
|
4206
|
-
position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
|
4207
|
-
),
|
|
4208
|
-
children
|
|
4209
|
-
}
|
|
4210
|
-
)
|
|
4235
|
+
className: cn("text-lg font-semibold", className),
|
|
4236
|
+
...props
|
|
4211
4237
|
}
|
|
4212
|
-
)
|
|
4213
|
-
|
|
4214
|
-
var
|
|
4215
|
-
|
|
4238
|
+
));
|
|
4239
|
+
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
|
4240
|
+
var AlertDialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx16(
|
|
4241
|
+
AlertDialogPrimitive.Description,
|
|
4216
4242
|
{
|
|
4217
4243
|
ref,
|
|
4218
|
-
className: cn("
|
|
4244
|
+
className: cn("text-sm text-zinc-500 dark:text-zinc-400", className),
|
|
4219
4245
|
...props
|
|
4220
4246
|
}
|
|
4221
4247
|
));
|
|
4222
|
-
|
|
4223
|
-
var
|
|
4224
|
-
|
|
4248
|
+
AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
|
|
4249
|
+
var AlertDialogAction = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx16(AlertDialogPrimitive.Action, { ref, className: cn(buttonVariants(), className), ...props }));
|
|
4250
|
+
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
|
|
4251
|
+
var AlertDialogCancel = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx16(
|
|
4252
|
+
AlertDialogPrimitive.Cancel,
|
|
4225
4253
|
{
|
|
4226
4254
|
ref,
|
|
4227
|
-
className: cn(
|
|
4228
|
-
|
|
4229
|
-
|
|
4255
|
+
className: cn(buttonVariants({ variant: "outline" }), "mt-2 sm:!mt-0", className),
|
|
4256
|
+
...props
|
|
4257
|
+
}
|
|
4258
|
+
));
|
|
4259
|
+
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
|
|
4260
|
+
|
|
4261
|
+
// src/components/databrowser/components/display/delete-alert-dialog.tsx
|
|
4262
|
+
import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4263
|
+
function DeleteAlertDialog({
|
|
4264
|
+
children,
|
|
4265
|
+
onDeleteConfirm,
|
|
4266
|
+
open,
|
|
4267
|
+
onOpenChange,
|
|
4268
|
+
deletionType
|
|
4269
|
+
}) {
|
|
4270
|
+
return /* @__PURE__ */ jsxs10(AlertDialog, { open, onOpenChange, children: [
|
|
4271
|
+
children && /* @__PURE__ */ jsx17(AlertDialogTrigger, { asChild: true, children }),
|
|
4272
|
+
/* @__PURE__ */ jsxs10(AlertDialogContent, { children: [
|
|
4273
|
+
/* @__PURE__ */ jsxs10(AlertDialogHeader, { children: [
|
|
4274
|
+
/* @__PURE__ */ jsx17(AlertDialogTitle, { children: deletionType === "item" ? "Delete Item" : "Delete Key" }),
|
|
4275
|
+
/* @__PURE__ */ jsxs10(AlertDialogDescription, { className: "mt-5", children: [
|
|
4276
|
+
"Are you sure you want to delete this ",
|
|
4277
|
+
deletionType,
|
|
4278
|
+
"?",
|
|
4279
|
+
/* @__PURE__ */ jsx17("br", {}),
|
|
4280
|
+
"This action cannot be undone."
|
|
4281
|
+
] })
|
|
4282
|
+
] }),
|
|
4283
|
+
/* @__PURE__ */ jsxs10(AlertDialogFooter, { children: [
|
|
4284
|
+
/* @__PURE__ */ jsx17(AlertDialogCancel, { type: "button", children: "Cancel" }),
|
|
4285
|
+
/* @__PURE__ */ jsx17(
|
|
4286
|
+
AlertDialogAction,
|
|
4287
|
+
{
|
|
4288
|
+
className: "bg-red-500 text-gray-50 hover:bg-red-600",
|
|
4289
|
+
onClick: onDeleteConfirm,
|
|
4290
|
+
children: "Yes, Delete"
|
|
4291
|
+
}
|
|
4292
|
+
)
|
|
4293
|
+
] })
|
|
4294
|
+
] })
|
|
4295
|
+
] });
|
|
4296
|
+
}
|
|
4297
|
+
|
|
4298
|
+
// src/components/databrowser/components/item-context-menu.tsx
|
|
4299
|
+
import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4300
|
+
var ItemContextMenu = ({
|
|
4301
|
+
children,
|
|
4302
|
+
dataKey,
|
|
4303
|
+
type
|
|
4304
|
+
}) => {
|
|
4305
|
+
const { mutate: editItem } = useEditListItem();
|
|
4306
|
+
const [isAlertOpen, setAlertOpen] = useState6(false);
|
|
4307
|
+
const [data, setData] = useState6();
|
|
4308
|
+
return /* @__PURE__ */ jsxs11(Fragment2, { children: [
|
|
4309
|
+
/* @__PURE__ */ jsx18(
|
|
4310
|
+
DeleteAlertDialog,
|
|
4311
|
+
{
|
|
4312
|
+
deletionType: "item",
|
|
4313
|
+
open: isAlertOpen,
|
|
4314
|
+
onOpenChange: setAlertOpen,
|
|
4315
|
+
onDeleteConfirm: (e) => {
|
|
4316
|
+
e.stopPropagation();
|
|
4317
|
+
if (data) {
|
|
4318
|
+
editItem({
|
|
4319
|
+
type,
|
|
4320
|
+
dataKey,
|
|
4321
|
+
itemKey: data?.key,
|
|
4322
|
+
// For deletion
|
|
4323
|
+
newKey: void 0
|
|
4324
|
+
});
|
|
4325
|
+
}
|
|
4326
|
+
setAlertOpen(false);
|
|
4327
|
+
}
|
|
4328
|
+
}
|
|
4230
4329
|
),
|
|
4330
|
+
/* @__PURE__ */ jsxs11(ContextMenu, { children: [
|
|
4331
|
+
/* @__PURE__ */ jsx18(
|
|
4332
|
+
ContextMenuTrigger,
|
|
4333
|
+
{
|
|
4334
|
+
asChild: true,
|
|
4335
|
+
onContextMenu: (e) => {
|
|
4336
|
+
const el = e.target;
|
|
4337
|
+
const item = el.closest("[data-item-key]");
|
|
4338
|
+
if (item && item instanceof HTMLElement && item.dataset.itemKey !== void 0) {
|
|
4339
|
+
setData({
|
|
4340
|
+
key: item.dataset.itemKey,
|
|
4341
|
+
value: item.dataset.itemValue
|
|
4342
|
+
});
|
|
4343
|
+
} else {
|
|
4344
|
+
throw new Error("Key not found");
|
|
4345
|
+
}
|
|
4346
|
+
},
|
|
4347
|
+
children
|
|
4348
|
+
}
|
|
4349
|
+
),
|
|
4350
|
+
/* @__PURE__ */ jsxs11(ContextMenuContent, { children: [
|
|
4351
|
+
/* @__PURE__ */ jsx18(
|
|
4352
|
+
ContextMenuItem,
|
|
4353
|
+
{
|
|
4354
|
+
onClick: () => {
|
|
4355
|
+
if (!data) return;
|
|
4356
|
+
navigator.clipboard.writeText(data?.key);
|
|
4357
|
+
toast({
|
|
4358
|
+
description: "Key copied to clipboard"
|
|
4359
|
+
});
|
|
4360
|
+
},
|
|
4361
|
+
children: "Copy key"
|
|
4362
|
+
}
|
|
4363
|
+
),
|
|
4364
|
+
data?.value && /* @__PURE__ */ jsx18(
|
|
4365
|
+
ContextMenuItem,
|
|
4366
|
+
{
|
|
4367
|
+
onClick: () => {
|
|
4368
|
+
navigator.clipboard.writeText(data?.value ?? "");
|
|
4369
|
+
toast({
|
|
4370
|
+
description: "Value copied to clipboard"
|
|
4371
|
+
});
|
|
4372
|
+
},
|
|
4373
|
+
children: "Copy value"
|
|
4374
|
+
}
|
|
4375
|
+
),
|
|
4376
|
+
/* @__PURE__ */ jsx18(ContextMenuSeparator2, {}),
|
|
4377
|
+
/* @__PURE__ */ jsx18(ContextMenuItem, { disabled: type === "stream", onClick: () => setAlertOpen(true), children: "Delete item" })
|
|
4378
|
+
] })
|
|
4379
|
+
] })
|
|
4380
|
+
] });
|
|
4381
|
+
};
|
|
4382
|
+
|
|
4383
|
+
// src/components/databrowser/components/sidebar/infinite-scroll.tsx
|
|
4384
|
+
import { IconLoader2 } from "@tabler/icons-react";
|
|
4385
|
+
|
|
4386
|
+
// src/components/ui/scroll-area.tsx
|
|
4387
|
+
import * as React9 from "react";
|
|
4388
|
+
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
4389
|
+
import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4390
|
+
var ScrollArea = React9.forwardRef(({ className, children, onScroll, ...props }, ref) => /* @__PURE__ */ jsxs12(
|
|
4391
|
+
ScrollAreaPrimitive.Root,
|
|
4392
|
+
{
|
|
4393
|
+
ref,
|
|
4394
|
+
className: cn("relative overflow-hidden", className),
|
|
4231
4395
|
...props,
|
|
4232
4396
|
children: [
|
|
4233
|
-
/* @__PURE__ */
|
|
4234
|
-
|
|
4397
|
+
/* @__PURE__ */ jsx19(
|
|
4398
|
+
ScrollAreaPrimitive.Viewport,
|
|
4235
4399
|
{
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
fill: "none",
|
|
4240
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
4241
|
-
className: "h-4 w-4",
|
|
4242
|
-
children: /* @__PURE__ */ jsx17(
|
|
4243
|
-
"path",
|
|
4244
|
-
{
|
|
4245
|
-
d: "M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z",
|
|
4246
|
-
fill: "currentColor",
|
|
4247
|
-
fillRule: "evenodd",
|
|
4248
|
-
clipRule: "evenodd"
|
|
4249
|
-
}
|
|
4250
|
-
)
|
|
4400
|
+
onScroll,
|
|
4401
|
+
className: "h-full w-full rounded-[inherit] [&>div]:!block",
|
|
4402
|
+
children
|
|
4251
4403
|
}
|
|
4252
|
-
)
|
|
4253
|
-
/* @__PURE__ */
|
|
4404
|
+
),
|
|
4405
|
+
/* @__PURE__ */ jsx19(ScrollBar, {}),
|
|
4406
|
+
/* @__PURE__ */ jsx19(ScrollAreaPrimitive.Corner, {})
|
|
4254
4407
|
]
|
|
4255
4408
|
}
|
|
4256
4409
|
));
|
|
4257
|
-
|
|
4258
|
-
var
|
|
4259
|
-
|
|
4410
|
+
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
4411
|
+
var ScrollBar = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
|
|
4412
|
+
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
4260
4413
|
{
|
|
4261
4414
|
ref,
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
// src/components/ui/spinner.tsx
|
|
4269
|
-
import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4270
|
-
var Spinner = ({
|
|
4271
|
-
isLoading,
|
|
4272
|
-
className,
|
|
4273
|
-
isLoadingText,
|
|
4274
|
-
children
|
|
4275
|
-
}) => {
|
|
4276
|
-
return /* @__PURE__ */ jsx18("div", { className: className ?? "flex items-center", children: isLoading ? /* @__PURE__ */ jsxs10(Fragment2, { children: [
|
|
4277
|
-
isLoadingText,
|
|
4278
|
-
/* @__PURE__ */ jsx18(
|
|
4279
|
-
"svg",
|
|
4415
|
+
orientation: "vertical",
|
|
4416
|
+
className: cn("flex h-full w-2 touch-none select-none transition-colors", className),
|
|
4417
|
+
...props,
|
|
4418
|
+
children: /* @__PURE__ */ jsx19(
|
|
4419
|
+
ScrollAreaPrimitive.ScrollAreaThumb,
|
|
4280
4420
|
{
|
|
4281
|
-
|
|
4282
|
-
width: "24",
|
|
4283
|
-
height: "24",
|
|
4284
|
-
viewBox: "0 0 24 24",
|
|
4285
|
-
fill: "none",
|
|
4286
|
-
stroke: "currentColor",
|
|
4287
|
-
strokeWidth: "2",
|
|
4288
|
-
strokeLinecap: "round",
|
|
4289
|
-
strokeLinejoin: "round",
|
|
4290
|
-
className: cn("h-4 w-4 animate-spin", isLoadingText ? "ml-2" : ""),
|
|
4291
|
-
children: /* @__PURE__ */ jsx18("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
|
|
4421
|
+
className: cn("relative flex-1 rounded-full bg-neutral-200/70 dark:bg-neutral-800")
|
|
4292
4422
|
}
|
|
4293
4423
|
)
|
|
4294
|
-
|
|
4295
|
-
|
|
4424
|
+
}
|
|
4425
|
+
));
|
|
4426
|
+
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
4296
4427
|
|
|
4297
|
-
// src/components/databrowser/components/
|
|
4298
|
-
import { jsx as
|
|
4299
|
-
var
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
}
|
|
4311
|
-
const [open, setOpen] = useState5(false);
|
|
4312
|
-
const { mutateAsync: setTTL, isPending } = useSetTTL();
|
|
4313
|
-
const defaultValues = useMemo3(() => {
|
|
4314
|
-
return { type: "Seconds", value: ttl };
|
|
4315
|
-
}, [ttl]);
|
|
4316
|
-
const { control, handleSubmit, formState, reset } = useForm({
|
|
4317
|
-
defaultValues
|
|
4318
|
-
});
|
|
4319
|
-
useEffect4(() => {
|
|
4320
|
-
reset(defaultValues, {
|
|
4321
|
-
keepValues: true
|
|
4322
|
-
});
|
|
4323
|
-
}, [defaultValues]);
|
|
4324
|
-
const onSubmit = handleSubmit(async ({ value, type }) => {
|
|
4325
|
-
await setTTL({
|
|
4326
|
-
dataKey,
|
|
4327
|
-
ttl: value * timeUnits.find((unit) => unit.label === type).value
|
|
4328
|
-
});
|
|
4329
|
-
setOpen(false);
|
|
4330
|
-
});
|
|
4331
|
-
const handlePersist = async () => {
|
|
4332
|
-
await setTTL({
|
|
4333
|
-
dataKey,
|
|
4334
|
-
ttl: void 0
|
|
4335
|
-
});
|
|
4336
|
-
setOpen(false);
|
|
4428
|
+
// src/components/databrowser/components/sidebar/infinite-scroll.tsx
|
|
4429
|
+
import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4430
|
+
var InfiniteScroll = ({
|
|
4431
|
+
query,
|
|
4432
|
+
children
|
|
4433
|
+
}) => {
|
|
4434
|
+
const handleScroll = (e) => {
|
|
4435
|
+
const { scrollTop, clientHeight, scrollHeight } = e.currentTarget;
|
|
4436
|
+
if (scrollTop + clientHeight > scrollHeight - 100) {
|
|
4437
|
+
if (query.isFetching || !query.hasNextPage) {
|
|
4438
|
+
return;
|
|
4439
|
+
}
|
|
4440
|
+
query.fetchNextPage();
|
|
4441
|
+
}
|
|
4337
4442
|
};
|
|
4338
|
-
return /* @__PURE__ */
|
|
4339
|
-
|
|
4443
|
+
return /* @__PURE__ */ jsxs13(
|
|
4444
|
+
ScrollArea,
|
|
4340
4445
|
{
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
setOpen(isOpen);
|
|
4345
|
-
},
|
|
4446
|
+
type: "always",
|
|
4447
|
+
className: "block h-full w-full transition-all",
|
|
4448
|
+
onScroll: handleScroll,
|
|
4346
4449
|
children: [
|
|
4347
|
-
|
|
4348
|
-
/* @__PURE__ */
|
|
4349
|
-
/* @__PURE__ */ jsx19("h4", { className: "font-medium leading-none", children: "Expiration" }),
|
|
4350
|
-
/* @__PURE__ */ jsxs11("div", { children: [
|
|
4351
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex items-center", children: [
|
|
4352
|
-
/* @__PURE__ */ jsx19(
|
|
4353
|
-
Controller,
|
|
4354
|
-
{
|
|
4355
|
-
rules: {
|
|
4356
|
-
required: "Please enter an expiration time",
|
|
4357
|
-
min: { value: -1, message: "TTL can't be lower than -1" }
|
|
4358
|
-
},
|
|
4359
|
-
control,
|
|
4360
|
-
name: "value",
|
|
4361
|
-
render: ({ field }) => /* @__PURE__ */ jsx19(Input, { min: "-1", ...field, className: "grow rounded-r-none" })
|
|
4362
|
-
}
|
|
4363
|
-
),
|
|
4364
|
-
/* @__PURE__ */ jsx19(
|
|
4365
|
-
Controller,
|
|
4366
|
-
{
|
|
4367
|
-
control,
|
|
4368
|
-
name: "type",
|
|
4369
|
-
render: ({ field }) => /* @__PURE__ */ jsxs11(Select, { value: field.value, onValueChange: field.onChange, children: [
|
|
4370
|
-
/* @__PURE__ */ jsx19(SelectTrigger, { className: "w-auto rounded-l-none border-l-0 pr-8", children: /* @__PURE__ */ jsx19(SelectValue, {}) }),
|
|
4371
|
-
/* @__PURE__ */ jsx19(SelectContent, { children: timeUnits.map((unit) => /* @__PURE__ */ jsx19(SelectItem, { value: unit.label, children: unit.label }, unit.label)) })
|
|
4372
|
-
] })
|
|
4373
|
-
}
|
|
4374
|
-
)
|
|
4375
|
-
] }),
|
|
4376
|
-
formState.errors.value && /* @__PURE__ */ jsx19("p", { className: "mt-2 text-xs text-red-500", children: formState.errors.value.message }),
|
|
4377
|
-
/* @__PURE__ */ jsx19("p", { className: "mt-2 text-xs text-zinc-500", children: "TTL sets a timer to automatically delete keys after a defined period." })
|
|
4378
|
-
] }),
|
|
4379
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex justify-between", children: [
|
|
4380
|
-
/* @__PURE__ */ jsx19(
|
|
4381
|
-
Button,
|
|
4382
|
-
{
|
|
4383
|
-
type: "button",
|
|
4384
|
-
variant: "outline",
|
|
4385
|
-
disabled: ttl === PERSISTED_KEY,
|
|
4386
|
-
onClick: handlePersist,
|
|
4387
|
-
children: "Persist"
|
|
4388
|
-
}
|
|
4389
|
-
),
|
|
4390
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex gap-2", children: [
|
|
4391
|
-
/* @__PURE__ */ jsx19(Button, { variant: "outline", onClick: () => setOpen(false), type: "button", children: "Cancel" }),
|
|
4392
|
-
/* @__PURE__ */ jsx19(Button, { variant: "primary", type: "submit", children: /* @__PURE__ */ jsx19(Spinner, { isLoading: isPending, isLoadingText: "Saving", children: "Save" }) })
|
|
4393
|
-
] })
|
|
4394
|
-
] })
|
|
4395
|
-
] }) })
|
|
4450
|
+
children,
|
|
4451
|
+
/* @__PURE__ */ jsx20("div", { className: "flex h-[100px] justify-center py-2 text-zinc-300", children: query.isFetching && /* @__PURE__ */ jsx20(IconLoader2, { className: "animate-spin", size: 16 }) })
|
|
4396
4452
|
]
|
|
4397
4453
|
}
|
|
4398
4454
|
);
|
|
4399
|
-
}
|
|
4400
|
-
|
|
4401
|
-
// src/components/databrowser/components/display/header-badges.tsx
|
|
4402
|
-
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4403
|
-
var LengthBadge = ({
|
|
4404
|
-
dataKey,
|
|
4405
|
-
type,
|
|
4406
|
-
content
|
|
4407
|
-
}) => {
|
|
4408
|
-
const { data, isLoading } = useFetchKeyLength({ dataKey, type });
|
|
4409
|
-
const length = content?.length ?? data;
|
|
4410
|
-
return /* @__PURE__ */ jsx20(Badge, { label: "Length:", children: isLoading ? /* @__PURE__ */ jsx20(Skeleton, { className: "ml-1 h-3 w-10 rounded-md opacity-50" }) : length });
|
|
4411
|
-
};
|
|
4412
|
-
var SizeBadge = ({ dataKey }) => {
|
|
4413
|
-
const { data: size } = useFetchKeySize(dataKey);
|
|
4414
|
-
return /* @__PURE__ */ jsx20(Badge, { label: "Size:", children: size === void 0 || size === null ? /* @__PURE__ */ jsx20(Skeleton, { className: "ml-1 h-3 w-10 rounded-md opacity-50" }) : bytes(size, {
|
|
4415
|
-
unitSeparator: " "
|
|
4416
|
-
}) });
|
|
4417
4455
|
};
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4456
|
+
|
|
4457
|
+
// src/components/databrowser/components/display/display-header.tsx
|
|
4458
|
+
import { IconPlus } from "@tabler/icons-react";
|
|
4459
|
+
|
|
4460
|
+
// src/components/databrowser/components/type-tag.tsx
|
|
4461
|
+
import {
|
|
4462
|
+
IconArrowsSort,
|
|
4463
|
+
IconCodeDots,
|
|
4464
|
+
IconHash,
|
|
4465
|
+
IconLayersIntersect,
|
|
4466
|
+
IconList,
|
|
4467
|
+
IconQuote
|
|
4468
|
+
} from "@tabler/icons-react";
|
|
4469
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
4470
|
+
var iconsMap = {
|
|
4471
|
+
string: /* @__PURE__ */ jsx21(IconQuote, { size: 15, stroke: 1.3 }),
|
|
4472
|
+
set: /* @__PURE__ */ jsx21(IconLayersIntersect, { size: 15, stroke: 1.3 }),
|
|
4473
|
+
hash: /* @__PURE__ */ jsx21(IconHash, { size: 15, stroke: 1.3 }),
|
|
4474
|
+
json: /* @__PURE__ */ jsx21(IconCodeDots, { size: 15, stroke: 1.3 }),
|
|
4475
|
+
zset: /* @__PURE__ */ jsx21(IconArrowsSort, { size: 15, stroke: 1.3 }),
|
|
4476
|
+
list: /* @__PURE__ */ jsx21(IconList, { size: 15, stroke: 1.3 }),
|
|
4477
|
+
stream: /* @__PURE__ */ jsx21(IconList, { size: 15, stroke: 1.3 })
|
|
4440
4478
|
};
|
|
4441
|
-
var
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4479
|
+
var tagVariants = cva("inline-flex shrink-0 items-center rounded-md justify-center", {
|
|
4480
|
+
variants: {
|
|
4481
|
+
variant: {
|
|
4482
|
+
string: "bg-sky-200 text-sky-800",
|
|
4483
|
+
hash: "bg-amber-200 text-amber-800",
|
|
4484
|
+
set: "bg-indigo-200 text-indigo-800",
|
|
4485
|
+
zset: "bg-pink-200 text-pink-800",
|
|
4486
|
+
json: "bg-purple-200 text-purple-800",
|
|
4487
|
+
list: "bg-orange-200 text-orange-800",
|
|
4488
|
+
stream: "bg-green-200 text-green-800"
|
|
4489
|
+
},
|
|
4490
|
+
type: {
|
|
4491
|
+
icon: "size-5",
|
|
4492
|
+
badge: "h-6 px-2 uppercase whitespace-nowrap text-xs font-medium leading-none tracking-wide"
|
|
4493
|
+
}
|
|
4494
|
+
},
|
|
4495
|
+
defaultVariants: {
|
|
4496
|
+
variant: "string",
|
|
4497
|
+
type: "icon"
|
|
4498
|
+
}
|
|
4499
|
+
});
|
|
4500
|
+
function TypeTag({ className, variant, type }) {
|
|
4501
|
+
return /* @__PURE__ */ jsx21("span", { className: cn(tagVariants({ variant, type, className })), children: type === "icon" ? iconsMap[variant] : DATA_TYPE_NAMES[variant] });
|
|
4502
|
+
}
|
|
4445
4503
|
|
|
4446
4504
|
// src/components/databrowser/components/display/key-actions.tsx
|
|
4447
4505
|
import { IconDotsVertical } from "@tabler/icons-react";
|
|
@@ -4450,10 +4508,10 @@ import { IconDotsVertical } from "@tabler/icons-react";
|
|
|
4450
4508
|
import * as React10 from "react";
|
|
4451
4509
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
4452
4510
|
import { CheckIcon as CheckIcon2, ChevronRightIcon as ChevronRightIcon2, DotFilledIcon as DotFilledIcon2 } from "@radix-ui/react-icons";
|
|
4453
|
-
import { jsx as
|
|
4511
|
+
import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4454
4512
|
var DropdownMenu = DropdownMenuPrimitive.Root;
|
|
4455
4513
|
var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
4456
|
-
var DropdownMenuSubTrigger = React10.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */
|
|
4514
|
+
var DropdownMenuSubTrigger = React10.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs14(
|
|
4457
4515
|
DropdownMenuPrimitive.SubTrigger,
|
|
4458
4516
|
{
|
|
4459
4517
|
ref,
|
|
@@ -4465,12 +4523,12 @@ var DropdownMenuSubTrigger = React10.forwardRef(({ className, inset, children, .
|
|
|
4465
4523
|
...props,
|
|
4466
4524
|
children: [
|
|
4467
4525
|
children,
|
|
4468
|
-
/* @__PURE__ */
|
|
4526
|
+
/* @__PURE__ */ jsx22(ChevronRightIcon2, { className: "ml-auto size-4" })
|
|
4469
4527
|
]
|
|
4470
4528
|
}
|
|
4471
4529
|
));
|
|
4472
4530
|
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
4473
|
-
var DropdownMenuSubContent = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
4531
|
+
var DropdownMenuSubContent = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx22(
|
|
4474
4532
|
DropdownMenuPrimitive.SubContent,
|
|
4475
4533
|
{
|
|
4476
4534
|
ref,
|
|
@@ -4482,7 +4540,7 @@ var DropdownMenuSubContent = React10.forwardRef(({ className, ...props }, ref) =
|
|
|
4482
4540
|
}
|
|
4483
4541
|
));
|
|
4484
4542
|
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
4485
|
-
var DropdownMenuContent = React10.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */
|
|
4543
|
+
var DropdownMenuContent = React10.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx22(DropdownMenuPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ jsx22(
|
|
4486
4544
|
DropdownMenuPrimitive.Content,
|
|
4487
4545
|
{
|
|
4488
4546
|
ref,
|
|
@@ -4496,7 +4554,7 @@ var DropdownMenuContent = React10.forwardRef(({ className, sideOffset = 4, ...pr
|
|
|
4496
4554
|
}
|
|
4497
4555
|
) }));
|
|
4498
4556
|
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
4499
|
-
var DropdownMenuItem = React10.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */
|
|
4557
|
+
var DropdownMenuItem = React10.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx22(
|
|
4500
4558
|
DropdownMenuPrimitive.Item,
|
|
4501
4559
|
{
|
|
4502
4560
|
ref,
|
|
@@ -4509,7 +4567,7 @@ var DropdownMenuItem = React10.forwardRef(({ className, inset, ...props }, ref)
|
|
|
4509
4567
|
}
|
|
4510
4568
|
));
|
|
4511
4569
|
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
4512
|
-
var DropdownMenuCheckboxItem = React10.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */
|
|
4570
|
+
var DropdownMenuCheckboxItem = React10.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs14(
|
|
4513
4571
|
DropdownMenuPrimitive.CheckboxItem,
|
|
4514
4572
|
{
|
|
4515
4573
|
ref,
|
|
@@ -4520,13 +4578,13 @@ var DropdownMenuCheckboxItem = React10.forwardRef(({ className, children, checke
|
|
|
4520
4578
|
checked,
|
|
4521
4579
|
...props,
|
|
4522
4580
|
children: [
|
|
4523
|
-
/* @__PURE__ */
|
|
4581
|
+
/* @__PURE__ */ jsx22("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx22(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx22(CheckIcon2, { className: "size-4" }) }) }),
|
|
4524
4582
|
children
|
|
4525
4583
|
]
|
|
4526
4584
|
}
|
|
4527
4585
|
));
|
|
4528
4586
|
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
4529
|
-
var DropdownMenuRadioItem = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */
|
|
4587
|
+
var DropdownMenuRadioItem = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs14(
|
|
4530
4588
|
DropdownMenuPrimitive.RadioItem,
|
|
4531
4589
|
{
|
|
4532
4590
|
ref,
|
|
@@ -4536,13 +4594,13 @@ var DropdownMenuRadioItem = React10.forwardRef(({ className, children, ...props
|
|
|
4536
4594
|
),
|
|
4537
4595
|
...props,
|
|
4538
4596
|
children: [
|
|
4539
|
-
/* @__PURE__ */
|
|
4597
|
+
/* @__PURE__ */ jsx22("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx22(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx22(DotFilledIcon2, { className: "size-4 fill-current" }) }) }),
|
|
4540
4598
|
children
|
|
4541
4599
|
]
|
|
4542
4600
|
}
|
|
4543
4601
|
));
|
|
4544
4602
|
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
4545
|
-
var DropdownMenuLabel = React10.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */
|
|
4603
|
+
var DropdownMenuLabel = React10.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx22(
|
|
4546
4604
|
DropdownMenuPrimitive.Label,
|
|
4547
4605
|
{
|
|
4548
4606
|
ref,
|
|
@@ -4551,7 +4609,7 @@ var DropdownMenuLabel = React10.forwardRef(({ className, inset, ...props }, ref)
|
|
|
4551
4609
|
}
|
|
4552
4610
|
));
|
|
4553
4611
|
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
4554
|
-
var DropdownMenuSeparator = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
4612
|
+
var DropdownMenuSeparator = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx22(
|
|
4555
4613
|
DropdownMenuPrimitive.Separator,
|
|
4556
4614
|
{
|
|
4557
4615
|
ref,
|
|
@@ -4561,18 +4619,18 @@ var DropdownMenuSeparator = React10.forwardRef(({ className, ...props }, ref) =>
|
|
|
4561
4619
|
));
|
|
4562
4620
|
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
4563
4621
|
var DropdownMenuShortcut = ({ className, ...props }) => {
|
|
4564
|
-
return /* @__PURE__ */
|
|
4622
|
+
return /* @__PURE__ */ jsx22("span", { className: cn("ml-auto text-xs tracking-widest opacity-60", className), ...props });
|
|
4565
4623
|
};
|
|
4566
4624
|
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
|
4567
4625
|
|
|
4568
4626
|
// src/components/databrowser/components/display/key-actions.tsx
|
|
4569
|
-
import { jsx as
|
|
4627
|
+
import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4570
4628
|
function KeyActions({ dataKey, content }) {
|
|
4571
4629
|
const { mutateAsync: deleteKey } = useDeleteKey();
|
|
4572
|
-
return /* @__PURE__ */
|
|
4573
|
-
/* @__PURE__ */
|
|
4574
|
-
/* @__PURE__ */
|
|
4575
|
-
content && /* @__PURE__ */
|
|
4630
|
+
return /* @__PURE__ */ jsxs15(DropdownMenu, { children: [
|
|
4631
|
+
/* @__PURE__ */ jsx23(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx23(Button, { size: "icon-sm", children: /* @__PURE__ */ jsx23(IconDotsVertical, { className: "size-4 text-zinc-500" }) }) }),
|
|
4632
|
+
/* @__PURE__ */ jsxs15(DropdownMenuContent, { className: "", align: "end", children: [
|
|
4633
|
+
content && /* @__PURE__ */ jsx23(
|
|
4576
4634
|
DropdownMenuItem,
|
|
4577
4635
|
{
|
|
4578
4636
|
onClick: () => {
|
|
@@ -4584,12 +4642,12 @@ function KeyActions({ dataKey, content }) {
|
|
|
4584
4642
|
children: "Copy content"
|
|
4585
4643
|
}
|
|
4586
4644
|
),
|
|
4587
|
-
/* @__PURE__ */
|
|
4645
|
+
/* @__PURE__ */ jsx23(
|
|
4588
4646
|
DeleteAlertDialog,
|
|
4589
4647
|
{
|
|
4590
4648
|
deletionType: "key",
|
|
4591
4649
|
onDeleteConfirm: async () => await deleteKey(dataKey),
|
|
4592
|
-
children: /* @__PURE__ */
|
|
4650
|
+
children: /* @__PURE__ */ jsx23(DropdownMenuItem, { onSelect: (e) => e.preventDefault(), children: "Delete key" })
|
|
4593
4651
|
}
|
|
4594
4652
|
)
|
|
4595
4653
|
] })
|
|
@@ -4597,7 +4655,7 @@ function KeyActions({ dataKey, content }) {
|
|
|
4597
4655
|
}
|
|
4598
4656
|
|
|
4599
4657
|
// src/components/databrowser/components/display/display-header.tsx
|
|
4600
|
-
import { jsx as
|
|
4658
|
+
import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4601
4659
|
var DisplayHeader = ({
|
|
4602
4660
|
dataKey,
|
|
4603
4661
|
type,
|
|
@@ -4607,34 +4665,33 @@ var DisplayHeader = ({
|
|
|
4607
4665
|
const handleAddItem = () => {
|
|
4608
4666
|
setSelectedListItem({ key: type === "stream" ? "*" : "", isNew: true });
|
|
4609
4667
|
};
|
|
4610
|
-
return /* @__PURE__ */
|
|
4611
|
-
/* @__PURE__ */
|
|
4612
|
-
/* @__PURE__ */
|
|
4613
|
-
/* @__PURE__ */
|
|
4614
|
-
type !== "string" && type !== "json" && /* @__PURE__ */
|
|
4615
|
-
/* @__PURE__ */
|
|
4668
|
+
return /* @__PURE__ */ jsxs16("div", { className: "rounded-lg bg-zinc-100 px-3 py-2", children: [
|
|
4669
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex min-h-10 items-center justify-between gap-4", children: [
|
|
4670
|
+
/* @__PURE__ */ jsx24("h2", { className: "grow truncate text-base", children: dataKey.trim() === "" ? /* @__PURE__ */ jsx24("span", { className: "ml-1 text-zinc-500", children: "(Empty Key)" }) : /* @__PURE__ */ jsx24("span", { className: "font-semibold", children: dataKey }) }),
|
|
4671
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1", children: [
|
|
4672
|
+
type !== "string" && type !== "json" && /* @__PURE__ */ jsx24(Button, { onClick: handleAddItem, size: "icon-sm", children: /* @__PURE__ */ jsx24(IconPlus, { className: "size-4 text-zinc-500" }) }),
|
|
4673
|
+
/* @__PURE__ */ jsx24(KeyActions, { dataKey, content })
|
|
4616
4674
|
] })
|
|
4617
4675
|
] }),
|
|
4618
|
-
/* @__PURE__ */
|
|
4619
|
-
/* @__PURE__ */
|
|
4620
|
-
/* @__PURE__ */
|
|
4621
|
-
/* @__PURE__ */
|
|
4622
|
-
/* @__PURE__ */
|
|
4676
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex h-10 flex-wrap items-center gap-1.5", children: [
|
|
4677
|
+
/* @__PURE__ */ jsx24(TypeTag, { variant: type, type: "badge" }),
|
|
4678
|
+
/* @__PURE__ */ jsx24(SizeBadge, { dataKey }),
|
|
4679
|
+
/* @__PURE__ */ jsx24(LengthBadge, { dataKey, type, content }),
|
|
4680
|
+
/* @__PURE__ */ jsx24(HeaderTTLBadge, { dataKey })
|
|
4623
4681
|
] })
|
|
4624
4682
|
] });
|
|
4625
4683
|
};
|
|
4626
4684
|
|
|
4627
4685
|
// src/components/databrowser/components/display/display-list-edit.tsx
|
|
4628
|
-
import { useEffect as useEffect8 } from "react";
|
|
4629
4686
|
import { Controller as Controller2, FormProvider, useForm as useForm2, useFormContext } from "react-hook-form";
|
|
4630
4687
|
|
|
4631
4688
|
// src/components/ui/tooltip.tsx
|
|
4632
4689
|
import * as React11 from "react";
|
|
4633
4690
|
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
4634
|
-
import { Fragment as Fragment3, jsx as
|
|
4691
|
+
import { Fragment as Fragment3, jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4635
4692
|
var Tooltip = TooltipPrimitive.Root;
|
|
4636
4693
|
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
4637
|
-
var TooltipContent = React11.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */
|
|
4694
|
+
var TooltipContent = React11.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
4638
4695
|
TooltipPrimitive.Content,
|
|
4639
4696
|
{
|
|
4640
4697
|
ref,
|
|
@@ -4651,31 +4708,103 @@ var SimpleTooltip = ({
|
|
|
4651
4708
|
content,
|
|
4652
4709
|
children
|
|
4653
4710
|
}) => {
|
|
4654
|
-
if (!content) return /* @__PURE__ */
|
|
4655
|
-
return /* @__PURE__ */
|
|
4656
|
-
/* @__PURE__ */
|
|
4657
|
-
/* @__PURE__ */
|
|
4711
|
+
if (!content) return /* @__PURE__ */ jsx25(Fragment3, { children });
|
|
4712
|
+
return /* @__PURE__ */ jsxs17(Tooltip, { delayDuration: 400, children: [
|
|
4713
|
+
/* @__PURE__ */ jsx25(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx25("div", { children }) }),
|
|
4714
|
+
/* @__PURE__ */ jsx25(TooltipContent, { children: content })
|
|
4658
4715
|
] });
|
|
4659
4716
|
};
|
|
4660
4717
|
|
|
4718
|
+
// src/components/databrowser/hooks/use-fetch-hash-ttl.ts
|
|
4719
|
+
import { useQuery as useQuery7 } from "@tanstack/react-query";
|
|
4720
|
+
var FETCH_HASH_FIELD_TTLS_QUERY_KEY = "fetch-hash-field-ttls";
|
|
4721
|
+
var useFetchHashFieldExpires = ({
|
|
4722
|
+
dataKey,
|
|
4723
|
+
fields
|
|
4724
|
+
}) => {
|
|
4725
|
+
const { redis } = useDatabrowser();
|
|
4726
|
+
return useQuery7({
|
|
4727
|
+
queryKey: [FETCH_HASH_FIELD_TTLS_QUERY_KEY, dataKey, fields],
|
|
4728
|
+
queryFn: async () => {
|
|
4729
|
+
const cachedExpires = /* @__PURE__ */ new Map();
|
|
4730
|
+
for (const field of fields) {
|
|
4731
|
+
const expireAt = queryClient.getQueryData([
|
|
4732
|
+
FETCH_HASH_FIELD_TTLS_QUERY_KEY,
|
|
4733
|
+
dataKey,
|
|
4734
|
+
field
|
|
4735
|
+
]);
|
|
4736
|
+
if (expireAt !== void 0) cachedExpires.set(field, expireAt);
|
|
4737
|
+
}
|
|
4738
|
+
const filteredFields = fields.filter((field) => !cachedExpires.has(field));
|
|
4739
|
+
if (filteredFields.length === 0) return Object.fromEntries(cachedExpires.entries());
|
|
4740
|
+
const res = await redis.httl(dataKey, filteredFields);
|
|
4741
|
+
const expireAts = res.map(
|
|
4742
|
+
(ttl) => ttl === TTL_INFINITE || ttl === TTL_NOT_FOUND ? ttl : Date.now() + ttl * 1e3
|
|
4743
|
+
);
|
|
4744
|
+
for (const [i, field] of filteredFields.entries()) {
|
|
4745
|
+
queryClient.setQueryData([FETCH_HASH_FIELD_TTLS_QUERY_KEY, dataKey, field], expireAts[i]);
|
|
4746
|
+
}
|
|
4747
|
+
const newExpiresArray = expireAts.map((expireAt, i) => [filteredFields[i], expireAt]);
|
|
4748
|
+
return Object.fromEntries([...cachedExpires.entries(), ...newExpiresArray]);
|
|
4749
|
+
}
|
|
4750
|
+
});
|
|
4751
|
+
};
|
|
4752
|
+
|
|
4753
|
+
// src/components/databrowser/hooks/use-set-hash-ttl.ts
|
|
4754
|
+
import { useMutation as useMutation6 } from "@tanstack/react-query";
|
|
4755
|
+
var useSetHashTTL = () => {
|
|
4756
|
+
const { redis } = useDatabrowser();
|
|
4757
|
+
return useMutation6({
|
|
4758
|
+
mutationFn: async ({
|
|
4759
|
+
dataKey,
|
|
4760
|
+
field,
|
|
4761
|
+
ttl
|
|
4762
|
+
}) => {
|
|
4763
|
+
await (ttl === void 0 || ttl === TTL_INFINITE ? redis.hpersist(dataKey, field) : redis.hexpire(dataKey, field, ttl));
|
|
4764
|
+
},
|
|
4765
|
+
onSuccess: (_, { dataKey }) => {
|
|
4766
|
+
queryClient.removeQueries({
|
|
4767
|
+
queryKey: [FETCH_HASH_FIELD_TTLS_QUERY_KEY, dataKey]
|
|
4768
|
+
});
|
|
4769
|
+
}
|
|
4770
|
+
});
|
|
4771
|
+
};
|
|
4772
|
+
|
|
4773
|
+
// src/components/databrowser/components/display/hash/hash-field-ttl-badge.tsx
|
|
4774
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
4775
|
+
var HashFieldTTLBadge = ({ dataKey, field }) => {
|
|
4776
|
+
const { data } = useFetchHashFieldExpires({ dataKey, fields: [field] });
|
|
4777
|
+
const { mutate: setTTL, isPending } = useSetHashTTL();
|
|
4778
|
+
const expireAt = data?.[field];
|
|
4779
|
+
return /* @__PURE__ */ jsx26(
|
|
4780
|
+
TTLBadge,
|
|
4781
|
+
{
|
|
4782
|
+
label: "Field TTL:",
|
|
4783
|
+
expireAt,
|
|
4784
|
+
setTTL: (ttl) => setTTL({ dataKey, field, ttl }),
|
|
4785
|
+
isPending
|
|
4786
|
+
}
|
|
4787
|
+
);
|
|
4788
|
+
};
|
|
4789
|
+
|
|
4661
4790
|
// src/components/databrowser/components/display/input/use-field.tsx
|
|
4662
|
-
import { useEffect as useEffect7, useState as
|
|
4791
|
+
import { useEffect as useEffect7, useState as useState8 } from "react";
|
|
4663
4792
|
import { useController } from "react-hook-form";
|
|
4664
4793
|
|
|
4665
4794
|
// src/components/databrowser/components/display/input/content-type-select.tsx
|
|
4666
4795
|
import { useMemo as useMemo4 } from "react";
|
|
4667
|
-
import { jsx as
|
|
4796
|
+
import { jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4668
4797
|
var ContentTypeSelect = ({
|
|
4669
4798
|
value,
|
|
4670
4799
|
onChange,
|
|
4671
4800
|
data
|
|
4672
4801
|
}) => {
|
|
4673
4802
|
const isValidJSON = useMemo4(() => checkIsValidJSON(data), [data]);
|
|
4674
|
-
return /* @__PURE__ */
|
|
4675
|
-
/* @__PURE__ */
|
|
4676
|
-
/* @__PURE__ */
|
|
4677
|
-
/* @__PURE__ */
|
|
4678
|
-
/* @__PURE__ */
|
|
4803
|
+
return /* @__PURE__ */ jsxs18(Select, { value, onValueChange: onChange, children: [
|
|
4804
|
+
/* @__PURE__ */ jsx27(SelectTrigger, { className: "h-6 w-auto border-none bg-transparent pl-0 pr-6 text-xs text-zinc-500", children: /* @__PURE__ */ jsx27(SelectValue, { placeholder: "Text" }) }),
|
|
4805
|
+
/* @__PURE__ */ jsx27(SelectContent, { children: /* @__PURE__ */ jsxs18(SelectGroup, { children: [
|
|
4806
|
+
/* @__PURE__ */ jsx27(SelectItem, { value: "Text", children: "Text" }),
|
|
4807
|
+
/* @__PURE__ */ jsx27(SelectItem, { disabled: !isValidJSON, value: "JSON", children: "JSON" })
|
|
4679
4808
|
] }) })
|
|
4680
4809
|
] });
|
|
4681
4810
|
};
|
|
@@ -4685,12 +4814,12 @@ import { useEffect as useEffect6, useRef as useRef3 } from "react";
|
|
|
4685
4814
|
import { Editor, useMonaco } from "@monaco-editor/react";
|
|
4686
4815
|
|
|
4687
4816
|
// src/components/databrowser/copy-button.tsx
|
|
4688
|
-
import { useState as
|
|
4817
|
+
import { useState as useState7 } from "react";
|
|
4689
4818
|
import { IconCheck, IconCopy } from "@tabler/icons-react";
|
|
4690
|
-
import { jsx as
|
|
4819
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
4691
4820
|
function CopyButton({ value, ...props }) {
|
|
4692
|
-
const [copied, setCopied] =
|
|
4693
|
-
return /* @__PURE__ */
|
|
4821
|
+
const [copied, setCopied] = useState7(false);
|
|
4822
|
+
return /* @__PURE__ */ jsx28(
|
|
4694
4823
|
Button,
|
|
4695
4824
|
{
|
|
4696
4825
|
onClick: (e) => {
|
|
@@ -4707,7 +4836,7 @@ function CopyButton({ value, ...props }) {
|
|
|
4707
4836
|
variant: "secondary",
|
|
4708
4837
|
size: "icon-sm",
|
|
4709
4838
|
...props,
|
|
4710
|
-
children: copied ? /* @__PURE__ */
|
|
4839
|
+
children: copied ? /* @__PURE__ */ jsx28(IconCheck, { className: "size-4 text-green-500" }) : /* @__PURE__ */ jsx28(IconCopy, { className: "size-4 text-zinc-500" })
|
|
4711
4840
|
}
|
|
4712
4841
|
);
|
|
4713
4842
|
}
|
|
@@ -4720,7 +4849,7 @@ var handleCopyClick = async (textToCopy) => {
|
|
|
4720
4849
|
};
|
|
4721
4850
|
|
|
4722
4851
|
// src/components/databrowser/components/display/input/custom-editor.tsx
|
|
4723
|
-
import { jsx as
|
|
4852
|
+
import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4724
4853
|
var CustomEditor = ({
|
|
4725
4854
|
language,
|
|
4726
4855
|
value,
|
|
@@ -4737,7 +4866,7 @@ var CustomEditor = ({
|
|
|
4737
4866
|
}
|
|
4738
4867
|
monaco?.editor.setModelLanguage(editorRef.current.getModel(), language);
|
|
4739
4868
|
}, [monaco, language]);
|
|
4740
|
-
return /* @__PURE__ */
|
|
4869
|
+
return /* @__PURE__ */ jsxs19(
|
|
4741
4870
|
"div",
|
|
4742
4871
|
{
|
|
4743
4872
|
className: cn("group/editor relative", height === void 0 && "h-full p-2"),
|
|
@@ -4745,7 +4874,7 @@ var CustomEditor = ({
|
|
|
4745
4874
|
height
|
|
4746
4875
|
},
|
|
4747
4876
|
children: [
|
|
4748
|
-
/* @__PURE__ */
|
|
4877
|
+
/* @__PURE__ */ jsx29(
|
|
4749
4878
|
Editor,
|
|
4750
4879
|
{
|
|
4751
4880
|
loading: void 0,
|
|
@@ -4786,7 +4915,7 @@ var CustomEditor = ({
|
|
|
4786
4915
|
}
|
|
4787
4916
|
}
|
|
4788
4917
|
),
|
|
4789
|
-
showCopyButton && /* @__PURE__ */
|
|
4918
|
+
showCopyButton && /* @__PURE__ */ jsx29(
|
|
4790
4919
|
CopyButton,
|
|
4791
4920
|
{
|
|
4792
4921
|
value,
|
|
@@ -4799,7 +4928,7 @@ var CustomEditor = ({
|
|
|
4799
4928
|
};
|
|
4800
4929
|
|
|
4801
4930
|
// src/components/databrowser/components/display/input/use-field.tsx
|
|
4802
|
-
import { Fragment as Fragment4, jsx as
|
|
4931
|
+
import { Fragment as Fragment4, jsx as jsx30 } from "react/jsx-runtime";
|
|
4803
4932
|
var useField = ({
|
|
4804
4933
|
name,
|
|
4805
4934
|
form,
|
|
@@ -4812,16 +4941,19 @@ var useField = ({
|
|
|
4812
4941
|
name,
|
|
4813
4942
|
control: form.control
|
|
4814
4943
|
});
|
|
4815
|
-
const [contentType, setContentType] =
|
|
4944
|
+
const [contentType, setContentType] = useState8(
|
|
4816
4945
|
() => checkIsValidJSON(field.value) ? "JSON" : "Text"
|
|
4817
4946
|
);
|
|
4818
4947
|
useEffect7(() => {
|
|
4819
|
-
if (
|
|
4820
|
-
|
|
4948
|
+
if (contentType === "JSON" && checkIsValidJSON(data)) {
|
|
4949
|
+
form.setValue(name, formatJSON(data), {
|
|
4950
|
+
shouldDirty: false
|
|
4951
|
+
});
|
|
4952
|
+
} else {
|
|
4953
|
+
form.setValue(name, data, {
|
|
4954
|
+
shouldDirty: false
|
|
4955
|
+
});
|
|
4821
4956
|
}
|
|
4822
|
-
form.setValue(name, formatJSON(data), {
|
|
4823
|
-
shouldDirty: false
|
|
4824
|
-
});
|
|
4825
4957
|
}, [data]);
|
|
4826
4958
|
const handleTypeChange = (type) => {
|
|
4827
4959
|
setContentType(type);
|
|
@@ -4836,8 +4968,8 @@ var useField = ({
|
|
|
4836
4968
|
}
|
|
4837
4969
|
};
|
|
4838
4970
|
return {
|
|
4839
|
-
selector: /* @__PURE__ */
|
|
4840
|
-
editor: /* @__PURE__ */
|
|
4971
|
+
selector: /* @__PURE__ */ jsx30(ContentTypeSelect, { value: contentType, onChange: handleTypeChange, data: field.value }),
|
|
4972
|
+
editor: /* @__PURE__ */ jsx30(Fragment4, { children: /* @__PURE__ */ jsx30(
|
|
4841
4973
|
CustomEditor,
|
|
4842
4974
|
{
|
|
4843
4975
|
language: contentType === "JSON" ? "json" : "plaintext",
|
|
@@ -4861,13 +4993,13 @@ var checkIsValidJSON = (value) => {
|
|
|
4861
4993
|
};
|
|
4862
4994
|
|
|
4863
4995
|
// src/components/databrowser/components/display/display-list-edit.tsx
|
|
4864
|
-
import { jsx as
|
|
4996
|
+
import { jsx as jsx31, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4865
4997
|
var ListEditDisplay = ({
|
|
4866
4998
|
dataKey,
|
|
4867
4999
|
type,
|
|
4868
5000
|
item
|
|
4869
5001
|
}) => {
|
|
4870
|
-
return /* @__PURE__ */
|
|
5002
|
+
return /* @__PURE__ */ jsx31("div", { className: "grow rounded-md bg-zinc-100 p-3", children: /* @__PURE__ */ jsx31(ListEditForm, { item, type, dataKey }, item.key) });
|
|
4871
5003
|
};
|
|
4872
5004
|
var ListEditForm = ({
|
|
4873
5005
|
type,
|
|
@@ -4892,12 +5024,6 @@ var ListEditForm = ({
|
|
|
4892
5024
|
value: itemValue
|
|
4893
5025
|
}
|
|
4894
5026
|
});
|
|
4895
|
-
useEffect8(() => {
|
|
4896
|
-
form.reset({
|
|
4897
|
-
key: itemKey,
|
|
4898
|
-
value: itemValue
|
|
4899
|
-
});
|
|
4900
|
-
}, [itemKey, itemValue]);
|
|
4901
5027
|
const { mutateAsync: editItem, isPending } = useEditListItem();
|
|
4902
5028
|
const { setSelectedListItem } = useDatabrowserStore();
|
|
4903
5029
|
const [keyLabel, valueLabel] = headerLabels[type];
|
|
@@ -4912,9 +5038,9 @@ var ListEditForm = ({
|
|
|
4912
5038
|
});
|
|
4913
5039
|
setSelectedListItem(void 0);
|
|
4914
5040
|
});
|
|
4915
|
-
return /* @__PURE__ */
|
|
4916
|
-
/* @__PURE__ */
|
|
4917
|
-
type !== "list" && /* @__PURE__ */
|
|
5041
|
+
return /* @__PURE__ */ jsx31(FormProvider, { ...form, children: /* @__PURE__ */ jsxs20("form", { onSubmit, className: "flex flex-col gap-2", children: [
|
|
5042
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex grow flex-col gap-2", children: [
|
|
5043
|
+
type !== "list" && /* @__PURE__ */ jsx31(
|
|
4918
5044
|
FormItem,
|
|
4919
5045
|
{
|
|
4920
5046
|
readOnly: type === "stream",
|
|
@@ -4924,7 +5050,7 @@ var ListEditForm = ({
|
|
|
4924
5050
|
data: itemKey
|
|
4925
5051
|
}
|
|
4926
5052
|
),
|
|
4927
|
-
type === "zset" ? /* @__PURE__ */
|
|
5053
|
+
type === "zset" ? /* @__PURE__ */ jsx31(NumberFormItem, { name: "value", label: valueLabel }) : type !== "set" && /* @__PURE__ */ jsx31(
|
|
4928
5054
|
FormItem,
|
|
4929
5055
|
{
|
|
4930
5056
|
readOnly: type === "stream",
|
|
@@ -4935,43 +5061,55 @@ var ListEditForm = ({
|
|
|
4935
5061
|
}
|
|
4936
5062
|
)
|
|
4937
5063
|
] }),
|
|
4938
|
-
/* @__PURE__ */
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
5064
|
+
/* @__PURE__ */ jsxs20(
|
|
5065
|
+
"div",
|
|
5066
|
+
{
|
|
5067
|
+
className: cn(
|
|
5068
|
+
"flex items-center",
|
|
5069
|
+
type === "hash" && itemKey !== "" ? "justify-between" : "justify-end"
|
|
5070
|
+
),
|
|
5071
|
+
children: [
|
|
5072
|
+
type === "hash" && itemKey !== "" && /* @__PURE__ */ jsx31(HashFieldTTLBadge, { dataKey, field: itemKey }),
|
|
5073
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex gap-2", children: [
|
|
5074
|
+
/* @__PURE__ */ jsx31(
|
|
5075
|
+
Button,
|
|
5076
|
+
{
|
|
5077
|
+
type: "button",
|
|
5078
|
+
onClick: () => {
|
|
5079
|
+
setSelectedListItem(void 0);
|
|
5080
|
+
},
|
|
5081
|
+
children: "Cancel"
|
|
5082
|
+
}
|
|
5083
|
+
),
|
|
5084
|
+
/* @__PURE__ */ jsx31(
|
|
5085
|
+
SimpleTooltip,
|
|
5086
|
+
{
|
|
5087
|
+
content: type === "stream" && !isNew ? "Streams are not mutable" : void 0,
|
|
5088
|
+
children: /* @__PURE__ */ jsx31(
|
|
5089
|
+
Button,
|
|
5090
|
+
{
|
|
5091
|
+
variant: "primary",
|
|
5092
|
+
type: "submit",
|
|
5093
|
+
disabled: !form.formState.isValid || !form.formState.isDirty || type === "stream" && !isNew,
|
|
5094
|
+
children: /* @__PURE__ */ jsx31(Spinner, { isLoading: isPending, isLoadingText: "Saving", children: "Save" })
|
|
5095
|
+
}
|
|
5096
|
+
)
|
|
5097
|
+
}
|
|
5098
|
+
)
|
|
5099
|
+
] })
|
|
5100
|
+
]
|
|
5101
|
+
}
|
|
5102
|
+
)
|
|
4965
5103
|
] }) });
|
|
4966
5104
|
};
|
|
4967
5105
|
var NumberFormItem = ({ name, label }) => {
|
|
4968
|
-
return /* @__PURE__ */
|
|
4969
|
-
/* @__PURE__ */
|
|
4970
|
-
/* @__PURE__ */
|
|
5106
|
+
return /* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-1", children: [
|
|
5107
|
+
/* @__PURE__ */ jsx31("div", { className: "flex", children: /* @__PURE__ */ jsx31("span", { className: "text-xs font-medium text-zinc-700", children: label }) }),
|
|
5108
|
+
/* @__PURE__ */ jsx31(
|
|
4971
5109
|
Controller2,
|
|
4972
5110
|
{
|
|
4973
5111
|
name,
|
|
4974
|
-
render: ({ field }) => /* @__PURE__ */
|
|
5112
|
+
render: ({ field }) => /* @__PURE__ */ jsx31(
|
|
4975
5113
|
"input",
|
|
4976
5114
|
{
|
|
4977
5115
|
className: "plain-input rounded-md border border-zinc-300 px-3 py-1 shadow-sm",
|
|
@@ -4999,19 +5137,41 @@ var FormItem = ({
|
|
|
4999
5137
|
readOnly,
|
|
5000
5138
|
data
|
|
5001
5139
|
});
|
|
5002
|
-
return /* @__PURE__ */
|
|
5003
|
-
/* @__PURE__ */
|
|
5004
|
-
/* @__PURE__ */
|
|
5140
|
+
return /* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-1", children: [
|
|
5141
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-1 text-xs", children: [
|
|
5142
|
+
/* @__PURE__ */ jsx31("span", { className: "font-medium text-zinc-700", children: label }),
|
|
5005
5143
|
" ",
|
|
5006
|
-
/* @__PURE__ */
|
|
5144
|
+
/* @__PURE__ */ jsx31("span", { className: "text-zinc-300", children: "/" }),
|
|
5007
5145
|
selector
|
|
5008
5146
|
] }),
|
|
5009
|
-
/* @__PURE__ */
|
|
5147
|
+
/* @__PURE__ */ jsx31("div", { className: "overflow-hidden rounded-md border border-zinc-300 bg-white p-2 shadow-sm", children: editor })
|
|
5010
5148
|
] });
|
|
5011
5149
|
};
|
|
5012
5150
|
|
|
5151
|
+
// src/components/databrowser/components/display/hash/hash-field-ttl-info.tsx
|
|
5152
|
+
import { useEffect as useEffect8, useState as useState9 } from "react";
|
|
5153
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
5154
|
+
var HashFieldTTLInfo = ({
|
|
5155
|
+
dataKey,
|
|
5156
|
+
field,
|
|
5157
|
+
fields
|
|
5158
|
+
}) => {
|
|
5159
|
+
const { data } = useFetchHashFieldExpires({ dataKey, fields });
|
|
5160
|
+
const expireAt = data?.[field];
|
|
5161
|
+
const [ttl, setTTL] = useState9(() => calculateTTL(expireAt));
|
|
5162
|
+
useEffect8(() => {
|
|
5163
|
+
setTTL(calculateTTL(expireAt));
|
|
5164
|
+
const interval = setInterval(() => {
|
|
5165
|
+
setTTL(calculateTTL(expireAt));
|
|
5166
|
+
}, 1e3);
|
|
5167
|
+
return () => clearInterval(interval);
|
|
5168
|
+
}, [expireAt]);
|
|
5169
|
+
if (!expireAt || expireAt === TTL_NOT_FOUND || expireAt === TTL_INFINITE) return;
|
|
5170
|
+
return /* @__PURE__ */ jsx32("span", { className: "block min-w-[30px] whitespace-nowrap text-right text-red-600", children: formatTime(ttl ?? 0) });
|
|
5171
|
+
};
|
|
5172
|
+
|
|
5013
5173
|
// src/components/databrowser/components/display/display-list.tsx
|
|
5014
|
-
import { Fragment as Fragment5, jsx as
|
|
5174
|
+
import { Fragment as Fragment5, jsx as jsx33, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
5015
5175
|
var headerLabels = {
|
|
5016
5176
|
list: ["Index", "Content"],
|
|
5017
5177
|
hash: ["Field", "Value"],
|
|
@@ -5022,10 +5182,10 @@ var headerLabels = {
|
|
|
5022
5182
|
var ListDisplay = ({ dataKey, type }) => {
|
|
5023
5183
|
const { selectedListItem } = useDatabrowserStore();
|
|
5024
5184
|
const query = useFetchListItems({ dataKey, type });
|
|
5025
|
-
return /* @__PURE__ */
|
|
5026
|
-
/* @__PURE__ */
|
|
5027
|
-
selectedListItem && /* @__PURE__ */
|
|
5028
|
-
/* @__PURE__ */
|
|
5185
|
+
return /* @__PURE__ */ jsxs21("div", { className: "flex h-full flex-col gap-2", children: [
|
|
5186
|
+
/* @__PURE__ */ jsx33(DisplayHeader, { dataKey, type }),
|
|
5187
|
+
selectedListItem && /* @__PURE__ */ jsx33(ListEditDisplay, { dataKey, type, item: selectedListItem }),
|
|
5188
|
+
/* @__PURE__ */ jsx33("div", { className: cn("min-h-0 grow", selectedListItem && "hidden"), children: /* @__PURE__ */ jsx33(InfiniteScroll, { query, children: /* @__PURE__ */ jsx33("div", { className: "pr-3", children: /* @__PURE__ */ jsx33("table", { className: "w-full", children: /* @__PURE__ */ jsx33(ItemContextMenu, { dataKey, type, children: /* @__PURE__ */ jsx33("tbody", { children: /* @__PURE__ */ jsx33(ListItems, { dataKey, type, query }) }) }) }) }) }) })
|
|
5029
5189
|
] });
|
|
5030
5190
|
};
|
|
5031
5191
|
var ListItems = ({
|
|
@@ -5035,8 +5195,9 @@ var ListItems = ({
|
|
|
5035
5195
|
}) => {
|
|
5036
5196
|
const { setSelectedListItem } = useDatabrowserStore();
|
|
5037
5197
|
const keys = useMemo5(() => query.data?.pages.flatMap((page) => page.keys) ?? [], [query.data]);
|
|
5198
|
+
const fields = useMemo5(() => keys.map((key) => key.key), [keys]);
|
|
5038
5199
|
const { mutate: editItem } = useEditListItem();
|
|
5039
|
-
return /* @__PURE__ */
|
|
5200
|
+
return /* @__PURE__ */ jsx33(Fragment5, { children: keys.map(({ key, value }, i) => /* @__PURE__ */ jsxs21(
|
|
5040
5201
|
"tr",
|
|
5041
5202
|
{
|
|
5042
5203
|
"data-item-key": key,
|
|
@@ -5044,9 +5205,9 @@ var ListItems = ({
|
|
|
5044
5205
|
onClick: () => {
|
|
5045
5206
|
setSelectedListItem({ key });
|
|
5046
5207
|
},
|
|
5047
|
-
className: "h-10 border-b border-b-zinc-100 hover:bg-zinc-
|
|
5208
|
+
className: cn("h-10 border-b border-b-zinc-100 hover:bg-zinc-100 "),
|
|
5048
5209
|
children: [
|
|
5049
|
-
/* @__PURE__ */
|
|
5210
|
+
/* @__PURE__ */ jsx33(
|
|
5050
5211
|
"td",
|
|
5051
5212
|
{
|
|
5052
5213
|
className: cn(
|
|
@@ -5056,38 +5217,49 @@ var ListItems = ({
|
|
|
5056
5217
|
children: key
|
|
5057
5218
|
}
|
|
5058
5219
|
),
|
|
5059
|
-
value !== void 0 && /* @__PURE__ */
|
|
5220
|
+
value !== void 0 && /* @__PURE__ */ jsx33(
|
|
5060
5221
|
"td",
|
|
5061
5222
|
{
|
|
5062
5223
|
className: cn("cursor-pointer truncate px-3", type === "zset" ? "w-24" : "max-w-0"),
|
|
5063
5224
|
children: value
|
|
5064
5225
|
}
|
|
5065
5226
|
),
|
|
5066
|
-
type !== "stream" && /* @__PURE__ */
|
|
5227
|
+
type !== "stream" && /* @__PURE__ */ jsx33(
|
|
5067
5228
|
"td",
|
|
5068
5229
|
{
|
|
5069
|
-
|
|
5070
|
-
className: "px-3",
|
|
5230
|
+
className: "w-0 min-w-0 p-0",
|
|
5071
5231
|
onClick: (e) => {
|
|
5072
5232
|
e.stopPropagation();
|
|
5073
5233
|
},
|
|
5074
|
-
children: /* @__PURE__ */
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5234
|
+
children: /* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-end gap-2", children: [
|
|
5235
|
+
type === "hash" && /* @__PURE__ */ jsx33(HashFieldTTLInfo, { dataKey, field: key, fields }),
|
|
5236
|
+
/* @__PURE__ */ jsx33(
|
|
5237
|
+
DeleteAlertDialog,
|
|
5238
|
+
{
|
|
5239
|
+
deletionType: "item",
|
|
5240
|
+
onDeleteConfirm: (e) => {
|
|
5241
|
+
e.stopPropagation();
|
|
5242
|
+
editItem({
|
|
5243
|
+
type,
|
|
5244
|
+
dataKey,
|
|
5245
|
+
itemKey: key,
|
|
5246
|
+
// For deletion
|
|
5247
|
+
newKey: void 0
|
|
5248
|
+
});
|
|
5249
|
+
},
|
|
5250
|
+
children: /* @__PURE__ */ jsx33(
|
|
5251
|
+
Button,
|
|
5252
|
+
{
|
|
5253
|
+
className: "",
|
|
5254
|
+
size: "icon-sm",
|
|
5255
|
+
variant: "secondary",
|
|
5256
|
+
onClick: (e) => e.stopPropagation(),
|
|
5257
|
+
children: /* @__PURE__ */ jsx33(IconTrash, { className: "size-4 text-zinc-500" })
|
|
5258
|
+
}
|
|
5259
|
+
)
|
|
5260
|
+
}
|
|
5261
|
+
)
|
|
5262
|
+
] })
|
|
5091
5263
|
}
|
|
5092
5264
|
)
|
|
5093
5265
|
]
|
|
@@ -5099,16 +5271,16 @@ var ListItems = ({
|
|
|
5099
5271
|
// src/components/databrowser/components/display/display-simple.tsx
|
|
5100
5272
|
import { useEffect as useEffect9 } from "react";
|
|
5101
5273
|
import { useForm as useForm3 } from "react-hook-form";
|
|
5102
|
-
import { Fragment as Fragment6, jsx as
|
|
5274
|
+
import { Fragment as Fragment6, jsx as jsx34, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
5103
5275
|
var EditorDisplay = ({ dataKey, type }) => {
|
|
5104
5276
|
const { data } = useFetchSimpleKey(dataKey, type);
|
|
5105
|
-
return /* @__PURE__ */
|
|
5106
|
-
/* @__PURE__ */
|
|
5107
|
-
/* @__PURE__ */
|
|
5277
|
+
return /* @__PURE__ */ jsxs22("div", { className: "flex h-full w-full flex-col gap-2", children: [
|
|
5278
|
+
/* @__PURE__ */ jsx34(DisplayHeader, { dataKey, type, content: data ?? void 0 }),
|
|
5279
|
+
/* @__PURE__ */ jsx34(
|
|
5108
5280
|
"div",
|
|
5109
5281
|
{
|
|
5110
5282
|
className: "flex h-full grow flex-col gap-2\n rounded-md bg-zinc-100 p-3",
|
|
5111
|
-
children: data === void 0 ? /* @__PURE__ */
|
|
5283
|
+
children: data === void 0 ? /* @__PURE__ */ jsx34(Spinner, { isLoadingText: "", isLoading: true }) : data === null ? /* @__PURE__ */ jsx34(Fragment6, {}) : /* @__PURE__ */ jsx34(EditorDisplayForm, { dataKey, type, data }, dataKey)
|
|
5112
5284
|
}
|
|
5113
5285
|
)
|
|
5114
5286
|
] });
|
|
@@ -5122,26 +5294,21 @@ var EditorDisplayForm = ({
|
|
|
5122
5294
|
defaultValues: { value: data }
|
|
5123
5295
|
});
|
|
5124
5296
|
useEffect9(() => {
|
|
5125
|
-
form.reset(
|
|
5126
|
-
{ value: data },
|
|
5127
|
-
{
|
|
5128
|
-
keepValues: false
|
|
5129
|
-
}
|
|
5130
|
-
);
|
|
5297
|
+
form.reset({ value: data });
|
|
5131
5298
|
}, [data]);
|
|
5132
5299
|
const { editor, selector } = useField({ name: "value", form, data });
|
|
5133
5300
|
const { mutateAsync: setKey, isPending: isSettingKey } = useSetSimpleKey(dataKey, type);
|
|
5134
5301
|
const handleCancel = () => {
|
|
5135
|
-
form.reset();
|
|
5302
|
+
form.reset({ value: data });
|
|
5136
5303
|
};
|
|
5137
|
-
return /* @__PURE__ */
|
|
5138
|
-
/* @__PURE__ */
|
|
5139
|
-
/* @__PURE__ */
|
|
5140
|
-
/* @__PURE__ */
|
|
5304
|
+
return /* @__PURE__ */ jsxs22(Fragment6, { children: [
|
|
5305
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex grow flex-col gap-1", children: [
|
|
5306
|
+
/* @__PURE__ */ jsx34("div", { className: "flex shrink-0 items-center gap-2", children: type === "json" ? /* @__PURE__ */ jsx34("div", {}) : selector }),
|
|
5307
|
+
/* @__PURE__ */ jsx34("div", { className: "grow rounded-md border border-zinc-300 bg-white p-1", children: editor })
|
|
5141
5308
|
] }),
|
|
5142
|
-
/* @__PURE__ */
|
|
5143
|
-
form.formState.isDirty && /* @__PURE__ */
|
|
5144
|
-
/* @__PURE__ */
|
|
5309
|
+
/* @__PURE__ */ jsx34("div", { className: "flex shrink-0 items-center gap-2", children: /* @__PURE__ */ jsxs22("div", { className: "ml-auto flex gap-2", children: [
|
|
5310
|
+
form.formState.isDirty && /* @__PURE__ */ jsx34(Button, { onClick: handleCancel, children: "Cancel" }),
|
|
5311
|
+
/* @__PURE__ */ jsx34(
|
|
5145
5312
|
Button,
|
|
5146
5313
|
{
|
|
5147
5314
|
variant: "primary",
|
|
@@ -5149,7 +5316,7 @@ var EditorDisplayForm = ({
|
|
|
5149
5316
|
await setKey(value);
|
|
5150
5317
|
}),
|
|
5151
5318
|
disabled: !form.formState.isValid || !form.formState.isDirty,
|
|
5152
|
-
children: /* @__PURE__ */
|
|
5319
|
+
children: /* @__PURE__ */ jsx34(Spinner, { isLoading: isSettingKey, isLoadingText: "Saving", children: "Save" })
|
|
5153
5320
|
}
|
|
5154
5321
|
)
|
|
5155
5322
|
] }) })
|
|
@@ -5157,19 +5324,19 @@ var EditorDisplayForm = ({
|
|
|
5157
5324
|
};
|
|
5158
5325
|
|
|
5159
5326
|
// src/components/databrowser/components/display/index.tsx
|
|
5160
|
-
import { Fragment as Fragment7, jsx as
|
|
5327
|
+
import { Fragment as Fragment7, jsx as jsx35 } from "react/jsx-runtime";
|
|
5161
5328
|
var DataDisplay = () => {
|
|
5162
5329
|
const { selectedKey } = useDatabrowserStore();
|
|
5163
5330
|
const { query } = useKeys();
|
|
5164
5331
|
const type = useKeyType(selectedKey);
|
|
5165
|
-
return /* @__PURE__ */
|
|
5332
|
+
return /* @__PURE__ */ jsx35("div", { className: "h-full rounded-xl border bg-white p-1", children: !selectedKey ? /* @__PURE__ */ jsx35("div", {}) : !type ? query.isLoading ? /* @__PURE__ */ jsx35("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx35("span", { className: "text-gray-500", children: "Loading..." }) }) : /* @__PURE__ */ jsx35("div", {}) : /* @__PURE__ */ jsx35(Fragment7, { children: type === "string" || type === "json" ? /* @__PURE__ */ jsx35(EditorDisplay, { dataKey: selectedKey, type }) : /* @__PURE__ */ jsx35(ListDisplay, { dataKey: selectedKey, type }) }) });
|
|
5166
5333
|
};
|
|
5167
5334
|
|
|
5168
5335
|
// src/components/databrowser/components/sidebar/index.tsx
|
|
5169
5336
|
import { IconRefresh } from "@tabler/icons-react";
|
|
5170
5337
|
|
|
5171
5338
|
// src/components/databrowser/components/add-key-modal.tsx
|
|
5172
|
-
import { useState as
|
|
5339
|
+
import { useState as useState10 } from "react";
|
|
5173
5340
|
import { DialogDescription as DialogDescription2 } from "@radix-ui/react-dialog";
|
|
5174
5341
|
import { PlusIcon } from "@radix-ui/react-icons";
|
|
5175
5342
|
import { Controller as Controller3, useForm as useForm4 } from "react-hook-form";
|
|
@@ -5177,12 +5344,12 @@ import { Controller as Controller3, useForm as useForm4 } from "react-hook-form"
|
|
|
5177
5344
|
// src/components/ui/dialog.tsx
|
|
5178
5345
|
import * as React12 from "react";
|
|
5179
5346
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
5180
|
-
import { jsx as
|
|
5347
|
+
import { jsx as jsx36, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
5181
5348
|
var Dialog = DialogPrimitive.Root;
|
|
5182
5349
|
var DialogTrigger = DialogPrimitive.Trigger;
|
|
5183
|
-
var DialogPortal = (props) => /* @__PURE__ */
|
|
5350
|
+
var DialogPortal = (props) => /* @__PURE__ */ jsx36(DialogPrimitive.Portal, { container: portalRoot, ...props });
|
|
5184
5351
|
DialogPortal.displayName = DialogPrimitive.Portal.displayName;
|
|
5185
|
-
var DialogOverlay = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5352
|
+
var DialogOverlay = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx36(
|
|
5186
5353
|
DialogPrimitive.Overlay,
|
|
5187
5354
|
{
|
|
5188
5355
|
ref,
|
|
@@ -5196,9 +5363,9 @@ var DialogOverlay = React12.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
5196
5363
|
}
|
|
5197
5364
|
));
|
|
5198
5365
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
5199
|
-
var DialogContent = React12.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */
|
|
5200
|
-
/* @__PURE__ */
|
|
5201
|
-
/* @__PURE__ */
|
|
5366
|
+
var DialogContent = React12.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs23(DialogPortal, { children: [
|
|
5367
|
+
/* @__PURE__ */ jsx36(DialogOverlay, {}),
|
|
5368
|
+
/* @__PURE__ */ jsxs23(
|
|
5202
5369
|
DialogPrimitive.Content,
|
|
5203
5370
|
{
|
|
5204
5371
|
ref,
|
|
@@ -5218,8 +5385,8 @@ var DialogContent = React12.forwardRef(({ className, children, ...props }, ref)
|
|
|
5218
5385
|
...props,
|
|
5219
5386
|
children: [
|
|
5220
5387
|
children,
|
|
5221
|
-
/* @__PURE__ */
|
|
5222
|
-
/* @__PURE__ */
|
|
5388
|
+
/* @__PURE__ */ jsxs23(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-zinc-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-zinc-100 data-[state=open]:text-zinc-500 dark:ring-offset-zinc-950 dark:focus:ring-zinc-300 dark:data-[state=open]:bg-zinc-800 dark:data-[state=open]:text-zinc-400", children: [
|
|
5389
|
+
/* @__PURE__ */ jsx36(
|
|
5223
5390
|
"svg",
|
|
5224
5391
|
{
|
|
5225
5392
|
width: "15",
|
|
@@ -5228,7 +5395,7 @@ var DialogContent = React12.forwardRef(({ className, children, ...props }, ref)
|
|
|
5228
5395
|
fill: "none",
|
|
5229
5396
|
xmlns: "http://www.w3.org/2000/svg",
|
|
5230
5397
|
className: "h-4 w-4",
|
|
5231
|
-
children: /* @__PURE__ */
|
|
5398
|
+
children: /* @__PURE__ */ jsx36(
|
|
5232
5399
|
"path",
|
|
5233
5400
|
{
|
|
5234
5401
|
d: "M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z",
|
|
@@ -5239,16 +5406,16 @@ var DialogContent = React12.forwardRef(({ className, children, ...props }, ref)
|
|
|
5239
5406
|
)
|
|
5240
5407
|
}
|
|
5241
5408
|
),
|
|
5242
|
-
/* @__PURE__ */
|
|
5409
|
+
/* @__PURE__ */ jsx36("span", { className: "sr-only", children: "Close" })
|
|
5243
5410
|
] })
|
|
5244
5411
|
]
|
|
5245
5412
|
}
|
|
5246
5413
|
)
|
|
5247
5414
|
] }));
|
|
5248
5415
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
5249
|
-
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */
|
|
5416
|
+
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx36("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
|
|
5250
5417
|
DialogHeader.displayName = "DialogHeader";
|
|
5251
|
-
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */
|
|
5418
|
+
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx36(
|
|
5252
5419
|
"div",
|
|
5253
5420
|
{
|
|
5254
5421
|
className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
|
|
@@ -5256,7 +5423,7 @@ var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx33(
|
|
|
5256
5423
|
}
|
|
5257
5424
|
);
|
|
5258
5425
|
DialogFooter.displayName = "DialogFooter";
|
|
5259
|
-
var DialogTitle = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5426
|
+
var DialogTitle = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx36(
|
|
5260
5427
|
DialogPrimitive.Title,
|
|
5261
5428
|
{
|
|
5262
5429
|
ref,
|
|
@@ -5265,7 +5432,7 @@ var DialogTitle = React12.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
5265
5432
|
}
|
|
5266
5433
|
));
|
|
5267
5434
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
5268
|
-
var DialogDescription = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5435
|
+
var DialogDescription = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx36(
|
|
5269
5436
|
DialogPrimitive.Description,
|
|
5270
5437
|
{
|
|
5271
5438
|
ref,
|
|
@@ -5276,10 +5443,10 @@ var DialogDescription = React12.forwardRef(({ className, ...props }, ref) => /*
|
|
|
5276
5443
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
5277
5444
|
|
|
5278
5445
|
// src/components/databrowser/components/add-key-modal.tsx
|
|
5279
|
-
import { jsx as
|
|
5446
|
+
import { jsx as jsx37, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5280
5447
|
function AddKeyModal() {
|
|
5281
5448
|
const { setSelectedKey } = useDatabrowserStore();
|
|
5282
|
-
const [open, setOpen] =
|
|
5449
|
+
const [open, setOpen] = useState10(false);
|
|
5283
5450
|
const { mutateAsync: addKey, isPending } = useAddKey();
|
|
5284
5451
|
const { control, handleSubmit, formState, reset } = useForm4({
|
|
5285
5452
|
defaultValues: {
|
|
@@ -5299,7 +5466,7 @@ function AddKeyModal() {
|
|
|
5299
5466
|
});
|
|
5300
5467
|
}, 100);
|
|
5301
5468
|
});
|
|
5302
|
-
return /* @__PURE__ */
|
|
5469
|
+
return /* @__PURE__ */ jsxs24(
|
|
5303
5470
|
Dialog,
|
|
5304
5471
|
{
|
|
5305
5472
|
open,
|
|
@@ -5308,24 +5475,24 @@ function AddKeyModal() {
|
|
|
5308
5475
|
setOpen(open2);
|
|
5309
5476
|
},
|
|
5310
5477
|
children: [
|
|
5311
|
-
/* @__PURE__ */
|
|
5312
|
-
/* @__PURE__ */
|
|
5313
|
-
/* @__PURE__ */
|
|
5314
|
-
/* @__PURE__ */
|
|
5315
|
-
/* @__PURE__ */
|
|
5316
|
-
/* @__PURE__ */
|
|
5317
|
-
/* @__PURE__ */
|
|
5478
|
+
/* @__PURE__ */ jsx37(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsx37(Button, { variant: "primary", size: "icon-sm", children: /* @__PURE__ */ jsx37(PlusIcon, { className: "size-4" }) }) }),
|
|
5479
|
+
/* @__PURE__ */ jsxs24(DialogContent, { className: "max-w-[400px]", children: [
|
|
5480
|
+
/* @__PURE__ */ jsx37(DialogHeader, { children: /* @__PURE__ */ jsx37(DialogTitle, { children: "Create new key" }) }),
|
|
5481
|
+
/* @__PURE__ */ jsx37("div", { className: "sr-only", children: /* @__PURE__ */ jsx37(DialogDescription2, { children: "Create new key" }) }),
|
|
5482
|
+
/* @__PURE__ */ jsxs24("form", { className: "mt-4", onSubmit, children: [
|
|
5483
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-1", children: [
|
|
5484
|
+
/* @__PURE__ */ jsx37(
|
|
5318
5485
|
Controller3,
|
|
5319
5486
|
{
|
|
5320
5487
|
control,
|
|
5321
5488
|
name: "type",
|
|
5322
|
-
render: ({ field }) => /* @__PURE__ */
|
|
5323
|
-
/* @__PURE__ */
|
|
5324
|
-
/* @__PURE__ */
|
|
5489
|
+
render: ({ field }) => /* @__PURE__ */ jsxs24(Select, { value: field.value, onValueChange: field.onChange, children: [
|
|
5490
|
+
/* @__PURE__ */ jsx37(SelectTrigger, { className: "h-8 w-auto pl-[3px] pr-8", children: /* @__PURE__ */ jsx37(SelectValue, {}) }),
|
|
5491
|
+
/* @__PURE__ */ jsx37(SelectContent, { children: /* @__PURE__ */ jsx37(SelectGroup, { children: DATA_TYPES.map((type) => /* @__PURE__ */ jsx37(SelectItem, { value: type, children: /* @__PURE__ */ jsx37(TypeTag, { variant: type, type: "badge" }) }, type)) }) })
|
|
5325
5492
|
] })
|
|
5326
5493
|
}
|
|
5327
5494
|
),
|
|
5328
|
-
/* @__PURE__ */
|
|
5495
|
+
/* @__PURE__ */ jsx37(
|
|
5329
5496
|
Controller3,
|
|
5330
5497
|
{
|
|
5331
5498
|
rules: {
|
|
@@ -5333,14 +5500,14 @@ function AddKeyModal() {
|
|
|
5333
5500
|
},
|
|
5334
5501
|
control,
|
|
5335
5502
|
name: "key",
|
|
5336
|
-
render: ({ field }) => /* @__PURE__ */
|
|
5503
|
+
render: ({ field }) => /* @__PURE__ */ jsx37(Input, { placeholder: "mykey", ...field, className: "h-8 grow" })
|
|
5337
5504
|
}
|
|
5338
5505
|
)
|
|
5339
5506
|
] }),
|
|
5340
|
-
formState.errors.key && /* @__PURE__ */
|
|
5341
|
-
/* @__PURE__ */
|
|
5342
|
-
/* @__PURE__ */
|
|
5343
|
-
/* @__PURE__ */
|
|
5507
|
+
formState.errors.key && /* @__PURE__ */ jsx37("p", { className: "mb-3 mt-2 text-xs text-red-500", children: formState.errors.key?.message }),
|
|
5508
|
+
/* @__PURE__ */ jsx37("p", { className: "mt-2 text-xs text-zinc-500", children: "After creating the key, you can edit the value" }),
|
|
5509
|
+
/* @__PURE__ */ jsxs24("div", { className: "mt-6 flex justify-end gap-2", children: [
|
|
5510
|
+
/* @__PURE__ */ jsx37(
|
|
5344
5511
|
Button,
|
|
5345
5512
|
{
|
|
5346
5513
|
type: "button",
|
|
@@ -5351,7 +5518,7 @@ function AddKeyModal() {
|
|
|
5351
5518
|
children: "Cancel"
|
|
5352
5519
|
}
|
|
5353
5520
|
),
|
|
5354
|
-
/* @__PURE__ */
|
|
5521
|
+
/* @__PURE__ */ jsx37(Button, { variant: "primary", type: "submit", children: /* @__PURE__ */ jsx37(Spinner, { isLoading: isPending, isLoadingText: "Creating", children: "Create" }) })
|
|
5355
5522
|
] })
|
|
5356
5523
|
] })
|
|
5357
5524
|
] })
|
|
@@ -5361,24 +5528,24 @@ function AddKeyModal() {
|
|
|
5361
5528
|
}
|
|
5362
5529
|
|
|
5363
5530
|
// src/components/databrowser/components/sidebar/empty.tsx
|
|
5364
|
-
import { jsx as
|
|
5531
|
+
import { jsx as jsx38, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
5365
5532
|
var Empty = () => {
|
|
5366
|
-
return /* @__PURE__ */
|
|
5367
|
-
/* @__PURE__ */
|
|
5368
|
-
/* @__PURE__ */
|
|
5533
|
+
return /* @__PURE__ */ jsx38("div", { className: "flex h-full w-full items-center justify-center rounded-md border border-dashed px-4 py-6 text-center", children: /* @__PURE__ */ jsxs25("div", { className: "space-y-5", children: [
|
|
5534
|
+
/* @__PURE__ */ jsx38("p", { className: "text-md font-medium", children: "Data on a break" }),
|
|
5535
|
+
/* @__PURE__ */ jsx38("p", { className: "text-balance text-center", children: '"Quick, lure it back with some CLI magic!"' })
|
|
5369
5536
|
] }) });
|
|
5370
5537
|
};
|
|
5371
5538
|
|
|
5372
5539
|
// src/components/databrowser/components/sidebar-context-menu.tsx
|
|
5373
|
-
import { useState as
|
|
5540
|
+
import { useState as useState11 } from "react";
|
|
5374
5541
|
import { ContextMenuSeparator as ContextMenuSeparator3 } from "@radix-ui/react-context-menu";
|
|
5375
|
-
import { Fragment as Fragment8, jsx as
|
|
5542
|
+
import { Fragment as Fragment8, jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
5376
5543
|
var SidebarContextMenu = ({ children }) => {
|
|
5377
5544
|
const { mutate: deleteKey } = useDeleteKey();
|
|
5378
|
-
const [isAlertOpen, setAlertOpen] =
|
|
5379
|
-
const [dataKey, setDataKey] =
|
|
5380
|
-
return /* @__PURE__ */
|
|
5381
|
-
/* @__PURE__ */
|
|
5545
|
+
const [isAlertOpen, setAlertOpen] = useState11(false);
|
|
5546
|
+
const [dataKey, setDataKey] = useState11("");
|
|
5547
|
+
return /* @__PURE__ */ jsxs26(Fragment8, { children: [
|
|
5548
|
+
/* @__PURE__ */ jsx39(
|
|
5382
5549
|
DeleteAlertDialog,
|
|
5383
5550
|
{
|
|
5384
5551
|
deletionType: "key",
|
|
@@ -5391,8 +5558,8 @@ var SidebarContextMenu = ({ children }) => {
|
|
|
5391
5558
|
}
|
|
5392
5559
|
}
|
|
5393
5560
|
),
|
|
5394
|
-
/* @__PURE__ */
|
|
5395
|
-
/* @__PURE__ */
|
|
5561
|
+
/* @__PURE__ */ jsxs26(ContextMenu, { children: [
|
|
5562
|
+
/* @__PURE__ */ jsx39(
|
|
5396
5563
|
ContextMenuTrigger,
|
|
5397
5564
|
{
|
|
5398
5565
|
onContextMenu: (e) => {
|
|
@@ -5407,8 +5574,8 @@ var SidebarContextMenu = ({ children }) => {
|
|
|
5407
5574
|
children
|
|
5408
5575
|
}
|
|
5409
5576
|
),
|
|
5410
|
-
/* @__PURE__ */
|
|
5411
|
-
/* @__PURE__ */
|
|
5577
|
+
/* @__PURE__ */ jsxs26(ContextMenuContent, { children: [
|
|
5578
|
+
/* @__PURE__ */ jsx39(
|
|
5412
5579
|
ContextMenuItem,
|
|
5413
5580
|
{
|
|
5414
5581
|
onClick: () => {
|
|
@@ -5420,18 +5587,18 @@ var SidebarContextMenu = ({ children }) => {
|
|
|
5420
5587
|
children: "Copy key"
|
|
5421
5588
|
}
|
|
5422
5589
|
),
|
|
5423
|
-
/* @__PURE__ */
|
|
5424
|
-
/* @__PURE__ */
|
|
5590
|
+
/* @__PURE__ */ jsx39(ContextMenuSeparator3, {}),
|
|
5591
|
+
/* @__PURE__ */ jsx39(ContextMenuItem, { onClick: () => setAlertOpen(true), children: "Delete key" })
|
|
5425
5592
|
] })
|
|
5426
5593
|
] })
|
|
5427
5594
|
] });
|
|
5428
5595
|
};
|
|
5429
5596
|
|
|
5430
5597
|
// src/components/databrowser/components/sidebar/keys-list.tsx
|
|
5431
|
-
import { Fragment as Fragment9, jsx as
|
|
5598
|
+
import { Fragment as Fragment9, jsx as jsx40, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
5432
5599
|
var KeysList = () => {
|
|
5433
5600
|
const { keys } = useKeys();
|
|
5434
|
-
return /* @__PURE__ */
|
|
5601
|
+
return /* @__PURE__ */ jsx40("div", { className: "pr-3", children: /* @__PURE__ */ jsx40(SidebarContextMenu, { children: /* @__PURE__ */ jsx40(Fragment9, { children: keys.map((data, i) => /* @__PURE__ */ jsx40(KeyItem, { nextKey: keys.at(i + 1)?.[0] ?? "", data }, data[0])) }) }) });
|
|
5435
5602
|
};
|
|
5436
5603
|
var keyStyles = {
|
|
5437
5604
|
string: "border-sky-400 !bg-sky-50 text-sky-900",
|
|
@@ -5447,7 +5614,7 @@ var KeyItem = ({ data, nextKey }) => {
|
|
|
5447
5614
|
const [dataKey, dataType] = data;
|
|
5448
5615
|
const isKeySelected = selectedKey === dataKey;
|
|
5449
5616
|
const isNextKeySelected = selectedKey === nextKey;
|
|
5450
|
-
return /* @__PURE__ */
|
|
5617
|
+
return /* @__PURE__ */ jsxs27(
|
|
5451
5618
|
Button,
|
|
5452
5619
|
{
|
|
5453
5620
|
"data-key": dataKey,
|
|
@@ -5460,28 +5627,28 @@ var KeyItem = ({ data, nextKey }) => {
|
|
|
5460
5627
|
),
|
|
5461
5628
|
onClick: () => setSelectedKey(dataKey),
|
|
5462
5629
|
children: [
|
|
5463
|
-
/* @__PURE__ */
|
|
5464
|
-
/* @__PURE__ */
|
|
5465
|
-
!isKeySelected && !isNextKeySelected && /* @__PURE__ */
|
|
5630
|
+
/* @__PURE__ */ jsx40(TypeTag, { variant: dataType, type: "icon" }),
|
|
5631
|
+
/* @__PURE__ */ jsx40("p", { className: "truncate whitespace-nowrap", children: dataKey }),
|
|
5632
|
+
!isKeySelected && !isNextKeySelected && /* @__PURE__ */ jsx40("span", { className: "absolute -bottom-px left-3 right-3 h-px bg-zinc-100" })
|
|
5466
5633
|
]
|
|
5467
5634
|
}
|
|
5468
5635
|
);
|
|
5469
5636
|
};
|
|
5470
5637
|
|
|
5471
5638
|
// src/components/databrowser/components/sidebar/search-input.tsx
|
|
5472
|
-
import { useState as
|
|
5639
|
+
import { useState as useState12 } from "react";
|
|
5473
5640
|
import { IconX } from "@tabler/icons-react";
|
|
5474
|
-
import { jsx as
|
|
5641
|
+
import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
5475
5642
|
var SearchInput = () => {
|
|
5476
5643
|
const { setSearchKey, search } = useDatabrowserStore();
|
|
5477
|
-
const [state, setState] =
|
|
5644
|
+
const [state, setState] = useState12(search.key);
|
|
5478
5645
|
const submit = (value) => {
|
|
5479
5646
|
if (value.trim() !== "" && !value.includes("*")) value = `${value}*`;
|
|
5480
5647
|
setSearchKey(value);
|
|
5481
5648
|
setState(value);
|
|
5482
5649
|
};
|
|
5483
|
-
return /* @__PURE__ */
|
|
5484
|
-
/* @__PURE__ */
|
|
5650
|
+
return /* @__PURE__ */ jsxs28("div", { className: "relative grow", children: [
|
|
5651
|
+
/* @__PURE__ */ jsx41(
|
|
5485
5652
|
Input,
|
|
5486
5653
|
{
|
|
5487
5654
|
placeholder: "Search",
|
|
@@ -5496,7 +5663,7 @@ var SearchInput = () => {
|
|
|
5496
5663
|
value: state
|
|
5497
5664
|
}
|
|
5498
5665
|
),
|
|
5499
|
-
|
|
5666
|
+
state && /* @__PURE__ */ jsxs28(
|
|
5500
5667
|
Button,
|
|
5501
5668
|
{
|
|
5502
5669
|
type: "button",
|
|
@@ -5505,10 +5672,11 @@ var SearchInput = () => {
|
|
|
5505
5672
|
className: "absolute right-1 top-1/2 h-5 w-5 -translate-y-1/2 text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-100",
|
|
5506
5673
|
onClick: () => {
|
|
5507
5674
|
setSearchKey("");
|
|
5675
|
+
setState("");
|
|
5508
5676
|
},
|
|
5509
5677
|
children: [
|
|
5510
|
-
/* @__PURE__ */
|
|
5511
|
-
/* @__PURE__ */
|
|
5678
|
+
/* @__PURE__ */ jsx41(IconX, { size: 16 }),
|
|
5679
|
+
/* @__PURE__ */ jsx41("span", { className: "sr-only", children: "Clear" })
|
|
5512
5680
|
]
|
|
5513
5681
|
}
|
|
5514
5682
|
)
|
|
@@ -5516,19 +5684,19 @@ var SearchInput = () => {
|
|
|
5516
5684
|
};
|
|
5517
5685
|
|
|
5518
5686
|
// src/components/databrowser/components/sidebar/skeleton-buttons.tsx
|
|
5519
|
-
import { jsx as
|
|
5687
|
+
import { jsx as jsx42, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
5520
5688
|
var DEFAULT_SKELETON_COUNT = 6;
|
|
5521
|
-
var LoadingSkeleton = () => /* @__PURE__ */
|
|
5522
|
-
/* @__PURE__ */
|
|
5523
|
-
/* @__PURE__ */
|
|
5689
|
+
var LoadingSkeleton = () => /* @__PURE__ */ jsx42("div", { className: "grid", children: Array.from({ length: DEFAULT_SKELETON_COUNT }).fill(0).map((_, idx) => /* @__PURE__ */ jsxs29("div", { className: "flex h-10 items-center gap-2 px-3", children: [
|
|
5690
|
+
/* @__PURE__ */ jsx42(Skeleton, { className: "size-5 shrink-0 rounded" }),
|
|
5691
|
+
/* @__PURE__ */ jsx42(Skeleton, { className: "h-4 grow rounded" })
|
|
5524
5692
|
] }, idx)) });
|
|
5525
5693
|
|
|
5526
5694
|
// src/components/databrowser/components/sidebar/type-selector.tsx
|
|
5527
|
-
import { jsx as
|
|
5695
|
+
import { jsx as jsx43, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
5528
5696
|
var ALL_TYPES_KEY = "all";
|
|
5529
5697
|
function DataTypeSelector() {
|
|
5530
5698
|
const { search, setSearchType } = useDatabrowserStore();
|
|
5531
|
-
return /* @__PURE__ */
|
|
5699
|
+
return /* @__PURE__ */ jsxs30(
|
|
5532
5700
|
Select,
|
|
5533
5701
|
{
|
|
5534
5702
|
onValueChange: (type) => {
|
|
@@ -5540,9 +5708,9 @@ function DataTypeSelector() {
|
|
|
5540
5708
|
},
|
|
5541
5709
|
value: search.type === void 0 ? ALL_TYPES_KEY : search.type,
|
|
5542
5710
|
children: [
|
|
5543
|
-
/* @__PURE__ */
|
|
5544
|
-
/* @__PURE__ */
|
|
5545
|
-
([key, value]) => /* @__PURE__ */
|
|
5711
|
+
/* @__PURE__ */ jsx43(SelectTrigger, { className: "!w-auto select-none whitespace-nowrap rounded-r-none border-r-0 border-zinc-300 pr-8", children: /* @__PURE__ */ jsx43(SelectValue, {}) }),
|
|
5712
|
+
/* @__PURE__ */ jsx43(SelectContent, { children: /* @__PURE__ */ jsx43(SelectGroup, { children: [[ALL_TYPES_KEY, "All Types"], ...Object.entries(DATA_TYPE_NAMES)].map(
|
|
5713
|
+
([key, value]) => /* @__PURE__ */ jsx43(SelectItem, { value: key, children: value }, key)
|
|
5546
5714
|
) }) })
|
|
5547
5715
|
]
|
|
5548
5716
|
}
|
|
@@ -5550,15 +5718,15 @@ function DataTypeSelector() {
|
|
|
5550
5718
|
}
|
|
5551
5719
|
|
|
5552
5720
|
// src/components/databrowser/components/sidebar/index.tsx
|
|
5553
|
-
import { jsx as
|
|
5721
|
+
import { jsx as jsx44, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
5554
5722
|
function Sidebar() {
|
|
5555
5723
|
const { keys, query, refetch } = useKeys();
|
|
5556
|
-
return /* @__PURE__ */
|
|
5557
|
-
/* @__PURE__ */
|
|
5558
|
-
/* @__PURE__ */
|
|
5559
|
-
/* @__PURE__ */
|
|
5560
|
-
/* @__PURE__ */
|
|
5561
|
-
/* @__PURE__ */
|
|
5724
|
+
return /* @__PURE__ */ jsxs31("div", { className: "flex h-full flex-col gap-2 rounded-xl border bg-white p-1", children: [
|
|
5725
|
+
/* @__PURE__ */ jsxs31("div", { className: "rounded-lg bg-zinc-100 px-3 py-2", children: [
|
|
5726
|
+
/* @__PURE__ */ jsxs31("div", { className: "flex h-10 items-center justify-between pl-1", children: [
|
|
5727
|
+
/* @__PURE__ */ jsx44(DisplayDbSize, {}),
|
|
5728
|
+
/* @__PURE__ */ jsxs31("div", { className: "flex gap-1", children: [
|
|
5729
|
+
/* @__PURE__ */ jsx44(
|
|
5562
5730
|
Button,
|
|
5563
5731
|
{
|
|
5564
5732
|
className: "h-7 w-7 px-0",
|
|
@@ -5573,39 +5741,45 @@ function Sidebar() {
|
|
|
5573
5741
|
queryClient.invalidateQueries({
|
|
5574
5742
|
queryKey: [FETCH_DB_SIZE_QUERY_KEY]
|
|
5575
5743
|
});
|
|
5744
|
+
queryClient.invalidateQueries({
|
|
5745
|
+
queryKey: [FETCH_KEY_TYPE_QUERY_KEY]
|
|
5746
|
+
});
|
|
5576
5747
|
},
|
|
5577
|
-
children: /* @__PURE__ */
|
|
5748
|
+
children: /* @__PURE__ */ jsx44(Spinner, { isLoading: query.isFetching, children: /* @__PURE__ */ jsx44(IconRefresh, { size: 16 }) })
|
|
5578
5749
|
}
|
|
5579
5750
|
),
|
|
5580
|
-
/* @__PURE__ */
|
|
5751
|
+
/* @__PURE__ */ jsx44(AddKeyModal, {})
|
|
5581
5752
|
] })
|
|
5582
5753
|
] }),
|
|
5583
|
-
/* @__PURE__ */
|
|
5584
|
-
/* @__PURE__ */
|
|
5585
|
-
/* @__PURE__ */
|
|
5754
|
+
/* @__PURE__ */ jsxs31("div", { className: "flex h-10 items-center", children: [
|
|
5755
|
+
/* @__PURE__ */ jsx44(DataTypeSelector, {}),
|
|
5756
|
+
/* @__PURE__ */ jsx44(SearchInput, {})
|
|
5586
5757
|
] })
|
|
5587
5758
|
] }),
|
|
5588
|
-
query.isLoading ? /* @__PURE__ */
|
|
5759
|
+
query.isLoading && keys.length === 0 ? /* @__PURE__ */ jsx44(LoadingSkeleton, {}) : keys.length > 0 ? (
|
|
5760
|
+
// Infinite scroll already has a loader at the bottom
|
|
5761
|
+
/* @__PURE__ */ jsx44(InfiniteScroll, { query, children: /* @__PURE__ */ jsx44(KeysList, {}) })
|
|
5762
|
+
) : /* @__PURE__ */ jsx44(Empty, {})
|
|
5589
5763
|
] });
|
|
5590
5764
|
}
|
|
5591
5765
|
|
|
5592
5766
|
// src/components/databrowser/index.tsx
|
|
5593
|
-
import { jsx as
|
|
5767
|
+
import { jsx as jsx45, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
5594
5768
|
var RedisBrowser = ({ token, url }) => {
|
|
5595
5769
|
const credentials = useMemo6(() => ({ token, url }), [token, url]);
|
|
5596
5770
|
useEffect10(() => {
|
|
5597
5771
|
queryClient.resetQueries();
|
|
5598
5772
|
}, [credentials.url]);
|
|
5599
|
-
return /* @__PURE__ */
|
|
5600
|
-
/* @__PURE__ */
|
|
5773
|
+
return /* @__PURE__ */ jsx45(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx45(TooltipProvider, { children: /* @__PURE__ */ jsx45(DatabrowserProvider, { redisCredentials: credentials, children: /* @__PURE__ */ jsx45(KeysProvider, { children: /* @__PURE__ */ jsxs32("div", { className: "ups-db", style: { height: "100%" }, children: [
|
|
5774
|
+
/* @__PURE__ */ jsxs32(
|
|
5601
5775
|
PanelGroup,
|
|
5602
5776
|
{
|
|
5603
5777
|
autoSaveId: "persistence",
|
|
5604
5778
|
direction: "horizontal",
|
|
5605
5779
|
className: "h-full w-full gap-0.5 text-sm antialiased",
|
|
5606
5780
|
children: [
|
|
5607
|
-
/* @__PURE__ */
|
|
5608
|
-
/* @__PURE__ */
|
|
5781
|
+
/* @__PURE__ */ jsx45(Panel, { defaultSize: 30, minSize: 30, children: /* @__PURE__ */ jsx45(Sidebar, {}) }),
|
|
5782
|
+
/* @__PURE__ */ jsx45(PanelResizeHandle, { className: "h-fullm flex w-1.5 items-center justify-center rounded-full hover:bg-zinc-300/20", children: /* @__PURE__ */ jsx45(
|
|
5609
5783
|
IconDotsVertical2,
|
|
5610
5784
|
{
|
|
5611
5785
|
size: 16,
|
|
@@ -5613,11 +5787,11 @@ var RedisBrowser = ({ token, url }) => {
|
|
|
5613
5787
|
className: "pointer-events-none shrink-0 opacity-20"
|
|
5614
5788
|
}
|
|
5615
5789
|
) }),
|
|
5616
|
-
/* @__PURE__ */
|
|
5790
|
+
/* @__PURE__ */ jsx45(Panel, { minSize: 40, children: /* @__PURE__ */ jsx45(DataDisplay, {}) })
|
|
5617
5791
|
]
|
|
5618
5792
|
}
|
|
5619
5793
|
),
|
|
5620
|
-
/* @__PURE__ */
|
|
5794
|
+
/* @__PURE__ */ jsx45(Toaster, {})
|
|
5621
5795
|
] }) }) }) }) });
|
|
5622
5796
|
};
|
|
5623
5797
|
export {
|