Skip to content

Commit

Permalink
Warn the user if they forgot to set install/abandon date (#806)
Browse files Browse the repository at this point in the history
* Warn the user if they forgot to set install/abandon date

* Move DOM element construction into HTML template

* Add node support
  • Loading branch information
Andrew-Dickinson authored Jan 12, 2025
1 parent 8feaa16 commit b9367ae
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 3 deletions.
8 changes: 7 additions & 1 deletion src/meshapi/admin/models/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from simple_history.admin import SimpleHistoryAdmin

from meshapi.models import Install
from meshapi.widgets import ExternalHyperlinkWidget
from meshapi.widgets import ExternalHyperlinkWidget, WarnAboutDatesWidget

from ..ranked_search import RankedSearchMixin

Expand All @@ -31,6 +31,11 @@ class Meta:


class InstallAdminForm(forms.ModelForm):
validate_install_abandon_date_set_widget = forms.Field(
required=False,
widget=WarnAboutDatesWidget(),
)

class Meta:
model = Install
fields = "__all__"
Expand Down Expand Up @@ -139,6 +144,7 @@ class InstallAdmin(RankedSearchMixin, ImportExportMixin, ExportActionMixin, Simp
"diy",
"referral",
"notes",
"validate_install_abandon_date_set_widget", # Hidden by widget CSS
]
},
),
Expand Down
8 changes: 7 additions & 1 deletion src/meshapi/admin/models/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from simple_history.admin import SimpleHistoryAdmin

from meshapi.models import Building, Node
from meshapi.widgets import AutoPopulateLocationWidget
from meshapi.widgets import AutoPopulateLocationWidget, WarnAboutDatesWidget

from ..inlines import (
AccessPointInline,
Expand All @@ -39,6 +39,11 @@ class Meta:


class NodeAdminForm(forms.ModelForm):
validate_install_abandon_date_set_widget = forms.Field(
required=False,
widget=WarnAboutDatesWidget(),
)

auto_populate_location_field = forms.Field(
required=False,
widget=AutoPopulateLocationWidget("Building"),
Expand Down Expand Up @@ -104,6 +109,7 @@ class NodeAdmin(RankedSearchMixin, ExportActionMixin, ImportExportModelAdmin, Si
{
"fields": [
"notes",
"validate_install_abandon_date_set_widget",
]
},
),
Expand Down
3 changes: 3 additions & 0 deletions src/meshapi/static/widgets/warn_about_date.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.field-validate_install_abandon_date_set_widget {
display: none;
}
98 changes: 98 additions & 0 deletions src/meshapi/static/widgets/warn_about_date.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
$(document).ready(function($) {
const getCurrentISODate = () => {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed
const date = String(now.getDate()).padStart(2, '0');
return `${year}-${month}-${date}`;
};

function submitAdminForm(saveAction) {
const adminForm = document.querySelector('#content-main form');

// Create a hidden input to simulate the button action
const hiddenInput = document.createElement('input');
hiddenInput.type = 'hidden';
hiddenInput.name = saveAction;
hiddenInput.value = '1';
adminForm.appendChild(hiddenInput);
adminForm.submit();

return true;
}

const saveButtons = $('.submit-row input[value*="Save"]');


function hideWarning(){
$('#dateMissingWarning').remove();
saveButtons.each((i, button) => {
$(button).removeClass("disabled-button");
})
}

function showWarning(dateField, statusField, saveAction, dateType){
const errorNotice = $("#dateMissingWarningTemplate").clone();
errorNotice.prop("id", "dateMissingWarning");

errorNotice.find("#saveCurrentDateButton").on("click", () => {
dateField.val(getCurrentISODate())
submitAdminForm(saveAction);
return false;
});

errorNotice.find("#saveNoDateButton").on("click", () => {
submitAdminForm(saveAction);
return false;
});

errorNotice.find("#statusText").text(statusField.val());
errorNotice.find("#dateTypeText").text(dateType);

saveButtons.each((i, button) => {
$(button).addClass("disabled-button");
})

errorNotice.insertBefore($('.submit-row').first())
}

$('#id_install_date').on("input", (e) => {
hideWarning();
});

$('#id_abandon_date').on("input", (e) => {
hideWarning();
});

$('#id_status').on("change", (e) => {
hideWarning();
});

saveButtons.on('click', (e) => {
const status = $('#id_status').val();
const installDate = $('#id_install_date').val();
const abandonDate = $('#id_abandon_date').val();

$('.datetimeshortcuts a').on("click", (e) => {
hideWarning();
});

if (status === "Active") {
if (!installDate) {
hideWarning();
showWarning($("#id_install_date"), $('#id_status'), e.target.name, "Install")

return false;
}
} else if (["Closed", "Inactive"].indexOf(status) !== -1){
if (installDate && !abandonDate) {
hideWarning();
showWarning($("#id_abandon_date"), $('#id_status'), e.target.name, "Abandon")

return false;
}
}

return true;
})
});
11 changes: 11 additions & 0 deletions src/meshapi/templates/widgets/warn_about_date.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div id="dateMissingWarningTemplate" class="warning-box">
<p>
<b>Warning</b>: Status set to <span id="statusText"></span> without setting <span id="dateTypeText"></span> Date
</p>
<a id="saveCurrentDateButton" class="button" href="#" style="padding: 10px 15px; display: inline-block; text-decoration: none;">
Use Today's Date
</a>
<a id="saveNoDateButton" class="button" href="#" style="padding: 10px 15px; display: inline-block; margin-left: 10px; text-decoration: none;">
Continue Without Setting Date
</a>
</div>
10 changes: 10 additions & 0 deletions src/meshapi/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,13 @@ def get_context(self, name: str, value: str, attrs: Optional[dict] = None) -> di
context["auto_populate_source"] = self.source
context["auto_populate_url"] = self.source
return context


class WarnAboutDatesWidget(forms.Widget):
template_name = "widgets/warn_about_date.html"

class Media:
css = {
"all": ("widgets/warn_about_date.css",),
}
js = ["widgets/warn_about_date.js"]
8 changes: 7 additions & 1 deletion src/meshweb/static/admin/admin_ext.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
color: black;
}

.disabled-button {
background-color: #afafaf !important;
opacity: 20%;
cursor: unset !important;
}

@media screen and (max-width: 600px) {
.warning-box {
display: none;
Expand Down Expand Up @@ -187,4 +193,4 @@ fieldset h2 {

.hidden {
display: none;
}
}

0 comments on commit b9367ae

Please sign in to comment.