Skip to content

Commit

Permalink
Add organization page
Browse files Browse the repository at this point in the history
The organization page means we can also link to the org from the
proposal view instead of rendering the full org data

Issue #35
  • Loading branch information
slifty committed Oct 1, 2021
1 parent d40d2e4 commit 2c5aa2d
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 72 deletions.
17 changes: 17 additions & 0 deletions cgap/blueprints/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ def updateOrganization(organization_id):
))


@bp.route('/organizations/<int:organization_id>/proposals', methods=['GET'])
def getProposalsByOrganizationId(organization_id):
query = Proposal.select(
Proposal,
Organization,
).join(
Organization,
attr='organization'
).where(
Proposal.organization_id == organization_id,
)

print(organization_id)
proposals = [model_to_dict(proposal, recurse=True) for proposal in query]
return json.dumps(proposals, default=str)


@bp.route('/proposals/', methods=['GET'])
def getProposals():
query = Proposal.select(
Expand Down
6 changes: 5 additions & 1 deletion cgap/blueprints/ux.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,9 @@ def apidoc():
return render_template('apidoc.html')

@bp.route('/proposal/<int:proposal_id>', methods=('GET', 'POST'))
def view(proposal_id):
def viewProposal(proposal_id):
return render_template('proposal.html', proposal_id=proposal_id)

@bp.route('/organization/<int:organization_id>', methods=('GET', 'POST'))
def viewOrganization(organization_id):
return render_template('organization.html', organization_id=organization_id)
162 changes: 162 additions & 0 deletions cgap/static/organization.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
const app = Vue.createApp({});

function hasMatch(firstString, secondString) {
return firstString.toLowerCase().indexOf(secondString.toLowerCase()) >= 0;
}

app.component('Organization', {
props: ['organizationId'],
data: function() {
return {
organization: {
'name': '',
'mission_statement': '',
'website': '',
'entity_type': '',
'registration_number': '',
'address': '',
'phone': '',
'email': '',
'dba_name': '',
'ceo_name': '',
'ceo_title': '',
'ceo_address': '',
'operating_budget': '',
'is_lobbying': '',
'start_date': '',
'grant_agreement_signatory': '',
'fiscal_end_date': '',
},
proposals: [],
}
},
mounted() {
this.loadOrganization();
this.loadProposals();
},
computed: {},
methods: {
generateProposalViewUrl(id) {
return `/proposal/${id}`;
},
loadOrganization(query) {
try {
const url = `/api/organizations/${this.organizationId}`
var request = new XMLHttpRequest();
request.open('GET', url, true);

var context = this
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
context.organization = JSON.parse(this.response);
}
};

request.onerror = function() {
console.log('Could not load organization data.');
};

request.send();
} catch {}
},
loadProposals(query) {
try {
const url = `/api/organizations/${this.organizationId}/proposals`
var request = new XMLHttpRequest();
request.open('GET', url, true);

var context = this
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
context.proposals = JSON.parse(this.response);
}
};

request.onerror = function() {
console.log('Could not load organization proposals.');
};

request.send();
} catch {}
},
},

