Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
rachidatecs committed Feb 23, 2024
2 parents 07401d9 + 2817a3e commit 735f433
Show file tree
Hide file tree
Showing 9 changed files with 736 additions and 124 deletions.
297 changes: 237 additions & 60 deletions src/registrar/admin.py

Large diffs are not rendered by default.

31 changes: 29 additions & 2 deletions src/registrar/assets/js/get-gov-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,33 @@ function openInNewTab(el, removeAttribute = false){
// <<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
// Initialization code.

/** An IIFE for pages in DjangoAdmin that use modals.
* Dja strips out form elements, and modals generate their content outside
* of the current form scope, so we need to "inject" these inputs.
*/
(function (){
function createPhantomModalFormButtons(){
let submitButtons = document.querySelectorAll('.usa-modal button[type="submit"]');
form = document.querySelector("form")
submitButtons.forEach((button) => {

let input = document.createElement("input");
input.type = "submit";
input.name = button.name;
input.value = button.value;
input.style.display = "none"

// Add the hidden input to the form
form.appendChild(input);
button.addEventListener("click", () => {
console.log("clicking")
input.click();
})
})
}

createPhantomModalFormButtons();
})();
/** An IIFE for pages in DjangoAdmin which may need custom JS implementation.
* Currently only appends target="_blank" to the domain_form object,
* but this can be expanded.
Expand All @@ -41,8 +68,8 @@ function openInNewTab(el, removeAttribute = false){
let domainFormElement = document.getElementById("domain_form");
let domainSubmitButton = document.getElementById("manageDomainSubmitButton");
if(domainSubmitButton && domainFormElement){
domainSubmitButton.addEventListener("mouseover", () => openInNewTab(domainFormElement, true));
domainSubmitButton.addEventListener("mouseout", () => openInNewTab(domainFormElement, false));
domainSubmitButton.addEventListener("mouseover", () => openInNewTab(domainFormElement, true));
domainSubmitButton.addEventListener("mouseout", () => openInNewTab(domainFormElement, false));
}
}

Expand Down
32 changes: 32 additions & 0 deletions src/registrar/assets/sass/_theme/_admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ h1, h2, h3,
.submit-row div.spacer {
flex-grow: 1;
}
.submit-row .mini-spacer{
margin-left: 2px;
margin-right: 2px;
}
.submit-row span {
margin-top: units(1);
}
Expand Down Expand Up @@ -270,3 +274,31 @@ h1, h2, h3,
margin: 0!important;
}
}

// Hides the "clear" button on autocomplete, as we already have one to use
.select2-selection__clear {
display: none;
}

// Fixes a display issue where the list was entirely white, or had too much whitespace
.select2-dropdown {
display: inline-grid !important;
}

input.admin-confirm-button {
text-transform: none;
}

// Button groups in /admin incorrectly have bullets.
// Remove that!
.usa-modal__footer .usa-button-group__item {
list-style-type: none;
}

// USWDS media checks are overzealous in this situation,
// we should manually define this behaviour.
@media (max-width: 768px) {
.button-list-mobile {
display: contents !important;
}
}
10 changes: 6 additions & 4 deletions src/registrar/models/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,15 +265,17 @@ def renew_domain(self, length: int = 1, unit: epp.Unit = epp.Unit.YEAR):
Default length and unit of time are 1 year.
"""
# if no expiration date from registry, set to today

# If no date is specified, grab the registry_expiration_date
try:
cur_exp_date = self.registry_expiration_date
exp_date = self.registry_expiration_date
except KeyError:
# if no expiration date from registry, set it to today
logger.warning("current expiration date not set; setting to today")
cur_exp_date = date.today()
exp_date = date.today()

# create RenewDomain request
request = commands.RenewDomain(name=self.name, cur_exp_date=cur_exp_date, period=epp.Period(length, unit))
request = commands.RenewDomain(name=self.name, cur_exp_date=exp_date, period=epp.Period(length, unit))

try:
# update expiration date in registry, and set the updated
Expand Down
37 changes: 37 additions & 0 deletions src/registrar/models/utility/generic_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""This file contains general purpose helpers that don't belong in any specific location"""

import time
import logging


logger = logging.getLogger(__name__)


class Timer:
"""
This class is used to measure execution time for performance profiling.
__enter__ and __exit__ is used such that you can wrap any code you want
around a with statement. After this exits, logger.info will print
the execution time in seconds.
Note that this class does not account for general randomness as more
robust libraries do, so there is some tiny amount of latency involved
in using this, but it is minimal enough that for most applications it is not
noticable.
Usage:
with Timer():
...some code
"""

def __enter__(self):
"""Starts the timer"""
self.start = time.time()
# This allows usage of the instance within the with block
return self

def __exit__(self, *args):
"""Ends the timer and logs what happened"""
self.end = time.time()
self.duration = self.end - self.start
logger.info(f"Execution time: {self.duration} seconds")
3 changes: 2 additions & 1 deletion src/registrar/templates/admin/base_site.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
<link rel="apple-touch-icon" size="180x180"
href="{% static 'img/registrar/favicons/favicon-180.png' %}"
>
<script src="{% static 'js/uswds-init.min.js' %}" defer></script>
<script src="{% static 'js/uswds.min.js' %}" defer></script>
<script type="application/javascript" src="{% static 'js/get-gov-admin.js' %}" defer></script>
{% endblock %}

{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}

{% block extrastyle %}{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static 'css/styles.css' %}" />
{% endblock %}
Expand Down
124 changes: 110 additions & 14 deletions src/registrar/templates/django/admin/domain_change_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,117 @@
{% load i18n static %}

{% block field_sets %}
<div class="submit-row">
<input id="manageDomainSubmitButton" type="submit" value="Manage domain" name="_edit_domain">
<input type="submit" value="Get registry status" name="_get_status">
<div class="spacer"></div>
{% if original.state == original.State.READY %}
<input type="submit" value="Place hold" name="_place_client_hold" class="custom-link-button">
{% elif original.state == original.State.ON_HOLD %}
<input type="submit" value="Remove hold" name="_remove_client_hold" class="custom-link-button">
{% endif %}
{% if original.state == original.State.READY or original.state == original.State.ON_HOLD %}
<span> | </span>
{% endif %}
{% if original.state != original.State.DELETED %}
<input type="submit" value="Remove from registry" name="_delete_domain" class="custom-link-button">
<div class="display-flex flex-row flex-justify submit-row">
<div class="flex-align-self-start button-list-mobile">
<input id="manageDomainSubmitButton" type="submit" value="Manage domain" name="_edit_domain">
{# Dja has margin styles defined on inputs as is. Lets work with it, rather than fight it. #}
<span class="mini-spacer"></span>
<input type="submit" value="Get registry status" name="_get_status">
</div>
<div class="desktop:flex-align-self-end">
{% if original.state != original.State.DELETED %}
<a
class="text-middle"
href="#toggle-extend-expiration-alert"
aria-controls="toggle-extend-expiration-alert"
data-open-modal
>
Extend expiration date
</a>
<span class="margin-left-05 margin-right-05 text-middle"> | </span>
{% endif %}
{% if original.state == original.State.READY %}
<input type="submit" value="Place hold" name="_place_client_hold" class="custom-link-button">
{% elif original.state == original.State.ON_HOLD %}
<input type="submit" value="Remove hold" name="_remove_client_hold" class="custom-link-button">
{% endif %}
{% if original.state == original.State.READY or original.state == original.State.ON_HOLD %}
<span class="margin-left-05 margin-right-05 text-middle"> | </span>
{% endif %}
{% if original.state != original.State.DELETED %}
<input type="submit" value="Remove from registry" name="_delete_domain" class="custom-link-button">
{% endif %}
</div>
</div>
{{ block.super }}
{% endblock %}

{% block submit_buttons_bottom %}
{% comment %}
Modals behave very weirdly in django admin.
They tend to "strip out" any injected form elements, leaving only the main form.
In addition, USWDS handles modals by first destroying the element, then repopulating it toward the end of the page.
In effect, this means that the modal is not, and cannot, be surrounded by any form element at compile time.

The current workaround for this is to use javascript to inject a hidden input, and bind submit of that
element to the click of the confirmation button within this modal.

This is controlled by the class `dja-form-placeholder` on the button.

In addition, the modal element MUST be placed low in the DOM. The script loads slower on DJA than on other portions
of the application, so this means that it will briefly "populate", causing unintended visual effects.
{% endcomment %}
<div
class="usa-modal"
id="toggle-extend-expiration-alert"
aria-labelledby="Are you sure you want to extend the expiration date?"
aria-describedby="This expiration date will be extended."
>
<div class="usa-modal__content">
<div class="usa-modal__main">
<h2 class="usa-modal__heading" id="modal-1-heading">
Are you sure you want to extend the expiration date?
</h2>
<div class="usa-prose">
<p>
This will extend the expiration date by one year.
{# Acts as a <br> #}
<div class="display-inline"></div>
This action cannot be undone.
</p>
<p>
Domain: <b>{{ original.name }}</b>
{# Acts as a <br> #}
<div class="display-inline"></div>
New expiration date: <b>{{ extended_expiration_date }}</b>
{{test}}
</p>
</div>

<div class="usa-modal__footer">
<ul class="usa-button-group">
<li class="usa-button-group__item">
<button
type="submit"
class="usa-button dja-form-placeholder"
name="_extend_expiration_date"
>
Yes, extend date
</button>
</li>
<li class="usa-button-group__item">
<button
type="button"
class="usa-button usa-button--unstyled padding-105 text-center"
data-close-modal
>
Cancel
</button>
</li>
</ul>
</div>
</div>
<button
type="button"
class="usa-button usa-modal__close"
aria-label="Close this window"
data-close-modal
>
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img">
<use xlink:href="{%static 'img/sprite.svg'%}#close"></use>
</svg>
</button>
</div>
</div>
{{ block.super }}
{% endblock %}
24 changes: 19 additions & 5 deletions src/registrar/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ def dummy_user(self, item_name, short_hand):
first_name="{} first_name:{}".format(item_name, short_hand),
last_name="{} last_name:{}".format(item_name, short_hand),
username="{} username:{}".format(item_name + str(uuid.uuid4())[:8], short_hand),
is_staff=True,
)[0]
return user

Expand Down Expand Up @@ -921,6 +922,11 @@ def dummyInfoContactResultData(
ex_date=datetime.date(2023, 5, 25),
)

mockButtonRenewedDomainExpDate = fakedEppObject(
"fake.gov",
ex_date=datetime.date(2025, 5, 25),
)

mockDnsNeededRenewedDomainExpDate = fakedEppObject(
"fakeneeded.gov",
ex_date=datetime.date(2023, 2, 15),
Expand Down Expand Up @@ -1049,11 +1055,19 @@ def mockRenewDomainCommand(self, _request, cleaned):
res_data=[self.mockMaximumRenewedDomainExpDate],
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY,
)
else:
return MagicMock(
res_data=[self.mockRenewedDomainExpDate],
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY,
)
elif getattr(_request, "name", None) == "fake.gov":
period = getattr(_request, "period", None)
extension_period = getattr(period, "length", None)
if extension_period == 2:
return MagicMock(
res_data=[self.mockButtonRenewedDomainExpDate],
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY,
)
else:
return MagicMock(
res_data=[self.mockRenewedDomainExpDate],
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY,
)

def mockInfoDomainCommands(self, _request, cleaned):
request_name = getattr(_request, "name", None)
Expand Down
Loading

0 comments on commit 735f433

Please sign in to comment.