diff --git a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.fixture.ts b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.fixture.ts index 1fd31b482ec6..1f0786862759 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.fixture.ts +++ b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.fixture.ts @@ -267,6 +267,10 @@ const statementsPagePropsFixture: StatementsPageProps = { "3": "gcp-us-west1", "4": "gcp-europe-west1", }, + sortSetting: { + ascending: false, + columnTitle: "executionCount" + }, statements: [ { label: @@ -686,6 +690,7 @@ const statementsPagePropsFixture: StatementsPageProps = { onSearchComplete: noop, onDiagnosticsReportDownload: noop, onColumnsChange: noop, + onSortingChange: noop, }; export const statementsPagePropsWithRequestError: StatementsPageProps = { diff --git a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.selectors.ts b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.selectors.ts index 140c33b33b65..3d2299ec7bb3 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.selectors.ts +++ b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.selectors.ts @@ -237,3 +237,8 @@ export const selectDateRange = createSelector( Moment, ], ); + +export const selectSortSetting = createSelector( + localStorageSelector, + localStorage => localStorage["sortSetting/StatementsPage"], +); diff --git a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.spec.tsx b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.spec.tsx index 6254c894dcec..e70548843e98 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.spec.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.spec.tsx @@ -37,10 +37,10 @@ describe("StatementsPage", () => { const statementsPageInstance = statementsPageWrapper.instance(); assert.equal( - statementsPageInstance.state.sortSetting.columnTitle, + statementsPageInstance.props.sortSetting.columnTitle, "executionCount", ); - assert.equal(statementsPageInstance.state.sortSetting.ascending, false); + assert.equal(statementsPageInstance.props.sortSetting.ascending, false); }); }); }); diff --git a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.tsx b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.tsx index 423ef13d432c..0c34dec54144 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.tsx @@ -105,11 +105,11 @@ export interface StatementsPageStateProps { lastReset: string; columns: string[]; nodeRegions: { [key: string]: string }; + sortSetting: SortSetting; isTenant?: UIConfigState["isTenant"]; } export interface StatementsPageState { - sortSetting: SortSetting; search?: string; pagination: ISortedTablePagination; filters?: Filters; @@ -141,11 +141,6 @@ export class StatementsPage extends React.Component< this.props.history.location.search, ); const defaultState = { - sortSetting: { - // Sort by Execution Count column as default option. - ascending: false, - columnTitle: "executionCount", - }, pagination: { pageSize: 20, current: 1, @@ -167,24 +162,26 @@ export class StatementsPage extends React.Component< getStateFromHistory = (): Partial => { const { history } = this.props; const searchParams = new URLSearchParams(history.location.search); - const ascending = searchParams.get("ascending") || undefined; - const columnTitle = searchParams.get("columnTitle") || undefined; const searchQuery = searchParams.get("q") || undefined; + const ascending = (searchParams.get("ascending") || undefined) === "true"; + const columnTitle = searchParams.get("columnTitle") || undefined; + const sortSetting = this.props.sortSetting; + + if ( + this.props.onSortingChange && + columnTitle && + (sortSetting.columnTitle != columnTitle || + sortSetting.ascending != ascending) + ) { + this.props.onSortingChange("Statements", columnTitle, ascending); + } return { - sortSetting: { - ascending: ascending === "true", - columnTitle, - }, search: searchQuery, }; }; changeSortSetting = (ss: SortSetting): void => { - this.setState({ - sortSetting: ss, - }); - syncHistory( { ascending: ss.ascending.toString(), @@ -421,6 +418,7 @@ export class StatementsPage extends React.Component< onColumnsChange, nodeRegions, isTenant, + sortSetting, } = this.props; const appAttrValue = queryByName(location, appAttr); const selectedApp = appAttrValue || ""; @@ -544,7 +542,7 @@ export class StatementsPage extends React.Component< className="statements-table" data={data} columns={displayColumns} - sortSetting={this.state.sortSetting} + sortSetting={sortSetting} onChangeSortSetting={this.changeSortSetting} renderNoResult={ ({ refreshStatements: (req?: StatementsRequest) => @@ -115,7 +117,11 @@ export const ConnectedStatementsPage = withRouter( value, }), ), - onSortingChange: (tableName: string, columnName: string) => + onSortingChange: ( + tableName: string, + columnName: string, + ascending: boolean, + ) => { dispatch( analyticsActions.track({ name: "Column Sorted", @@ -123,7 +129,14 @@ export const ConnectedStatementsPage = withRouter( tableName, columnName, }), - ), + ); + dispatch( + localStorageActions.update({ + key: "sortSetting/StatementsPage", + value: { columnTitle: columnName, ascending: ascending }, + }), + ); + }, onStatementClick: () => dispatch( analyticsActions.track({ diff --git a/pkg/ui/workspaces/cluster-ui/src/store/localStorage/localStorage.reducer.ts b/pkg/ui/workspaces/cluster-ui/src/store/localStorage/localStorage.reducer.ts index 27cde4cb3f9d..e28dbc27fda8 100644 --- a/pkg/ui/workspaces/cluster-ui/src/store/localStorage/localStorage.reducer.ts +++ b/pkg/ui/workspaces/cluster-ui/src/store/localStorage/localStorage.reducer.ts @@ -17,11 +17,17 @@ type StatementsDateRangeState = { end: number; }; +type SortSetting = { + ascending: boolean; + columnTitle: string; +}; + export type LocalStorageState = { "adminUi/showDiagnosticsModal": boolean; "showColumns/StatementsPage": string; "showColumns/TransactionPage": string; "dateRange/StatementsPage": StatementsDateRangeState; + "sortSetting/StatementsPage": SortSetting; }; type Payload = { @@ -37,6 +43,11 @@ const defaultDateRange: StatementsDateRangeState = { end: moment.utc().unix() + 60, // Add 1 minute to account for potential lag. }; +const defaultSortSetting: SortSetting = { + ascending: false, + columnTitle: "executionCount", +}; + // TODO (koorosh): initial state should be restored from preserved keys in LocalStorage const initialState: LocalStorageState = { "adminUi/showDiagnosticsModal": @@ -49,6 +60,9 @@ const initialState: LocalStorageState = { "dateRange/StatementsPage": JSON.parse(localStorage.getItem("dateRange/StatementsPage")) || defaultDateRange, + "sortSetting/StatementsPage": + JSON.parse(localStorage.getItem("sortSetting/StatementsPage")) || + defaultSortSetting, }; const localStorageSlice = createSlice({ diff --git a/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.fixture.ts b/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.fixture.ts index 9d889dd7190c..a8d9ecce9f17 100644 --- a/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.fixture.ts +++ b/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.fixture.ts @@ -180,6 +180,10 @@ const statementsPagePropsFixture: StatementsPageProps = { "3": "gcp-us-west1", "4": "gcp-europe-west1", }, + sortSetting: { + ascending: false, + columnTitle: "executionCount", + }, columns: null, match: { path: "/statements", diff --git a/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.tsx b/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.tsx index 67dc9fad54ba..60e5940cb850 100644 --- a/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.tsx +++ b/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.tsx @@ -46,7 +46,6 @@ import { trackDownloadDiagnosticsBundleAction, trackStatementsPaginationAction, trackStatementsSearchAction, - trackTableSortAction, } from "src/redux/analyticsActions"; import { resetSQLStatsAction } from "src/redux/sqlStats"; import { LocalSetting } from "src/redux/localsettings"; @@ -232,18 +231,25 @@ export const statementColumnsLocalSetting = new LocalSetting( null, ); +export const sortSettingLocalSetting = new LocalSetting( + "sortSetting/StatementsPage", + (state: AdminUIState) => state.localSettings, + { ascending: false, columnTitle: "executionCount" }, +); + export default withRouter( connect( (state: AdminUIState, props: RouteComponentProps) => ({ statements: selectStatements(state, props), statementsError: state.cachedData.statements.lastError, - dateRange: selectDateRange(state), apps: selectApps(state), databases: selectDatabases(state), totalFingerprints: selectTotalFingerprints(state), lastReset: selectLastReset(state), columns: statementColumnsLocalSetting.selectorToArray(state), nodeRegions: nodeRegionsByIDSelector(state), + dateRange: selectDateRange(state), + sortSetting: sortSettingLocalSetting.selector(state), }), { refreshStatements: refreshStatements, @@ -257,7 +263,15 @@ export default withRouter( onSearchComplete: (results: AggregateStatistics[]) => trackStatementsSearchAction(results.length), onPageChanged: trackStatementsPaginationAction, - onSortingChange: trackTableSortAction, + onSortingChange: ( + _tableName: string, + columnName: string, + ascending: boolean, + ) => + sortSettingLocalSetting.set({ + ascending: ascending, + columnTitle: columnName, + }), onDiagnosticsReportDownload: (report: IStatementDiagnosticsReport) => trackDownloadDiagnosticsBundleAction(report.statement_fingerprint), // We use `null` when the value was never set and it will show all columns.