Merge pull request #408 from dod-ccpo/filter-by-status-and-role
Filter by status and role
This commit is contained in:
@@ -67,8 +67,5 @@ class WorkspaceUser(object):
|
|||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<WorkspaceUser(user='{}', role='{}', workspace='{}', num_environment_roles='{}')>".format(
|
return "<WorkspaceUser(user='{}', role='{}', workspace='{}', num_environment_roles='{}')>".format(
|
||||||
self.user.full_name,
|
self.user_name, self.role, self.workspace.name, self.num_environment_roles
|
||||||
self.role,
|
|
||||||
self.workspace.name,
|
|
||||||
self.num_environment_roles,
|
|
||||||
)
|
)
|
||||||
|
@@ -21,7 +21,11 @@ from atst.forms.project import NewProjectForm, ProjectForm
|
|||||||
from atst.forms.new_member import NewMemberForm
|
from atst.forms.new_member import NewMemberForm
|
||||||
from atst.forms.edit_member import EditMemberForm
|
from atst.forms.edit_member import EditMemberForm
|
||||||
from atst.forms.workspace import WorkspaceForm
|
from atst.forms.workspace import WorkspaceForm
|
||||||
from atst.forms.data import ENVIRONMENT_ROLES, ENV_ROLE_MODAL_DESCRIPTION
|
from atst.forms.data import (
|
||||||
|
ENVIRONMENT_ROLES,
|
||||||
|
ENV_ROLE_MODAL_DESCRIPTION,
|
||||||
|
WORKSPACE_ROLE_DEFINITIONS,
|
||||||
|
)
|
||||||
from atst.domain.authz import Authorization
|
from atst.domain.authz import Authorization
|
||||||
from atst.models.permissions import Permissions
|
from atst.models.permissions import Permissions
|
||||||
from atst.domain.invitations import Invitations
|
from atst.domain.invitations import Invitations
|
||||||
@@ -102,9 +106,26 @@ def workspace_members(workspace_id):
|
|||||||
new_member = next(
|
new_member = next(
|
||||||
filter(lambda m: m.user_name == new_member_name, workspace.members), None
|
filter(lambda m: m.user_name == new_member_name, workspace.members), None
|
||||||
)
|
)
|
||||||
|
members_list = [
|
||||||
|
{
|
||||||
|
"name": k.user_name,
|
||||||
|
"status": k.status,
|
||||||
|
"id": k.user_id,
|
||||||
|
"role": k.role_displayname,
|
||||||
|
"num_env": k.num_environment_roles,
|
||||||
|
"edit_link": url_for(
|
||||||
|
"workspaces.view_member", workspace_id=workspace.id, member_id=k.user_id
|
||||||
|
),
|
||||||
|
}
|
||||||
|
for k in workspace.members
|
||||||
|
]
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"workspaces/members/index.html", workspace=workspace, new_member=new_member
|
"workspaces/members/index.html",
|
||||||
|
workspace=workspace,
|
||||||
|
choices=WORKSPACE_ROLE_DEFINITIONS,
|
||||||
|
members=members_list,
|
||||||
|
new_member=new_member,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
40
js/components/forms/members_list.js
Normal file
40
js/components/forms/members_list.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'members-list',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
members: Array,
|
||||||
|
choices: Array,
|
||||||
|
},
|
||||||
|
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
searchValue: '',
|
||||||
|
status: '',
|
||||||
|
role: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
searchedList: function () {
|
||||||
|
return this.members.filter(
|
||||||
|
member => this.status ?
|
||||||
|
member.status === this.status | this.status === 'all'
|
||||||
|
: true
|
||||||
|
).filter(
|
||||||
|
member => this.role ? (
|
||||||
|
this.getRoleFromDisplayName(member.role) === this.role | this.role === 'all')
|
||||||
|
: true
|
||||||
|
).filter(
|
||||||
|
member => this.searchValue ? member.name.toLowerCase()
|
||||||
|
.includes(this.searchValue.toLowerCase()) : true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getRoleFromDisplayName: function (role) {
|
||||||
|
return this.choices.find(choice => choice.display_name === role).name
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
@@ -20,6 +20,7 @@ import selector from './components/selector'
|
|||||||
import BudgetChart from './components/charts/budget_chart'
|
import BudgetChart from './components/charts/budget_chart'
|
||||||
import SpendTable from './components/tables/spend_table'
|
import SpendTable from './components/tables/spend_table'
|
||||||
import CcpoApproval from './components/forms/ccpo_approval'
|
import CcpoApproval from './components/forms/ccpo_approval'
|
||||||
|
import MembersList from './components/forms/members_list'
|
||||||
import LocalDatetime from './components/local_datetime'
|
import LocalDatetime from './components/local_datetime'
|
||||||
|
|
||||||
Vue.use(VTooltip)
|
Vue.use(VTooltip)
|
||||||
@@ -41,6 +42,7 @@ const app = new Vue({
|
|||||||
BudgetChart,
|
BudgetChart,
|
||||||
SpendTable,
|
SpendTable,
|
||||||
CcpoApproval,
|
CcpoApproval,
|
||||||
|
MembersList,
|
||||||
LocalDatetime,
|
LocalDatetime,
|
||||||
EditEnvironmentRole,
|
EditEnvironmentRole,
|
||||||
EditProjectRoles,
|
EditProjectRoles,
|
||||||
|
@@ -45,39 +45,41 @@
|
|||||||
) }}
|
) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<form class='search-bar'>
|
|
||||||
|
<members-list inline-template id="search-template" v-bind:members='{{ members | tojson}}' v-bind:choices='{{ choices | tojson}}'>
|
||||||
|
<div>
|
||||||
|
<form class='search-bar' @submit.prevent>
|
||||||
<div class='usa-input search-input'>
|
<div class='usa-input search-input'>
|
||||||
<label for='members-search'>Search members by name</label>
|
<label for='members-search'>Search members by name</label>
|
||||||
<input type='search' id='members-search' name='members-search' placeholder="Search by name"/>
|
<input v-model='searchValue' type='search' id='members-search' name='members-search' placeholder="Search by name"/>
|
||||||
<button type="submit">
|
<button type="button"></button>
|
||||||
<span class="hide">Search</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='usa-input filter-input'>
|
<div class='usa-input filter-input'>
|
||||||
<label for='filter-status'>Filter members by status</label>
|
<label for='filter-status'>Filter members by status</label>
|
||||||
<select id="filter-status" name="filter-status">
|
<select v-model="status" id="filter-status" name="filter-status">
|
||||||
<option value="" selected disabled>Filter by status</option>
|
<option value="" selected disabled>Filter by status</option>
|
||||||
<option value="">Active</option>
|
<option value="all">View All</option>
|
||||||
<option value="">Pending</option>
|
<option value="active">Active</option>
|
||||||
<option value="">Denied</option>
|
<option value="pending">Pending</option>
|
||||||
|
<option value="denied">Denied</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='usa-input filter-input'>
|
<div class='usa-input filter-input'>
|
||||||
<label for='filter-role'>Filter members by role</label>
|
<label for='filter-role'>Filter members by role</label>
|
||||||
<select id="filter-role" name="filter-role">
|
<select v-model="role" id="filter-role" name="filter-role">
|
||||||
<option value="" selected disabled>Filter by role</option>
|
<option value="" selected disabled>Filter by role</option>
|
||||||
<option value="">Admin</option>
|
<option value="all">View All</option>
|
||||||
<option value="">CCPO</option>
|
{% for role in choices %}
|
||||||
<option value="">Developer</option>
|
<option value='{{ role.name }}'>{{ role.display_name }}</option>
|
||||||
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
<div class='responsive-table-wrapper'>
|
<div class='responsive-table-wrapper'>
|
||||||
<table>
|
<table v-if='searchedList && searchedList.length'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" width="50%">Name</th>
|
<th scope="col" width="50%">Name</th>
|
||||||
@@ -86,23 +88,35 @@
|
|||||||
<th scope="col">Workspace Role</th>
|
<th scope="col">Workspace Role</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for m in workspace.members %}
|
<tr v-for='member in searchedList'>
|
||||||
{% set num_environment_roles = m.num_environment_roles %}
|
<td>
|
||||||
<tr>
|
<a :href="member.edit_link" class="icon-link icon-link--large" v-html="member.name"></a>
|
||||||
<td><a href="{{ url_for('workspaces.update_member', workspace_id=workspace.id, member_id=m.user_id) }}" class="icon-link icon-link--large">{{ m.user_name }}</a></td>
|
</td>
|
||||||
{% if num_environment_roles %}
|
<td class="table-cell--align-right" v-if='member.num_env'>
|
||||||
<td class="table-cell--align-right">{{ num_environment_roles }}</td>
|
<span v-html="member.num_env"></span>
|
||||||
{% else %}
|
</td>
|
||||||
<td class='table-cell--shrink'><span class="label label--info">No Environment Access</span></td>
|
<td class='table-cell--shrink' v-else>
|
||||||
{% endif %}
|
<span class="label label--info">No Environment Access</span>
|
||||||
<td>{{ m.status }}</a></td>
|
</td>
|
||||||
<td>{{ m.role_displayname }}</a></td>
|
<td v-html="member.status"></td>
|
||||||
|
<td v-html="member.role"></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<div v-else>
|
||||||
|
{{ EmptyState(
|
||||||
|
'No members found.',
|
||||||
|
action_label=None,
|
||||||
|
action_href=None,
|
||||||
|
sub_message='Please try a different search.',
|
||||||
|
icon=None
|
||||||
|
) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</members-list>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user