Skip to content

Commit b812676

Browse files
authored
feat: show function output column in data view (#930)
Signed-off-by: ryjiang <[email protected]>
1 parent 6af3321 commit b812676

File tree

15 files changed

+206
-124
lines changed

15 files changed

+206
-124
lines changed

client/src/components/grid/Grid.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import type { AttuGridType } from './Types';
3232
* @param handlesort how to sort table, if it's undefined, then you can not sort table
3333
* @param order 'desc' | 'asc'. sort direction
3434
* @param order order by which table field
35+
* @param addSpacerColumn control spacer column display. default is false
3536
* @returns
3637
*/
3738
const AttuGrid: FC<AttuGridType> = props => {
@@ -44,8 +45,8 @@ const AttuGrid: FC<AttuGridType> = props => {
4445
const {
4546
rowCount = 20,
4647
rowsPerPage = 10,
47-
tableHeaderHeight = 43.5,
48-
rowHeight = 41,
48+
tableHeaderHeight = 44,
49+
rowHeight = 42,
4950
pagerHeight = 52,
5051
primaryKey = 'id',
5152
showToolbar = false,
@@ -79,6 +80,7 @@ const AttuGrid: FC<AttuGridType> = props => {
7980
hideOnDisable,
8081
rowDecorator = () => ({}),
8182
sx = {},
83+
addSpacerColumn = false,
8284
} = props;
8385

8486
const _isSelected = (row: { [x: string]: any }) => {
@@ -131,7 +133,7 @@ const AttuGrid: FC<AttuGridType> = props => {
131133
containerHeight -
132134
tableHeaderHeight -
133135
(showPagination ? pagerHeight : 0) -
134-
(hasToolbar ? 47 : 0);
136+
(hasToolbar ? 42 : 0);
135137

136138
const rowCount = Math.floor(totalHeight / rowHeight);
137139

@@ -226,6 +228,7 @@ const AttuGrid: FC<AttuGridType> = props => {
226228
orderBy={orderBy}
227229
rowHeight={rowHeight}
228230
rowDecorator={rowDecorator}
231+
addSpacerColumn={addSpacerColumn}
229232
></Table>
230233
{rowCount && showPagination ? (
231234
<TablePagination

client/src/components/grid/Table.tsx

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,26 @@ import CopyButton from '../advancedSearch/CopyButton';
1616
import type { Theme } from '@mui/material/styles';
1717
import type { TableType } from './Types';
1818

19+
/**
20+
* Enhanced Table Component
21+
*
22+
* Usage example with spacer column:
23+
* <AttuGrid
24+
* colDefinitions={[
25+
* { id: 'name', label: 'Name', disablePadding: false },
26+
* { id: 'age', label: 'Age', disablePadding: false }
27+
* ]}
28+
* addSpacerColumn={true} // This will add a spacer column that absorbs remaining space
29+
* // ... other props
30+
* />
31+
*
32+
* The spacer column will:
33+
* - Have width: 'auto' and minWidth: 'auto'
34+
* - Display no content
35+
* - Naturally absorb remaining horizontal space without forcing table width
36+
* - Prevent unnecessary horizontal scrollbars
37+
*/
38+
1939
const EnhancedTable: FC<TableType> = props => {
2040
let {
2141
selected,
@@ -44,10 +64,30 @@ const EnhancedTable: FC<TableType> = props => {
4464
orderBy,
4565
rowDecorator = () => ({}),
4666
rowHeight,
67+
// whether to add a spacer column to control space distribution
68+
addSpacerColumn = false,
4769
} = props;
4870

4971
const hasData = rows && rows.length > 0;
5072

73+
// Add spacer column definition if needed
74+
const finalColDefinitions = addSpacerColumn
75+
? [
76+
...colDefinitions,
77+
{
78+
id: '__spacer__',
79+
align: 'left' as const,
80+
disablePadding: false,
81+
label: '',
82+
getStyle: () => ({
83+
width: '66.7%',
84+
minWidth: 'auto',
85+
}),
86+
formatter: () => null,
87+
},
88+
]
89+
: colDefinitions;
90+
5191
return (
5292
<TableContainer
5393
sx={theme => ({
@@ -70,7 +110,7 @@ const EnhancedTable: FC<TableType> = props => {
70110
>
71111
{!headEditable ? (
72112
<EnhancedTableHead
73-
colDefinitions={colDefinitions}
113+
colDefinitions={finalColDefinitions}
74114
numSelected={selected.length}
75115
order={order}
76116
orderBy={orderBy}
@@ -144,12 +184,30 @@ const EnhancedTable: FC<TableType> = props => {
144184
</TableCell>
145185
)}
146186

147-
{colDefinitions.map((colDef, i) => {
187+
{finalColDefinitions.map((colDef, i) => {
148188
const { actionBarConfigs = [], needCopy = false } =
149189
colDef;
150190
const cellStyleFromDef = colDef.getStyle
151191
? colDef.getStyle(row[colDef.id])
152192
: {};
193+
194+
// Skip rendering for spacer column
195+
if (colDef.id === '__spacer__') {
196+
return (
197+
<TableCell
198+
key={colDef.id}
199+
sx={[
200+
(theme: Theme) => ({
201+
borderBottom: `1px solid ${theme.palette.divider}`,
202+
}),
203+
cellStyleFromDef,
204+
]}
205+
>
206+
{/* Empty content for spacer column */}
207+
</TableCell>
208+
);
209+
}
210+
153211
return colDef.showActionCell ? (
154212
<TableCell
155213
sx={
@@ -323,8 +381,8 @@ const EnhancedTable: FC<TableType> = props => {
323381
})}
324382
colSpan={
325383
openCheckBox
326-
? colDefinitions.length + 1
327-
: colDefinitions.length
384+
? finalColDefinitions.length + 1
385+
: finalColDefinitions.length
328386
}
329387
>
330388
{noData}
@@ -344,8 +402,8 @@ const EnhancedTable: FC<TableType> = props => {
344402
})}
345403
colSpan={
346404
openCheckBox
347-
? colDefinitions.length + 1
348-
: colDefinitions.length
405+
? finalColDefinitions.length + 1
406+
: finalColDefinitions.length
349407
}
350408
>
351409
<LoadingTable />

client/src/components/grid/Types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ export type TableType = {
9999
order?: SortDirection;
100100
orderBy?: string;
101101
ref?: Ref<HTMLDivElement>;
102+
// whether to add a spacer column to control space distribution
103+
addSpacerColumn?: boolean;
102104
};
103105

104106
export type ColDefinitionsType = {
@@ -159,6 +161,8 @@ export type AttuGridType = ToolBarType & {
159161
pagerHeight?: number;
160162
rowDecorator?: (row: any) => SxProps<Theme> | React.CSSProperties;
161163
sx?: SxProps<Theme>;
164+
// whether to add a spacer column to control space distribution
165+
addSpacerColumn?: boolean;
162166
};
163167

164168
export type ActionBarType = {

client/src/hooks/Query.ts

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,24 @@ export const useQuery = (params: {
5959
};
6060

6161
// query function
62-
const query = async (
63-
page: number = currentPage,
64-
consistency_level = queryState.consistencyLevel,
65-
_outputFields = queryState.outputFields,
66-
expr = queryState.expr
67-
) => {
62+
const query = async (page: number = currentPage, queryState: QueryState) => {
6863
if (!collection || !collection.loaded) return;
69-
const _expr = getPageExpr(page, expr);
64+
const _expr = getPageExpr(page, queryState.expr);
7065

7166
onQueryStart(_expr);
7267

68+
// each queryState.outputFields can not be a function output
69+
const outputFields = queryState.outputFields.filter(
70+
f =>
71+
!collection.schema.fields.find(ff => ff.name === f)?.is_function_output
72+
);
73+
7374
try {
7475
const queryParams = {
7576
expr: _expr,
76-
output_fields: _outputFields,
77+
output_fields: outputFields,
7778
limit: pageSize || 10,
78-
consistency_level,
79+
consistency_level: queryState.consistencyLevel,
7980
// travel_timestamp: timeTravelInfo.timestamp,
8081
};
8182

@@ -111,7 +112,7 @@ export const useQuery = (params: {
111112

112113
onQueryEnd?.(res);
113114
} catch (e: any) {
114-
reset();
115+
reset(true);
115116
} finally {
116117
onQueryFinally?.();
117118
}
@@ -142,9 +143,11 @@ export const useQuery = (params: {
142143
};
143144

144145
// reset
145-
const reset = () => {
146+
const reset = (clearData = false) => {
146147
setCurrentPage(0);
147-
setQueryResult({ data: [], latency: 0 });
148+
if (clearData) {
149+
setQueryResult({ data: [], latency: 0 });
150+
}
148151

149152
pageCache.current.clear();
150153
};
@@ -166,12 +169,7 @@ export const useQuery = (params: {
166169
count(queryState.consistencyLevel, queryState.expr);
167170

168171
// Then fetch actual data
169-
query(
170-
currentPage,
171-
queryState.consistencyLevel,
172-
queryState.outputFields,
173-
queryState.expr
174-
);
172+
query(currentPage, queryState);
175173
}, [
176174
pageSize,
177175
queryState.outputFields,
@@ -181,6 +179,19 @@ export const useQuery = (params: {
181179
queryState.tick,
182180
]);
183181

182+
// Reset state when collection changes
183+
useEffect(() => {
184+
// Immediately reset when collection changes to avoid showing stale data
185+
setQueryResult({ data: [], latency: 0 });
186+
setCurrentPage(0);
187+
pageCache.current.clear();
188+
189+
// Set total to collection row count as fallback
190+
if (collection) {
191+
setTotal(collection.rowCount || 0);
192+
}
193+
}, [collection.collection_name]);
194+
184195
return {
185196
// total query count
186197
total,

client/src/pages/databases/Databases.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,7 @@ const Databases = () => {
227227
// if query state not found, and the schema is ready, create new query state
228228
if (!query && c.schema) {
229229
setQueryState(prevState => {
230-
const fields = [...c.schema.fields].filter(
231-
f => !f.is_function_output
232-
);
230+
const fields = c.schema.fields;
233231
return [
234232
...prevState,
235233
{

client/src/pages/databases/collections/Collections.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,8 @@ const Collections = () => {
468468
page={currentPage}
469469
onPageChange={handlePageChange}
470470
rowsPerPage={pageSize}
471-
tableHeaderHeight={46}
472-
rowHeight={41}
471+
tableHeaderHeight={44}
472+
rowHeight={42}
473473
setRowsPerPage={handlePageSize}
474474
isLoading={loading}
475475
handleSort={handleGridSort}

0 commit comments

Comments
 (0)