Merge pull request #423 from dod-ccpo/sort-members
Sort workspace members list
This commit is contained in:
commit
0c7fb4ca9b
@ -1,3 +1,50 @@
|
|||||||
|
import { compose, sortBy, reverse, indexBy, partial, prop, pipe, toLower } from 'ramda'
|
||||||
|
|
||||||
|
const search = (query, members) => {
|
||||||
|
if (query === '' || query === 'all') {
|
||||||
|
return members
|
||||||
|
} else {
|
||||||
|
const normalizedQuery = query.toLowerCase()
|
||||||
|
return members.filter(
|
||||||
|
(member) => member.name.toLowerCase().includes(normalizedQuery)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const filterByStatus = (status, members) => {
|
||||||
|
if (status === '' || status === 'all') {
|
||||||
|
return members
|
||||||
|
} else {
|
||||||
|
return members.filter(
|
||||||
|
(member) => member.status === status
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const filterByRole = (role, rolesByDisplayname, members) => {
|
||||||
|
const getRoleNameFromDisplayName = (_role) => rolesByDisplayname[_role].name
|
||||||
|
|
||||||
|
if (role === '' || role === 'all') {
|
||||||
|
return members
|
||||||
|
} else {
|
||||||
|
return members.filter(
|
||||||
|
(member) => getRoleNameFromDisplayName(member.role) === role
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sort = (sortInfo, members) => {
|
||||||
|
if (sortInfo.columnName === '') {
|
||||||
|
return members
|
||||||
|
} else {
|
||||||
|
const sortColumn = sortInfo.columns[sortInfo.columnName]
|
||||||
|
const sortedMembers = sortColumn.sortFunc(sortColumn.attr, members)
|
||||||
|
|
||||||
|
return sortInfo.isAscending ?
|
||||||
|
sortedMembers :
|
||||||
|
reverse(sortedMembers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'members-list',
|
name: 'members-list',
|
||||||
@ -8,33 +55,73 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
|
const alphabeticalSort = (attr, members) => {
|
||||||
|
const lowercaseProp = compose(toLower, prop(attr))
|
||||||
|
return sortBy(lowercaseProp, members)
|
||||||
|
}
|
||||||
|
|
||||||
|
const numericSort = (attr, members) => sortBy(prop(attr), members)
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
displayName: 'Name',
|
||||||
|
attr: 'name',
|
||||||
|
sortFunc: alphabeticalSort,
|
||||||
|
width: "50%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Environments',
|
||||||
|
attr: 'num_env',
|
||||||
|
sortFunc: numericSort,
|
||||||
|
class: "table-cell--align-right"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
attr: 'status',
|
||||||
|
sortFunc: alphabeticalSort
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Workspace Role',
|
||||||
|
attr: 'role',
|
||||||
|
sortFunc: alphabeticalSort
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
searchValue: '',
|
searchValue: '',
|
||||||
status: '',
|
status: '',
|
||||||
role: '',
|
role: '',
|
||||||
|
rolesByDisplayName: indexBy(prop('display_name'), this.choices),
|
||||||
|
sortInfo: {
|
||||||
|
columnName: '',
|
||||||
|
isAscending: true,
|
||||||
|
columns: indexBy(prop('displayName'), columns)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
searchedList: function () {
|
searchedList: function () {
|
||||||
return this.members.filter(
|
return pipe(
|
||||||
member => this.status ?
|
partial(search, [this.searchValue]),
|
||||||
member.status === this.status | this.status === 'all'
|
partial(filterByStatus, [this.status]),
|
||||||
: true
|
partial(filterByRole, [this.role, this.rolesByDisplayName]),
|
||||||
).filter(
|
partial(sort, [this.sortInfo])
|
||||||
member => this.role ? (
|
)(this.members)
|
||||||
this.getRoleFromDisplayName(member.role) === this.role | this.role === 'all')
|
|
||||||
: true
|
|
||||||
).filter(
|
|
||||||
member => this.searchValue ? member.name.toLowerCase()
|
|
||||||
.includes(this.searchValue.toLowerCase()) : true
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
getRoleFromDisplayName: function (role) {
|
updateSort: function(columnName) {
|
||||||
return this.choices.find(choice => choice.display_name === role).name
|
// clicking a column twice toggles ascending / descending
|
||||||
|
if (columnName === this.sortInfo.columnName) {
|
||||||
|
this.sortInfo.isAscending = !this.sortInfo.isAscending
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sortInfo.columnName = columnName
|
||||||
},
|
},
|
||||||
},
|
getColumns: function() {
|
||||||
|
return Object.values(this.sortInfo.columns)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
{% from "components/empty_state.html" import EmptyState %}
|
{% from "components/empty_state.html" import EmptyState %}
|
||||||
{% from "components/alert.html" import Alert %}
|
{% from "components/alert.html" import Alert %}
|
||||||
|
{% from "components/icon.html" import Icon %}
|
||||||
|
|
||||||
{% block workspace_content %}
|
{% block workspace_content %}
|
||||||
|
|
||||||
@ -82,10 +83,15 @@
|
|||||||
<table v-if='searchedList && searchedList.length'>
|
<table v-if='searchedList && searchedList.length'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" width="50%">Name</th>
|
<th v-for="col in getColumns()" @click="updateSort(col.displayName)" :width="col.width" :class="col.class" scope="col">
|
||||||
<th scope="col" class="table-cell--align-right">Environments</th>
|
!{ col.displayName }
|
||||||
<th scope="col">Status</th>
|
<span v-if="col.displayName === sortInfo.columnName && sortInfo.isAscending">
|
||||||
<th scope="col">Workspace Role</th>
|
{{ Icon("caret_down") }}
|
||||||
|
</span>
|
||||||
|
<span v-if="col.displayName === sortInfo.columnName && !sortInfo.isAscending">
|
||||||
|
{{ Icon("caret_up") }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user