Sortable listing of task orders on funding page
This commit is contained in:
parent
a6a53525f8
commit
e92ee12f20
102
js/components/tables/task_order_list.js
Normal file
102
js/components/tables/task_order_list.js
Normal 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>'
|
||||||
|
}
|
@ -21,6 +21,7 @@ import Modal from './mixins/modal'
|
|||||||
import selector from './components/selector'
|
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 TaskOrderList from './components/tables/task_order_list.js'
|
||||||
import CcpoApproval from './components/forms/ccpo_approval'
|
import CcpoApproval from './components/forms/ccpo_approval'
|
||||||
import MembersList from './components/members_list'
|
import MembersList from './components/members_list'
|
||||||
import LocalDatetime from './components/local_datetime'
|
import LocalDatetime from './components/local_datetime'
|
||||||
@ -48,6 +49,7 @@ const app = new Vue({
|
|||||||
selector,
|
selector,
|
||||||
BudgetChart,
|
BudgetChart,
|
||||||
SpendTable,
|
SpendTable,
|
||||||
|
TaskOrderList,
|
||||||
CcpoApproval,
|
CcpoApproval,
|
||||||
MembersList,
|
MembersList,
|
||||||
LocalDatetime,
|
LocalDatetime,
|
||||||
|
@ -6,13 +6,72 @@
|
|||||||
{% block portfolio_content %}
|
{% block portfolio_content %}
|
||||||
|
|
||||||
{% macro ViewLink(task_order) %}
|
{% 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">
|
<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>
|
<span>View</span>
|
||||||
{{ Icon("caret_right") }}
|
{{ Icon("caret_right") }}
|
||||||
</a>
|
</a>
|
||||||
{% endmacro %}
|
{% 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">
|
<div class="portfolio-funding">
|
||||||
{% for task_order in pending_task_orders %}
|
{% for task_order in pending_task_orders %}
|
||||||
<div class='panel'>
|
<div class='panel'>
|
||||||
@ -46,16 +105,12 @@
|
|||||||
) }}
|
) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<ul>
|
{% if active_task_orders %}
|
||||||
{% for task_order in portfolio.task_orders %}
|
{{ TaskOrderList(active_task_orders, label='success') }}
|
||||||
<li class='block-list__item'>
|
{% endif %}
|
||||||
<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 expired_task_orders %}
|
||||||
|
{{ TaskOrderList(expired_task_orders, label='') }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user