Alerting: Enable `no-nested-ternary` ESLint rule (#104085)

This commit is contained in:
Tom Ratcliffe 2025-04-23 12:00:40 +01:00 committed by GitHub
parent dc0501e376
commit f9d2199b12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 117 additions and 106 deletions

View File

@ -268,6 +268,7 @@ module.exports = [
'react/self-closing-comp': 'error',
'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }],
'unicorn/no-unused-properties': 'error',
'no-nested-ternary': 'error',
},
},
{

View File

@ -149,13 +149,16 @@ function useAlertsFolderViewParams() {
const [labelFilter, setLabelFilter] = useState(searchParams.get(AlertFolderViewParams.labelFilter) ?? '');
const sortParam = searchParams.get(AlertFolderViewParams.sortOrder);
const [sortOrder, setSortOrder] = useState<SortOrder | undefined>(
sortParam === SortOrder.Ascending
? SortOrder.Ascending
: sortParam === SortOrder.Descending
? SortOrder.Descending
: undefined
);
const defaultSortOrder = (() => {
if (sortParam === SortOrder.Ascending) {
return SortOrder.Ascending;
}
if (sortParam === SortOrder.Descending) {
return SortOrder.Descending;
}
return undefined;
})();
const [sortOrder, setSortOrder] = useState<SortOrder | undefined>(defaultSortOrder);
useDebounce(
() =>

View File

@ -107,9 +107,8 @@ export const MuteTimingsTable = () => {
</>
)}
</Stack>
{items.length > 0 ? (
<DynamicTable items={items} cols={columns} pagination={{ itemsPerPage: 25 }} />
) : !hideActions ? (
{items.length > 0 ? <DynamicTable items={items} cols={columns} pagination={{ itemsPerPage: 25 }} /> : null}
{items.length === 0 && !hideActions ? (
<EmptyAreaWithCTA
text={t(
'alerting.mute-timings-table.text-havent-created-timings',

View File

@ -237,18 +237,19 @@ const Policy = (props: PolicyComponentProps) => {
}
/>
) : null}
{isImmutablePolicy ? (
isAutogeneratedPolicyRoot ? (
<AutogeneratedRootIndicator />
) : (
<DefaultPolicyIndicator />
)
) : hasMatchers ? (
<Matchers matchers={matchers ?? []} formatter={getAmMatcherFormatter(alertManagerSourceName)} />
) : (
<span className={styles.metadata}>
<Trans i18nKey="alerting.policies.no-matchers">No matchers</Trans>
</span>
{isImmutablePolicy && (
<>{isAutogeneratedPolicyRoot ? <AutogeneratedRootIndicator /> : <DefaultPolicyIndicator />}</>
)}
{!isImmutablePolicy && (
<>
{hasMatchers ? (
<Matchers matchers={matchers ?? []} formatter={getAmMatcherFormatter(alertManagerSourceName)} />
) : (
<span className={styles.metadata}>
<Trans i18nKey="alerting.policies.no-matchers">No matchers</Trans>
</span>
)}
</>
)}
<Spacer />
{/* TODO maybe we should move errors to the gutter instead? */}

View File

@ -54,19 +54,23 @@ export function TemplateDataDocs() {
</>
}
dataItems={GlobalTemplateData}
typeRenderer={(type) =>
type === '[]Alert' ? (
<PopupCard content={AlertTemplateDataTable}>
<div className={styles.interactiveType}>{type}</div>
</PopupCard>
) : type === 'KeyValue' ? (
<PopupCard content={<KeyValueTemplateDataTable />}>
<div className={styles.interactiveType}>{type}</div>
</PopupCard>
) : (
type
)
}
typeRenderer={(type) => {
if (type === '[]Alert') {
return (
<PopupCard content={AlertTemplateDataTable}>
<div className={styles.interactiveType}>{type}</div>
</PopupCard>
);
}
if (type === 'KeyValue') {
return (
<PopupCard content={<KeyValueTemplateDataTable />}>
<div className={styles.interactiveType}>{type}</div>
</PopupCard>
);
}
return type;
}}
/>
</Stack>
);

View File

@ -138,11 +138,9 @@ export function ReceiverForm<R extends ChannelValues>({
<form onSubmit={handleSubmit(submitCallback, onInvalid)} className={styles.wrapper}>
<Stack justifyContent="space-between" alignItems="center">
<h2 className={styles.heading}>
{!isEditable
? t('alerting.receiver-form.contact-point', 'Contact point')
: initialValues
? t('alerting.receiver-form.contact-point-update', 'Update contact point')
: t('alerting.receiver-form.contact-point-create', 'Create contact point')}
{!isEditable && t('alerting.receiver-form.contact-point', 'Contact point')}
{isEditable && initialValues && t('alerting.receiver-form.contact-point-update', 'Update contact point')}
{isEditable && !initialValues && t('alerting.receiver-form.contact-point-create', 'Create contact point')}
</h2>
{canManagePermissions && contactPointId && (
<ManagePermissions

View File

@ -78,11 +78,16 @@ export const NotificationsStep = ({ alertUid }: NotificationsStepProps) => {
},
}
: undefined;
const title = isRecordingRuleByType(type)
? 'Add labels'
: isGrafanaManaged
? 'Configure notifications'
: 'Configure labels and notifications';
const title = (() => {
if (isRecordingRuleByType(type)) {
return 'Add labels';
}
if (isGrafanaManaged) {
return 'Configure notifications';
}
return 'Configure labels and notifications';
})();
return (
<RuleEditorSection
@ -128,17 +133,13 @@ export const NotificationsStep = ({ alertUid }: NotificationsStepProps) => {
</Text>
</div>
)}
{shouldAllowSimplifiedRouting ? ( // when simplified routing is enabled and is grafana rule
simplifiedModeInNotificationsStepEnabled ? ( // simplified mode is enabled
<ManualAndAutomaticRoutingSimplified alertUid={alertUid} />
) : (
// simplified mode is disabled
<ManualAndAutomaticRouting alertUid={alertUid} />
)
) : // when simplified routing is not enabled, render the notification preview as we did before
shouldRenderpreview ? (
<AutomaticRooting alertUid={alertUid} />
) : null}
{shouldAllowSimplifiedRouting && simplifiedModeInNotificationsStepEnabled && (
<ManualAndAutomaticRoutingSimplified alertUid={alertUid} />
)}
{shouldAllowSimplifiedRouting && !simplifiedModeInNotificationsStepEnabled && (
<ManualAndAutomaticRouting alertUid={alertUid} />
)}
{!shouldAllowSimplifiedRouting && shouldRenderpreview && <AutomaticRooting alertUid={alertUid} />}
</RuleEditorSection>
);
};

View File

@ -362,13 +362,15 @@ export const AlertRuleForm = ({ existing, prefill, isManualRestore }: Props) =>
onDismiss={() => setShowDeleteModal(false)}
/>
) : null}
{showEditYaml ? (
isGrafanaManagedRuleByType(type) ? (
<GrafanaRuleExporter alertUid={uidFromParams} onClose={() => setShowEditYaml(false)} />
) : (
<RuleInspector onClose={() => setShowEditYaml(false)} />
)
) : null}
{showEditYaml && (
<>
{isGrafanaManagedRuleByType(type) && (
<GrafanaRuleExporter alertUid={uidFromParams} onClose={() => setShowEditYaml(false)} />
)}
{!isGrafanaManagedRuleByType(type) && <RuleInspector onClose={() => setShowEditYaml(false)} />}
</>
)}
</FormProvider>
);
};

View File

@ -127,9 +127,8 @@ export function VersionHistoryTable({
return (
<Stack direction="row" alignItems="center" justifyContent="flex-end">
{isFirstItem ? (
<Badge text={t('alerting.alertVersionHistory.latest', 'Latest')} color="blue" />
) : canRestore ? (
{isFirstItem && <Badge text={t('alerting.alertVersionHistory.latest', 'Latest')} color="blue" />}
{!isFirstItem && canRestore && (
<>
<Button
variant="secondary"
@ -153,7 +152,7 @@ export function VersionHistoryTable({
<Trans i18nKey="alerting.alertVersionHistory.restore">Restore</Trans>
</Button>
</>
) : null}
)}
</Stack>
);
},

View File

@ -400,44 +400,38 @@ function rulerRuleToCombinedRule(
namespace: CombinedRuleNamespace,
group: CombinedRuleGroup
): CombinedRule {
return rulerRuleType.dataSource.alertingRule(rule)
? {
name: rule.alert,
query: rule.expr,
labels: rule.labels || {},
annotations: rule.annotations || {},
rulerRule: rule,
namespace,
group,
instanceTotals: {},
filteredInstanceTotals: {},
uid: rulerRuleType.grafana.rule(rule) ? rule.grafana_alert.uid : undefined,
}
: rulerRuleType.dataSource.recordingRule(rule)
? {
name: rule.record,
query: rule.expr,
labels: rule.labels || {},
annotations: {},
rulerRule: rule,
namespace,
group,
instanceTotals: {},
filteredInstanceTotals: {},
uid: rulerRuleType.grafana.rule(rule) ? rule.grafana_alert.uid : undefined,
}
: {
name: rule.grafana_alert.title,
query: '',
labels: rule.labels || {},
annotations: rule.annotations || {},
rulerRule: rule,
namespace,
group,
instanceTotals: {},
filteredInstanceTotals: {},
uid: rulerRuleType.grafana.rule(rule) ? rule.grafana_alert.uid : undefined,
};
const commonProps = {
labels: rule.labels || {},
rulerRule: rule,
namespace,
group,
instanceTotals: {},
filteredInstanceTotals: {},
uid: rulerRuleType.grafana.rule(rule) ? rule.grafana_alert.uid : undefined,
};
if (rulerRuleType.dataSource.alertingRule(rule)) {
return {
...commonProps,
name: rule.alert,
query: rule.expr,
annotations: rule.annotations || {},
};
}
if (rulerRuleType.dataSource.recordingRule(rule)) {
return {
...commonProps,
name: rule.record,
query: rule.expr,
annotations: {},
};
}
return {
...commonProps,
name: rule.grafana_alert.title,
query: '',
annotations: rule.annotations || {},
};
}
// find existing rule in group that matches the given prom rule

View File

@ -36,6 +36,15 @@ export const DEFAULT_GROUP_EVALUATION_INTERVAL = formatPrometheusDuration(
);
export const getDefaultFormValues = (): RuleFormValues => {
const { canCreateGrafanaRules, canCreateCloudRules } = getRulesAccess();
const type = (() => {
if (canCreateGrafanaRules) {
return RuleFormType.grafana;
}
if (canCreateCloudRules) {
return RuleFormType.cloudAlerting;
}
return undefined;
})();
return Object.freeze({
name: '',
@ -43,7 +52,7 @@ export const getDefaultFormValues = (): RuleFormValues => {
labels: [{ key: '', value: '' }],
annotations: defaultAnnotations,
dataSourceName: GRAFANA_RULES_SOURCE_NAME, // let's use Grafana-managed alert rule by default
type: canCreateGrafanaRules ? RuleFormType.grafana : canCreateCloudRules ? RuleFormType.cloudAlerting : undefined, // viewers can't create prom alerts
type, // viewers can't create prom alerts
group: '',
// grafana