diff --git a/atst/routes/workspaces.py b/atst/routes/workspaces.py
index 64faac94..fcc5f7ae 100644
--- a/atst/routes/workspaces.py
+++ b/atst/routes/workspaces.py
@@ -12,6 +12,8 @@ from atst.domain.workspaces import Workspaces
from atst.domain.projects import Projects
from atst.forms.new_project import NewProjectForm
from atst.forms.new_member import NewMemberForm
+from atst.domain.authz import Authorization
+from atst.models.permissions import Permissions
bp = Blueprint("workspaces", __name__)
@@ -26,7 +28,15 @@ def workspace():
)
except UnauthorizedError:
pass
- return {"workspace": workspace}
+
+ def user_can(permission):
+ if workspace:
+ return Authorization.has_workspace_permission(
+ g.current_user, workspace, permission
+ )
+ return False
+
+ return {"workspace": workspace, "permissions": Permissions, "user_can": user_can}
@bp.route("/workspaces")
diff --git a/styles/components/_empty_state.scss b/styles/components/_empty_state.scss
index be8675ad..6117484b 100644
--- a/styles/components/_empty_state.scss
+++ b/styles/components/_empty_state.scss
@@ -14,7 +14,7 @@
@include icon-color($color-gray-light);
}
- p {
+ .empty-state__message {
@include h2;
line-height: 1.2;
max-width: 15em;
@@ -24,4 +24,13 @@
@include h1;
}
}
+
+ .empty-state__sub-message {
+ @include h4;
+ color: $color-gray;
+
+ @include media($large-screen) {
+ @include h3;
+ }
+ }
}
diff --git a/templates/components/empty_state.html b/templates/components/empty_state.html
index 7dc6f119..b0aaa038 100644
--- a/templates/components/empty_state.html
+++ b/templates/components/empty_state.html
@@ -1,13 +1,20 @@
{% from "components/icon.html" import Icon %}
-{% macro EmptyState(message, actionLabel, actionHref, icon=None) -%}
+{% macro EmptyState(message, action_label, action_href, icon=None, sub_message=None) -%}
-
{{ message }}
+
{{ message }}
{% if icon %}
{{ Icon(icon) }}
{% endif %}
-
{{ actionLabel }}
+ {% if sub_message %}
+
{{ sub_message }}
+ {% endif %}
+
+ {% if action_href and action_label %}
+
{{ action_label }}
+ {% endif %}
+
{%- endmacro %}
diff --git a/templates/navigation/workspace_navigation.html b/templates/navigation/workspace_navigation.html
index a3de6043..5ef3ec8c 100644
--- a/templates/navigation/workspace_navigation.html
+++ b/templates/navigation/workspace_navigation.html
@@ -6,7 +6,7 @@
"Projects",
href=url_for("workspaces.workspace_projects", workspace_id=workspace.id),
active=request.url_rule.rule.startswith('/workspaces//projects'),
- subnav=[
+ subnav=None if not user_can(permissions.ADD_APPLICATION_IN_WORKSPACE) else [
{
"label": "Add New Project",
"href": url_for('workspaces.new_project', workspace_id=workspace.id),
@@ -20,7 +20,7 @@
"Members",
href=url_for("workspaces.workspace_members", workspace_id=workspace.id),
active=request.url_rule.rule.startswith('/workspaces//members'),
- subnav=[
+ subnav=None if not user_can(permissions.ASSIGN_AND_UNASSIGN_ATAT_ROLE) else [
{
"label": "Add New Member",
"href": url_for("workspaces.new_member", workspace_id=workspace.id),
diff --git a/templates/requests.html b/templates/requests.html
index 85190baf..31f2c7d1 100644
--- a/templates/requests.html
+++ b/templates/requests.html
@@ -29,8 +29,8 @@
{{ EmptyState(
'There are currently no active requests for you to see.',
- actionLabel='Create a new JEDI Cloud Request',
- actionHref=url_for('requests.requests_form_new', screen=1),
+ action_label='Create a new JEDI Cloud Request',
+ action_href=url_for('requests.requests_form_new', screen=1),
icon='document'
) }}
diff --git a/templates/workspace_members.html b/templates/workspace_members.html
index 6fb852cb..d1e43515 100644
--- a/templates/workspace_members.html
+++ b/templates/workspace_members.html
@@ -6,10 +6,13 @@
{% if not workspace.members %}
+ {% set user_can_invite = user_can(permissions.ASSIGN_AND_UNASSIGN_ATAT_ROLE) %}
+
{{ EmptyState(
'There are currently no members in this Workspace.',
- actionLabel='Invite a new Member',
- actionHref='/members/new',
+ action_label='Invite a new Member' if user_can_invite else None,
+ action_href='/members/new' if user_can_invite else None,
+ sub_message=None if user_can_invite else 'Please contact your JEDI workspace administrator to invite new members.',
icon='avatar'
) }}
diff --git a/templates/workspace_projects.html b/templates/workspace_projects.html
index d2af0e17..0ad2d6ef 100644
--- a/templates/workspace_projects.html
+++ b/templates/workspace_projects.html
@@ -1,36 +1,54 @@
{% from "components/icon.html" import Icon %}
{% from "components/alert.html" import Alert %}
+{% from "components/empty_state.html" import EmptyState %}
{% extends "base_workspace.html" %}
+
{% block workspace_content %}
-{% for project in workspace.projects %}
-
-{% endfor %}
+ {% set can_create_projects = user_can(permissions.ADD_APPLICATION_IN_WORKSPACE) %}
+
+ {{ EmptyState(
+ 'This workspace doesn’t have any projects yet.',
+ action_label='Add a New Project' if can_create_projects else None,
+ action_href=url_for('workspaces.new_project', workspace_id=workspace.id) if can_create_projects else None,
+ icon='cloud',
+ sub_message=None if can_create_projects else 'Please contact your JEDI workspace administrator to set up a new project.'
+ ) }}
+
+{% else %}
+
+ {% for project in workspace.projects %}
+
+ {% endfor %}
+
+{% endif %}
{% endblock %}
diff --git a/tests/routes/test_workspaces.py b/tests/routes/test_workspaces.py
new file mode 100644
index 00000000..202a8127
--- /dev/null
+++ b/tests/routes/test_workspaces.py
@@ -0,0 +1,53 @@
+from tests.factories import UserFactory, WorkspaceFactory
+from atst.domain.workspaces import Workspaces
+from atst.models.workspace_user import WorkspaceUser
+
+
+def test_user_with_permission_has_add_project_link(client, user_session):
+ user = UserFactory.create()
+ workspace = WorkspaceFactory.create()
+ Workspaces._create_workspace_role(user, workspace, "owner")
+
+ user_session(user)
+ response = client.get("/workspaces/{}/projects".format(workspace.id))
+ assert (
+ 'href="/workspaces/{}/projects/new"'.format(workspace.id).encode()
+ in response.data
+ )
+
+
+def test_user_without_permission_has_no_add_project_link(client, user_session):
+ user = UserFactory.create()
+ workspace = WorkspaceFactory.create()
+ Workspaces._create_workspace_role(user, workspace, "developer")
+ user_session(user)
+ response = client.get("/workspaces/{}/projects".format(workspace.id))
+ assert (
+ 'href="/workspaces/{}/projects/new"'.format(workspace.id).encode()
+ not in response.data
+ )
+
+
+def test_user_with_permission_has_add_member_link(client, user_session):
+ user = UserFactory.create()
+ workspace = WorkspaceFactory.create()
+ Workspaces._create_workspace_role(user, workspace, "owner")
+
+ user_session(user)
+ response = client.get("/workspaces/{}/members".format(workspace.id))
+ assert (
+ 'href="/workspaces/{}/members/new"'.format(workspace.id).encode()
+ in response.data
+ )
+
+
+def test_user_without_permission_has_no_add_member_link(client, user_session):
+ user = UserFactory.create()
+ workspace = WorkspaceFactory.create()
+ Workspaces._create_workspace_role(user, workspace, "developer")
+ user_session(user)
+ response = client.get("/workspaces/{}/members".format(workspace.id))
+ assert (
+ 'href="/workspaces/{}/members/new"'.format(workspace.id).encode()
+ not in response.data
+ )