Skip to content

Commit 95e3fca

Browse files
committed
2 parents 6b7cba1 + 64f8507 commit 95e3fca

File tree

3 files changed

+106
-4
lines changed

3 files changed

+106
-4
lines changed

app/javascript/packs/application.js

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,30 @@ document.addEventListener("turbolinks:load", () => {
1717
/*****************************************
1818
********* submit_forecasts start ********
1919
*****************************************/
20+
const checkStorageForForecast = () => {
21+
let member = document.querySelector("#forecast-form #member-emails")
22+
let forecastForm = document.getElementById("forecast-form")
23+
if (forecastForm && member) {
24+
let inputs = forecastForm.elements
25+
let storedValues = JSON.parse(localStorage.getItem(`${member.value};${forecastForm.dataset.date}`))
26+
if (storedValues) {
27+
for (let i = 0; i < inputs.length; i++) {
28+
if (inputs[i].name &&
29+
inputs[i].name.toLowerCase() != "authenticity_token" &&
30+
inputs[i].name.toLowerCase() != "member_forecast[team_monthly_forecast_id]" &&
31+
inputs[i].name.toLowerCase() != "member_forecast[member_id]") {
32+
if (storedValues[inputs[i].name]) {
33+
inputs[i].value = storedValues[inputs[i].name]
34+
}
35+
}
36+
}
37+
return true
38+
} else {
39+
return false
40+
}
41+
}
42+
}
43+
2044
// Handle changing form content based on selected team
2145
const userDetailsForm = document.getElementById("forecast-user-details-form")
2246
const userDetailsFormTeamField = document.querySelector("#forecast-user-details-form #user-details-team-id")
@@ -32,8 +56,8 @@ document.addEventListener("turbolinks:load", () => {
3256
if (userDetailsForm) {
3357
userDetailsForm.addEventListener("ajax:success", () => {
3458
bindMemberChangeHandler()
59+
checkStorageForForecast()
3560
countHours()
36-
3761
})
3862
userDetailsForm.addEventListener("ajax:error", () => {
3963
location.reload()
@@ -59,6 +83,24 @@ document.addEventListener("turbolinks:load", () => {
5983
if (formButton) {
6084
formButton.disabled = false
6185
}
86+
// if false, clear inputs because member changed
87+
if (!checkStorageForForecast()) {
88+
let forecastForm = document.getElementById("forecast-form")
89+
let inputs = forecastForm.elements
90+
for (let i = 0; i < inputs.length; i++) {
91+
if (inputs[i].name &&
92+
inputs[i].name.toLowerCase() != "authenticity_token" &&
93+
inputs[i].name.toLowerCase() != "member_forecast[team_monthly_forecast_id]" &&
94+
inputs[i].name.toLowerCase() != "member_forecast[member_id]") {
95+
// don't clear holiday
96+
if (inputs[i].dataset.holiday) {
97+
inputs[i].value = inputs[i].dataset.holiday
98+
} else if (inputs[i].name) {
99+
inputs[i].value = ""
100+
}
101+
}
102+
}
103+
}
62104
})
63105
}
64106
}
@@ -94,8 +136,62 @@ document.addEventListener("turbolinks:load", () => {
94136
currentHours.classList.remove("text-green-600", "font-bold")
95137
}
96138
}
139+
const submitForecastButton = document.querySelector("#forecast-form #forecast-submit")
140+
141+
// Store the submission locally
142+
if (submitForecastButton) {
143+
submitForecastButton.addEventListener('click', (e) => {
144+
let forecastForm = document.getElementById("forecast-form")
145+
if (forecastForm) {
146+
let inputs = forecastForm.elements
147+
let memberId = document.querySelector("#forecast-form #member-emails").value
148+
let submission = {}
149+
for (let i = 0; i < inputs.length; i++) {
150+
if (inputs[i].name &&
151+
inputs[i].name.toLowerCase() != "authenticity_token" &&
152+
inputs[i].name.toLowerCase() != "member_forecast[team_monthly_forecast_id]" &&
153+
inputs[i].name.toLowerCase() != "member_forecast[member_id]") {
154+
submission[inputs[i].name] = inputs[i].value
155+
}
156+
}
157+
try {
158+
localStorage.setItem(`${memberId};${forecastForm.dataset.date}`, JSON.stringify(submission));
159+
} catch (e) {
160+
if ((
161+
// everything except Firefox
162+
e.code === 22 ||
163+
// Firefox
164+
e.code === 1014 ||
165+
// test name field too, because code might not be present
166+
// everything except Firefox
167+
e.name === 'QuotaExceededError' ||
168+
// Firefox
169+
e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
170+
// acknowledge QuotaExceededError only if there's something already stored
171+
(storage && storage.length !== 0)) {
172+
let keys = []
173+
for ( let i = 0; i < localStorage.length; ++i ) {
174+
keys.append(localStorage.key(i));
175+
}
176+
// remove last 4 submissions and store again
177+
let sorted = keys.sort()
178+
for (let i = 0; sorted[i] && i < 4; i++) {
179+
localStorage.removeItem(sorted[i])
180+
}
181+
localStorage.setItem(`${memberId};${forecastForm.dataset.date}`, JSON.stringify(submission));
182+
}
183+
}
184+
}
185+
})
186+
}
187+
188+
// Whenver form present and page reloads, check storage
189+
let forecastForm = document.getElementById("forecast-form")
190+
if (forecastForm) {
191+
checkStorageForForecast()
192+
countHours()
193+
}
97194

98-
countHours()
99195
/***************************************
100196
********* submit_forecasts end ********
101197
***************************************/

app/views/submit_forecasts/_form.html.erb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div id="member-email" class="text-gray-500 mb-2"><%= @member&.email%></div>
22
<div>There are <span class="expected-hours"><b><%= @team_monthly_forecast&.monthly_forecast&.total_hours %></b></span> hours this month.</div>
3-
<%= form_with model: member_forecast, url: create_forecast_path, method: :post, id: "forecast-form" do |form| %>
3+
<%= form_with model: member_forecast, url: create_forecast_path, method: :post, id: "forecast-form", data: { date: @team_monthly_forecast&.date&.strftime("%Y-%m")} do |form| %>
44
<% if team_monthly_forecast.present? %>
55
<%= hidden_field_tag :team_monthly_forecast_id, team_monthly_forecast.id, id: "team-monthly-forecast-id", name: "member_forecast[team_monthly_forecast_id]", required: true %>
66
<% else %>
@@ -39,7 +39,11 @@
3939
<%= form.label team_field.field.name, team_field.field.name, class: "text-gray-700 whitespace-nowrap" %>
4040
</td>
4141
<td class="align-middle">
42-
<%= form.number_field :hours, step: 1, min: 0, name: "member_forecast[hours[#{team_field.field.id}]]", value: @member_forecast&.hours&.fetch(team_field.field.id.to_s, nil), class: "hour-input block w-full rounded-md border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50", value: @team_monthly_forecast.monthly_forecast.holiday_hours, required: true %>
42+
<%= form.number_field :hours, step: 1, min: 0, name: "member_forecast[hours[#{team_field.field.id}]]",
43+
value: @member_forecast&.hours&.fetch(team_field.field.id.to_s, nil) || @team_monthly_forecast.monthly_forecast.holiday_hours,
44+
class: "hour-input block w-full rounded-md border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50",
45+
data: { holiday: @team_monthly_forecast.monthly_forecast.holiday_hours },
46+
required: true %>
4347
</td>
4448
</tr>
4549
<tr>

app/views/submit_forecasts/form_ajax.js.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ document.getElementById("forecast-form-container").innerHTML = "<%= j render "fo
66
document.querySelector("#forecast-form-container #member-emails").innerHTML = "<%= j select_tag "member-id", options_from_collection_for_select(@members&.sort_by { |member| member&.email&.downcase } || [], :id, :email, @member&.id), { prompt: "select email", id: "member-emails", required: true } %>"
77
<%# Clear email under header %>
88
document.querySelector("#member-email").innerText = null
9+
<%# Add date %>
10+
document.querySelector("#forecast-form-container #forecast-form").dataset.date = "<%= team_monthly_forecast&.date&.strftime("%Y-%m") %>"
911

1012
history.pushState(
1113
{ 'team': '<%= team&.slug %>' },

0 commit comments

Comments
 (0)