diff --git a/packages/grafana-runtime/src/components/DataSourcePicker.tsx b/packages/grafana-runtime/src/components/DataSourcePicker.tsx index 1146c35fe02..7936b793434 100644 --- a/packages/grafana-runtime/src/components/DataSourcePicker.tsx +++ b/packages/grafana-runtime/src/components/DataSourcePicker.tsx @@ -55,7 +55,7 @@ export class DataSourcePicker extends PureComponent = { autoFocus: false, openMenuOnFocus: false, - placeholder: 'Select datasource', + placeholder: 'Select data source', }; state: DataSourcePickerState = {}; diff --git a/public/app/features/alerting/unified/components/rules/AlertInstancesTable.tsx b/public/app/features/alerting/unified/components/rules/AlertInstancesTable.tsx index c2e8a59ccc0..c04f0aa7ee5 100644 --- a/public/app/features/alerting/unified/components/rules/AlertInstancesTable.tsx +++ b/public/app/features/alerting/unified/components/rules/AlertInstancesTable.tsx @@ -1,8 +1,8 @@ import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import { AlertingRule } from 'app/types/unified-alerting'; +import { Alert } from 'app/types/unified-alerting'; import { css, cx } from '@emotion/css'; -import React, { FC, Fragment, useState } from 'react'; +import React, { FC, Fragment, useMemo, useState } from 'react'; import { getAlertTableStyles } from '../../styles/table'; import { alertInstanceKey } from '../../utils/rules'; import { AlertLabels } from '../AlertLabels'; @@ -10,8 +10,10 @@ import { CollapseToggle } from '../CollapseToggle'; import { AlertInstanceDetails } from './AlertInstanceDetails'; import { AlertStateTag } from './AlertStateTag'; +type AlertWithKey = Alert & { key: string }; + interface Props { - instances: AlertingRule['alerts']; + instances: Alert[]; } export const AlertInstancesTable: FC = ({ instances }) => { @@ -20,6 +22,18 @@ export const AlertInstancesTable: FC = ({ instances }) => { const [expandedKeys, setExpandedKeys] = useState([]); + // add key & sort instance. API returns instances in random order, different every time. + const sortedInstances = useMemo( + (): AlertWithKey[] => + instances + .map((instance) => ({ + ...instance, + key: alertInstanceKey(instance), + })) + .sort((a, b) => a.key.localeCompare(b.key)), + [instances] + ); + const toggleExpandedState = (ruleKey: string) => setExpandedKeys( expandedKeys.includes(ruleKey) ? expandedKeys.filter((key) => key !== ruleKey) : [...expandedKeys, ruleKey] @@ -42,8 +56,7 @@ export const AlertInstancesTable: FC = ({ instances }) => { - {instances.map((instance, idx) => { - const key = alertInstanceKey(instance); + {sortedInstances.map(({ key, ...instance }, idx) => { const isExpanded = expandedKeys.includes(key); // don't allow expanding if there's nothing to show