diff --git a/pkg/ui/workspaces/cluster-ui/src/api/indexActionsApi.ts b/pkg/ui/workspaces/cluster-ui/src/api/indexActionsApi.ts index 39e09bb1d776..22066da7d4ec 100644 --- a/pkg/ui/workspaces/cluster-ui/src/api/indexActionsApi.ts +++ b/pkg/ui/workspaces/cluster-ui/src/api/indexActionsApi.ts @@ -26,7 +26,7 @@ export function executeIndexRecAction( databaseName: string, ): Promise { const statements = stmts - .split(";") + ?.split(";") .filter(stmt => stmt.trim().length != 0) .map(stmt => { return { sql: stmt.trim() }; diff --git a/pkg/ui/workspaces/cluster-ui/src/api/schemaInsightsApi.ts b/pkg/ui/workspaces/cluster-ui/src/api/schemaInsightsApi.ts index 64794d20bd33..481bc5314992 100644 --- a/pkg/ui/workspaces/cluster-ui/src/api/schemaInsightsApi.ts +++ b/pkg/ui/workspaces/cluster-ui/src/api/schemaInsightsApi.ts @@ -95,7 +95,7 @@ function createIndexRecommendationsToSchemaInsight( txn_result.rows.forEach(row => { row.index_recommendations.forEach(rec => { - const recSplit = rec.split(" : "); + const recSplit = rec?.split(" : "); const recType = recSplit[0]; const recQuery = recSplit[1]; let idxType: InsightType; diff --git a/pkg/ui/workspaces/cluster-ui/src/api/txnInsightsApi.ts b/pkg/ui/workspaces/cluster-ui/src/api/txnInsightsApi.ts index 1e7b99a3c564..b46e63b635a4 100644 --- a/pkg/ui/workspaces/cluster-ui/src/api/txnInsightsApi.ts +++ b/pkg/ui/workspaces/cluster-ui/src/api/txnInsightsApi.ts @@ -384,7 +384,7 @@ function formatTxnInsightsRow(row: TxnInsightsResponseRow): TxnInsightEvent { transactionExecutionID: row.txn_id, transactionFingerprintID: row.txn_fingerprint_id, implicitTxn: row.implicit_txn, - query: row.query.split(" ; ").join("\n"), + query: row.query?.split(" ; ").join("\n"), startTime, endTime, elapsedTimeMillis: endTime.diff(startTime, "milliseconds"), diff --git a/pkg/ui/workspaces/cluster-ui/src/databaseDetailsPage/databaseDetailsPage.tsx b/pkg/ui/workspaces/cluster-ui/src/databaseDetailsPage/databaseDetailsPage.tsx index de00c45ade4b..802ae299ecf8 100644 --- a/pkg/ui/workspaces/cluster-ui/src/databaseDetailsPage/databaseDetailsPage.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/databaseDetailsPage/databaseDetailsPage.tsx @@ -181,7 +181,7 @@ function filterBySearchQuery( } const res = search - .toLowerCase() + ?.toLowerCase() .split(" ") .every(val => matchString.includes(val)); @@ -279,7 +279,7 @@ export class DatabaseDetailsPage extends React.Component< changeSortSetting = (ss: SortSetting): void => { syncHistory( { - ascending: ss.ascending.toString(), + ascending: ss.ascending?.toString(), columnTitle: ss.columnTitle, }, this.props.history, @@ -378,9 +378,9 @@ export class DatabaseDetailsPage extends React.Component< const { search, tables, filters, nodeRegions } = this.props; const regionsSelected = - filters.regions.length > 0 ? filters.regions.split(",") : []; + filters.regions?.length > 0 ? filters.regions?.split(",") : []; const nodesSelected = - filters.nodes.length > 0 ? filters.nodes.split(",") : []; + filters.nodes?.length > 0 ? filters.nodes?.split(",") : []; return tables .filter(table => (search ? filterBySearchQuery(table, search) : true)) @@ -394,11 +394,11 @@ export class DatabaseDetailsPage extends React.Component< table.details.nodes?.forEach(node => { if ( foundRegion || - regionsSelected.includes(nodeRegions[node.toString()]) + regionsSelected.includes(nodeRegions[node?.toString()]) ) { foundRegion = true; } - if (foundNode || nodesSelected.includes("n" + node.toString())) { + if (foundNode || nodesSelected.includes("n" + node?.toString())) { foundNode = true; } if (foundNode && foundRegion) return true; @@ -411,7 +411,7 @@ export class DatabaseDetailsPage extends React.Component< private changeViewMode(viewMode: ViewMode) { syncHistory( { - viewMode: viewMode.toString(), + viewMode: viewMode?.toString(), }, this.props.history, ); @@ -738,7 +738,7 @@ export class DatabaseDetailsPage extends React.Component< hideAppNames={true} regions={regions} hideTimeLabel={true} - nodes={nodes.map(n => "n" + n.toString())} + nodes={nodes.map(n => "n" + n?.toString())} activeFilters={activeFilters} filters={defaultFilters} onSubmitFilters={this.onSubmitFilters} diff --git a/pkg/ui/workspaces/cluster-ui/src/databaseTablePage/databaseTablePage.tsx b/pkg/ui/workspaces/cluster-ui/src/databaseTablePage/databaseTablePage.tsx index 596b07bebe99..7aa060bfc54c 100644 --- a/pkg/ui/workspaces/cluster-ui/src/databaseTablePage/databaseTablePage.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/databaseTablePage/databaseTablePage.tsx @@ -298,7 +298,7 @@ export class DatabaseTablePage extends React.Component< searchParams.set(columnTitleAttr, sortSetting.columnTitle); searchParams.set(ascendingAttr, String(sortSetting.ascending)); - history.location.search = searchParams.toString(); + history.location.search = searchParams?.toString(); history.replace(history.location); } diff --git a/pkg/ui/workspaces/cluster-ui/src/databasesPage/databasesPage.tsx b/pkg/ui/workspaces/cluster-ui/src/databasesPage/databasesPage.tsx index b268e3ae9594..670366e47be7 100644 --- a/pkg/ui/workspaces/cluster-ui/src/databasesPage/databasesPage.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/databasesPage/databasesPage.tsx @@ -155,7 +155,7 @@ function filterBySearchQuery( } return search - .toLowerCase() + ?.toLowerCase() .split(" ") .every(val => matchString.includes(val)); } @@ -329,7 +329,7 @@ export class DatabasesPage extends React.Component< changeSortSetting = (ss: SortSetting): void => { syncHistory( { - ascending: ss.ascending.toString(), + ascending: ss.ascending?.toString(), columnTitle: ss.columnTitle, }, this.props.history, @@ -424,9 +424,9 @@ export class DatabasesPage extends React.Component< // The regions and nodes selected from the filter dropdown. const regionsSelected = - filters.regions.length > 0 ? filters.regions.split(",") : []; + filters.regions?.length > 0 ? filters.regions?.split(",") : []; const nodesSelected = - filters.nodes.length > 0 ? filters.nodes.split(",") : []; + filters.nodes?.length > 0 ? filters.nodes?.split(",") : []; return databases .filter(db => (search ? filterBySearchQuery(db, search) : true)) @@ -440,11 +440,11 @@ export class DatabasesPage extends React.Component< db.nodes?.forEach(node => { if ( foundRegion || - regionsSelected.includes(nodeRegions[node.toString()]) + regionsSelected.includes(nodeRegions[node?.toString()]) ) { foundRegion = true; } - if (foundNode || nodesSelected.includes("n" + node.toString())) { + if (foundNode || nodesSelected.includes("n" + node?.toString())) { foundNode = true; } if (foundNode && foundRegion) return true; @@ -617,7 +617,7 @@ export class DatabasesPage extends React.Component< hideAppNames={true} regions={regions} hideTimeLabel={true} - nodes={nodes.map(n => "n" + n.toString())} + nodes={nodes.map(n => "n" + n?.toString())} activeFilters={activeFilters} filters={defaultFilters} onSubmitFilters={this.onSubmitFilters} diff --git a/pkg/ui/workspaces/cluster-ui/src/highlightedText/highlightedText.tsx b/pkg/ui/workspaces/cluster-ui/src/highlightedText/highlightedText.tsx index 7858a0ce3abc..c0341667e865 100644 --- a/pkg/ui/workspaces/cluster-ui/src/highlightedText/highlightedText.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/highlightedText/highlightedText.tsx @@ -34,7 +34,7 @@ export function getWordAt(word: string, text: string): number { } function rebaseText(text: string, highlight: string): string { - const search = highlight.split(" "); + const search = highlight?.split(" "); const maxLength = 425; const defaultCropLength = 150; const defaultBeforeAfterCrop = 20; @@ -88,7 +88,7 @@ export function getHighlightedText( "highlightNotDefined", ); const search = highlight - .split(" ") + ?.split(" ") .map(val => { if (val.length > 0) { return val.toLowerCase(); @@ -97,7 +97,7 @@ export function getHighlightedText( }) .join("|"); const parts = isOriginalText - ? text.split(new RegExp(`(${search})`, "gi")) + ? text?.split(new RegExp(`(${search})`, "gi")) : rebaseText(text, highlight).split(new RegExp(`(${search})`, "gi")); const highlightClass = hasDarkBkg ? "_text-bold-light" : "_text-bold"; return parts.map((part, i) => { diff --git a/pkg/ui/workspaces/cluster-ui/src/indexDetailsPage/indexDetailsPage.tsx b/pkg/ui/workspaces/cluster-ui/src/indexDetailsPage/indexDetailsPage.tsx index 35e3b0b3774b..17b31149ba6b 100644 --- a/pkg/ui/workspaces/cluster-ui/src/indexDetailsPage/indexDetailsPage.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/indexDetailsPage/indexDetailsPage.tsx @@ -423,7 +423,7 @@ export class IndexDetailsPage extends React.Component< statement.applicationName.startsWith(INTERNAL_APP_NAME_PREFIX); if (filters.app && filters.app !== "All") { - const criteria = decodeURIComponent(filters.app).split(","); + const criteria = decodeURIComponent(filters.app)?.split(","); let showInternal = false; if (criteria.includes(INTERNAL_APP_NAME_PREFIX)) { showInternal = true; @@ -465,7 +465,7 @@ export class IndexDetailsPage extends React.Component< const regions = unique( isTenant ? flatMap(statements, statement => statement.stats.regions) - : nodes.map(node => nodeRegions[node.toString()]), + : nodes.map(node => nodeRegions[node?.toString()]), ).sort(); const filteredStmts = this.filteredStatements(); diff --git a/pkg/ui/workspaces/cluster-ui/src/insights/indexActionBtn.tsx b/pkg/ui/workspaces/cluster-ui/src/insights/indexActionBtn.tsx index ae5779903df7..0cda2668f962 100644 --- a/pkg/ui/workspaces/cluster-ui/src/insights/indexActionBtn.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/insights/indexActionBtn.tsx @@ -198,7 +198,7 @@ function addIdxName(statement: string): string { return statement; } let result = ""; - const statements = statement.split(";"); + const statements = statement?.split(";"); for (let i = 0; i < statements.length; i++) { if (statements[i].trim().toUpperCase().startsWith("CREATE INDEX ON ")) { result = `${result}${createIdxName(statements[i])}; `; @@ -241,7 +241,7 @@ export function createIdxName(statement: string): string { } info = info.substring(0, i - 1); - const variables = info.split(","); + const variables = info?.split(","); let expressions = 0; let value; for (let i = 0; i < variables.length; i++) { diff --git a/pkg/ui/workspaces/cluster-ui/src/insights/utils.ts b/pkg/ui/workspaces/cluster-ui/src/insights/utils.ts index ab26aadc11a6..0b39dd6265a1 100644 --- a/pkg/ui/workspaces/cluster-ui/src/insights/utils.ts +++ b/pkg/ui/workspaces/cluster-ui/src/insights/utils.ts @@ -38,7 +38,7 @@ export const filterTransactionInsights = ( txn?.application?.startsWith(internalAppNamePrefix); if (filters.app) { filteredTransactions = filteredTransactions.filter(txn => { - const apps = filters.app.toString().split(","); + const apps = filters.app?.toString().split(","); let showInternal = false; if (apps.includes(internalAppNamePrefix)) { showInternal = true; @@ -108,8 +108,8 @@ export const filterSchemaInsights = ( if (filters.database) { const databases = - filters.database.toString().length > 0 - ? filters.database.toString().split(",") + filters.database?.toString().length > 0 + ? filters.database?.toString().split(",") : []; if (databases.includes(unset)) { databases.push(""); diff --git a/pkg/ui/workspaces/cluster-ui/src/multiSelectCheckbox/multiSelectCheckbox.tsx b/pkg/ui/workspaces/cluster-ui/src/multiSelectCheckbox/multiSelectCheckbox.tsx index 417f9440ba4c..31f059b5dbf3 100644 --- a/pkg/ui/workspaces/cluster-ui/src/multiSelectCheckbox/multiSelectCheckbox.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/multiSelectCheckbox/multiSelectCheckbox.tsx @@ -106,7 +106,7 @@ export const MultiSelectCheckbox = (props: MultiSelectCheckboxProps) => { .map(function (option: SelectOption) { return option.label; }) - .toString(); + ?.toString(); parent.setState({ filters: { ...parent.state.filters, diff --git a/pkg/ui/workspaces/cluster-ui/src/queryFilter/filter.tsx b/pkg/ui/workspaces/cluster-ui/src/queryFilter/filter.tsx index 9b38208ff5ac..f72423f8809f 100644 --- a/pkg/ui/workspaces/cluster-ui/src/queryFilter/filter.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/queryFilter/filter.tsx @@ -194,7 +194,7 @@ export const handleFiltersFromQueryString = ( app: filters.app, timeNumber: filters.timeNumber, timeUnit: filters.timeUnit, - fullScan: filters.fullScan.toString(), + fullScan: filters.fullScan?.toString(), sqlType: filters.sqlType, database: filters.database, regions: filters.regions, @@ -237,7 +237,7 @@ export const updateFiltersQueryParamsOnTab = ( app: filters.app, timeNumber: filters.timeNumber, timeUnit: filters.timeUnit, - fullScan: filters.fullScan.toString(), + fullScan: filters.fullScan?.toString(), sqlType: filters.sqlType, database: filters.database, regions: filters.regions, @@ -482,7 +482,7 @@ export class Filter extends React.Component { })) : []; const usernameValue = usernameOptions.filter(option => { - return filters.username.split(",").includes(option.label); + return filters.username?.split(",").includes(option.label); }); const usernameFilter = (
@@ -508,7 +508,7 @@ export class Filter extends React.Component { })) : []; const sessionStatusValue = sessionStatusOptions.filter(option => { - return filters.sessionStatus.split(",").includes(option.label); + return filters.sessionStatus?.split(",").includes(option.label); }); const sessionStatusFilter = (
@@ -536,7 +536,7 @@ export class Filter extends React.Component { })) : []; const executionStatusValue = executionStatusOptions.filter(option => - filters.executionStatus.split(",").includes(option.label), + filters.executionStatus?.split(",").includes(option.label), ); const executionStatusFilter = (
@@ -564,7 +564,7 @@ export class Filter extends React.Component { })) : []; const schemaInsightTypeValue = schemaInsightTypeOptions.filter(option => { - return filters.schemaInsightType.split(",").includes(option.label); + return filters.schemaInsightType?.split(",").includes(option.label); }); const schemaInsightTypeFilter = (
@@ -619,7 +619,7 @@ export class Filter extends React.Component { })) : []; const regionsValue = regionsOptions.filter(option => - filters.regions.split(",").includes(option.label), + filters.regions?.split(",").includes(option.label), ); const regionsFilter = (
@@ -642,7 +642,7 @@ export class Filter extends React.Component { })) : []; const nodesValue = nodesOptions.filter(option => { - return filters.nodes.split(",").includes(option.label); + return filters.nodes?.split(",").includes(option.label); }); const nodesFilter = (
@@ -836,7 +836,7 @@ interface FilterBadgeProps { function FilterBadge(props: FilterBadgeProps): React.ReactElement { const { filters, name, values, onRemoveFilter } = props; const unit = name === "timeNumber" ? props.unit : ""; - let value = `${getLabelFromKey(name)}: ${values.toString()} ${unit}`; + let value = `${getLabelFromKey(name)}: ${values?.toString()} ${unit}`; if (value.length > 100) { value = value.substring(0, 100) + "..."; } diff --git a/pkg/ui/workspaces/cluster-ui/src/selectors/recentExecutions.selectors.ts b/pkg/ui/workspaces/cluster-ui/src/selectors/recentExecutions.selectors.ts index e790115fe9d4..75cb2fa25432 100644 --- a/pkg/ui/workspaces/cluster-ui/src/selectors/recentExecutions.selectors.ts +++ b/pkg/ui/workspaces/cluster-ui/src/selectors/recentExecutions.selectors.ts @@ -96,7 +96,7 @@ export const selectContentionDetailsForStatement = createSelector( export const selectAppName = createSelector( (state: AppState) => state.adminUI?.sessions, response => { - if (!response.data) return null; + if (!response?.data) return null; return response.data.internal_app_name_prefix; }, ); diff --git a/pkg/ui/workspaces/cluster-ui/src/sessions/sessionDetails.tsx b/pkg/ui/workspaces/cluster-ui/src/sessions/sessionDetails.tsx index a4b82c830437..0f0c75028dba 100644 --- a/pkg/ui/workspaces/cluster-ui/src/sessions/sessionDetails.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/sessions/sessionDetails.tsx @@ -173,7 +173,7 @@ export class SessionDetails extends React.Component { if (session.active_queries?.length > 0) { this.terminateQueryRef?.current?.showModalFor({ query_id: session.active_queries[0].id, - node_id: session.node_id.toString(), + node_id: session.node_id?.toString(), }); } }} @@ -187,7 +187,7 @@ export class SessionDetails extends React.Component { onTerminateSessionClick && onTerminateSessionClick(); this.terminateSessionRef?.current?.showModalFor({ session_id: session.id, - node_id: session.node_id.toString(), + node_id: session.node_id?.toString(), }); }} type="secondary" @@ -385,12 +385,12 @@ export class SessionDetails extends React.Component { this.props.uiConfig?.showGatewayNodeLink ? (
) : ( - session.node_id.toString() + session.node_id?.toString() ) } /> diff --git a/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsPage.tsx b/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsPage.tsx index 3fde145b7787..88f3df8e9a3f 100644 --- a/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsPage.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsPage.tsx @@ -184,7 +184,7 @@ export class SessionsPage extends React.Component< syncHistory( { - ascending: ss.ascending.toString(), + ascending: ss.ascending?.toString(), columnTitle: ss.columnTitle, }, this.props.history, diff --git a/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsPageConnected.tsx b/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsPageConnected.tsx index b6e8732ba1c8..c766cd9c3ecb 100644 --- a/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsPageConnected.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsPageConnected.tsx @@ -36,7 +36,7 @@ export const selectSessionsData = createSelector( export const selectSessions = createSelector( (state: AppState) => state.adminUI?.sessions, (state: SessionsState) => { - if (!state.data) { + if (!state?.data) { return null; } return state.data.sessions.map(session => { @@ -48,7 +48,7 @@ export const selectSessions = createSelector( export const selectAppName = createSelector( (state: AppState) => state.adminUI?.sessions, (state: SessionsState) => { - if (!state.data) { + if (!state?.data) { return null; } return state.data.internal_app_name_prefix; @@ -64,7 +64,7 @@ export const selectColumns = createSelector( localStorageSelector, localStorage => localStorage["showColumns/SessionsPage"] - ? localStorage["showColumns/SessionsPage"].split(",") + ? localStorage["showColumns/SessionsPage"]?.split(",") : null, ); @@ -135,7 +135,7 @@ export const SessionsPageConnected = withRouter( name: "Filter Clicked", page: "Sessions", filterName: "filters", - value: value.toString(), + value: value?.toString(), }), ); dispatch( diff --git a/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsTable.tsx b/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsTable.tsx index 03e8378e1c7f..c043e898f626 100644 --- a/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsTable.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/sessions/sessionsTable.tsx @@ -284,7 +284,7 @@ export function makeSessionsColumns( onTerminateSessionClick && onTerminateSessionClick(); terminateSessionRef?.current?.showModalFor({ session_id: session.id, - node_id: session.node_id.toString(), + node_id: session.node_id?.toString(), }); break; case "cancelStatement": @@ -292,7 +292,7 @@ export function makeSessionsColumns( onTerminateStatementClick && onTerminateStatementClick(); terminateQueryRef?.current?.showModalFor({ query_id: session.active_queries[0].id, - node_id: session.node_id.toString(), + node_id: session.node_id?.toString(), }); } break; diff --git a/pkg/ui/workspaces/cluster-ui/src/sortedtable/sortedtable.spec.tsx b/pkg/ui/workspaces/cluster-ui/src/sortedtable/sortedtable.spec.tsx index 8168570a9ab8..44882d0ae7c5 100644 --- a/pkg/ui/workspaces/cluster-ui/src/sortedtable/sortedtable.spec.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/sortedtable/sortedtable.spec.tsx @@ -37,7 +37,7 @@ const columns: ColumnDescriptor[] = [ { name: "second", title: "second", - cell: tr => tr.value.toString(), + cell: tr => tr.value?.toString(), sort: tr => tr.value, rollup: trs => _.sumBy(trs, tr => tr.value), }, @@ -130,7 +130,7 @@ describe("", function () { ); assert.equal( row.childAt(0).childAt(1).text(), - rowData.value.toString(), + rowData.value?.toString(), "second columns match", ); }); diff --git a/pkg/ui/workspaces/cluster-ui/src/sortedtable/sortedtable.tsx b/pkg/ui/workspaces/cluster-ui/src/sortedtable/sortedtable.tsx index 4a0c26ec9fc9..89617fa2f2f6 100644 --- a/pkg/ui/workspaces/cluster-ui/src/sortedtable/sortedtable.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/sortedtable/sortedtable.tsx @@ -427,7 +427,9 @@ export function longListWithTooltip( {value.split(", ").join("\r\n")} +
+          {value?.split(", ").join("\r\n")}
+        
} >
{summary}
@@ -490,7 +492,7 @@ export const updateSortSettingQueryParamsOnTab = ( const currentTab = searchParams.get("tab") || ""; const ascending = (searchParams.get("ascending") || - defaultSortSetting.ascending.toString()) === "true"; + defaultSortSetting.ascending?.toString()) === "true"; const columnTitle = searchParams.get("columnTitle") || defaultSortSetting.columnTitle; if ( @@ -499,7 +501,7 @@ export const updateSortSettingQueryParamsOnTab = ( sortSetting.ascending != ascending) ) { const params = { - ascending: sortSetting.ascending.toString(), + ascending: sortSetting.ascending?.toString(), columnTitle: sortSetting.columnTitle, }; const nextSearchParams = new URLSearchParams(history.location.search); @@ -510,7 +512,7 @@ export const updateSortSettingQueryParamsOnTab = ( nextSearchParams.set(key, value); } }); - history.location.search = nextSearchParams.toString(); + history.location.search = nextSearchParams?.toString(); history.replace(history.location); } }; diff --git a/pkg/ui/workspaces/cluster-ui/src/sqlActivity/util.tsx b/pkg/ui/workspaces/cluster-ui/src/sqlActivity/util.tsx index 5f0bb539cc4e..d770226c812a 100644 --- a/pkg/ui/workspaces/cluster-ui/src/sqlActivity/util.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/sqlActivity/util.tsx @@ -22,7 +22,7 @@ export function filteredStatementsData( ): AggregateStatistics[] { const timeValue = getTimeValueInSeconds(filters); const sqlTypes = - filters.sqlType.length > 0 + filters.sqlType?.length > 0 ? filters.sqlType.split(",").map(function (sqlType: string) { // Adding "Type" to match the value on the Statement // Possible values: TypeDDL, TypeDML, TypeDCL and TypeTCL @@ -30,12 +30,12 @@ export function filteredStatementsData( }) : []; const databases = - filters.database.length > 0 ? filters.database.split(",") : []; + filters.database?.length > 0 ? filters.database.split(",") : []; if (databases.includes(unset)) { databases.push(""); } - const regions = filters.regions.length > 0 ? filters.regions.split(",") : []; - const nodes = filters.nodes.length > 0 ? filters.nodes.split(",") : []; + const regions = filters.regions?.length > 0 ? filters.regions.split(",") : []; + const nodes = filters.nodes?.length > 0 ? filters.nodes.split(",") : []; // Return statements filtered by the values selected on the filter and // the search text. A statement must match all selected filters to be diff --git a/pkg/ui/workspaces/cluster-ui/src/statementDetails/planDetails/planDetails.tsx b/pkg/ui/workspaces/cluster-ui/src/statementDetails/planDetails/planDetails.tsx index 699eafd1c117..c07965345f07 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementDetails/planDetails/planDetails.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/statementDetails/planDetails/planDetails.tsx @@ -241,7 +241,7 @@ function formatIdxRecommendations( for (let i = 0; i < idxRecs.length; i++) { const rec = idxRecs[i]; let idxType: InsightType; - const t = rec.split(" : ")[0]; + const t = rec?.split(" : ")[0]; switch (t) { case "creation": idxType = "CreateIndex"; @@ -259,7 +259,7 @@ function formatIdxRecommendations( const idxRec: InsightRecommendation = { type: idxType, database: database, - query: rec.split(" : ")[1], + query: rec?.split(" : ")[1], execution: { statement: query, summary: query.length > 120 ? query.slice(0, 120) + "..." : query, diff --git a/pkg/ui/workspaces/cluster-ui/src/statementDetails/planDetails/plansTable.tsx b/pkg/ui/workspaces/cluster-ui/src/statementDetails/planDetails/plansTable.tsx index 26895d6d6534..2082b0e4476d 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementDetails/planDetails/plansTable.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/statementDetails/planDetails/plansTable.tsx @@ -203,7 +203,7 @@ export function formatIndexes(indexes: string[], database: string): ReactNode { if (!indexes[i].includes("@")) { continue; } - indexInfo = indexes[i].split("@"); + indexInfo = indexes[i]?.split("@"); tableName = indexInfo[0]; idxName = indexInfo[1]; if (indexMap.has(tableName)) { diff --git a/pkg/ui/workspaces/cluster-ui/src/statementDetails/planView/planView.tsx b/pkg/ui/workspaces/cluster-ui/src/statementDetails/planView/planView.tsx index 3a4dd1b6ae7b..45ef78f04d0c 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementDetails/planView/planView.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/statementDetails/planView/planView.tsx @@ -145,7 +145,7 @@ function shouldHideNode(nodeName: string): boolean { // hyphens to camel case. '(anti)' is also removed from the resulting string. export function standardizeKey(str: string): string { return str - .toLowerCase() + ?.toLowerCase() .split(/[ -]+/) .filter(str => str !== "(anti)") .map((str, i) => @@ -268,12 +268,12 @@ export function PlanView({ const globalAttrs: FlatPlanNodeAttribute[] = [ { key: "distribution", - values: [globalProperties.distribution.toString()], + values: [globalProperties.distribution?.toString()], warn: false, // distribution is never warned }, { key: "vectorized", - values: [globalProperties.vectorized.toString()], + values: [globalProperties.vectorized?.toString()], warn: false, // vectorized is never warned }, ]; diff --git a/pkg/ui/workspaces/cluster-ui/src/statementDetails/statementDetails.tsx b/pkg/ui/workspaces/cluster-ui/src/statementDetails/statementDetails.tsx index 303acbac3143..1ce066e5cb1e 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementDetails/statementDetails.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/statementDetails/statementDetails.tsx @@ -186,7 +186,7 @@ function AppLink(props: { app: string }) { return ( {props.app} @@ -357,7 +357,7 @@ export class StatementDetails extends React.Component< searchParams.set("tab", tabId); history.replace({ ...history.location, - search: searchParams.toString(), + search: searchParams?.toString(), }); this.setState({ currentTab: tabId, @@ -550,7 +550,7 @@ export class StatementDetails extends React.Component< this.props.statementDetails; const nodes: string[] = unique( - (stats.nodes || []).map(node => node.toString()), + (stats.nodes || []).map(node => node?.toString()), ).sort(); const regions = unique( isTenant 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 f0be5e98c63c..427e6d717dad 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.selectors.ts +++ b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.selectors.ts @@ -64,12 +64,12 @@ export const selectApps = createSelector(sqlStatsSelector, sqlStatsState => { let sawBlank = false; let sawInternal = false; const apps: { [app: string]: boolean } = {}; - sqlStatsState.data.statements.forEach( + sqlStatsState?.data?.statements.forEach( (statement: ICollectedStatementStatistics) => { if ( - sqlStatsState.data.internal_app_name_prefix && - statement.key.key_data.app.startsWith( - sqlStatsState.data.internal_app_name_prefix, + sqlStatsState?.data?.internal_app_name_prefix && + statement?.key?.key_data.app.startsWith( + sqlStatsState?.data?.internal_app_name_prefix, ) ) { sawInternal = true; @@ -81,18 +81,18 @@ export const selectApps = createSelector(sqlStatsSelector, sqlStatsState => { }, ); return [] - .concat(sawInternal ? [sqlStatsState.data.internal_app_name_prefix] : []) + .concat(sawInternal ? [sqlStatsState?.data.internal_app_name_prefix] : []) .concat(sawBlank ? [unset] : []) .concat(Object.keys(apps).sort()); }); // selectDatabases returns the array of all databases in the cluster. export const selectDatabases = createSelector(databasesListSelector, state => { - if (!state.data) { + if (!state?.data) { return []; } - return state.data.databases + return state?.data.databases .filter((dbName: string) => dbName !== null && dbName.length > 0) .sort(); }); @@ -102,7 +102,7 @@ export const selectDatabases = createSelector(databasesListSelector, state => { export const selectTotalFingerprints = createSelector( sqlStatsSelector, state => { - if (!state.data) { + if (!state?.data) { return 0; } const aggregated = aggregateStatementStats(state.data.statements); @@ -113,7 +113,7 @@ export const selectTotalFingerprints = createSelector( // selectLastReset returns a string displaying the last time the statement // statistics were reset. export const selectLastReset = createSelector(sqlStatsSelector, state => { - if (!state.data) { + if (!state?.data) { return ""; } @@ -144,18 +144,18 @@ export const selectStatements = createSelector( diagnosticsReportsPerStatement, ): AggregateStatistics[] => { // State is valid if we successfully fetched data, and the data has not yet been invalidated. - if (!state.data || !state.valid) { + if (!state?.data || !state?.valid) { return null; } let statements = flattenStatementStats(state.data.statements); const app = queryByName(props.location, appAttr); const isInternal = (statement: ExecutionStatistics) => - statement.app.startsWith(state.data.internal_app_name_prefix); + statement.app.startsWith(state?.data.internal_app_name_prefix); if (app && app !== "All") { const criteria = decodeURIComponent(app).split(","); let showInternal = false; - if (criteria.includes(state.data.internal_app_name_prefix)) { + if (criteria.includes(state?.data.internal_app_name_prefix)) { showInternal = true; } if (criteria.includes(unset)) { @@ -229,7 +229,7 @@ export const selectColumns = createSelector( // return array of columns if user have customized it or `null` otherwise localStorage => localStorage["showColumns/StatementsPage"] - ? localStorage["showColumns/StatementsPage"].split(",") + ? localStorage["showColumns/StatementsPage"]?.split(",") : null, ); diff --git a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.tsx b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.tsx index f4904b19d3b7..8caa43ccd2e1 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.tsx @@ -197,7 +197,7 @@ export function filterBySearchQuery( } return search - .toLowerCase() + ?.toLowerCase() .split(" ") .every( val => matchString.includes(val) || matchFingerPrintId.includes(val), @@ -268,7 +268,7 @@ export class StatementsPage extends React.Component< changeSortSetting = (ss: SortSetting): void => { syncHistory( { - ascending: ss.ascending.toString(), + ascending: ss.ascending?.toString(), columnTitle: ss.columnTitle, }, this.props.history, @@ -452,7 +452,7 @@ export class StatementsPage extends React.Component< app: filters.app, timeNumber: filters.timeNumber, timeUnit: filters.timeUnit, - fullScan: filters.fullScan.toString(), + fullScan: filters.fullScan?.toString(), sqlType: filters.sqlType, database: filters.database, regions: filters.regions, @@ -549,7 +549,7 @@ export class StatementsPage extends React.Component< const regions = unique( isTenant ? flatMap(statements, statement => statement.stats.regions) - : nodes.map(node => nodeRegions[node.toString()]), + : nodes.map(node => nodeRegions[node?.toString()]), ).sort(); // If the cluster is a tenant cluster we don't show info @@ -561,7 +561,7 @@ export class StatementsPage extends React.Component< // hiding columns that won't be displayed for tenants. const columns = makeStatementsColumns( statements, - filters.app.split(","), + filters.app?.split(","), this.props.stmtsTotalRuntimeSecs, "statement", isTenant, diff --git a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPageConnected.tsx b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPageConnected.tsx index df8c6668f568..23fd7d72ebe9 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPageConnected.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPageConnected.tsx @@ -205,7 +205,7 @@ export const ConnectedStatementsPage = withRouter( name: "Filter Clicked", page: "Statements", filterName: "filters", - value: value.toString(), + value: value?.toString(), }), ); dispatch( diff --git a/pkg/ui/workspaces/cluster-ui/src/statementsTable/statementsTable.tsx b/pkg/ui/workspaces/cluster-ui/src/statementsTable/statementsTable.tsx index 8964473ce5c2..f6e87496a078 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementsTable/statementsTable.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/statementsTable/statementsTable.tsx @@ -392,7 +392,7 @@ export function populateRegionNodeForStatements( // E.g. {"gcp-us-east1" : [1,3,4]} if (stmt.stats.nodes) { stmt.stats.nodes.forEach(node => { - const region = nodeRegions[node.toString()]; + const region = nodeRegions[node?.toString()]; if (region) { if (Object.keys(regions).includes(region)) { regions[region].add(longToInt(node)); @@ -412,7 +412,7 @@ export function populateRegionNodeForStatements( Array.from(regions[region]) .sort() .map(n => "n" + n) - .toString() + + ?.toString() + ")", ); }); diff --git a/pkg/ui/workspaces/cluster-ui/src/store/insights/statementInsights/statementInsights.selectors.ts b/pkg/ui/workspaces/cluster-ui/src/store/insights/statementInsights/statementInsights.selectors.ts index f30b39bf3c68..8a66abaa7d21 100644 --- a/pkg/ui/workspaces/cluster-ui/src/store/insights/statementInsights/statementInsights.selectors.ts +++ b/pkg/ui/workspaces/cluster-ui/src/store/insights/statementInsights/statementInsights.selectors.ts @@ -46,7 +46,7 @@ export const selectColumns = createSelector( localStorageSelector, localStorage => localStorage["showColumns/StatementInsightsPage"] - ? localStorage["showColumns/StatementInsightsPage"].split(",") + ? localStorage["showColumns/StatementInsightsPage"]?.split(",") : null, ); diff --git a/pkg/ui/workspaces/cluster-ui/src/store/jobs/jobs.selectors.ts b/pkg/ui/workspaces/cluster-ui/src/store/jobs/jobs.selectors.ts index f5aa7de346b8..2d5fc6288f5d 100644 --- a/pkg/ui/workspaces/cluster-ui/src/store/jobs/jobs.selectors.ts +++ b/pkg/ui/workspaces/cluster-ui/src/store/jobs/jobs.selectors.ts @@ -42,6 +42,6 @@ export const selectColumns = createSelector( // return array of columns if user have customized it or `null` otherwise localStorage => localStorage["showColumns/JobsPage"] - ? localStorage["showColumns/JobsPage"].split(",") + ? localStorage["showColumns/JobsPage"]?.split(",") : null, ); diff --git a/pkg/ui/workspaces/cluster-ui/src/store/sessions/sessions.selectors.ts b/pkg/ui/workspaces/cluster-ui/src/store/sessions/sessions.selectors.ts index b9a4c0e2f46c..65ff4ce97e23 100644 --- a/pkg/ui/workspaces/cluster-ui/src/store/sessions/sessions.selectors.ts +++ b/pkg/ui/workspaces/cluster-ui/src/store/sessions/sessions.selectors.ts @@ -20,7 +20,7 @@ export const selectSession = createSelector( (state: AppState) => state.adminUI?.sessions, (_state: AppState, props: RouteComponentProps) => props, (state: SessionsState, props: RouteComponentProps) => { - if (!state.data) { + if (!state?.data) { return null; } const sessionID = getMatchParamByName(props.match, sessionAttr); diff --git a/pkg/ui/workspaces/cluster-ui/src/store/statementDetails/statementDetails.reducer.ts b/pkg/ui/workspaces/cluster-ui/src/store/statementDetails/statementDetails.reducer.ts index 77aec1076ef6..22464f0a2f07 100644 --- a/pkg/ui/workspaces/cluster-ui/src/store/statementDetails/statementDetails.reducer.ts +++ b/pkg/ui/workspaces/cluster-ui/src/store/statementDetails/statementDetails.reducer.ts @@ -75,7 +75,7 @@ const sqlDetailsStatsSlice = createSlice({ const key = action?.payload ? generateStmtDetailsToID( action.payload.fingerprint_id, - action.payload.app_names.toString(), + action.payload.app_names?.toString(), action.payload.start, action.payload.end, ) @@ -92,7 +92,7 @@ const sqlDetailsStatsSlice = createSlice({ const key = action?.payload ? generateStmtDetailsToID( action.payload.fingerprint_id, - action.payload.app_names.toString(), + action.payload.app_names?.toString(), action.payload.start, action.payload.end, ) diff --git a/pkg/ui/workspaces/cluster-ui/src/store/statementDetails/statementDetails.sagas.ts b/pkg/ui/workspaces/cluster-ui/src/store/statementDetails/statementDetails.sagas.ts index c73fabc72161..74a74e619be2 100644 --- a/pkg/ui/workspaces/cluster-ui/src/store/statementDetails/statementDetails.sagas.ts +++ b/pkg/ui/workspaces/cluster-ui/src/store/statementDetails/statementDetails.sagas.ts @@ -31,7 +31,7 @@ export function* requestSQLDetailsStatsSaga( const key = action?.payload ? generateStmtDetailsToID( action.payload.fingerprint_id, - action.payload.app_names.toString(), + action.payload.app_names?.toString(), action.payload.start, action.payload.end, ) diff --git a/pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetails.tsx b/pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetails.tsx index 63eb25d3b9be..e0066bc33eb0 100644 --- a/pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetails.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetails.tsx @@ -277,7 +277,7 @@ export class TransactionDetails extends React.Component< return ( statements?.filter( s => - s.key.key_data.transaction_fingerprint_id.toString() === + s.key.key_data.transaction_fingerprint_id?.toString() === this.props.transactionFingerprintId, ) ?? [] ); diff --git a/pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetailsConnected.tsx b/pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetailsConnected.tsx index 40de5b6ec8a1..190ef230c1c1 100644 --- a/pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetailsConnected.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetailsConnected.tsx @@ -67,7 +67,7 @@ export const selectTransaction = createSelector( const transaction = transactions.filter( txn => - txn.stats_data.transaction_fingerprint_id.toString() == + txn.stats_data.transaction_fingerprint_id?.toString() == txnFingerprintId, )[0]; return { diff --git a/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPage.selectors.ts b/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPage.selectors.ts index 3a9fd6b740e4..b5ede47c03ba 100644 --- a/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPage.selectors.ts +++ b/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPage.selectors.ts @@ -43,7 +43,7 @@ export const selectTxnColumns = createSelector( // return array of columns if user have customized it or `null` otherwise localStorage => localStorage["showColumns/TransactionPage"] - ? localStorage["showColumns/TransactionPage"].split(",") + ? localStorage["showColumns/TransactionPage"]?.split(",") : null, ); diff --git a/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPage.tsx b/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPage.tsx index 070c3c6038b9..2a9f17238b1e 100644 --- a/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPage.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPage.tsx @@ -282,7 +282,7 @@ export class TransactionsPage extends React.Component< onChangeSortSetting = (ss: SortSetting): void => { syncHistory( { - ascending: ss.ascending.toString(), + ascending: ss.ascending?.toString(), columnTitle: ss.columnTitle, }, this.props.history, @@ -493,7 +493,7 @@ export class TransactionsPage extends React.Component< const regions = unique( isTenant ? flatMap(statements, statement => statement.stats.regions) - : nodes.map(node => nodeRegions[node.toString()]), + : nodes.map(node => nodeRegions[node?.toString()]), ).sort(); // Creates a list of all possible columns, diff --git a/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPageConnected.tsx b/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPageConnected.tsx index a117a10f94c0..dc91f40cb810 100644 --- a/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPageConnected.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/transactionsPage/transactionsPageConnected.tsx @@ -143,7 +143,7 @@ export const TransactionsPageConnected = withRouter( name: "Filter Clicked", page: "Transactions", filterName: "filters", - value: value.toString(), + value: value?.toString(), }), ); dispatch( diff --git a/pkg/ui/workspaces/cluster-ui/src/transactionsPage/utils.ts b/pkg/ui/workspaces/cluster-ui/src/transactionsPage/utils.ts index 49459d7e099f..31d27ed3acbd 100644 --- a/pkg/ui/workspaces/cluster-ui/src/transactionsPage/utils.ts +++ b/pkg/ui/workspaces/cluster-ui/src/transactionsPage/utils.ts @@ -171,8 +171,8 @@ export const filterTransactions = ( activeFilters: 0, }; const timeValue = getTimeValueInSeconds(filters); - const regions = filters.regions.length > 0 ? filters.regions.split(",") : []; - const nodes = filters.nodes.length > 0 ? filters.nodes.split(",") : []; + const regions = filters.regions?.length > 0 ? filters.regions.split(",") : []; + const nodes = filters.nodes?.length > 0 ? filters.nodes.split(",") : []; const activeFilters = calculateActiveFilters(filters); @@ -292,7 +292,7 @@ export const generateRegionNode = ( ).forEach(stmt => { stmt.stats.nodes && stmt.stats.nodes.forEach(n => { - const node = n.toString(); + const node = n?.toString(); if (Object.keys(regions).includes(nodeRegions[node])) { regions[nodeRegions[node]].add(longToInt(n)); } else { @@ -311,7 +311,7 @@ export const generateRegionNode = ( Array.from(regions[region]) .sort() .map(n => "n" + n) - .toString() + + ?.toString() + ")", ); }); diff --git a/pkg/ui/workspaces/cluster-ui/src/transactionsTable/transactionsTable.tsx b/pkg/ui/workspaces/cluster-ui/src/transactionsTable/transactionsTable.tsx index 6d41731fdcfe..b403715265b8 100644 --- a/pkg/ui/workspaces/cluster-ui/src/transactionsTable/transactionsTable.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/transactionsTable/transactionsTable.tsx @@ -148,7 +148,7 @@ export function makeTransactionsColumns( ) || "Transaction query unavailable.", aggregatedTs: TimestampToString(item.stats_data.aggregated_ts), transactionFingerprintId: - item.stats_data.transaction_fingerprint_id.toString(), + item.stats_data.transaction_fingerprint_id?.toString(), search, }), sort: (item: TransactionInfo) => diff --git a/pkg/ui/workspaces/cluster-ui/src/util/appStats/appStats.ts b/pkg/ui/workspaces/cluster-ui/src/util/appStats/appStats.ts index 87c6b99f6b2b..62eb9058f937 100644 --- a/pkg/ui/workspaces/cluster-ui/src/util/appStats/appStats.ts +++ b/pkg/ui/workspaces/cluster-ui/src/util/appStats/appStats.ts @@ -355,7 +355,7 @@ export function statementKey(stmt: ExecutionStatistics): string { export function transactionScopedStatementKey( stmt: ExecutionStatistics, ): string { - return statementKey(stmt) + stmt.transaction_fingerprint_id.toString(); + return statementKey(stmt) + stmt.transaction_fingerprint_id?.toString(); } export const generateStmtDetailsToID = ( @@ -377,7 +377,7 @@ export const generateStmtDetailsToID = ( apps[i] = ""; } } - appNames = unique(apps).sort().toString(); + appNames = unique(apps)?.sort()?.toString(); } let generatedID = fingerprintID; if (appNames) { diff --git a/pkg/ui/workspaces/cluster-ui/src/util/format.ts b/pkg/ui/workspaces/cluster-ui/src/util/format.ts index a9c67ca6161f..e52f93a130a2 100644 --- a/pkg/ui/workspaces/cluster-ui/src/util/format.ts +++ b/pkg/ui/workspaces/cluster-ui/src/util/format.ts @@ -267,8 +267,8 @@ export const limitStringArray = (arr: string[], limit: number): string => { function add(a: string, b: string): string { let c = 0; const r = []; - const x = a.split("").map(Number); - const y = b.split("").map(Number); + const x = a?.split("").map(Number); + const y = b?.split("").map(Number); while (x.length || y.length) { const s = (x.pop() || 0) + (y.pop() || 0) + c; r.unshift(s < 10 ? s : s - 10); @@ -282,7 +282,7 @@ function add(a: string, b: string): string { // to an int64 (in string form). export function HexStringToInt64String(s: string): string { let dec = "0"; - s.split("").forEach(function (chr: string) { + s?.split("").forEach(function (chr: string) { const n = parseInt(chr, 16); for (let t = 8; t; t >>= 1) { dec = add(dec, dec); @@ -376,7 +376,7 @@ export function FormatQuery(query: string): string { Object.keys(breakLinesKeywords).forEach(key => { query = query.replace(new RegExp(key, "g"), `\n${breakLinesKeywords[key]}`); }); - const lines = query.split("\n").map(line => { + const lines = query?.split("\n").map(line => { if (line.length <= LINE_BREAK_LIMIT) { return line; } diff --git a/pkg/ui/workspaces/cluster-ui/src/util/formatNumber.ts b/pkg/ui/workspaces/cluster-ui/src/util/formatNumber.ts index 5352f0009e8d..245c1cb9bf08 100644 --- a/pkg/ui/workspaces/cluster-ui/src/util/formatNumber.ts +++ b/pkg/ui/workspaces/cluster-ui/src/util/formatNumber.ts @@ -11,7 +11,7 @@ import { isNumber } from "lodash"; function numberToString(n: number) { - return n.toString(); + return n?.toString(); } export function formatNumberForDisplay( diff --git a/pkg/ui/workspaces/db-console/src/redux/indexUsageStats/indexUsageStatsSagas.ts b/pkg/ui/workspaces/db-console/src/redux/indexUsageStats/indexUsageStatsSagas.ts index c030a03a8141..c576ce4f74f4 100644 --- a/pkg/ui/workspaces/db-console/src/redux/indexUsageStats/indexUsageStatsSagas.ts +++ b/pkg/ui/workspaces/db-console/src/redux/indexUsageStats/indexUsageStatsSagas.ts @@ -36,7 +36,7 @@ export const selectIndexStatsKeys = createSelector( ); export const KeyToTableRequest = (key: string): TableIndexStatsRequest => { - const s = key.split("/"); + const s = key?.split("/"); const database = s[0]; const table = s[1]; return new TableIndexStatsRequest({ database, table }); diff --git a/pkg/ui/workspaces/db-console/src/selectors/recentExecutionsSelectors.ts b/pkg/ui/workspaces/db-console/src/selectors/recentExecutionsSelectors.ts index 3012a28c7cc3..1962080c3eef 100644 --- a/pkg/ui/workspaces/db-console/src/selectors/recentExecutionsSelectors.ts +++ b/pkg/ui/workspaces/db-console/src/selectors/recentExecutionsSelectors.ts @@ -61,7 +61,7 @@ export const selectRecentStatement = createSelector( export const selectAppName = createSelector( (state: AdminUIState) => state.cachedData.sessions, (state?: CachedDataReducerState) => { - if (!state.data) { + if (!state?.data) { return null; } return state.data.internal_app_name_prefix; diff --git a/pkg/ui/workspaces/db-console/src/util/api.ts b/pkg/ui/workspaces/db-console/src/util/api.ts index b51f7c43fdbc..31f8c5f7d9dd 100644 --- a/pkg/ui/workspaces/db-console/src/util/api.ts +++ b/pkg/ui/workspaces/db-console/src/util/api.ts @@ -627,7 +627,7 @@ export function getRangeLog( timeout?: moment.Duration, ): Promise { const rangeID = FixLong(req.range_id); - const rangeIDQuery = rangeID.eq(0) ? "" : `/${rangeID.toString()}`; + const rangeIDQuery = rangeID.eq(0) ? "" : `/${rangeID?.toString()}`; const limit = !_.isNil(req.limit) ? `?limit=${req.limit}` : ""; return timeoutFetch( serverpb.RangeLogResponse, diff --git a/pkg/ui/workspaces/db-console/src/util/highlightedText.tsx b/pkg/ui/workspaces/db-console/src/util/highlightedText.tsx index f9f8cd916885..2616daf8dbce 100644 --- a/pkg/ui/workspaces/db-console/src/util/highlightedText.tsx +++ b/pkg/ui/workspaces/db-console/src/util/highlightedText.tsx @@ -37,8 +37,8 @@ export default function getHighlightedText( }) .join("|"); const parts = isOriginalText - ? text.split(new RegExp(`(${search})`, "gi")) - : rebaseText(text, highlight).split(new RegExp(`(${search})`, "gi")); + ? text?.split(new RegExp(`(${search})`, "gi")) + : rebaseText(text, highlight)?.split(new RegExp(`(${search})`, "gi")); const highlightClass = hasDarkBkg ? "_text-bold-light" : "_text-bold"; return parts.map((part, i) => { if (search.includes(part.toLowerCase())) { @@ -54,7 +54,7 @@ export default function getHighlightedText( } function rebaseText(text: string, highlight: string) { - const search = highlight.split(" "); + const search = highlight?.split(" "); const maxLength = 425; const defaultCropLength = 150; const defaultBeforeAfterCrop = 20; diff --git a/pkg/ui/workspaces/db-console/src/util/query.ts b/pkg/ui/workspaces/db-console/src/util/query.ts index 5478bb82e75f..0d3fe2e60aef 100644 --- a/pkg/ui/workspaces/db-console/src/util/query.ts +++ b/pkg/ui/workspaces/db-console/src/util/query.ts @@ -28,7 +28,7 @@ export function propsToQueryString(props: { [k: string]: any }): string { return _.compact( _.map(props, (v: any, k: string) => !_.isNull(v) && !_.isUndefined(v) - ? `${encodeURIComponent(k)}=${encodeURIComponent(v.toString())}` + ? `${encodeURIComponent(k)}=${encodeURIComponent(v?.toString())}` : null, ), ).join("&"); diff --git a/pkg/ui/workspaces/db-console/src/views/keyVisualizer/keyVisualizer.tsx b/pkg/ui/workspaces/db-console/src/views/keyVisualizer/keyVisualizer.tsx index ab9129b0eee7..b3b2b80c2ff5 100644 --- a/pkg/ui/workspaces/db-console/src/views/keyVisualizer/keyVisualizer.tsx +++ b/pkg/ui/workspaces/db-console/src/views/keyVisualizer/keyVisualizer.tsx @@ -249,7 +249,7 @@ export default class KeyVisualizer extends React.PureComponent< for (const [timestring, xOffset] of Object.entries(xAxisLabels)) { // split timestring and render each part - const [s1, s2] = timestring.split("T"); + const [s1, s2] = timestring?.split("T"); this.ctx.fillText( s1, diff --git a/pkg/ui/workspaces/db-console/src/views/sessions/sessionDetails.tsx b/pkg/ui/workspaces/db-console/src/views/sessions/sessionDetails.tsx index 5c10b78d1780..8dfe58ab436b 100644 --- a/pkg/ui/workspaces/db-console/src/views/sessions/sessionDetails.tsx +++ b/pkg/ui/workspaces/db-console/src/views/sessions/sessionDetails.tsx @@ -39,7 +39,7 @@ export const selectSession = createSelector( state: CachedDataReducerState, props: RouteComponentProps, ) => { - if (!state.data) { + if (!state?.data) { return null; } const sessionID = getMatchParamByName(props.match, sessionAttr); diff --git a/pkg/ui/workspaces/db-console/src/views/sessions/sessionsPage.tsx b/pkg/ui/workspaces/db-console/src/views/sessions/sessionsPage.tsx index 7f19ce38e2eb..19944c1cbc53 100644 --- a/pkg/ui/workspaces/db-console/src/views/sessions/sessionsPage.tsx +++ b/pkg/ui/workspaces/db-console/src/views/sessions/sessionsPage.tsx @@ -48,7 +48,7 @@ export const selectSessions = createSelector( state: CachedDataReducerState, _: RouteComponentProps, ) => { - if (!state.data) { + if (!state?.data) { return null; } return state.data.sessions.map(session => { @@ -64,7 +64,7 @@ export const selectAppName = createSelector( state: CachedDataReducerState, _: RouteComponentProps, ) => { - if (!state.data) { + if (!state?.data) { return null; } return state.data.internal_app_name_prefix; 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 44c0347d480b..cef5f937ca53 100644 --- a/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.tsx +++ b/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.tsx @@ -113,18 +113,18 @@ export const selectStatements = createSelector( props: RouteComponentProps, diagnosticsReportsPerStatement, ): AggregateStatistics[] => { - if (!state.data || !state.valid) { + if (!state?.data || !state?.valid) { return null; } let statements = flattenStatementStats(state.data.statements); const app = queryByName(props.location, appAttr); const isInternal = (statement: ExecutionStatistics) => - statement.app.startsWith(state.data.internal_app_name_prefix); + statement.app.startsWith(state?.data.internal_app_name_prefix); if (app && app !== "All") { const criteria = decodeURIComponent(app).split(","); let showInternal = false; - if (criteria.includes(state.data.internal_app_name_prefix)) { + if (criteria.includes(state?.data.internal_app_name_prefix)) { showInternal = true; } if (criteria.includes(unset)) { @@ -200,12 +200,12 @@ export const selectApps = createSelector( let sawBlank = false; let sawInternal = false; const apps: { [app: string]: boolean } = {}; - state.data.statements.forEach( + state?.data.statements.forEach( (statement: ICollectedStatementStatistics) => { if ( - state.data.internal_app_name_prefix && - statement.key.key_data.app.startsWith( - state.data.internal_app_name_prefix, + state?.data.internal_app_name_prefix && + statement?.key.key_data.app.startsWith( + state?.data.internal_app_name_prefix, ) ) { sawInternal = true; @@ -217,7 +217,7 @@ export const selectApps = createSelector( }, ); return [] - .concat(sawInternal ? [state.data.internal_app_name_prefix] : []) + .concat(sawInternal ? [state?.data.internal_app_name_prefix] : []) .concat(sawBlank ? [unset] : []) .concat(Object.keys(apps)) .sort(); @@ -228,7 +228,7 @@ export const selectApps = createSelector( export const selectDatabases = createSelector( (state: AdminUIState) => state.cachedData.databases, (state: CachedDataReducerState) => { - if (!state.data) { + if (!state?.data) { return []; } @@ -243,7 +243,7 @@ export const selectDatabases = createSelector( export const selectTotalFingerprints = createSelector( (state: AdminUIState) => state.cachedData.statements, (state: CachedDataReducerState) => { - if (!state.data) { + if (!state?.data) { return 0; } const aggregated = aggregateStatementStats(state.data.statements); @@ -256,7 +256,7 @@ export const selectTotalFingerprints = createSelector( export const selectLastReset = createSelector( (state: AdminUIState) => state.cachedData.statements, (state: CachedDataReducerState) => { - if (!state.data) { + if (!state?.data) { return "unknown"; } return PrintTime(util.TimestampToMoment(state.data.last_reset)); diff --git a/pkg/ui/workspaces/db-console/src/views/transactions/transactionsPage.tsx b/pkg/ui/workspaces/db-console/src/views/transactions/transactionsPage.tsx index 219428954c48..a577acf7f6af 100644 --- a/pkg/ui/workspaces/db-console/src/views/transactions/transactionsPage.tsx +++ b/pkg/ui/workspaces/db-console/src/views/transactions/transactionsPage.tsx @@ -67,7 +67,7 @@ export const selectData = createSelector( export const selectLastReset = createSelector( (state: AdminUIState) => state.cachedData.transactions, (state: CachedDataReducerState) => { - if (!state.data) { + if (!state?.data) { return "unknown"; }