mirror of
https://github.com/prymitive/karma
synced 2026-05-09 03:36:44 +00:00
Merge pull request #676 from prymitive/startsAt-sort-fallback
feat(ui): use alerts timestamp as secondary sort key
This commit is contained in:
@@ -25,6 +25,33 @@ import { GridSizesConfig, GetGridElementWidth } from "./GridSize";
|
||||
|
||||
import "./index.css";
|
||||
|
||||
const getGroupStartsAt = g => moment.max(g.alerts.map(a => moment(a.startsAt)));
|
||||
|
||||
const getLabelValue = (alertStore, settingsStore, sortOrder, sortLabel, g) => {
|
||||
// if timestamp sort is enabled use latest alert for sorting
|
||||
if (sortOrder === settingsStore.gridConfig.options.startsAt.value) {
|
||||
return getGroupStartsAt(g);
|
||||
}
|
||||
|
||||
const labelValue =
|
||||
g.labels[sortLabel] ||
|
||||
g.shared.labels[sortLabel] ||
|
||||
g.alerts[0].labels[sortLabel];
|
||||
let mappedValue;
|
||||
|
||||
// check if we have a mapping for label value
|
||||
if (
|
||||
labelValue !== undefined &&
|
||||
alertStore.settings.values.sorting.valueMapping[sortLabel] !== undefined
|
||||
) {
|
||||
mappedValue =
|
||||
alertStore.settings.values.sorting.valueMapping[sortLabel][labelValue];
|
||||
}
|
||||
|
||||
// if we have a mapped value then return it, if not return original value
|
||||
return mappedValue !== undefined ? mappedValue : labelValue;
|
||||
};
|
||||
|
||||
const AlertGrid = observer(
|
||||
class AlertGrid extends Component {
|
||||
static propTypes = {
|
||||
@@ -136,38 +163,22 @@ const AlertGrid = observer(
|
||||
? alertStore.settings.values.sorting.grid.label
|
||||
: settingsStore.gridConfig.config.sortLabel;
|
||||
|
||||
const getLabelValue = g => {
|
||||
// if timestamp sort is enabled use latest alert for sorting
|
||||
if (sortOrder === settingsStore.gridConfig.options.startsAt.value) {
|
||||
return moment.max(g.alerts.map(a => moment(a.startsAt)));
|
||||
}
|
||||
|
||||
const labelValue =
|
||||
g.labels[sortLabel] ||
|
||||
g.shared.labels[sortLabel] ||
|
||||
g.alerts[0].labels[sortLabel];
|
||||
let mappedValue;
|
||||
|
||||
// check if we have a mapping for label value
|
||||
if (
|
||||
labelValue !== undefined &&
|
||||
alertStore.settings.values.sorting.valueMapping[sortLabel] !==
|
||||
undefined
|
||||
) {
|
||||
mappedValue =
|
||||
alertStore.settings.values.sorting.valueMapping[sortLabel][
|
||||
labelValue
|
||||
];
|
||||
}
|
||||
|
||||
// if we have a mapped value then return it, if not return original value
|
||||
return mappedValue !== undefined ? mappedValue : labelValue;
|
||||
};
|
||||
|
||||
const val = sortReverse ? -1 : 1;
|
||||
|
||||
const av = getLabelValue(a);
|
||||
const bv = getLabelValue(b);
|
||||
const av = getLabelValue(
|
||||
alertStore,
|
||||
settingsStore,
|
||||
sortOrder,
|
||||
sortLabel,
|
||||
a
|
||||
);
|
||||
const bv = getLabelValue(
|
||||
alertStore,
|
||||
settingsStore,
|
||||
sortOrder,
|
||||
sortLabel,
|
||||
b
|
||||
);
|
||||
|
||||
if (av === undefined && av === undefined) {
|
||||
// if both alerts lack the label they are equal
|
||||
@@ -178,6 +189,18 @@ const AlertGrid = observer(
|
||||
} else if (bv === undefined || av < bv) {
|
||||
// if the first one has label but the second doesn't then the second should be rendered after the first
|
||||
return val * -1;
|
||||
} else if (
|
||||
sortOrder !== settingsStore.gridConfig.options.startsAt.value
|
||||
) {
|
||||
const ast = getGroupStartsAt(a);
|
||||
const bst = getGroupStartsAt(b);
|
||||
if (ast > bst) {
|
||||
return 1;
|
||||
} else if (ast < bst) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -326,6 +326,50 @@ describe("<AlertGrid />", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("startsAt is used as secondary sort key if all labels have equal value", () => {
|
||||
settingsStore.gridConfig.config.sortOrder =
|
||||
settingsStore.gridConfig.options.label.value;
|
||||
settingsStore.gridConfig.config.sortLabel = "cluster";
|
||||
|
||||
MockGroupList(3, 1);
|
||||
alertStore.data.groups.id1.alerts[0].labels.cluster = "dev";
|
||||
alertStore.data.groups.id1.alerts[0].startsAt = "2000-01-01T00:00:02.000Z";
|
||||
alertStore.data.groups.id2.alerts[0].labels.cluster = "dev";
|
||||
alertStore.data.groups.id2.alerts[0].startsAt = "2000-01-01T00:00:03.000Z";
|
||||
alertStore.data.groups.id3.alerts[0].labels.cluster = "dev";
|
||||
alertStore.data.groups.id3.alerts[0].startsAt = "2000-01-01T00:00:01.000Z";
|
||||
|
||||
const tree = ShallowAlertGrid();
|
||||
const alertGroups = tree.find("AlertGroup");
|
||||
expect(alertGroups.map(g => g.props().group.id)).toEqual([
|
||||
"id3",
|
||||
"id1",
|
||||
"id2"
|
||||
]);
|
||||
});
|
||||
|
||||
it("original order is preserved when startsAt is used as fallback and all alerts have the same timestamp", () => {
|
||||
settingsStore.gridConfig.config.sortOrder =
|
||||
settingsStore.gridConfig.options.label.value;
|
||||
settingsStore.gridConfig.config.sortLabel = "cluster";
|
||||
|
||||
MockGroupList(3, 1);
|
||||
alertStore.data.groups.id1.alerts[0].labels.cluster = "dev";
|
||||
alertStore.data.groups.id1.alerts[0].startsAt = "2000-01-01T00:00:01.000Z";
|
||||
alertStore.data.groups.id2.alerts[0].labels.cluster = "dev";
|
||||
alertStore.data.groups.id2.alerts[0].startsAt = "2000-01-01T00:00:01.000Z";
|
||||
alertStore.data.groups.id3.alerts[0].labels.cluster = "dev";
|
||||
alertStore.data.groups.id3.alerts[0].startsAt = "2000-01-01T00:00:01.000Z";
|
||||
|
||||
const tree = ShallowAlertGrid();
|
||||
const alertGroups = tree.find("AlertGroup");
|
||||
expect(alertGroups.map(g => g.props().group.id)).toEqual([
|
||||
"id1",
|
||||
"id2",
|
||||
"id3"
|
||||
]);
|
||||
});
|
||||
|
||||
it("doesn't throw errors after FontFaceObserver timeout", () => {
|
||||
MockGroupList(60, 5);
|
||||
ShallowAlertGrid();
|
||||
|
||||
Reference in New Issue
Block a user