Skip to content

Commit 48103df

Browse files
Front/wf date filtering (#305)
## πŸ“ Description renderedtext/project-tasks#2405 renderedtext/project-tasks#2402 ## βœ… Checklist - [ ] I have tested this change - [ ] This change requires documentation update
1 parent faf0227 commit 48103df

File tree

8 files changed

+238
-18
lines changed

8 files changed

+238
-18
lines changed

β€Žfront/assets/js/people/spinner.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
export default function toggleSpinner() {
22
const spinner = document.querySelector(".spinner")
3+
4+
if (!spinner) {
5+
return
6+
}
7+
38
if(spinner.style.display == "none"){
49
spinner.style.display = "block"
510
}else{

β€Žfront/assets/js/workflow_list.js

Lines changed: 98 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,117 @@
1-
import $ from "jquery";
2-
31
import { TokenPagination } from "./pollman_list/token_pagination"
42
import { PollmanList } from "./pollman_list/list"
3+
import debounce from "./debounce"
54

65
export var WorkflowList = {
6+
initiated: false,
7+
pagination: null,
8+
pollmanList: null,
9+
container: null,
10+
queryParams: ['page_token', 'direction', 'date_from', 'date_to', 'author'],
11+
712
init: function() {
813
if(this.initiated === true) { return; }
914

1015
this.initiated = true
11-
1216
this.pagination = new TokenPagination("#workflow-lists")
13-
1417
let pollmanList = new PollmanList;
1518

1619
let updatePollman = function(container, params) {
17-
pollmanList.updateOptionsAndFetch(container, params);
18-
1920
const currentUrl = new URL(window.location.href);
20-
currentUrl.searchParams.set('page_token', params.page_token);
21-
currentUrl.searchParams.set('direction', params.direction);
21+
const mergedParams = {};
22+
23+
WorkflowList.queryParams.forEach(queryParam => {
24+
const currentValue = currentUrl.searchParams.get(queryParam);
25+
if (currentValue) {
26+
mergedParams[queryParam] = currentValue;
27+
}
28+
});
29+
30+
Object.keys(params).forEach(key => {
31+
mergedParams[key] = params[key];
32+
});
33+
34+
pollmanList.updateOptionsAndFetch(container, mergedParams);
35+
36+
WorkflowList.queryParams.forEach(queryParam => {
37+
const paramValue = mergedParams[queryParam];
38+
if (paramValue && paramValue !== '') {
39+
currentUrl.searchParams.set(queryParam, paramValue);
40+
} else {
41+
currentUrl.searchParams.delete(queryParam);
42+
}
43+
});
44+
2245
window.history.pushState({}, '', currentUrl.toString());
2346
}
2447

2548
this.pagination.onUpdate(updatePollman);
49+
this.initFilterButtons(updatePollman);
50+
this.initializeDateFilterValues();
51+
},
52+
53+
initFilterButtons: function(updatePollman) {
54+
const dateFromInput = document.getElementById('date_from');
55+
const dateToInput = document.getElementById('date_to');
56+
const authorInput = document.getElementById('author');
57+
58+
59+
const applyFilters = () => {
60+
const dateFrom = dateFromInput?.value;
61+
const dateTo = dateToInput?.value;
62+
const author = authorInput?.value;
63+
64+
// Validate date range
65+
if (dateFrom && dateTo) {
66+
const fromDate = new Date(dateFrom);
67+
const toDate = new Date(dateTo);
68+
69+
if (fromDate > toDate) {
70+
alert('Start date must be before end date');
71+
return;
72+
}
73+
}
74+
75+
let params = {'page_token': '', 'direction': ''};
76+
params.date_from = dateFrom;
77+
params.date_to = dateTo;
78+
params.author = author;
79+
80+
const container = document.querySelector('.pollman-container');
81+
updatePollman(container, params);
82+
};
83+
84+
if (authorInput) {
85+
authorInput.addEventListener('input', debounce(applyFilters, 300, false));
86+
}
87+
if (dateFromInput) {
88+
dateFromInput.addEventListener('change', applyFilters);
89+
}
90+
if (dateToInput) {
91+
dateToInput.addEventListener('change', applyFilters);
92+
}
93+
},
94+
95+
initializeDateFilterValues: function() {
96+
const urlParams = new URLSearchParams(window.location.search);
97+
const dateFrom = urlParams.get('date_from');
98+
const dateTo = urlParams.get('date_to');
99+
const author = urlParams.get('author');
100+
101+
const dateFromInput = document.getElementById('date_from');
102+
const dateToInput = document.getElementById('date_to');
103+
const authorInput = document.getElementById('author');
104+
105+
if (dateFrom && dateFromInput) {
106+
dateFromInput.value = dateFrom;
107+
}
108+
109+
if (dateTo && dateToInput) {
110+
dateToInput.value = dateTo;
111+
}
112+
113+
if (author && authorInput) {
114+
authorInput.value = author;
115+
}
26116
}
27117
}

β€Žfront/lib/front/branch_page/model.ex

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ defmodule Front.BranchPage.Model do
3535
field(:organization_id, String.t())
3636
field(:page_token, String.t())
3737
field(:direction, String.t())
38+
field(:date_from, String.t())
39+
field(:date_to, String.t())
40+
field(:author, String.t())
3841
end
3942
end
4043

@@ -134,24 +137,87 @@ defmodule Front.BranchPage.Model do
134137
end
135138

136139
defp list_workflows(params) do
137-
{wfs, next_page_token, previous_page_token} =
140+
api_params =
138141
[
139142
page_size: 10,
140143
page_token: params.page_token,
141144
project_id: params.project_id,
142145
branch_name: params.branch_name,
143146
direction: map_workflow_direction(params.direction)
144147
]
148+
|> inject_date_filter_param(params.date_from, :date_from)
149+
|> inject_date_filter_param(params.date_to, :date_to)
150+
|> inject_requesters_param(params.author, params.organization_id, params.project_id)
151+
152+
{wfs, next_page_token, previous_page_token} =
153+
api_params
145154
|> Models.Workflow.list_keyset()
146155

147156
workflows = Front.Decorators.Workflow.decorate_many(wfs)
148157

149158
{workflows, next_page_token, previous_page_token}
150159
end
151160

161+
defp inject_requesters_param(api_params, author, _, _) when author in [nil, ""], do: api_params
162+
163+
defp inject_requesters_param(api_params, author, org_id, project_id) do
164+
case Front.RBAC.Members.list_project_members(org_id, project_id, username: author) do
165+
{:ok, {members, _total_pages}} ->
166+
case members |> Enum.map(& &1.id) do
167+
[] -> api_params
168+
user_ids -> Keyword.put(api_params, :requester_ids, user_ids)
169+
end
170+
171+
_ ->
172+
api_params
173+
end
174+
end
175+
176+
defp inject_date_filter_param(api_params, date, _) when date in [nil, ""], do: api_params
177+
178+
defp inject_date_filter_param(api_params, date, :date_from),
179+
do: Keyword.put(api_params, :created_after, timestamp(:beginning, date))
180+
181+
defp inject_date_filter_param(api_params, date, :date_to),
182+
do: Keyword.put(api_params, :created_before, timestamp(:end, date))
183+
184+
defp timestamp(_, timestamp) when timestamp in [nil, ""], do: nil
185+
186+
@date_format "{YYYY}-{0M}-{0D}"
187+
defp timestamp(direction, date) do
188+
rounding_func =
189+
case direction do
190+
:beginning -> &Timex.beginning_of_day/1
191+
:end -> &Timex.end_of_day/1
192+
_ -> nil
193+
end
194+
195+
case Timex.parse(date, @date_format) do
196+
{:ok, datetime} ->
197+
datetime |> Timex.to_datetime() |> rounding_func.() |> to_google_timestamp()
198+
199+
{:error, reason} ->
200+
Logger.error("Error parsing date: #{inspect(reason)}")
201+
nil
202+
end
203+
end
204+
205+
defp to_google_timestamp(date) do
206+
case Timex.to_unix(date) do
207+
{:error, _} -> nil
208+
s -> Google.Protobuf.Timestamp.new(seconds: s)
209+
end
210+
end
211+
152212
defp map_workflow_direction("next"), do: Direction.value(:NEXT)
153213
defp map_workflow_direction("previous"), do: Direction.value(:PREVIOUS)
154214
defp map_workflow_direction(_), do: map_workflow_direction("next")
155215

156-
defp first_page?(params), do: params.page_token == ""
216+
defp first_page?(params) do
217+
filter_fields = [:page_token, :date_from, :date_to, :author]
218+
219+
Enum.all?(filter_fields, fn field ->
220+
is_nil(Map.get(params, field)) || Map.get(params, field) == ""
221+
end)
222+
end
157223
end

β€Žfront/lib/front/models/user.ex

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,28 @@ defmodule Front.Models.User do
327327
end)
328328
end
329329

330+
def search_users(query, limit \\ 20) do
331+
Watchman.benchmark("search_users.duration", fn ->
332+
request =
333+
InternalApi.User.SearchUsersRequest.new(
334+
query: query,
335+
limit: limit
336+
)
337+
338+
{:ok, channel} = channel()
339+
340+
case InternalApi.User.UserService.Stub.search_users(channel, request) do
341+
{:ok, response} ->
342+
users = Enum.map(response.users, fn user -> construct(user) end)
343+
{:ok, users}
344+
345+
{:error, error} ->
346+
Logger.error("[User Model] Error while searching users: #{inspect(error)}")
347+
{:error, error}
348+
end
349+
end)
350+
end
351+
330352
defp refresh_repository_provider(user_id, provider) do
331353
Watchman.benchmark("refresh_repository_provider.duration", fn ->
332354
alias InternalApi.User.UserService.Stub

β€Žfront/lib/front_web/controllers/branch_controller.ex

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ defmodule FrontWeb.BranchController do
3939
org_id = conn.assigns.organization_id
4040
page_token = params["page_token"] || ""
4141
direction = params["direction"] || ""
42+
date_from = params["date_from"] || ""
43+
date_to = params["date_to"] || ""
44+
author = params["author"] || ""
4245

4346
branch = conn.assigns.branch
4447
project = conn.assigns.project
@@ -50,7 +53,10 @@ defmodule FrontWeb.BranchController do
5053
project_id: project.id,
5154
organization_id: org_id,
5255
page_token: page_token,
53-
direction: direction
56+
direction: direction,
57+
date_from: date_from,
58+
date_to: date_to,
59+
author: author
5460
)
5561

5662
{:ok, model, source} = params |> BranchPage.Model.get()
@@ -60,7 +66,10 @@ defmodule FrontWeb.BranchController do
6066
href: "/branches/#{branch.id}/workflows",
6167
params: [
6268
page_token: page_token,
63-
direction: direction
69+
direction: direction,
70+
date_from: date_from,
71+
date_to: date_to,
72+
author: author
6473
]
6574
}
6675

@@ -89,6 +98,9 @@ defmodule FrontWeb.BranchController do
8998
def workflows(conn, params) do
9099
page_token = params["page_token"] || ""
91100
direction = params["direction"] || ""
101+
date_from = params["date_from"] || ""
102+
date_to = params["date_to"] || ""
103+
author = params["author"] || ""
92104

93105
branch = conn.assigns.branch
94106
project = conn.assigns.project
@@ -100,7 +112,10 @@ defmodule FrontWeb.BranchController do
100112
project_id: project.id,
101113
organization_id: conn.assigns.organization_id,
102114
page_token: page_token,
103-
direction: direction
115+
direction: direction,
116+
date_from: date_from,
117+
date_to: date_to,
118+
author: author
104119
)
105120

