Skip to content

Commit

Permalink
adds more information about portfolio requests/grants
Browse files Browse the repository at this point in the history
  • Loading branch information
smirolo committed Jul 23, 2024
1 parent b7f705b commit 8199210
Show file tree
Hide file tree
Showing 8 changed files with 369 additions and 219 deletions.
1 change: 1 addition & 0 deletions djaopsp/jinja2.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def environment(**options):
env.filters['host'] = deployutils_extratags.host
env.filters['is_authenticated'] = deployutils_extratags.is_authenticated
env.filters['date'] = djaopsp_tags.date
env.filters['humanizeDate'] = djaopsp_tags.humanizeDate
env.filters['humanizeTimeDelta'] = djaopsp_tags.humanizeTimeDelta
env.filters['md'] = pages_tags.md
env.filters['messages'] = djaopsp_tags.messages
Expand Down
119 changes: 84 additions & 35 deletions djaopsp/static/js/assess-vue.js
Original file line number Diff line number Diff line change
Expand Up @@ -1090,13 +1090,16 @@ Vue.component('scorecard', {
*/
Vue.component('scorecard-requests', {
mixins: [
itemListMixin
itemListMixin,
accountDetailMixin
],
data: function() {
return {
url: this.$urls.api_requests,
params: {state: "request-initiated"},
api_profiles_url: this.$urls.api_organizations,
api_accounts_url: this.$urls.api_organizations,
api_sample_list_url: this.$urls.api_sample_list,
api_portfolios_grants_url: this.$urls.survey_api_portfolios_grants,
getCompleteCb: 'getCompleted',
byCampaigns: {}
}
Expand All @@ -1106,38 +1109,32 @@ Vue.component('scorecard-requests', {
var vm = this;
vm.reqPost(portfolio.api_accept,
function(resp) { // success
vm.items.results.splice(idx, 1);
vm.showMessages(
["You have accepted the request(s)."],
"success");
portfolio.done = true;
vm.$forceUpdate();
});
},
ignore: function(portfolio, idx) {
var vm = this;
vm.reqDelete(portfolio.api_accept,
function(resp) { // success
vm.items.results.splice(idx, 1);
vm.showMessages(
["You have denied the request(s)."],
"success");
});
},
getCompleted: function(){
var vm = this;
vm.mergeResults = false;
const profiles = new Set();
vm.byCampaigns = {};
for( let idx =0; idx < vm.items.results.length; ++idx ) {
const item = vm.items.results[idx];
profiles.add(item.grantee);
const campaign =
item.campaign.slug ? item.campaign.slug : item.campaign;
if( !(campaign in vm.byCampaigns) ) {
vm.byCampaigns[campaign] = {
vm.$set(vm.byCampaigns, campaign, {
campaign: item.campaign,
expected_behavior: 'share',//'share', 'update', 'create'
requests: []
};
requests: [],
grantCandidates: []
});
}
if( item.expected_behavior === 'update' &&
vm.byCampaigns[campaign].expected_behavior === 'share' ) {
Expand All @@ -1149,33 +1146,66 @@ Vue.component('scorecard-requests', {
}
vm.byCampaigns[campaign].requests.push(item);
}
if( profiles.size > 0 ) {
let queryParams = "?q_f==slug&q=";
let sep = "";
for( const profile of profiles ) {
queryParams += sep + profile;
sep = ",";
}
vm.reqGet(vm.api_profiles_url + queryParams,
if( vm.api_sample_list_url ) {
vm.reqGet(vm.api_sample_list_url,{state: 'completed'},
function(resp) {
let profiles = {}
for( let idx = 0; idx < resp.results.length; ++idx ) {
const item = resp.results[idx];
profiles[item.slug] = item;
}
for( let idx =0; idx < vm.items.results.length; ++idx ) {
const item = vm.items.results[idx];
if( item.grantee in profiles ) {
item.grantee = profiles[item.grantee];
for( let idx = 0; idx < resp.results.length; ++idx ) {
const item = resp.results[idx];
const campaign = item.campaign.slug ?
item.campaign.slug : item.campaign;
if( !(campaign in vm.byCampaigns) ) {
vm.$set(vm.byCampaigns, campaign, {
campaign: item.campaign,
last_completed_at: item.created_at,
expected_behavior: 'share',
requests: [],
grantCandidates: []
});
}
if( !vm.byCampaigns[campaign].last_completed_at ||
vm.byCampaigns[campaign].last_completed_at
< item.created_at) {
vm.byCampaigns[campaign].last_completed_at =
item.created_at;
}
for( let gdx = 0; gdx < item.grantees.length;
++gdx ) {
// Implementation Note: We rely on the API
// returning a list sorted by `created_at` here.
if( item.created_at <
vm.byCampaigns[campaign].last_completed_at ) {
vm.byCampaigns[campaign].grantCandidates.push({
grantee: item.grantees[gdx],
last_shared_at: item.created_at
});
}
}
}
for(fieldName in vm.byCampaigns) {
if( vm.byCampaigns.hasOwnProperty(fieldName) ) {
const campaign = vm.byCampaigns[fieldName];
vm.populateAccounts(
campaign.grantCandidates, 'grantee');
}
}
vm.$forceUpdate();
}, function() {
// Fail silently and run in degraded mode if we cannot load
// the profile information (picture, etc.)
});
}
vm.populateAccounts(vm.items.results, 'grantee');
},
submitGrant: function(candidate, campaign) {
var vm = this;
vm.reqPost(vm.api_portfolios_grants_url, {
grantee: {slug: candidate.grantee}, campaign:campaign.slug},
function(resp) { // success
candidate.done = true;
vm.$forceUpdate();
});
},
},
computed: {
hasPendingRequests: function() {
return Object.keys(this.byCampaigns).length > 0;
}
},
mounted: function(){
this.get();
Expand Down Expand Up @@ -2121,3 +2151,22 @@ Vue.component('respondents-list', {
this.get()
}
});


Vue.component('decorate-profiles', {
mixins: [
httpRequestMixin,
accountDetailMixin
],
data: function() {
return {
api_accounts_url: this.$urls.api_accounts,
}
},
mounted: function(){
var vm = this;
if( vm.$el.dataset && vm.$el.dataset.elements ) {
vm.populateAccounts(JSON.parse(vm.$el.dataset.elements), 'grantee');
}
}
});
46 changes: 31 additions & 15 deletions djaopsp/templates/app/assess/redirects.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,49 @@ <h5>{{assessment.title}}
<div class="card-body">
{% if assessment.last_completed_at %}
<p>
{{profile.printable_name}} last completed {{assessment.title}} questionnaire on {{assessment.last_completed_at|date}}{% if assessment.author %} by <span class="author">{{assessment.author}}</span>{% endif %}
{{profile.printable_name}} last completed {{assessment.title}} questionnaire on {{assessment.last_completed_at|date}}{% if assessment.respondents %} by{% for user in assessment.respondents %} <span class="author">{{user.get_full_name()}}</span>{{ ", " if not loop.last else "" }}{% endfor %}{% endif %}
</p>
{% endif %}
<p>
{% if profile.ends_at %}
{% trans profile=profile.printable_name, ends_at=profile.ends_at|humanizeDate %}The following organizations would like a copy of your response before {{ends_at}}.{% endtrans %}
{% else %}
{% trans profile=profile.printable_name %}The following organizations would like a copy of your response.{% endtrans %}
{% endif %}
</p>
{% for request in assessment.grantees %}
<div>
<div class="row align-items-center">
<div class="col-2">
<img class="img-fluid" style="max-height:64px;" src="{{'/static/img/default-organization.png'|asset}}" >
</div>
<div class="col-5">
{{request.grantee.slug}}
<decorate-profiles data-elements='{{assessment.requests|to_json}}' inline-template>
<div>
{% for request in assessment.requests %}
<div>
<div class="row align-items-center">
<div class="col-2">
<img class="img-fluid" style="max-height:64px;" :src="getAccountPicture('{{request.grantee}}') ? getAccountPicture('{{request.grantee}}') : '{{'/static/img/default-organization.png'|asset}}'" >
</div>
<div class="col-5">
[[getAccountPrintableName('{{request.grantee}}')]]
<div>
<small>on {{request.created_at|date}}
({{request.created_at|humanizeTimeDelta}})</small>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
<small> - on {{request.created_at|date}}
({{request.created_at|humanizeTimeDelta}})</small>
</div>
{% endfor %}
</decorate-profiles>
</div>{# /.card-body #}
<div class="card-footer">
<div class="row">
<div class="col-md-6 text-center">
{% if assessment.share_url %}
<a class="btn btn-primary my-2"
href="{{assessment.share_url}}">{% trans %}Share{% endtrans %}</a>
href="{{assessment.share_url}}">{% trans created_at=assessment.last_completed_at|date %}Share {{created_at}} assessment{% endtrans %}</a>
{% endif %}
</div>
<div class="col-md-6 text-center">
{% if assessment.update_url %}
<a class="btn btn-primary my-2"
href="{{assessment.update_url}}">{% if assessment.share_url %}{% trans %}Update{% endtrans %}{% else %}{% trans %}Continue{% endtrans %}{% endif %}</a>
href="{{assessment.update_url}}">{% if assessment.share_url %}{% trans %}Update with new information{% endtrans %}{% else %}{% trans %}Continue{% endtrans %}{% endif %}</a>
{% else %}
<form action="." method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{csrf_token}}">
Expand All @@ -58,6 +68,12 @@ <h5>{{assessment.title}}
</div>{# /.card-footer #}
</div>
{% endfor %}
<hr />
<p class="mt-4">
{% trans %}This Website provides additional questionnaires on which to assess
your organizations performance on a variety of qualitative and quantitative
metrics.{% endtrans %} <a href="{{'docs/guides/'|site_url}}">{% trans %}See questionnaires{% endtrans %} &raquo;</a>
</p>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 8199210

Please sign in to comment.