diff --git a/app/assets/v2/js/pages/bounty_details.js b/app/assets/v2/js/pages/bounty_details.js index 45a834deb0f..3a6f3607eed 100644 --- a/app/assets/v2/js/pages/bounty_details.js +++ b/app/assets/v2/js/pages/bounty_details.js @@ -492,7 +492,7 @@ const isAvailableIfReserved = function(bounty) { const isBountyOwner = result => { if (typeof web3 == 'undefined' || !web3.eth || - typeof web3.eth.coinbase == 'undefined' || !web3.eth.coinbase) { + typeof web3.eth.coinbase == 'undefined' || !web3.eth.coinbase || !result) { return false; } return caseInsensitiveCompare(web3.eth.coinbase, result['bounty_owner_address']); @@ -1179,19 +1179,6 @@ var do_actions = function(result) { actions.push(_entry); } - if (show_extend_deadline) { - const enabled = true; - const _entry = { - enabled: enabled, - href: '/extend-deadlines', - text: gettext('Extend Expiration'), - parent: 'bounty_actions', - title: gettext('Extend deadline of an issue') - }; - - actions.push(_entry); - } - if (show_invoice) { const _entry = { enabled: true, @@ -1205,14 +1192,30 @@ var do_actions = function(result) { } if (show_change_bounty) { + const connector_char = result['url'].indexOf('?') == -1 ? '?' : '&'; + const _entry = [ { enabled: true, href: '/bounty/change/' + result['pk'], - text: gettext('Edit Issue Details'), + text: gettext('Edit Issue'), parent: 'bounty_actions', - title: gettext('Update your Bounty Settings to get the right Crowd') - } + title: gettext('Update your Bounty Settings to get the right Crowd'), + edit_dropdown: true, + edit_issue_href: '/bounty/change/' + result['pk'], + show_extend_expiration: show_extend_deadline, + extend_expiration_href: '/extend-deadlines', + show_remarket: true, + remarket_enabled: result['can_remarket'], + remarket_url: result['url'] + connector_char + 'trigger_remarket=1' + }// , + // { + // enabled: true, + // href: '/issue/refund_request?pk=' + result['pk'], + // text: gettext('Request Fee Refund'), + // parent: 'right_actions', + // title: gettext('Raise a request if you believe you need your fee refunded') + // } ]; actions.push(..._entry); diff --git a/app/dashboard/helpers.py b/app/dashboard/helpers.py index d2b6d5f2c03..ea3002e0541 100644 --- a/app/dashboard/helpers.py +++ b/app/dashboard/helpers.py @@ -452,6 +452,10 @@ def create_new_bounty(old_bounties, bounty_payload, bounty_details, bounty_id): 'web3_created': timezone.make_aware( timezone.datetime.fromtimestamp(bounty_payload.get('created')), timezone=UTC), + 'last_remarketed': timezone.make_aware( + timezone.datetime.fromtimestamp(bounty_payload.get('created')), + timezone=UTC), + 'remarketed_count': 0, 'github_url': url, 'token_name': token_name, 'token_address': token_address, diff --git a/app/dashboard/migrations/0042_auto_20190718_1749.py b/app/dashboard/migrations/0042_auto_20190718_1749.py new file mode 100644 index 00000000000..cd2ccdff024 --- /dev/null +++ b/app/dashboard/migrations/0042_auto_20190718_1749.py @@ -0,0 +1,23 @@ +# Generated by Django 2.1.7 on 2019-07-18 17:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dashboard', '0041_auto_20190718_1222'), + ] + + operations = [ + migrations.AddField( + model_name='bounty', + name='last_remarketed', + field=models.DateTimeField(blank=True, db_index=True, null=True), + ), + migrations.AddField( + model_name='bounty', + name='remarketed_count', + field=models.PositiveSmallIntegerField(blank=True, default=0, null=True), + ), + ] diff --git a/app/dashboard/migrations/0048_merge_20190808_1934.py b/app/dashboard/migrations/0048_merge_20190808_1934.py new file mode 100644 index 00000000000..85255da1788 --- /dev/null +++ b/app/dashboard/migrations/0048_merge_20190808_1934.py @@ -0,0 +1,14 @@ +# Generated by Django 2.1.7 on 2019-08-08 19:34 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('dashboard', '0047_auto_20190808_1206'), + ('dashboard', '0042_auto_20190718_1749'), + ] + + operations = [ + ] diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 55bdeef8e34..78c8ba9159d 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -310,6 +310,8 @@ class Bounty(SuperModel): is_featured = models.BooleanField( default=False, help_text=_('Whether this bounty is featured')) featuring_date = models.DateTimeField(blank=True, null=True, db_index=True) + last_remarketed = models.DateTimeField(blank=True, null=True, db_index=True) + remarketed_count = models.PositiveSmallIntegerField(default=0, blank=True, null=True) fee_amount = models.DecimalField(default=0, decimal_places=18, max_digits=50) fee_tx_id = models.CharField(default="0x0", max_length=255, blank=True) coupon_code = models.ForeignKey('dashboard.Coupon', blank=True, null=True, related_name='coupon', on_delete=models.SET_NULL) @@ -1102,6 +1104,23 @@ def reserved_for_user_handle(self, handle): self.bounty_reserved_for_user = profile + @property + def can_remarket(self): + result = True + + if self.remarketed_count >= 2: + result = False + + if self.last_remarketed: + one_hour_after_remarketing = self.last_remarketed + timezone.timedelta(hours=1) + if timezone.now() < one_hour_after_remarketing: + result = False + + if self.interested.count() > 0: + result = False + + return result + class BountyFulfillmentQuerySet(models.QuerySet): """Handle the manager queryset for BountyFulfillments.""" diff --git a/app/dashboard/router.py b/app/dashboard/router.py index 41773ab6fd7..6a2cb493f58 100644 --- a/app/dashboard/router.py +++ b/app/dashboard/router.py @@ -21,7 +21,7 @@ import time from datetime import datetime -from django.db.models import Count +from django.db.models import Count, F import django_filters.rest_framework from kudos.models import KudosTransfer @@ -146,7 +146,7 @@ class Meta: 'attached_job_description', 'needs_review', 'github_issue_state', 'is_issue_closed', 'additional_funding_summary', 'funding_organisation', 'paid', 'admin_override_suspend_auto_approval', 'reserved_for_user_handle', 'is_featured', - 'featuring_date', 'repo_type', 'unsigned_nda', 'funder_last_messaged_on', + 'featuring_date', 'repo_type', 'unsigned_nda', 'funder_last_messaged_on', 'can_remarket' ) def create(self, validated_data): @@ -378,7 +378,10 @@ def get_queryset(self): # order order_by = self.request.query_params.get('order_by') if order_by and order_by != 'null': - queryset = queryset.order_by(order_by) + if order_by == 'recently_marketed': + queryset = queryset.order_by(F('last_remarketed').desc(nulls_last = True), '-web3_created') + else: + queryset = queryset.order_by(order_by) queryset = queryset.distinct() diff --git a/app/dashboard/templates/bounty/details.html b/app/dashboard/templates/bounty/details.html index 19ced004c96..94e812c26e6 100644 --- a/app/dashboard/templates/bounty/details.html +++ b/app/dashboard/templates/bounty/details.html @@ -227,9 +227,23 @@
{% trans "Funder" %}
[[/if]] [[else]] - - [[:text]] - + [[if edit_dropdown]] + + [[else]] + + [[:text]] + + [[/if]] [[/if]] diff --git a/app/dashboard/templates/shared/search_bar.html b/app/dashboard/templates/shared/search_bar.html index dd42d23fd3e..7d1ccb7ece6 100644 --- a/app/dashboard/templates/shared/search_bar.html +++ b/app/dashboard/templates/shared/search_bar.html @@ -23,6 +23,7 @@
{% trans "Sort by" %}