Merge pull request #676 from prymitive/startsAt-sort-fallback

feat(ui): use alerts timestamp as secondary sort key
This commit is contained in:
Łukasz Mierzwa
2019-05-04 22:45:50 +01:00
committed by GitHub
2 changed files with 97 additions and 30 deletions

View File

@@ -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;
}

View File

@@ -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();