Add inline forms to organization dashboard for creating services and inviting users

This commit is contained in:
Beverly Nguyen
2025-10-30 10:00:52 -07:00
parent 3cbdffa21e
commit 949f09bb70
2 changed files with 94 additions and 3 deletions

View File

@@ -6,18 +6,22 @@ from flask import current_app, flash, redirect, render_template, request, url_fo
from flask_login import current_user
from app import current_organization, org_invite_api_client, organizations_client
from app.enums import OrganizationType
from app.formatters import email_safe
from app.main import main
from app.main.forms import (
AdminBillingDetailsForm,
AdminNewOrganizationForm,
AdminNotesForm,
AdminOrganizationDomainsForm,
CreateServiceForm,
InviteOrgUserForm,
OrganizationOrganizationTypeForm,
RenameOrganizationForm,
SearchByNameForm,
SearchUsersForm,
)
from app.main.views.add_service import _create_service
from app.main.views.dashboard import (
get_tuples_of_financial_years,
requested_and_current_financial_year,
@@ -109,13 +113,42 @@ def get_services_dashboard_data(organization, year):
return services
@main.route("/organizations/<uuid:org_id>", methods=["GET"])
@main.route("/organizations/<uuid:org_id>", methods=["GET", "POST"])
@user_has_permissions()
def organization_dashboard(org_id):
if not current_app.config.get("ORGANIZATION_DASHBOARD_ENABLED", False):
return redirect(url_for(".organization_usage", org_id=org_id))
year = requested_and_current_financial_year(request)[0]
action = request.args.get("action")
create_service_form = None
invite_user_form = None
if action == "create-service" or request.form.get("form_name") == "create_service":
create_service_form = CreateServiceForm(
organization_type=current_user.default_organization_type or OrganizationType.FEDERAL
)
if request.method == "POST" and create_service_form.validate_on_submit():
service_id, error = _create_service(
create_service_form.name.data,
create_service_form.organization_type.data,
email_safe(create_service_form.name.data),
create_service_form,
)
if not error:
return redirect(url_for(".service_dashboard", service_id=service_id))
if action == "invite-user" or request.form.get("form_name") == "invite_user":
invite_user_form = InviteOrgUserForm(inviter_email_address=current_user.email_address)
if request.method == "POST" and invite_user_form.validate_on_submit():
invited_org_user = InvitedOrgUser.create(
current_user.id, org_id, invite_user_form.email_address.data
)
flash(f"Invite sent to {invited_org_user.email_address}", "default_with_tick")
return redirect(url_for(".organization_dashboard", org_id=org_id))
message_allowance = get_organization_message_allowance(org_id)
@@ -129,6 +162,10 @@ def organization_dashboard(org_id):
trial_services=len(current_organization.trial_services),
suspended_services=len(current_organization.suspended_services),
total_services=len(current_organization.services),
create_service_form=create_service_form,
invite_user_form=invite_user_form,
show_create_service=create_service_form is not None,
show_invite_user=invite_user_form is not None,
**message_allowance,
)

View File

@@ -58,8 +58,62 @@
</div>
</div>
<details class="usa-details">
<summary class="usa-details__summary font-heading-lg ">What is a service?</summary>
<div class="display-flex flex-gap-1 margin-bottom-3">
<a href="{{ url_for('.organization_dashboard', org_id=current_org.id, action='create-service') }}" class="usa-button {% if not show_create_service %}usa-button--outline{% endif %}">
Create new service
</a>
<a href="{{ url_for('.organization_dashboard', org_id=current_org.id, action='invite-user') }}" class="usa-button {% if not show_invite_user %}usa-button--outline{% endif %}">
Add org admin
</a>
</div>
{% if show_create_service and create_service_form %}
<div class="bg-base-lightest padding-3 radius-md margin-bottom-3 position-relative">
<a href="{{ url_for('.organization_dashboard', org_id=current_org.id) }}" class="position-absolute top-1 right-1 text-base-dark text-no-underline hover:text-primary" aria-label="Close">
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img">
<use xlink:href="/static/images/sprite.svg#close"></use>
</svg>
</a>
<h3 class="margin-top-0">Create a new service</h3>
<form method="post" action="{{ url_for('.organization_dashboard', org_id=current_org.id, action='create-service') }}">
<input type="hidden" name="csrf_token" value="{{ create_service_form.csrf_token._value() }}"/>
<input type="hidden" name="form_name" value="create_service"/>
{{ create_service_form.name(param_extensions={"hint": {"text": "You can change this later"}}) }}
<div class="display-flex flex-gap-1 margin-top-3">
<button type="submit" class="usa-button">Create service</button>
<a href="{{ url_for('.organization_dashboard', org_id=current_org.id) }}" class="usa-button usa-button--unstyled">Cancel</a>
</div>
</form>
</div>
{% endif %}
{% if show_invite_user and invite_user_form %}
<div class="bg-base-lightest padding-3 radius-md margin-bottom-3 position-relative">
<a href="{{ url_for('.organization_dashboard', org_id=current_org.id) }}" class="position-absolute top-1 right-1 text-base-dark text-no-underline hover:text-primary" aria-label="Close">
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img">
<use xlink:href="/static/images/sprite.svg#close"></use>
</svg>
</a>
<h3 class="margin-top-0">Invite a team member</h3>
<p class="margin-top-0">{{ current_org.name }} team members can see usage and team members for each service, and invite other team members.</p>
<form method="post" action="{{ url_for('.organization_dashboard', org_id=current_org.id, action='invite-user') }}">
<input type="hidden" name="csrf_token" value="{{ invite_user_form.csrf_token._value() }}"/>
<input type="hidden" name="form_name" value="invite_user"/>
{{ invite_user_form.email_address(param_extensions={"classes": ""}, error_message_with_html=True) }}
<div class="display-flex flex-gap-1 margin-top-3">
<button type="submit" class="usa-button">Send invitation</button>
<a href="{{ url_for('.organization_dashboard', org_id=current_org.id) }}" class="usa-button usa-button--unstyled">Cancel</a>
</div>
</form>
</div>
{% endif %}
<details class="usa-details">
<summary class="usa-details__summary font-heading-lg ">What is a service?</summary>
<div class="usa-details__content">
<p class="usa-body">
When you join Notify, you're added to a service. This is your organization's workspace for sending text messages and emails. Within your service, you can: