chore(style): Enforce optional chaining (#21614)

This commit is contained in:
Evan Rusackas 2022-10-03 08:17:20 -07:00 committed by GitHub
parent 3edc656f20
commit 4245bc3f38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 83 additions and 114 deletions

View File

@ -96,6 +96,7 @@ module.exports = {
'@typescript-eslint/no-non-null-assertion': 0, // disabled temporarily '@typescript-eslint/no-non-null-assertion': 0, // disabled temporarily
'@typescript-eslint/explicit-function-return-type': 0, '@typescript-eslint/explicit-function-return-type': 0,
'@typescript-eslint/explicit-module-boundary-types': 0, // re-enable up for discussion '@typescript-eslint/explicit-module-boundary-types': 0, // re-enable up for discussion
'@typescript-eslint/prefer-optional-chain': 2,
camelcase: 0, camelcase: 0,
'class-methods-use-this': 0, 'class-methods-use-this': 0,
'func-names': 0, 'func-names': 0,

View File

@ -54,11 +54,7 @@ const TooltipSection = ({
); );
export const isLabelTruncated = (labelRef?: React.RefObject<any>): boolean => export const isLabelTruncated = (labelRef?: React.RefObject<any>): boolean =>
!!( !!(labelRef?.current?.scrollWidth > labelRef?.current?.clientWidth);
labelRef &&
labelRef.current &&
labelRef.current.scrollWidth > labelRef.current.clientWidth
);
export const getColumnLabelText = (column: ColumnMeta): string => export const getColumnLabelText = (column: ColumnMeta): string =>
column.verbose_name || column.column_name; column.verbose_name || column.column_name;

View File

@ -77,10 +77,8 @@ export const dndGroupByControl: SharedControlConfig<
valueKey: 'column_name', valueKey: 'column_name',
allowAll: true, allowAll: true,
filterOption: ({ data: opt }: FilterOption<ColumnMeta>, text: string) => filterOption: ({ data: opt }: FilterOption<ColumnMeta>, text: string) =>
(opt.column_name && opt.column_name?.toLowerCase().includes(text.toLowerCase()) ||
opt.column_name.toLowerCase().includes(text.toLowerCase())) || opt.verbose_name?.toLowerCase().includes(text.toLowerCase()) ||
(opt.verbose_name &&
opt.verbose_name.toLowerCase().includes(text.toLowerCase())) ||
false, false,
promptTextCreator: (label: unknown) => label, promptTextCreator: (label: unknown) => label,
mapStateToProps(state, controlState) { mapStateToProps(state, controlState) {

View File

@ -67,8 +67,7 @@ class CategoricalColorScale extends ExtensibleFunction {
const cleanedValue = stringifyAndTrim(value); const cleanedValue = stringifyAndTrim(value);
const sharedLabelColor = getSharedLabelColor(); const sharedLabelColor = getSharedLabelColor();
const parentColor = const parentColor = this.parentForcedColors?.[cleanedValue];
this.parentForcedColors && this.parentForcedColors[cleanedValue];
if (parentColor) { if (parentColor) {
sharedLabelColor.addSlice(cleanedValue, parentColor, sliceId); sharedLabelColor.addSlice(cleanedValue, parentColor, sliceId);
return parentColor; return parentColor;

View File

@ -94,7 +94,7 @@ export default async function callApi({
cache !== 'no-store' && cache !== 'no-store' &&
cache !== 'reload' && cache !== 'reload' &&
CACHE_AVAILABLE && CACHE_AVAILABLE &&
(window.location && window.location.protocol) === 'https:' window.location?.protocol === 'https:'
) { ) {
let supersetCache: Cache | null = null; let supersetCache: Cache | null = null;
try { try {

View File

@ -169,7 +169,7 @@ export default class Registry<
const item = this.items[key]; const item = this.items[key];
if (item !== undefined) { if (item !== undefined) {
if ('loader' in item) { if ('loader' in item) {
return item.loader && item.loader(); return item.loader?.();
} }
return item.value; return item.value;

View File

@ -46,7 +46,7 @@ export default function transformProps(chartProps: BigNumberTotalChartProps) {
data.length === 0 ? null : parseMetricValue(data[0][metricName]); data.length === 0 ? null : parseMetricValue(data[0][metricName]);
let metricEntry; let metricEntry;
if (chartProps.datasource && chartProps.datasource.metrics) { if (chartProps.datasource?.metrics) {
metricEntry = chartProps.datasource.metrics.find( metricEntry = chartProps.datasource.metrics.find(
metricItem => metricItem.metric_name === metric, metricItem => metricItem.metric_name === metric,
); );

View File

@ -155,7 +155,7 @@ export default function transformProps(
} }
let metricEntry; let metricEntry;
if (chartProps.datasource && chartProps.datasource.metrics) { if (chartProps.datasource?.metrics) {
metricEntry = chartProps.datasource.metrics.find( metricEntry = chartProps.datasource.metrics.find(
metricEntry => metricEntry.metric_name === metric, metricEntry => metricEntry.metric_name === metric,
); );

View File

@ -182,7 +182,7 @@ const AceEditorWrapper = ({
const tableWords = tables.map(t => { const tableWords = tables.map(t => {
const tableName = t.value; const tableName = t.value;
const extendedTable = extendedTables.find(et => et.name === tableName); const extendedTable = extendedTables.find(et => et.name === tableName);
const cols = (extendedTable && extendedTable.columns) || []; const cols = extendedTable?.columns || [];
cols.forEach(col => { cols.forEach(col => {
columns[col.name] = null; // using an object as a unique set columns[col.name] = null; // using an object as a unique set
}); });

View File

@ -130,10 +130,7 @@ export default function chartReducer(
return { ...state, latestQueryFormData: action.value }; return { ...state, latestQueryFormData: action.value };
}, },
[actions.ANNOTATION_QUERY_STARTED](state) { [actions.ANNOTATION_QUERY_STARTED](state) {
if ( if (state.annotationQuery?.[action.annotation.name]) {
state.annotationQuery &&
state.annotationQuery[action.annotation.name]
) {
state.annotationQuery[action.annotation.name].abort(); state.annotationQuery[action.annotation.name].abort();
} }
const annotationQuery = { const annotationQuery = {

View File

@ -69,7 +69,7 @@ export default function ConfirmStatusChange({
return ( return (
<> <>
{children && children(showConfirm)} {children?.(showConfirm)}
<DeleteModal <DeleteModal
description={description} description={description}
onConfirm={confirm} onConfirm={confirm}

View File

@ -214,7 +214,7 @@ export default class CRUDCollection extends React.PureComponent<
getLabel(col: any) { getLabel(col: any) {
const { columnLabels } = this.props; const { columnLabels } = this.props;
let label = columnLabels && columnLabels[col] ? columnLabels[col] : col; let label = columnLabels?.[col] ? columnLabels[col] : col;
if (label.startsWith('__')) { if (label.startsWith('__')) {
// special label-free columns (ie: caret for expand, delete cross) // special label-free columns (ie: caret for expand, delete cross)
label = ''; label = '';
@ -350,7 +350,7 @@ export default class CRUDCollection extends React.PureComponent<
} }
renderCell(record: any, col: any) { 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 val = record[col];
const onChange = this.onCellChange.bind(this, record.id, col); const onChange = this.onCellChange.bind(this, record.id, col);
return renderer ? renderer(val, onChange, this.getLabel(col), record) : val; return renderer ? renderer(val, onChange, this.getLabel(col), record) : val;

View File

@ -75,19 +75,18 @@ function DatabaseErrorMessage({
</> </>
); );
const copyText = const copyText = extra?.issue_codes
extra && extra.issue_codes ? t('%(message)s\nThis may be triggered by: \n%(issues)s', {
? t('%(message)s\nThis may be triggered by: \n%(issues)s', { message,
message, issues: extra.issue_codes
issues: extra.issue_codes .map(issueCode => issueCode.message)
.map(issueCode => issueCode.message) .join('\n'),
.join('\n'), })
}) : message;
: message;
return ( return (
<ErrorAlert <ErrorAlert
title={t('%s Error', (extra && extra.engine_name) || t('DB engine'))} title={t('%s Error', extra?.engine_name || t('DB engine'))}
subtitle={subtitle} subtitle={subtitle}
level={level} level={level}
source={source} source={source}

View File

@ -67,8 +67,8 @@ export default function FacePile({ users, maxCount = 4 }: FacePileProps) {
borderColor: color, borderColor: color,
}} }}
> >
{first_name && first_name[0]?.toLocaleUpperCase()} {first_name?.[0]?.toLocaleUpperCase()}
{last_name && last_name[0]?.toLocaleUpperCase()} {last_name?.[0]?.toLocaleUpperCase()}
</StyledAvatar> </StyledAvatar>
</Tooltip> </Tooltip>
); );

View File

@ -74,8 +74,7 @@ function UIFilters(
}, },
index, index,
) => { ) => {
const initialValue = const initialValue = internalFilters?.[index]?.value;
internalFilters[index] && internalFilters[index].value;
if (input === 'select') { if (input === 'select') {
return ( return (
<SelectFilter <SelectFilter

View File

@ -170,7 +170,7 @@ export const handleFilterOptionHelper = (
if (filterOption) { if (filterOption) {
const searchValue = search.trim().toLowerCase(); const searchValue = search.trim().toLowerCase();
if (optionFilterProps && optionFilterProps.length) { if (optionFilterProps?.length) {
return optionFilterProps.some(prop => { return optionFilterProps.some(prop => {
const optionProp = option?.[prop] const optionProp = option?.[prop]
? String(option[prop]).trim().toLowerCase() ? String(option[prop]).trim().toLowerCase()

View File

@ -292,9 +292,9 @@ export default React.memo(
{row.cells.map(cell => { {row.cells.map(cell => {
if (cell.column.hidden) return null; if (cell.column.hidden) return null;
const columnCellProps = cell.column.cellProps || {}; const columnCellProps = cell.column.cellProps || {};
const isWrapText = const isWrapText = columnsForWrapText?.includes(
columnsForWrapText && cell.column.Header as string,
columnsForWrapText.includes(cell.column.Header as string); );
return ( return (
<td <td

View File

@ -282,25 +282,22 @@ class SliceHeaderControls extends React.PureComponent<
break; break;
case MENU_KEYS.TOGGLE_CHART_DESCRIPTION: case MENU_KEYS.TOGGLE_CHART_DESCRIPTION:
// eslint-disable-next-line no-unused-expressions // 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; break;
case MENU_KEYS.EXPLORE_CHART: case MENU_KEYS.EXPLORE_CHART:
// eslint-disable-next-line no-unused-expressions // 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; break;
case MENU_KEYS.EXPORT_CSV: case MENU_KEYS.EXPORT_CSV:
// eslint-disable-next-line no-unused-expressions // 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; break;
case MENU_KEYS.FULLSCREEN: case MENU_KEYS.FULLSCREEN:
this.props.handleToggleFullSize(); this.props.handleToggleFullSize();
break; break;
case MENU_KEYS.EXPORT_FULL_CSV: case MENU_KEYS.EXPORT_FULL_CSV:
// eslint-disable-next-line no-unused-expressions // 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; break;
case MENU_KEYS.DOWNLOAD_AS_IMAGE: { case MENU_KEYS.DOWNLOAD_AS_IMAGE: {
// menu closes with a delay, we need to hide it manually, // menu closes with a delay, we need to hide it manually,

View File

@ -136,7 +136,7 @@ const FilterControl: React.FC<FilterProps> = ({
{name} {name}
</StyledFilterControlTitle> </StyledFilterControlTitle>
{isRequired && <RequiredFieldIndicator />} {isRequired && <RequiredFieldIndicator />}
{filter.description && filter.description.trim() && ( {filter.description?.trim() && (
<DescriptionToolTip description={filter.description} /> <DescriptionToolTip description={filter.description} />
)} )}
<StyledIcon data-test="filter-icon">{icon}</StyledIcon> <StyledIcon data-test="filter-icon">{icon}</StyledIcon>

View File

@ -62,10 +62,9 @@ export const useFilterScope = (filter: Filter) => {
if ( if (
filter.scope.excluded.length === 0 && filter.scope.excluded.length === 0 &&
(filter.scope.rootPath[0] === DASHBOARD_ROOT_ID || (filter.scope.rootPath[0] === DASHBOARD_ROOT_ID ||
(topLevelTabs && topLevelTabs?.every(topLevelTab =>
topLevelTabs.every(topLevelTab => filter.scope.rootPath.includes(topLevelTab),
filter.scope.rootPath.includes(topLevelTab), ))
)))
) { ) {
return { all: [t('All charts')] }; return { all: [t('All charts')] };
} }

View File

@ -396,7 +396,7 @@ export function FiltersConfigModal({
let array: string[] = []; let array: string[] = [];
if (formItem && 'dependencies' in formItem) { if (formItem && 'dependencies' in formItem) {
array = [...formItem.dependencies]; array = [...formItem.dependencies];
} else if (configItem && configItem.cascadeParentIds) { } else if (configItem?.cascadeParentIds) {
array = [...configItem.cascadeParentIds]; array = [...configItem.cascadeParentIds];
} }
dependencyMap.set(key, array); dependencyMap.set(key, array);

View File

@ -209,9 +209,9 @@ export const DashboardPage: FC<PageProps> = ({ idOrSlug }: PageProps) => {
useEffect(() => { useEffect(() => {
// should convert filter_box to filter component? // should convert filter_box to filter component?
const hasFilterBox = const hasFilterBox = charts?.some(
charts && chart => chart.form_data?.viz_type === 'filter_box',
charts.some(chart => chart.form_data?.viz_type === 'filter_box'); );
const canEdit = dashboard && canUserEditDashboard(dashboard, user); const canEdit = dashboard && canUserEditDashboard(dashboard, user);
if (canEdit) { if (canEdit) {

View File

@ -99,10 +99,7 @@ enum FILTER_COMPONENT_FILTER_TYPES {
const getPreselectedValuesFromDashboard = const getPreselectedValuesFromDashboard =
(preselectedFilters: PreselectedFiltersMeatadata) => (preselectedFilters: PreselectedFiltersMeatadata) =>
(filterKey: string, column: string) => { (filterKey: string, column: string) => {
if ( if (preselectedFilters[filterKey]?.[column]) {
preselectedFilters[filterKey] &&
preselectedFilters[filterKey][column]
) {
// overwrite default values by dashboard default_filters // overwrite default values by dashboard default_filters
return preselectedFilters[filterKey][column]; return preselectedFilters[filterKey][column];
} }

View File

@ -151,13 +151,12 @@ const DndFilterSelect = (props: DndFilterSelectProps) => {
endpoint: `/api/v1/database/${dbId}/table_extra/${name}/${schema}/`, endpoint: `/api/v1/database/${dbId}/table_extra/${name}/${schema}/`,
}) })
.then(({ json }: { json: Record<string, any> }) => { .then(({ json }: { json: Record<string, any> }) => {
if (json && json.partitions) { if (json?.partitions) {
const { partitions } = json; const { partitions } = json;
// for now only show latest_partition option // for now only show latest_partition option
// when table datasource has only 1 partition key. // when table datasource has only 1 partition key.
if ( if (
partitions && partitions?.cols &&
partitions.cols &&
Object.keys(partitions.cols).length === 1 Object.keys(partitions.cols).length === 1
) { ) {
setPartitionColumn(partitions.cols[0]); setPartitionColumn(partitions.cols[0]);

View File

@ -158,7 +158,7 @@ export const useSimpleTabFilterProps = (props: Props) => {
} else if (option && 'saved_metric_name' in option) { } else if (option && 'saved_metric_name' in option) {
subject = option.saved_metric_name; subject = option.saved_metric_name;
clause = CLAUSES.HAVING; clause = CLAUSES.HAVING;
} else if (option && option.label) { } else if (option?.label) {
subject = option.label; subject = option.label;
clause = CLAUSES.HAVING; clause = CLAUSES.HAVING;
} }

View File

@ -174,7 +174,7 @@ export function getAllControlsState(
getSectionsToRender(vizType, datasourceType).forEach(section => getSectionsToRender(vizType, datasourceType).forEach(section =>
section.controlSetRows.forEach(fieldsetRow => section.controlSetRows.forEach(fieldsetRow =>
fieldsetRow.forEach((field: CustomControlItem) => { fieldsetRow.forEach((field: CustomControlItem) => {
if (field && field.config && field.name) { if (field?.config && field.name) {
const { config, name } = field; const { config, name } = field;
controlsState[name] = getControlStateFromControlConfig( controlsState[name] = getControlStateFromControlConfig(
config, config,

View File

@ -105,7 +105,7 @@ const getParsedExploreURLPathParams = (pathname: string) =>
Object.keys(EXPLORE_URL_PATH_PARAMS).reduce((acc, currentParam) => { Object.keys(EXPLORE_URL_PATH_PARAMS).reduce((acc, currentParam) => {
const re = new RegExp(`/(${currentParam})/(\\w+)`); const re = new RegExp(`/(${currentParam})/(\\w+)`);
const pathGroups = pathname.match(re); const pathGroups = pathname.match(re);
if (pathGroups && pathGroups[2]) { if (pathGroups?.[2]) {
return { ...acc, [EXPLORE_URL_PATH_PARAMS[currentParam]]: pathGroups[2] }; return { ...acc, [EXPLORE_URL_PATH_PARAMS[currentParam]]: pathGroups[2] };
} }
return acc; return acc;

View File

@ -228,7 +228,7 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
: null; : null;
// firstItem[0] !== undefined for a case when groupby changed but new data still not fetched // 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 // TODO: still need repopulate default value in config modal when column changed
if (firstItem && firstItem[0] !== undefined) { if (firstItem?.[0] !== undefined) {
updateDataMask(firstItem); updateDataMask(firstItem);
} }
} else if (isDisabled) { } else if (isDisabled) {

View File

@ -171,7 +171,7 @@ const loadEventsFromApi = async () => {
if (Object.keys(listenersByJobId).length) { if (Object.keys(listenersByJobId).length) {
try { try {
const { result: events } = await fetchEvents(eventArgs); const { result: events } = await fetchEvents(eventArgs);
if (events && events.length) await processEvents(events); if (events?.length) await processEvents(events);
} catch (err) { } catch (err) {
logging.warn(err); logging.warn(err);
} }

View File

@ -52,7 +52,7 @@ if (typeof window !== 'undefined') {
bootstrapData = root bootstrapData = root
? JSON.parse(root.getAttribute('data-bootstrap') || '{}') ? JSON.parse(root.getAttribute('data-bootstrap') || '{}')
: {}; : {};
if (bootstrapData.common && bootstrapData.common.language_pack) { if (bootstrapData?.common?.language_pack) {
const languagePack = bootstrapData.common.language_pack; const languagePack = bootstrapData.common.language_pack;
configure({ languagePack }); configure({ languagePack });
moment.locale(bootstrapData.common.locale); moment.locale(bootstrapData.common.locale);

View File

@ -52,7 +52,7 @@ function toggleCheckbox(apiUrlPrefix: string, selector: string) {
.then(() => undefined) .then(() => undefined)
.catch(response => .catch(response =>
getClientErrorObject(response).then(parsedResp => { getClientErrorObject(response).then(parsedResp => {
if (parsedResp && parsedResp.message) { if (parsedResp?.message) {
showApiMessage(parsedResp); showApiMessage(parsedResp);
} }
}), }),

View File

@ -30,7 +30,7 @@ function getDefaultConfiguration(): ClientConfig {
protocol: ['http:', 'https:'].includes(window?.location?.protocol) protocol: ['http:', 'https:'].includes(window?.location?.protocol)
? (window?.location?.protocol as 'http:' | 'https:') ? (window?.location?.protocol as 'http:' | 'https:')
: undefined, : undefined,
host: (window.location && window.location.host) || '', host: window.location?.host || '',
csrfToken: csrfToken || cookieCSRFToken, csrfToken: csrfToken || cookieCSRFToken,
}; };
} }

View File

@ -191,7 +191,7 @@ function AlertList({
const toggleActive = useCallback( const toggleActive = useCallback(
(data: AlertObject, checked: boolean) => { (data: AlertObject, checked: boolean) => {
if (data && data.id) { if (data?.id) {
const update_id = data.id; const update_id = data.id;
const original = [...alerts]; const original = [...alerts];

View File

@ -544,7 +544,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
if (isEditMode) { if (isEditMode) {
// Edit // Edit
if (currentAlert && currentAlert.id) { if (currentAlert?.id) {
const update_id = currentAlert.id; const update_id = currentAlert.id;
delete data.id; delete data.id;
@ -664,8 +664,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
[], [],
); );
const databaseLabel = const databaseLabel = currentAlert?.database && !currentAlert.database.label;
currentAlert && currentAlert.database && !currentAlert.database.label;
useEffect(() => { useEffect(() => {
// Find source if current alert has one set // Find source if current alert has one set
if (databaseLabel) { if (databaseLabel) {
@ -738,8 +737,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
[chartOptions, currentAlert?.chart], [chartOptions, currentAlert?.chart],
); );
const noChartLabel = const noChartLabel = currentAlert?.chart && !currentAlert?.chart.label;
currentAlert && currentAlert.chart && !currentAlert.chart.label;
useEffect(() => { useEffect(() => {
// Find source if current alert has one set // Find source if current alert has one set
if (noChartLabel) { if (noChartLabel) {
@ -899,13 +897,12 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
const validate = () => { const validate = () => {
if ( if (
currentAlert && currentAlert?.name?.length &&
currentAlert.name?.length && currentAlert?.owners?.length &&
currentAlert.owners?.length && currentAlert?.crontab?.length &&
currentAlert.crontab?.length && currentAlert?.working_timeout !== undefined &&
currentAlert.working_timeout !== undefined && ((contentType === 'dashboard' && !!currentAlert?.dashboard) ||
((contentType === 'dashboard' && !!currentAlert.dashboard) || (contentType === 'chart' && !!currentAlert?.chart)) &&
(contentType === 'chart' && !!currentAlert.chart)) &&
checkNotificationSettings() checkNotificationSettings()
) { ) {
if (isReport) { if (isReport) {
@ -932,7 +929,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
isEditMode && isEditMode &&
(!currentAlert?.id || alert?.id !== currentAlert.id || (isHidden && show)) (!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; const id = alert.id || 0;
fetchResource(id); fetchResource(id);
} }
@ -1214,10 +1211,8 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
name="threshold" name="threshold"
disabled={conditionNotNull} disabled={conditionNotNull}
value={ value={
currentAlert && currentAlert?.validator_config_json?.threshold !==
currentAlert.validator_config_json && undefined
currentAlert.validator_config_json.threshold !==
undefined
? currentAlert.validator_config_json.threshold ? currentAlert.validator_config_json.threshold
: '' : ''
} }

View File

@ -130,7 +130,7 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
const onSave = () => { const onSave = () => {
if (isEditMode) { if (isEditMode) {
// Edit // Edit
if (currentAnnotation && currentAnnotation.id) { if (currentAnnotation?.id) {
const update_id = currentAnnotation.id; const update_id = currentAnnotation.id;
delete currentAnnotation.id; delete currentAnnotation.id;
delete currentAnnotation.created_by; delete currentAnnotation.created_by;
@ -217,10 +217,9 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
const validate = () => { const validate = () => {
if ( if (
currentAnnotation && currentAnnotation?.short_descr?.length &&
currentAnnotation.short_descr?.length && currentAnnotation?.start_dttm?.length &&
currentAnnotation.start_dttm?.length && currentAnnotation?.end_dttm?.length
currentAnnotation.end_dttm?.length
) { ) {
setDisableSave(false); setDisableSave(false);
} else { } else {
@ -237,7 +236,7 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
(annotation && annotation.id !== currentAnnotation.id) || (annotation && annotation.id !== currentAnnotation.id) ||
show) show)
) { ) {
if (annotation && annotation.id !== null && !loading) { if (annotation?.id !== null && !loading) {
const id = annotation.id || 0; const id = annotation.id || 0;
fetchResource(id); fetchResource(id);
@ -337,7 +336,7 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
<StyledJsonEditor <StyledJsonEditor
onChange={onJsonChange} onChange={onJsonChange}
value={ value={
currentAnnotation && currentAnnotation.json_metadata currentAnnotation?.json_metadata
? currentAnnotation.json_metadata ? currentAnnotation.json_metadata
: '' : ''
} }

View File

@ -126,7 +126,7 @@ const AnnotationLayerModal: FunctionComponent<AnnotationLayerModalProps> = ({
const onSave = () => { const onSave = () => {
if (isEditMode) { if (isEditMode) {
// Edit // Edit
if (currentLayer && currentLayer.id) { if (currentLayer?.id) {
const update_id = currentLayer.id; const update_id = currentLayer.id;
delete currentLayer.id; delete currentLayer.id;
delete currentLayer.created_by; delete currentLayer.created_by;
@ -173,7 +173,7 @@ const AnnotationLayerModal: FunctionComponent<AnnotationLayerModalProps> = ({
}; };
const validate = () => { const validate = () => {
if (currentLayer && currentLayer.name?.length) { if (currentLayer?.name?.length) {
setDisableSave(false); setDisableSave(false);
} else { } else {
setDisableSave(true); setDisableSave(true);

View File

@ -101,7 +101,7 @@ const CssTemplateModal: FunctionComponent<CssTemplateModalProps> = ({
const onSave = () => { const onSave = () => {
if (isEditMode) { if (isEditMode) {
// Edit // Edit
if (currentCssTemplate && currentCssTemplate.id) { if (currentCssTemplate?.id) {
const update_id = currentCssTemplate.id; const update_id = currentCssTemplate.id;
delete currentCssTemplate.id; delete currentCssTemplate.id;
delete currentCssTemplate.created_by; delete currentCssTemplate.created_by;
@ -157,10 +157,8 @@ const CssTemplateModal: FunctionComponent<CssTemplateModalProps> = ({
const validate = () => { const validate = () => {
if ( if (
currentCssTemplate && currentCssTemplate?.template_name.length &&
currentCssTemplate.template_name.length && currentCssTemplate?.css?.length
currentCssTemplate.css &&
currentCssTemplate.css.length
) { ) {
setDisableSave(false); setDisableSave(false);
} else { } else {
@ -174,10 +172,10 @@ const CssTemplateModal: FunctionComponent<CssTemplateModalProps> = ({
isEditMode && isEditMode &&
(!currentCssTemplate || (!currentCssTemplate ||
!currentCssTemplate.id || !currentCssTemplate.id ||
(cssTemplate && cssTemplate.id !== currentCssTemplate.id) || (cssTemplate && cssTemplate?.id !== currentCssTemplate.id) ||
(isHidden && show)) (isHidden && show))
) { ) {
if (cssTemplate && cssTemplate.id !== null && !loading) { if (cssTemplate?.id !== null && !loading) {
const id = cssTemplate.id || 0; const id = cssTemplate.id || 0;
fetchResource(id); fetchResource(id);

View File

@ -78,9 +78,7 @@ function DashboardCard({
role="button" role="button"
tabIndex={0} tabIndex={0}
className="action-button" className="action-button"
onClick={() => onClick={() => openDashboardEditModal?.(dashboard)}
openDashboardEditModal && openDashboardEditModal(dashboard)
}
data-test="dashboard-card-option-edit-button" data-test="dashboard-card-option-edit-button"
> >
<Icons.EditAlt iconSize="l" data-test="edit-alt" /> {t('Edit')} <Icons.EditAlt iconSize="l" data-test="edit-alt" /> {t('Edit')}

View File

@ -227,10 +227,8 @@ export function createErrorHandler(
const errorsArray = parsedError?.errors; const errorsArray = parsedError?.errors;
const config = await SupersetText; const config = await SupersetText;
if ( if (
errorsArray && errorsArray?.length &&
errorsArray.length && config?.ERRORS &&
config &&
config.ERRORS &&
errorsArray[0].error_type in config.ERRORS errorsArray[0].error_type in config.ERRORS
) { ) {
parsedError.message = config.ERRORS[errorsArray[0].error_type]; parsedError.message = config.ERRORS[errorsArray[0].error_type];

View File

@ -287,7 +287,7 @@ const RightMenu = ({
onDatabaseAdd={handleDatabaseAdd} onDatabaseAdd={handleDatabaseAdd}
/> />
)} )}
{environmentTag && environmentTag.text && ( {environmentTag?.text && (
<Label <Label
css={{ borderRadius: `${theme.gridUnit * 125}px` }} css={{ borderRadius: `${theme.gridUnit * 125}px` }}
color={ color={