template: `
<h1>Organization (#{{organization.id}})</h1>
<h2>Organization Fields</h2>
<table class="table">
<thead>
<tr>
<th scope="col">Field</th>
<th scope="col">Value</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Organization Name</th>
<td>{{organization.name}}</td>
</tr>
<tr>
<th scope="row">Organization Mission Statement</th>
<td>{{organization.mission_statement}}</td>
</tr>
<tr>
<th scope="row">Organization Website</th>
<td>{{organization.website}}</td>
</tr>
<tr>
<th scope="row">Organization Entity Type</th>
<td>{{organization.entity_type}}</td>
</tr>
<tr>
<th scope="row">Organization Registration Number</th>
<td>{{organization.registration_number}}</td>
</tr>
<tr>
<th scope="row">Organization Address</th>
<td>{{organization.address}}</td>
</tr>
<tr>
<th scope="row">Organization Phone</th>
<td>{{organization.phone}}</td>
</tr>
<tr>
<th scope="row">Organization Email</th>
<td>{{organization.email}}</td>
</tr>
<tr>
<th scope="row">Organization DBA</th>
<td>{{organization.dba_name}}</td>
</tr>
<tr>
<th scope="row">Organization CEO</th>
<td>{{organization.ceo_name}}</td>
</tr>
<tr>
<th scope="row">Operating Budget</th>
<td>{{organization.operating_budget}}</td>
</tr>
<tr>
<th scope="row">Lobbying Activity</th>
<td>{{organization.is_lobbying}}</td>
</tr>
<tr>
<th scope="row">Organization Start Date</th>
<td>{{organization.start_date}}</td>
</tr>
<tr>
<th scope="row">Organization Signatory</th>
<td>{{organization.grant_agreement_signatory}}</td>
</tr>
<tr>
<th scope="row">Organization Fiscal End Date</th>
<td>{{organization.fiscal_end_date}}</td>
</tr>
</tbody>
</table>
<h2>Proposals</h2>
<ul>
<li v-for="proposal in proposals"><a :href="generateProposalViewUrl(proposal.id)">{{proposal.name}}</a></li>
</ul>
`
})
74 changes: 3 additions & 71 deletions cgap/static/proposal.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,13 @@ app.component('Proposal', {
request.send();
} catch {}
},
handleInput(event) {
this.fetchProposals(event.target.value);
generateOrganizationViewUrl(id) {
return `/organization/${id}`;
}
},

template: `
<h1>Proposal (#{{proposal.id}})</h1>
<h2>Organization Fields</h2>
<table class="table">
<thead>
<tr>
Expand All @@ -84,75 +83,8 @@ app.component('Proposal', {
<tbody>
<tr>
<th scope="row">Organization Name</th>
<td>{{proposal.organization.name}}</td>
<td>{{proposal.organization.name}} <a :href="generateOrganizationViewUrl(proposal.organization.id)">(View)</a></td>
</tr>
<tr>
<th scope="row">Organization Mission Statement</th>
<td>{{proposal.organization.mission_statement}}</td>
</tr>
<tr>
<th scope="row">Organization Website</th>
<td>{{proposal.organization.website}}</td>
</tr>
<tr>
<th scope="row">Organization Entity Type</th>
<td>{{proposal.organization.entity_type}}</td>
</tr>
<tr>
<th scope="row">Organization Registration Number</th>
<td>{{proposal.organization.registration_number}}</td>
</tr>
<tr>
<th scope="row">Organization Address</th>
<td>{{proposal.organization.address}}</td>
</tr>
<tr>
<th scope="row">Organization Phone</th>
<td>{{proposal.organization.phone}}</td>
</tr>
<tr>
<th scope="row">Organization Email</th>
<td>{{proposal.organization.email}}</td>
</tr>
<tr>
<th scope="row">Organization DBA</th>
<td>{{proposal.organization.dba_name}}</td>
</tr>
<tr>
<th scope="row">Organization CEO</th>
<td>{{proposal.organization.ceo_name}}</td>
</tr>
<tr>
<th scope="row">Operating Budget</th>
<td>{{proposal.organization.operating_budget}}</td>
</tr>
<tr>
<th scope="row">Lobbying Activity</th>
<td>{{proposal.organization.is_lobbying}}</td>
</tr>
<tr>
<th scope="row">Organization Start Date</th>
<td>{{proposal.organization.start_date}}</td>
</tr>
<tr>
<th scope="row">Organization Signatory</th>
<td>{{proposal.organization.grant_agreement_signatory}}</td>
</tr>
<tr>
<th scope="row">Organization Fiscal End Date</th>
<td>{{proposal.organization.fiscal_end_date}}</td>
</tr>
</tbody>
</table>
<h2>Proposal Fields</h2>
<table class="table">
<thead>
<tr>
<th scope="col">Field</th>
<th scope="col">Value</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Submission Date</th>
<td>{{proposal.created}}</td>
Expand Down
16 changes: 16 additions & 0 deletions cgap/templates/organization.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% extends 'base.html' %}

{% block head %}
<script type="text/javascript" src="{{ url_for('static', filename='organization.js') }}"></script>
{% endblock %}

{% block title %}View Organization{% endblock %}

{% block content %}
<div id="app">
<organization organization-id="{{ organization_id }}"></organization>
</div>
<script type="text/javascript">
app.mount('#app')
</script>
{% endblock %}

0 comments on commit 2c5aa2d

Please sign in to comment.