Use ApplicationRole.id instead of User.id in forms. This eliminates the
need for the function that checks whether a user is in a given
application, because looking up the application role will raise an error
if the user is not.
Our forms should rely on role IDs for displaying user information on the
portfolio page. This way they are decoupled from user table data and can
eventually rely on invitation user data where an invitation has been
sent but a user does not exist yet.
Previously, we were encoding the portfolio_role.user_id as part of the
form data for the portfolio admin page. This was convenient because it
allowed us to easily determine certain display attributes in the
template. Instead, we should rely on the PortfolioRole as the source of
truth for member information. This commit adds:
- Portfolio.owner_role to return the PortfolioRole of the owner
- explicitly passes the PortfolioRole IDs for the PPoC and current user
to the template
- PortfolioRole.full_name for deriving the member name
- raise specific invitation type if invite not found in invitation domain classes
- more terse assignments of defaults in invitation service, smh
- terser margin expression for inline input fields
- sass formatting
- use translation for cancel link
- oxford comma for app team management permission explanation
- do not format environment roles with hyphens for role selection
- generalize some additional methods in the invitation domain base class
- use plain atst.models import path
The environment name will be grayed out until something besides the
default "no access" is selected.
Small changes to the application member subforms:
- filter for "None" as a string
- have nested forms inherit from FlaskForm; each nested form adds its
own validation error flash otherwise if there are validation problems
- domain method for creating a new application member
- ApplicationInvitations domain class
- nested form for adding a new user that holds user data, application
permission sets, and environment roles
- Invitation service can infer invitation type based on role it's given
- new invitation email templates