Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export type CollectionViewContextType = {
limit: number;
};
setJsonSchema(schema: object): Promise<void>; //monacoEditor.languages.json.DiagnosticsOptions, but we don't want to import monacoEditor here
setSort: (sort: string) => void;
};
isAiRowVisible: boolean; // Controls visibility of the AI prompt row in QueryEditor
queryInsights: QueryInsightsState; // Query insights state for progressive loading
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ export const QueryEditor = ({ onExecuteRequest }: QueryEditorProps): JSX.Element
* any pending schema update is cancelled before a new one begins, guaranteeing
* a clean, predictable state and allowing the Monaco worker to initialize correctly.
*/
setSort: (sort: string) => {
setSortValue(sort);
},
setJsonSchema: async (schema) => {
// Use the ref to cancel the previous operation
if (schemaAbortControllerRef.current) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,62 @@ export function DataViewPanelTable({ liveHeaders, liveData, handleStepIn }: Prop
field: header,
minWidth: 100,
formatter: cellFormatter,
sortable: true,
// No-op comparer: server-side sort replaces the dataset, so we don't want
// SlickGrid's default field-value comparer to scramble our typed cell objects.
sorter: () => 0,
};
});

// Tracks the current sort state for tri-state cycling (asc -> desc -> none).
const sortStateRef = useRef<{ field: string | null; direction: 'asc' | 'desc' | null }>({
field: null,
direction: null,
});

const onSort = React.useCallback(
(event: CustomEvent<{ args: { sortCol?: { field?: string }; sortAsc?: boolean } }>): void => {
const sortCol = event.detail.args.sortCol;
const field = sortCol?.field;
if (!field) {
return;
}
const newAsc = event.detail.args.sortAsc !== false;
const prev = sortStateRef.current;

// Tri-state cycle: when SlickGrid wraps from desc back to asc on the same column, clear it.
let nextField: string | null;
let nextDir: 'asc' | 'desc' | null;
if (prev.field === field && prev.direction === 'desc' && newAsc) {
nextField = null;
nextDir = null;
// Clear SlickGrid's sort indicator
gridRef.current?.sortService?.clearSorting?.();
} else {
nextField = field;
nextDir = newAsc ? 'asc' : 'desc';
}
sortStateRef.current = { field: nextField, direction: nextDir };

const sortJson = nextField ? `{ "${nextField}": ${nextDir === 'asc' ? 1 : -1} }` : '{ }';

// Update the Sort input in the QueryEditor so the user sees what was applied.
currentContext.queryEditor?.setSort?.(sortJson);

// Trigger a refresh by updating activeQuery (mirrors the executeQuery flow).
setCurrentContext((prevCtx) => ({
...prevCtx,
activeQuery: {
...prevCtx.activeQuery,
sort: sortJson,
pageNumber: 1,
executionIntent: 'refresh',
},
}));
},
[currentContext.queryEditor, setCurrentContext],
);

// Update grid columns ref whenever they change
React.useEffect(() => {
gridColumnsRef.current = gridColumns;
Expand Down Expand Up @@ -139,6 +192,9 @@ export function DataViewPanelTable({ liveHeaders, liveData, handleStepIn }: Prop
enableCellNavigation: true,
enableTextSelectionOnCells: true,

enableSorting: true,
multiColumnSort: false,

enableCheckboxSelector: false, // todo: [post MVP] this is failing, it looks like it happens when we're defining columns after the grid has been created.. we're deleting the 'checkbox' column. we can work around it, but it needs a bit more attention to get it done right.
enableRowSelection: true,
multiSelect: true,
Expand Down Expand Up @@ -215,6 +271,9 @@ export function DataViewPanelTable({ liveHeaders, liveData, handleStepIn }: Prop
columns={gridColumns}
dataset={liveData}
onDblClick={(event) => onCellDblClick(event)}
onSort={(event) =>
onSort(event as CustomEvent<{ args: { sortCol?: { field?: string }; sortAsc?: boolean } }>)
}
onSelectedRowsChanged={debounce(
(event: { detail: { eventData: unknown; args: OnSelectedRowsChangedEventArgs } }) =>
onSelectedRowsChanged(event.detail.eventData, event.detail.args),
Expand Down