mirror of
https://git.wownero.com/wownero/wownero-funding-system.git
synced 2024-08-15 00:53:45 +00:00
Introduced a new proposal status: proposed. Moved some templates around and created macros.
This commit is contained in:
parent
29e5a9eb95
commit
b34d06d49e
11 changed files with 88 additions and 134 deletions
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
import socket
|
||||
import collections
|
||||
import os
|
||||
|
||||
|
||||
|
@ -33,3 +34,12 @@ FUNDING_CATEGORIES = [
|
|||
'misc',
|
||||
'design'
|
||||
]
|
||||
|
||||
FUNDING_STATUSES = collections.OrderedDict()
|
||||
FUNDING_STATUSES[0] = 'disabled'
|
||||
FUNDING_STATUSES[1] = 'proposal'
|
||||
FUNDING_STATUSES[2] = 'funding'
|
||||
FUNDING_STATUSES[3] = 'wip'
|
||||
FUNDING_STATUSES[4] = 'completed'
|
||||
|
||||
USER_REG_DISABLED = False
|
|
@ -10,7 +10,7 @@ from wowfunding.orm.orm import Proposal, User
|
|||
|
||||
@app.route('/api/1/proposals')
|
||||
@endpoint.api(
|
||||
parameter('status', type=int, location='args', default=0),
|
||||
parameter('status', type=int, location='args', default=1),
|
||||
parameter('cat', type=str, location='args'),
|
||||
parameter('limit', type=int, location='args', default=20),
|
||||
parameter('offset', type=int, location='args', default=0)
|
||||
|
|
|
@ -13,6 +13,7 @@ def templating():
|
|||
return dict(logged_in=current_user.is_authenticated,
|
||||
current_user=current_user,
|
||||
funding_categories=settings.FUNDING_CATEGORIES,
|
||||
funding_statuses=settings.FUNDING_STATUSES,
|
||||
summary_data=summary_data[1])
|
||||
|
||||
|
||||
|
@ -24,7 +25,7 @@ def fetch_summary(purge=False):
|
|||
|
||||
data = {}
|
||||
categories = settings.FUNDING_CATEGORIES
|
||||
statuses = [0, 1, 2]
|
||||
statuses = settings.FUNDING_STATUSES.keys()
|
||||
|
||||
for cat in categories:
|
||||
q = db_session.query(Proposal)
|
||||
|
|
|
@ -93,11 +93,12 @@ class Proposal(base):
|
|||
addr_receiving = sa.Column(sa.VARCHAR)
|
||||
|
||||
# proposal status:
|
||||
# -1: disabled
|
||||
# 0: proposed
|
||||
# 1: wip
|
||||
# 2: completed
|
||||
status = sa.Column(sa.INTEGER, default=0)
|
||||
# 0: disabled
|
||||
# 1: proposed
|
||||
# 2: funding required
|
||||
# 3: wip
|
||||
# 4: completed
|
||||
status = sa.Column(sa.INTEGER, default=1)
|
||||
|
||||
user_id = sa.Column(sa.Integer, sa.ForeignKey('users.user_id'))
|
||||
user = relationship("User", back_populates="proposals")
|
||||
|
@ -140,13 +141,18 @@ class Proposal(base):
|
|||
return
|
||||
|
||||
# check if we have a valid addr_donation generated. if not, make one.
|
||||
if not result.addr_donation:
|
||||
if not result.addr_donation and result.status >= 2:
|
||||
Proposal.generate_donation_addr(result)
|
||||
|
||||
comment_count = db_session.query(sa.func.count(Comment.id)).filter(Comment.proposal_id == result.id).scalar()
|
||||
setattr(result, 'comment_count', comment_count)
|
||||
return result
|
||||
|
||||
@property
|
||||
def comment_count(self):
|
||||
from wowfunding.factory import db_session
|
||||
q = db_session.query(sa.func.count(Comment.id))
|
||||
q = q.filter(Comment.proposal_id == self.id)
|
||||
return q.scalar()
|
||||
|
||||
def get_comments(self):
|
||||
from wowfunding.factory import db_session
|
||||
q = db_session.query(Comment)
|
||||
|
@ -231,13 +237,16 @@ class Proposal(base):
|
|||
return addr_donation['address']
|
||||
|
||||
@classmethod
|
||||
def find_by_args(cls, status:int = None, cat: str = None, limit: int = 20, offset=0):
|
||||
def find_by_args(cls, status: int = None, cat: str = None, limit: int = 20, offset=0):
|
||||
from wowfunding.factory import db_session
|
||||
if status is None or not status >= 0 or not status <= 2:
|
||||
raise NotImplementedError('missing status')
|
||||
if isinstance(status, int) and status not in settings.FUNDING_STATUSES.keys():
|
||||
raise NotImplementedError('invalid status')
|
||||
if isinstance(cat, str) and cat not in settings.FUNDING_CATEGORIES:
|
||||
raise NotImplementedError('invalid cat')
|
||||
|
||||
q = cls.query
|
||||
q = q.filter(Proposal.status == status)
|
||||
if isinstance(status, int):
|
||||
q = q.filter(Proposal.status == status)
|
||||
if cat:
|
||||
q = q.filter(Proposal.category == cat)
|
||||
q = q.order_by(Proposal.date_added.desc())
|
||||
|
@ -245,12 +254,7 @@ class Proposal(base):
|
|||
if isinstance(offset, int):
|
||||
q = q.offset(offset)
|
||||
|
||||
results = q.all()
|
||||
for result in results:
|
||||
comment_count = db_session.query(sa.func.count(Comment.id)).filter(
|
||||
Comment.proposal_id == result.id).scalar()
|
||||
setattr(result, 'comment_count', comment_count)
|
||||
return results
|
||||
return q.all()
|
||||
|
||||
@classmethod
|
||||
def search(cls, key: str):
|
||||
|
|
|
@ -130,6 +130,7 @@ def proposal_api_add(title, content, pid, funds_target, addr_receiving, category
|
|||
p.funds_target = funds_target
|
||||
p.addr_receiving = addr_receiving
|
||||
p.category = category
|
||||
p.status = 1
|
||||
db_session.add(p)
|
||||
|
||||
db_session.commit()
|
||||
|
@ -169,21 +170,30 @@ def user(name):
|
|||
user = q.first()
|
||||
return render_template('user.html', user=user)
|
||||
|
||||
|
||||
@app.route('/proposals')
|
||||
@endpoint.api(
|
||||
parameter('status', type=int, location='args', default=0),
|
||||
parameter('page', type=int, location='args'),
|
||||
parameter('cat', type=str, location='args')
|
||||
parameter('status', type=int, location='args', required=False),
|
||||
parameter('page', type=int, location='args', required=False),
|
||||
parameter('cat', type=str, location='args', required=False)
|
||||
)
|
||||
def proposals(status, page, cat):
|
||||
if not isinstance(status, int) and not isinstance(page, int) and not cat:
|
||||
# no args, render overview
|
||||
proposals = {
|
||||
'proposed': Proposal.find_by_args(status=1, limit=10),
|
||||
'funding': Proposal.find_by_args(status=2, limit=10),
|
||||
'wip': Proposal.find_by_args(status=3, limit=4)}
|
||||
return make_response(render_template('proposal/overview.html', proposals=proposals))
|
||||
|
||||
try:
|
||||
if not isinstance(status, int):
|
||||
status = 1
|
||||
proposals = Proposal.find_by_args(status=status, cat=cat)
|
||||
except:
|
||||
return make_response(redirect(url_for('proposals') + '?status=0'))
|
||||
|
||||
return make_response(render_template('proposals.html', proposals=proposals, status=status, cat=cat))
|
||||
return make_response(redirect(url_for('proposals')))
|
||||
|
||||
return make_response(render_template('proposal/proposals.html',
|
||||
proposals=proposals, status=status, cat=cat))
|
||||
|
||||
@app.route('/register', methods=['GET', 'POST'])
|
||||
def register():
|
||||
|
|
|
@ -99,6 +99,11 @@ body {
|
|||
font-size: 15px;
|
||||
}
|
||||
|
||||
.table-proposal tbody td:first-child{
|
||||
word-break: break-word;
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.table-hover tbody tr:hover {
|
||||
background-color: rgba(0,0,0,.075);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
function clickDataHref(d){
|
||||
window.location.href = d.getAttribute("data-href");
|
||||
function proposalNavbarclickDataHref(d){
|
||||
if(d.classList.contains('active')){
|
||||
// if the navbar button is already active, remove filter, go to proposals page
|
||||
window.location.href = '/proposals'
|
||||
} else {
|
||||
window.location.href = d.getAttribute("data-href");
|
||||
}
|
||||
}
|
||||
|
||||
function hideShow(element_id) {
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
<label for="category">Category</label>
|
||||
<select class="form-control" id="category" name="category">
|
||||
{% for cat in funding_categories %}
|
||||
<option value="{{cat}}"{% if cat == proposal.category %} selected{% endif %}>{{cat}}</option>
|
||||
<option value="{{cat}}"{% if proposal and cat == proposal.category %} selected{% endif %}>{{cat}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
23
wowfunding/templates/proposal/proposals.html
Normal file
23
wowfunding/templates/proposal/proposals.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% from 'proposal/macros/table.html' import proposal_table %}
|
||||
|
||||
<div class="container">
|
||||
{% include 'proposal/macros/navbar.html' %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
{% if proposals %}
|
||||
{{ proposal_table(title='', _proposals=proposals) }}
|
||||
{% else %}
|
||||
No proposals here yet.
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'sidebar.html' %}
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
</div>
|
||||
<!-- /.container -->
|
||||
{% endblock %}
|
|
@ -1,104 +0,0 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div class="col-lg-8" style="padding-bottom: 0px;">
|
||||
<div class="row">
|
||||
<div class="form-group" style="text-align: center;">
|
||||
<div>
|
||||
<div data-toggle="buttons" class="btn-group btn-group-toggle">
|
||||
<label onclick="clickDataHref(this);" data-href="{{ url_for('proposals', status=0) }}" class="btn btn-success {% if status == 0 %}active{% endif %}">
|
||||
Proposals <small>({{summary_data['statuses'][0]}})</small>
|
||||
</label>
|
||||
<label onclick="clickDataHref(this);" data-href="{{ url_for('proposals', status=1) }}" class="btn btn-success {% if status == 1 %}active{% endif %}">
|
||||
Work in progress <small>({{summary_data['statuses'][1]}})</small>
|
||||
</label>
|
||||
<label onclick="clickDataHref(this);" data-href="{{ url_for('proposals', status=2) }}" class="btn btn-success {% if status == 2 %}active{% endif %}">
|
||||
Completed <small>({{summary_data['statuses'][2]}})</small>
|
||||
</label>
|
||||
</div>
|
||||
<div id="point-wow-left">
|
||||
<img src="/static/point-left.png" style="margin-left: 10px;width: 60px;">
|
||||
<span style="color: #fc4dff;font-size: 16px;font-style: italic;font-weight: bold;margin-left: 6px;">wow</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if cat %}
|
||||
<small class="form-text text-muted" style="margin-top: -2px;">
|
||||
Results limited by category '{{cat}}'. <a href="{{ url_for('proposals', status=status) }}">Undo filter</a>.
|
||||
</small>
|
||||
<br>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
{% if proposals %}
|
||||
<table class="table table-proposal table-hover" style="margin-bottom:6px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="font-size: x-large;">Proposal</th>
|
||||
<th>Username</th>
|
||||
<th id="date">Date</th>
|
||||
{% if status == 0 %}
|
||||
<th style="text-align: right;">Funding</th>
|
||||
{% else %}
|
||||
<th></th>
|
||||
{% endif %}
|
||||
<th style="display: table-cell;text-align: center;">
|
||||
<img width="24" src="/static/msg.png">
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for p in proposals %}
|
||||
<tr>
|
||||
<td><b><a href="/proposal/{{ p.id }}">{{ p.headline }}</a></b></td>
|
||||
<td><a href="/user/{{ p.user.username }}">{{ p.user.username }}</a></td>
|
||||
<td id="date"><small>{{ p.date_added.strftime('%Y-%m-%d %H:%M') }}</small></td>
|
||||
<td>
|
||||
<span style="float:right;">
|
||||
{% if p.funds_progress >= 0.1 and status == 0 %}
|
||||
{{p.funds_progress|int}}%
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</span>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
{% if p.comment_count %}
|
||||
{{p.comment_count}}
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
No proposals here yet.
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'sidebar.html' %}
|
||||
</div>
|
||||
|
||||
<!--<div class="col-md-12">-->
|
||||
|
||||
<!--<!– Pagination –>-->
|
||||
<!--<ul class="pagination mb-4">-->
|
||||
<!--<li class="page-item">-->
|
||||
<!--<a class="page-link" href="#">← Older</a>-->
|
||||
<!--</li>-->
|
||||
<!--<li class="page-item disabled">-->
|
||||
<!--<a class="page-link" href="#">Newer →</a>-->
|
||||
<!--</li>-->
|
||||
<!--</ul>-->
|
||||
<!--</div>-->
|
||||
<br>
|
||||
|
||||
</div>
|
||||
<!-- /.container -->
|
||||
{% endblock %}
|
Loading…
Reference in a new issue