Skip to content

Commit 90baeaa

Browse files
committed
feat: online advisor v1
1 parent cec39f0 commit 90baeaa

File tree

19 files changed

+2331
-1404
lines changed

19 files changed

+2331
-1404
lines changed

apps/dashboard/app/(main)/observability/database/[id]/online-advisor/page.tsx

Lines changed: 841 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import { MagnifyingGlassIcon, XIcon } from '@phosphor-icons/react';
2+
import type { Table } from '@tanstack/react-table';
3+
import { Input } from '@/components/ui/input';
4+
import { TableContent } from './table-content';
5+
import { TableTabs } from './table-tabs';
6+
7+
interface TabConfig<TData> {
8+
id: string;
9+
label: string;
10+
data: TData[];
11+
columns: any[];
12+
getFilter?: (row: TData) => { field: string; value: string };
13+
}
14+
15+
interface FullScreenModalProps<TData extends { name: string | number }> {
16+
table: Table<TData>;
17+
title?: string;
18+
description?: string;
19+
onClose: () => void;
20+
showSearch?: boolean;
21+
globalFilter: string;
22+
onGlobalFilterChange: (value: string) => void;
23+
tabs?: TabConfig<TData>[];
24+
activeTab?: string;
25+
onTabChange?: (tabId: string) => void;
26+
expandable?: boolean;
27+
getSubRows?: (row: TData) => TData[] | undefined;
28+
renderSubRow?: (
29+
subRow: TData,
30+
parentRow: TData,
31+
index: number
32+
) => React.ReactNode;
33+
onAddFilter?: (field: string, value: string, tableTitle?: string) => void;
34+
onRowAction?: (row: TData) => void;
35+
onRowClick?: (field: string, value: string | number) => void;
36+
}
37+
38+
export function FullScreenModal<TData extends { name: string | number }>({
39+
table,
40+
title,
41+
description,
42+
onClose,
43+
showSearch = true,
44+
globalFilter,
45+
onGlobalFilterChange,
46+
tabs,
47+
activeTab,
48+
onTabChange,
49+
expandable = false,
50+
getSubRows,
51+
renderSubRow,
52+
onAddFilter,
53+
onRowAction,
54+
onRowClick,
55+
}: FullScreenModalProps<TData>) {
56+
return (
57+
<div className="relative flex h-full w-full flex-col bg-sidebar">
58+
<div className="flex items-start justify-between border-sidebar-border border-b bg-sidebar px-3 pt-3 pb-2">
59+
<div className="min-w-0 flex-1">
60+
{title && (
61+
<h3 className="truncate font-semibold text-sidebar-foreground text-sm">
62+
{title}
63+
</h3>
64+
)}
65+
{description && (
66+
<p className="mt-0.5 line-clamp-2 text-sidebar-foreground/70 text-xs">
67+
{description}
68+
</p>
69+
)}
70+
</div>
71+
<button
72+
aria-label="Close full screen"
73+
className="ml-2 flex items-center justify-center rounded bg-sidebar-accent/60 p-2 text-sidebar-foreground transition-colors hover:bg-sidebar-accent"
74+
onClick={onClose}
75+
style={{ minWidth: 40, minHeight: 40 }}
76+
tabIndex={0}
77+
title="Close"
78+
type="button"
79+
>
80+
<XIcon size={20} />
81+
</button>
82+
</div>
83+
84+
{tabs && tabs.length > 1 && (
85+
<div className="mt-2">
86+
<TableTabs
87+
activeTab={activeTab || ''}
88+
onTabChange={onTabChange || (() => {})}
89+
tabs={tabs}
90+
/>
91+
</div>
92+
)}
93+
94+
{showSearch && (
95+
<div className="flex items-center px-3 py-2">
96+
<div className="relative w-full max-w-xs">
97+
<Input
98+
aria-label="Search table"
99+
className="h-8 w-full border-sidebar-border bg-sidebar-accent/30 pr-2 pl-7 text-sidebar-foreground text-xs"
100+
onChange={(event) => onGlobalFilterChange(event.target.value)}
101+
placeholder="Filter data..."
102+
value={globalFilter ?? ''}
103+
/>
104+
<MagnifyingGlassIcon className="-translate-y-1/2 absolute top-1/2 left-2 h-3 w-3 transform text-sidebar-foreground/50" />
105+
{globalFilter && (
106+
<button
107+
aria-label="Clear search"
108+
className="-translate-y-1/2 absolute top-1/2 right-2 rounded p-1 hover:bg-sidebar-accent/60"
109+
onClick={() => onGlobalFilterChange('')}
110+
type="button"
111+
>
112+
<XIcon className="h-3 w-3 text-sidebar-foreground/60" />
113+
</button>
114+
)}
115+
</div>
116+
</div>
117+
)}
118+
119+
<div className="flex-1 overflow-auto px-3 pb-3">
120+
<TableContent
121+
activeTab={activeTab}
122+
expandable={expandable}
123+
getSubRows={getSubRows}
124+
globalFilter={globalFilter}
125+
minHeight="100%"
126+
onAddFilter={onAddFilter}
127+
onGlobalFilterChange={onGlobalFilterChange}
128+
onRowAction={onRowAction}
129+
onRowClick={onRowClick}
130+
renderSubRow={renderSubRow}
131+
table={table}
132+
tabs={tabs}
133+
title={title}
134+
/>
135+
</div>
136+
</div>
137+
);
138+
}

0 commit comments

Comments
 (0)