elseware-ui 2.31.1 → 2.31.2
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/LICENSE +21 -0
- package/README.md +98 -109
- package/dist/index.css +18 -18
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +1349 -1303
- package/dist/index.d.ts +1349 -1303
- package/dist/index.js +510 -122
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +511 -123
- package/dist/index.mjs.map +1 -1
- package/package.json +110 -110
package/dist/index.mjs
CHANGED
|
@@ -22,7 +22,7 @@ import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
|
|
|
22
22
|
import { MdUpload, MdOutlineDone, MdOutlineRemoveCircleOutline } from 'react-icons/md';
|
|
23
23
|
import '@mdxeditor/editor/style.css';
|
|
24
24
|
import { MDXEditor, headingsPlugin, linkPlugin, listsPlugin, imagePlugin, tablePlugin, linkDialogPlugin, thematicBreakPlugin, quotePlugin, toolbarPlugin, UndoRedo, Separator, BlockTypeSelect, BoldItalicUnderlineToggles, StrikeThroughSupSubToggles, ListsToggle, CreateLink, InsertImage, InsertTable, InsertThematicBreak, markdownShortcutPlugin, frontmatterPlugin, codeBlockPlugin, codeMirrorPlugin } from '@mdxeditor/editor';
|
|
25
|
-
import { BiDotsVerticalRounded, BiEdit, BiTrash, BiFlag, BiLike, BiDislike, BiChevronDown, BiChevronUp } from 'react-icons/bi';
|
|
25
|
+
import { BiDotsVerticalRounded, BiEdit, BiTrash, BiFlag, BiSolidLike, BiLike, BiSolidDislike, BiDislike, BiChevronDown, BiChevronUp } from 'react-icons/bi';
|
|
26
26
|
|
|
27
27
|
// node_modules/clsx/dist/clsx.mjs
|
|
28
28
|
function r(e) {
|
|
@@ -3104,7 +3104,7 @@ var ShapeSwitch = () => {
|
|
|
3104
3104
|
{
|
|
3105
3105
|
value: currentShape,
|
|
3106
3106
|
onChange: handleChange,
|
|
3107
|
-
className: "\
|
|
3107
|
+
className: "\n px-3 py-2 rounded-md border border-gray-300\n bg-white dark:bg-gray-800\n text-sm shadow-sm\n focus:outline-none\n ",
|
|
3108
3108
|
children: Object.keys(Shape).map((shape) => /* @__PURE__ */ jsx("option", { value: shape, children: shape }, shape))
|
|
3109
3109
|
}
|
|
3110
3110
|
) });
|
|
@@ -16098,7 +16098,7 @@ function MarkdownTOC({ title = "Table of Contents" }) {
|
|
|
16098
16098
|
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
16099
16099
|
"h2",
|
|
16100
16100
|
{
|
|
16101
|
-
className: "\
|
|
16101
|
+
className: "\n text-sm\n font-semibold\n uppercase\n tracking-wide\n text-gray-900\n dark:text-gray-100\n ",
|
|
16102
16102
|
children: title
|
|
16103
16103
|
}
|
|
16104
16104
|
) }),
|
|
@@ -17427,7 +17427,7 @@ var GlowWrapper = ({
|
|
|
17427
17427
|
/* @__PURE__ */ jsx(
|
|
17428
17428
|
"span",
|
|
17429
17429
|
{
|
|
17430
|
-
className: "\
|
|
17430
|
+
className: "\n pointer-events-none absolute inset-0 opacity-0 \n group-hover:opacity-100 transition-opacity duration-300\n ",
|
|
17431
17431
|
style: { background: "var(--glow-bg)" }
|
|
17432
17432
|
}
|
|
17433
17433
|
),
|
|
@@ -17459,49 +17459,60 @@ function ShowMore({ text, limit }) {
|
|
|
17459
17459
|
}
|
|
17460
17460
|
var ShowMore_default = ShowMore;
|
|
17461
17461
|
function CommentComposer({
|
|
17462
|
+
avatar,
|
|
17462
17463
|
placeholder = "Add a comment...",
|
|
17463
17464
|
submitLabel = "Comment",
|
|
17465
|
+
disabled,
|
|
17466
|
+
loading,
|
|
17464
17467
|
onSubmit
|
|
17465
17468
|
}) {
|
|
17466
17469
|
const [value, setValue] = useState("");
|
|
17467
17470
|
const [focused, setFocused] = useState(false);
|
|
17468
17471
|
async function handleSubmit() {
|
|
17469
|
-
|
|
17470
|
-
|
|
17472
|
+
const content = value.trim();
|
|
17473
|
+
if (!content) {
|
|
17474
|
+
return;
|
|
17475
|
+
}
|
|
17476
|
+
await onSubmit?.(content);
|
|
17477
|
+
setValue("");
|
|
17478
|
+
setFocused(false);
|
|
17479
|
+
}
|
|
17480
|
+
function handleCancel() {
|
|
17471
17481
|
setValue("");
|
|
17472
17482
|
setFocused(false);
|
|
17473
17483
|
}
|
|
17474
17484
|
return /* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
17475
|
-
/* @__PURE__ */ jsx(Avatar, { size: "md" }),
|
|
17485
|
+
/* @__PURE__ */ jsx(Avatar, { src: avatar, size: "md" }),
|
|
17476
17486
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col gap-3", children: [
|
|
17477
17487
|
/* @__PURE__ */ jsx(
|
|
17478
17488
|
"textarea",
|
|
17479
17489
|
{
|
|
17480
17490
|
value,
|
|
17491
|
+
disabled: disabled || loading,
|
|
17481
17492
|
placeholder,
|
|
17482
17493
|
onFocus: () => setFocused(true),
|
|
17483
17494
|
onChange: (e) => setValue(e.target.value),
|
|
17484
|
-
className: "w-full
|
|
17495
|
+
className: "\n w-full\n min-h-[56px]\n resize-none\n bg-transparent\n border-b\n border-gray-300\n dark:border-neutral-700\n outline-none\n pb-2\n text-sm\n "
|
|
17485
17496
|
}
|
|
17486
17497
|
),
|
|
17487
17498
|
(focused || value.length > 0) && /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
17488
17499
|
/* @__PURE__ */ jsx(
|
|
17489
17500
|
Button_default,
|
|
17490
17501
|
{
|
|
17502
|
+
text: "Cancel",
|
|
17491
17503
|
variant: "secondary",
|
|
17492
17504
|
appearance: "ghost",
|
|
17493
|
-
|
|
17494
|
-
onClick:
|
|
17495
|
-
setValue("");
|
|
17496
|
-
setFocused(false);
|
|
17497
|
-
}
|
|
17505
|
+
disabled: loading,
|
|
17506
|
+
onClick: handleCancel
|
|
17498
17507
|
}
|
|
17499
17508
|
),
|
|
17500
17509
|
/* @__PURE__ */ jsx(
|
|
17501
17510
|
Button_default,
|
|
17502
17511
|
{
|
|
17503
|
-
variant: "primary",
|
|
17504
17512
|
text: submitLabel,
|
|
17513
|
+
variant: "primary",
|
|
17514
|
+
loading,
|
|
17515
|
+
disabled: !value.trim(),
|
|
17505
17516
|
onClick: handleSubmit
|
|
17506
17517
|
}
|
|
17507
17518
|
)
|
|
@@ -17510,6 +17521,78 @@ function CommentComposer({
|
|
|
17510
17521
|
] });
|
|
17511
17522
|
}
|
|
17512
17523
|
var CommentComposer_default = CommentComposer;
|
|
17524
|
+
function CommentActions({
|
|
17525
|
+
likes = 0,
|
|
17526
|
+
dislikes = 0,
|
|
17527
|
+
liked = false,
|
|
17528
|
+
disliked = false,
|
|
17529
|
+
canReply = true,
|
|
17530
|
+
onLike,
|
|
17531
|
+
onDislike,
|
|
17532
|
+
onReply
|
|
17533
|
+
}) {
|
|
17534
|
+
return /* @__PURE__ */ jsxs(
|
|
17535
|
+
"div",
|
|
17536
|
+
{
|
|
17537
|
+
className: "\n flex\n items-center\n gap-5\n text-sm\n text-gray-500\n dark:text-gray-400\n ",
|
|
17538
|
+
children: [
|
|
17539
|
+
/* @__PURE__ */ jsxs(
|
|
17540
|
+
"button",
|
|
17541
|
+
{
|
|
17542
|
+
onClick: onLike,
|
|
17543
|
+
className: `
|
|
17544
|
+
inline-flex
|
|
17545
|
+
items-center
|
|
17546
|
+
gap-1
|
|
17547
|
+
transition-colors
|
|
17548
|
+
${liked ? "text-blue-500" : "hover:text-gray-900 dark:hover:text-gray-100"}
|
|
17549
|
+
`,
|
|
17550
|
+
children: [
|
|
17551
|
+
liked ? /* @__PURE__ */ jsx(BiSolidLike, { size: 18 }) : /* @__PURE__ */ jsx(BiLike, { size: 18 }),
|
|
17552
|
+
/* @__PURE__ */ jsx("span", { children: likes })
|
|
17553
|
+
]
|
|
17554
|
+
}
|
|
17555
|
+
),
|
|
17556
|
+
/* @__PURE__ */ jsxs(
|
|
17557
|
+
"button",
|
|
17558
|
+
{
|
|
17559
|
+
onClick: onDislike,
|
|
17560
|
+
className: `
|
|
17561
|
+
inline-flex
|
|
17562
|
+
items-center
|
|
17563
|
+
gap-1
|
|
17564
|
+
transition-colors
|
|
17565
|
+
${disliked ? "text-red-500" : "hover:text-gray-900 dark:hover:text-gray-100"}
|
|
17566
|
+
`,
|
|
17567
|
+
children: [
|
|
17568
|
+
disliked ? /* @__PURE__ */ jsx(BiSolidDislike, { size: 18 }) : /* @__PURE__ */ jsx(BiDislike, { size: 18 }),
|
|
17569
|
+
/* @__PURE__ */ jsx("span", { children: dislikes })
|
|
17570
|
+
]
|
|
17571
|
+
}
|
|
17572
|
+
),
|
|
17573
|
+
canReply && /* @__PURE__ */ jsx(
|
|
17574
|
+
"button",
|
|
17575
|
+
{
|
|
17576
|
+
onClick: onReply,
|
|
17577
|
+
className: "\n font-medium\n transition-colors\n hover:text-gray-900\n dark:hover:text-gray-100\n ",
|
|
17578
|
+
children: "Reply"
|
|
17579
|
+
}
|
|
17580
|
+
)
|
|
17581
|
+
]
|
|
17582
|
+
}
|
|
17583
|
+
);
|
|
17584
|
+
}
|
|
17585
|
+
var CommentActions_default = CommentActions;
|
|
17586
|
+
function CommentContent({ content }) {
|
|
17587
|
+
return /* @__PURE__ */ jsx(
|
|
17588
|
+
"div",
|
|
17589
|
+
{
|
|
17590
|
+
className: "\n text-sm\n leading-relaxed\n whitespace-pre-wrap\n break-words\n text-gray-700\n dark:text-gray-300\n ",
|
|
17591
|
+
children: content
|
|
17592
|
+
}
|
|
17593
|
+
);
|
|
17594
|
+
}
|
|
17595
|
+
var CommentContent_default = CommentContent;
|
|
17513
17596
|
|
|
17514
17597
|
// src/compositions/comment-thread/utils/formatCommentDate.ts
|
|
17515
17598
|
function formatCommentDate(date) {
|
|
@@ -17517,11 +17600,26 @@ function formatCommentDate(date) {
|
|
|
17517
17600
|
const target = new Date(date);
|
|
17518
17601
|
const seconds = Math.floor((now.getTime() - target.getTime()) / 1e3);
|
|
17519
17602
|
const intervals = [
|
|
17520
|
-
{
|
|
17521
|
-
|
|
17522
|
-
|
|
17523
|
-
|
|
17524
|
-
{
|
|
17603
|
+
{
|
|
17604
|
+
label: "year",
|
|
17605
|
+
seconds: 31536e3
|
|
17606
|
+
},
|
|
17607
|
+
{
|
|
17608
|
+
label: "month",
|
|
17609
|
+
seconds: 2592e3
|
|
17610
|
+
},
|
|
17611
|
+
{
|
|
17612
|
+
label: "day",
|
|
17613
|
+
seconds: 86400
|
|
17614
|
+
},
|
|
17615
|
+
{
|
|
17616
|
+
label: "hour",
|
|
17617
|
+
seconds: 3600
|
|
17618
|
+
},
|
|
17619
|
+
{
|
|
17620
|
+
label: "minute",
|
|
17621
|
+
seconds: 60
|
|
17622
|
+
}
|
|
17525
17623
|
];
|
|
17526
17624
|
for (const interval of intervals) {
|
|
17527
17625
|
const count = Math.floor(seconds / interval.seconds);
|
|
@@ -17534,67 +17632,27 @@ function formatCommentDate(date) {
|
|
|
17534
17632
|
function CommentHeader({
|
|
17535
17633
|
avatar,
|
|
17536
17634
|
username,
|
|
17635
|
+
firstName,
|
|
17636
|
+
lastName,
|
|
17537
17637
|
createdAt,
|
|
17538
17638
|
edited
|
|
17539
17639
|
}) {
|
|
17640
|
+
const displayName = firstName || lastName ? `${firstName ?? ""} ${lastName ?? ""}`.trim() : username;
|
|
17540
17641
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
17541
17642
|
/* @__PURE__ */ jsx(Avatar, { src: avatar, size: "sm" }),
|
|
17542
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2
|
|
17543
|
-
/* @__PURE__ */
|
|
17643
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap min-w-0", children: [
|
|
17644
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-sm text-gray-900 dark:text-gray-100", children: displayName }),
|
|
17645
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
|
|
17544
17646
|
"@",
|
|
17545
17647
|
username
|
|
17546
17648
|
] }),
|
|
17547
|
-
/* @__PURE__ */ jsx("span", { className: "text-gray-500 dark:text-gray-400", children:
|
|
17548
|
-
|
|
17649
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: "\xB7" }),
|
|
17650
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: formatCommentDate(createdAt) }),
|
|
17651
|
+
edited && /* @__PURE__ */ jsx("span", { className: "text-xs text-gray-400 dark:text-gray-500", children: "(edited)" })
|
|
17549
17652
|
] })
|
|
17550
17653
|
] });
|
|
17551
17654
|
}
|
|
17552
17655
|
var CommentHeader_default = CommentHeader;
|
|
17553
|
-
function CommentContent({ content }) {
|
|
17554
|
-
return /* @__PURE__ */ jsx("div", { className: "text-sm leading-relaxed whitespace-pre-wrap text-gray-700 dark:text-gray-300", children: content });
|
|
17555
|
-
}
|
|
17556
|
-
var CommentContent_default = CommentContent;
|
|
17557
|
-
function CommentActions({
|
|
17558
|
-
likes = 0,
|
|
17559
|
-
dislikes = 0,
|
|
17560
|
-
onLike,
|
|
17561
|
-
onDislike,
|
|
17562
|
-
onReply
|
|
17563
|
-
}) {
|
|
17564
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-5 text-sm text-gray-500 dark:text-gray-400", children: [
|
|
17565
|
-
/* @__PURE__ */ jsxs(
|
|
17566
|
-
"button",
|
|
17567
|
-
{
|
|
17568
|
-
onClick: onLike,
|
|
17569
|
-
className: "inline-flex items-center gap-1 hover:text-gray-900 dark:hover:text-gray-100 transition-colors",
|
|
17570
|
-
children: [
|
|
17571
|
-
/* @__PURE__ */ jsx(BiLike, { size: 18 }),
|
|
17572
|
-
/* @__PURE__ */ jsx("span", { children: likes })
|
|
17573
|
-
]
|
|
17574
|
-
}
|
|
17575
|
-
),
|
|
17576
|
-
/* @__PURE__ */ jsxs(
|
|
17577
|
-
"button",
|
|
17578
|
-
{
|
|
17579
|
-
onClick: onDislike,
|
|
17580
|
-
className: "inline-flex items-center gap-1 hover:text-gray-900 dark:hover:text-gray-100 transition-colors",
|
|
17581
|
-
children: [
|
|
17582
|
-
/* @__PURE__ */ jsx(BiDislike, { size: 18 }),
|
|
17583
|
-
/* @__PURE__ */ jsx("span", { children: dislikes })
|
|
17584
|
-
]
|
|
17585
|
-
}
|
|
17586
|
-
),
|
|
17587
|
-
/* @__PURE__ */ jsx(
|
|
17588
|
-
"button",
|
|
17589
|
-
{
|
|
17590
|
-
onClick: onReply,
|
|
17591
|
-
className: "font-medium hover:text-gray-900 dark:hover:text-gray-100 transition-colors",
|
|
17592
|
-
children: "Reply"
|
|
17593
|
-
}
|
|
17594
|
-
)
|
|
17595
|
-
] });
|
|
17596
|
-
}
|
|
17597
|
-
var CommentActions_default = CommentActions;
|
|
17598
17656
|
function CommentMenu({
|
|
17599
17657
|
canEdit,
|
|
17600
17658
|
canDelete,
|
|
@@ -17614,28 +17672,34 @@ function CommentMenu({
|
|
|
17614
17672
|
document.addEventListener("mousedown", handleOutsideClick);
|
|
17615
17673
|
return () => document.removeEventListener("mousedown", handleOutsideClick);
|
|
17616
17674
|
}, []);
|
|
17675
|
+
const hasActions = canEdit || canDelete || canReport;
|
|
17676
|
+
if (!hasActions) {
|
|
17677
|
+
return null;
|
|
17678
|
+
}
|
|
17617
17679
|
return /* @__PURE__ */ jsxs("div", { ref, className: "relative", children: [
|
|
17618
17680
|
/* @__PURE__ */ jsx(
|
|
17619
17681
|
"button",
|
|
17620
17682
|
{
|
|
17683
|
+
type: "button",
|
|
17621
17684
|
onClick: () => setOpen((prev) => !prev),
|
|
17622
|
-
className: "text-gray-500
|
|
17685
|
+
className: "\n text-gray-500\n hover:text-gray-900\n dark:hover:text-gray-100\n transition-colors\n ",
|
|
17623
17686
|
children: /* @__PURE__ */ jsx(BiDotsVerticalRounded, { size: 18 })
|
|
17624
17687
|
}
|
|
17625
17688
|
),
|
|
17626
17689
|
open && /* @__PURE__ */ jsxs(
|
|
17627
17690
|
"div",
|
|
17628
17691
|
{
|
|
17629
|
-
className: "\
|
|
17692
|
+
className: "\n absolute\n right-0\n top-full\n mt-2\n min-w-[180px]\n overflow-hidden\n rounded-xl\n border\n border-gray-200\n dark:border-neutral-800\n bg-white\n dark:bg-neutral-900\n shadow-xl\n z-50\n ",
|
|
17630
17693
|
children: [
|
|
17631
17694
|
canEdit && /* @__PURE__ */ jsxs(
|
|
17632
17695
|
"button",
|
|
17633
17696
|
{
|
|
17697
|
+
type: "button",
|
|
17634
17698
|
onClick: () => {
|
|
17635
17699
|
setOpen(false);
|
|
17636
17700
|
onEdit?.();
|
|
17637
17701
|
},
|
|
17638
|
-
className: "w-full
|
|
17702
|
+
className: "\n w-full\n flex\n items-center\n gap-2\n px-4\n py-3\n text-sm\n hover:bg-gray-100\n dark:hover:bg-neutral-800\n ",
|
|
17639
17703
|
children: [
|
|
17640
17704
|
/* @__PURE__ */ jsx(BiEdit, {}),
|
|
17641
17705
|
"Edit"
|
|
@@ -17645,11 +17709,12 @@ function CommentMenu({
|
|
|
17645
17709
|
canDelete && /* @__PURE__ */ jsxs(
|
|
17646
17710
|
"button",
|
|
17647
17711
|
{
|
|
17712
|
+
type: "button",
|
|
17648
17713
|
onClick: () => {
|
|
17649
17714
|
setOpen(false);
|
|
17650
17715
|
onDelete?.();
|
|
17651
17716
|
},
|
|
17652
|
-
className: "w-full
|
|
17717
|
+
className: "\n w-full\n flex\n items-center\n gap-2\n px-4\n py-3\n text-sm\n text-red-500\n hover:bg-gray-100\n dark:hover:bg-neutral-800\n ",
|
|
17653
17718
|
children: [
|
|
17654
17719
|
/* @__PURE__ */ jsx(BiTrash, {}),
|
|
17655
17720
|
"Delete"
|
|
@@ -17659,11 +17724,12 @@ function CommentMenu({
|
|
|
17659
17724
|
canReport && /* @__PURE__ */ jsxs(
|
|
17660
17725
|
"button",
|
|
17661
17726
|
{
|
|
17727
|
+
type: "button",
|
|
17662
17728
|
onClick: () => {
|
|
17663
17729
|
setOpen(false);
|
|
17664
17730
|
onReport?.();
|
|
17665
17731
|
},
|
|
17666
|
-
className: "w-full
|
|
17732
|
+
className: "\n w-full\n flex\n items-center\n gap-2\n px-4\n py-3\n text-sm\n hover:bg-gray-100\n dark:hover:bg-neutral-800\n ",
|
|
17667
17733
|
children: [
|
|
17668
17734
|
/* @__PURE__ */ jsx(BiFlag, {}),
|
|
17669
17735
|
"Report"
|
|
@@ -17681,25 +17747,37 @@ function CommentRepliesToggle({
|
|
|
17681
17747
|
collapsed,
|
|
17682
17748
|
onToggle
|
|
17683
17749
|
}) {
|
|
17750
|
+
if (repliesCount <= 0) {
|
|
17751
|
+
return null;
|
|
17752
|
+
}
|
|
17753
|
+
const label = collapsed ? `View ${repliesCount} ${repliesCount === 1 ? "reply" : "replies"}` : "Hide replies";
|
|
17684
17754
|
return /* @__PURE__ */ jsxs(
|
|
17685
17755
|
"button",
|
|
17686
17756
|
{
|
|
17757
|
+
type: "button",
|
|
17687
17758
|
onClick: onToggle,
|
|
17688
|
-
className: "inline-flex
|
|
17759
|
+
className: "\n inline-flex\n items-center\n gap-1\n w-fit\n text-sm\n font-medium\n text-blue-500\n hover:text-blue-400\n transition-colors\n ",
|
|
17689
17760
|
children: [
|
|
17690
17761
|
collapsed ? /* @__PURE__ */ jsx(BiChevronDown, { size: 18 }) : /* @__PURE__ */ jsx(BiChevronUp, { size: 18 }),
|
|
17691
|
-
/* @__PURE__ */ jsx("span", { children:
|
|
17762
|
+
/* @__PURE__ */ jsx("span", { children: label })
|
|
17692
17763
|
]
|
|
17693
17764
|
}
|
|
17694
17765
|
);
|
|
17695
17766
|
}
|
|
17696
17767
|
var CommentRepliesToggle_default = CommentRepliesToggle;
|
|
17697
|
-
function ReplyComposer({
|
|
17768
|
+
function ReplyComposer({
|
|
17769
|
+
avatar,
|
|
17770
|
+
username,
|
|
17771
|
+
loading,
|
|
17772
|
+
onSubmit
|
|
17773
|
+
}) {
|
|
17698
17774
|
return /* @__PURE__ */ jsx("div", { className: "pt-2", children: /* @__PURE__ */ jsx(
|
|
17699
17775
|
CommentComposer_default,
|
|
17700
17776
|
{
|
|
17701
|
-
|
|
17777
|
+
avatar,
|
|
17778
|
+
loading,
|
|
17702
17779
|
submitLabel: "Reply",
|
|
17780
|
+
placeholder: `Reply to @${username}`,
|
|
17703
17781
|
onSubmit
|
|
17704
17782
|
}
|
|
17705
17783
|
) });
|
|
@@ -17708,7 +17786,7 @@ var ReplyComposer_default = ReplyComposer;
|
|
|
17708
17786
|
|
|
17709
17787
|
// src/compositions/comment-thread/constants/comment.constants.ts
|
|
17710
17788
|
var MAX_COMMENT_DEPTH = 5;
|
|
17711
|
-
var COMMENT_INDENTATION =
|
|
17789
|
+
var COMMENT_INDENTATION = 24;
|
|
17712
17790
|
function CommentItem({
|
|
17713
17791
|
comment,
|
|
17714
17792
|
depth = 0,
|
|
@@ -17723,7 +17801,7 @@ function CommentItem({
|
|
|
17723
17801
|
const [isReplying, setIsReplying] = useState(false);
|
|
17724
17802
|
const resolvedDepth = Math.min(depth, MAX_COMMENT_DEPTH);
|
|
17725
17803
|
async function handleReply(content) {
|
|
17726
|
-
|
|
17804
|
+
await onReply?.(comment, content);
|
|
17727
17805
|
setIsReplying(false);
|
|
17728
17806
|
}
|
|
17729
17807
|
return /* @__PURE__ */ jsxs(
|
|
@@ -17731,16 +17809,18 @@ function CommentItem({
|
|
|
17731
17809
|
{
|
|
17732
17810
|
className: "flex flex-col gap-4",
|
|
17733
17811
|
style: {
|
|
17734
|
-
paddingLeft:
|
|
17812
|
+
paddingLeft: resolvedDepth * COMMENT_INDENTATION
|
|
17735
17813
|
},
|
|
17736
17814
|
children: [
|
|
17737
|
-
/* @__PURE__ */ jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxs("div", { className: "flex-1 flex
|
|
17815
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-3 min-w-0", children: [
|
|
17738
17816
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
17739
17817
|
/* @__PURE__ */ jsx(
|
|
17740
17818
|
CommentHeader_default,
|
|
17741
17819
|
{
|
|
17742
|
-
avatar: comment.author
|
|
17743
|
-
username: comment.author
|
|
17820
|
+
avatar: comment.author?.avatar,
|
|
17821
|
+
username: comment.author?.username ?? "unknown",
|
|
17822
|
+
firstName: comment.author?.firstName,
|
|
17823
|
+
lastName: comment.author?.lastName,
|
|
17744
17824
|
createdAt: comment.createdAt,
|
|
17745
17825
|
edited: comment.edited
|
|
17746
17826
|
}
|
|
@@ -17763,18 +17843,19 @@ function CommentItem({
|
|
|
17763
17843
|
{
|
|
17764
17844
|
likes: comment.likes,
|
|
17765
17845
|
dislikes: comment.dislikes,
|
|
17846
|
+
liked: comment.liked,
|
|
17847
|
+
disliked: comment.disliked,
|
|
17848
|
+
canReply: comment.permissions?.canReply,
|
|
17766
17849
|
onLike: () => onLike?.(comment),
|
|
17767
17850
|
onDislike: () => onDislike?.(comment),
|
|
17768
|
-
onReply: () =>
|
|
17769
|
-
setIsReplying((prev) => !prev);
|
|
17770
|
-
onReply?.(comment);
|
|
17771
|
-
}
|
|
17851
|
+
onReply: () => setIsReplying((prev) => !prev)
|
|
17772
17852
|
}
|
|
17773
17853
|
),
|
|
17774
17854
|
isReplying && /* @__PURE__ */ jsx(
|
|
17775
17855
|
ReplyComposer_default,
|
|
17776
17856
|
{
|
|
17777
|
-
|
|
17857
|
+
avatar: comment.author?.avatar,
|
|
17858
|
+
username: comment.author?.username,
|
|
17778
17859
|
onSubmit: handleReply
|
|
17779
17860
|
}
|
|
17780
17861
|
),
|
|
@@ -17824,6 +17905,9 @@ function CommentList({
|
|
|
17824
17905
|
onDelete,
|
|
17825
17906
|
onReport
|
|
17826
17907
|
}) {
|
|
17908
|
+
if (!comments.length) {
|
|
17909
|
+
return null;
|
|
17910
|
+
}
|
|
17827
17911
|
return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-8", children: comments.map((comment) => /* @__PURE__ */ jsx(
|
|
17828
17912
|
CommentItem_default,
|
|
17829
17913
|
{
|
|
@@ -17840,52 +17924,356 @@ function CommentList({
|
|
|
17840
17924
|
)) });
|
|
17841
17925
|
}
|
|
17842
17926
|
var CommentList_default = CommentList;
|
|
17843
|
-
|
|
17844
|
-
|
|
17845
|
-
|
|
17846
|
-
|
|
17847
|
-
|
|
17848
|
-
|
|
17849
|
-
|
|
17927
|
+
function EditCommentModal({
|
|
17928
|
+
show,
|
|
17929
|
+
comment,
|
|
17930
|
+
handleCloseModal,
|
|
17931
|
+
onSubmit
|
|
17932
|
+
}) {
|
|
17933
|
+
if (!comment) return null;
|
|
17934
|
+
return /* @__PURE__ */ jsx(Modal_default, { title: "Edit Comment", show, handleOnClose: handleCloseModal, children: /* @__PURE__ */ jsx(
|
|
17935
|
+
Form,
|
|
17936
|
+
{
|
|
17937
|
+
enableReinitialize: true,
|
|
17938
|
+
initialValues: {
|
|
17939
|
+
content: comment.content
|
|
17940
|
+
},
|
|
17941
|
+
onSubmit: async (values) => {
|
|
17942
|
+
await onSubmit?.(comment, values.content);
|
|
17943
|
+
handleCloseModal();
|
|
17944
|
+
},
|
|
17945
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
17946
|
+
/* @__PURE__ */ jsx(TextArea_default, { name: "content", rows: 5, placeholder: "Comment" }),
|
|
17947
|
+
/* @__PURE__ */ jsx(Button_default, { type: "submit", variant: "success", text: "Save Changes" })
|
|
17948
|
+
] })
|
|
17949
|
+
}
|
|
17950
|
+
) });
|
|
17850
17951
|
}
|
|
17851
|
-
|
|
17852
|
-
|
|
17853
|
-
|
|
17854
|
-
|
|
17855
|
-
|
|
17856
|
-
|
|
17857
|
-
onEdit,
|
|
17858
|
-
onDelete,
|
|
17859
|
-
onReport
|
|
17952
|
+
var EditCommentModal_default = EditCommentModal;
|
|
17953
|
+
function DeleteCommentModal({
|
|
17954
|
+
show,
|
|
17955
|
+
comment,
|
|
17956
|
+
handleCloseModal,
|
|
17957
|
+
onDelete
|
|
17860
17958
|
}) {
|
|
17861
|
-
|
|
17862
|
-
|
|
17863
|
-
|
|
17959
|
+
if (!comment) return null;
|
|
17960
|
+
return /* @__PURE__ */ jsx(Modal_default, { title: "Delete Comment", show, handleOnClose: handleCloseModal, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5", children: [
|
|
17961
|
+
/* @__PURE__ */ jsx(Typography.Paragraph, { children: "Are you sure you want to permanently delete this comment?" }),
|
|
17962
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-3 justify-end", children: [
|
|
17963
|
+
/* @__PURE__ */ jsx(Button_default, { text: "Cancel", appearance: "ghost", onClick: handleCloseModal }),
|
|
17964
|
+
/* @__PURE__ */ jsx(
|
|
17965
|
+
Button_default,
|
|
17966
|
+
{
|
|
17967
|
+
text: "Delete",
|
|
17968
|
+
variant: "danger",
|
|
17969
|
+
onClick: async () => {
|
|
17970
|
+
await onDelete?.(comment);
|
|
17971
|
+
handleCloseModal();
|
|
17972
|
+
}
|
|
17973
|
+
}
|
|
17974
|
+
)
|
|
17975
|
+
] })
|
|
17976
|
+
] }) });
|
|
17977
|
+
}
|
|
17978
|
+
var DeleteCommentModal_default = DeleteCommentModal;
|
|
17979
|
+
var REPORT_REASONS = [
|
|
17980
|
+
{
|
|
17981
|
+
label: "Spam",
|
|
17982
|
+
value: "spam"
|
|
17983
|
+
},
|
|
17984
|
+
{
|
|
17985
|
+
label: "Harassment",
|
|
17986
|
+
value: "harassment"
|
|
17987
|
+
},
|
|
17988
|
+
{
|
|
17989
|
+
label: "Hate Speech",
|
|
17990
|
+
value: "hate_speech"
|
|
17991
|
+
},
|
|
17992
|
+
{
|
|
17993
|
+
label: "Misleading Information",
|
|
17994
|
+
value: "misleading_information"
|
|
17995
|
+
},
|
|
17996
|
+
{
|
|
17997
|
+
label: "Other",
|
|
17998
|
+
value: "other"
|
|
17864
17999
|
}
|
|
17865
|
-
|
|
17866
|
-
|
|
18000
|
+
];
|
|
18001
|
+
function ReportCommentModal({
|
|
18002
|
+
show,
|
|
18003
|
+
comment,
|
|
18004
|
+
handleCloseModal,
|
|
18005
|
+
onSubmit
|
|
18006
|
+
}) {
|
|
18007
|
+
if (!comment) return null;
|
|
18008
|
+
return /* @__PURE__ */ jsx(Modal_default, { title: "Report Comment", show, handleOnClose: handleCloseModal, children: /* @__PURE__ */ jsx(
|
|
18009
|
+
Form,
|
|
17867
18010
|
{
|
|
17868
|
-
|
|
17869
|
-
|
|
17870
|
-
|
|
18011
|
+
initialValues: {
|
|
18012
|
+
reason: "",
|
|
18013
|
+
description: ""
|
|
18014
|
+
},
|
|
18015
|
+
onSubmit: async (values) => {
|
|
18016
|
+
await onSubmit?.(comment, {
|
|
18017
|
+
reason: values.reason,
|
|
18018
|
+
description: values.description
|
|
18019
|
+
});
|
|
18020
|
+
handleCloseModal();
|
|
17871
18021
|
},
|
|
17872
|
-
children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-
|
|
17873
|
-
/* @__PURE__ */ jsx(
|
|
18022
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
18023
|
+
/* @__PURE__ */ jsx(Select_default, { name: "reason", placeholder: "Reason", options: REPORT_REASONS }),
|
|
17874
18024
|
/* @__PURE__ */ jsx(
|
|
17875
|
-
|
|
18025
|
+
TextArea_default,
|
|
17876
18026
|
{
|
|
17877
|
-
|
|
17878
|
-
|
|
17879
|
-
|
|
17880
|
-
onReply,
|
|
17881
|
-
onEdit,
|
|
17882
|
-
onDelete,
|
|
17883
|
-
onReport
|
|
18027
|
+
name: "description",
|
|
18028
|
+
rows: 4,
|
|
18029
|
+
placeholder: "Additional details"
|
|
17884
18030
|
}
|
|
17885
|
-
)
|
|
18031
|
+
),
|
|
18032
|
+
/* @__PURE__ */ jsx(Button_default, { type: "submit", variant: "danger", text: "Submit Report" })
|
|
17886
18033
|
] })
|
|
17887
18034
|
}
|
|
18035
|
+
) });
|
|
18036
|
+
}
|
|
18037
|
+
var ReportCommentModal_default = ReportCommentModal;
|
|
18038
|
+
function useCommentModals() {
|
|
18039
|
+
const [showEditModal, setShowEditModal] = useState(false);
|
|
18040
|
+
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
|
18041
|
+
const [showReportModal, setShowReportModal] = useState(false);
|
|
18042
|
+
return {
|
|
18043
|
+
showEditModal,
|
|
18044
|
+
openEditModal: () => setShowEditModal(true),
|
|
18045
|
+
closeEditModal: () => setShowEditModal(false),
|
|
18046
|
+
showDeleteModal,
|
|
18047
|
+
openDeleteModal: () => setShowDeleteModal(true),
|
|
18048
|
+
closeDeleteModal: () => setShowDeleteModal(false),
|
|
18049
|
+
showReportModal,
|
|
18050
|
+
openReportModal: () => setShowReportModal(true),
|
|
18051
|
+
closeReportModal: () => setShowReportModal(false)
|
|
18052
|
+
};
|
|
18053
|
+
}
|
|
18054
|
+
function useCommentSelection() {
|
|
18055
|
+
const [selectedComment, setSelectedComment] = useState(
|
|
18056
|
+
null
|
|
17888
18057
|
);
|
|
18058
|
+
function selectComment(comment) {
|
|
18059
|
+
setSelectedComment(comment);
|
|
18060
|
+
}
|
|
18061
|
+
function clearSelection() {
|
|
18062
|
+
setSelectedComment(null);
|
|
18063
|
+
}
|
|
18064
|
+
return {
|
|
18065
|
+
selectedComment,
|
|
18066
|
+
selectComment,
|
|
18067
|
+
clearSelection
|
|
18068
|
+
};
|
|
18069
|
+
}
|
|
18070
|
+
|
|
18071
|
+
// src/compositions/comment-thread/utils/buildCommentTree.ts
|
|
18072
|
+
function buildCommentTree(comments) {
|
|
18073
|
+
const map = /* @__PURE__ */ new Map();
|
|
18074
|
+
const roots = [];
|
|
18075
|
+
comments.forEach((comment) => {
|
|
18076
|
+
map.set(comment.id, {
|
|
18077
|
+
...comment,
|
|
18078
|
+
replies: []
|
|
18079
|
+
});
|
|
18080
|
+
});
|
|
18081
|
+
comments.forEach((comment) => {
|
|
18082
|
+
const current = map.get(comment.id);
|
|
18083
|
+
if (!comment.parentCommentId) {
|
|
18084
|
+
roots.push(current);
|
|
18085
|
+
return;
|
|
18086
|
+
}
|
|
18087
|
+
const parent = map.get(comment.parentCommentId);
|
|
18088
|
+
if (parent) {
|
|
18089
|
+
parent.replies.push(current);
|
|
18090
|
+
}
|
|
18091
|
+
});
|
|
18092
|
+
return roots;
|
|
18093
|
+
}
|
|
18094
|
+
|
|
18095
|
+
// src/compositions/comment-thread/utils/updateComment.ts
|
|
18096
|
+
function updateComment(comments, commentId, updater) {
|
|
18097
|
+
return comments.map((comment) => {
|
|
18098
|
+
if (comment.id === commentId) {
|
|
18099
|
+
return updater(comment);
|
|
18100
|
+
}
|
|
18101
|
+
return {
|
|
18102
|
+
...comment,
|
|
18103
|
+
replies: comment.replies ? updateComment(comment.replies, commentId, updater) : []
|
|
18104
|
+
};
|
|
18105
|
+
});
|
|
18106
|
+
}
|
|
18107
|
+
|
|
18108
|
+
// src/compositions/comment-thread/utils/removeComment.ts
|
|
18109
|
+
function removeComment(comments, commentId) {
|
|
18110
|
+
return comments.filter((comment) => comment.id !== commentId).map((comment) => ({
|
|
18111
|
+
...comment,
|
|
18112
|
+
replies: comment.replies ? removeComment(comment.replies, commentId) : []
|
|
18113
|
+
}));
|
|
18114
|
+
}
|
|
18115
|
+
|
|
18116
|
+
// src/compositions/comment-thread/utils/insertReply.ts
|
|
18117
|
+
function insertReply(comments, parentId, reply) {
|
|
18118
|
+
return comments.map((comment) => {
|
|
18119
|
+
if (comment.id === parentId) {
|
|
18120
|
+
return {
|
|
18121
|
+
...comment,
|
|
18122
|
+
replies: [...comment.replies || [], reply]
|
|
18123
|
+
};
|
|
18124
|
+
}
|
|
18125
|
+
return {
|
|
18126
|
+
...comment,
|
|
18127
|
+
replies: comment.replies ? insertReply(comment.replies, parentId, reply) : []
|
|
18128
|
+
};
|
|
18129
|
+
});
|
|
18130
|
+
}
|
|
18131
|
+
function CommentThread({
|
|
18132
|
+
postId,
|
|
18133
|
+
currentUser,
|
|
18134
|
+
dataSource,
|
|
18135
|
+
loading = false,
|
|
18136
|
+
onEdit,
|
|
18137
|
+
onDelete,
|
|
18138
|
+
onReport
|
|
18139
|
+
}) {
|
|
18140
|
+
const [comments, setComments] = useState([]);
|
|
18141
|
+
const [isLoadingComments, setIsLoadingComments] = useState(true);
|
|
18142
|
+
const selection = useCommentSelection();
|
|
18143
|
+
const modals = useCommentModals();
|
|
18144
|
+
useEffect(() => {
|
|
18145
|
+
async function loadComments() {
|
|
18146
|
+
try {
|
|
18147
|
+
const result = await dataSource.getComments();
|
|
18148
|
+
setComments(buildCommentTree(result));
|
|
18149
|
+
} finally {
|
|
18150
|
+
setIsLoadingComments(false);
|
|
18151
|
+
}
|
|
18152
|
+
}
|
|
18153
|
+
loadComments();
|
|
18154
|
+
}, [dataSource]);
|
|
18155
|
+
async function handleCreateComment(content) {
|
|
18156
|
+
const comment = await dataSource.createComment({
|
|
18157
|
+
content,
|
|
18158
|
+
parentCommentId: null
|
|
18159
|
+
});
|
|
18160
|
+
setComments((prev) => [comment, ...prev]);
|
|
18161
|
+
}
|
|
18162
|
+
async function handleReply(parentComment, content) {
|
|
18163
|
+
const reply = await dataSource.createComment({
|
|
18164
|
+
content,
|
|
18165
|
+
parentCommentId: parentComment.id
|
|
18166
|
+
});
|
|
18167
|
+
setComments((prev) => insertReply(prev, parentComment.id, reply));
|
|
18168
|
+
}
|
|
18169
|
+
async function handleLike(comment) {
|
|
18170
|
+
const result = await dataSource.toggleLike(comment.id);
|
|
18171
|
+
setComments(
|
|
18172
|
+
(prev) => updateComment(prev, comment.id, (item) => ({
|
|
18173
|
+
...item,
|
|
18174
|
+
likes: result.likes,
|
|
18175
|
+
dislikes: result.dislikes,
|
|
18176
|
+
liked: result.liked,
|
|
18177
|
+
disliked: result.disliked
|
|
18178
|
+
}))
|
|
18179
|
+
);
|
|
18180
|
+
}
|
|
18181
|
+
async function handleDislike(comment) {
|
|
18182
|
+
const result = await dataSource.toggleDislike(comment.id);
|
|
18183
|
+
setComments(
|
|
18184
|
+
(prev) => updateComment(prev, comment.id, (item) => ({
|
|
18185
|
+
...item,
|
|
18186
|
+
likes: result.likes,
|
|
18187
|
+
dislikes: result.dislikes,
|
|
18188
|
+
liked: result.liked,
|
|
18189
|
+
disliked: result.disliked
|
|
18190
|
+
}))
|
|
18191
|
+
);
|
|
18192
|
+
}
|
|
18193
|
+
async function handleUpdateComment(comment, content) {
|
|
18194
|
+
const updated = await dataSource.updateComment({
|
|
18195
|
+
id: comment.id,
|
|
18196
|
+
content
|
|
18197
|
+
});
|
|
18198
|
+
setComments((prev) => updateComment(prev, comment.id, () => updated));
|
|
18199
|
+
}
|
|
18200
|
+
async function handleDeleteComment(comment) {
|
|
18201
|
+
await dataSource.deleteComment(comment.id);
|
|
18202
|
+
setComments((prev) => removeComment(prev, comment.id));
|
|
18203
|
+
onDelete?.(comment);
|
|
18204
|
+
}
|
|
18205
|
+
async function handleReportComment(comment, payload) {
|
|
18206
|
+
await dataSource.reportComment?.(
|
|
18207
|
+
comment.id,
|
|
18208
|
+
payload.reason,
|
|
18209
|
+
payload.description
|
|
18210
|
+
);
|
|
18211
|
+
onReport?.(comment);
|
|
18212
|
+
}
|
|
18213
|
+
if (loading || isLoadingComments) {
|
|
18214
|
+
return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-6", children: "Loading comments..." });
|
|
18215
|
+
}
|
|
18216
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
18217
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
|
|
18218
|
+
/* @__PURE__ */ jsx(
|
|
18219
|
+
CommentComposer_default,
|
|
18220
|
+
{
|
|
18221
|
+
avatar: currentUser.avatar,
|
|
18222
|
+
onSubmit: handleCreateComment
|
|
18223
|
+
}
|
|
18224
|
+
),
|
|
18225
|
+
/* @__PURE__ */ jsx(
|
|
18226
|
+
CommentList_default,
|
|
18227
|
+
{
|
|
18228
|
+
comments,
|
|
18229
|
+
onLike: handleLike,
|
|
18230
|
+
onDislike: handleDislike,
|
|
18231
|
+
onReply: handleReply,
|
|
18232
|
+
onEdit: (comment) => {
|
|
18233
|
+
selection.selectComment(comment);
|
|
18234
|
+
onEdit?.(comment);
|
|
18235
|
+
modals.openEditModal();
|
|
18236
|
+
},
|
|
18237
|
+
onDelete: (comment) => {
|
|
18238
|
+
selection.selectComment(comment);
|
|
18239
|
+
modals.openDeleteModal();
|
|
18240
|
+
},
|
|
18241
|
+
onReport: (comment) => {
|
|
18242
|
+
selection.selectComment(comment);
|
|
18243
|
+
onReport?.(comment);
|
|
18244
|
+
modals.openReportModal();
|
|
18245
|
+
}
|
|
18246
|
+
}
|
|
18247
|
+
)
|
|
18248
|
+
] }),
|
|
18249
|
+
/* @__PURE__ */ jsx(
|
|
18250
|
+
EditCommentModal_default,
|
|
18251
|
+
{
|
|
18252
|
+
show: modals.showEditModal,
|
|
18253
|
+
comment: selection.selectedComment,
|
|
18254
|
+
handleCloseModal: modals.closeEditModal,
|
|
18255
|
+
onSubmit: handleUpdateComment
|
|
18256
|
+
}
|
|
18257
|
+
),
|
|
18258
|
+
/* @__PURE__ */ jsx(
|
|
18259
|
+
DeleteCommentModal_default,
|
|
18260
|
+
{
|
|
18261
|
+
show: modals.showDeleteModal,
|
|
18262
|
+
comment: selection.selectedComment,
|
|
18263
|
+
handleCloseModal: modals.closeDeleteModal,
|
|
18264
|
+
onDelete: handleDeleteComment
|
|
18265
|
+
}
|
|
18266
|
+
),
|
|
18267
|
+
/* @__PURE__ */ jsx(
|
|
18268
|
+
ReportCommentModal_default,
|
|
18269
|
+
{
|
|
18270
|
+
show: modals.showReportModal,
|
|
18271
|
+
comment: selection.selectedComment,
|
|
18272
|
+
handleCloseModal: modals.closeReportModal,
|
|
18273
|
+
onSubmit: handleReportComment
|
|
18274
|
+
}
|
|
18275
|
+
)
|
|
18276
|
+
] });
|
|
17889
18277
|
}
|
|
17890
18278
|
var CommentThread_default = CommentThread;
|
|
17891
18279
|
function DataViewTable({
|