aboutsummaryrefslogtreecommitdiff
path: root/gn2/wqflask/templates/oauth2
diff options
context:
space:
mode:
authorArun Isaac2023-12-29 18:55:37 +0000
committerArun Isaac2023-12-29 19:01:46 +0000
commit204a308be0f741726b9a620d88fbc22b22124c81 (patch)
treeb3cf66906674020b530c844c2bb4982c8a0e2d39 /gn2/wqflask/templates/oauth2
parent83062c75442160427b50420161bfcae2c5c34c84 (diff)
downloadgenenetwork2-204a308be0f741726b9a620d88fbc22b22124c81.tar.gz
Namespace all modules under gn2.
We move all modules under a gn2 directory. This is important for "correct" packaging and deployment as a Guix service.
Diffstat (limited to 'gn2/wqflask/templates/oauth2')
-rw-r--r--gn2/wqflask/templates/oauth2/create-resource.html89
-rw-r--r--gn2/wqflask/templates/oauth2/create-role.html46
-rw-r--r--gn2/wqflask/templates/oauth2/data-list-genotype.html166
-rw-r--r--gn2/wqflask/templates/oauth2/data-list-mrna.html168
-rw-r--r--gn2/wqflask/templates/oauth2/data-list-phenotype.html209
-rw-r--r--gn2/wqflask/templates/oauth2/data-list.html53
-rw-r--r--gn2/wqflask/templates/oauth2/display_error.html10
-rw-r--r--gn2/wqflask/templates/oauth2/group.html114
-rw-r--r--gn2/wqflask/templates/oauth2/group_join_or_create.html99
-rw-r--r--gn2/wqflask/templates/oauth2/join-requests.html73
-rw-r--r--gn2/wqflask/templates/oauth2/list_roles.html80
-rw-r--r--gn2/wqflask/templates/oauth2/login.html47
-rw-r--r--gn2/wqflask/templates/oauth2/masquerade.html39
-rw-r--r--gn2/wqflask/templates/oauth2/profile_nav.html64
-rw-r--r--gn2/wqflask/templates/oauth2/register_user.html62
-rw-r--r--gn2/wqflask/templates/oauth2/request_error.html32
-rw-r--r--gn2/wqflask/templates/oauth2/resources.html58
-rw-r--r--gn2/wqflask/templates/oauth2/role.html56
-rw-r--r--gn2/wqflask/templates/oauth2/view-group-role.html102
-rw-r--r--gn2/wqflask/templates/oauth2/view-resource.html352
-rw-r--r--gn2/wqflask/templates/oauth2/view-user.html48
21 files changed, 1967 insertions, 0 deletions
diff --git a/gn2/wqflask/templates/oauth2/create-resource.html b/gn2/wqflask/templates/oauth2/create-resource.html
new file mode 100644
index 00000000..479f4152
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/create-resource.html
@@ -0,0 +1,89 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+
+{%block title%}Create Resource{%endblock%}
+{%block css%}
+<link rel="stylesheet" type="text/css" href="/static/new/css/mytooltip.css" />
+{%endblock%}
+
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("resources", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ {%if resource_category_error%}
+ <p>
+ <span class="glyphicon glyphicon-exclamation-sign text-danger"></span>
+ &nbsp;
+ <span class="text-danger">{{resource_category_error.error}}</span>:
+ {{resource_category_error.error_message}}
+ </p>
+ {%else%}
+ <form method="POST"
+ action="{{url_for('oauth2.resource.create_resource')}}">
+
+ <fieldset>
+ <legend>Resource Category</legend>
+ <div class="form-group">
+ {%for category in resource_categories%}
+ <div class="radio mytooltip">
+ <label for="rdo:resource_category:{{category.resource_category_id}}"
+ class="form-label"
+ style="text-transform: capitalize;">
+ <input type="radio" name="resource_category" required="required"
+ id="rdo:resource_category:{{category.resource_category_id}}"
+ value="{{category.resource_category_id}}"
+ {%if resource_category is defined%}
+ {%if category.resource_category_id == resource_category%}
+ checked="checked"
+ {%endif%}
+ {%endif%} />
+ {{category.resource_category_key}}
+ </label>
+ <span class="mytooltiptext">
+ {{category.resource_category_description}}
+ </span>
+ </div>
+ {%endfor%}
+ </div>
+ </fieldset>
+
+ <fieldset>
+ <legend>Basic Resource Information</legend>
+ <div class="form-group mytooltip">
+ <label for="resource_name" class="form-label">Name</label>
+ <input type="text" name="resource_name" class="form-control"
+ {%if resource_name is defined and resource_name is not none%}
+ value="{{resource_name}}"
+ {%endif%}
+ required="required" />
+ <span class="mytooltiptext">
+ The resource name, e.g. the experiment name.
+ </span>
+ </div>
+ </fieldset>
+
+ <fieldset>
+ <legend>Access Control</legend>
+ <div class="form-group mytooltip">
+ <label for="chk-public">Publicly Viewable?</label>
+ <input type="checkbox" name="public" id="chk-public"
+ checked="checked" />
+ <span class="mytooltiptext">
+ Select whether data in this resource will be publicly viewable.
+ </span>
+ </div>
+ </fieldset>
+
+ <input class="btn btn-primary" type="submit" value="Create" />
+
+ </form>
+ {%endif%}
+ </div>
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/create-role.html b/gn2/wqflask/templates/oauth2/create-role.html
new file mode 100644
index 00000000..f2bff7b4
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/create-role.html
@@ -0,0 +1,46 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("roles", user_privileges)}}
+ <h3>Create Role</h3>
+
+ {{flash_me()}}
+
+ {%if group_privileges_error is defined%}
+ {{display_error("Group Privileges", group_privileges_error)}}
+ {%else%}
+ {%if "group:role:create-role" in user_privileges%}
+ <form method="POST" action="{{url_for('oauth2.role.create_role')}}">
+ <legend>Create Group Role</legend>
+ <div class="form-group">
+ <label for="role_name" class="form-label">Name</label>
+ <input type="text" id="role_name" name="role_name" required="required"
+ class="form-control"
+ {%if prev_role_name is defined and prev_role_name is not none%}
+ value="{{prev_role_name}}"
+ {%endif%} />
+ </div>
+ <label class="form-label">Privileges</label>
+ {%for priv in group_privileges%}
+ <div class="checkbox">
+ <label for="chk:{{priv.privilege_id}}">
+ <input type="checkbox" id="chk:{{priv.privilege_id}}"
+ name="privileges[]" value={{priv.privilege_id}} />
+ <span style="text-transform: capitalize;">
+ {{priv.privilege_description}}
+ </span> ({{priv.privilege_id}})
+ </label>
+ </div>
+ {%endfor%}
+
+ <input type="submit" class="btn btn-primary" value="Create" />
+ </form>
+ {%else%}
+ {{display_error("Privilege", {"error":"PrivilegeError", "error_description": "You do not have sufficient privileges to create a new role."})}}
+ {%endif%}
+ {%endif%}
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/data-list-genotype.html b/gn2/wqflask/templates/oauth2/data-list-genotype.html
new file mode 100644
index 00000000..c780a583
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/data-list-genotype.html
@@ -0,0 +1,166 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+
+{%block title%}Link Data: Genotype{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{%endblock%}
+
+{%block content%}
+<div class="container" style="width: 98%;">
+ {{profile_nav("data", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="row">
+ <noscript>This page needs javascript to work correctly</noscript>
+ </div>
+
+ <div class="row">
+ <form id="frm-link-genotypes" method="POST"
+ action="{{url_for('oauth2.data.link_genotype_data')}}">
+ <legend>Link Genotype Datasets to Group</legend>
+
+ <input type="hidden" name="species_name" value="{{species_name}}" />
+
+ <div class="form-group">
+ <label for="select-group">Group</label>
+ <select id="select-group" name="group_id" required="required"
+ class="form-control">
+ <option value="">Select group</option>
+ {%for group in groups%}
+ <option value="{{group.group_id}}">{{group.group_name}}</option>
+ {%endfor%}
+ </select>
+ </div>
+
+ <div class="form-group">
+ <table id="tbl-link-genotypes"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-selected-datasets='{{selected_datasets | list | tojson}}'>
+ <thead>
+ <tr>
+ <th>Deselect</th>
+ <th>Group</th>
+ <th>Dataset Name</th>
+ <th>Dataset FullName</th>
+ <th>Dataset ShortName</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for dataset in selected_datasets%}
+ <tr>
+ <td>
+ <input type="checkbox" class="checkbox checkbox-selected"
+ name="selected"
+ value='{{dataset | tojson}}' />
+ </td>
+ <td>{{dataset.dataset_name}}</td>
+ <td>{{dataset.dataset_fullname}}</td>
+ <td>{{dataset.dataset_shortname}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp
+ No datasets selected for linking.
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+ <div class="form-group text-center">
+ <input type="submit" value="Link Selected"
+ class="btn btn-primary"
+ style="border-top: 0.3em;"
+ {%if groups | length <= 0 or selected_datasets | length <= 0%}
+ disabled="disabled"
+ {%endif%} />
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <span id="search-messages" class="alert-danger" style="display:none"></span>
+ <form id="frm-search"
+ action="{{search_uri}}"
+ method="POST">
+ <legend>Search: Genotype</legend>
+ <input type="hidden" value="{{species_name}}" name="species"
+ id="txt-species-name" />
+ <input type="hidden" value="{{dataset_type}}" name="dataset_type"
+ id="txt-dataset-type" />
+ <input type="hidden" value="{{per_page}}" name="per_page"
+ id="txt-per-page" />
+
+ <div class="form-group">
+ <label for="txt-query">Dataset Search String</label>
+ <input type="text" id="txt-query" name="query" class="form-control"
+ value="{{query}}"/>
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <div id="search-error" class="text-danger" style="display: none;">
+ <span class="glyphicon glyphicon-exclamation-sign"></span>
+ &nbsp
+ <span id="search-error-text"></span>
+ </div>
+ <table id="tbl-genotypes"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-datasets='{{datasets | list | tojson}}'>
+ <thead>
+ <tr>
+ <th>Select</th>
+ <th>Group</th>
+ <th>Dataset Name</th>
+ <th>Dataset FullName</th>
+ <th>Dataset ShortName</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for dataset in datasets:%}
+ <tr>
+ <td>
+ <input type="checkbox" class="checkbox checkbox-search"
+ name="search_datasets"
+ value='{{dataset | tojson}}' />
+ </td>
+ <td>{{dataset.InbredSetName}}</td>
+ <td>{{dataset.dataset_name}}</td>
+ <td>{{dataset.dataset_fullname}}</td>
+ <td>{{dataset.dataset_shortname}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp
+ No datasets available for selection.
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+
+</div>
+{%endblock%}
+
+{%block js%}
+<script src="/static/new/javascript/auth/search.js"
+ language="javascript" type="text/javascript"></script>
+<script src="/static/new/javascript/auth/search_genotypes.js"
+ language="javascript" type="text/javascript"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/data-list-mrna.html b/gn2/wqflask/templates/oauth2/data-list-mrna.html
new file mode 100644
index 00000000..0e163235
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/data-list-mrna.html
@@ -0,0 +1,168 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+
+{%block title%}Link Data: Genotype{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{%endblock%}
+
+{%block content%}
+<div class="container" style="width: 98%;">
+ {{profile_nav("data", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="row">
+ <noscript>This page needs javascript to work correctly</noscript>
+ </div>
+
+ <div class="row">
+ <form id="frm-link" method="POST"
+ action="{{url_for('oauth2.data.link_mrna_data')}}">
+ <legend>Link mRNA Assay Datasets to Group</legend>
+
+ <input type="hidden" name="species_name" value="{{species_name}}" />
+
+ <div class="form-group">
+ <label for="select-group">Group</label>
+ <select id="select-group" name="group_id" required="required"
+ class="form-control">
+ <option value="">Select group</option>
+ {%for group in groups%}
+ <option value="{{group.group_id}}">{{group.group_name}}</option>
+ {%endfor%}
+ </select>
+ </div>
+
+ <div class="form-group">
+ <table id="tbl-link"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-datasets='{{selected_datasets | list | tojson}}'>
+ <thead>
+ <tr>
+ <th>Deselect</th>
+ <th>Group</th>
+ <th>Dataset Name</th>
+ <th>Dataset FullName</th>
+ <th>Dataset ShortName</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for dataset in selected_datasets%}
+ <tr>
+ <td>
+ <input type="checkbox" class="checkbox checkbox-selected"
+ name="selected"
+ value='{{dataset | tojson}}' />
+ </td>
+ <td>{{dataset.dataset_name}}</td>
+ <td>{{dataset.dataset_fullname}}</td>
+ <td>{{dataset.dataset_shortname}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp
+ No datasets selected for linking.
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+ <div class="form-group text-center">
+ <input type="submit" value="Link Selected"
+ class="btn btn-primary"
+ style="border-top: 0.3em;"
+ {%if groups | length <= 0 or selected_datasets | length <= 0%}
+ disabled="disabled"
+ {%endif%} />
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <span id="search-messages" class="alert-danger" style="display:none"></span>
+ <form id="frm-search"
+ action="{{search_uri}}"
+ method="POST">
+ <legend>Search: mRNA Assay</legend>
+ <input type="hidden" value="{{species_name}}" name="species"
+ id="txt-species-name" />
+ <input type="hidden" value="{{dataset_type}}" name="dataset_type"
+ id="txt-dataset-type" />
+ <input type="hidden" value="{{per_page}}" name="per_page"
+ id="txt-per-page" />
+
+ <div class="form-group">
+ <label for="txt-query">Dataset Search String</label>
+ <input type="text" id="txt-query" name="query" class="form-control"
+ value="{{query}}"/>
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <div id="search-error" class="text-danger" style="display: none;">
+ <span class="glyphicon glyphicon-exclamation-sign"></span>
+ &nbsp
+ <span id="search-error-text"></span>
+ </div>
+ <table id="tbl-search"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-datasets='{{datasets | list | tojson}}'>
+ <thead>
+ <tr>
+ <th>Select</th>
+ <th>Group</th>
+ <th>Study Name</th>
+ <th>Dataset Name</th>
+ <th>Dataset FullName</th>
+ <th>Dataset ShortName</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for dataset in datasets:%}
+ <tr>
+ <td>
+ <input type="checkbox" class="checkbox checkbox-search"
+ name="search_datasets"
+ value='{{dataset | tojson}}' />
+ </td>
+ <td>{{dataset.InbredSetName}}</td>
+ <td>{{dataset.StudyName}}</td>
+ <td>{{dataset.dataset_name}}</td>
+ <td>{{dataset.dataset_fullname}}</td>
+ <td>{{dataset.dataset_shortname}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp
+ No datasets available for selection.
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+
+</div>
+{%endblock%}
+
+{%block js%}
+<script src="/static/new/javascript/auth/search.js"
+ language="javascript" type="text/javascript"></script>
+<script src="/static/new/javascript/auth/search_mrna.js"
+ language="javascript" type="text/javascript"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/data-list-phenotype.html b/gn2/wqflask/templates/oauth2/data-list-phenotype.html
new file mode 100644
index 00000000..8c79c0d6
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/data-list-phenotype.html
@@ -0,0 +1,209 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+
+{%block title%}Link Data: Phenotype{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{%endblock%}
+
+{%block content%}
+
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("data", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="row">
+ <noscript>This page needs javascript to work correctly</noscript>
+ </div>
+
+ <div class="row">
+ <form id="frm-link-phenotypes"
+ action="{{url_for('oauth2.data.link_phenotype_data')}}"
+ method="POST">
+ <input type="hidden" value="{{species_name}}" name="species_name" />
+ <legend style="text-transform: capitalize;">
+ {{dataset_type}}: Link Traits to Group
+ </legend>
+
+ <div class="form-group">
+ <label for="select-group">Group</label>
+ <select id="select-group" name="group_id" required="required"
+ class="form-control">
+ <option value="">Select group</option>
+ {%for group in groups%}
+ <option value="{{group.group_id}}">{{group.group_name}}</option>
+ {%endfor%}
+ </select>
+ </div>
+
+ <table id="tbl-link-phenotypes"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-traits="[]">
+ <thead>
+ <tr>
+ <th>Link</th>
+ <th>Name</th>
+ <th>Group</th>
+ <th>Dataset</th>
+ <th>Dataset Fullname</th>
+ <th>Description</th>
+ <th>Authors</th>
+ <th>Year</th>
+ <th>Location</th>
+ <th>LRS</th>
+ <th>Additive</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for trait in selected%}
+ <tr>
+ <th>
+ <input type="checkbox" class="checkbox checkbox-search"
+ name="search_traits" value="{{trait | tojson}}" />
+ </th>
+ <th>{{trait.name}}</th>
+ <th>{{trait.group}}</th>
+ <th>{{trait.dataset}}</th>
+ <th>{{trait.dataset_fullname}}</th>
+ <th>{{trait.description}}</th>
+ <th>{{trait.authors | join(" ")}}</th>
+ <th>
+ <a href="{{trait.pubmed_linj}}" title="Pubmed link for trait">
+ {{trait.year}}
+ </a>
+ </th>
+ <th>CHR{{trait.geno_chr}}@{{trait.geno_mb}}</th>
+ <th>{{trait.lrs}}</th>
+ <th>{{trait.additive}}</th>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center" style="text-align: center;">
+ <br/><b><font size="4">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp;
+ There are no phenotype traits to link to the user group.
+ </font></b><br />
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+
+ <div class="form-group text-center">
+ <input type="submit" value="Link Selected"
+ class="btn btn-primary"
+ style="border-top: 0.3em;"
+ {%if groups | length <= 0 or traits | length <= 0%}
+ disabled="disabled"
+ {%endif%} />
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <span id="search-messages" class="alert-danger" style="display:none"></span>
+ <form id="frm-search-traits"
+ action="#"
+ method="POST"
+ data-gn-server-url="{{gn_server_url}}">
+ {%if dataset_type == "mrna"%}
+ <legend>mRNA: Search</legend>
+ {%else%}
+ <legend style="text-transform: capitalize;">
+ {{dataset_type}}: Search
+ </legend>
+ {%endif%}
+ <input type="hidden" value="{{species_name}}" name="species"
+ id="txt-species-name" />
+ <input type="hidden" value="{{dataset_type}}" name="dataset_type"
+ id="txt-dataset-type" />
+ <input type="hidden" value="{{per_page}}" name="per_page"
+ id="txt-per-page" />
+
+ <div class="form-group">
+ <label for="txt-query">Search</label>
+ <div class="input-group">
+ <span class="input-group-addon">species:{{species_name}} AND </span>
+ <input type="text" id="txt-query" name="query" class="form-control"
+ value="{{query}}"/>
+ </div>
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <table id="tbl-phenotypes"
+ class="table-hover table-striped cell-border dataTable no-footer"
+ data-traits="{{traits | tojson}}"
+ data-initial-job-id="{{search_results.job_id}}"
+ data-initial-command-id="{{search_results.command_id}}">
+ <thead>
+ <tr>
+ <th>Select</th>
+ <th>Name</th>
+ <th>Group</th>
+ <th>Dataset</th>
+ <th>Dataset Fullname</th>
+ <th>Description</th>
+ <th>Authors</th>
+ <th>Year</th>
+ <th>Location</th>
+ <th>LRS</th>
+ <th>Additive</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for trait in traits%}
+ <tr>
+ <th>
+ <input type="checkbox" class="checkbox checkbox-search"
+ name="search_traits" value="{{trait | tojson}}" />
+ </th>
+ <th>{{trait.name}}</th>
+ <th>{{trait.group}}</th>
+ <th>{{trait.dataset}}</th>
+ <th>{{trait.dataset_fullname}}</th>
+ <th>{{trait.description}}</th>
+ <th>{{trait.authors | join(" ")}}</th>
+ <th>
+ <a href="{{trait.pubmed_linj}}" title="Pubmed link for trait">
+ {{trait.year}}
+ </a>
+ </th>
+ <th>CHR{{trait.geno_chr}}@{{trait.geno_mb}}</th>
+ <th>{{trait.lrs}}</th>
+ <th>{{trait.additive}}</th>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="100%" align="center" style="text-align: center;">
+ <br/><b><font size="4">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp;
+ There are no phenotype traits to select from.
+ </font></b><br />
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+</div>
+
+{%endblock%}
+
+{%block js%}
+<script language="javascript" type="text/javascript"
+ src="/static/new/javascript/auth/search.js"></script>
+<script language="javascript" type="text/javascript"
+ src="/static/new/javascript/auth/search_phenotypes.js"></script>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/data-list.html b/gn2/wqflask/templates/oauth2/data-list.html
new file mode 100644
index 00000000..8a8f6694
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/data-list.html
@@ -0,0 +1,53 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}Link Data{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("data", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="row">
+ <form id="frm-select-datatype"
+ action="{{url_for('oauth2.data.list_data')}}"
+ method="POST">
+ <legend>Search</legend>
+ {%if species_error is defined%}
+ {{display_error("Species", species_error)}}
+ {%elif species | length == 0%}
+ <span class="glyphicon glyphicon-info-sign text-danger">
+ </span>
+ &nbsp;
+ <strong class="text-danger">No list of species to select from</strong>
+ {%else%}
+ <div class="form-group">
+ <label for="select-species">Species</label>
+ <select id="select-species" name="species_name" required="required"
+ class="form-control">
+ <option value="">Select Species</option>
+ {%for spc in species%}
+ <option value="{{spc.Name}}">
+ {{spc.MenuName}} ({{spc.FullName}})
+ </option>
+ {%endfor%}
+ </select>
+ </div>
+
+ <div class="form-group">
+ <label for="select-dataset-type">Dataset/Trait Type</label>
+ <select id="select-dataset-type" name="dataset_type"
+ required="required" class="form-control">
+ <option value="">Select dataset type</option>
+ <option value="mrna">mRNA Assay (ProbeSet) Dataset</option>
+ <option value="genotype">Genotype Dataset</option>
+ <option value="phenotype">Phenotype (Publish) Dataset</option>
+ </select>
+ </div>
+
+ <input type="submit" class="btn btn-primary" value="Search" />
+ {%endif%}
+ </form>
+ </div>
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/display_error.html b/gn2/wqflask/templates/oauth2/display_error.html
new file mode 100644
index 00000000..9abe02c4
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/display_error.html
@@ -0,0 +1,10 @@
+{%macro display_error(title, the_error)%}
+
+<strong>{{title}}</strong>:
+<span class="glyphicon glyphicon-exclamation-sign text-danger">
+</span>
+&nbsp;
+<strong class="text-danger">{{the_error.error}}:</strong>
+{{the_error.error_description}}
+
+{%endmacro%}
diff --git a/gn2/wqflask/templates/oauth2/group.html b/gn2/wqflask/templates/oauth2/group.html
new file mode 100644
index 00000000..f4c29d18
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/group.html
@@ -0,0 +1,114 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("group", user_privileges)}}
+
+ {{flash_me()}}
+
+ {%if group_error is defined%}
+ <div class="row" style="text-align:center;line-height:5em;">
+ {{display_error("Group", group_error)}}
+ </div>
+ {%else%}
+ <div class="container-fluid">
+ <div class="row">
+ {%if group_join_requests_error is defined %}
+ {{display_error("Join Requests", group_join_requests_error)}}
+ {%else%}
+ <a href="{{url_for('oauth2.group.list_join_requests')}}"
+ class="btn btn-info">
+ Requests ({{group_join_requests | count}})
+ </a>
+ {%endif%}
+ </div>
+ <div class="row">
+ <table class="table">
+ <caption>Group Information</caption>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th colspan="2" style="text-align: center;">Metadata</th>
+ <th colspan="2" style="text-align: center;">Actions</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ <tr>
+ <td rowspan="{{group.group_metadata.items() | count + 1}}">
+ {{group.group_name}}
+ </td>
+ <td><strong>Key</strong></td>
+ <td><strong>Value</strong></td>
+ <td rowspan="{{group.group_metadata.items() | count + 1}}"
+ style="text-align: center;">
+ <a href="{{url_for('oauth2.group.edit_group', group_id=group.group_id)}}"
+ class="btn btn-info" title="Edit group information">Edit</a>
+ </td>
+ <td rowspan="{{group.group_metadata.items() | count + 1}}"
+ style="text-align: center;">
+ <a href="{{url_for('oauth2.group.edit_group', group_id=group.group_id)}}"
+ class="btn btn-danger" title="Delete this group">Delete</a>
+ </td>
+ </tr>
+
+ {%for key,val in group.group_metadata.items()%}
+ <tr>
+ <td>{{key.split("_") | map("capitalize") | join(" ")}}</td>
+ <td>{{val}}</td>
+ </tr>
+ {%endfor%}
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+
+ <div class="container-fluid">
+
+ <table class="table">
+ <caption>Group Users</caption>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Email</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for user in users%}
+ <tr>
+ <td>{{user.name}}</td>
+ <td>{{user.email}}</td>
+ <td>
+ <a href="url_for('oauth2.group.remove_user', user_id=user.user_id)"
+ title="Remove this user from being a member of this group."
+ class="btn btn-danger">Remove</a>
+ </td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="3">
+ {%if user_error is defined%}
+ <span class="glyphicon glyphicon-exclamation-sign text-danger">
+ </span>
+ &nbsp;
+ <strong class="text-danger">{{user_error.error}}</strong>
+ {{user_error.error_description}}
+ {%else%}
+ No users found for this group
+ {%endif%}
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+
+ </div>
+ {%endif%}
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/group_join_or_create.html b/gn2/wqflask/templates/oauth2/group_join_or_create.html
new file mode 100644
index 00000000..8255d2f8
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/group_join_or_create.html
@@ -0,0 +1,99 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%block title%}Join or Create Group{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css" href="/static/new/css/mytooltip.css" />
+{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("group", user_privileges)}}
+
+ <h3>Join or Create Group</h3>
+
+ {{flash_me()}}
+
+ {%if group_join_request is defined and group_join_request.exists %}
+ <p>
+ <span class="glyphicon glyphicon-info-sign text-warning"></span>
+ &nbsp;
+ <span class="text-info">You have an active request to join a group.</span>
+ </p>
+
+ <p class="explainer">
+ You cannot create a group, or request to join a new group until your
+ currently active request has been either accepted or rejected.
+ </p>
+ {%else%}
+ <p>You can</p>
+
+ {%if groups | length > 0 %}
+ <div class="explainer">
+ <p>
+ For most users, this is the preffered choice. You request access to an
+ existing group, and the group leader will chose whether or not to add you to
+ their group.</p>
+
+ <p>You can only be a member of a single group.</p>
+ </div>
+
+ <form action="{{url_for('oauth2.user.request_add_to_group')}}"
+ method="POST">
+ <legend>Request to be added to group</legend>
+ <div class="form-group">
+ <label class="control-label" for="group">Group</label>
+ <select class="form-control" id="group" required="required" name="group">
+ <option value="">Select a group</option>
+ {%for group in groups%}
+ <option value="{{group.group_id}}">{{group.group_name}}</option>
+ {%endfor%}
+ </select>
+ </div>
+ <div class="form-group">
+ <input type="submit" value="Request Access" class="btn btn-primary" />
+ </div>
+ </form>
+
+ <p>or</p>
+ {%else%}
+ <p>
+ <span class="glyphicon glyphicon-warning-sign text-warning"></span>
+ &nbsp;
+ <span class="text-warning">There an currently no groups to join.</span>
+ </p>
+ {%endif%}
+
+ <div class="explainer">
+ <p>
+ Creating a new group automatically makes you that group's administrator.
+ </p>
+
+ <p>You can only be a member of a single group.</p>
+ </div>
+
+ <form action="{{url_for('oauth2.group.create_group')}}"
+ method="POST">
+ <legend>Create a new group</legend>
+ <div class="form-group mytooltip">
+ <label class="control-label" for="group_name">Group Name</label>
+ <input type="text" class="form-control" id="group_name"
+ name="group_name"required="required" />
+ <span class="mytooltiptext">
+ Name of the group.
+ </span>
+ </div>
+ <div class="form-group mytooltip">
+ <label class="control-label" for="group_desc">Group Description</label>
+ <textarea class="form-control" id="group_description"
+ name="group_description"></textarea>
+ <span class="mytooltiptext">
+ A description to help identify the purpose/goal of the group
+ </span>
+ </div>
+ <div class="form-group">
+ <input type="submit" value="Create Group" class="btn btn-primary" />
+ </div>
+ </form>
+ {%endif%}
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/join-requests.html b/gn2/wqflask/templates/oauth2/join-requests.html
new file mode 100644
index 00000000..833b4e93
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/join-requests.html
@@ -0,0 +1,73 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("group", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ <table class="table">
+ <caption>Join Requests</caption>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Email</th>
+ <th>Request Date/Time</th>
+ <th>Status</th>
+ <th>Message</th>
+ <th colspan="2" style="text-align: center;">Actions</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for request in requests%}
+ <tr>
+ <td>{{request.name}}</td>
+ <td>{{request.email}}</td>
+ <td>{{datetime_string(request.timestamp)}}</td>
+ <td>{{request.status}}</td>
+ <td>{{request.message}}</td>
+ <td>
+ <form method="POST"
+ action="{{url_for('oauth2.group.accept_join_request')}}">
+ <input type="hidden" name="request_id"
+ value="{{request.request_id}}" />
+ <input type="submit" class="btn btn-primary" value="Accept"
+ {%if request.status != "PENDING"%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </td>
+ <td>
+ <form method="POST"
+ action="{{url_for('oauth2.group.reject_join_request')}}">
+ <input type="hidden" name="request_id"
+ value="{{request.request_id}}" />
+ <input type="submit" class="btn btn-danger" value="Reject"
+ {%if request.status != "PENDING"%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="3">
+ {%if error is defined %}
+ {{display_error("Join Requests", error)}}
+ {%else%}
+ No one has requested to join your group yet.
+ {%endif%}
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/list_roles.html b/gn2/wqflask/templates/oauth2/list_roles.html
new file mode 100644
index 00000000..a4061fca
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/list_roles.html
@@ -0,0 +1,80 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("roles", user_privileges)}}
+ <h3>Roles</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ <h3>Your System-Level Roles</h3>
+ <ul>
+ {%for role in roles %}
+ <li>
+ <a href="{{url_for('oauth2.role.role', role_id=role.role_id)}}"
+ title="Link to role {{role.role_name}}">{{role.role_name}}</a>
+ </li>
+ {%else%}
+ <li>
+ <span class="glyphicon glyphicon-warning-sign"></span>&nbsp;
+ <span class="text-warning">No roles attached to this user</span>
+ </li>
+ {%endfor%}
+ </ul>
+ </div>
+
+ <div class="row">
+ <h3>Group-Wide Roles</h3>
+
+ {%if "group:role:create-role" in user_privileges%}
+ <a href="{{url_for('oauth2.role.create_role')}}"
+ title="Link to create a new group role"
+ class="btn btn-info">New Group Role</a>
+ {%endif%}
+
+ {%if group_roles_error is defined%}
+ {{display_error("Group Roles", group_role_error)}}
+ {%else%}
+ <table class="table">
+ <caption>Group Roles</caption>
+ <thead>
+ <tr>
+ <th>Role Name</th>
+ <th colspan="100%">Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for grole in group_roles%}
+ <tr>
+ <td>{{grole.role.role_name}}</td>
+ <td>
+ <a href="{{url_for('oauth2.group.group_role', group_role_id=grole.group_role_id)}}"
+ title="Link to role {{grole.role.role_name}}"
+ class="btn btn-info">
+ View
+ </a>
+ </td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="3">
+ <span class="glyphicon glyphicon-exclamation-sign text-info">
+ </span>
+ &nbsp;
+ <span class="text-info">No group roles found</span>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/login.html b/gn2/wqflask/templates/oauth2/login.html
new file mode 100644
index 00000000..eaa1a192
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/login.html
@@ -0,0 +1,47 @@
+{%extends "base.html"%}
+{%block title%}Login{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ <h3>Sign in here.</h3>
+
+ <form class="form-horizontal"
+ {%if next_endpoint%}
+ action="{{url_for('oauth2.user.login', next=next_endpoint)}}"
+ {%else%}
+ action="{{url_for('oauth2.user.login')}}"
+ {%endif%}
+ method="POST" id="oauth2-login-form">
+ <fieldset>
+ <legend>Sign in with Genenetwork</legend>
+ {{flash_me()}}
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="email_address"
+ style="text-align:left;">Email</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="email_address" name="email_address" type="email"
+ {%if email%}value="{{email}}"{%endif%}
+ placeholder="your@email.address" size="50"
+ class="form-control" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="password"
+ style="text-align:left;">Password</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="password" name="password" type="password"
+ size="50" class="form-control"
+ placeholder="your password" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div style="margin-left:20px;" class="col-xs-4 controls">
+ <input type="submit" class="btn btn-primary form-control" id="submit" name="submit"
+ value="Sign in" />
+ </div>
+ </div>
+ </fieldset>
+ </form>
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/masquerade.html b/gn2/wqflask/templates/oauth2/masquerade.html
new file mode 100644
index 00000000..48ec6cee
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/masquerade.html
@@ -0,0 +1,39 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}Masquerade As{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("masquerade", user_privileges)}}
+
+ {{flash_me()}}
+
+ {%if users_error is defined%}
+ {{display_error("Users", users_error)}}
+ {%else%}
+ <div class="container-fluid">
+ <div class="row">
+ <form method="POST"
+ action="{{url_for('oauth2.user.masquerade')}}">
+ <legend>Masquerade As</legend>
+ <div class="form-group">
+ <label for="select-masquerade" class="form-label">
+ Masquerade as
+ </label>
+ <select id="select-masquerade" name="masquerade_as"
+ required="required" class="form-control">
+ <option value="">Select User</option>
+ {%for user in users%}
+ <option value="{{user.user_id}}">{{user.name}} ({{user.email}})</option>
+ {%endfor%}
+ </select>
+ </div>
+ <div class="form-group">
+ <input type="submit" class="btn btn-primary" value="Masquerade" />
+ </div>
+ </form>
+ </div>
+ </div>
+ {%endif%}
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/profile_nav.html b/gn2/wqflask/templates/oauth2/profile_nav.html
new file mode 100644
index 00000000..aa752905
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/profile_nav.html
@@ -0,0 +1,64 @@
+{%macro profile_nav(calling_page, user_sys_privileges)%}
+
+<ul class="nav nav-pills">
+
+ <li role="presentation"
+ {%if calling_page == "dashboard"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.user.user_profile')}}">Dashboard</a>
+ </li>
+
+ <li role="presentation"
+ {%if calling_page == "group"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.group.user_group')}}">Group</a>
+ </li>
+
+ <li role="presentation"
+ {%if calling_page == "roles"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.role.user_roles')}}">Roles</a>
+ </li>
+
+ <li role="presentation"
+ {%if calling_page == "resources"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.resource.user_resources')}}">Resources</a>
+ </li>
+
+ {%if "system:data:link-to-group" in user_sys_privileges %}
+ <li role="presentation"
+ {%if calling_page == "data"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.data.list_data')}}">Link Data</a>
+ </li>
+ {%endif%}
+
+ {%if "system:user:masquerade" in user_sys_privileges %}
+ <li role="presentation"
+ {%if calling_page == "masquerade"%}
+ class="active"
+ {%endif%}>
+ <a href="{{url_for('oauth2.user.masquerade')}}"
+ title="Masquerade as another user">
+ Masquerade As
+ </a>
+ </li>
+ {%endif%}
+
+ <li role="presentation">
+ {%if logged_in():%}
+ <a href="{{url_for('oauth2.user.logout')}}">Logout</a>
+ {%else%}
+ <a href="{{url_for('oauth2.user.login')}}">Login</a>
+ {%endif%}
+ </li>
+
+</ul>
+
+{%endmacro%}
diff --git a/gn2/wqflask/templates/oauth2/register_user.html b/gn2/wqflask/templates/oauth2/register_user.html
new file mode 100644
index 00000000..27ccbd30
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/register_user.html
@@ -0,0 +1,62 @@
+{%extends "base.html"%}
+{%block title%}Register New User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ <h3>Register User</h3>
+
+ <form class="form-horizontal"
+ action="{{url_for('oauth2.user.register_user')}}"
+ method="POST" id="oauth2-register-user-form">
+ <fieldset>
+ <legend>Register User</legend>
+ {{flash_me()}}
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="name"
+ style="text-align:left;">Name</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="user_name" name="user_name" type="text"
+ placeholder="Your Name" size="50"
+ class="form-control" required="required" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="email_address"
+ style="text-align:left;">Email</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="email_address" name="email_address" type="email"
+ placeholder="your@email.address" size="50"
+ class="form-control" required="required" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="password"
+ style="text-align:left;">Password</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="password" name="password" type="password"
+ size="50" class="form-control"
+ placeholder="your password" required="required" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="col-xs-1 control-label" for="confirm_password"
+ style="text-align:left;">Confirm Password</label>
+ <div style="margin-left:20px;" class="col-xs-4">
+ <input id="confirm_password" name="confirm_password" type="password"
+ size="50" class="form-control" required="required"
+ placeholder="your password, again" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div style="margin-left:20px;" class="col-xs-4 controls">
+ <input type="submit" class="btn btn-primary form-control" id="submit" name="submit"
+ value="Register" />
+ </div>
+ </div>
+ </fieldset>
+ </form>
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/request_error.html b/gn2/wqflask/templates/oauth2/request_error.html
new file mode 100644
index 00000000..e6ed5fff
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/request_error.html
@@ -0,0 +1,32 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("error", user_privileges)}}
+ <h3>ERROR</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+
+ <div class="row">
+ <dl>
+ <dt>Error code</dt>
+ <dd>{{response.status}}[{{response.status_code}}]</dd>
+
+ <dt>URI</dt>
+ <dd>{{response.url}}</dd>
+
+ <dt>Content Type</dt>
+ <dd>{{response.content_type or "-"}}</dd>
+
+ <dt>{{response.content}}</dt>
+ <dd>{{response.content}}</dd>
+ </dl>
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/resources.html b/gn2/wqflask/templates/oauth2/resources.html
new file mode 100644
index 00000000..c52043db
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/resources.html
@@ -0,0 +1,58 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("resources", user_privileges)}}
+ <h3>Resources</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ <a href="{{url_for('oauth2.resource.create_resource')}}"
+ class="btn btn-info" title="Create a new resource">
+ Create New Resource
+ </a>
+ </div>
+
+ <div class="row">
+ <table class="table">
+ <caption>Resources</caption>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Category</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for resource in resources %}
+ <tr>
+ <td>
+ <a href="{{url_for(
+ 'oauth2.resource.view_resource',
+ resource_id=resource.resource_id)}}"
+ title="View resource {{resource.resource_name}}">
+ {{resource.resource_name}}
+ </a>
+ </td>
+ <td>{{resource.resource_category.resource_category_key}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="3">
+ <span class="glyphicon glyphicon-warning-sign"></span>&nbsp;
+ <span class="text-warning">
+ The user has no access to any resource.
+ </span>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/role.html b/gn2/wqflask/templates/oauth2/role.html
new file mode 100644
index 00000000..c33c93ee
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/role.html
@@ -0,0 +1,56 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("roles", user_privileges)}}
+ <h3>Role: {{role.role_name}}</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ <div class="panel panel-info">
+ <div class="panel-heading">
+ <strong>{{role.role_name}}</strong>
+ </div>
+ <div class="panel-body">
+ <table class="table">
+ <thead>
+ <tr><th>privilege id</th><th>description</th></tr>
+ </thead>
+ <tbody>
+ {%for privilege in role.privileges:%}
+ <tr>
+ <td>{{privilege.privilege_id}}</td>
+ <td>{{privilege.privilege_description}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td>
+ <span class="glyphicon glyphicon-warning-sign text-warning"></span>
+ &nbsp;
+ </td>
+ <td>
+ <span class="text-warning">No privileges found for this role.</span>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+ <div class="panel-footer">
+ <p>
+ This role acts on the resource with ID:
+ <a href="{{url_for('oauth2.resource.view_resource', resource_id=resource_id)}}">
+ {{resource_id}}
+ </a>
+ </p>
+ </div>
+ </div>
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/view-group-role.html b/gn2/wqflask/templates/oauth2/view-group-role.html
new file mode 100644
index 00000000..5da023bf
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/view-group-role.html
@@ -0,0 +1,102 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("roles", user_privileges)}}
+ <h3>View Group Role</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ <h3>Role Details</h3>
+ {%if group_role_error is defined%}
+ {{display_error("Group Role", group_role_error)}}
+ {%else%}
+ <table class="table">
+ <caption>Details for '{{group_role.role.role_name}}' Role</caption>
+ <thead>
+ <tr>
+ <th>Privilege</th>
+ <th>Description</th>
+ <th>Action</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for privilege in group_role.role.privileges%}
+ <tr>
+ <td>{{privilege.privilege_id}}</td>
+ <td>{{privilege.privilege_description}}</td>
+ <td>
+ <form action="{{url_for(
+ 'oauth2.group.delete_privilege_from_role',
+ group_role_id=group_role.group_role_id)}}"
+ method="POST">
+ <input type="hidden" name="privilege_id"
+ value="{{privilege.privilege_id}}" />
+ <input type="submit" class="btn btn-danger"
+ value="Remove"
+ {%if not group_role.role.user_editable%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+ </div>
+
+ <div class="row">
+ <h3>Other Privileges</h3>
+ <table class="table">
+ <caption>Other Privileges not Assigned to this Role</caption>
+ <thead>
+ <tr>
+ <th>Privilege</th>
+ <th>Description</th>
+ <th>Action</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for priv in group_privileges%}
+ <tr>
+ <td>{{priv.privilege_id}}</td>
+ <td>{{priv.privilege_description}}</td>
+ <td>
+ <form action="{{url_for(
+ 'oauth2.group.add_privilege_to_role',
+ group_role_id=group_role.group_role_id)}}"
+ method="POST">
+ <input type="hidden" name="privilege_id"
+ value="{{priv.privilege_id}}" />
+ <input type="submit" class="btn btn-warning"
+ value="Add to Role"
+ {%if not group_role.role.user_editable%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="3">
+ <span class="glyphicon glyphicon-info-sign text-info">
+ </span>
+ &nbsp;
+ <span class="text-info">All privileges assigned!</span>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/view-resource.html b/gn2/wqflask/templates/oauth2/view-resource.html
new file mode 100644
index 00000000..275fcb24
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/view-resource.html
@@ -0,0 +1,352 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("resources", user_privileges)}}
+ <h3>Resources</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+
+ {%if resource_error is defined %}
+ {{display_error("Resource", resource_error)}}
+ {%else%}
+ <div class="row">
+ <h3>Resource Details</h3>
+ <table class="table">
+ <caption>Resource: {{resource.resource_name}}</caption>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Category</th>
+ <th colspan="3" style="text-align: center;">Actions</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ <tr>
+ <td>{{resource.resource_name}}</td>
+ <td>{{resource.resource_category.resource_category_description}}</td>
+ <td>
+ <form method="POST"
+ action="{{url_for(
+ 'oauth2.resource.toggle_public',
+ resource_id=resource.resource_id)}}">
+
+ <div class="input-group">
+ {%if resource.public%}
+ <input type="submit" value="Make Private"
+ class="btn btn-success" />
+ {%else%}
+ <input type="submit" value="Make Public"
+ class="btn btn-danger" />
+ {%endif%}
+ </div>
+ </form>
+ </td>
+ <td>
+ <a href="{{url_for(
+ 'oauth2.resource.edit_resource',
+ resource_id=resource.resource_id)}}"
+ title="Edit resource"
+ class="btn btn-warning">Edit</a>
+ </td>
+ <td>
+ <a href="{{url_for(
+ 'oauth2.resource.delete_resource',
+ resource_id=resource.resource_id)}}"
+ title="Edit resource"
+ class="btn btn-danger">Delete</a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div class="row">
+ <h3>Resource Data</h3>
+ <table class="table">
+ <caption>Resource Data</caption>
+ <thead>
+ <tr>
+ {%if resource.resource_category.resource_category_key == "phenotype"%}
+ <th>Trait</th>
+ <th>Description</th>
+ <th>Year</th>
+ {%endif%}
+ <th>Dataset Name</th>
+ <th>Full Name</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for data_item in resource.resource_data:%}
+ <tr>
+ {%if resource.resource_category.resource_category_key == "phenotype"%}
+ <td>
+ <a href="/show_trait?trait_id={{data_item.PublishXRefId}}&dataset={{data_item.dataset_name}}"
+ title="Trait Data and Analysis for {{data_item.PublishXRefId}}"
+ target="_blank">
+ {{data_item.PublishXRefId}}
+ </a>
+ </td>
+ <td>{{data_item.description}}</td>
+ <td>
+ {%if data_item.PubMed_ID%}
+ <a href="https://pubmed.ncbi.nlm.nih.gov/{{data_item.PubMed_ID}}/"
+ title="{{data_item.Title}}" target="_blank">
+ {{data_item.Year}}
+ </a>
+ {%else%}
+ {{data_item.Year}}
+ {%endif%}
+ </td>
+ {%endif%}
+ <td>
+ <a href="https://gn1.genenetwork.org/webqtl/main.py?FormID=sharinginfo&GN_AccessionId={{data_item.accession_id}}&InfoPageName={{data_item.dataset_name}}"
+ title="Link to information on dataset '{{data_item.dataset_fullname}}'"
+ target="_blank">
+ {{data_item.dataset_name}}
+ </a>
+ </td>
+ <td>{{data_item.dataset_fullname}}</td>
+ <td>
+ <form action="{{url_for('oauth2.resource.unlink_data_from_resource')}}"
+ method="POST">
+ <input type="hidden" name="resource_id"
+ value="{{resource.resource_id}}" />
+ <input type="hidden" name="data_link_id"
+ value="{{data_item.data_link_id}}" />
+ <input type="submit" value="Unlink" class="btn btn-danger" />
+ </form>
+ </td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="2">
+ <span class="glyphicon glyphicon-info-sign text-danger">
+ </span>
+ &nbsp;
+ <strong class="text-info">No linked data.</strong>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ <form action="{{url_for('oauth2.resource.view_resource', resource_id=resource.resource_id)}}"
+ method="GET"
+ style="width:100%;text-align:center;">
+ <input type="hidden" name="page" value="{{page}}" />
+ <input type="hidden" name="count_per_page" value="{{count_per_page}}" />
+
+ <input type="submit" name="submit" value="prev" class="btn btn-info"
+ {%if page == 1 %}disabled="disabled"{%endif%} />
+ <input type="submit" name="submit" value="next" class="btn btn-info"
+ {%if resource.resource_data | length < count_per_page %}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </div>
+
+ <div class="row">
+ <h3>Unlinked Data</h3>
+ <table class="table">
+ <caption>Link Data</caption>
+ <thead>
+ <tr>
+ {%if resource.resource_category.resource_category_key == "phenotype"%}
+ <th>Trait</th>
+ <th>Description</th>
+ <th>Year</th>
+ {%endif%}
+ <th>Dataset Name</th>
+ <th>Dataset FullName</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%if unlinked_error is defined%}
+ {{display_error("Unlinked Data Error", unlinked_error)}}
+ {%else%}
+ {%for data_item in unlinked_data:%}
+ <tr>
+ {%if resource.resource_category.resource_category_key == "phenotype"%}
+ <td>
+ <a href="/show_trait?trait_id={{data_item.PublishXRefId}}&dataset={{data_item.dataset_name}}"
+ title="Trait Data and Analysis for {{data_item.PublishXRefId}}"
+ target="_blank">
+ {{data_item.PublishXRefId}}
+ </a>
+ </td>
+ <td>{{data_item.description}}</td>
+ <td>
+ {%if data_item.PubMed_ID%}
+ <a href="https://pubmed.ncbi.nlm.nih.gov/{{data_item.PubMed_ID}}/"
+ title="{{data_item.Title}}" target="_blank">
+ {{data_item.Year}}
+ </a>
+ {%else%}
+ {{data_item.Year}}
+ {%endif%}
+ </td>
+ {%endif%}
+ <td>
+ <a href="https://gn1.genenetwork.org/webqtl/main.py?FormID=sharinginfo&GN_AccessionId={{data_item.accession_id}}&InfoPageName={{data_item.dataset_name}}"
+ title="Dataset Group: {{data_item.dataset_name}}"
+ target="_blank">
+ {{data_item.dataset_name}}
+ </a>
+ </td>
+ <td>{{data_item.dataset_fullname}}</td>
+ <td>
+ <form method="POST"
+ action="{{url_for('oauth2.resource.link_data_to_resource')}}">
+ <input type="hidden" name="resource_id"
+ value="{{resource.resource_id}}" />
+ <input type="hidden" name="data_link_id"
+ value="{{data_item.data_link_id}}" />
+ <input type="hidden" name="dataset_type"
+ value="{{resource.resource_category.resource_category_key | lower}}" />
+ <input type="submit" value="Link" class="btn btn-info"
+ {%if resource.resource_category.resource_category_description == "mRNA Dataset" and resource.resource_data | count != 0%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ </td>
+ </tr>
+ {%else%}
+ <span class="glyphicon glyphicon-info-sign text-info">
+ </span>
+ &nbsp;
+ <strong class="text-info">No data to link.</strong>
+ {%endfor%}
+ {%endif%}
+ </tbody>
+ </table>
+ </div>
+
+ <div class="row">
+ <h3>User Roles</h3>
+ {%if users_n_roles_error is defined%}
+ {{display_error("Users and Roles", users_n_roles_error)}}
+ {%else%}
+ <table class="table">
+ <caption>User Roles</caption>
+ <thead>
+ <tr>
+ <th>User Email</th>
+ <th>User Name</th>
+ <th>User Group</th>
+ <th colspan="2">Assigned Roles</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for user_row in users_n_roles%}
+ <tr>
+ <td rowspan="{{user_row.roles | length + 1}}">{{user_row.user.email}}</td>
+ <td rowspan="{{user_row.roles | length + 1}}">{{user_row.user.name}}</td>
+ <td rowspan="{{user_row.roles | length + 1}}">
+ {{user_row.user_group.group_name}}</td>
+ <th>Role</th>
+ <th>Action</th>
+ </tr>
+ {%for grole in user_row.roles%}
+ <tr>
+ <td>
+ <a href="{{url_for(
+ 'oauth2.role.role',
+ role_id=grole.role_id)}}"
+ title="Details for '{{grole.role_name}}' role">
+ {{grole.role_name}}
+ </a>
+ </td>
+ <td>
+ <form action="{{url_for('oauth2.resource.unassign_role',
+ resource_id=resource.resource_id)}}"
+ method="POST">
+ <input type="hidden" name="user_id"
+ value="{{user_row.user.user_id}}" />
+ <input type="hidden" name="group_role_id"
+ value="{{grole.group_role_id}}">
+ <input type="submit"
+ value="Unassign"
+ class="btn btn-danger"
+ {%if user_row.user.user_id==this_user.user_id%}
+ disabled="disabled"
+ {%endif%}>
+ </form>
+ </td>
+ </tr>
+ {%endfor%}
+ {%else%}
+ <tr>
+ <td colspan="5">
+ <span class="glyphicon glyphicon-info-sign text-info">
+ </span>
+ &nbsp;
+ <span class="text-info">
+ There are no users assigned any role for this resource.
+ </span>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+ </div>
+
+ <div class="row">
+ <h3>Assign</h3>
+ {%if group_roles_error is defined%}
+ {{display_error("Group Roles", group_roles_error)}}
+ {%elif users_error is defined%}
+ {{display_error("Users", users_error)}}
+ {%else%}
+ <form action="{{url_for(
+ 'oauth2.resource.assign_role',
+ resource_id=resource.resource_id)}}"
+ method="POST" autocomplete="off">
+ <input type="hidden" name="resource_id" value="{{resource_id}}" />
+ <div class="form-group">
+ <label for="group_role_id" class="form-label">Role</label>
+ <select class="form-control" name="group_role_id"
+ id="group_role_id" required="required">
+ <option value="">Select role</option>
+ {%for grole in group_roles%}
+ <option value="{{grole.group_role_id}}">
+ {{grole.role.role_name}}
+ </option>
+ {%endfor%}
+ </select>
+ </div>
+ <div class="form-group">
+ <label for="user-email" class="form-label">User Email</label>
+ <input list="users-list" name="user_email" class="form-control"
+ {%if users | length == 0%}
+ disabled="disabled"
+ {%endif%}
+ required="required" />
+ <datalist id="users-list">
+ {%for user in users%}
+ <option value="{{user.email}}">{{user.email}} - {{user.name}}</option>
+ {%endfor%}
+ </datalist>
+ </div>
+
+ <input type="submit" class="btn btn-primary" value="Assign"
+ {%if users | length == 0%}
+ disabled="disabled"
+ {%endif%} />
+ </form>
+ {%endif%}
+ </div>
+ {%endif%}
+
+ </div>
+
+</div>
+{%endblock%}
diff --git a/gn2/wqflask/templates/oauth2/view-user.html b/gn2/wqflask/templates/oauth2/view-user.html
new file mode 100644
index 00000000..34526b14
--- /dev/null
+++ b/gn2/wqflask/templates/oauth2/view-user.html
@@ -0,0 +1,48 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("dashboard", user_privileges)}}
+ <h3>View User</h3>
+
+ {{flash_me()}}
+
+ <div class="container-fluid">
+ <div class="row">
+ {%if user_details%}
+ <p><strong>Name</strong>: {{user_details.name}}</p>
+ <p><strong>E-Mail</strong>: {{user_details.email}}</p>
+ {%if user_details.group%}
+ <p><strong>Group</strong>:{{user_details.group.group_name}}</p>
+ {%else%}
+ <p>
+ <span class="glyphicon glyphicon-warning-sign text-warning"></span>
+ &nbsp;
+ <span class="text-warning">User is not a member of a group.</span>
+ </p>
+
+ {%if group_join_request is defined and group_join_request.exists %}
+ <p>
+ <span class="glyphicon glyphicon-info-sign text-warning"></span>
+ &nbsp;
+ <span class="text-info">You have an active join request to a group.</span>
+ </p>
+ {%else%}
+ <p><a href="{{url_for('oauth2.group.join_or_create')}}"
+ class="btn btn-primary"
+ title="Join an existing group, or create your own group">
+ Join or Create group
+ </a></p>
+ {%endif%}
+
+ {%endif%}
+ {%else%}
+ <p class="text-warning">No details found.</p>
+ {%endif%}
+ </div>
+
+ </div>
+
+</div>
+{%endblock%}