mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-24 00:07:02 -04:00
Add service editing to organization dashboard with confirmation modal
- Add edit form for service name, primary contact, and status - Add confirmation modal before saving changes - Refactor dashboard actions into helper functions - Add validation for service name and email format
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
|
import re
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from flask import (
|
from flask import (
|
||||||
|
Response,
|
||||||
current_app,
|
current_app,
|
||||||
flash,
|
flash,
|
||||||
redirect,
|
redirect,
|
||||||
@@ -35,11 +37,15 @@ from app.main.views.dashboard import (
|
|||||||
requested_and_current_financial_year,
|
requested_and_current_financial_year,
|
||||||
)
|
)
|
||||||
from app.models.organization import AllOrganizations, Organization
|
from app.models.organization import AllOrganizations, Organization
|
||||||
|
from app.models.service import Service
|
||||||
from app.models.user import InvitedOrgUser, User
|
from app.models.user import InvitedOrgUser, User
|
||||||
|
from app.notify_client import cache
|
||||||
from app.utils.csv import Spreadsheet
|
from app.utils.csv import Spreadsheet
|
||||||
from app.utils.user import user_has_permissions, user_is_platform_admin
|
from app.utils.user import user_has_permissions, user_is_platform_admin
|
||||||
from notifications_python_client.errors import HTTPError
|
from notifications_python_client.errors import HTTPError
|
||||||
|
|
||||||
|
EMAIL_REGEX = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
|
||||||
|
|
||||||
|
|
||||||
@main.route("/organizations", methods=["GET"])
|
@main.route("/organizations", methods=["GET"])
|
||||||
@user_is_platform_admin
|
@user_is_platform_admin
|
||||||
@@ -88,6 +94,96 @@ def get_organization_message_allowance(org_id):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_create_service(org_id):
|
||||||
|
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_name = create_service_form.name.data
|
||||||
|
service_id, error = _create_service(
|
||||||
|
service_name,
|
||||||
|
create_service_form.organization_type.data,
|
||||||
|
email_safe(service_name),
|
||||||
|
create_service_form,
|
||||||
|
)
|
||||||
|
if not error:
|
||||||
|
current_organization.associate_service(service_id)
|
||||||
|
flash(f"Service '{service_name}' has been created", "default_with_tick")
|
||||||
|
session["new_service_id"] = service_id
|
||||||
|
return redirect(url_for(".organization_dashboard", org_id=org_id))
|
||||||
|
else:
|
||||||
|
flash("Error creating service", "error")
|
||||||
|
|
||||||
|
return create_service_form
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_invite_user(org_id):
|
||||||
|
invite_user_form = InviteOrgUserForm(
|
||||||
|
inviter_email_address=current_user.email_address
|
||||||
|
)
|
||||||
|
|
||||||
|
if request.method == "POST" and invite_user_form.validate_on_submit():
|
||||||
|
try:
|
||||||
|
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))
|
||||||
|
except Exception:
|
||||||
|
flash("Error sending invitation", "error")
|
||||||
|
|
||||||
|
return invite_user_form
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_edit_service(org_id, service_id):
|
||||||
|
service = Service.from_id(service_id)
|
||||||
|
|
||||||
|
if request.method == "POST":
|
||||||
|
service_name = request.form.get("service_name", "").strip()
|
||||||
|
primary_contact = request.form.get("primary_contact", "").strip()
|
||||||
|
new_status = request.form.get("status")
|
||||||
|
|
||||||
|
if not service_name:
|
||||||
|
flash("Service name is required", "error")
|
||||||
|
elif primary_contact and not re.match(EMAIL_REGEX, primary_contact):
|
||||||
|
flash("Please enter a valid email address", "error")
|
||||||
|
else:
|
||||||
|
if service_name != service.name:
|
||||||
|
service.update(name=service_name)
|
||||||
|
|
||||||
|
if primary_contact != (service.billing_contact_email_addresses or ""):
|
||||||
|
service.update(billing_contact_email_addresses=primary_contact)
|
||||||
|
|
||||||
|
current_status = "trial" if service.trial_mode else "live"
|
||||||
|
if new_status != current_status:
|
||||||
|
service.update_status(live=(new_status == "live"))
|
||||||
|
cache.redis_client.delete("organizations")
|
||||||
|
|
||||||
|
flash("Service updated successfully", "default_with_tick")
|
||||||
|
session["updated_service_id"] = str(service_id)
|
||||||
|
return redirect(url_for(".organization_dashboard", org_id=org_id))
|
||||||
|
|
||||||
|
return {
|
||||||
|
"id": service.id,
|
||||||
|
"name": (
|
||||||
|
request.form.get("service_name", "").strip()
|
||||||
|
if request.method == "POST"
|
||||||
|
else service.name
|
||||||
|
),
|
||||||
|
"primary_contact": (
|
||||||
|
request.form.get("primary_contact", "").strip()
|
||||||
|
if request.method == "POST"
|
||||||
|
else (service.billing_contact_email_addresses or "")
|
||||||
|
),
|
||||||
|
"status": "trial" if service.trial_mode else "live",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_services_dashboard_data(organization, year):
|
def get_services_dashboard_data(organization, year):
|
||||||
try:
|
try:
|
||||||
dashboard_data = organizations_client.get_organization_dashboard(
|
dashboard_data = organizations_client.get_organization_dashboard(
|
||||||
@@ -133,73 +229,45 @@ def organization_dashboard(org_id):
|
|||||||
|
|
||||||
year = requested_and_current_financial_year(request)[0]
|
year = requested_and_current_financial_year(request)[0]
|
||||||
action = request.args.get("action")
|
action = request.args.get("action")
|
||||||
|
service_id = request.args.get("service_id")
|
||||||
|
|
||||||
create_service_form = None
|
create_service_form = None
|
||||||
invite_user_form = None
|
invite_user_form = None
|
||||||
|
edit_service_data = None
|
||||||
|
|
||||||
if action == "create-service" or request.form.get("form_name") == "create_service":
|
if action == "create-service":
|
||||||
create_service_form = CreateServiceForm(
|
result = _handle_create_service(org_id)
|
||||||
organization_type=current_user.default_organization_type
|
if isinstance(result, Response):
|
||||||
or OrganizationType.FEDERAL
|
return result
|
||||||
)
|
create_service_form = result
|
||||||
|
|
||||||
if request.method == "POST" and create_service_form.validate_on_submit():
|
elif action == "invite-user":
|
||||||
service_name = create_service_form.name.data
|
result = _handle_invite_user(org_id)
|
||||||
service_id, error = _create_service(
|
if isinstance(result, Response):
|
||||||
service_name,
|
return result
|
||||||
create_service_form.organization_type.data,
|
invite_user_form = result
|
||||||
email_safe(service_name),
|
|
||||||
create_service_form,
|
|
||||||
)
|
|
||||||
if not error:
|
|
||||||
current_organization.associate_service(service_id)
|
|
||||||
current_app.logger.info(
|
|
||||||
f"Service {service_id} created and associated with org {org_id}"
|
|
||||||
)
|
|
||||||
flash(f"Service '{service_name}' has been created", "default_with_tick")
|
|
||||||
session["new_service_id"] = service_id
|
|
||||||
return redirect(url_for(".organization_dashboard", org_id=org_id))
|
|
||||||
else:
|
|
||||||
current_app.logger.error(f"Error creating service: {error}")
|
|
||||||
flash("Error creating service", "error")
|
|
||||||
|
|
||||||
if action == "invite-user" or request.form.get("form_name") == "invite_user":
|
elif action == "edit-service" and service_id:
|
||||||
invite_user_form = InviteOrgUserForm(
|
result = _handle_edit_service(org_id, service_id)
|
||||||
inviter_email_address=current_user.email_address
|
if isinstance(result, Response):
|
||||||
)
|
return result
|
||||||
|
edit_service_data = result
|
||||||
if request.method == "POST" and invite_user_form.validate_on_submit():
|
|
||||||
try:
|
|
||||||
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))
|
|
||||||
except Exception as e:
|
|
||||||
current_app.logger.error(f"Error inviting user: {e}")
|
|
||||||
flash("Error sending invitation", "error")
|
|
||||||
|
|
||||||
message_allowance = get_organization_message_allowance(org_id)
|
message_allowance = get_organization_message_allowance(org_id)
|
||||||
|
|
||||||
services_with_usage = get_services_dashboard_data(current_organization, year)
|
|
||||||
new_service_id = session.pop("new_service_id", None)
|
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"views/organizations/organization/index.html",
|
"views/organizations/organization/index.html",
|
||||||
selected_year=year,
|
selected_year=year,
|
||||||
services=services_with_usage,
|
services=get_services_dashboard_data(current_organization, year),
|
||||||
live_services=len(current_organization.live_services),
|
live_services=len(current_organization.live_services),
|
||||||
trial_services=len(current_organization.trial_services),
|
trial_services=len(current_organization.trial_services),
|
||||||
suspended_services=len(current_organization.suspended_services),
|
suspended_services=len(current_organization.suspended_services),
|
||||||
total_services=len(current_organization.services),
|
total_services=len(current_organization.services),
|
||||||
create_service_form=create_service_form,
|
create_service_form=create_service_form,
|
||||||
invite_user_form=invite_user_form,
|
invite_user_form=invite_user_form,
|
||||||
show_create_service=create_service_form is not None,
|
edit_service_data=edit_service_data,
|
||||||
show_invite_user=invite_user_form is not None,
|
new_service_id=session.pop("new_service_id", None),
|
||||||
new_service_id=new_service_id,
|
updated_service_id=session.pop("updated_service_id", None),
|
||||||
**message_allowance,
|
**message_allowance,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user