Skip to content

Commit

Permalink
ui: save search query on cache for Statements page
Browse files Browse the repository at this point in the history
Previously, a search  was not maintained when
the page change (e.g. coming back from Transaction details).
This commits saves the selected value to be used.

Partially adresses cockroachdb#71851

Release note: None
  • Loading branch information
maryliag committed Nov 24, 2021
1 parent 50768de commit 2965602
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ const statementsPagePropsFixture: StatementsPageProps = {
ascending: false,
columnTitle: "executionCount"
},
search: "",
filters: {
app: "",
timeNumber: "0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,8 @@ export const selectFilters = createSelector(
localStorageSelector,
localStorage => localStorage["filters/StatementsPage"],
);

export const selectSearch = createSelector(
localStorageSelector,
localStorage => localStorage["search/StatementsPage"],
);
79 changes: 51 additions & 28 deletions pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export interface StatementsPageDispatchProps {
dismissAlertMessage: () => void;
onActivateStatementDiagnostics: (statement: string) => void;
onDiagnosticsModalOpen?: (statement: string) => void;
onSearchComplete?: (results: AggregateStatistics[]) => void;
onSearchComplete?: (query: string) => void;
onPageChanged?: (newPage: number) => void;
onSortingChange?: (
name: string,
Expand All @@ -112,11 +112,11 @@ export interface StatementsPageStateProps {
nodeRegions: { [key: string]: string };
sortSetting: SortSetting;
filters: Filters;
search: string;
isTenant?: UIConfigState["isTenant"];
}

export interface StatementsPageState {
search?: string;
pagination: ISortedTablePagination;
filters?: Filters;
activeFilters?: number;
Expand Down Expand Up @@ -148,37 +148,46 @@ export class StatementsPage extends React.Component<
pageSize: 20,
current: 1,
},
search: "",
};
const stateFromHistory = this.getStateFromHistory();
this.state = merge(defaultState, stateFromHistory);
this.activateDiagnosticsRef = React.createRef();
}

getStateFromHistory = (): Partial<StatementsPageState> => {
const { history, sortSetting, filters } = this.props;
const {
history,
search,
sortSetting,
filters,
onSearchComplete,
onFilterChange,
onSortingChange,
} = this.props;
const searchParams = new URLSearchParams(history.location.search);

// Search query.
const searchQuery = searchParams.get("q") || undefined;
if (onSearchComplete && searchQuery && search != searchQuery) {
onSearchComplete(searchQuery);
}

// Sort Settings.
handleSortSettingFromQueryString(
"Statements",
history.location.search,
sortSetting,
this.props.onSortingChange,
onSortingChange,
);

// Filters.
const latestFilter = handleFiltersFromQueryString(
history,
filters,
this.props.onFilterChange,
onFilterChange,
);

return {
search: searchQuery,
filters: latestFilter,
activeFilters: calculateActiveFilters(latestFilter),
};
Expand Down Expand Up @@ -235,31 +244,39 @@ export class StatementsPage extends React.Component<
}

updateQueryParamsOnTabSwitch(): void {
updateFiltersQueryParamsOnTab(
"Statements",
this.state.filters,
this.props.history,
);
const { history, search, sortSetting } = this.props;
const tab = "Statements";

// Search.
const searchParams = new URLSearchParams(history.location.search);
const currentTab = searchParams.get("tab") || "";
const searchQueryString = searchParams.get("q") || "";
if (currentTab === tab && search && search != searchQueryString) {
syncHistory(
{
q: search,
},
history,
);
}

// Filters.
updateFiltersQueryParamsOnTab(tab, this.state.filters, history);

// Sort Setting.
updateSortSettingQueryParamsOnTab(
"Statements",
this.props.sortSetting,
tab,
sortSetting,
{
ascending: false,
columnTitle: "executionCount",
},
this.props.history,
history,
);
}

componentDidUpdate = (
__: StatementsPageProps,
prevState: StatementsPageState,
): void => {
componentDidUpdate = (): void => {
this.updateQueryParamsOnTabSwitch();
if (this.state.search && this.state.search !== prevState.search) {
this.props.onSearchComplete(this.filteredStatementsData());
}
this.refreshStatements();
if (!this.props.isTenant) {
this.props.refreshStatementDiagnosticsRequests();
Expand All @@ -277,7 +294,9 @@ export class StatementsPage extends React.Component<
};

onSubmitSearchField = (search: string): void => {
this.setState({ search });
if (this.props.onSearchComplete) {
this.props.onSearchComplete(search);
}
this.resetPagination();
syncHistory(
{
Expand Down Expand Up @@ -314,7 +333,9 @@ export class StatementsPage extends React.Component<
};

onClearSearchField = (): void => {
this.setState({ search: "" });
if (this.props.onSearchComplete) {
this.props.onSearchComplete("");
}
syncHistory(
{
q: undefined,
Expand All @@ -339,6 +360,7 @@ export class StatementsPage extends React.Component<
app: undefined,
timeNumber: undefined,
timeUnit: undefined,
fullScan: undefined,
sqlType: undefined,
database: undefined,
regions: undefined,
Expand All @@ -349,8 +371,8 @@ export class StatementsPage extends React.Component<
};

filteredStatementsData = (): AggregateStatistics[] => {
const { search, filters } = this.state;
const { statements, nodeRegions, isTenant } = this.props;
const { filters } = this.state;
const { search, statements, nodeRegions, isTenant } = this.props;
const timeValue = getTimeValueInSeconds(filters);
const sqlTypes =
filters.sqlType.length > 0
Expand Down Expand Up @@ -382,7 +404,7 @@ export class StatementsPage extends React.Component<
.filter(statement => (filters.fullScan ? statement.fullScan : true))
.filter(statement =>
search
.split(" ")
?.split(" ")
.every(val =>
statement.label.toLowerCase().includes(val.toLowerCase()),
),
Expand Down Expand Up @@ -430,7 +452,7 @@ export class StatementsPage extends React.Component<
};

renderStatements = (): React.ReactElement => {
const { pagination, search, filters, activeFilters } = this.state;
const { pagination, filters, activeFilters } = this.state;
const {
statements,
apps,
Expand All @@ -443,6 +465,7 @@ export class StatementsPage extends React.Component<
nodeRegions,
isTenant,
sortSetting,
search,
} = this.props;
const data = this.filteredStatementsData();
const totalWorkload = calculateTotalWorkload(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ import {
selectDateRange,
selectSortSetting,
selectFilters,
selectSearch,
} from "./statementsPage.selectors";
import { selectIsTenant } from "../store/uiConfig";
import { AggregateStatistics } from "../statementsTable";
import { nodeRegionsByIDSelector } from "../store/nodes";
import { StatementsRequest } from "src/api/statementsApi";

Expand All @@ -49,18 +49,19 @@ export const ConnectedStatementsPage = withRouter(
RouteComponentProps
>(
(state: AppState, props: StatementsPageProps) => ({
statements: selectStatements(state, props),
statementsError: selectStatementsLastError(state),
apps: selectApps(state),
columns: selectColumns(state),
databases: selectDatabases(state),
totalFingerprints: selectTotalFingerprints(state),
dateRange: selectDateRange(state),
filters: selectFilters(state),
isTenant: selectIsTenant(state),
lastReset: selectLastReset(state),
columns: selectColumns(state),
nodeRegions: selectIsTenant(state) ? {} : nodeRegionsByIDSelector(state),
dateRange: selectDateRange(state),
search: selectSearch(state),
sortSetting: selectSortSetting(state),
isTenant: selectIsTenant(state),
filters: selectFilters(state),
statements: selectStatements(state, props),
statementsError: selectStatementsLastError(state),
totalFingerprints: selectTotalFingerprints(state),
}),
(dispatch: Dispatch) => ({
refreshStatements: (req?: StatementsRequest) =>
Expand Down Expand Up @@ -103,13 +104,20 @@ export const ConnectedStatementsPage = withRouter(
action: "Downloaded",
}),
),
onSearchComplete: (_results: AggregateStatistics[]) =>
onSearchComplete: (query: string) => {
dispatch(
analyticsActions.track({
name: "Keyword Searched",
page: "Statements",
}),
),
);
dispatch(
localStorageActions.update({
key: "search/StatementsPage",
value: query,
}),
);
},
onFilterChange: value => {
dispatch(
analyticsActions.track({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export type LocalStorageState = {
"sortSetting/SessionsPage": SortSetting;
"filters/StatementsPage": Filters;
"filters/TransactionsPage": Filters;
"search/StatementsPage": string;
};

type Payload = {
Expand Down Expand Up @@ -85,6 +86,8 @@ const initialState: LocalStorageState = {
"filters/TransactionsPage":
JSON.parse(localStorage.getItem("filters/TransactionsPage")) ||
defaultFilters,
"search/StatementsPage":
JSON.parse(localStorage.getItem("search/StatementsPage")) || null,
};

const localStorageSlice = createSlice({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ const statementsPagePropsFixture: StatementsPageProps = {
ascending: false,
columnTitle: "executionCount",
},
search: "",
filters: {
app: "",
timeNumber: "0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ import {
import {
trackDownloadDiagnosticsBundleAction,
trackStatementsPaginationAction,
trackStatementsSearchAction,
} from "src/redux/analyticsActions";
import { resetSQLStatsAction } from "src/redux/sqlStats";
import { LocalSetting } from "src/redux/localsettings";
Expand Down Expand Up @@ -251,20 +250,27 @@ export const filtersLocalSetting = new LocalSetting(
defaultFilters,
);

export const searchLocalSetting = new LocalSetting(
"search/StatementsPage",
(state: AdminUIState) => state.localSettings,
null,
);

export default withRouter(
connect(
(state: AdminUIState, props: RouteComponentProps) => ({
statements: selectStatements(state, props),
statementsError: state.cachedData.statements.lastError,
apps: selectApps(state),
columns: statementColumnsLocalSetting.selectorToArray(state),
databases: selectDatabases(state),
totalFingerprints: selectTotalFingerprints(state),
dateRange: selectDateRange(state),
filters: filtersLocalSetting.selector(state),
lastReset: selectLastReset(state),
columns: statementColumnsLocalSetting.selectorToArray(state),
nodeRegions: nodeRegionsByIDSelector(state),
dateRange: selectDateRange(state),
search: searchLocalSetting.selector(state),
sortSetting: sortSettingLocalSetting.selector(state),
filters: filtersLocalSetting.selector(state),
statements: selectStatements(state, props),
statementsError: state.cachedData.statements.lastError,
totalFingerprints: selectTotalFingerprints(state),
}),
{
refreshStatements: refreshStatements,
Expand All @@ -275,8 +281,7 @@ export default withRouter(
createStatementDiagnosticsAlertLocalSetting.set({ show: false }),
onActivateStatementDiagnostics: createStatementDiagnosticsReportAction,
onDiagnosticsModalOpen: createOpenDiagnosticsModalAction,
onSearchComplete: (results: AggregateStatistics[]) =>
trackStatementsSearchAction(results.length),
onSearchComplete: (query: string) => searchLocalSetting.set(query),
onPageChanged: trackStatementsPaginationAction,
onSortingChange: (
_tableName: string,
Expand Down

0 comments on commit 2965602

Please sign in to comment.