diff --git a/pkg/ui/workspaces/cluster-ui/src/api/eventsApi.ts b/pkg/ui/workspaces/cluster-ui/src/api/eventsApi.ts index e152efd85008..b5d4bac7ce18 100644 --- a/pkg/ui/workspaces/cluster-ui/src/api/eventsApi.ts +++ b/pkg/ui/workspaces/cluster-ui/src/api/eventsApi.ts @@ -14,6 +14,8 @@ import { SqlExecutionRequest, sqlResultsAreEmpty, SqlStatement, + SqlApiResponse, + formatApiResult, } from "./sqlApi"; import { withTimeout } from "./util"; import moment from "moment"; @@ -89,20 +91,20 @@ export function buildEventsSQLRequest( export function getNonRedactedEvents( req: NonRedactedEventsRequest = {}, timeout?: moment.Duration, -): Promise { +): Promise> { const eventsRequest: SqlExecutionRequest = buildEventsSQLRequest(req); return withTimeout( executeInternalSql(eventsRequest), timeout, ).then(result => { - // If request succeeded but query failed, throw error (caught by saga/cacheDataReducer). - if (result.error) { - throw result.error; - } - if (sqlResultsAreEmpty(result)) { - return []; + return formatApiResult([], result.error, "retrieving events information"); } - return result.execution.txn_results[0].rows; + + return formatApiResult( + result.execution.txn_results[0].rows, + result.error, + "retrieving events information", + ); }); } diff --git a/pkg/ui/workspaces/db-console/src/redux/apiReducers.ts b/pkg/ui/workspaces/db-console/src/redux/apiReducers.ts index 0f1807bcfa04..8995bac0c08d 100644 --- a/pkg/ui/workspaces/db-console/src/redux/apiReducers.ts +++ b/pkg/ui/workspaces/db-console/src/redux/apiReducers.ts @@ -524,7 +524,9 @@ export const refreshRawTrace = rawTraceReducerObj.refresh; export interface APIReducersState { cluster: CachedDataReducerState; - events: CachedDataReducerState; + events: CachedDataReducerState< + clusterUiApi.SqlApiResponse + >; health: HealthState; nodes: CachedDataReducerState; raft: CachedDataReducerState; diff --git a/pkg/ui/workspaces/db-console/src/redux/events.ts b/pkg/ui/workspaces/db-console/src/redux/events.ts index 073e6ef4e613..57e071816ff3 100644 --- a/pkg/ui/workspaces/db-console/src/redux/events.ts +++ b/pkg/ui/workspaces/db-console/src/redux/events.ts @@ -14,7 +14,7 @@ import { AdminUIState } from "src/redux/state"; * eventsSelector selects the list of events from the store. */ export function eventsSelector(state: AdminUIState) { - return state.cachedData.events.data; + return state.cachedData.events?.data?.results; } /** @@ -27,3 +27,7 @@ export function eventsValidSelector(state: AdminUIState) { export function eventsLastErrorSelector(state: AdminUIState) { return state.cachedData.events.lastError; } + +export const eventsMaxApiReached = (state: AdminUIState): boolean => { + return !!state.cachedData.events?.data?.maxSizeReached; +}; diff --git a/pkg/ui/workspaces/db-console/src/util/api.spec.ts b/pkg/ui/workspaces/db-console/src/util/api.spec.ts index 0b1fe15f8ca4..55af5a3e6554 100644 --- a/pkg/ui/workspaces/db-console/src/util/api.spec.ts +++ b/pkg/ui/workspaces/db-console/src/util/api.spec.ts @@ -330,7 +330,7 @@ describe("rest api", function () { return clusterUiApi.getNonRedactedEvents().then(result => { expect(fetchMock.calls(clusterUiApi.SQL_API_PATH).length).toBe(1); - expect(result.length).toBe(1); + expect(result.results.length).toBe(1); }); }); @@ -364,7 +364,7 @@ describe("rest api", function () { return clusterUiApi.getNonRedactedEvents(req).then(result => { expect(fetchMock.calls(clusterUiApi.SQL_API_PATH).length).toBe(1); - expect(result.length).toBe(1); + expect(result.results.length).toBe(1); }); }); diff --git a/pkg/ui/workspaces/db-console/src/views/cluster/containers/events/index.tsx b/pkg/ui/workspaces/db-console/src/views/cluster/containers/events/index.tsx index 505233051f7e..1c5bab561d93 100644 --- a/pkg/ui/workspaces/db-console/src/views/cluster/containers/events/index.tsx +++ b/pkg/ui/workspaces/db-console/src/views/cluster/containers/events/index.tsx @@ -19,6 +19,7 @@ import { eventsLastErrorSelector, eventsSelector, eventsValidSelector, + eventsMaxApiReached, } from "src/redux/events"; import { LocalSetting } from "src/redux/localsettings"; import { AdminUIState } from "src/redux/state"; @@ -31,6 +32,7 @@ import { util, api as clusterUiApi, } from "@cockroachlabs/cluster-ui"; +import { InlineAlert } from "@cockroachlabs/ui-components"; import "./events.styl"; // Number of events to show in the sidebar. @@ -134,6 +136,7 @@ export interface EventPageProps { sortSetting: SortSetting; setSort: typeof eventsSortSetting.set; lastError: Error; + maxSizeApiReached: boolean; } export class EventPageUnconnected extends React.Component { @@ -148,30 +151,43 @@ export class EventPageUnconnected extends React.Component { } renderContent() { - const { events, sortSetting } = this.props; + const { events, sortSetting, maxSizeApiReached } = this.props; const simplifiedEvents = _.map(events, getEventInfo); return ( -
- this.props.setSort(setting)} - columns={[ - { - title: "Event", - name: "event", - cell: e => e.content, - }, - { - title: "Timestamp", - name: "timestamp", - cell: e => e.fromNowString, - sort: e => e.sortableTimestamp, - }, - ]} - /> -
+ <> +
+ this.props.setSort(setting)} + columns={[ + { + title: "Event", + name: "event", + cell: e => e.content, + }, + { + title: "Timestamp", + name: "timestamp", + cell: e => e.fromNowString, + sort: e => e.sortableTimestamp, + }, + ]} + /> +
+ {maxSizeApiReached && ( + + Not all events are displayed because the maximum number of + events was reached in the console.  + + } + /> + )} + ); } @@ -183,7 +199,7 @@ export class EventPageUnconnected extends React.Component {

Events

-
+