106121
{:ok, model, source} = params |> BranchPage.Model.get()
@@ -110,7 +125,10 @@ defmodule FrontWeb.BranchController do
110125
href: "/branches/#{branch.id}/workflows",
111126
params: [
112127
page_token: page_token,
113-
direction: direction
128+
direction: direction,
129+
date_from: date_from,
130+
date_to: date_to,
131+
author: author
114132
]
115133
}
116134

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div class="flex-m items-center">
2+
<%# <input id="author" name="author" type="text" placeholder="User" class="form-control mb3 mb0-m mr3 w5"> %>
3+
4+
<div class="flex items-center mr2">
5+
<span class="f6 gray mr1">From</span>
6+
<input id="date_from" name="date_from" type="date" class="form-control mb3 mb0-m w4">
7+
</div>
8+
<div class="flex items-center">
9+
<span class="f6 gray mr1">To</span>
10+
<input id="date_to" name="date_to" type="date" class="form-control mb3 mb0-m w4">
11+
</div>
12+
</div>

β€Žfront/lib/front_web/templates/branch/guest.html.eex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
</div>
2525

2626
<div class="bg-washed-gray pa3 br3 ba b--black-075">
27-
<div class="f5 mb2">
28-
Most recent activity on this <%= branch_type_name(@branch.type) |> String.downcase() %>
27+
<div class="flex-m items-center justify-between mb3">
28+
<div class="f5 gray mr3 mb3 mb0-m">
29+
Most recent activity on this <%= branch_type_name(@branch.type) |> String.downcase() %>
30+
</div>
2931
</div>
3032
<div id="workflow-lists">
3133
<%= render FrontWeb.BranchView, "_workflows.html", project: @project, workflows: @workflows, branch: @branch, conn: @conn, page: :branch, pagination: @pagination, pollman: @pollman, conflict_info: @conflict_info %>

β€Žfront/lib/front_web/templates/branch/member.html.eex

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,13 @@
3030
</div>
3131

3232
<div class="bg-washed-gray pa3 br3 ba b--black-075">
33-
<div class="f5 mb2">
34-
Most recent activity on this <%= branch_type_name(@branch.type) |> String.downcase() %>
33+
<div class="flex-m items-center justify-between mb3">
34+
<div class="f5 gray mr3 mb3 mb0-m">
35+
Most recent activity on this <%= branch_type_name(@branch.type) |> String.downcase() %>
36+
</div>
37+
<%= if FeatureProvider.feature_enabled?(:workflow_filtering, param: @organization.id) do %>
38+
<%= render FrontWeb.BranchView, "_filters.html" %>
39+
<% end %>
3540
</div>
3641
<div id="workflow-lists">
3742
<%= render FrontWeb.BranchView, "_workflows.html", project: @project, workflows: @workflows, branch: @branch, conn: @conn, page: :branch, pagination: @pagination, pollman: @pollman, conflict_info: @conflict_info %>

0 commit comments

Comments
Β (0)