Discussion: Proposed technical implementation of a data structure for date ranges
Background
In regards to #197879 (closed) and date time ranges there is something that doesn't quite fit right now. You may refer to an old issue that has info on the general direction of our date picking -> gitlab-foss#31368 (closed)
![](/-/project/278964/uploads/00f74c5597d87da26dde74f6b6441668/image.png)
When the user selects the "Last 3 hours" option, it makes sense that we take that range of "Last 3 hours" as dates {start: now() - (3 hours in seconds), end: now()}
, then convert that to ISO Date Strings and send that request to the backend.
We would store those dates in the Vuex store, to let the user know where they are, which range is active, and then issue a fetch call for the data.
Problem
But what if we want to refresh the data at a later point? The user might click on a "refresh" button or we might want to schedule a refresh every X seconds.
Naively we could reload using the current dates in the Vuex store, but that's not what the user wants, they want the "Last 3 hours" of data, refreshed to match now()
.
Proposal
So we must store something else in Vuex: the number of seconds before now(), so we can recalculate the dates every time we fetch data.
AND we must also be able to store absolute dates, so the user can select a custom time range.
So, I suggest a data structure like this:
{
start_time: <String ISO Date> OR <Number>,
end_time: <String ISO Date> OR <Number>,
label: String
}
If the start_date
/end_date
is a String
, it should get interpreted as an ISO Date.
{
start_time: "2020-01-01T00:00:00Z"
end_time: "2020-01-01T23:59:59Z"
label: "1st of January"
}
BUT if start_time
is a Number
, it represents seconds added to now(), so "Last 3 hours" would be represented as:
{
start_time: - (60 * 60 * 3)
end_time: 0 // now
label: "Last 3 hours"
}
As not always we will be able to define a label in advance, so some times we will generate it with the given info:
{
start_time: "2020-01-01T00:00:00Z"
end_time: "2020-01-01T23:59:59Z"
label: "2020-01-01 to 2020-01-01 23:59:59" // calculated
}
There would be a util that transforms these DateRange to pairs of start / end date that would be sent to the backend:
getAbsoluteTimeRange({ // still working on the naming, ideas?
start_time: - (60 * 60 * 3)
end_time: 0 // now
label: "Last 3 hours"
});
Returns something like:
{
start: "2020-01-22T04:25:47Z",
end: "2020-01-22T07:25:47Z"
}
But this result is updated every time getAbsoluteTimeRange
is called, this function would be called in the Vuex action, right before fetching from the backend.
Usage
We would use this data structure when we need to represent a time range, a would create some sort of lib around it, to manipulate the ranges and go from one representation to the other.