diff --git a/frontend/src/App.res b/frontend/src/App.res index 8b40e3ab..1cc485dc 100644 --- a/frontend/src/App.res +++ b/frontend/src/App.res @@ -266,14 +266,15 @@ module Welcome = { } } -let makeOnSelectRepoId = (worker, repoId) => - AppRouter.Repo({repoId: repoId, benchmarkName: None, worker: worker})->AppRouter.go +let makeOnSelectRepoId = (worker, repoId) => { + AppRouter.Repo({repoId, benchmarkName: None, worker, dateRange: None})->AppRouter.go +} module ErrorView = { @react.component let make = (~msg, ~repoIds=[], ~onSelectRepoId=makeOnSelectRepoId(None)) => { <> - ()} /> + ()} /> {Rx.text(msg)} @@ -291,25 +292,68 @@ module ErrorView = { module RepoView = { @react.component - let make = (~repoId=?, ~branch=?, ~pullNumber=?, ~pullBase=?, ~benchmarkName=?, ~worker) => { + let make = ( + ~repoId=?, + ~branch=?, + ~pullNumber=?, + ~pullBase=?, + ~benchmarkName=?, + ~worker, + ~dateRange=?, + ) => { let ({ReScriptUrql.Hooks.response: response}, _) = { ReScriptUrql.Hooks.useQuery(~query=module(GetAllRepos), ()) } - let ((startDate, endDate), setDateRange) = React.useState(getDefaultDateRange) - let onSelectDateRange = (startDate, endDate) => setDateRange(_ => (startDate, endDate)) + let convertDates = range => { + switch range { + | Some((start, end)) => + Some((Js.Date.fromString(start ++ "T00:00:00"), Js.Date.fromString(end ++ "T23:59:59"))) + | _ => None + } + } + let ((startDate, endDate), setDateRange) = React.useState(() => + convertDates(dateRange)->Belt.Option.getWithDefault(getDefaultDateRange()) + ) + let onSelectDateRange = (startDate, endDate) => { + let makeUtcISOString = d => { + let tzOffset = Js.Date.getTimezoneOffset(d) + // Convert offset to milliseconds and subtract from local time + let utcTimeMs = Js.Date.getTime(d) -. tzOffset *. 60.0 *. 1000.0 + let utcDate = Js.Date.fromFloat(utcTimeMs) + Js.String2.split(Js.Date.toISOString(utcDate), "T")[0] + } + let dateRange = Some(makeUtcISOString(startDate), makeUtcISOString(endDate)) + setDateRange(_ => (startDate, endDate)) + switch (repoId, pullNumber, pullBase) { + | (Some(repoId), Some(pullNumber), Some(pullBase)) => + AppRouter.RepoPull({ + repoId, + pullNumber, + pullBase, + benchmarkName, + worker, + dateRange, + })->AppRouter.go + | (Some(repoId), _, _) => + AppRouter.Repo({repoId, benchmarkName, worker, dateRange})->AppRouter.go + | _ => () + } + } let setWorker = worker => { switch (repoId, pullNumber, pullBase) { | (Some(repoId), Some(pullNumber), Some(pullBase)) => AppRouter.RepoPull({ - repoId: repoId, - pullNumber: pullNumber, - pullBase: pullBase, - benchmarkName: benchmarkName, - worker: worker, + repoId, + pullNumber, + pullBase, + benchmarkName, + worker, + dateRange, })->AppRouter.go - | (Some(repoId), _, _) => AppRouter.Repo({repoId, benchmarkName, worker})->AppRouter.go + | (Some(repoId), _, _) => + AppRouter.Repo({repoId, benchmarkName, worker, dateRange})->AppRouter.go | _ => () } } @@ -327,6 +371,7 @@ module RepoView = { {pullNumber->Rx.onSome(pullNumber => { let href = AppRouter.RepoPull({ - repoId: repoId, - pullNumber: pullNumber, - pullBase: pullBase, + repoId, + pullNumber, + pullBase, benchmarkName: None, - worker: worker, + worker, + dateRange, })->AppRouter.path <> - "/" - { - let href = AppRouter.RepoBranch({ - repoId: repoId, - branch: pullBase, - benchmarkName: None, - worker: worker, - })->AppRouter.path - - } + "/" + { + let href = AppRouter.RepoBranch({ + repoId, + branch: pullBase, + benchmarkName: None, + worker, + dateRange, + })->AppRouter.path + + } "/" @@ -385,20 +432,25 @@ module RepoView = { let href = switch pullNumber { | None => AppRouter.Repo({ - repoId: repoId, + repoId, benchmarkName: Some(benchmarkName), - worker: worker, + worker, + dateRange, }) | Some(pullNumber) => AppRouter.RepoPull({ - repoId: repoId, - pullNumber: pullNumber, - pullBase: pullBase, + repoId, + pullNumber, + pullBase, benchmarkName: Some(benchmarkName), - worker: worker, + worker, + dateRange, }) }->AppRouter.path - <> "/" + <> + "/" + + })} let githubLink = @@ -416,7 +468,9 @@ module RepoView = { {githubLink} - + }} @@ -430,12 +484,15 @@ let make = () => { switch route { | Error({reason}) => -
+
+ +
| Ok(Main) => - | Ok(Repo({repoId, benchmarkName, worker})) => - | Ok(RepoPull({repoId, pullNumber, pullBase, benchmarkName, worker})) => - - | Ok(RepoBranch({repoId, branch, benchmarkName, worker})) => - + | Ok(Repo({repoId, benchmarkName, worker, dateRange})) => + + | Ok(RepoPull({repoId, pullNumber, pullBase, benchmarkName, worker, dateRange})) => + + | Ok(RepoBranch({repoId, branch, benchmarkName, worker, dateRange})) => + } } diff --git a/frontend/src/AppRouter.res b/frontend/src/AppRouter.res index 9a51b6a8..002fc101 100644 --- a/frontend/src/AppRouter.res +++ b/frontend/src/AppRouter.res @@ -1,16 +1,24 @@ type worker = option<(string, string)> +type dateRange = option<(string, string)> type route = | Main - | Repo({repoId: string, benchmarkName: option, worker: worker}) + | Repo({repoId: string, benchmarkName: option, worker: worker, dateRange: dateRange}) | RepoPull({ repoId: string, pullNumber: int, pullBase: string, benchmarkName: option, worker: worker, + dateRange: dateRange, + }) + | RepoBranch({ + repoId: string, + branch: string, + benchmarkName: option, + worker: worker, + dateRange: dateRange, }) - | RepoBranch({repoId: string, branch: string, benchmarkName: option, worker: worker}) type error = { path: list, @@ -27,29 +35,45 @@ let parseParams = (query) => { }) } -let getWorker = (query) => { +let getWorker = query => { let params = parseParams(query) - let find = (key) => Js.Array.find((((key', _)) => key == key'), params) + let find = key => Js.Array.find(((key', _)) => key == key', params) switch (find("worker"), find("image")) { - | (Some((_, worker)), Some((_, image))) => Some((worker, image)) - | _ => None + | (Some((_, worker)), Some((_, image))) => Some((worker, image)) + | _ => None + } +} + +let getDateRange = query => { + let params = parseParams(query) + let find = key => Js.Array.find(((key', _)) => key == key', params) + switch (find("start"), find("end")) { + | (Some((_, start)), Some((_, end))) => Some((start, end)) + | _ => None } } let route = (url: RescriptReactRouter.url) => { let worker = getWorker(url.search) + let dateRange = getDateRange(url.search) switch url.path { | list{} => Ok(Main) | list{orgName, repoName} => - Ok(Repo({repoId: orgName ++ "/" ++ repoName, - benchmarkName: None, - worker})) + Ok( + Repo({ + repoId: orgName ++ "/" ++ repoName, + benchmarkName: None, + worker, + dateRange, + }), + ) | list{orgName, repoName, "benchmark", benchmarkName} => Ok( Repo({ repoId: orgName ++ "/" ++ repoName, benchmarkName: Some(benchmarkName), worker, + dateRange, }), ) | list{orgName, repoName, "branch", branchName} => @@ -59,6 +83,7 @@ let route = (url: RescriptReactRouter.url) => { branch: branchName, benchmarkName: None, worker, + dateRange, }), ) | list{orgName, repoName, "branch", branchName, "benchmark", benchmarkName} => @@ -68,6 +93,7 @@ let route = (url: RescriptReactRouter.url) => { branch: branchName, benchmarkName: Some(benchmarkName), worker, + dateRange, }), ) | list{orgName, repoName, "pull", pullNumberStr, "base", pullBase} => @@ -80,6 +106,7 @@ let route = (url: RescriptReactRouter.url) => { pullBase, benchmarkName: None, worker, + dateRange, }), ) | None => Error({path: url.path, reason: "Invalid pull number: " ++ pullNumberStr}) @@ -94,6 +121,7 @@ let route = (url: RescriptReactRouter.url) => { pullBase, benchmarkName: Some(benchmarkName), worker, + dateRange, }), ) | None => Error({path: url.path, reason: "Invalid pull number: " ++ pullNumberStr}) @@ -102,28 +130,51 @@ let route = (url: RescriptReactRouter.url) => { } } -let workerParams = (worker) => - switch worker { - | None => "" - | Some((worker, dockerImage)) => - "?worker=" ++ Js.Global.encodeURIComponent(worker) ++ "&image=" ++ Js.Global.encodeURIComponent(dockerImage) +let makeQueryParams = (worker, dateRange) => { + switch (worker, dateRange) { + | (Some((worker, dockerImage)), Some((start, end))) => + "?worker=" ++ + Js.Global.encodeURIComponent(worker) ++ + "&image=" ++ + Js.Global.encodeURIComponent(dockerImage) ++ + "&start=" ++ + Js.Global.encodeURIComponent(start) ++ + "&end=" ++ + Js.Global.encodeURIComponent(end) + | (Some((worker, dockerImage)), None) => + "?worker=" ++ + Js.Global.encodeURIComponent(worker) ++ + "&image=" ++ + Js.Global.encodeURIComponent(dockerImage) + | (None, Some((start, end))) => + "?start=" ++ Js.Global.encodeURIComponent(start) ++ "&end=" ++ Js.Global.encodeURIComponent(end) + | (None, None) => "" } +} -let path = route => +let path = route => { switch route { | Main => "/" - | Repo({repoId, benchmarkName: None, worker}) => "/" ++ repoId ++ workerParams(worker) - | Repo({repoId, benchmarkName: Some(benchmarkName), worker}) => - "/" ++ repoId ++ "/benchmark/" ++ benchmarkName ++ workerParams(worker) - | RepoPull({repoId, pullNumber, pullBase, benchmarkName: None, worker}) => + | Repo({repoId, benchmarkName: None, worker, dateRange}) => + "/" ++ repoId ++ makeQueryParams(worker, dateRange) + | Repo({repoId, benchmarkName: Some(benchmarkName), worker, dateRange}) => + "/" ++ repoId ++ "/benchmark/" ++ benchmarkName ++ makeQueryParams(worker, dateRange) + | RepoPull({repoId, pullNumber, pullBase, benchmarkName: None, worker, dateRange}) => "/" ++ repoId ++ "/pull/" ++ Belt.Int.toString(pullNumber) ++ "/base/" ++ pullBase ++ - workerParams(worker) - | RepoPull({repoId, pullNumber, pullBase, benchmarkName: Some(benchmarkName), worker}) => + makeQueryParams(worker, dateRange) + | RepoPull({ + repoId, + pullNumber, + pullBase, + benchmarkName: Some(benchmarkName), + worker, + dateRange, + }) => "/" ++ repoId ++ "/pull/" ++ @@ -132,12 +183,19 @@ let path = route => pullBase ++ "/benchmark/" ++ benchmarkName ++ - workerParams(worker) - | RepoBranch({repoId, branch, benchmarkName: None, worker}) => - "/" ++ repoId ++ "/branch/" ++ branch ++ workerParams(worker) - | RepoBranch({repoId, branch, benchmarkName: Some(benchmarkName), worker}) => - "/" ++ repoId ++ "/branch/" ++ branch ++ "/benchmark/" ++ benchmarkName ++ workerParams(worker) + makeQueryParams(worker, dateRange) + | RepoBranch({repoId, branch, benchmarkName: None, worker, dateRange}) => + "/" ++ repoId ++ "/branch/" ++ branch ++ makeQueryParams(worker, dateRange) + | RepoBranch({repoId, branch, benchmarkName: Some(benchmarkName), worker, dateRange}) => + "/" ++ + repoId ++ + "/branch/" ++ + branch ++ + "/benchmark/" ++ + benchmarkName ++ + makeQueryParams(worker, dateRange) } +} let useRoute = () => RescriptReactRouter.useUrl()->route diff --git a/frontend/src/Sidebar.res b/frontend/src/Sidebar.res index ec29d158..38600e3d 100644 --- a/frontend/src/Sidebar.res +++ b/frontend/src/Sidebar.res @@ -55,6 +55,7 @@ module PullsList = { pullBase: pullBase, benchmarkName: selectedBenchmarkName, worker: worker, + dateRange: None, })->AppRouter.path} text={pullToString((pullNumber, prTitle, None))} /> @@ -134,12 +135,14 @@ module BenchmarksMenu = { pullBase: pullBase, benchmarkName: Some(benchmarkName), worker: worker, + dateRange: None, }) | _ => AppRouter.Repo({ repoId: repoId, benchmarkName: Some(benchmarkName), worker: worker, + dateRange: None, }) } @@ -167,6 +170,7 @@ module BranchesMenu = { ~selectedBenchmarkName=?, ~selectedPull=?, ~worker, + ~dateRange, ) => { let branchNames = branchesMenuData->Belt.Array.keepMap(obj => obj.branch) @@ -182,6 +186,7 @@ module BranchesMenu = { branch, benchmarkName: selectedBenchmarkName, worker, + dateRange, })->AppRouter.go | _ => () } @@ -198,6 +203,7 @@ module BranchesMenu = { repoId, benchmarkName: selectedBenchmarkName, worker, + dateRange: None, }) | Some(branch) => AppRouter.RepoBranch({ @@ -205,6 +211,7 @@ module BranchesMenu = { branch, benchmarkName: selectedBenchmarkName, worker, + dateRange: None, }) } { + let make = (~repoId, ~selectedBranch=?, ~selectedPull=?, ~selectedBenchmarkName=?, ~worker, ~dateRange) => { let ({ReScriptUrql.Hooks.response: response}, _) = { ReScriptUrql.Hooks.useQuery( ~query=module(SidebarMenuData), @@ -258,7 +265,7 @@ module SidebarMenu = { | false => Rx.null }} @@ -347,6 +354,7 @@ module Workers = { let make = ( ~repoIds, ~worker, + ~dateRange, ~setWorker, ~selectedBranch=?, ~selectedRepoId=?, @@ -359,7 +367,7 @@ let make = ( | Some(repoId) => <> - + }