You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2022/09/27 23:40:39 UTC

[superset] branch enforce-optional-chaining created (now 8d603ddfe1)

This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a change to branch enforce-optional-chaining
in repository https://gitbox.apache.org/repos/asf/superset.git


      at 8d603ddfe1 All the fixes!

This branch includes the following new commits:

     new 9e1d06fc2c adding the rule!
     new 8d603ddfe1 All the fixes!

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[superset] 01/02: adding the rule!

Posted by ru...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch enforce-optional-chaining
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 9e1d06fc2c35b5e03acb3592cc03f37f369ad048
Author: Evan Rusackas <ev...@preset.io>
AuthorDate: Tue Sep 27 16:56:59 2022 -0600

    adding the rule!
---
 superset-frontend/.eslintrc.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/superset-frontend/.eslintrc.js b/superset-frontend/.eslintrc.js
index 98a453d8cf..6eebb0d2df 100644
--- a/superset-frontend/.eslintrc.js
+++ b/superset-frontend/.eslintrc.js
@@ -96,6 +96,7 @@ module.exports = {
         '@typescript-eslint/no-non-null-assertion': 0, // disabled temporarily
         '@typescript-eslint/explicit-function-return-type': 0,
         '@typescript-eslint/explicit-module-boundary-types': 0, // re-enable up for discussion
+        '@typescript-eslint/prefer-optional-chain': 2,
         camelcase: 0,
         'class-methods-use-this': 0,
         'func-names': 0,


[superset] 02/02: All the fixes!

Posted by ru...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch enforce-optional-chaining
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 8d603ddfe1fd8b45fd2b5003af3165e750428ca1
Author: Evan Rusackas <ev...@preset.io>
AuthorDate: Tue Sep 27 17:40:28 2022 -0600

    All the fixes!
---
 .../src/components/labelUtils.tsx                  |  6 +----
 .../src/shared-controls/dndControls.tsx            |  6 ++---
 .../src/color/CategoricalColorScale.ts             |  3 +--
 .../src/connection/callApi/callApi.ts              |  2 +-
 .../superset-ui-core/src/models/Registry.ts        |  2 +-
 .../src/BigNumber/BigNumberTotal/transformProps.ts |  2 +-
 .../BigNumberWithTrendline/transformProps.ts       |  2 +-
 .../SqlLab/components/AceEditorWrapper/index.tsx   |  2 +-
 .../src/components/Chart/chartReducer.ts           |  5 +---
 .../src/components/ConfirmStatusChange/index.tsx   |  2 +-
 .../src/components/Datasource/CollectionTable.tsx  |  4 +--
 .../ErrorMessage/DatabaseErrorMessage.tsx          | 19 +++++++-------
 .../src/components/FacePile/index.tsx              |  4 +--
 .../src/components/ListView/Filters/index.tsx      |  3 +--
 superset-frontend/src/components/Select/utils.tsx  |  2 +-
 .../src/components/TableCollection/index.tsx       |  6 ++---
 .../components/SliceHeaderControls/index.tsx       | 11 +++-----
 .../FilterBar/FilterControls/FilterControl.tsx     |  2 +-
 .../nativeFilters/FilterCard/useFilterScope.ts     |  7 +++---
 .../FiltersConfigModal/FiltersConfigModal.tsx      |  2 +-
 .../src/dashboard/containers/DashboardPage.tsx     |  6 ++---
 .../src/dashboard/util/filterboxMigrationHelper.ts |  5 +---
 .../DndColumnSelectControl/DndFilterSelect.tsx     |  5 ++--
 .../index.tsx                                      |  2 +-
 .../src/explore/controlUtils/getControlState.ts    |  2 +-
 .../exploreUtils/getParsedExploreURLParams.ts      |  2 +-
 .../components/Select/SelectFilterPlugin.tsx       |  2 +-
 superset-frontend/src/middleware/asyncEvent.ts     |  2 +-
 superset-frontend/src/preamble.ts                  |  2 +-
 superset-frontend/src/setup/setupApp.ts            |  2 +-
 superset-frontend/src/setup/setupClient.ts         |  2 +-
 .../src/views/CRUD/alert/AlertList.tsx             |  2 +-
 .../src/views/CRUD/alert/AlertReportModal.tsx      | 29 +++++++++-------------
 .../src/views/CRUD/annotation/AnnotationModal.tsx  | 13 +++++-----
 .../CRUD/annotationlayers/AnnotationLayerModal.tsx |  4 +--
 .../views/CRUD/csstemplates/CssTemplateModal.tsx   | 12 ++++-----
 .../src/views/CRUD/dashboard/DashboardCard.tsx     |  4 +--
 superset-frontend/src/views/CRUD/utils.tsx         |  6 ++---
 .../src/views/components/RightMenu.tsx             |  2 +-
 39 files changed, 82 insertions(+), 114 deletions(-)

diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/components/labelUtils.tsx b/superset-frontend/packages/superset-ui-chart-controls/src/components/labelUtils.tsx
index ca7ddff4ce..2d1acb1585 100644
--- a/superset-frontend/packages/superset-ui-chart-controls/src/components/labelUtils.tsx
+++ b/superset-frontend/packages/superset-ui-chart-controls/src/components/labelUtils.tsx
@@ -54,11 +54,7 @@ const TooltipSection = ({
 );
 
 export const isLabelTruncated = (labelRef?: React.RefObject<any>): boolean =>
-  !!(
-    labelRef &&
-    labelRef.current &&
-    labelRef.current.scrollWidth > labelRef.current.clientWidth
-  );
+  !!(labelRef?.current?.scrollWidth > labelRef?.current.clientWidth);
 
 export const getColumnLabelText = (column: ColumnMeta): string =>
   column.verbose_name || column.column_name;
diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/dndControls.tsx b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/dndControls.tsx
index 691dbca7c0..1d1949e93a 100644
--- a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/dndControls.tsx
+++ b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/dndControls.tsx
@@ -77,10 +77,8 @@ export const dndGroupByControl: SharedControlConfig<
   valueKey: 'column_name',
   allowAll: true,
   filterOption: ({ data: opt }: FilterOption<ColumnMeta>, text: string) =>
-    (opt.column_name &&
-      opt.column_name.toLowerCase().includes(text.toLowerCase())) ||
-    (opt.verbose_name &&
-      opt.verbose_name.toLowerCase().includes(text.toLowerCase())) ||
+    opt.column_name?.toLowerCase().includes(text.toLowerCase()) ||
+    opt.verbose_name?.toLowerCase().includes(text.toLowerCase()) ||
     false,
   promptTextCreator: (label: unknown) => label,
   mapStateToProps(state, controlState) {
diff --git a/superset-frontend/packages/superset-ui-core/src/color/CategoricalColorScale.ts b/superset-frontend/packages/superset-ui-core/src/color/CategoricalColorScale.ts
index 2a6a4d63a0..e254730ac3 100644
--- a/superset-frontend/packages/superset-ui-core/src/color/CategoricalColorScale.ts
+++ b/superset-frontend/packages/superset-ui-core/src/color/CategoricalColorScale.ts
@@ -67,8 +67,7 @@ class CategoricalColorScale extends ExtensibleFunction {
     const cleanedValue = stringifyAndTrim(value);
     const sharedLabelColor = getSharedLabelColor();
 
-    const parentColor =
-      this.parentForcedColors && this.parentForcedColors[cleanedValue];
+    const parentColor = this.parentForcedColors?.[cleanedValue];
     if (parentColor) {
       sharedLabelColor.addSlice(cleanedValue, parentColor, sliceId);
       return parentColor;
diff --git a/superset-frontend/packages/superset-ui-core/src/connection/callApi/callApi.ts b/superset-frontend/packages/superset-ui-core/src/connection/callApi/callApi.ts
index 7a19e94c03..c682e5b730 100644
--- a/superset-frontend/packages/superset-ui-core/src/connection/callApi/callApi.ts
+++ b/superset-frontend/packages/superset-ui-core/src/connection/callApi/callApi.ts
@@ -94,7 +94,7 @@ export default async function callApi({
     cache !== 'no-store' &&
     cache !== 'reload' &&
     CACHE_AVAILABLE &&
-    (window.location && window.location.protocol) === 'https:'
+    window.location?.protocol === 'https:'
   ) {
     let supersetCache: Cache | null = null;
     try {
diff --git a/superset-frontend/packages/superset-ui-core/src/models/Registry.ts b/superset-frontend/packages/superset-ui-core/src/models/Registry.ts
index 90a8065e29..e876bc2b50 100644
--- a/superset-frontend/packages/superset-ui-core/src/models/Registry.ts
+++ b/superset-frontend/packages/superset-ui-core/src/models/Registry.ts
@@ -169,7 +169,7 @@ export default class Registry<
     const item = this.items[key];
     if (item !== undefined) {
       if ('loader' in item) {
-        return item.loader && item.loader();
+        return item.loader?.();
       }
 
       return item.value;
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.ts
index 47a152fedd..3438654831 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.ts
@@ -46,7 +46,7 @@ export default function transformProps(chartProps: BigNumberTotalChartProps) {
     data.length === 0 ? null : parseMetricValue(data[0][metricName]);
 
   let metricEntry;
-  if (chartProps.datasource && chartProps.datasource.metrics) {
+  if (chartProps.datasource?.metrics) {
     metricEntry = chartProps.datasource.metrics.find(
       metricItem => metricItem.metric_name === metric,
     );
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/transformProps.ts
index 6a7ffdcbdc..86615d376e 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/transformProps.ts
@@ -155,7 +155,7 @@ export default function transformProps(
   }
 
   let metricEntry;
-  if (chartProps.datasource && chartProps.datasource.metrics) {
+  if (chartProps.datasource?.metrics) {
     metricEntry = chartProps.datasource.metrics.find(
       metricEntry => metricEntry.metric_name === metric,
     );
diff --git a/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx b/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
index 6b70be228b..dd1d707eae 100644
--- a/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
+++ b/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
@@ -197,7 +197,7 @@ class AceEditorWrapper extends React.PureComponent<Props, State> {
     const tableWords = tables.map(t => {
       const tableName = t.value;
       const extendedTable = extendedTables.find(et => et.name === tableName);
-      const cols = (extendedTable && extendedTable.columns) || [];
+      const cols = extendedTable?.columns || [];
       cols.forEach(col => {
         columns[col.name] = null; // using an object as a unique set
       });
diff --git a/superset-frontend/src/components/Chart/chartReducer.ts b/superset-frontend/src/components/Chart/chartReducer.ts
index 11b498290f..1d1ae60ea6 100644
--- a/superset-frontend/src/components/Chart/chartReducer.ts
+++ b/superset-frontend/src/components/Chart/chartReducer.ts
@@ -130,10 +130,7 @@ export default function chartReducer(
       return { ...state, latestQueryFormData: action.value };
     },
     [actions.ANNOTATION_QUERY_STARTED](state) {
-      if (
-        state.annotationQuery &&
-        state.annotationQuery[action.annotation.name]
-      ) {
+      if (state.annotationQuery?.[action.annotation.name]) {
         state.annotationQuery[action.annotation.name].abort();
       }
       const annotationQuery = {
diff --git a/superset-frontend/src/components/ConfirmStatusChange/index.tsx b/superset-frontend/src/components/ConfirmStatusChange/index.tsx
index a11bc0eeab..09c374bdb5 100644
--- a/superset-frontend/src/components/ConfirmStatusChange/index.tsx
+++ b/superset-frontend/src/components/ConfirmStatusChange/index.tsx
@@ -69,7 +69,7 @@ export default function ConfirmStatusChange({
 
   return (
     <>
-      {children && children(showConfirm)}
+      {children?.(showConfirm)}
       <DeleteModal
         description={description}
         onConfirm={confirm}
diff --git a/superset-frontend/src/components/Datasource/CollectionTable.tsx b/superset-frontend/src/components/Datasource/CollectionTable.tsx
index e0eb44e845..b909609837 100644
--- a/superset-frontend/src/components/Datasource/CollectionTable.tsx
+++ b/superset-frontend/src/components/Datasource/CollectionTable.tsx
@@ -214,7 +214,7 @@ export default class CRUDCollection extends React.PureComponent<
 
   getLabel(col: any) {
     const { columnLabels } = this.props;
-    let label = columnLabels && columnLabels[col] ? columnLabels[col] : col;
+    let label = columnLabels?.[col] ? columnLabels[col] : col;
     if (label.startsWith('__')) {
       // special label-free columns (ie: caret for expand, delete cross)
       label = '';
@@ -350,7 +350,7 @@ export default class CRUDCollection extends React.PureComponent<
   }
 
   renderCell(record: any, col: any) {
-    const renderer = this.props.itemRenderers && this.props.itemRenderers[col];
+    const renderer = this?.props?.itemRenderers?.[col];
     const val = record[col];
     const onChange = this.onCellChange.bind(this, record.id, col);
     return renderer ? renderer(val, onChange, this.getLabel(col), record) : val;
diff --git a/superset-frontend/src/components/ErrorMessage/DatabaseErrorMessage.tsx b/superset-frontend/src/components/ErrorMessage/DatabaseErrorMessage.tsx
index 612abcaf75..a7a0a4199f 100644
--- a/superset-frontend/src/components/ErrorMessage/DatabaseErrorMessage.tsx
+++ b/superset-frontend/src/components/ErrorMessage/DatabaseErrorMessage.tsx
@@ -75,19 +75,18 @@ function DatabaseErrorMessage({
     </>
   );
 
-  const copyText =
-    extra && extra.issue_codes
-      ? t('%(message)s\nThis may be triggered by: \n%(issues)s', {
-          message,
-          issues: extra.issue_codes
-            .map(issueCode => issueCode.message)
-            .join('\n'),
-        })
-      : message;
+  const copyText = extra?.issue_codes
+    ? t('%(message)s\nThis may be triggered by: \n%(issues)s', {
+        message,
+        issues: extra.issue_codes
+          .map(issueCode => issueCode.message)
+          .join('\n'),
+      })
+    : message;
 
   return (
     <ErrorAlert
-      title={t('%s Error', (extra && extra.engine_name) || t('DB engine'))}
+      title={t('%s Error', extra?.engine_name || t('DB engine'))}
       subtitle={subtitle}
       level={level}
       source={source}
diff --git a/superset-frontend/src/components/FacePile/index.tsx b/superset-frontend/src/components/FacePile/index.tsx
index 730d162e2d..44cc62ce1d 100644
--- a/superset-frontend/src/components/FacePile/index.tsx
+++ b/superset-frontend/src/components/FacePile/index.tsx
@@ -67,8 +67,8 @@ export default function FacePile({ users, maxCount = 4 }: FacePileProps) {
                 borderColor: color,
               }}
             >
-              {first_name && first_name[0]?.toLocaleUpperCase()}
-              {last_name && last_name[0]?.toLocaleUpperCase()}
+              {first_name?.[0]?.toLocaleUpperCase()}
+              {last_name?.[0]?.toLocaleUpperCase()}
             </StyledAvatar>
           </Tooltip>
         );
diff --git a/superset-frontend/src/components/ListView/Filters/index.tsx b/superset-frontend/src/components/ListView/Filters/index.tsx
index 6f839cd720..ec25282bb6 100644
--- a/superset-frontend/src/components/ListView/Filters/index.tsx
+++ b/superset-frontend/src/components/ListView/Filters/index.tsx
@@ -74,8 +74,7 @@ function UIFilters(
           },
           index,
         ) => {
-          const initialValue =
-            internalFilters[index] && internalFilters[index].value;
+          const initialValue = internalFilters?.[index]?.value;
           if (input === 'select') {
             return (
               <SelectFilter
diff --git a/superset-frontend/src/components/Select/utils.tsx b/superset-frontend/src/components/Select/utils.tsx
index 5ec7e33d10..0d499b4f1d 100644
--- a/superset-frontend/src/components/Select/utils.tsx
+++ b/superset-frontend/src/components/Select/utils.tsx
@@ -170,7 +170,7 @@ export const handleFilterOptionHelper = (
 
   if (filterOption) {
     const searchValue = search.trim().toLowerCase();
-    if (optionFilterProps && optionFilterProps.length) {
+    if (optionFilterProps?.length) {
       return optionFilterProps.some(prop => {
         const optionProp = option?.[prop]
           ? String(option[prop]).trim().toLowerCase()
diff --git a/superset-frontend/src/components/TableCollection/index.tsx b/superset-frontend/src/components/TableCollection/index.tsx
index ad83f3b902..88296edf63 100644
--- a/superset-frontend/src/components/TableCollection/index.tsx
+++ b/superset-frontend/src/components/TableCollection/index.tsx
@@ -292,9 +292,9 @@ export default React.memo(
                 {row.cells.map(cell => {
                   if (cell.column.hidden) return null;
                   const columnCellProps = cell.column.cellProps || {};
-                  const isWrapText =
-                    columnsForWrapText &&
-                    columnsForWrapText.includes(cell.column.Header as string);
+                  const isWrapText = columnsForWrapText?.includes(
+                    cell.column.Header as string,
+                  );
 
                   return (
                     <td
diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx b/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx
index 057421a9fb..19bb612b04 100644
--- a/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx
+++ b/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx
@@ -282,25 +282,22 @@ class SliceHeaderControls extends React.PureComponent<
         break;
       case MENU_KEYS.TOGGLE_CHART_DESCRIPTION:
         // eslint-disable-next-line no-unused-expressions
-        this.props.toggleExpandSlice &&
-          this.props.toggleExpandSlice(this.props.slice.slice_id);
+        this.props.toggleExpandSlice?.(this.props.slice.slice_id);
         break;
       case MENU_KEYS.EXPLORE_CHART:
         // eslint-disable-next-line no-unused-expressions
-        this.props.logExploreChart &&
-          this.props.logExploreChart(this.props.slice.slice_id);
+        this.props.logExploreChart?.(this.props.slice.slice_id);
         break;
       case MENU_KEYS.EXPORT_CSV:
         // eslint-disable-next-line no-unused-expressions
-        this.props.exportCSV && this.props.exportCSV(this.props.slice.slice_id);
+        this.props.exportCSV?.(this.props.slice.slice_id);
         break;
       case MENU_KEYS.FULLSCREEN:
         this.props.handleToggleFullSize();
         break;
       case MENU_KEYS.EXPORT_FULL_CSV:
         // eslint-disable-next-line no-unused-expressions
-        this.props.exportFullCSV &&
-          this.props.exportFullCSV(this.props.slice.slice_id);
+        this.props.exportFullCSV?.(this.props.slice.slice_id);
         break;
       case MENU_KEYS.DOWNLOAD_AS_IMAGE: {
         // menu closes with a delay, we need to hide it manually,
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControl.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControl.tsx
index ff5b08781e..986572c7f0 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControl.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControl.tsx
@@ -136,7 +136,7 @@ const FilterControl: React.FC<FilterProps> = ({
           {name}
         </StyledFilterControlTitle>
         {isRequired && <RequiredFieldIndicator />}
-        {filter.description && filter.description.trim() && (
+        {filter.description?.trim() && (
           <DescriptionToolTip description={filter.description} />
         )}
         <StyledIcon data-test="filter-icon">{icon}</StyledIcon>
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterCard/useFilterScope.ts b/superset-frontend/src/dashboard/components/nativeFilters/FilterCard/useFilterScope.ts
index 12a578c35a..35c84a8591 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterCard/useFilterScope.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterCard/useFilterScope.ts
@@ -62,10 +62,9 @@ export const useFilterScope = (filter: Filter) => {
     if (
       filter.scope.excluded.length === 0 &&
       (filter.scope.rootPath[0] === DASHBOARD_ROOT_ID ||
-        (topLevelTabs &&
-          topLevelTabs.every(topLevelTab =>
-            filter.scope.rootPath.includes(topLevelTab),
-          )))
+        topLevelTabs?.every(topLevelTab =>
+          filter.scope.rootPath.includes(topLevelTab),
+        ))
     ) {
       return { all: [t('All charts')] };
     }
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.tsx
index d258b34fa7..fd4f7d550f 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.tsx
@@ -396,7 +396,7 @@ export function FiltersConfigModal({
         let array: string[] = [];
         if (formItem && 'dependencies' in formItem) {
           array = [...formItem.dependencies];
-        } else if (configItem && configItem.cascadeParentIds) {
+        } else if (configItem?.cascadeParentIds) {
           array = [...configItem.cascadeParentIds];
         }
         dependencyMap.set(key, array);
diff --git a/superset-frontend/src/dashboard/containers/DashboardPage.tsx b/superset-frontend/src/dashboard/containers/DashboardPage.tsx
index 410bf4ab50..17097b6c1c 100644
--- a/superset-frontend/src/dashboard/containers/DashboardPage.tsx
+++ b/superset-frontend/src/dashboard/containers/DashboardPage.tsx
@@ -209,9 +209,9 @@ export const DashboardPage: FC<PageProps> = ({ idOrSlug }: PageProps) => {
 
   useEffect(() => {
     // should convert filter_box to filter component?
-    const hasFilterBox =
-      charts &&
-      charts.some(chart => chart.form_data?.viz_type === 'filter_box');
+    const hasFilterBox = charts?.some(
+      chart => chart.form_data?.viz_type === 'filter_box',
+    );
     const canEdit = dashboard && canUserEditDashboard(dashboard, user);
 
     if (canEdit) {
diff --git a/superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts b/superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts
index 51ef73a03a..4eebbc0752 100644
--- a/superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts
+++ b/superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts
@@ -99,10 +99,7 @@ enum FILTER_COMPONENT_FILTER_TYPES {
 const getPreselectedValuesFromDashboard =
   (preselectedFilters: PreselectedFiltersMeatadata) =>
   (filterKey: string, column: string) => {
-    if (
-      preselectedFilters[filterKey] &&
-      preselectedFilters[filterKey][column]
-    ) {
+    if (preselectedFilters[filterKey]?.[column]) {
       // overwrite default values by dashboard default_filters
       return preselectedFilters[filterKey][column];
     }
diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx
index 285c731323..58923f118d 100644
--- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx
+++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx
@@ -151,13 +151,12 @@ const DndFilterSelect = (props: DndFilterSelectProps) => {
           endpoint: `/api/v1/database/${dbId}/table_extra/${name}/${schema}/`,
         })
           .then(({ json }: { json: Record<string, any> }) => {
-            if (json && json.partitions) {
+            if (json?.partitions) {
               const { partitions } = json;
               // for now only show latest_partition option
               // when table datasource has only 1 partition key.
               if (
-                partitions &&
-                partitions.cols &&
+                partitions?.cols &&
                 Object.keys(partitions.cols).length === 1
               ) {
                 setPartitionColumn(partitions.cols[0]);
diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx
index 910f7986fd..773e58c3e4 100644
--- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx
@@ -158,7 +158,7 @@ export const useSimpleTabFilterProps = (props: Props) => {
     } else if (option && 'saved_metric_name' in option) {
       subject = option.saved_metric_name;
       clause = CLAUSES.HAVING;
-    } else if (option && option.label) {
+    } else if (option?.label) {
       subject = option.label;
       clause = CLAUSES.HAVING;
     }
diff --git a/superset-frontend/src/explore/controlUtils/getControlState.ts b/superset-frontend/src/explore/controlUtils/getControlState.ts
index f3c5d8b4cf..794c2b7b7a 100644
--- a/superset-frontend/src/explore/controlUtils/getControlState.ts
+++ b/superset-frontend/src/explore/controlUtils/getControlState.ts
@@ -174,7 +174,7 @@ export function getAllControlsState(
   getSectionsToRender(vizType, datasourceType).forEach(section =>
     section.controlSetRows.forEach(fieldsetRow =>
       fieldsetRow.forEach((field: CustomControlItem) => {
-        if (field && field.config && field.name) {
+        if (field?.config && field.name) {
           const { config, name } = field;
           controlsState[name] = getControlStateFromControlConfig(
             config,
diff --git a/superset-frontend/src/explore/exploreUtils/getParsedExploreURLParams.ts b/superset-frontend/src/explore/exploreUtils/getParsedExploreURLParams.ts
index 1e5007875a..f09a363858 100644
--- a/superset-frontend/src/explore/exploreUtils/getParsedExploreURLParams.ts
+++ b/superset-frontend/src/explore/exploreUtils/getParsedExploreURLParams.ts
@@ -105,7 +105,7 @@ const getParsedExploreURLPathParams = (pathname: string) =>
   Object.keys(EXPLORE_URL_PATH_PARAMS).reduce((acc, currentParam) => {
     const re = new RegExp(`/(${currentParam})/(\\w+)`);
     const pathGroups = pathname.match(re);
-    if (pathGroups && pathGroups[2]) {
+    if (pathGroups?.[2]) {
       return { ...acc, [EXPLORE_URL_PATH_PARAMS[currentParam]]: pathGroups[2] };
     }
     return acc;
diff --git a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
index d1bb3df747..9cea856d47 100644
--- a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
+++ b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
@@ -228,7 +228,7 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
         : null;
       // firstItem[0] !== undefined for a case when groupby changed but new data still not fetched
       // TODO: still need repopulate default value in config modal when column changed
-      if (firstItem && firstItem[0] !== undefined) {
+      if (firstItem?.[0] !== undefined) {
         updateDataMask(firstItem);
       }
     } else if (isDisabled) {
diff --git a/superset-frontend/src/middleware/asyncEvent.ts b/superset-frontend/src/middleware/asyncEvent.ts
index 9ae4f90e47..f76b0a713f 100644
--- a/superset-frontend/src/middleware/asyncEvent.ts
+++ b/superset-frontend/src/middleware/asyncEvent.ts
@@ -171,7 +171,7 @@ const loadEventsFromApi = async () => {
   if (Object.keys(listenersByJobId).length) {
     try {
       const { result: events } = await fetchEvents(eventArgs);
-      if (events && events.length) await processEvents(events);
+      if (events?.length) await processEvents(events);
     } catch (err) {
       logging.warn(err);
     }
diff --git a/superset-frontend/src/preamble.ts b/superset-frontend/src/preamble.ts
index f6ae99b084..374ee34fba 100644
--- a/superset-frontend/src/preamble.ts
+++ b/superset-frontend/src/preamble.ts
@@ -52,7 +52,7 @@ if (typeof window !== 'undefined') {
   bootstrapData = root
     ? JSON.parse(root.getAttribute('data-bootstrap') || '{}')
     : {};
-  if (bootstrapData.common && bootstrapData.common.language_pack) {
+  if (bootstrapData?.common.language_pack) {
     const languagePack = bootstrapData.common.language_pack;
     configure({ languagePack });
     moment.locale(bootstrapData.common.locale);
diff --git a/superset-frontend/src/setup/setupApp.ts b/superset-frontend/src/setup/setupApp.ts
index ba3b9ac961..227aad3a68 100644
--- a/superset-frontend/src/setup/setupApp.ts
+++ b/superset-frontend/src/setup/setupApp.ts
@@ -52,7 +52,7 @@ function toggleCheckbox(apiUrlPrefix: string, selector: string) {
     .then(() => undefined)
     .catch(response =>
       getClientErrorObject(response).then(parsedResp => {
-        if (parsedResp && parsedResp.message) {
+        if (parsedResp?.message) {
           showApiMessage(parsedResp);
         }
       }),
diff --git a/superset-frontend/src/setup/setupClient.ts b/superset-frontend/src/setup/setupClient.ts
index 8802ae4722..80ce6b54bb 100644
--- a/superset-frontend/src/setup/setupClient.ts
+++ b/superset-frontend/src/setup/setupClient.ts
@@ -30,7 +30,7 @@ function getDefaultConfiguration(): ClientConfig {
     protocol: ['http:', 'https:'].includes(window?.location?.protocol)
       ? (window?.location?.protocol as 'http:' | 'https:')
       : undefined,
-    host: (window.location && window.location.host) || '',
+    host: window.location?.host || '',
     csrfToken: csrfToken || cookieCSRFToken,
   };
 }
diff --git a/superset-frontend/src/views/CRUD/alert/AlertList.tsx b/superset-frontend/src/views/CRUD/alert/AlertList.tsx
index a2fdb9110e..cd9ba95608 100644
--- a/superset-frontend/src/views/CRUD/alert/AlertList.tsx
+++ b/superset-frontend/src/views/CRUD/alert/AlertList.tsx
@@ -191,7 +191,7 @@ function AlertList({
 
   const toggleActive = useCallback(
     (data: AlertObject, checked: boolean) => {
-      if (data && data.id) {
+      if (data?.id) {
         const update_id = data.id;
         const original = [...alerts];
 
diff --git a/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx b/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx
index fe34b22e80..de5d5cad06 100644
--- a/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx
+++ b/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx
@@ -544,7 +544,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
 
     if (isEditMode) {
       // Edit
-      if (currentAlert && currentAlert.id) {
+      if (currentAlert?.id) {
         const update_id = currentAlert.id;
 
         delete data.id;
@@ -664,8 +664,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
     [],
   );
 
-  const databaseLabel =
-    currentAlert && currentAlert.database && !currentAlert.database.label;
+  const databaseLabel = currentAlert?.database && !currentAlert.database.label;
   useEffect(() => {
     // Find source if current alert has one set
     if (databaseLabel) {
@@ -738,8 +737,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
     [chartOptions, currentAlert?.chart],
   );
 
-  const noChartLabel =
-    currentAlert && currentAlert.chart && !currentAlert.chart.label;
+  const noChartLabel = currentAlert?.chart && !currentAlert?.chart.label;
   useEffect(() => {
     // Find source if current alert has one set
     if (noChartLabel) {
@@ -899,13 +897,12 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
 
   const validate = () => {
     if (
-      currentAlert &&
-      currentAlert.name?.length &&
-      currentAlert.owners?.length &&
-      currentAlert.crontab?.length &&
-      currentAlert.working_timeout !== undefined &&
-      ((contentType === 'dashboard' && !!currentAlert.dashboard) ||
-        (contentType === 'chart' && !!currentAlert.chart)) &&
+      currentAlert?.name?.length &&
+      currentAlert?.owners?.length &&
+      currentAlert?.crontab?.length &&
+      currentAlert?.working_timeout !== undefined &&
+      ((contentType === 'dashboard' && !!currentAlert?.dashboard) ||
+        (contentType === 'chart' && !!currentAlert?.chart)) &&
       checkNotificationSettings()
     ) {
       if (isReport) {
@@ -932,7 +929,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
       isEditMode &&
       (!currentAlert?.id || alert?.id !== currentAlert.id || (isHidden && show))
     ) {
-      if (alert && alert.id !== null && !loading && !fetchError) {
+      if (alert?.id !== null && !loading && !fetchError) {
         const id = alert.id || 0;
         fetchResource(id);
       }
@@ -1214,10 +1211,8 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
                       name="threshold"
                       disabled={conditionNotNull}
                       value={
-                        currentAlert &&
-                        currentAlert.validator_config_json &&
-                        currentAlert.validator_config_json.threshold !==
-                          undefined
+                        currentAlert?.validator_config_json?.threshold !==
+                        undefined
                           ? currentAlert.validator_config_json.threshold
                           : ''
                       }
diff --git a/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx b/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx
index 22af06241f..6d438c8d59 100644
--- a/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx
+++ b/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx
@@ -130,7 +130,7 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
   const onSave = () => {
     if (isEditMode) {
       // Edit
-      if (currentAnnotation && currentAnnotation.id) {
+      if (currentAnnotation?.id) {
         const update_id = currentAnnotation.id;
         delete currentAnnotation.id;
         delete currentAnnotation.created_by;
@@ -217,10 +217,9 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
 
   const validate = () => {
     if (
-      currentAnnotation &&
-      currentAnnotation.short_descr?.length &&
-      currentAnnotation.start_dttm?.length &&
-      currentAnnotation.end_dttm?.length
+      currentAnnotation?.short_descr?.length &&
+      currentAnnotation?.start_dttm?.length &&
+      currentAnnotation?.end_dttm?.length
     ) {
       setDisableSave(false);
     } else {
@@ -237,7 +236,7 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
         (annotation && annotation.id !== currentAnnotation.id) ||
         show)
     ) {
-      if (annotation && annotation.id !== null && !loading) {
+      if (annotation?.id !== null && !loading) {
         const id = annotation.id || 0;
 
         fetchResource(id);
@@ -337,7 +336,7 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
         <StyledJsonEditor
           onChange={onJsonChange}
           value={
-            currentAnnotation && currentAnnotation.json_metadata
+            currentAnnotation?.json_metadata
               ? currentAnnotation.json_metadata
               : ''
           }
diff --git a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx
index a7b78de39a..7510ef51c9 100644
--- a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx
+++ b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx
@@ -126,7 +126,7 @@ const AnnotationLayerModal: FunctionComponent<AnnotationLayerModalProps> = ({
   const onSave = () => {
     if (isEditMode) {
       // Edit
-      if (currentLayer && currentLayer.id) {
+      if (currentLayer?.id) {
         const update_id = currentLayer.id;
         delete currentLayer.id;
         delete currentLayer.created_by;
@@ -173,7 +173,7 @@ const AnnotationLayerModal: FunctionComponent<AnnotationLayerModalProps> = ({
   };
 
   const validate = () => {
-    if (currentLayer && currentLayer.name?.length) {
+    if (currentLayer?.name?.length) {
       setDisableSave(false);
     } else {
       setDisableSave(true);
diff --git a/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx b/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx
index 3248babb63..6348697359 100644
--- a/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx
+++ b/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx
@@ -101,7 +101,7 @@ const CssTemplateModal: FunctionComponent<CssTemplateModalProps> = ({
   const onSave = () => {
     if (isEditMode) {
       // Edit
-      if (currentCssTemplate && currentCssTemplate.id) {
+      if (currentCssTemplate?.id) {
         const update_id = currentCssTemplate.id;
         delete currentCssTemplate.id;
         delete currentCssTemplate.created_by;
@@ -157,10 +157,8 @@ const CssTemplateModal: FunctionComponent<CssTemplateModalProps> = ({
 
   const validate = () => {
     if (
-      currentCssTemplate &&
-      currentCssTemplate.template_name.length &&
-      currentCssTemplate.css &&
-      currentCssTemplate.css.length
+      currentCssTemplate?.template_name.length &&
+      currentCssTemplate?.css?.length
     ) {
       setDisableSave(false);
     } else {
@@ -174,10 +172,10 @@ const CssTemplateModal: FunctionComponent<CssTemplateModalProps> = ({
       isEditMode &&
       (!currentCssTemplate ||
         !currentCssTemplate.id ||
-        (cssTemplate && cssTemplate.id !== currentCssTemplate.id) ||
+        (cssTemplate && cssTemplate?.id !== currentCssTemplate.id) ||
         (isHidden && show))
     ) {
-      if (cssTemplate && cssTemplate.id !== null && !loading) {
+      if (cssTemplate?.id !== null && !loading) {
         const id = cssTemplate.id || 0;
 
         fetchResource(id);
diff --git a/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx b/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx
index 2da9f45515..cadb2ed965 100644
--- a/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx
+++ b/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx
@@ -78,9 +78,7 @@ function DashboardCard({
             role="button"
             tabIndex={0}
             className="action-button"
-            onClick={() =>
-              openDashboardEditModal && openDashboardEditModal(dashboard)
-            }
+            onClick={() => openDashboardEditModal?.(dashboard)}
             data-test="dashboard-card-option-edit-button"
           >
             <Icons.EditAlt iconSize="l" data-test="edit-alt" /> {t('Edit')}
diff --git a/superset-frontend/src/views/CRUD/utils.tsx b/superset-frontend/src/views/CRUD/utils.tsx
index b82e5b4e58..8d9c1cea83 100644
--- a/superset-frontend/src/views/CRUD/utils.tsx
+++ b/superset-frontend/src/views/CRUD/utils.tsx
@@ -227,10 +227,8 @@ export function createErrorHandler(
     const errorsArray = parsedError?.errors;
     const config = await SupersetText;
     if (
-      errorsArray &&
-      errorsArray.length &&
-      config &&
-      config.ERRORS &&
+      errorsArray?.length &&
+      config?.ERRORS &&
       errorsArray[0].error_type in config.ERRORS
     ) {
       parsedError.message = config.ERRORS[errorsArray[0].error_type];
diff --git a/superset-frontend/src/views/components/RightMenu.tsx b/superset-frontend/src/views/components/RightMenu.tsx
index cacd4089cb..5563c787af 100644
--- a/superset-frontend/src/views/components/RightMenu.tsx
+++ b/superset-frontend/src/views/components/RightMenu.tsx
@@ -287,7 +287,7 @@ const RightMenu = ({
           onDatabaseAdd={handleDatabaseAdd}
         />
       )}
-      {environmentTag && environmentTag.text && (
+      {environmentTag?.text && (
         <Label
           css={{ borderRadius: `${theme.gridUnit * 125}px` }}
           color={