mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-25 03:58:39 +02:00
add logic for invitation
This commit is contained in:
parent
ae770ab3c2
commit
2bc8d38002
7 changed files with 106 additions and 51 deletions
|
@ -3791,7 +3791,7 @@ class WaffleFlagAdmin(FlagAdmin):
|
||||||
if extra_context is None:
|
if extra_context is None:
|
||||||
extra_context = {}
|
extra_context = {}
|
||||||
extra_context["dns_prototype_flag"] = flag_is_active_for_user(request.user, "dns_prototype_flag")
|
extra_context["dns_prototype_flag"] = flag_is_active_for_user(request.user, "dns_prototype_flag")
|
||||||
extra_context["organization_member"] = flag_is_active_for_user(request.user, "organization_member")
|
extra_context["organization_members"] = flag_is_active_for_user(request.user, "organization_members")
|
||||||
return super().changelist_view(request, extra_context=extra_context)
|
return super().changelist_view(request, extra_context=extra_context)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { initDomainsTable } from './table-domains.js';
|
||||||
import { initDomainRequestsTable } from './table-domain-requests.js';
|
import { initDomainRequestsTable } from './table-domain-requests.js';
|
||||||
import { initMembersTable } from './table-members.js';
|
import { initMembersTable } from './table-members.js';
|
||||||
import { initMemberDomainsTable } from './table-member-domains.js';
|
import { initMemberDomainsTable } from './table-member-domains.js';
|
||||||
import { initPortfolioMemberPageToggle } from './portfolio-member-page.js';
|
import { initPortfolioNewMemberPageToggle } from './portfolio-member-page.js';
|
||||||
import { initAddNewMemberPageListeners } from './portfolio-member-page.js';
|
import { initAddNewMemberPageListeners } from './portfolio-member-page.js';
|
||||||
|
|
||||||
initDomainValidators();
|
initDomainValidators();
|
||||||
|
@ -20,13 +20,6 @@ nameserversFormListener();
|
||||||
|
|
||||||
hookupYesNoListener("other_contacts-has_other_contacts",'other-employees', 'no-other-employees');
|
hookupYesNoListener("other_contacts-has_other_contacts",'other-employees', 'no-other-employees');
|
||||||
hookupYesNoListener("additional_details-has_anything_else_text",'anything-else', null);
|
hookupYesNoListener("additional_details-has_anything_else_text",'anything-else', null);
|
||||||
hookupRadioTogglerListener(
|
|
||||||
'member_access_level',
|
|
||||||
{
|
|
||||||
'admin': 'new-member-admin-permissions',
|
|
||||||
'basic': 'new-member-basic-permissions'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
hookupYesNoListener("additional_details-has_cisa_representative",'cisa-representative', null);
|
hookupYesNoListener("additional_details-has_cisa_representative",'cisa-representative', null);
|
||||||
initializeUrbanizationToggle();
|
initializeUrbanizationToggle();
|
||||||
|
|
||||||
|
@ -42,5 +35,9 @@ initDomainRequestsTable();
|
||||||
initMembersTable();
|
initMembersTable();
|
||||||
initMemberDomainsTable();
|
initMemberDomainsTable();
|
||||||
|
|
||||||
initPortfolioMemberPageToggle();
|
// Init the portfolio new member page
|
||||||
|
initPortfolioNewMemberPageToggle();
|
||||||
initAddNewMemberPageListeners();
|
initAddNewMemberPageListeners();
|
||||||
|
|
||||||
|
// Init all other portfolio member pages
|
||||||
|
initPortfolioMemberPage();
|
|
@ -2,9 +2,10 @@ import { uswdsInitializeModals } from './helpers-uswds.js';
|
||||||
import { getCsrfToken } from './helpers.js';
|
import { getCsrfToken } from './helpers.js';
|
||||||
import { generateKebabHTML } from './table-base.js';
|
import { generateKebabHTML } from './table-base.js';
|
||||||
import { MembersTable } from './table-members.js';
|
import { MembersTable } from './table-members.js';
|
||||||
|
import { hookupRadioTogglerListener } from './radios.js';
|
||||||
|
|
||||||
// This is specifically for the Member Profile (Manage Member) Page member/invitation removal
|
// This is specifically for the Member Profile (Manage Member) Page member/invitation removal
|
||||||
export function initPortfolioMemberPageToggle() {
|
export function initPortfolioNewMemberPageToggle() {
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const wrapperDeleteAction = document.getElementById("wrapper-delete-action")
|
const wrapperDeleteAction = document.getElementById("wrapper-delete-action")
|
||||||
if (wrapperDeleteAction) {
|
if (wrapperDeleteAction) {
|
||||||
|
@ -53,6 +54,16 @@ export function initAddNewMemberPageListeners() {
|
||||||
if (!add_member_form){
|
if (!add_member_form){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Hookup the radio elements
|
||||||
|
hookupRadioTogglerListener(
|
||||||
|
'member_access_level',
|
||||||
|
{
|
||||||
|
'admin': 'new-member-admin-permissions',
|
||||||
|
'basic': 'new-member-basic-permissions'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hookup the submission buttons
|
||||||
document.getElementById("confirm_new_member_submit").addEventListener("click", function() {
|
document.getElementById("confirm_new_member_submit").addEventListener("click", function() {
|
||||||
// Upon confirmation, submit the form
|
// Upon confirmation, submit the form
|
||||||
document.getElementById("add_member_form").submit();
|
document.getElementById("add_member_form").submit();
|
||||||
|
@ -168,5 +179,50 @@ export function initAddNewMemberPageListeners() {
|
||||||
modalTrigger.click();
|
modalTrigger.click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export for the rest of the portfolio pages (not add)
|
||||||
|
export function initPortfolioMemberPage() {
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
hookupRadioTogglerListener(
|
||||||
|
'role',
|
||||||
|
{
|
||||||
|
'organization_admin': 'new-member-admin-permissions',
|
||||||
|
'organization_member': 'new-member-basic-permissions'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// let memberForm = document.getElementById("member_form");
|
||||||
|
// if (!memberForm) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let memberAdminContainer = document.getElementById("member-admin-permissions");
|
||||||
|
// let memberBasicContainer = document.getElementById("member-basic-permissions");
|
||||||
|
// let roleRadios = document.querySelectorAll('input[name="role"]');
|
||||||
|
|
||||||
|
// function toggleContainers() {
|
||||||
|
// let selectedRole = document.querySelector('input[name="role"]:checked');
|
||||||
|
// if (!selectedRole) {
|
||||||
|
// hideElement(memberAdminContainer);
|
||||||
|
// hideElement(memberBasicContainer);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (selectedRole.value === "organization_admin") {
|
||||||
|
// showElement(memberAdminContainer);
|
||||||
|
// hideElement(memberBasicContainer);
|
||||||
|
// } else if (selectedRole.value === "organization_member") {
|
||||||
|
// hideElement(memberAdminContainer);
|
||||||
|
// showElement(memberBasicContainer);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Initial state
|
||||||
|
// toggleContainers();
|
||||||
|
|
||||||
|
// // Add change listener to all radio buttons
|
||||||
|
// roleRadios.forEach(radio => {
|
||||||
|
// radio.addEventListener("change", toggleContainers);
|
||||||
|
// });
|
||||||
|
});
|
||||||
}
|
}
|
|
@ -64,8 +64,8 @@ export function hookupRadioTogglerListener(radioButtonName, valueToElementMap) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radioButtons.length) {
|
if (radioButtons && radioButtons.length) {
|
||||||
// Add event listener to each radio button
|
// Add event listener to each radio button
|
||||||
radioButtons.forEach(function (radioButton) {
|
radioButtons.forEach(function (radioButton) {
|
||||||
radioButton.addEventListener('change', handleRadioButtonChange);
|
radioButton.addEventListener('change', handleRadioButtonChange);
|
||||||
|
|
|
@ -109,12 +109,13 @@ class PortfolioSeniorOfficialForm(forms.ModelForm):
|
||||||
cleaned_data.pop("full_name", None)
|
cleaned_data.pop("full_name", None)
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
|
|
||||||
class BasePortfolioMemberForm(forms.Form):
|
class BasePortfolioMemberForm(forms.Form):
|
||||||
required_star = '<abbr class="usa-hint usa-hint--required" title="required">*</abbr>'
|
required_star = '<abbr class="usa-hint usa-hint--required" title="required">*</abbr>'
|
||||||
role = forms.ChoiceField(
|
role = forms.ChoiceField(
|
||||||
choices=[
|
choices=[
|
||||||
(UserPortfolioRoleChoices.ORGANIZATION_ADMIN.value, "Admin access"),
|
(UserPortfolioRoleChoices.ORGANIZATION_ADMIN.value, "Admin access"),
|
||||||
(UserPortfolioRoleChoices.ORGANIZATION_MEMBER.value, "Basic access")
|
(UserPortfolioRoleChoices.ORGANIZATION_MEMBER.value, "Basic access"),
|
||||||
],
|
],
|
||||||
widget=forms.RadioSelect,
|
widget=forms.RadioSelect,
|
||||||
required=True,
|
required=True,
|
||||||
|
@ -175,12 +176,18 @@ class BasePortfolioMemberForm(forms.Form):
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, instance=None, **kwargs):
|
def __init__(self, *args, instance=None, **kwargs):
|
||||||
self.instance = instance
|
|
||||||
# If we have an instance, set initial
|
|
||||||
if instance:
|
|
||||||
kwargs['initial'] = self._map_instance_to_form(instance)
|
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
self.instance = instance
|
||||||
|
self.initial = self._map_instance_to_form(self.instance)
|
||||||
|
# Adds a <p> description beneath each role option
|
||||||
|
self.fields["role"].descriptions = {
|
||||||
|
"organization_admin": UserPortfolioRoleChoices.get_role_description(
|
||||||
|
UserPortfolioRoleChoices.ORGANIZATION_ADMIN
|
||||||
|
),
|
||||||
|
"organization_member": UserPortfolioRoleChoices.get_role_description(
|
||||||
|
UserPortfolioRoleChoices.ORGANIZATION_MEMBER
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
def _map_instance_to_form(self, instance):
|
def _map_instance_to_form(self, instance):
|
||||||
"""Maps model instance data to form fields"""
|
"""Maps model instance data to form fields"""
|
||||||
|
@ -235,10 +242,7 @@ class BasePortfolioMemberForm(forms.Form):
|
||||||
raise ValueError(f"ROLE_REQUIRED_FIELDS referenced a non-existent field: {field_name}.")
|
raise ValueError(f"ROLE_REQUIRED_FIELDS referenced a non-existent field: {field_name}.")
|
||||||
|
|
||||||
if not cleaned_data.get(field_name):
|
if not cleaned_data.get(field_name):
|
||||||
self.add_error(
|
self.add_error(field_name, self.fields.get(field_name).error_messages.get("required"))
|
||||||
field_name,
|
|
||||||
self.fields.get(field_name).error_messages.get("required")
|
|
||||||
)
|
|
||||||
|
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
|
@ -259,7 +263,7 @@ class BasePortfolioMemberForm(forms.Form):
|
||||||
if role == UserPortfolioRoleChoices.ORGANIZATION_ADMIN:
|
if role == UserPortfolioRoleChoices.ORGANIZATION_ADMIN:
|
||||||
if domain_request_permission_admin:
|
if domain_request_permission_admin:
|
||||||
additional_permissions.add(domain_request_permission_admin)
|
additional_permissions.add(domain_request_permission_admin)
|
||||||
|
|
||||||
if member_permission_admin:
|
if member_permission_admin:
|
||||||
additional_permissions.add(member_permission_admin)
|
additional_permissions.add(member_permission_admin)
|
||||||
else:
|
else:
|
||||||
|
@ -285,21 +289,6 @@ class PortfolioMemberForm(BasePortfolioMemberForm):
|
||||||
"""
|
"""
|
||||||
Form for updating a portfolio member.
|
Form for updating a portfolio member.
|
||||||
"""
|
"""
|
||||||
class Meta:
|
|
||||||
model = UserPortfolioPermission
|
|
||||||
fields = [
|
|
||||||
"roles",
|
|
||||||
"additional_permissions",
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(self, *args, instance=None, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.fields['role'].descriptions = {
|
|
||||||
"organization_admin": UserPortfolioRoleChoices.get_role_description(UserPortfolioRoleChoices.ORGANIZATION_ADMIN),
|
|
||||||
"organization_member": UserPortfolioRoleChoices.get_role_description(UserPortfolioRoleChoices.ORGANIZATION_MEMBER)
|
|
||||||
}
|
|
||||||
self.instance = instance
|
|
||||||
self.initial = self._map_instance_to_form(self.instance)
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioInvitedMemberForm(BasePortfolioMemberForm):
|
class PortfolioInvitedMemberForm(BasePortfolioMemberForm):
|
||||||
|
@ -307,13 +296,6 @@ class PortfolioInvitedMemberForm(BasePortfolioMemberForm):
|
||||||
Form for updating a portfolio invited member.
|
Form for updating a portfolio invited member.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = PortfolioInvitation
|
|
||||||
fields = [
|
|
||||||
"roles",
|
|
||||||
"additional_permissions",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class NewMemberForm(forms.ModelForm):
|
class NewMemberForm(forms.ModelForm):
|
||||||
member_access_level = forms.ChoiceField(
|
member_access_level = forms.ChoiceField(
|
||||||
|
|
|
@ -18,7 +18,12 @@
|
||||||
<a href="{% url 'members' %}" class="usa-breadcrumb__link"><span>Members</span></a>
|
<a href="{% url 'members' %}" class="usa-breadcrumb__link"><span>Members</span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="usa-breadcrumb__list-item">
|
<li class="usa-breadcrumb__list-item">
|
||||||
<a href="{% url 'member' pk=member.pk %}" class="usa-breadcrumb__link"><span>Manage member</span></a>
|
{% if member %}
|
||||||
|
{% url 'member' pk=member.pk as back_url %}
|
||||||
|
{% elif invitation %}
|
||||||
|
{% url 'invitedmember' pk=invitation.pk as back_url %}
|
||||||
|
{% endif %}
|
||||||
|
<a href="{{back_url}}" class="usa-breadcrumb__link"><span>Manage member</span></a>
|
||||||
</li>
|
</li>
|
||||||
{% comment %} Manage members {% endcomment %}
|
{% comment %} Manage members {% endcomment %}
|
||||||
<li class="usa-breadcrumb__list-item usa-current" aria-current="page">
|
<li class="usa-breadcrumb__list-item usa-current" aria-current="page">
|
||||||
|
@ -36,13 +41,29 @@
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<fieldset class="usa-fieldset">
|
<fieldset class="usa-fieldset">
|
||||||
<legend>
|
<legend>
|
||||||
<h2 class="margin-top-1">Member email</h2>
|
{% if member and member.email or invitation and invitation.email %}
|
||||||
|
<h2 class="margin-top-1">Member email</h2>
|
||||||
|
{% else %}
|
||||||
|
<h2 class="margin-top-1">Member</h2>
|
||||||
|
{% endif %}
|
||||||
</legend>
|
</legend>
|
||||||
<p class="margin-top-0">
|
<p class="margin-top-0">
|
||||||
|
{% comment %}
|
||||||
|
Show member email if possible, then invitation email.
|
||||||
|
If neither of these are true, show the name or as a last resort just "None".
|
||||||
|
{% endcomment %}
|
||||||
{% if member %}
|
{% if member %}
|
||||||
{{ member.email }}
|
{% if member.email %}
|
||||||
|
{{ member.email }}
|
||||||
|
{% else %}
|
||||||
|
{{ member.get_formatted_name }}
|
||||||
|
{% endif %}
|
||||||
{% elif invitation %}
|
{% elif invitation %}
|
||||||
{{ invitation.email }}
|
{% if invitation.email %}
|
||||||
|
{{ invitation.email }}
|
||||||
|
{% else %}
|
||||||
|
None
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
<!-- Member email -->
|
<!-- Member email -->
|
||||||
|
|
|
@ -165,7 +165,6 @@ class PortfolioMemberEditView(PortfolioMemberEditPermissionView, View):
|
||||||
user = portfolio_permission.user
|
user = portfolio_permission.user
|
||||||
|
|
||||||
form = self.form_class(request.POST, instance=portfolio_permission)
|
form = self.form_class(request.POST, instance=portfolio_permission)
|
||||||
print(f"form valid: {form.is_valid()}")
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
return redirect("member", pk=pk)
|
return redirect("member", pk=pk)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue