Sortable listing of task orders on funding page

This commit is contained in:
Patrick Smith 2019-01-15 17:30:33 -05:00
parent a6a53525f8
commit e92ee12f20
3 changed files with 169 additions and 10 deletions

View File

@ -0,0 +1,102 @@
import { set } from 'vue/dist/vue'
import { compose, sortBy, reverse, indexBy, prop, toLower } from 'ramda'
import { formatDollars } from '../../lib/dollars'
import localDatetime from '../../components/local_datetime'
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 {
name: 'task-order-list',
props: {
data: Array
},
components: {
localDatetime
},
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: 'Status',
attr: 'display_status',
},
{
displayName: 'Period of Performance',
attr: 'start_date',
sortFunc: numericSort,
width: "50%"
},
{
displayName: 'Initial Value',
attr: 'budget',
class: "table-cell--align-right",
sortFunc: numericSort
},
{
displayName: 'Balance',
attr: 'budget',
class: "table-cell--align-right",
sortFunc: numericSort
},
{
displayName: ''
}
]
const defaultSortColumn = 'Period of Performance'
return {
sortInfo: {
columnName: defaultSortColumn,
isAscending: false,
columns: indexBy(prop('displayName'), columns)
}
}
},
computed: {
taskOrders: function () {
return sort(this.sortInfo, this.data)
}
},
methods: {
updateSort: function(columnName) {
// 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)
},
formatDollars: function (value) {
return formatDollars(value, false)
}
},
template: '<div></div>'
}

View File

@ -21,6 +21,7 @@ import Modal from './mixins/modal'
import selector from './components/selector'
import BudgetChart from './components/charts/budget_chart'
import SpendTable from './components/tables/spend_table'
import TaskOrderList from './components/tables/task_order_list.js'
import CcpoApproval from './components/forms/ccpo_approval'
import MembersList from './components/members_list'
import LocalDatetime from './components/local_datetime'
@ -48,6 +49,7 @@ const app = new Vue({
selector,
BudgetChart,
SpendTable,
TaskOrderList,
CcpoApproval,
MembersList,
LocalDatetime,

View File

@ -6,13 +6,72 @@
{% block portfolio_content %}
{% macro ViewLink(task_order) %}
<a href="{{ url_for('portfolios.view_task_order', portfolio_id=portfolio.id, task_order_id=task_order.id) }}" class="icon-link view-task-order-link">
<span>View</span>
{{ Icon("caret_right") }}
</a>
{% endmacro %}
{% macro TaskOrderList(task_orders, label='success') %}
<task-order-list
inline-template
v-bind:data='{{ task_orders | tojson }}'
v-cloak
>
<div class='responsive-table-wrapper'>
<table v-cloak>
<thead>
<tr>
<th v-for="col in getColumns()" @click="updateSort(col.displayName)" :width="col.width" :class="col.class" scope="col">
!{ col.displayName }
<template v-if="col.sortFunc">
<span v-if="col.displayName === sortInfo.columnName && sortInfo.isAscending">
{{ Icon("caret_down") }}
</span>
<span v-if="col.displayName === sortInfo.columnName && !sortInfo.isAscending">
{{ Icon("caret_up") }}
</span>
</template>
</th>
</tr>
</thead>
<tbody>
<tr v-for='taskOrder in taskOrders' :key="taskOrder.id">
<td>
<span class='label label--{{ label }}'>!{ taskOrder.display_status }</span>
</td>
<td class='table-cell--grow'>
<span>
<local-datetime
v-bind:timestamp="taskOrder.start_date"
format="M/D/YYYY">
</local-datetime>
-
<local-datetime
v-bind:timestamp="taskOrder.end_date"
format="M/D/YYYY">
</local-datetime>
</td>
<td class="table-cell--align-right">
<span v-html='formatDollars(taskOrder.budget)'></span>
</td>
<td class="table-cell--align-right">
<span v-html='formatDollars(taskOrder.budget)'></span>
</td>
<td>
<a v-bind:href="taskOrder.url" class="icon-link view-task-order-link">
<span>View</span>
{{ Icon("caret_right") }}
</a>
</td>
</tr>
</tbody>
</table>
</div>
</task-order-list>
{% endmacro %}
<div class="portfolio-funding">
{% for task_order in pending_task_orders %}
<div class='panel'>
@ -46,16 +105,12 @@
) }}
{% endif %}
<ul>
{% for task_order in portfolio.task_orders %}
<li class='block-list__item'>
<a href='{{ url_for("portfolios.view_task_order", portfolio_id=portfolio.id, task_order_id=task_order.id)}}'>
<span>{{ task_order.start_date }} - {{ task_order.end_date }}</span>
</a>
</li>
{% endfor %}
</ul>
{% if active_task_orders %}
{{ TaskOrderList(active_task_orders, label='success') }}
{% endif %}
{% if expired_task_orders %}
{{ TaskOrderList(expired_task_orders, label='') }}
{% endif %}
</div>