From 992cbe2c760054375e9b0720f23076eef6151ef3 Mon Sep 17 00:00:00 2001 From: Owocki Date: Sat, 20 Jul 2019 08:34:44 -0600 Subject: [PATCH 001/131] proof of concept of org profile editing --- app/app/context.py | 1 + app/assets/v2/css/profile.css | 4 ++-- app/dashboard/templates/profiles/profile.html | 10 +++++----- app/dashboard/templates/shared/nav_auth.html | 6 ++++++ app/dashboard/views.py | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/app/app/context.py b/app/app/context.py index b24a3c0e0e2..85a069c3bcf 100644 --- a/app/app/context.py +++ b/app/app/context.py @@ -80,6 +80,7 @@ def preprocess(request): 'release': settings.RELEASE, 'env': settings.ENV, 'email_key': email_key, + 'orgs': profile.organizations if profile else [], 'profile_id': profile.id if profile else '', 'hotjar': settings.HOTJAR_CONFIG, 'ipfs_config': { diff --git a/app/assets/v2/css/profile.css b/app/assets/v2/css/profile.css index e5108c2f4eb..2736039b164 100644 --- a/app/assets/v2/css/profile.css +++ b/app/assets/v2/css/profile.css @@ -109,11 +109,11 @@ height: 40px; } -.is_my_profile a:hover .profile-header__avatar{ +.is_editable a:hover .profile-header__avatar{ border: 3px solid #0fce7c; } -.is_my_profile{ +.is_editable{ cursor: pointer; } diff --git a/app/dashboard/templates/profiles/profile.html b/app/dashboard/templates/profiles/profile.html index 1a92a10b67e..000265f8c47 100644 --- a/app/dashboard/templates/profiles/profile.html +++ b/app/dashboard/templates/profiles/profile.html @@ -21,7 +21,7 @@ {% include 'home/nav.html' %}
{% csrf_token %} - {% if is_my_profile %} + {% if is_editable %}
Edit Header Photo @@ -41,12 +41,12 @@
{% if not hidden %} -
- {% if is_my_profile %} + diff --git a/app/dashboard/templates/shared/nav_auth.html b/app/dashboard/templates/shared/nav_auth.html index ef67e36b9c9..1fdce7e0d1e 100644 --- a/app/dashboard/templates/shared/nav_auth.html +++ b/app/dashboard/templates/shared/nav_auth.html @@ -60,6 +60,12 @@ {% trans "My Profile" %} + {% for org in orgs %} + + + {{org}}'s {% trans "Profile" %} + + {% endfor %} {% else %} diff --git a/app/dashboard/views.py b/app/dashboard/views.py index c7edc8a1ea1..a367132485d 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -1987,6 +1987,8 @@ def profile(request, handle): all_activities = context.get('activities') context['avg_rating'] = profile.get_average_star_rating context['is_my_profile'] = request.user.is_authenticated and request.user.username.lower() == handle.lower() + context['is_my_org'] = request.user.is_authenticated and any([handle.lower() == org.lower() for org in request.user.profile.organizations ]) + context['is_editable'] = context['is_my_org'] or context['is_my_profile'] context['ratings'] = range(0,5) tabs = [] From 75a2039fda4f255e6eb49d2d4ad34be39b8b8bdc Mon Sep 17 00:00:00 2001 From: Owocki Date: Sun, 21 Jul 2019 11:17:04 -0600 Subject: [PATCH 002/131] adds the ability to toggle persona on profile --- app/assets/v2/css/profile.css | 4 ++++ app/assets/v2/js/base.js | 7 ++++-- .../templates/profiles/organization.html | 3 ++- app/dashboard/templates/profiles/profile.html | 8 ++++++- .../templates/shared/profile_rank_link.html | 23 +++++++++++++++++++ app/dashboard/views.py | 2 ++ 6 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 app/dashboard/templates/shared/profile_rank_link.html diff --git a/app/assets/v2/css/profile.css b/app/assets/v2/css/profile.css index e5108c2f4eb..76f7f89b151 100644 --- a/app/assets/v2/css/profile.css +++ b/app/assets/v2/css/profile.css @@ -431,4 +431,8 @@ nav.navbar.navbar-dark{ background-image: url(/static/v2/images/header-bg.png); } +#rank_link{ + font-size: 12px; + color: black; +} diff --git a/app/assets/v2/js/base.js b/app/assets/v2/js/base.js index aea43baa8d4..dc308f2ce5e 100644 --- a/app/assets/v2/js/base.js +++ b/app/assets/v2/js/base.js @@ -233,8 +233,7 @@ if ($('#is-authenticated').val() === 'True' && !localStorage['notify_policy_upda $('#notify_policy_update').bootstrapModal('show'); } -if (document.contxt.github_handle && !document.contxt.persona_is_funder && !document.contxt.persona_is_hunter) { - +var show_persona_modal = function(e) { const content = $.parseHTML( ` \ No newline at end of file diff --git a/app/dashboard/templates/profiles/scorecard_hunter.html b/app/dashboard/templates/profiles/scorecard_hunter.html index f46b2142f41..fbcec1fb25c 100644 --- a/app/dashboard/templates/profiles/scorecard_hunter.html +++ b/app/dashboard/templates/profiles/scorecard_hunter.html @@ -37,4 +37,5 @@
+ {% include "profiles/heatmap.html" %}
\ No newline at end of file diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 9ed51ed88ef..2d5e2722935 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -1841,6 +1841,29 @@ def profile_keywords(request, handle): return JsonResponse(response) +def profile_activity(request, handle): + """Display profile activity details. + + Args: + handle (str): The profile handle. + + """ + try: + profile = profile_helper(handle, True) + except (ProfileNotFoundException, ProfileHiddenException): + raise Http404 + + activities = list(profile.get_various_activities().values_list('created_on', flat=True)) + activities += list(profile.actions.values_list('created_on', flat=True)) + response = {} + prev_date = timezone.now() + for i in range(1, 8*30): + date = timezone.now() - timezone.timedelta(days=i) + response[int(date.timestamp())] = len([activity_date for activity_date in activities if (activity_date < prev_date and activity_date > date)]) + prev_date = date + return JsonResponse(response) + + @require_POST @login_required def profile_job_opportunity(request, handle): From 0bfe3ff701de51c61911c8f0045c73724df6070a Mon Sep 17 00:00:00 2001 From: Owocki Date: Thu, 29 Aug 2019 16:00:30 -0600 Subject: [PATCH 020/131] whos viewed my profile --- app/assets/v2/js/pages/profile.js | 7 ++-- app/dashboard/admin.py | 4 +- .../migrations/0050_auto_20190829_2141.py | 38 +++++++++++++++++++ app/dashboard/models.py | 23 +++++++++++ .../templates/profiles/tab_workedwith.html | 14 ++++++- app/dashboard/views.py | 10 ++++- 6 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 app/dashboard/migrations/0050_auto_20190829_2141.py diff --git a/app/assets/v2/js/pages/profile.js b/app/assets/v2/js/pages/profile.js index f8ac9185d91..b6607eba328 100644 --- a/app/assets/v2/js/pages/profile.js +++ b/app/assets/v2/js/pages/profile.js @@ -31,9 +31,10 @@ $(document).ready(function() { if (fetchInProgress) { return; } - var is_on_activity_tab = $("#tab_controller .nav-link.active").data('href') == "tab2"; - var are_there_no_tabs = $("#tab_controller .nav-link.active").length == 0; - if (!is_on_activity_tab && !are_there_no_tabs){ + var is_on_activity_tab = $('#tab_controller .nav-link.active').data('href') == 'tab2'; + var are_there_no_tabs = $('#tab_controller .nav-link.active').length == 0; + + if (!is_on_activity_tab && !are_there_no_tabs) { return; } diff --git a/app/dashboard/admin.py b/app/dashboard/admin.py index 0a23bcca48c..ebee9c6b2c6 100644 --- a/app/dashboard/admin.py +++ b/app/dashboard/admin.py @@ -25,7 +25,8 @@ from .models import ( Activity, BlockedUser, Bounty, BountyFulfillment, BountyInvites, BountySyncRequest, CoinRedemption, CoinRedemptionRequest, Coupon, FeedbackEntry, HackathonEvent, HackathonSponsor, Interest, LabsResearch, Profile, - RefundFeeRequest, SearchHistory, Sponsor, Tip, TokenApproval, Tool, ToolVote, UserAction, UserVerificationModel, + ProfileView, RefundFeeRequest, SearchHistory, Sponsor, Tip, TokenApproval, Tool, ToolVote, UserAction, + UserVerificationModel, ) @@ -311,6 +312,7 @@ def link(self, instance): admin.site.register(SearchHistory, SearchHistoryAdmin) admin.site.register(Activity, ActivityAdmin) admin.site.register(BlockedUser, GeneralAdmin) +admin.site.register(ProfileView, GeneralAdmin) admin.site.register(UserAction, UserActionAdmin) admin.site.register(Interest, InterestAdmin) admin.site.register(Profile, ProfileAdmin) diff --git a/app/dashboard/migrations/0050_auto_20190829_2141.py b/app/dashboard/migrations/0050_auto_20190829_2141.py new file mode 100644 index 00000000000..1cc9047e4d1 --- /dev/null +++ b/app/dashboard/migrations/0050_auto_20190829_2141.py @@ -0,0 +1,38 @@ +# Generated by Django 2.2.3 on 2019-08-29 21:41 + +from django.db import migrations, models +import django.db.models.deletion +import economy.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dashboard', '0049_auto_20190828_0322'), + ] + + operations = [ + migrations.AlterField( + model_name='activity', + name='activity_type', + field=models.CharField(blank=True, choices=[('status_update', 'Update status'), ('new_bounty', 'New Bounty'), ('start_work', 'Work Started'), ('stop_work', 'Work Stopped'), ('work_submitted', 'Work Submitted'), ('work_done', 'Work Done'), ('worker_approved', 'Worker Approved'), ('worker_rejected', 'Worker Rejected'), ('worker_applied', 'Worker Applied'), ('increased_bounty', 'Increased Funding'), ('killed_bounty', 'Canceled Bounty'), ('new_tip', 'New Tip'), ('receive_tip', 'Tip Received'), ('bounty_abandonment_escalation_to_mods', 'Escalated checkin from @gitcoinbot about bounty status'), ('bounty_abandonment_warning', 'Checkin from @gitcoinbot about bounty status'), ('bounty_removed_slashed_by_staff', 'Dinged and Removed from Bounty by Staff'), ('bounty_removed_by_staff', 'Removed from Bounty by Staff'), ('bounty_removed_by_funder', 'Removed from Bounty by Funder'), ('new_crowdfund', 'New Crowdfund Contribution'), ('new_grant', 'New Grant'), ('update_grant', 'Updated Grant'), ('killed_grant', 'Cancelled Grant'), ('new_grant_contribution', 'Contributed to Grant'), ('new_grant_subscription', 'Subscribed to Grant'), ('killed_grant_contribution', 'Cancelled Grant Contribution'), ('new_milestone', 'New Milestone'), ('update_milestone', 'Updated Milestone'), ('new_kudos', 'New Kudos'), ('joined', 'Joined Gitcoin'), ('updated_avatar', 'Updated Avatar')], db_index=True, max_length=50), + ), + migrations.AlterField( + model_name='useraction', + name='action', + field=models.CharField(choices=[('Login', 'Login'), ('Logout', 'Logout'), ('Visit', 'Visit'), ('added_slack_integration', 'Added Slack Integration'), ('removed_slack_integration', 'Removed Slack Integration'), ('updated_avatar', 'Updated Avatar'), ('status_update', 'Update Status'), ('account_disconnected', 'Account Disconnected')], db_index=True, max_length=50), + ), + migrations.CreateModel( + name='ProfileView', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_on', models.DateTimeField(db_index=True, default=economy.models.get_time)), + ('modified_on', models.DateTimeField(default=economy.models.get_time)), + ('target', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='viewed_by', to='dashboard.Profile')), + ('viewer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='viewed_profiles', to='dashboard.Profile')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 2a85f2ff938..43b4d8f388f 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -3465,3 +3465,26 @@ class Coupon(SuperModel): def __str__(self): """Return the string representation of Coupon.""" return f'code: {self.code} | fee: {self.fee_percentage} %' + + +class ProfileView(SuperModel): + """Records profileviews .""" + + target = models.ForeignKey('dashboard.Profile', related_name='viewed_by', on_delete=models.CASCADE, db_index=True) + viewer = models.ForeignKey('dashboard.Profile', related_name='viewed_profiles', on_delete=models.CASCADE, db_index=True) + + def __str__(self): + return f"{self.viewer} => {self.target} on {self.created_on}" + + +@receiver(post_save, sender=ProfileView, dispatch_uid="post_add_profileview") +def post_add_profileview(sender, instance, created, **kwargs): + # disregard other profileviews added within 30 minutes of each other + if created: + dupes = ProfileView.objects.exclude(pk=instance.pk) + dupes = dupes.filter(created_on__gte=(instance.created_on - timezone.timedelta(minutes=30))) + dupes = dupes.filter(created_on__lte=(instance.created_on + timezone.timedelta(minutes=30))) + dupes = dupes.filter(target=instance.target) + dupes = dupes.filter(viewer=instance.viewer) + for dupe in dupes: + dupe.delete() diff --git a/app/dashboard/templates/profiles/tab_workedwith.html b/app/dashboard/templates/profiles/tab_workedwith.html index 8ecd9f83807..5a14f065c92 100644 --- a/app/dashboard/templates/profiles/tab_workedwith.html +++ b/app/dashboard/templates/profiles/tab_workedwith.html @@ -1,4 +1,4 @@ -{% load i18n static %} +{% load i18n static humanize %} {% if not hidden %} {% if is_editable %} @@ -7,6 +7,18 @@
{% endif %} + + {% if is_editable %} +
+ Whos Viewed My Profile + {% for viewer in profile.viewed_by.all %} +
+ - {{viewer.viewer.handle}} {{viewer.created_on | naturaltime}} +
+ {% endfor %} +
+ {% endif %} +
Reviews Received {% for feedback in feedbacks_got %} diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 9ed51ed88ef..065e290795f 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -72,7 +72,7 @@ from .helpers import get_bounty_data_for_activity, handle_bounty_views, load_files_in_directory from .models import ( Activity, Bounty, BountyDocuments, BountyFulfillment, BountyInvites, CoinRedemption, CoinRedemptionRequest, Coupon, - FeedbackEntry, HackathonEvent, HackathonSponsor, Interest, LabsResearch, Profile, ProfileSerializer, + FeedbackEntry, HackathonEvent, HackathonSponsor, Interest, LabsResearch, Profile, ProfileSerializer, ProfileView, RefundFeeRequest, Sponsor, Subscription, Tool, ToolVote, UserAction, UserVerificationModel, ) from .notifications import ( @@ -2117,6 +2117,14 @@ def profile(request, handle): context['tabs'] = [] context['tabs'].append(obj) + # record profile view + if request.user.is_authenticated and not context['is_my_profile']: + # TODO move the DB write into a celery job + ProfileView.objects.create( + target=profile, + viewer=request.user.profile, + ) + if request.method == 'POST' and request.is_ajax(): # Update profile address data when new preferred address is sent validated = request.user.is_authenticated and request.user.username.lower() == profile.handle.lower() From 66248d3c4c086a716751d9d0d0699c14882a7f9a Mon Sep 17 00:00:00 2001 From: Owocki Date: Thu, 29 Aug 2019 16:04:08 -0600 Subject: [PATCH 021/131] fixes event listener for when ur not looking at ur own profile --- app/assets/v2/js/status.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/app/assets/v2/js/status.js b/app/assets/v2/js/status.js index 6ad4a22759c..d3c7c3fec81 100644 --- a/app/assets/v2/js/status.js +++ b/app/assets/v2/js/status.js @@ -1,5 +1,14 @@ $(document).ready(function() { let button = document.querySelector('#btn_post'); + if(button){ + button.addEventListener( + 'click', + function() { + submitStatusUpdate(); + }, + false + ); + } $('body').on('focus change paste keyup blur', 'textarea', function() { if ( @@ -13,14 +22,6 @@ $(document).ready(function() { } }); - button.addEventListener( - 'click', - function() { - submitStatusUpdate(); - }, - false - ); - function submitStatusUpdate() { const data = new FormData(); const message = $('#textarea'); From f0a96bad1d7675954cb4e5d839c9ac28ff1b0f7d Mon Sep 17 00:00:00 2001 From: Owocki Date: Thu, 29 Aug 2019 16:53:06 -0600 Subject: [PATCH 022/131] moves the dataviz into a stats tab --- app/assets/v2/css/profile.css | 2 +- app/assets/v2/js/pages/profile.js | 2 +- .../templates/profiles/activity_stats.html | 5 +++ app/dashboard/templates/profiles/heatmap.html | 36 ++++++++++--------- .../templates/profiles/organization.html | 2 +- app/dashboard/templates/profiles/profile.html | 1 + .../templates/profiles/scorecard_funder.html | 2 +- .../templates/profiles/scorecard_hunter.html | 2 +- .../templates/profiles/tab_stats.html | 5 +++ app/dashboard/templates/profiles/tabs.html | 5 +++ 10 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 app/dashboard/templates/profiles/activity_stats.html create mode 100644 app/dashboard/templates/profiles/tab_stats.html diff --git a/app/assets/v2/css/profile.css b/app/assets/v2/css/profile.css index 5cc4275d2cc..d5ef86534c8 100644 --- a/app/assets/v2/css/profile.css +++ b/app/assets/v2/css/profile.css @@ -1,4 +1,4 @@ -.tab1, .tab3, .tab4{ +.tab1, .tab3, .tab4, .tab5{ display: none; } .mh-150{ diff --git a/app/assets/v2/js/pages/profile.js b/app/assets/v2/js/pages/profile.js index f8ac9185d91..6a3730515a3 100644 --- a/app/assets/v2/js/pages/profile.js +++ b/app/assets/v2/js/pages/profile.js @@ -12,7 +12,7 @@ $(document).ready(function() { $(this).addClass('active'); var target_class = $(this).data('href'); - $('.tab1, .tab2, .tab3, .tab4').css('display', 'none'); + $('.tab1, .tab2, .tab3, .tab4, .tab5').css('display', 'none'); $('.' + target_class).css('display', 'block'); e.preventDefault(); }); diff --git a/app/dashboard/templates/profiles/activity_stats.html b/app/dashboard/templates/profiles/activity_stats.html new file mode 100644 index 00000000000..e6ab3b459b1 --- /dev/null +++ b/app/dashboard/templates/profiles/activity_stats.html @@ -0,0 +1,5 @@ +last seen: x days ago +activity level: high +top skills: python, django, javascript +success pct: +number of repeat relationships diff --git a/app/dashboard/templates/profiles/heatmap.html b/app/dashboard/templates/profiles/heatmap.html index 8f0fe1e677f..21f0c43c3b8 100644 --- a/app/dashboard/templates/profiles/heatmap.html +++ b/app/dashboard/templates/profiles/heatmap.html @@ -2,21 +2,23 @@ -
-High Activity Level; Recently Active -
+
+
+ High Activity Level; Recently Active +
+
+ -
- \ No newline at end of file +
\ No newline at end of file diff --git a/app/dashboard/templates/profiles/organization.html b/app/dashboard/templates/profiles/organization.html index 8fe07717fdf..f8eb5e0aa0f 100644 --- a/app/dashboard/templates/profiles/organization.html +++ b/app/dashboard/templates/profiles/organization.html @@ -48,5 +48,5 @@
- {% include "profiles/heatmap.html" %} + {% include "profiles/activity_stats.html" %}
diff --git a/app/dashboard/templates/profiles/profile.html b/app/dashboard/templates/profiles/profile.html index a066d5b53b2..d8a5770c107 100644 --- a/app/dashboard/templates/profiles/profile.html +++ b/app/dashboard/templates/profiles/profile.html @@ -65,6 +65,7 @@ {% include 'profiles/tabs.html' %} {% include 'profiles/tab_details.html' %} {% include 'profiles/tab_resume.html' %} + {% include 'profiles/tab_stats.html' %}
diff --git a/app/dashboard/templates/profiles/scorecard_funder.html b/app/dashboard/templates/profiles/scorecard_funder.html index b2a69ed984a..c67a7bf114e 100644 --- a/app/dashboard/templates/profiles/scorecard_funder.html +++ b/app/dashboard/templates/profiles/scorecard_funder.html @@ -32,5 +32,5 @@
- {% include "profiles/heatmap.html" %} + {% include "profiles/activity_stats.html" %} \ No newline at end of file diff --git a/app/dashboard/templates/profiles/scorecard_hunter.html b/app/dashboard/templates/profiles/scorecard_hunter.html index fbcec1fb25c..928e14a426d 100644 --- a/app/dashboard/templates/profiles/scorecard_hunter.html +++ b/app/dashboard/templates/profiles/scorecard_hunter.html @@ -37,5 +37,5 @@ - {% include "profiles/heatmap.html" %} + {% include "profiles/activity_stats.html" %} \ No newline at end of file diff --git a/app/dashboard/templates/profiles/tab_stats.html b/app/dashboard/templates/profiles/tab_stats.html new file mode 100644 index 00000000000..ec651fe53cd --- /dev/null +++ b/app/dashboard/templates/profiles/tab_stats.html @@ -0,0 +1,5 @@ +{% load i18n static %} + +
+ {% include "profiles/heatmap.html" %} +
\ No newline at end of file diff --git a/app/dashboard/templates/profiles/tabs.html b/app/dashboard/templates/profiles/tabs.html index 9324b2eb4c8..0b4ea7db14e 100644 --- a/app/dashboard/templates/profiles/tabs.html +++ b/app/dashboard/templates/profiles/tabs.html @@ -13,6 +13,11 @@ Details + {% if show_resume_tab %} - + +
{% if profile.resume %}
-
Resume
+
Resume
Download Resume
{% endif %} - - - - {% endif %} diff --git a/app/dashboard/templates/profiles/tabs.html b/app/dashboard/templates/profiles/tabs.html index d3ff8b45802..adb47fc8b92 100644 --- a/app/dashboard/templates/profiles/tabs.html +++ b/app/dashboard/templates/profiles/tabs.html @@ -53,7 +53,7 @@ -
+
From 0d2c1f91bcd8743e357ccd85cd1562bf9196cba1 Mon Sep 17 00:00:00 2001 From: Onuwa Nnachi Isaac Date: Mon, 9 Sep 2019 15:51:42 +0100 Subject: [PATCH 042/131] Fix lint issues --- app/assets/v2/css/profile.css | 46 ++--- .../templates/profiles/activity_level.html | 44 ++--- .../templates/profiles/header_avatar.html | 34 ++-- app/dashboard/templates/profiles/profile.html | 62 +++---- .../templates/profiles/scorecard_funder.html | 68 ++++---- .../templates/profiles/scorecard_hunter.html | 78 ++++----- .../templates/profiles/tab_resume.html | 51 +++--- .../templates/profiles/tab_workedwith.html | 36 ++-- app/dashboard/templates/profiles/tabs.html | 165 ++++++++---------- app/dashboard/templates/shared/feedback.html | 42 +++-- app/dashboard/views.py | 2 +- 11 files changed, 300 insertions(+), 328 deletions(-) diff --git a/app/assets/v2/css/profile.css b/app/assets/v2/css/profile.css index 8ec3d607807..5fb638eca7e 100644 --- a/app/assets/v2/css/profile.css +++ b/app/assets/v2/css/profile.css @@ -2,26 +2,26 @@ display: none; } - .tab-projects__item img { - width: 50px; - height: 50px; - } - - .tag-list .tag-list__item { - background: #E8F0FA; - padding: 4px; - border-radius: 2px; - font-size: 14px; - color: #6487AE; - } +.tab-projects__item img { + width: 50px; + height: 50px; +} + +.tag-list .tag-list__item { + background: #E8F0FA; + padding: 4px; + border-radius: 2px; + font-size: 14px; + color: #6487AE; +} - .review-comment { - background: #E4E6E7; - border-radius: 5px; - padding: 5px 7px; - font-size: 12px; - color: #666666; - } +.review-comment { + background: #E4E6E7; + border-radius: 5px; + padding: 5px 7px; + font-size: 12px; + color: #666666; +} .mh-150{ min-height: 150px; @@ -451,7 +451,7 @@ background-image: url(/static/v2/images/header-bg.png); } - #rank_link{ - font-size: 12px; - color: black; - } \ No newline at end of file +#rank_link{ + font-size: 12px; + color: black; +} \ No newline at end of file diff --git a/app/dashboard/templates/profiles/activity_level.html b/app/dashboard/templates/profiles/activity_level.html index 492b81ac040..6682858fbcd 100644 --- a/app/dashboard/templates/profiles/activity_level.html +++ b/app/dashboard/templates/profiles/activity_level.html @@ -1,26 +1,26 @@ {% load i18n static avatar_tags %}
-
-
- {% if level %} - #{{ level }} - {% else %} -   - {% endif %} - {% trans "Activity Level" %} -
-
-
    -
  • {% trans "Last seen" %} 2 days ago
  • -
  • 100 days {% trans "longest streak" %}
  • -
  • 10 {% trans "repeat relationships" %}
  • -
  • - {% for i in ratings %} - - {% endfor %} - ({{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}}) -
  • -
-
+
+
+ {% if level %} + #{{ level }} + {% else %} +   + {% endif %} + {% trans "Activity Level" %}
+
+
    +
  • {% trans "Last seen" %} 2 days ago
  • +
  • 100 days {% trans "longest streak" %}
  • +
  • 10 {% trans "repeat relationships" %}
  • +
  • + {% for rating in ratings %} + + {% endfor %} + ({{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}}) +
  • +
+
+
\ No newline at end of file diff --git a/app/dashboard/templates/profiles/header_avatar.html b/app/dashboard/templates/profiles/header_avatar.html index 449c432a3c3..2c9f4948adb 100644 --- a/app/dashboard/templates/profiles/header_avatar.html +++ b/app/dashboard/templates/profiles/header_avatar.html @@ -1,18 +1,18 @@ {% load i18n static avatar_tags %} - \ No newline at end of file + \ No newline at end of file diff --git a/app/dashboard/templates/profiles/profile.html b/app/dashboard/templates/profiles/profile.html index d81755f5082..155b74c9bb1 100644 --- a/app/dashboard/templates/profiles/profile.html +++ b/app/dashboard/templates/profiles/profile.html @@ -22,22 +22,22 @@ {% include 'shared/top_nav.html' with class='d-md-flex' %} {% include 'home/nav.html' %}
- {% csrf_token %} - {% if is_editable %} + {% csrf_token %} + {% if is_editable %}
-
-
-
- - - Update Header Image - -
-
+
+
+
+ + + Update Header Image + +
+
- {% endif %} - {% if not hidden and is_staff %} + {% endif %} + {% if not hidden and is_staff %}
Staff only {% trans "Profile Admin" %} @@ -45,44 +45,36 @@ {% endif %}
-
-
-
- {% if not hidden %} - {% include 'profiles/header_avatar.html' %} - {% include 'profiles/header_details.html' %} +
+
+
+ {% if not hidden %} + {% include 'profiles/header_avatar.html' %} + {% include 'profiles/header_details.html' %} {% if not hidden %} {% if profile.is_org %} {% include 'profiles/organization.html' %} {% else %} {% if profile.persona_is_hunter %} - {% include 'profiles/scorecard_hunter.html' %} - {% elif profile.persona_is_funder %} + {% include 'profiles/scorecard_hunter.html' %} + {% elif profile.persona_is_funder %} {% include 'profiles/scorecard_funder.html' %} - {% endif %} -
-
{% endif %} - {% endif %}
- {% endif%} - + {% endif %} + {% endif %} +
+
+ {% endif%} + {% include 'profiles/tabs.html' %} -
{% if hidden %} {% include 'profiles/hidden.html' %} - {% else %} - - {% if tabs %} - {% include 'profiles/tab_workedwith.html' %} - {% else %} - {% include 'profiles/none.html' %} {% endif %} - {% endif %}
{% include 'profiles/tabs_close.html' %} diff --git a/app/dashboard/templates/profiles/scorecard_funder.html b/app/dashboard/templates/profiles/scorecard_funder.html index 0dedbf09052..6bbe0043bdf 100644 --- a/app/dashboard/templates/profiles/scorecard_funder.html +++ b/app/dashboard/templates/profiles/scorecard_funder.html @@ -1,38 +1,38 @@ {% load i18n static avatar_tags %}
-
-
-
-
- {% if scoreboard %} - #{{ scoreboard }} - {% else %} -   - {% endif %} - {% trans "Funder" %} +
+
+
+
+ {% if scoreboard %} + #{{ scoreboard }} + {% else %} +   + {% endif %} + {% trans "Funder" %} {% include "shared/profile_rank_link.html" with link='payers' %} -
-
-
    -
  • {{ funded_bounties_count }} {% trans "bounties funded" %}
  • -
  • {{ sum_eth_funded|floatformat:2 }} ETH {% trans "funded" %}
  • -
  • - {% if works_with_funded|length %} - {% trans "Funds" %}: - {% for profile, num_times in works_with_funded.items %} - {% if forloop.counter < 6 %} - - - - {% endif %} - {% endfor %} - {% if works_with_funded|length > 5 %} -
    +{{works_with_funded|length|add:"-5"}}
    - {% endif %} - {% endif %} -
  • -
-
-
- {% include "profiles/activity_level.html" with level='High'%} \ No newline at end of file +
+
    +
  • {{ funded_bounties_count }} {% trans "bounties funded" %}
  • +
  • {{ sum_eth_funded|floatformat:2 }} ETH {% trans "funded" %}
  • +
  • + {% if works_with_funded|length %} + {% trans "Funds" %}: + {% for profile, num_times in works_with_funded.items %} + {% if forloop.counter < 6 %} + + + + {% endif %} + {% endfor %} + {% if works_with_funded|length > 5 %} +
    +{{works_with_funded|length|add:"-5"}}
    + {% endif %} + {% endif %} +
  • +
+
+
+
+ {% include "profiles/activity_level.html" with level='High'%} \ No newline at end of file diff --git a/app/dashboard/templates/profiles/scorecard_hunter.html b/app/dashboard/templates/profiles/scorecard_hunter.html index ded10db19fc..c86525f08c9 100644 --- a/app/dashboard/templates/profiles/scorecard_hunter.html +++ b/app/dashboard/templates/profiles/scorecard_hunter.html @@ -1,41 +1,41 @@ {% load i18n static avatar_tags %} -
-
-
-
-
- {% if scoreboard_position_contributor %} - #{{ scoreboard_position_contributor }} - {% else %} -   - {% endif %} - {% trans "Contributor" %} - {% include "shared/profile_rank_link.html" with link='earners' %} -
-
-
    -
  • {{ count_bounties_completed }} {% trans "bounties completed" %}
  • -
  • {{ sum_eth_collected|floatformat:2 }} ETH {% trans "collected" %}
  • - {% if no_times_been_removed %} -
  • - {% trans "removed from" %} {{ no_times_been_removed }} {% trans "bounties" %}
  • - {% endif %} -
  • - {% if works_with_collected|length %} - Contributes To: - {% for profile, num_times in works_with_collected.items %} - {% if forloop.counter < 6 %} - - - - {% endif %} - {% endfor %} - {% if works_with_collected|length > 5 %} -
    +{{works_with_collected|length|add:"-5"}}
    - {% endif %} +
    +
    +
    +
    +
    + {% if scoreboard_position_contributor %} + #{{ scoreboard_position_contributor }} + {% else %} +   + {% endif %} + {% trans "Contributor" %} + {% include "shared/profile_rank_link.html" with link='earners' %} +
    +
    +
      +
    • {{ count_bounties_completed }} {% trans "bounties completed" %}
    • +
    • {{ sum_eth_collected|floatformat:2 }} ETH {% trans "collected" %}
    • + {% if no_times_been_removed %} +
    • - {% trans "removed from" %} {{ no_times_been_removed }} {% trans "bounties" %}
    • + {% endif %} +
    • + {% if works_with_collected|length %} + Contributes To: + {% for profile, num_times in works_with_collected.items %} + {% if forloop.counter < 6 %} + + + {% endif %} -
    • -
    -
    -
    -
    - {% include "profiles/activity_level.html" with level='High' %} \ No newline at end of file + {% endfor %} + {% if works_with_collected|length > 5 %} +
    +{{works_with_collected|length|add:"-5"}}
    + {% endif %} + {% endif %} +
  • +
+
+
+
+ {% include "profiles/activity_level.html" with level='High' %} \ No newline at end of file diff --git a/app/dashboard/templates/profiles/tab_resume.html b/app/dashboard/templates/profiles/tab_resume.html index 32a01edca05..9c4b94f9e24 100644 --- a/app/dashboard/templates/profiles/tab_resume.html +++ b/app/dashboard/templates/profiles/tab_resume.html @@ -1,26 +1,29 @@ {% load i18n static %} - {% if not hidden and not profile.is_org and show_resume_tab %} -
Job Preferences
-
-
- Actively looking for (Full Time, Part Time, Contract) -
-
- Looking for companies in {% for loc in profile.job_location %}{{loc.name}}, {% endfor %} -
-
- Compensation Expectation USD $10,000/month -
-
-
- {% if profile.resume %} -
-
Resume
- Download Resume -
- - - - {% endif %} - {% endif %} +{% if not hidden and not profile.is_org and show_resume_tab %} +
Job Preferences
+
+
+ + Actively looking for (Full Time, Part Time, Contract) +
+
+ + Looking for companies in {% for loc in profile.job_location %}{{loc.name}}, {% endfor %} +
+
+ + Compensation Expectation USD $10,000/month +
+
+
+ {% if profile.resume %} +
+
Resume
+ Download Resume +
+ + + + {% endif %} +{% endif %} diff --git a/app/dashboard/templates/profiles/tab_workedwith.html b/app/dashboard/templates/profiles/tab_workedwith.html index b00f92a0a0b..0b447128b2f 100644 --- a/app/dashboard/templates/profiles/tab_workedwith.html +++ b/app/dashboard/templates/profiles/tab_workedwith.html @@ -1,24 +1,24 @@ {% load i18n static %} - {% if not hidden %} - {% if is_editable %} -
- {% include "shared/rate_bounties.html" %} -
- {% endif %} - + {% if not hidden %} + {% if is_editable %}
-
{% trans "Reviews Received" %}
- {% for feedback in feedbacks_got %} - {% include "shared/feedback.html" %} - {% endfor %} + {% include "shared/rate_bounties.html" %}
+ {% endif %} -
-
{% trans "Reviews Sent" %}
- {% for feedback in feedbacks_sent %} - {% include "shared/feedback.html" %} - {% endfor %} -
+
+
{% trans "Reviews Received" %}
+ {% for feedback in feedbacks_got %} + {% include "shared/feedback.html" %} + {% endfor %} +
- {% endif %} +
+
{% trans "Reviews Sent" %}
+ {% for feedback in feedbacks_sent %} + {% include "shared/feedback.html" %} + {% endfor %} +
+ + {% endif %} diff --git a/app/dashboard/templates/profiles/tabs.html b/app/dashboard/templates/profiles/tabs.html index adb47fc8b92..8afc6cde040 100644 --- a/app/dashboard/templates/profiles/tabs.html +++ b/app/dashboard/templates/profiles/tabs.html @@ -1,103 +1,76 @@ {% load i18n static %} - {% if not hidden and not profile.is_org %} - -
- -
-
-
-
-
-
- {% include 'profiles/tab_activity.html' %} -
-
-
+ {% if not hidden and not profile.is_org %} +
+ +
+
+
+
+
+
+ {% include 'profiles/tab_activity.html' %}
-
-
-
-
- {% include 'profiles/tab_resume.html' %} -
-
-
+
+
+
+
+
+
+
+ {% include 'profiles/tab_resume.html' %}
-
-
-
-
- {% include 'profiles/tab_ratings.html' %} -
-
-
+
+
+
+
+
+
+
+ {% include 'profiles/tab_ratings.html' %}
-
-
-
-
- {% include 'profiles/tab_portfolio.html' %} -
-
-
+
+
+
+
+
+
+
+ {% include 'profiles/tab_portfolio.html' %}
-
-
-
-
- {% include "shared/profile_kudos.html" %} -
-
-
+
+
+
+
+
+
+
+ {% include "shared/profile_kudos.html" %}
+
- {% endif %} \ No newline at end of file +
+
+ {% endif %} \ No newline at end of file diff --git a/app/dashboard/templates/shared/feedback.html b/app/dashboard/templates/shared/feedback.html index 6bc80f30df7..5a1ac183582 100644 --- a/app/dashboard/templates/shared/feedback.html +++ b/app/dashboard/templates/shared/feedback.html @@ -14,26 +14,30 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . {% endcomment %} -{% load i18n staticfiles %} +{% load i18n staticfiles avatar_tags%}
-
-
- - -
+
+
+ +
-
-
-
- @{{feedback.sender_profile}} - for {{feedback.bounty.org_name}}: {{feedback.bounty.title}} -
-
- {% for i in ratings %} - - {% endfor %} -
-
+
+
+
+
+ @{{feedback.sender_profile}} + for {{feedback.bounty.org_name}}: + {{feedback.bounty.title}} + +
+
+ {% for rating in ratings %} + + {% endfor %} +
+
-{{ feedback.comment }} \ No newline at end of file +{% if feedback.comment %} + {{ feedback.comment }} +{% endif %} \ No newline at end of file diff --git a/app/dashboard/views.py b/app/dashboard/views.py index c6b8bb279f3..297fd0947c4 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -2094,7 +2094,7 @@ def profile(request, handle): ).exclude( feedbacks__feedbackType='approver', feedbacks__sender_profile=profile, - ).distinct('pk').nocache() + ).distinct('pk') context['unrated_contributed_bounties'] = Bounty.objects.current().prefetch_related('feedbacks').filter(interested__profile=profile, network=network,) \ .filter(interested__status='okay') \ From c8b7cc8ac1402784d32340e19b66ef68dd944188 Mon Sep 17 00:00:00 2001 From: Onuwa Nnachi Isaac Date: Mon, 9 Sep 2019 15:51:52 +0100 Subject: [PATCH 043/131] Add progress bar to ratings --- .../templates/profiles/tab_ratings.html | 95 ++++++++++++++----- 1 file changed, 70 insertions(+), 25 deletions(-) diff --git a/app/dashboard/templates/profiles/tab_ratings.html b/app/dashboard/templates/profiles/tab_ratings.html index 04acf274d02..f04ee73ba1b 100644 --- a/app/dashboard/templates/profiles/tab_ratings.html +++ b/app/dashboard/templates/profiles/tab_ratings.html @@ -1,33 +1,78 @@ {% load i18n static %}
- {% for i in ratings %} - - {% endfor %} -
-   {{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}} -
+ {% for i in ratings %} + + {% endfor %} +
+   {{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}} +
-
- Satisfaction {{feedback.satisfaction_rating}} -
-
- Speed {{feedback.speed_rating}} -
-
- Recommended to other funders {{feedback.recommendation_rating}} -
-
- Communication/Responsiveness {{feedback.communication_rating}} -
-
- Quality of Code Submission {{feedback.code_quality_rating}} -
+
+
+
+ Satisfaction +
+
+
+
+
+
+
+
+
+
+
+ Speed +
+
+
+
+
+
+
+
+
+
+
+ Recommend to other funders +
+
+
+
+
+
+
+
+
+
+
+ Communication/Responsivess +
+
+
+
+
+
+
+
+
+
+
+ Quality of Code Submission +
+
+
+
+
+
+
+
-
Reviews
- {% for feedback in feedbacks_got %} - {% include "shared/feedback.html" %} - {% endfor %} +
Reviews
+ {% for feedback in feedbacks_got %} + {% include "shared/feedback.html" %} + {% endfor %}
\ No newline at end of file From a86ea4b28065e0907bc660e1b6f300111dc5a082 Mon Sep 17 00:00:00 2001 From: Owocki Date: Mon, 9 Sep 2019 14:35:45 -0600 Subject: [PATCH 044/131] this commit adds methods for calculating all the info needed on profiles to give them activity data --- app/dashboard/admin.py | 9 +- .../commands/cleanup_dupe_profiles.py | 1 + .../management/commands/create_rep_records.py | 47 ++++ .../migrations/0052_auto_20190909_1822.py | 43 ++++ app/dashboard/migrations/0053_repentry.py | 33 +++ app/dashboard/models.py | 213 +++++++++++++++++- app/dashboard/points.py | 19 ++ .../templates/profiles/activity_stats.html | 26 ++- app/dashboard/templates/profiles/heatmap.html | 9 +- 9 files changed, 386 insertions(+), 14 deletions(-) create mode 100644 app/dashboard/management/commands/create_rep_records.py create mode 100644 app/dashboard/migrations/0052_auto_20190909_1822.py create mode 100644 app/dashboard/migrations/0053_repentry.py create mode 100644 app/dashboard/points.py diff --git a/app/dashboard/admin.py b/app/dashboard/admin.py index ebee9c6b2c6..e8191d2708b 100644 --- a/app/dashboard/admin.py +++ b/app/dashboard/admin.py @@ -26,7 +26,7 @@ Activity, BlockedUser, Bounty, BountyFulfillment, BountyInvites, BountySyncRequest, CoinRedemption, CoinRedemptionRequest, Coupon, FeedbackEntry, HackathonEvent, HackathonSponsor, Interest, LabsResearch, Profile, ProfileView, RefundFeeRequest, SearchHistory, Sponsor, Tip, TokenApproval, Tool, ToolVote, UserAction, - UserVerificationModel, + UserVerificationModel, REPEntry ) @@ -42,6 +42,12 @@ class GeneralAdmin(admin.ModelAdmin): list_display = ['created_on', '__str__'] +class REPEntryAdmin(admin.ModelAdmin): + ordering = ['-id'] + list_display = ['created_on', '__str__'] + raw_id_fields = ['profile'] + + class ToolAdmin(admin.ModelAdmin): ordering = ['-id'] list_display = ['created_on', '__str__'] @@ -311,6 +317,7 @@ def link(self, instance): admin.site.register(SearchHistory, SearchHistoryAdmin) admin.site.register(Activity, ActivityAdmin) +admin.site.register(REPEntry, REPEntryAdmin) admin.site.register(BlockedUser, GeneralAdmin) admin.site.register(ProfileView, GeneralAdmin) admin.site.register(UserAction, UserActionAdmin) diff --git a/app/dashboard/management/commands/cleanup_dupe_profiles.py b/app/dashboard/management/commands/cleanup_dupe_profiles.py index 4e15fe6819a..0080d2db506 100644 --- a/app/dashboard/management/commands/cleanup_dupe_profiles.py +++ b/app/dashboard/management/commands/cleanup_dupe_profiles.py @@ -46,6 +46,7 @@ def combine_profiles(p1, p2): p1.hide_profile = False p1.suppress_leaderboard = any([p1.suppress_leaderboard, p2.suppress_leaderboard]) p1.user = p2.user if p2.user else p1.user + p1.created_on = p2.created_on if p2.created_on > p1.created_on else p1.created_on # tips, bounties, fulfillments, and interests , activities, actions for obj in p2.received_tips.all(): obj.recipient_profile = p1 diff --git a/app/dashboard/management/commands/create_rep_records.py b/app/dashboard/management/commands/create_rep_records.py new file mode 100644 index 00000000000..4ab4ecb09d7 --- /dev/null +++ b/app/dashboard/management/commands/create_rep_records.py @@ -0,0 +1,47 @@ +''' + Copyright (C) 2018 Gitcoin Core + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +''' + +from django.core.management.base import BaseCommand + +from dashboard.models import Activity, UserAction, REPEntry + + +class Command(BaseCommand): + + help = 'creates REP records for current acivity feeds' + + def handle(self, *args, **options): + for instance in Activity.objects.all().order_by('created_on'): + if instance.point_value(): + print(instance.pk) + REPEntry.objects.create( + why=instance.activity_type, + profile=instance.profile, + source=instance, + value=instance.point_value(), + ) + + for instance in UserAction.objects.all().order_by('created_on'): + if instance.point_value(): + print(instance.pk) + REPEntry.objects.create( + why=instance.action, + profile=instance.profile, + source=instance, + value=instance.point_value(), + ) diff --git a/app/dashboard/migrations/0052_auto_20190909_1822.py b/app/dashboard/migrations/0052_auto_20190909_1822.py new file mode 100644 index 00000000000..aecf0ffa9bb --- /dev/null +++ b/app/dashboard/migrations/0052_auto_20190909_1822.py @@ -0,0 +1,43 @@ +# Generated by Django 2.2.3 on 2019-09-09 18:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dashboard', '0051_profile_dominant_persona'), + ] + + operations = [ + migrations.AddField( + model_name='profile', + name='activity_level', + field=models.CharField(blank=True, help_text='the users activity level (high, low, new)', max_length=10), + ), + migrations.AddField( + model_name='profile', + name='avg_hourly_rate', + field=models.DecimalField(decimal_places=2, default=0, max_digits=50), + ), + migrations.AddField( + model_name='profile', + name='longest_streak', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='profile', + name='num_repeated_relationships', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='profile', + name='rep', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='profile', + name='success_rate', + field=models.IntegerField(default=0), + ), + ] diff --git a/app/dashboard/migrations/0053_repentry.py b/app/dashboard/migrations/0053_repentry.py new file mode 100644 index 00000000000..d75169b2886 --- /dev/null +++ b/app/dashboard/migrations/0053_repentry.py @@ -0,0 +1,33 @@ +# Generated by Django 2.2.3 on 2019-09-09 20:26 + +from django.db import migrations, models +import django.db.models.deletion +import economy.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('dashboard', '0052_auto_20190909_1822'), + ] + + operations = [ + migrations.CreateModel( + name='REPEntry', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_on', models.DateTimeField(db_index=True, default=economy.models.get_time)), + ('modified_on', models.DateTimeField(default=economy.models.get_time)), + ('why', models.CharField(max_length=50)), + ('source_id', models.PositiveIntegerField()), + ('value', models.PositiveIntegerField()), + ('balance', models.PositiveIntegerField()), + ('profile', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='repentries', to='dashboard.Profile')), + ('source_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 421e4b66307..23aa281c53a 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -40,11 +40,14 @@ from django.urls.exceptions import NoReverseMatch from django.utils import timezone from django.utils.translation import gettext_lazy as _ +from django.contrib.contenttypes.fields import GenericForeignKey +from django.contrib.contenttypes.models import ContentType import pytz import requests from app.utils import get_upload_filename from dashboard.tokens import addr_to_token +from dashboard.points import point_values from economy.models import ConversionRate, SuperModel from economy.utils import ConversionRateNotFoundError, convert_amount, convert_token_to_usdt from gas.utils import recommend_min_gas_price_to_confirm_in_time @@ -664,6 +667,12 @@ def keywords_list(self): except AttributeError: return [] + @property + def fulfillers_handles(self): + bounty_fulfillers = self.fulfillments.filter(accepted=True).values_list('fulfiller_github_username', flat=True) + tip_fulfillers = self.tips.values_list('username', flat=True) + return list(bounty_fulfillers) + list(tip_fulfillers) + @property def now(self): """Return the time now in the current timezone.""" @@ -1797,7 +1806,6 @@ def __str__(self): return f"{self.profile.handle} type: {self.activity_type} created: {naturalday(self.created)} " \ f"needs review: {self.needs_review}" - @property def humanized_activity_type(self): """Turn snake_case into Snake Case. @@ -1810,6 +1818,13 @@ def humanized_activity_type(self): return activity_type[1] return ' '.join([x.capitalize() for x in self.activity_type.split('_')]) + def point_value(self): + """ + + Returns: + int the Point value of this activity + """ + return point_values.get(self.activity_type, 0) def i18n_name(self): return _(next((x[1] for x in self.ACTIVITY_TYPES if x[0] == self.activity_type), 'Unknown type')) @@ -1929,6 +1944,7 @@ def to_dict(self, fields=None, exclude=None): @receiver(post_save, sender=Activity, dispatch_uid="post_add_activity") def post_add_activity(sender, instance, created, **kwargs): if created: + # make sure duplicate activity feed items are removed dupes = Activity.objects.exclude(pk=instance.pk) dupes = dupes.filter(created_on__gte=(instance.created_on - timezone.timedelta(minutes=5))) dupes = dupes.filter(created_on__lte=(instance.created_on + timezone.timedelta(minutes=5))) @@ -1944,6 +1960,14 @@ def post_add_activity(sender, instance, created, **kwargs): for dupe in dupes: dupe.delete() + # add REP + if instance.point_value(): + REPEntry.objects.create( + why=instance.activity_type, + profile=instance.profile, + source=instance, + value=instance.point_value(), + ) class LabsResearch(SuperModel): @@ -2105,6 +2129,12 @@ class Profile(SuperModel): help_text=_('override profile avatar'), ) dominant_persona = models.CharField(max_length=25, choices=PERSONAS, blank=True) + longest_streak = models.IntegerField(default=0) + activity_level = models.CharField(max_length=10, blank=True, help_text=_('the users activity level (high, low, new)')) + num_repeated_relationships = models.IntegerField(default=0) + avg_hourly_rate = models.DecimalField(default=0, decimal_places=2, max_digits=50) + success_rate = models.IntegerField(default=0) + rep = models.IntegerField(default=0) objects = ProfileQuerySet.as_manager() @@ -2400,6 +2430,136 @@ def is_staff(self): """ return self.user.is_staff if self.user else False + def calc_activity_level(self): + """Determines the activity level of a user + + Returns: + str: High, Low, Medium, or New + + """ + high_threshold = 15 + med_threshold = 15 + new_threshold_days = 7 + + if self.created_on > (timezone.now() - timezone.timedelta(days=new_threshold_days)): + return "New" + + visits = self.actions.filter(action='Visit') + visits_last_month = visits.filter(created_on__gt=timezone.now() - timezone.timedelta(days=30)).count() + + if visits_last_month > high_threshold: + return "High" + if visits_last_month > med_threshold: + return "Medium" + if visits_last_month > med_threshold: + return "Low" + + + def calc_longest_streak(self): + """ Determines the longest streak, in workdays, of this user + + Returns: + int: a number of weekdays + + """ + + # setup + action_dates = self.actions.all().values_list('created_on', flat=True) + start_date = timezone.datetime(self.created_on.year, self.created_on.month, self.created_on.day) + end_date = timezone.datetime(timezone.now().year, timezone.now().month, timezone.now().day) + + # loop setup + iterdate = start_date + max_streak = 0 + this_streak = 0 + while iterdate < end_date: + # housekeeping + last_iterdate = start_date + iterdate += timezone.timedelta(days=1) + + is_weekday = iterdate.weekday() < 5 + if not is_weekday: + continue + + has_action_during_window = len([ele for ele in action_dates if ele > last_iterdate.replace(tzinfo=pytz.utc) and ele < iterdate.replace(tzinfo=pytz.utc)]) + if has_action_during_window: + this_streak += 1 + if this_streak > max_streak: + max_streak = this_streak + else: + this_streak = 0 + + return max_streak + + def calc_num_repeated_relationships(self): + """ the number of repeat relationships that this user has created + + Returns: + int: a number of repeat relationships + + """ + bounties = self.bounties + completed_bounties = bounties.filter(idx_status__in=['done']) + relationships = [] + for bounty in completed_bounties: + fulfiller_handles = bounty.fulfillers_handles + if bounty.is_funder(self.handle): + for handle in fulfiller_handles: + relationships.append(handle) + if self.handle in fulfiller_handles: + relationships.append(bounty.bounty_owner_github_username) + + rel_count = { key: 0 for key in relationships } + for rel in relationships: + rel_count[rel] += 1 + + return len([key for key, val in rel_count.items() if val > 1]) + + + def calc_avg_hourly_rate(self): + """ + + Returns: + float: the average hourly rate for this user in dollars + + """ + rates = [] + for bounty in self.bounties: + hr = bounty.hourly_rate + if hr: + rates.append(hr) + if len(rates) == 0: + return 0 + return sum(rates)/len(rates) + + def calc_success_rate(self): + """ + + Returns: + int; the success percentage for this users bounties as a positive integer. + + """ + bounties = self.bounties + completed_bounties = bounties.filter(idx_status__in=['done']) + eligible_bounties = bounties.filter(idx_status__in=['done', 'expired', 'cancelled']) + + if eligible_bounties.count() == 0: + return -1 + + return int(completed_bounties.count() * 100 / eligible_bounties.count()) + + def calc_rep_number(self): + """ + + Returns: + the REP points that the user has. + + """ + rep = self.repentries.order_by('-created_on') + if rep.exists(): + return rep.first().balance + return 0 + @property def get_quarterly_stats(self): """Generate last 90 days stats for this user. @@ -3094,6 +3254,15 @@ def psave_profile(sender, instance, **kwargs): instance.handle = instance.handle.lower() instance.actions_count = instance.get_num_actions + instance.calculate_and_save_persona() + + instance.activity_level = instance.calc_activity_level() + instance.longest_streak = instance.calc_longest_streak() + instance.num_repeated_relationships = instance.calc_num_repeated_relationships() + instance.avg_hourly_rate = instance.calc_avg_hourly_rate() + instance.success_rate = instance.calc_success_rate() + instance.rep = instance.calc_rep_number() + @receiver(user_logged_in) def post_login(sender, request, user, **kwargs): @@ -3187,6 +3356,27 @@ class Meta: def __str__(self): return f"{self.action} by {self.profile} at {self.created_on}" + def point_value(self): + """ + + Returns: + int the Point value of this user action + """ + return point_values.get(self.action, 0) + + +@receiver(post_save, sender=UserAction, dispatch_uid="post_add_ua") +def post_add_ua(sender, instance, created, **kwargs): + if created: + # add REP + if instance.point_value(): + REPEntry.objects.create( + why=instance.action, + profile=instance.profile, + source=instance, + value=instance.point_value(), + ) + class CoinRedemption(SuperModel): """Define the coin redemption schema.""" @@ -3500,3 +3690,24 @@ def post_add_profileview(sender, instance, created, **kwargs): dupes = dupes.filter(viewer=instance.viewer) for dupe in dupes: dupe.delete() + +class REPEntry(SuperModel): + """Records REP .""" + + why = models.CharField(max_length=50) + profile = models.ForeignKey('dashboard.Profile', related_name='repentries', on_delete=models.CASCADE, db_index=True) + source_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) + source_id = models.PositiveIntegerField() + source = GenericForeignKey('source_type', 'source_id') + value = models.PositiveIntegerField() + balance = models.PositiveIntegerField() + + def __str__(self): + return f"{self.profile.handle} + {self.value} => {self.balance} on {self.created_on}" + + +@receiver(pre_save, sender=REPEntry, dispatch_uid="post_add_rep") +def psave_rep(sender, instance, **kwargs): + instance.balance = sum(REPEntry.objects.filter(profile=instance.profile).values_list('value', flat=True)) + + diff --git a/app/dashboard/points.py b/app/dashboard/points.py new file mode 100644 index 00000000000..f8fffbef5fa --- /dev/null +++ b/app/dashboard/points.py @@ -0,0 +1,19 @@ +point_values = { + 'Login': 1, + 'Visit': 1, + 'new_tip': 1, + 'send_tip': 1, + 'new_grant_subscription': 2, + 'new_grant_contribution': 2, + 'new_kudos': 2, + 'new_bounty': 8, + 'worker_approved': 3, + 'worker_rejected': 2, + 'increase_payout': 1, + 'increased_bounty': 1, + 'new_crowdfund': 2, + 'worker_applied': 2, + 'start_work': 3, + 'work_submitted': 5, + 'work_done': 8, +} \ No newline at end of file diff --git a/app/dashboard/templates/profiles/activity_stats.html b/app/dashboard/templates/profiles/activity_stats.html index 2ab0ecc6962..a4acf871d2f 100644 --- a/app/dashboard/templates/profiles/activity_stats.html +++ b/app/dashboard/templates/profiles/activity_stats.html @@ -1,30 +1,36 @@ +{% load humanize %}
  • - Last Seen: x days ago + Last Seen: {{profile.last_visit|naturaltime}} +
  • +
  • + Joined: {{profile.created_on|naturaltime}}
  • {% if profile.persona_is_hunter %}
  • - Top Skills: x, y, z + Top Skills: {{profile.keywords|join:", "}} +
  • + {% endif %} + {% if profile.success_rate != -1 %} +
  • + Success Rate: {{profile.success_rate}}%
  • {% endif %}
  • - Success Rate: x% -
  • -
  • - Repeat {% if profile.persona_is_funder %}Workers{%else%}Funders{%endif%}: x + Repeat {% if profile.persona_is_funder %}Workers{%else%}Funders{%endif%}: {{profile.num_repeated_relationships}}
  • {% if is_staff %} {% if profile.persona_is_hunter %}
  • - Longest activity streak: x days + Longest activity streak: {{profile.longest_streak}} weekdays
  • {% endif %}
  • - Activity Level: x + Activity Level: {{profile.activity_level}}
  • - REP: x + REP: {{profile.rep}}
  • - Avg Hourly Rate $x + Avg Hourly Rate ${{profile.avg_hourly_rate}}
  • {% endif %} diff --git a/app/dashboard/templates/profiles/heatmap.html b/app/dashboard/templates/profiles/heatmap.html index 24ce0fa530e..0dfb89b334a 100644 --- a/app/dashboard/templates/profiles/heatmap.html +++ b/app/dashboard/templates/profiles/heatmap.html @@ -8,6 +8,11 @@
    From 75b13155f17181f69552c8fb20e43b4ec656febf Mon Sep 17 00:00:00 2001 From: Owocki Date: Mon, 9 Sep 2019 14:39:16 -0600 Subject: [PATCH 045/131] make fix --- app/dashboard/admin.py | 4 ++-- app/dashboard/management/commands/create_rep_records.py | 6 +++--- app/dashboard/models.py | 8 +++----- app/dashboard/points.py | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/app/dashboard/admin.py b/app/dashboard/admin.py index e8191d2708b..17f46b9a9fd 100644 --- a/app/dashboard/admin.py +++ b/app/dashboard/admin.py @@ -25,8 +25,8 @@ from .models import ( Activity, BlockedUser, Bounty, BountyFulfillment, BountyInvites, BountySyncRequest, CoinRedemption, CoinRedemptionRequest, Coupon, FeedbackEntry, HackathonEvent, HackathonSponsor, Interest, LabsResearch, Profile, - ProfileView, RefundFeeRequest, SearchHistory, Sponsor, Tip, TokenApproval, Tool, ToolVote, UserAction, - UserVerificationModel, REPEntry + ProfileView, RefundFeeRequest, REPEntry, SearchHistory, Sponsor, Tip, TokenApproval, Tool, ToolVote, UserAction, + UserVerificationModel, ) diff --git a/app/dashboard/management/commands/create_rep_records.py b/app/dashboard/management/commands/create_rep_records.py index 4ab4ecb09d7..918f841f3ae 100644 --- a/app/dashboard/management/commands/create_rep_records.py +++ b/app/dashboard/management/commands/create_rep_records.py @@ -18,7 +18,7 @@ from django.core.management.base import BaseCommand -from dashboard.models import Activity, UserAction, REPEntry +from dashboard.models import Activity, REPEntry, UserAction class Command(BaseCommand): @@ -27,7 +27,7 @@ class Command(BaseCommand): def handle(self, *args, **options): for instance in Activity.objects.all().order_by('created_on'): - if instance.point_value(): + if instance.point_value() and instance.profile: print(instance.pk) REPEntry.objects.create( why=instance.activity_type, @@ -37,7 +37,7 @@ def handle(self, *args, **options): ) for instance in UserAction.objects.all().order_by('created_on'): - if instance.point_value(): + if instance.point_value() and instance.profile: print(instance.pk) REPEntry.objects.create( why=instance.action, diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 23aa281c53a..0ab9e2e3113 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -27,6 +27,8 @@ from django.conf import settings from django.contrib.auth.models import User from django.contrib.auth.signals import user_logged_in, user_logged_out +from django.contrib.contenttypes.fields import GenericForeignKey +from django.contrib.contenttypes.models import ContentType from django.contrib.humanize.templatetags.humanize import naturalday, naturaltime from django.contrib.postgres.fields import ArrayField, JSONField from django.core.validators import MaxValueValidator, MinValueValidator @@ -40,14 +42,12 @@ from django.urls.exceptions import NoReverseMatch from django.utils import timezone from django.utils.translation import gettext_lazy as _ -from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType import pytz import requests from app.utils import get_upload_filename -from dashboard.tokens import addr_to_token from dashboard.points import point_values +from dashboard.tokens import addr_to_token from economy.models import ConversionRate, SuperModel from economy.utils import ConversionRateNotFoundError, convert_amount, convert_token_to_usdt from gas.utils import recommend_min_gas_price_to_confirm_in_time @@ -3709,5 +3709,3 @@ def __str__(self): @receiver(pre_save, sender=REPEntry, dispatch_uid="post_add_rep") def psave_rep(sender, instance, **kwargs): instance.balance = sum(REPEntry.objects.filter(profile=instance.profile).values_list('value', flat=True)) - - diff --git a/app/dashboard/points.py b/app/dashboard/points.py index f8fffbef5fa..b7fd9acf335 100644 --- a/app/dashboard/points.py +++ b/app/dashboard/points.py @@ -16,4 +16,4 @@ 'start_work': 3, 'work_submitted': 5, 'work_done': 8, -} \ No newline at end of file +} From 0c60cf73b21378b1bbddf5d8a4bec3365d698bbc Mon Sep 17 00:00:00 2001 From: Owocki Date: Mon, 9 Sep 2019 15:18:45 -0600 Subject: [PATCH 046/131] profile rep --- app/app/urls.py | 1 + .../management/commands/create_rep_records.py | 2 + .../templates/profiles/REPgraph.html | 97 +++++++++++++++++++ app/dashboard/templates/profiles/heatmap.html | 4 +- .../templates/profiles/tab_activity.html | 2 +- app/dashboard/views.py | 28 +++++- 6 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 app/dashboard/templates/profiles/REPgraph.html diff --git a/app/app/urls.py b/app/app/urls.py index b88748e5b67..b9a6b0637b3 100644 --- a/app/app/urls.py +++ b/app/app/urls.py @@ -95,6 +95,7 @@ # api views url(r'^api/v0.1/profile/(.*)?/keywords', dashboard.views.profile_keywords, name='profile_keywords'), url(r'^api/v0.1/profile/(.*)?/activity.json', dashboard.views.profile_activity, name='profile_activity'), + url(r'^api/v0.1/profile/(.*)?/rep.csv', dashboard.views.profile_rep, name='profile_rep'), url(r'^api/v0.1/profile/banner', dashboard.views.change_user_profile_banner, name='change_user_profile_banner'), url(r'^api/v0.1/activity', retail.views.create_status_update, name='create_status_update'), url( diff --git a/app/dashboard/management/commands/create_rep_records.py b/app/dashboard/management/commands/create_rep_records.py index 918f841f3ae..1eb7734f982 100644 --- a/app/dashboard/management/commands/create_rep_records.py +++ b/app/dashboard/management/commands/create_rep_records.py @@ -30,6 +30,7 @@ def handle(self, *args, **options): if instance.point_value() and instance.profile: print(instance.pk) REPEntry.objects.create( + created_on=instance.created_on, why=instance.activity_type, profile=instance.profile, source=instance, @@ -40,6 +41,7 @@ def handle(self, *args, **options): if instance.point_value() and instance.profile: print(instance.pk) REPEntry.objects.create( + created_on=instance.created_on, why=instance.action, profile=instance.profile, source=instance, diff --git a/app/dashboard/templates/profiles/REPgraph.html b/app/dashboard/templates/profiles/REPgraph.html new file mode 100644 index 00000000000..def49bb6a7d --- /dev/null +++ b/app/dashboard/templates/profiles/REPgraph.html @@ -0,0 +1,97 @@ +{% load humanize %} + + + + + +
    +
    + {{profile.rep}} REP +
    +
    + + +
    \ No newline at end of file diff --git a/app/dashboard/templates/profiles/heatmap.html b/app/dashboard/templates/profiles/heatmap.html index 0dfb89b334a..ea29ab4dc70 100644 --- a/app/dashboard/templates/profiles/heatmap.html +++ b/app/dashboard/templates/profiles/heatmap.html @@ -1,10 +1,12 @@ +{% load humanize %} +
    - X Activity Level; RecentlyXXXXX Active + {{profile.activity_level}} Activity Level; Active {{profile.last_visit|naturaltime}}
    @@ -122,4 +128,4 @@ {% endif %} - + \ No newline at end of file diff --git a/app/dashboard/templates/profiles/scorecard_funder.html b/app/dashboard/templates/profiles/scorecard_funder.html index 6f0b76f55ab..2def73ded92 100644 --- a/app/dashboard/templates/profiles/scorecard_funder.html +++ b/app/dashboard/templates/profiles/scorecard_funder.html @@ -1,40 +1,38 @@ {% load i18n static avatar_tags %} -
    -
    -
    - {% if scoreboard_position_funder %} - #{{ scoreboard_position_funder }} - {% else %} -   - {% endif %} - {% trans "Funder" %} - {% include "shared/profile_rank_link.html" with link='payers' %} -
    -
    -
      -
    • - {% if works_with_funded|length %} - {% trans "Funds" %}: - {% for profile, num_times in works_with_funded.items %} - {% if forloop.counter < 6 %} - - - - {% endif %} - {% endfor %} - {% if works_with_funded|length > 5 %} -
      +{{works_with_funded|length|add:"-5"}}
      - {% endif %} - {% endif %} -
    • -
    -
    - {% trans "Stats" %} -
    -
    -
  • {{ funded_bounties_count }} {% trans "bounties funded" %}
  • -
  • {{ sum_eth_funded|floatformat:2 }} ETH {% trans "funded" %}
  • - {% include "profiles/activity_stats.html" %} - -
    -
    \ No newline at end of file +
    +
    +
    +
    +
    + {% if scoreboard %} + #{{ scoreboard }} + {% else %} +   + {% endif %} + {% trans "Funder" %} + {% include "shared/profile_rank_link.html" with link='payers' %} +
    +
    +
      +
    • {{ funded_bounties_count }} {% trans "bounties funded" %}
    • +
    • {{ sum_eth_funded|floatformat:2 }} ETH {% trans "funded" %}
    • +
    • + {% if works_with_funded|length %} + {% trans "Funds" %}: + {% for profile, num_times in works_with_funded.items %} + {% if forloop.counter < 6 %} + + + + {% endif %} + {% endfor %} + {% if works_with_funded|length > 5 %} +
      +{{works_with_funded|length|add:"-5"}}
      + {% endif %} + {% endif %} +
    • +
    +
    +
    +
    + {% include "profiles/activity_level.html" with level='High'%} diff --git a/app/dashboard/templates/profiles/scorecard_hunter.html b/app/dashboard/templates/profiles/scorecard_hunter.html index 928e14a426d..0ca92a22251 100644 --- a/app/dashboard/templates/profiles/scorecard_hunter.html +++ b/app/dashboard/templates/profiles/scorecard_hunter.html @@ -1,7 +1,7 @@ {% load i18n static avatar_tags %}
    -
    +
    {% if scoreboard_position_contributor %} @@ -37,5 +37,5 @@
    - {% include "profiles/activity_stats.html" %} -
    \ No newline at end of file +
    + {% include "profiles/activity_level.html" with level='High' %} From 920fc51f34690e66bbeb7a48cf3796b001f10f71 Mon Sep 17 00:00:00 2001 From: Onuwa Nnachi Isaac Date: Mon, 9 Sep 2019 12:30:37 +0100 Subject: [PATCH 051/131] Update profile designs --- app/assets/v2/css/profile.css | 202 +++--------------- app/dashboard/templates/profiles/profile.html | 28 +-- .../templates/profiles/tab_activity.html | 9 +- .../templates/profiles/tab_portfolio.html | 55 +++-- .../templates/profiles/tab_ratings.html | 59 ++--- .../templates/profiles/tab_resume.html | 29 ++- app/dashboard/templates/profiles/tabs.html | 77 ++++++- app/dashboard/templates/shared/feedback.html | 33 +-- app/dashboard/views.py | 3 +- 9 files changed, 242 insertions(+), 253 deletions(-) diff --git a/app/assets/v2/css/profile.css b/app/assets/v2/css/profile.css index 4f8c1d4a167..9bdd6c1e28c 100644 --- a/app/assets/v2/css/profile.css +++ b/app/assets/v2/css/profile.css @@ -1,175 +1,44 @@ - -.mh-150{ - min-height: 150px; -} - -.overflow-visible { - overflow: visible; -} - -.profile-card { - background: white; - border-radius: 5px; - z-index: 1; - position: relative; - padding: 2rem; -} - -.profile-header__avatar { - float: left; - width: 7.25rem; - height: 7.25rem; - border-radius: 50%; -} - -.profile-header { - position: relative; - min-height: 450px; -} - -.profile-header__handle { - padding-top: 0.8rem; - margin-bottom: 0; - line-height: 1; - font-weight: 700; - font-size: 1.7rem; -} - -.profile-header__handle small { - text-transform: none; -} - -.profile-header__bio { - clear: both; -} - -.profile-bounties__group-title > i { - color: #25E899; -} - -.profile-header__links { - margin: 0; - padding: 0; -} - -.profile-header__links a { - margin-left: 2px; - margin-right: 2px; - font-size: 1.2rem; - transition: all 0.3s; - color: #000; - text-decoration: none; -} - -.profile-header__links a:hover i { - color: #1AB56D; -} - -.profile-header__links img { - width: 1.5rem; - height: 1.5rem; - margin-right: 0.5em; - filter: invert(100%); -} - -.float_avatar_image { - margin-top: -140px; - position: relative; -} - -.float_avatar_image img { - height: 186px; - width: 186px; - border: 3px solid #FFFFFF; - box-shadow: 0 -2px 4px 0 rgba(0,0,0,0.50); -} - -.avatar_edit { - text-align: center; - background: linear-gradient(to top,rgba(255,255,255,0.6),rgba(255,255,255,0.0)); - border-radius: 0% 0% 50% 50% / 0% 0% 100% 100%; - color: black; - height: 90px; - width: 180px; - position: absolute; - top: 93px; - margin: auto; - right: 0; - left: 0; - transition: .2s all linear; -} - -.avatar_edit_text { - position: absolute; - top: 50%; - color: black; - font-weight: bold; - font-size: 20px; - margin: auto; - width: 100%; - height: 40px; -} - -.is_editable a:hover .profile-header__avatar{ - border: 3px solid #0fce7c; -} - -.is_editable{ - cursor: pointer; -} - -a:hover .avatar_edit { - background-color: rgba(255, 255, 255, 0.7); - height: 180px; - width: 180px; - top: 3px; - border-radius: 50%; -} - -a:hover .avatar_edit .avatar_edit_text { - top: 40%; -} - -.picky img { - width: 100%; - height: auto; - vertical-align: middle; -} - - -.profile-organizations .organization { - display: inline-block; -} - -.profile-bounties--activities{ - min-height: 200px; -} - -.profile-organizations .organization img{ - max-height: 4rem; - max-width: 4rem; - margin-right: 0.5rem; - margin-bottom: 0.5rem; - border-radius: 50%; -} - - -@media (max-width: 1200px) { - .profile-header{ - min-height: 350px; +.tab1, .tab3, .tab4{ + display: none; } -} - -@media (max-width: 767.98px) { - .profile-header__main-infos { - text-align: center; + .tab-projects__item img { + width: 50px; + height: 50px; + } + + .tag-list .tag-list__item { + background: #E8F0FA; + padding: 4px; + border-radius: 2px; + font-size: 14px; + color: #6487AE; } - .profile-header{ - min-height: 200px; + .review-comment { + background: #E4E6E7; + border-radius: 5px; + padding: 5px 7px; + font-size: 12px; + color: #666666; } + .mh-150{ + min-height: 150px; + } + + .overflow-visible { + overflow: visible; + } + + .profile-card { + background: white; + border-radius: 5px; + z-index: 1; + position: relative; + padding: 2rem; + } + .profile-header__avatar { float: left; width: 7.25rem; @@ -284,7 +153,6 @@ a:hover .avatar_edit .avatar_edit_text { /* a:hover .avatar_edit .avatar_edit_text { top: 40%; } */ - .picky img { width: 100%; height: auto; diff --git a/app/dashboard/templates/profiles/profile.html b/app/dashboard/templates/profiles/profile.html index b50ed8b5c3e..a80ad9dd520 100644 --- a/app/dashboard/templates/profiles/profile.html +++ b/app/dashboard/templates/profiles/profile.html @@ -69,29 +69,17 @@
    {% endif%} + {% include 'profiles/tabs.html' %} + +
    +
    {% if hidden %} {% include 'profiles/hidden.html' %} {% else %} - {% include 'profiles/tabs.html' %} - - {% if tab == 'kudos' %} - {% include 'profiles/tab_kudos.html' %} - {% elif tab == 'resume' %} - {% include 'profiles/tab_resume.html' %} - {% elif tab == 'active' %} - {% include 'profiles/tab_active.html' %} - {% elif tab == 'portfolio' %} - {% include 'profiles/tab_portfolio.html' %} - {% elif tab == 'activity' %} - {% include 'profiles/tab_activity.html' %} - {% elif tab == 'ratings' %} - {% include 'profiles/tab_ratings.html' %} - {% elif tab == 'viewers' %} - {% include 'profiles/tab_viewers.html' %} - {% endif %} - {% endif %} - - {% if none %} + + {% if tabs %} + {% include 'profiles/tab_workedwith.html' %} + {% else %} {% include 'profiles/none.html' %} {% endif %} diff --git a/app/dashboard/templates/profiles/tab_activity.html b/app/dashboard/templates/profiles/tab_activity.html index ae07cbfba88..335323f0a72 100644 --- a/app/dashboard/templates/profiles/tab_activity.html +++ b/app/dashboard/templates/profiles/tab_activity.html @@ -15,15 +15,10 @@
    {% if is_my_profile %} -
    -
    - {% include 'profiles/status_box.html' %} -
    -
    + {% include 'profiles/status_box.html' %} {% endif %} - -
    +
    diff --git a/app/dashboard/templates/profiles/tab_portfolio.html b/app/dashboard/templates/profiles/tab_portfolio.html index b263f12d905..75cb66354bf 100644 --- a/app/dashboard/templates/profiles/tab_portfolio.html +++ b/app/dashboard/templates/profiles/tab_portfolio.html @@ -1,16 +1,43 @@ {% load i18n static %} +
    Top Skills
    +
    + Python + Django + Ethereum + Solidity +
    +
    +
    Projects
    -
    -
    - Built Foo the Bar now for @owocki 10 days ago, for the Grow Ethereum Hackathon. Skills used: Python, Django -
    -
    - Built Foo the Bar now for @owocki 10 days ago, for the Grow Ethereum Hackathon. Skills used: Python, Django -
    -
    - Built Foo the Bar now for @owocki 10 days ago, for the Grow Ethereum Hackathon. Skills used: Python, Django -
    -
    - Built Foo the Bar now for @owocki 10 days ago, for the Grow Ethereum Hackathon. Skills used: Python, Django -
    -
    \ No newline at end of file +
    +
    + +
    +
    +
    ENS + Arweave
      + for Arweave +
    +
    + Python + Django + Ethereum + Solidity +
    +
    +
    +
    + +
    +
    +
    ENS + Arweave
      + for Arweave +
    +
    + Python + Django + Ethereum + Solidity +
    +
    +
    +
    diff --git a/app/dashboard/templates/profiles/tab_ratings.html b/app/dashboard/templates/profiles/tab_ratings.html index e5b30b9d6c3..b816ca6d59f 100644 --- a/app/dashboard/templates/profiles/tab_ratings.html +++ b/app/dashboard/templates/profiles/tab_ratings.html @@ -1,26 +1,33 @@ -{% load i18n static humanize %} - - {% if not hidden %} - {% if is_editable %} -
    - {% include "shared/rate_bounties.html" %} -
    - {% endif %} - -
    -
    {% trans "Reviews Received" %}
    - {% for feedback in feedbacks_got %} - {% include "shared/feedback.html" %} - {% endfor %} -
    - -
    -
    {% trans "Reviews Sent" %}
    - {% for feedback in feedbacks_sent %} - {% include "shared/feedback.html" %} - {% endfor %} -
    - - {% endif %} - - {% endif %} +{% load i18n static %} +
    + {% for i in ratings %} + + {% endfor %} +
    +   {{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}} +
    +
    +
    +
    + Satisfaction {{feedback.satisfaction_rating}} +
    +
    + Speed {{feedback.speed_rating}} +
    +
    + Recommended to other funders {{feedback.recommendation_rating}} +
    +
    + Communication/Responsiveness {{feedback.communication_rating}} +
    +
    + Quality of Code Submission {{feedback.code_quality_rating}} +
    +
    +
    +
    +
    Reviews
    + {% for feedback in feedbacks_got %} + {% include "shared/feedback.html" %} + {% endfor %} +
    diff --git a/app/dashboard/templates/profiles/tab_resume.html b/app/dashboard/templates/profiles/tab_resume.html index 94958a4c6d4..36614b9f2d7 100644 --- a/app/dashboard/templates/profiles/tab_resume.html +++ b/app/dashboard/templates/profiles/tab_resume.html @@ -1,7 +1,30 @@ {% load i18n static %} {% if not hidden and not profile.is_org and show_resume_tab %} -
    +
    Job Preferences
    +
      +
    • + Actively looking for (Full Time, Part Time, Contract) +
    • +
    • + Looking for companies in USA, Remote +
    • +
    • + Compensation Expectation USD $10,000/month +
    • +
    +
    + {% if profile.resume %} +
    +
    Resume
    + Download Resume +
    + + + + {% endif %} + + + + {% endif %} diff --git a/app/dashboard/templates/profiles/tabs.html b/app/dashboard/templates/profiles/tabs.html index b80b2cc16a8..be5021e5945 100644 --- a/app/dashboard/templates/profiles/tabs.html +++ b/app/dashboard/templates/profiles/tabs.html @@ -1,6 +1,6 @@ {% load i18n static %} {% if not hidden and not profile.is_org %} -
    + +
    + +
    +
    +
    +
    +
    +
    + {% include 'profiles/tab_activity.html' %} +
    +
    +
    +
    +
    +
    +
    +
    + {% include 'profiles/tab_resume.html' %} +
    +
    +
    +
    +
    +
    +
    +
    + {% include 'profiles/tab_ratings.html' %} +
    +
    +
    +
    +
    +
    +
    +
    + {% include 'profiles/tab_portfolio.html' %} +
    +
    +
    +
    +
    +
    +
    +
    + {% include "shared/profile_kudos.html" %} +
    +
    +
    +
    +
    {% endif %} \ No newline at end of file diff --git a/app/dashboard/templates/shared/feedback.html b/app/dashboard/templates/shared/feedback.html index 6d39e98bd26..6bc80f30df7 100644 --- a/app/dashboard/templates/shared/feedback.html +++ b/app/dashboard/templates/shared/feedback.html @@ -15,20 +15,25 @@ along with this program. If not, see . {% endcomment %} {% load i18n staticfiles %} -
    -
    -
    - {{ feedback.sender_profile }} -
    {{ feedback.sender_profile }}
    +
    +
    +
    + +
    -
    - {% for i in ratings %} - - {% endfor %} +
    +
    +
    +
    + @{{feedback.sender_profile}} + for {{feedback.bounty.org_name}}: {{feedback.bounty.title}} +
    +
    + {% for i in ratings %} + + {% endfor %} +
    - {% if feedback.comment %} -
    {{ feedback.comment }}
    - {% endif %} - View Bounty
    -
    \ No newline at end of file +
    +{{ feedback.comment }} \ No newline at end of file diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 17d1edd3c00..5d95c44d24c 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -2012,7 +2012,8 @@ def get_profile_tab(request, profile, tab, prev_context): context['is_editable'] = context['is_my_profile'] # or context['is_my_org'] context['ratings'] = range(0,5) context['profile'] = profile - # context['show_resume_tab'] = profile.show_job_status or context['is_my_profile'] + # context['show_resume_tab'] = profile.show_job_status if context['is_my_profile'] + context['show_resume_tab'] = True tabs = [] counts = all_activities.values('activity_type').order_by('activity_type').annotate(the_count=Count('activity_type')) From 4592e1fafa56450a3db5c84a67858797a7d0cacc Mon Sep 17 00:00:00 2001 From: Onuwa Nnachi Isaac Date: Mon, 9 Sep 2019 12:44:51 +0100 Subject: [PATCH 052/131] Fix resume UI --- .../templates/profiles/tab_resume.html | 99 ++----------------- app/dashboard/templates/profiles/tabs.html | 2 +- 2 files changed, 11 insertions(+), 90 deletions(-) diff --git a/app/dashboard/templates/profiles/tab_resume.html b/app/dashboard/templates/profiles/tab_resume.html index 36614b9f2d7..32a01edca05 100644 --- a/app/dashboard/templates/profiles/tab_resume.html +++ b/app/dashboard/templates/profiles/tab_resume.html @@ -2,104 +2,25 @@ {% if not hidden and not profile.is_org and show_resume_tab %}
    Job Preferences
    -
      -
    • +
      +
      Actively looking for (Full Time, Part Time, Contract) -
    • -
    • - Looking for companies in USA, Remote -
    • -
    • +
    +
    + Looking for companies in {% for loc in profile.job_location %}{{loc.name}}, {% endfor %} +
    +
    Compensation Expectation USD $10,000/month - - +
    +
    {% if profile.resume %}
    -
    Resume
    +
    Resume
    Download Resume
    {% endif %} - - - - {% endif %} diff --git a/app/dashboard/templates/profiles/tabs.html b/app/dashboard/templates/profiles/tabs.html index be5021e5945..43bfda7fb7b 100644 --- a/app/dashboard/templates/profiles/tabs.html +++ b/app/dashboard/templates/profiles/tabs.html @@ -76,7 +76,7 @@
    -
    +
    From 66465f3fa7e748415abaa7f9488a350a28f321de Mon Sep 17 00:00:00 2001 From: Onuwa Nnachi Isaac Date: Mon, 9 Sep 2019 15:51:42 +0100 Subject: [PATCH 053/131] Fix lint issues --- app/assets/v2/css/profile.css | 36 ++-- .../templates/profiles/activity_level.html | 44 ++-- .../templates/profiles/header_avatar.html | 34 ++-- app/dashboard/templates/profiles/profile.html | 62 +++--- .../templates/profiles/scorecard_funder.html | 68 +++---- .../templates/profiles/scorecard_hunter.html | 78 ++++---- .../templates/profiles/tab_resume.html | 51 ++--- .../templates/profiles/tab_workedwith.html | 24 +++ app/dashboard/templates/profiles/tabs.html | 188 +++++++----------- app/dashboard/templates/shared/feedback.html | 42 ++-- app/dashboard/views.py | 2 +- 11 files changed, 301 insertions(+), 328 deletions(-) create mode 100644 app/dashboard/templates/profiles/tab_workedwith.html diff --git a/app/assets/v2/css/profile.css b/app/assets/v2/css/profile.css index 9bdd6c1e28c..20b30aa728a 100644 --- a/app/assets/v2/css/profile.css +++ b/app/assets/v2/css/profile.css @@ -2,26 +2,26 @@ display: none; } - .tab-projects__item img { - width: 50px; - height: 50px; - } +.tab-projects__item img { + width: 50px; + height: 50px; +} - .tag-list .tag-list__item { - background: #E8F0FA; - padding: 4px; - border-radius: 2px; - font-size: 14px; - color: #6487AE; - } +.tag-list .tag-list__item { + background: #E8F0FA; + padding: 4px; + border-radius: 2px; + font-size: 14px; + color: #6487AE; +} - .review-comment { - background: #E4E6E7; - border-radius: 5px; - padding: 5px 7px; - font-size: 12px; - color: #666666; - } +.review-comment { + background: #E4E6E7; + border-radius: 5px; + padding: 5px 7px; + font-size: 12px; + color: #666666; +} .mh-150{ min-height: 150px; diff --git a/app/dashboard/templates/profiles/activity_level.html b/app/dashboard/templates/profiles/activity_level.html index 492b81ac040..6682858fbcd 100644 --- a/app/dashboard/templates/profiles/activity_level.html +++ b/app/dashboard/templates/profiles/activity_level.html @@ -1,26 +1,26 @@ {% load i18n static avatar_tags %}
    -
    -
    - {% if level %} - #{{ level }} - {% else %} -   - {% endif %} - {% trans "Activity Level" %} -
    -
    -
      -
    • {% trans "Last seen" %} 2 days ago
    • -
    • 100 days {% trans "longest streak" %}
    • -
    • 10 {% trans "repeat relationships" %}
    • -
    • - {% for i in ratings %} - - {% endfor %} - ({{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}}) -
    • -
    -
    +
    +
    + {% if level %} + #{{ level }} + {% else %} +   + {% endif %} + {% trans "Activity Level" %}
    +
    +
      +
    • {% trans "Last seen" %} 2 days ago
    • +
    • 100 days {% trans "longest streak" %}
    • +
    • 10 {% trans "repeat relationships" %}
    • +
    • + {% for rating in ratings %} + + {% endfor %} + ({{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}}) +
    • +
    +
    +
    \ No newline at end of file diff --git a/app/dashboard/templates/profiles/header_avatar.html b/app/dashboard/templates/profiles/header_avatar.html index 449c432a3c3..2c9f4948adb 100644 --- a/app/dashboard/templates/profiles/header_avatar.html +++ b/app/dashboard/templates/profiles/header_avatar.html @@ -1,18 +1,18 @@ {% load i18n static avatar_tags %} - \ No newline at end of file + \ No newline at end of file diff --git a/app/dashboard/templates/profiles/profile.html b/app/dashboard/templates/profiles/profile.html index a80ad9dd520..155b74c9bb1 100644 --- a/app/dashboard/templates/profiles/profile.html +++ b/app/dashboard/templates/profiles/profile.html @@ -22,22 +22,22 @@ {% include 'shared/top_nav.html' with class='d-md-flex' %} {% include 'home/nav.html' %}
    - {% csrf_token %} - {% if is_editable %} + {% csrf_token %} + {% if is_editable %}
    -
    -
    -
    - - - Update Header Image - -
    -
    +
    +
    +
    + + + Update Header Image + +
    +
    - {% endif %} - {% if not hidden and is_staff %} + {% endif %} + {% if not hidden and is_staff %}
    Staff only {% trans "Profile Admin" %} @@ -45,44 +45,36 @@ {% endif %}
    -
    -
    -
    - {% if not hidden %} - {% include 'profiles/header_avatar.html' %} - {% include 'profiles/header_details.html' %} +
    +
    +
    + {% if not hidden %} + {% include 'profiles/header_avatar.html' %} + {% include 'profiles/header_details.html' %} {% if not hidden %} {% if profile.is_org %} {% include 'profiles/organization.html' %} {% else %} {% if profile.persona_is_hunter %} - {% include 'profiles/scorecard_hunter.html' %} - {% elif profile.persona_is_funder %} + {% include 'profiles/scorecard_hunter.html' %} + {% elif profile.persona_is_funder %} {% include 'profiles/scorecard_funder.html' %} - {% endif %} -
    -
    {% endif %} - {% endif %}
    - {% endif%} - + {% endif %} + {% endif %} +
    +
    + {% endif%} + {% include 'profiles/tabs.html' %} -
    {% if hidden %} {% include 'profiles/hidden.html' %} - {% else %} - - {% if tabs %} - {% include 'profiles/tab_workedwith.html' %} - {% else %} - {% include 'profiles/none.html' %} {% endif %} -
    {% include 'profiles/tabs_close.html' %} diff --git a/app/dashboard/templates/profiles/scorecard_funder.html b/app/dashboard/templates/profiles/scorecard_funder.html index 2def73ded92..4b5e3f78276 100644 --- a/app/dashboard/templates/profiles/scorecard_funder.html +++ b/app/dashboard/templates/profiles/scorecard_funder.html @@ -1,38 +1,38 @@ {% load i18n static avatar_tags %}
    -
    -
    -
    -
    - {% if scoreboard %} - #{{ scoreboard }} - {% else %} -   - {% endif %} - {% trans "Funder" %} +
    +
    +
    +
    + {% if scoreboard %} + #{{ scoreboard }} + {% else %} +   + {% endif %} + {% trans "Funder" %} {% include "shared/profile_rank_link.html" with link='payers' %} -
    -
    -
      -
    • {{ funded_bounties_count }} {% trans "bounties funded" %}
    • -
    • {{ sum_eth_funded|floatformat:2 }} ETH {% trans "funded" %}
    • -
    • - {% if works_with_funded|length %} - {% trans "Funds" %}: - {% for profile, num_times in works_with_funded.items %} - {% if forloop.counter < 6 %} - - - - {% endif %} - {% endfor %} - {% if works_with_funded|length > 5 %} -
      +{{works_with_funded|length|add:"-5"}}
      - {% endif %} - {% endif %} -
    • -
    -
    -
    - {% include "profiles/activity_level.html" with level='High'%} +
    +
      +
    • {{ funded_bounties_count }} {% trans "bounties funded" %}
    • +
    • {{ sum_eth_funded|floatformat:2 }} ETH {% trans "funded" %}
    • +
    • + {% if works_with_funded|length %} + {% trans "Funds" %}: + {% for profile, num_times in works_with_funded.items %} + {% if forloop.counter < 6 %} + + + + {% endif %} + {% endfor %} + {% if works_with_funded|length > 5 %} +
      +{{works_with_funded|length|add:"-5"}}
      + {% endif %} + {% endif %} +
    • +
    +
    +
    +
    + {% include "profiles/activity_level.html" with level='High'%} diff --git a/app/dashboard/templates/profiles/scorecard_hunter.html b/app/dashboard/templates/profiles/scorecard_hunter.html index 0ca92a22251..371b9f2c4ce 100644 --- a/app/dashboard/templates/profiles/scorecard_hunter.html +++ b/app/dashboard/templates/profiles/scorecard_hunter.html @@ -1,41 +1,41 @@ {% load i18n static avatar_tags %} -
    -
    -
    -
    -
    - {% if scoreboard_position_contributor %} - #{{ scoreboard_position_contributor }} - {% else %} -   - {% endif %} - {% trans "Contributor" %} - {% include "shared/profile_rank_link.html" with link='earners' %} -
    -
    -
      -
    • {{ count_bounties_completed }} {% trans "bounties completed" %}
    • -
    • {{ sum_eth_collected|floatformat:2 }} ETH {% trans "collected" %}
    • - {% if no_times_been_removed %} -
    • - {% trans "removed from" %} {{ no_times_been_removed }} {% trans "bounties" %}
    • - {% endif %} -
    • - {% if works_with_collected|length %} - Contributes To: - {% for profile, num_times in works_with_collected.items %} - {% if forloop.counter < 6 %} - - - - {% endif %} - {% endfor %} - {% if works_with_collected|length > 5 %} -
      +{{works_with_collected|length|add:"-5"}}
      - {% endif %} +
      +
      +
      +
      +
      + {% if scoreboard_position_contributor %} + #{{ scoreboard_position_contributor }} + {% else %} +   + {% endif %} + {% trans "Contributor" %} + {% include "shared/profile_rank_link.html" with link='earners' %} +
      +
      +
        +
      • {{ count_bounties_completed }} {% trans "bounties completed" %}
      • +
      • {{ sum_eth_collected|floatformat:2 }} ETH {% trans "collected" %}
      • + {% if no_times_been_removed %} +
      • - {% trans "removed from" %} {{ no_times_been_removed }} {% trans "bounties" %}
      • + {% endif %} +
      • + {% if works_with_collected|length %} + Contributes To: + {% for profile, num_times in works_with_collected.items %} + {% if forloop.counter < 6 %} + + + {% endif %} -
      • -
      -
      -
      -
      - {% include "profiles/activity_level.html" with level='High' %} + {% endfor %} + {% if works_with_collected|length > 5 %} +
      +{{works_with_collected|length|add:"-5"}}
      + {% endif %} + {% endif %} +
    • +
    +
    +
    +
    + {% include "profiles/activity_level.html" with level='High' %} diff --git a/app/dashboard/templates/profiles/tab_resume.html b/app/dashboard/templates/profiles/tab_resume.html index 32a01edca05..9c4b94f9e24 100644 --- a/app/dashboard/templates/profiles/tab_resume.html +++ b/app/dashboard/templates/profiles/tab_resume.html @@ -1,26 +1,29 @@ {% load i18n static %} - {% if not hidden and not profile.is_org and show_resume_tab %} -
    Job Preferences
    -
    -
    - Actively looking for (Full Time, Part Time, Contract) -
    -
    - Looking for companies in {% for loc in profile.job_location %}{{loc.name}}, {% endfor %} -
    -
    - Compensation Expectation USD $10,000/month -
    -
    -
    - {% if profile.resume %} -
    -
    Resume
    - Download Resume -
    - - - - {% endif %} - {% endif %} +{% if not hidden and not profile.is_org and show_resume_tab %} +
    Job Preferences
    +
    +
    + + Actively looking for (Full Time, Part Time, Contract) +
    +
    + + Looking for companies in {% for loc in profile.job_location %}{{loc.name}}, {% endfor %} +
    +
    + + Compensation Expectation USD $10,000/month +
    +
    +
    + {% if profile.resume %} +
    +
    Resume
    + Download Resume +
    + + + + {% endif %} +{% endif %} diff --git a/app/dashboard/templates/profiles/tab_workedwith.html b/app/dashboard/templates/profiles/tab_workedwith.html new file mode 100644 index 00000000000..0b447128b2f --- /dev/null +++ b/app/dashboard/templates/profiles/tab_workedwith.html @@ -0,0 +1,24 @@ +{% load i18n static %} + + {% if not hidden %} + {% if is_editable %} +
    + {% include "shared/rate_bounties.html" %} +
    + {% endif %} + +
    +
    {% trans "Reviews Received" %}
    + {% for feedback in feedbacks_got %} + {% include "shared/feedback.html" %} + {% endfor %} +
    + +
    +
    {% trans "Reviews Sent" %}
    + {% for feedback in feedbacks_sent %} + {% include "shared/feedback.html" %} + {% endfor %} +
    + + {% endif %} diff --git a/app/dashboard/templates/profiles/tabs.html b/app/dashboard/templates/profiles/tabs.html index 43bfda7fb7b..8afc6cde040 100644 --- a/app/dashboard/templates/profiles/tabs.html +++ b/app/dashboard/templates/profiles/tabs.html @@ -1,126 +1,76 @@ {% load i18n static %} - {% if not hidden and not profile.is_org %} - -
    - -
    -
    -
    -
    -
    -
    - {% include 'profiles/tab_activity.html' %} -
    -
    -
    + {% if not hidden and not profile.is_org %} +
    + +
    +
    +
    +
    +
    +
    + {% include 'profiles/tab_activity.html' %}
    -
    -
    -
    -
    - {% include 'profiles/tab_resume.html' %} -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    + {% include 'profiles/tab_resume.html' %}
    -
    -
    -
    -
    - {% include 'profiles/tab_ratings.html' %} -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    + {% include 'profiles/tab_ratings.html' %}
    -
    -
    -
    -
    - {% include 'profiles/tab_portfolio.html' %} -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    + {% include 'profiles/tab_portfolio.html' %}
    -
    -
    -
    -
    - {% include "shared/profile_kudos.html" %} -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    + {% include "shared/profile_kudos.html" %}
    +
    - {% endif %} \ No newline at end of file +
    +
    + {% endif %} \ No newline at end of file diff --git a/app/dashboard/templates/shared/feedback.html b/app/dashboard/templates/shared/feedback.html index 6bc80f30df7..5a1ac183582 100644 --- a/app/dashboard/templates/shared/feedback.html +++ b/app/dashboard/templates/shared/feedback.html @@ -14,26 +14,30 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . {% endcomment %} -{% load i18n staticfiles %} +{% load i18n staticfiles avatar_tags%}
    -
    -
    - - -
    +
    +
    + +
    -
    -
    -
    - @{{feedback.sender_profile}} - for {{feedback.bounty.org_name}}: {{feedback.bounty.title}} -
    -
    - {% for i in ratings %} - - {% endfor %} -
    -
    +
    +
    +
    +
    + @{{feedback.sender_profile}} + for {{feedback.bounty.org_name}}: + {{feedback.bounty.title}} + +
    +
    + {% for rating in ratings %} + + {% endfor %} +
    +
    -{{ feedback.comment }} \ No newline at end of file +{% if feedback.comment %} + {{ feedback.comment }} +{% endif %} \ No newline at end of file diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 5d95c44d24c..a6d6ed06ef3 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -2193,7 +2193,7 @@ def profile(request, handle, tab=None): ).exclude( feedbacks__feedbackType='approver', feedbacks__sender_profile=profile, - ).distinct('pk').nocache() + ).distinct('pk') context['unrated_contributed_bounties'] = Bounty.objects.current().prefetch_related('feedbacks').filter(interested__profile=profile, network=network,) \ .filter(interested__status='okay') \ From 3a4deb70c139c6e3145a1032504dbd03b70f2313 Mon Sep 17 00:00:00 2001 From: Onuwa Nnachi Isaac Date: Mon, 9 Sep 2019 15:51:52 +0100 Subject: [PATCH 054/131] Add progress bar to ratings --- .../templates/profiles/tab_ratings.html | 97 ++++++++++++++----- 1 file changed, 71 insertions(+), 26 deletions(-) diff --git a/app/dashboard/templates/profiles/tab_ratings.html b/app/dashboard/templates/profiles/tab_ratings.html index b816ca6d59f..f04ee73ba1b 100644 --- a/app/dashboard/templates/profiles/tab_ratings.html +++ b/app/dashboard/templates/profiles/tab_ratings.html @@ -1,33 +1,78 @@ {% load i18n static %}
    - {% for i in ratings %} - - {% endfor %} -
    -   {{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}} -
    + {% for i in ratings %} + + {% endfor %} +
    +   {{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}} +
    -
    - Satisfaction {{feedback.satisfaction_rating}} -
    -
    - Speed {{feedback.speed_rating}} -
    -
    - Recommended to other funders {{feedback.recommendation_rating}} -
    -
    - Communication/Responsiveness {{feedback.communication_rating}} -
    -
    - Quality of Code Submission {{feedback.code_quality_rating}} -
    +
    +
    +
    + Satisfaction +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + Speed +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + Recommend to other funders +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + Communication/Responsivess +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + Quality of Code Submission +
    +
    +
    +
    +
    +
    +
    +
    -
    Reviews
    - {% for feedback in feedbacks_got %} - {% include "shared/feedback.html" %} - {% endfor %} -
    +
    Reviews
    + {% for feedback in feedbacks_got %} + {% include "shared/feedback.html" %} + {% endfor %} +
    \ No newline at end of file From d119f251ea915eef91f2c42c1958beafba40584b Mon Sep 17 00:00:00 2001 From: Onuwa Nnachi Isaac Date: Mon, 9 Sep 2019 23:53:42 +0100 Subject: [PATCH 055/131] Update changes --- app/dashboard/views.py | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/app/dashboard/views.py b/app/dashboard/views.py index a6d6ed06ef3..ce62b19ab43 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -2006,14 +2006,8 @@ def get_profile_tab(request, profile, tab, prev_context): all_activities = context.get('activities') - context['avg_rating'] = profile.get_average_star_rating - context['is_my_profile'] = request.user.is_authenticated and request.user.username.lower() == handle.lower() - context['is_my_org'] = request.user.is_authenticated and any([handle.lower() == org.lower() for org in request.user.profile.organizations ]) - context['is_editable'] = context['is_my_profile'] # or context['is_my_org'] - context['ratings'] = range(0,5) - context['profile'] = profile - # context['show_resume_tab'] = profile.show_job_status if context['is_my_profile'] - context['show_resume_tab'] = True + if all_activities.count() == 0: + context['none'] = True tabs = [] counts = all_activities.values('activity_type').order_by('activity_type').annotate(the_count=Count('activity_type')) @@ -2186,22 +2180,8 @@ def profile(request, handle, tab=None): context['suppress_sumo'] = True context['feedbacks_sent'] = profile.feedbacks_sent.all() context['feedbacks_got'] = profile.feedbacks_got.all() - context['unrated_funded_bounties'] = Bounty.objects.current().prefetch_related('fulfillments', 'interested', 'interested__profile', 'feedbacks') \ - .filter( - bounty_owner_github_username__iexact=profile.handle, - network=network, - ).exclude( - feedbacks__feedbackType='approver', - feedbacks__sender_profile=profile, - ).distinct('pk') - - context['unrated_contributed_bounties'] = Bounty.objects.current().prefetch_related('feedbacks').filter(interested__profile=profile, network=network,) \ - .filter(interested__status='okay') \ - .filter(interested__pending=False).filter(idx_status='done') \ - .exclude( - feedbacks__feedbackType='worker', - feedbacks__sender_profile=profile - ).distinct('pk') + context['tab'] = tab + context['show_activity'] = request.GET.get('p', False) != False tab = get_profile_tab(request, profile, tab, context) if type(tab) == dict: From 2219625feb0af187245f04c8931181eea4a56f07 Mon Sep 17 00:00:00 2001 From: Owocki Date: Mon, 9 Sep 2019 18:44:16 -0600 Subject: [PATCH 056/131] smallfix --- app/dashboard/management/commands/create_rep_records.py | 5 +++++ app/dashboard/models.py | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/dashboard/management/commands/create_rep_records.py b/app/dashboard/management/commands/create_rep_records.py index 1eb7734f982..0bb2c1ffeb8 100644 --- a/app/dashboard/management/commands/create_rep_records.py +++ b/app/dashboard/management/commands/create_rep_records.py @@ -26,6 +26,7 @@ class Command(BaseCommand): help = 'creates REP records for current acivity feeds' def handle(self, *args, **options): + #REPEntry.objects.all().delete() for instance in Activity.objects.all().order_by('created_on'): if instance.point_value() and instance.profile: print(instance.pk) @@ -47,3 +48,7 @@ def handle(self, *args, **options): source=instance, value=instance.point_value(), ) + + # make sure balances look ok + for instance in REPEntry.objects.all().order_by('created_on'): + instance.save() diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 0ab9e2e3113..7e8cb81f31e 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -2451,8 +2451,8 @@ def calc_activity_level(self): return "High" if visits_last_month > med_threshold: return "Medium" - if visits_last_month > med_threshold: - return "Low" + return "Low" + def calc_longest_streak(self): @@ -2494,6 +2494,7 @@ def calc_longest_streak(self): def calc_num_repeated_relationships(self): """ the number of repeat relationships that this user has created + Returns: int: a number of repeat relationships @@ -3708,4 +3709,4 @@ def __str__(self): @receiver(pre_save, sender=REPEntry, dispatch_uid="post_add_rep") def psave_rep(sender, instance, **kwargs): - instance.balance = sum(REPEntry.objects.filter(profile=instance.profile).values_list('value', flat=True)) + instance.balance = sum(REPEntry.objects.filter(profile=instance.profile, created_on__lt=instance.created_on).values_list('value', flat=True)) + instance.value From d1574cc644def2763c9e6435530456028a16eb1c Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 15:19:19 -0600 Subject: [PATCH 057/131] med --- app/dashboard/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 7e8cb81f31e..6d43d34fd6e 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -2438,7 +2438,7 @@ def calc_activity_level(self): """ high_threshold = 15 - med_threshold = 15 + med_threshold = 7 new_threshold_days = 7 if self.created_on > (timezone.now() - timezone.timedelta(days=new_threshold_days)): From 8ef46fc0c34061f55ce84ce882309c691aea3d27 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 15:47:53 -0600 Subject: [PATCH 058/131] fixes issue with 3/5 --- .../management/commands/create_rep_records.py | 13 ++++++++----- app/dashboard/models.py | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/dashboard/management/commands/create_rep_records.py b/app/dashboard/management/commands/create_rep_records.py index 0bb2c1ffeb8..f91ce8fae91 100644 --- a/app/dashboard/management/commands/create_rep_records.py +++ b/app/dashboard/management/commands/create_rep_records.py @@ -19,15 +19,17 @@ from django.core.management.base import BaseCommand from dashboard.models import Activity, REPEntry, UserAction - +from django.utils import timezone class Command(BaseCommand): help = 'creates REP records for current acivity feeds' def handle(self, *args, **options): - #REPEntry.objects.all().delete() - for instance in Activity.objects.all().order_by('created_on'): + #REPEntry.objects.all().delete() + # exclude 3/5 to 3/6 where something wonky went on with activity feeds + activities = Activity.objects.exclude(created_on__gt=timezone.datetime(2019,3,5),created_on__lt=timezone.datetime(2019,3,6)).order_by('created_on') + for instance in activities: if instance.point_value() and instance.profile: print(instance.pk) REPEntry.objects.create( @@ -38,7 +40,8 @@ def handle(self, *args, **options): value=instance.point_value(), ) - for instance in UserAction.objects.all().order_by('created_on'): + uas = UserAction.objects.exclude(created_on__gt=timezone.datetime(2019,3,5),created_on__lt=timezone.datetime(2019,3,6)).order_by('created_on') + for instance in uas: if instance.point_value() and instance.profile: print(instance.pk) REPEntry.objects.create( @@ -50,5 +53,5 @@ def handle(self, *args, **options): ) # make sure balances look ok - for instance in REPEntry.objects.all().order_by('created_on'): + for instance in REPEntry.objects.filter(profile__handle='owocki').order_by('created_on'): instance.save() diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 6d43d34fd6e..1801aa26710 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -3710,3 +3710,4 @@ def __str__(self): @receiver(pre_save, sender=REPEntry, dispatch_uid="post_add_rep") def psave_rep(sender, instance, **kwargs): instance.balance = sum(REPEntry.objects.filter(profile=instance.profile, created_on__lt=instance.created_on).values_list('value', flat=True)) + instance.value + #print(f"updating {instance.pk} created on {instance.created_on} for {instance.why} worth {instance.value} to {instance.balance}") From 480be1378f693233fa82b9fbc2048ece41dbb1d8 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 15:50:46 -0600 Subject: [PATCH 059/131] make fix --- app/dashboard/management/commands/create_rep_records.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/dashboard/management/commands/create_rep_records.py b/app/dashboard/management/commands/create_rep_records.py index f91ce8fae91..d5ae4f642b4 100644 --- a/app/dashboard/management/commands/create_rep_records.py +++ b/app/dashboard/management/commands/create_rep_records.py @@ -17,9 +17,10 @@ ''' from django.core.management.base import BaseCommand +from django.utils import timezone from dashboard.models import Activity, REPEntry, UserAction -from django.utils import timezone + class Command(BaseCommand): From 23dc1f6d441ff3d967fb4ed38e719fbdb7f513dd Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 16:27:47 -0600 Subject: [PATCH 060/131] fixes ratings tab to actually be data drive n --- app/dashboard/models.py | 25 +++++++++---------- .../templates/profiles/tab_ratings.html | 14 +++++------ app/dashboard/views.py | 11 ++++---- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 1801aa26710..0fc1724fb09 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -2210,25 +2210,24 @@ def get_num_actions(self): num += self.get_my_grants.count() return num - @property - def get_average_star_rating(self): + def get_average_star_rating(self, scale=1): """Returns the average star ratings (overall and individual topic) for a particular user""" feedbacks = FeedbackEntry.objects.filter(receiver_profile=self).all() average_rating = {} - average_rating['overall'] = sum([feedback.rating for feedback in feedbacks]) \ - / feedbacks.count() if feedbacks.count() != 0 else 0 - average_rating['code_quality_rating'] = sum([feedback.code_quality_rating for feedback in feedbacks]) \ - / feedbacks.count() if feedbacks.count() != 0 else 0 - average_rating['communication_rating'] = sum([feedback.communication_rating for feedback in feedbacks]) \ - / feedbacks.count() if feedbacks.count() != 0 else 0 - average_rating['recommendation_rating'] = sum([feedback.recommendation_rating for feedback in feedbacks]) \ - / feedbacks.count() if feedbacks.count() != 0 else 0 - average_rating['satisfaction_rating'] = sum([feedback.satisfaction_rating for feedback in feedbacks]) \ - / feedbacks.count() if feedbacks.count() != 0 else 0 - average_rating['speed_rating'] = sum([feedback.speed_rating for feedback in feedbacks]) \ + average_rating['overall'] = sum([feedback.rating for feedback in feedbacks]) * scale \ / feedbacks.count() if feedbacks.count() != 0 else 0 + average_rating['code_quality_rating'] = sum([feedback.code_quality_rating for feedback in feedbacks]) * scale \ + / feedbacks.exclude(code_quality_rating=0).count() if feedbacks.exclude(code_quality_rating=0).count() != 0 else 0 + average_rating['communication_rating'] = sum([feedback.communication_rating for feedback in feedbacks]) * scale \ + / feedbacks.exclude(communication_rating=0).count() if feedbacks.exclude(communication_rating=0).count() != 0 else 0 + average_rating['recommendation_rating'] = sum([feedback.recommendation_rating for feedback in feedbacks]) * scale \ + / feedbacks.exclude(recommendation_rating=0).count() if feedbacks.exclude(recommendation_rating=0).count() != 0 else 0 + average_rating['satisfaction_rating'] = sum([feedback.satisfaction_rating for feedback in feedbacks]) * scale \ + / feedbacks.exclude(satisfaction_rating=0).count() if feedbacks.exclude(satisfaction_rating=0).count() != 0 else 0 + average_rating['speed_rating'] = sum([feedback.speed_rating for feedback in feedbacks]) * scale \ + / feedbacks.exclude(speed_rating=0).count() if feedbacks.exclude(speed_rating=0).count() != 0 else 0 average_rating['total_rating'] = feedbacks.count() return average_rating diff --git a/app/dashboard/templates/profiles/tab_ratings.html b/app/dashboard/templates/profiles/tab_ratings.html index f04ee73ba1b..f9f0522a1e5 100644 --- a/app/dashboard/templates/profiles/tab_ratings.html +++ b/app/dashboard/templates/profiles/tab_ratings.html @@ -1,10 +1,10 @@ {% load i18n static %}
    {% for i in ratings %} - + {% endfor %}
    -   {{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}} +   {{ avg_rating_scaled.total_rating }} {% trans "rating" %}{{avg_rating_scaled.total_rating | pluralize}}
    @@ -15,7 +15,7 @@
    -
    +
    @@ -27,7 +27,7 @@
    -
    +
    @@ -39,7 +39,7 @@
    -
    +
    @@ -51,7 +51,7 @@
    -
    +
    @@ -63,7 +63,7 @@
    -
    +
    diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 702a3a6abf0..d9b53a86af3 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -885,7 +885,7 @@ def previous_worked(): profile_json['work_done'] = count_work_completed profile_json['work_inprogress'] = count_work_in_progress profile_json['verification'] = user.get_my_verified_check - profile_json['avg_rating'] = user.get_average_star_rating + profile_json['avg_rating'] = user.get_average_star_rating() if user.avatar_baseavatar_related.exists(): user_avatar = user.avatar_baseavatar_related.first() profile_json['avatar_id'] = user_avatar.pk @@ -2197,12 +2197,13 @@ def profile(request, handle, tab=None): context['is_my_profile'] = request.user.is_authenticated and request.user.username.lower() == handle.lower() context['is_my_org'] = request.user.is_authenticated and any([handle.lower() == org.lower() for org in request.user.profile.organizations ]) context['show_resume_tab'] = profile.show_job_status or context['is_my_profile'] - context['avg_rating'] = profile.get_average_star_rating + context['avg_rating'] = profile.get_average_star_rating() + context['avg_rating_scaled'] = profile.get_average_star_rating(20) context['is_editable'] = context['is_my_profile'] # or context['is_my_org'] context['ratings'] = range(0,5) context['profile'] = profile context['verification'] = profile.get_my_verified_check - context['avg_rating'] = profile.get_average_star_rating + context['avg_rating'] = profile.get_average_star_rating() context['suppress_sumo'] = True context['feedbacks_sent'] = profile.feedbacks_sent.all() context['feedbacks_got'] = profile.feedbacks_got.all() @@ -3017,8 +3018,8 @@ def funder_dashboard_bounty_info(request, bounty_id): 'issue_message': i.issue_message}, 'handle': i.profile.handle, 'avatar_url': i.profile.avatar_url, - 'star_rating': i.profile.get_average_star_rating['overall'], - 'total_rating': i.profile.get_average_star_rating['total_rating'], + 'star_rating': i.profile.get_average_star_rating()['overall'], + 'total_rating': i.profile.get_average_star_rating()['total_rating'], 'fulfilled_bounties': len( [b for b in i.profile.get_fulfilled_bounties()]), 'leaderboard_rank': i.profile.get_contributor_leaderboard_index(), From 422da0d8ed83d2b4afad5d9f6dfd744234047e28 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 17:08:23 -0600 Subject: [PATCH 061/131] a bunch of good integration work on this --- app/assets/v2/js/pages/profile.js | 68 +++++++++++++++++++ .../templates/profiles/REPgraph.html | 66 +----------------- .../templates/profiles/activity_level.html | 14 +--- .../templates/profiles/activity_stats.html | 5 -- .../templates/profiles/scorecard_hunter.html | 7 +- .../templates/profiles/tab_active.html | 28 ++++++-- .../templates/profiles/tab_portfolio.html | 61 +++++++---------- app/dashboard/templates/profiles/tabs.html | 6 +- app/dashboard/templates/shared/feedback.html | 2 +- app/dashboard/templates/shared/nav_auth.html | 6 -- app/dashboard/views.py | 5 +- 11 files changed, 132 insertions(+), 136 deletions(-) diff --git a/app/assets/v2/js/pages/profile.js b/app/assets/v2/js/pages/profile.js index ae9a076b650..7e7d3c8b68c 100644 --- a/app/assets/v2/js/pages/profile.js +++ b/app/assets/v2/js/pages/profile.js @@ -97,6 +97,74 @@ $(document).ready(function() { }); (function($) { + + // rep graph + if($("#my_dataviz").length){ + // Set the dimensions of the canvas / graph + var margin = {top: 30, right: 30, bottom: 30, left: 70}, + width = $('#tab_controller').width() - margin.left - margin.right, + height = 270 - margin.top - margin.bottom; + + // Parse the date / time + var parseDate = d3.time.format("%d-%b-%y").parse; + + // Set the ranges + var x = d3.time.scale().range([0, width]); + var y = d3.scale.linear().range([height, 0]); + + // Define the axes + var xAxis = d3.svg.axis().scale(x) + .orient("bottom").ticks(5); + + var yAxis = d3.svg.axis().scale(y) + .orient("left").ticks(5); + + // Define the line + var valueline = d3.svg.line() + .x(function(d) { return x(d.date); }) + .y(function(d) { return y(d.close); }); + + // Adds the svg canvas + var svg = d3.select("#my_dataviz") + .append("svg") + .attr("width", width + margin.left + margin.right) + .attr("height", height + margin.top + margin.bottom) + .append("g") + .attr("transform", + "translate(" + margin.left + "," + margin.top + ")"); + + // Get the data + d3.csv(document.rep_url, function(error, data) { + data.forEach(function(d) { + d.date = parseDate(d.date); + d.close = +d.close; + }); + + // Scale the range of the data + x.domain(d3.extent(data, function(d) { return d.date; })); + y.domain([0, d3.max(data, function(d) { return d.close; })]); + + // Add the valueline path. + svg.append("path") + .attr("class", "line") + .attr("d", valueline(data)); + + // Add the X Axis + svg.append("g") + .attr("class", "x axis") + .attr("transform", "translate(0," + height + ")") + .call(xAxis); + + // Add the Y Axis + svg.append("g") + .attr("class", "y axis") + .call(yAxis); + + }); + + } + + $(document).on('click', '.load-more', function() { var address = $('#preferred-address').prop('title'); var link = $(this); diff --git a/app/dashboard/templates/profiles/REPgraph.html b/app/dashboard/templates/profiles/REPgraph.html index def49bb6a7d..cc2615c60d9 100644 --- a/app/dashboard/templates/profiles/REPgraph.html +++ b/app/dashboard/templates/profiles/REPgraph.html @@ -27,71 +27,7 @@
    \ No newline at end of file diff --git a/app/dashboard/templates/profiles/activity_level.html b/app/dashboard/templates/profiles/activity_level.html index 6682858fbcd..f91d2889f5f 100644 --- a/app/dashboard/templates/profiles/activity_level.html +++ b/app/dashboard/templates/profiles/activity_level.html @@ -2,8 +2,8 @@
    - {% if level %} - #{{ level }} + {% if profile.activity_level %} + {{ profile.activity_level }} {% else %}   {% endif %} @@ -11,15 +11,7 @@
      -
    • {% trans "Last seen" %} 2 days ago
    • -
    • 100 days {% trans "longest streak" %}
    • -
    • 10 {% trans "repeat relationships" %}
    • -
    • - {% for rating in ratings %} - - {% endfor %} - ({{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}}) -
    • + {% include 'profiles/activity_stats.html' %}
    diff --git a/app/dashboard/templates/profiles/activity_stats.html b/app/dashboard/templates/profiles/activity_stats.html index a4acf871d2f..6d4ba708bd0 100644 --- a/app/dashboard/templates/profiles/activity_stats.html +++ b/app/dashboard/templates/profiles/activity_stats.html @@ -5,11 +5,6 @@
  • Joined: {{profile.created_on|naturaltime}}
  • - {% if profile.persona_is_hunter %} -
  • - Top Skills: {{profile.keywords|join:", "}} -
  • - {% endif %} {% if profile.success_rate != -1 %}
  • Success Rate: {{profile.success_rate}}% diff --git a/app/dashboard/templates/profiles/scorecard_hunter.html b/app/dashboard/templates/profiles/scorecard_hunter.html index 371b9f2c4ce..85fb4a1814a 100644 --- a/app/dashboard/templates/profiles/scorecard_hunter.html +++ b/app/dashboard/templates/profiles/scorecard_hunter.html @@ -35,7 +35,12 @@ {% endif %}
  • +
    + {% for keyword in profile.keywords %} + {{keyword}} + {% endfor %} +
    - {% include "profiles/activity_level.html" with level='High' %} + {% include "profiles/activity_level.html"%} diff --git a/app/dashboard/templates/profiles/tab_active.html b/app/dashboard/templates/profiles/tab_active.html index aa02ac5c9e1..0e79e9011f4 100644 --- a/app/dashboard/templates/profiles/tab_active.html +++ b/app/dashboard/templates/profiles/tab_active.html @@ -1,9 +1,23 @@ -{% load i18n static %} +{% load i18n static avatar_tags humanize %} -
    - {% for active in active_bounties %} -
    - {{active.pk}} -- {{active.url}} +
    + {% for bounty in active_bounties %} +
    + +
    +
    +
    {{bounty.title}}
      +
    + for {{bounty.org_name}} +
    + {% for keyword in bounty.keywords_list %} + {{keyword}} + {% endfor %} +
    - {% endfor %} -
    \ No newline at end of file + +
    + {% endfor %} +
    diff --git a/app/dashboard/templates/profiles/tab_portfolio.html b/app/dashboard/templates/profiles/tab_portfolio.html index 75cb66354bf..5e49fe17f75 100644 --- a/app/dashboard/templates/profiles/tab_portfolio.html +++ b/app/dashboard/templates/profiles/tab_portfolio.html @@ -1,43 +1,34 @@ -{% load i18n static %} +{% load i18n static avatar_tags humanize %}
    Top Skills
    - Python - Django - Ethereum - Solidity + {% for keyword in profile.keywords %} + {{keyword}} + {% endfor %}
    Projects
    -
    - -
    -
    -
    ENS + Arweave
      - for Arweave -
    -
    - Python - Django - Ethereum - Solidity -
    -
    -
    -
    - -
    -
    -
    ENS + Arweave
      - for Arweave -
    -
    - Python - Django - Ethereum - Solidity -
    -
    -
    + {% for submission in profile.fulfilled.all %} +
    + +
    +
    +
    {{submission.bounty.created_on|naturaltime}}
      + for {{submission.bounty.org_name}} +
    +
    + {% for keyword in submission.bounty.keywords_list %} + {{keyword}} + {% endfor %} +
    +
    +
    + View Bounty > + {% if submission.fulfiller_github_url %} + View Work > + {% endif %} +
    +
    + {% endfor %}
    diff --git a/app/dashboard/templates/profiles/tabs.html b/app/dashboard/templates/profiles/tabs.html index 98afded9a14..63995ef6873 100644 --- a/app/dashboard/templates/profiles/tabs.html +++ b/app/dashboard/templates/profiles/tabs.html @@ -8,9 +8,9 @@ Activity - {% if active_bounties_count %} - diff --git a/app/dashboard/templates/shared/feedback.html b/app/dashboard/templates/shared/feedback.html index 5a1ac183582..bc6f44fd3dc 100644 --- a/app/dashboard/templates/shared/feedback.html +++ b/app/dashboard/templates/shared/feedback.html @@ -19,7 +19,7 @@
    - +
    diff --git a/app/dashboard/templates/shared/nav_auth.html b/app/dashboard/templates/shared/nav_auth.html index fc8eb3d7268..95fae255e40 100644 --- a/app/dashboard/templates/shared/nav_auth.html +++ b/app/dashboard/templates/shared/nav_auth.html @@ -68,12 +68,6 @@ {% trans "My Profile" %} - {% for org in orgs %} - - - {{org}}'s {% trans "Profile" %} - - {% endfor %} {% else %} diff --git a/app/dashboard/views.py b/app/dashboard/views.py index d9b53a86af3..b82826b275f 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -1993,8 +1993,7 @@ def get_profile_tab(request, profile, tab, prev_context): if profile.persona_is_funder: active_bounties = Bounty.objects.current().filter(bounty_owner_profile=profile).filter(idx_status__in=Bounty.WORK_IN_PROGRESS_STATUSES) elif profile.persona_is_hunter: - active_bounties = Bounty.objects.current().filter(interested__profile=profile).filter(interested__status='okay') \ - .filter(interested__pending=False).filter(idx_status__in=Bounty.WORK_IN_PROGRESS_STATUSES) + active_bounties = Bounty.objects.filter(pk__in=profile.active_bounties.values_list('bounty', flat=True)) else: active_bounties = Bounty.objects.none() context['active_bounties_count'] = active_bounties.count() @@ -2159,6 +2158,8 @@ def profile(request, handle, tab=None): # setup status = 200 tab = tab if tab else 'activity' + # staff only tabs + tab = 'activity' if tab in ['active', 'ratings', 'portfolio', 'viewers'] and not request.user.is_staff else tab owned_kudos = None sent_kudos = None handle = handle.replace("@", "") From 8ad9923cb8f7a66f8cdd5aa5c7e9105615f75cda Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 17:14:10 -0600 Subject: [PATCH 062/131] re adds who viewed my profile --- app/assets/v2/js/pages/profile.js | 90 +++++++++++++++++-------------- app/dashboard/views.py | 4 ++ 2 files changed, 53 insertions(+), 41 deletions(-) diff --git a/app/assets/v2/js/pages/profile.js b/app/assets/v2/js/pages/profile.js index 7e7d3c8b68c..19cd26182ed 100644 --- a/app/assets/v2/js/pages/profile.js +++ b/app/assets/v2/js/pages/profile.js @@ -99,70 +99,78 @@ $(document).ready(function() { (function($) { // rep graph - if($("#my_dataviz").length){ - // Set the dimensions of the canvas / graph + if ($('#my_dataviz').length) { + // Set the dimensions of the canvas / graph var margin = {top: 30, right: 30, bottom: 30, left: 70}, width = $('#tab_controller').width() - margin.left - margin.right, height = 270 - margin.top - margin.bottom; // Parse the date / time - var parseDate = d3.time.format("%d-%b-%y").parse; + var parseDate = d3.time.format('%d-%b-%y').parse; // Set the ranges - var x = d3.time.scale().range([0, width]); - var y = d3.scale.linear().range([height, 0]); + var x = d3.time.scale().range([ 0, width ]); + var y = d3.scale.linear().range([ height, 0 ]); // Define the axes var xAxis = d3.svg.axis().scale(x) - .orient("bottom").ticks(5); + .orient('bottom').ticks(5); var yAxis = d3.svg.axis().scale(y) - .orient("left").ticks(5); + .orient('left').ticks(5); // Define the line var valueline = d3.svg.line() - .x(function(d) { return x(d.date); }) - .y(function(d) { return y(d.close); }); + .x(function(d) { + return x(d.date); + }) + .y(function(d) { + return y(d.close); + }); // Adds the svg canvas - var svg = d3.select("#my_dataviz") - .append("svg") - .attr("width", width + margin.left + margin.right) - .attr("height", height + margin.top + margin.bottom) - .append("g") - .attr("transform", - "translate(" + margin.left + "," + margin.top + ")"); + var svg = d3.select('#my_dataviz') + .append('svg') + .attr('width', width + margin.left + margin.right) + .attr('height', height + margin.top + margin.bottom) + .append('g') + .attr('transform', + 'translate(' + margin.left + ',' + margin.top + ')'); // Get the data d3.csv(document.rep_url, function(error, data) { - data.forEach(function(d) { - d.date = parseDate(d.date); - d.close = +d.close; - }); - - // Scale the range of the data - x.domain(d3.extent(data, function(d) { return d.date; })); - y.domain([0, d3.max(data, function(d) { return d.close; })]); - - // Add the valueline path. - svg.append("path") - .attr("class", "line") - .attr("d", valueline(data)); - - // Add the X Axis - svg.append("g") - .attr("class", "x axis") - .attr("transform", "translate(0," + height + ")") - .call(xAxis); - - // Add the Y Axis - svg.append("g") - .attr("class", "y axis") - .call(yAxis); + data.forEach(function(d) { + d.date = parseDate(d.date); + d.close = +d.close; + }); + + // Scale the range of the data + x.domain(d3.extent(data, function(d) { + return d.date; + })); + y.domain([ 0, d3.max(data, function(d) { + return d.close; + }) ]); + + // Add the valueline path. + svg.append('path') + .attr('class', 'line') + .attr('d', valueline(data)); + + // Add the X Axis + svg.append('g') + .attr('class', 'x axis') + .attr('transform', 'translate(0,' + height + ')') + .call(xAxis); + + // Add the Y Axis + svg.append('g') + .attr('class', 'y axis') + .call(yAxis); }); - } + } $(document).on('click', '.load-more', function() { diff --git a/app/dashboard/views.py b/app/dashboard/views.py index b82826b275f..aaf6231d421 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -2217,6 +2217,10 @@ def profile(request, handle, tab=None): else: return tab + # record profile view + if request.user.is_authenticated and not context['is_my_profile']: + ProfileView.objects.create(target=profile, viewer=request.user.profile) + return TemplateResponse(request, 'profiles/profile.html', context, status=status) From d76e314a5e4bea34801ac972007fcb12e1e08e5e Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 18:05:24 -0600 Subject: [PATCH 063/131] make fix --- app/assets/v2/css/profile.css | 670 +++++++++++++++--------------- app/assets/v2/js/pages/profile.js | 6 +- 2 files changed, 338 insertions(+), 338 deletions(-) diff --git a/app/assets/v2/css/profile.css b/app/assets/v2/css/profile.css index 42f1c75c2ba..c67367576e8 100644 --- a/app/assets/v2/css/profile.css +++ b/app/assets/v2/css/profile.css @@ -20,433 +20,433 @@ color: #666666; } - .mh-150{ - min-height: 150px; - } +.mh-150{ + min-height: 150px; +} - .overflow-visible { - overflow: visible; - } +.overflow-visible { + overflow: visible; +} - .profile-card { - background: white; - border-radius: 5px; - z-index: 1; - position: relative; - padding: 2rem; - } +.profile-card { + background: white; + border-radius: 5px; + z-index: 1; + position: relative; + padding: 2rem; +} - .profile-header__avatar { - float: left; - width: 7.25rem; - height: 7.25rem; - border-radius: 50%; - } +.profile-header__avatar { + float: left; + width: 7.25rem; + height: 7.25rem; + border-radius: 50%; +} - .profile-header { - position: relative; - min-height: 450px; - } +.profile-header { + position: relative; + min-height: 450px; +} - .profile-header__handle { - padding-top: 0.8rem; - margin-bottom: 0; - line-height: 1; - font-weight: 700; - font-size: 1.7rem; - } +.profile-header__handle { + padding-top: 0.8rem; + margin-bottom: 0; + line-height: 1; + font-weight: 700; + font-size: 1.7rem; +} - .profile-header__handle small { - text-transform: none; - } +.profile-header__handle small { + text-transform: none; +} - .profile-header__bio { - clear: both; - } +.profile-header__bio { + clear: both; +} - .profile-bounties__group-title > i { - color: #25E899; - } +.profile-bounties__group-title > i { + color: #25E899; +} - .profile-header__links { - margin: 0; - padding: 0; - } +.profile-header__links { + margin: 0; + padding: 0; +} - .profile-header__links a { - margin-left: 2px; - margin-right: 2px; - font-size: 1.2rem; - transition: all 0.3s; - color: #000; - text-decoration: none; - } +.profile-header__links a { + margin-left: 2px; + margin-right: 2px; + font-size: 1.2rem; + transition: all 0.3s; + color: #000; + text-decoration: none; +} - .profile-header__links a:hover i { - color: #1AB56D; - } +.profile-header__links a:hover i { + color: #1AB56D; +} - .profile-header__links img { - width: 1.5rem; - height: 1.5rem; - margin-right: 0.5em; - filter: invert(100%); - } +.profile-header__links img { + width: 1.5rem; + height: 1.5rem; + margin-right: 0.5em; + filter: invert(100%); +} - .float_avatar_image { - margin-top: -140px; - position: relative; - } +.float_avatar_image { + margin-top: -140px; + position: relative; +} - .float_avatar_image img { - height: 186px; - width: 186px; - border: 3px solid #FFFFFF; - box-shadow: 0 -2px 4px 0 rgba(0,0,0,0.50); - } +.float_avatar_image img { + height: 186px; + width: 186px; + border: 3px solid #FFFFFF; + box-shadow: 0 -2px 4px 0 rgba(0,0,0,0.50); +} - .avatar_edit { - text-align: center; - background: #000; - opacity: 0.7; - border-radius: 0% 0% 50% 50% / 0% 0% 100% 100%; - height: 60px; - width: 173px; - position: absolute; - top: 122px; - margin: auto; - right: 0; - left: 0; - transition: .2s all linear; - } +.avatar_edit { + text-align: center; + background: #000; + opacity: 0.7; + border-radius: 0% 0% 50% 50% / 0% 0% 100% 100%; + height: 60px; + width: 173px; + position: absolute; + top: 122px; + margin: auto; + right: 0; + left: 0; + transition: .2s all linear; +} - .avatar_edit_text { - position: absolute; - top: 40%; - color: #ffffff; - font-weight: bold; - font-size: 14px; - margin: auto; - width: 100%; - height: 40px; - } +.avatar_edit_text { + position: absolute; + top: 40%; + color: #ffffff; + font-weight: bold; + font-size: 14px; + margin: auto; + width: 100%; + height: 40px; +} - /* .is_editable a:hover .profile-header__avatar{ +/* .is_editable a:hover .profile-header__avatar{ border: 3px solid #0fce7c; } */ - .is_editable{ - cursor: pointer; - } +.is_editable{ + cursor: pointer; +} - a:hover .avatar_edit { - /* background-color: rgba(255, 255, 255, 0.7); +a:hover .avatar_edit { + /* background-color: rgba(255, 255, 255, 0.7); height: 180px; width: 180px; top: 3px; border-radius: 50%; */ - } +} - /* a:hover .avatar_edit .avatar_edit_text { +/* a:hover .avatar_edit .avatar_edit_text { top: 40%; } */ - .picky img { - width: 100%; - height: auto; - vertical-align: middle; - } +.picky img { + width: 100%; + height: auto; + vertical-align: middle; +} - .profile-organizations .organization { - display: inline-block; - } +.profile-organizations .organization { + display: inline-block; +} + +.profile-bounties--activities{ + min-height: 200px; +} - .profile-bounties--activities{ - min-height: 200px; +.profile-organizations .organization img{ + max-height: 4rem; + max-width: 4rem; + margin-right: 0.5rem; + margin-bottom: 0.5rem; + border-radius: 50%; +} + + +@media (max-width: 1200px) { + .profile-header{ + min-height: 350px; } +} - .profile-organizations .organization img{ - max-height: 4rem; - max-width: 4rem; - margin-right: 0.5rem; - margin-bottom: 0.5rem; - border-radius: 50%; +@media (max-width: 767.98px) { + + .profile-header__main-infos { + text-align: center; } + .profile-header{ + min-height: 200px; + } - @media (max-width: 1200px) { - .profile-header{ - min-height: 350px; - } + .profile-header__avatar { + float: none; + margin-right: 0!important; } - @media (max-width: 767.98px) { + .profile-header__handle { + display: block; + } - .profile-header__main-infos { - text-align: center; - } + .profile-header__links li { + text-align: center; + float: none; + margin-right: 0; + } - .profile-header{ - min-height: 200px; - } + .row.bottom_notification{ + display: none; + } - .profile-header__avatar { - float: none; - margin-right: 0!important; - } +} - .profile-header__handle { - display: block; - } - .profile-header__links li { - text-align: center; - float: none; - margin-right: 0; - } +.profile-header__stats { + border: none; +} - .row.bottom_notification{ - display: none; - } +.profile-header__stats .card-header { + padding: 0.1rem 0.7rem; + color: #666; + border-radius: 0; + border-bottom: none; + font-size: 1.2rem; +} - } +.profile-header__stats .card-header b { + color: #000; + font-size: 1.7rem; +} +.profile-header__stats .card-body { + padding: 0.7rem; +} - .profile-header__stats { - border: none; - } +@media (min-width: 992px) and (max-width: 1199.98px) { .profile-header__stats .card-header { - padding: 0.1rem 0.7rem; - color: #666; - border-radius: 0; - border-bottom: none; - font-size: 1.2rem; - } - - .profile-header__stats .card-header b { - color: #000; - font-size: 1.7rem; + padding: 0 0.5rem; + font-size: 1.2rem; } .profile-header__stats .card-body { - padding: 0.7rem; + padding: 0.5rem; + font-size: 1rem; } +} - @media (min-width: 992px) and (max-width: 1199.98px) { +.profile-header__stats ul { + list-style-type: none; + padding: 0; + margin: 0; +} - .profile-header__stats .card-header { - padding: 0 0.5rem; - font-size: 1.2rem; - } +.profile-header__stats li { + margin: 0.15rem 0 0; +} - .profile-header__stats .card-body { - padding: 0.5rem; - font-size: 1rem; - } - } +.profile-header__stats li:first-child { + margin-top: 0; +} - .profile-header__stats ul { - list-style-type: none; - padding: 0; - margin: 0; - } +.profile-header__stats--contributor .card-header { + background-color: transparent; +} - .profile-header__stats li { - margin: 0.15rem 0 0; - } +.card-header::after { + content: ''; + position: relative; + height: 4px; + width: 100%; + display: block; + border-radius: 6px; + animation: grow 1s ease-in-out; +} - .profile-header__stats li:first-child { - margin-top: 0; - } +.animate-verify { + animation: verify 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28); +} - .profile-header__stats--contributor .card-header { - background-color: transparent; +@keyframes grow { + 0% { + width: 2%; } - - .card-header::after { - content: ''; - position: relative; - height: 4px; - width: 100%; - display: block; - border-radius: 6px; - animation: grow 1s ease-in-out; + 50% { + width: 2%; } - - .animate-verify { - animation: verify 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28); + 100% { + width: 100%; } +} - @keyframes grow { - 0% { - width: 2%; - } - 50% { - width: 2%; - } - 100% { - width: 100%; - } +@keyframes verify { + 0% { + transform: scale(1.5, 1.3); } - - @keyframes verify { - 0% { - transform: scale(1.5, 1.3); - } - 100% { - transform: scale(1); - } + 100% { + transform: scale(1); } +} - .profile-header__stats--contributor .card-header::after { - background: #00eb93; - } +.profile-header__stats--contributor .card-header::after { + background: #00eb93; +} - .profile-header__stats--funder .card-header::after { - background: #FFCE08; - } +.profile-header__stats--funder .card-header::after { + background: #FFCE08; +} - .profile-header__stats--funder .card-header { - background-color: transparent; - } +.profile-header__stats--funder .card-header { + background-color: transparent; +} - .profile-section-title { - border-bottom: 2px solid #3E24FB; - } +.profile-section-title { + border-bottom: 2px solid #3E24FB; +} - .profile-bounties--loading { - background-image: url('/static/v2/images/loading_v2.gif'); - background-repeat: no-repeat; - background-position: 0 -1rem; - background-size: 4rem; - height: 3rem; - } +.profile-bounties--loading { + background-image: url('/static/v2/images/loading_v2.gif'); + background-repeat: no-repeat; + background-position: 0 -1rem; + background-size: 4rem; + height: 3rem; +} - .profile-bounties .avatar { - width: 3.125rem; - height: 3.125rem; - margin-right: auto; - margin-left: auto; - border-radius: 100%; - min-height: 3.125rem; - } +.profile-bounties .avatar { + width: 3.125rem; + height: 3.125rem; + margin-right: auto; + margin-left: auto; + border-radius: 100%; + min-height: 3.125rem; +} - .profile-bounties .bounty_row { - padding-left: 0; - padding-right: 0; - } +.profile-bounties .bounty_row { + padding-left: 0; + padding-right: 0; +} - .profile-bounties .bounty_row--hidden { - display: none; - } +.profile-bounties .bounty_row--hidden { + display: none; +} - .profile-bounties .bounty-summary { - padding-left: 0; - padding-right: 0; - } +.profile-bounties .bounty-summary { + padding-left: 0; + padding-right: 0; +} - .profile-bounties .profile-bounties__btn-show-all { - border-color: #D3D3D3; - font-size: 0.875rem; - font-weight: 300; - } +.profile-bounties .profile-bounties__btn-show-all { + border-color: #D3D3D3; + font-size: 0.875rem; + font-weight: 300; +} - .profile-bounties .profile-bounties__btn-show-all:hover, - .profile-bounties .profile-bounties__btn-show-all:focus, - .profile-bounties .profile-bounties__btn-show-all:active { - border-color: #D3D3D3; - color: #6c757d; - background-color: #F9F9F9; - } +.profile-bounties .profile-bounties__btn-show-all:hover, +.profile-bounties .profile-bounties__btn-show-all:focus, +.profile-bounties .profile-bounties__btn-show-all:active { + border-color: #D3D3D3; + color: #6c757d; + background-color: #F9F9F9; +} - .profile-bounties__group-title { - color: #0D0764; - font-size: 1rem; - padding: 0.5rem 0 5px 0; - border-bottom: 2px solid #3E24FB; - } +.profile-bounties__group-title { + color: #0D0764; + font-size: 1rem; + padding: 0.5rem 0 5px 0; + border-bottom: 2px solid #3E24FB; +} - .profile-bounties__sort_label { - color: #3E24FB; - } +.profile-bounties__sort_label { + color: #3E24FB; +} - .profile_details .bounty_row:first-child { - border-top: none; - } +.profile_details .bounty_row:first-child { + border-top: none; +} - .profile_details .works_with_list span { - font-weight: bolder; - display: block; - margin-top: 6px; - margin-bottom: 6px; - } +.profile_details .works_with_list span { + font-weight: bolder; + display: block; + margin-top: 6px; + margin-bottom: 6px; +} - .profile_details .works_with_list img { - max-width: 30px; - border-radius: 50%; - box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.20); - } +.profile_details .works_with_list img { + max-width: 30px; + border-radius: 50%; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.20); +} - .profile_details .works_with_list .plus-img { - color: #3E00FF; - width: 30px; - height: 30px; - display: inline-flex; - background: #F8F9FA; - border-radius: 30px; - align-items: center; - vertical-align: middle; - font-size: 10px; - justify-content: center; - } +.profile_details .works_with_list .plus-img { + color: #3E00FF; + width: 30px; + height: 30px; + display: inline-flex; + background: #F8F9FA; + border-radius: 30px; + align-items: center; + vertical-align: middle; + font-size: 10px; + justify-content: center; +} - .profile_details .works_with_list a:hover { - text-decoration: none; - transform: scale(1.1); - } +.profile_details .works_with_list a:hover { + text-decoration: none; + transform: scale(1.1); +} - .no-profile-button { - background-color: #3E00FF; - color: #FFFFFF; - font-size: 0.875rem; - } +.no-profile-button { + background-color: #3E00FF; + color: #FFFFFF; + font-size: 0.875rem; +} - .no-profile-textcolor { - color: #666666; - } +.no-profile-textcolor { + color: #666666; +} - .profile-banner { - display: flex; - top: 0; - color: #ffffff; - z-index: 1; - width: 100vw; - cursor: pointer; - } +.profile-banner { + display: flex; + top: 0; + color: #ffffff; + z-index: 1; + width: 100vw; + cursor: pointer; +} - .profile-banner-cta { - background-color: #000; - padding: 6px 10px; - border-radius: 2px; - cursor: pointer; - } +.profile-banner-cta { + background-color: #000; + padding: 6px 10px; + border-radius: 2px; + cursor: pointer; +} - .picky { - cursor: pointer; - } +.picky { + cursor: pointer; +} - .picky:active, .picky:focus { - border: 2px solid #007bff; - } +.picky:active, .picky:focus { + border: 2px solid #007bff; +} - .selected { - border: 5px solid #007bff; - } +.selected { + border: 5px solid #007bff; +} - nav.navbar.navbar-dark{ - background-image: url(/static/v2/images/header-bg.png); - } +nav.navbar.navbar-dark{ + background-image: url(/static/v2/images/header-bg.png); +} #rank_link{ font-size: 12px; diff --git a/app/assets/v2/js/pages/profile.js b/app/assets/v2/js/pages/profile.js index 19cd26182ed..69f1b29f228 100644 --- a/app/assets/v2/js/pages/profile.js +++ b/app/assets/v2/js/pages/profile.js @@ -101,9 +101,9 @@ $(document).ready(function() { // rep graph if ($('#my_dataviz').length) { // Set the dimensions of the canvas / graph - var margin = {top: 30, right: 30, bottom: 30, left: 70}, - width = $('#tab_controller').width() - margin.left - margin.right, - height = 270 - margin.top - margin.bottom; + var margin = {top: 30, right: 30, bottom: 30, left: 70}; + var width = $('#tab_controller').width() - margin.left - margin.right; + var height = 270 - margin.top - margin.bottom; // Parse the date / time var parseDate = d3.time.format('%d-%b-%y').parse; From 09289afb190d3184d19825feeb8656f8c6ac413e Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 18:09:36 -0600 Subject: [PATCH 064/131] whos viewed my profile --- .../templates/profiles/tab_viewers.html | 55 ++++++++++--------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/app/dashboard/templates/profiles/tab_viewers.html b/app/dashboard/templates/profiles/tab_viewers.html index 7dc6f700c11..b2e3b75b401 100644 --- a/app/dashboard/templates/profiles/tab_viewers.html +++ b/app/dashboard/templates/profiles/tab_viewers.html @@ -1,27 +1,32 @@ -{% load i18n static humanize %} +{% load i18n static avatar_tags humanize %} +{% if not hidden %} +{% if is_staff %} +{% if is_editable %} - {% if not hidden %} - - {% if is_staff %} - {% if is_editable %} -
    -

    Whos Viewed My Profile

    - -
    - {% if profile.viewed_by.count == 0 %} - No Viewers - - {% endif %} - - {% for viewer in profile.viewed_by.all %} -
    - - {{viewer.viewer.handle}} {{viewer.created_on | naturaltime}} -
    - {% endfor %} -
    +
    +{% endif %} +{% endif %} +{% endif %} From b44a922b0dd466624e34b1aed754ca03a37eee08 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 18:18:51 -0600 Subject: [PATCH 065/131] persona stuf --- app/assets/v2/js/base.js | 28 ++++++++++--------- app/dashboard/models.py | 2 -- app/dashboard/templates/profiles/profile.html | 6 ++-- app/dashboard/templates/shared/nav_auth.html | 4 --- app/dashboard/views.py | 4 +-- 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/app/assets/v2/js/base.js b/app/assets/v2/js/base.js index e6a52b56b51..cf949e89b4b 100644 --- a/app/assets/v2/js/base.js +++ b/app/assets/v2/js/base.js @@ -271,6 +271,7 @@ $('body').on('click', '[data-persona]', function(e) { }); const sendPersonal = (persona) => { + $('#persona_modal').bootstrapModal('hide'); let postPersona = fetchData('/api/v0.1/choose_persona/', 'POST', {persona, 'access_token': document.contxt.access_token} ); @@ -280,7 +281,6 @@ const sendPersonal = (persona) => { return _alert(response.msg, 'error'); } - $('#persona_modal').bootstrapModal('hide'); const urls = [ { url: document.location.href, @@ -304,19 +304,21 @@ const sendPersonal = (persona) => { return false; }); }; + let do_redirect = document.URL.indexOf('/profile/') == -1; + if(do_redirect){ + if (response.persona === 'persona_is_funder') { + if (checkUrl(urls, document.location.href)) { + window.location = '/onboard/funder'; + } else { + return _alert(gettext('Thanks, you can read the guide here.'), 'info'); + } - if (response.persona === 'persona_is_funder') { - if (checkUrl(urls, document.location.href)) { - window.location = '/onboard/funder'; - } else { - return _alert(gettext('Thanks, you can read the guide here.'), 'info'); - } - - } else if (response.persona === 'persona_is_hunter') { - if (checkUrl(urls, document.location.href)) { - window.location = '/onboard/contributor'; - } else { - return _alert(gettext('Thanks, you can read the guide here.'), 'info'); + } else if (response.persona === 'persona_is_hunter') { + if (checkUrl(urls, document.location.href)) { + window.location = '/onboard/contributor'; + } else { + return _alert(gettext('Thanks, you can read the guide here.'), 'info'); + } } } diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 0fc1724fb09..18ce1cce83c 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -2307,8 +2307,6 @@ def calculate_and_save_persona(self, respect_defaults=True, decide_only_one=Fals self.dominant_persona = 'hunter' elif hunter_count < funder_count: self.dominant_persona = 'funder' - else: - self.dominant_persona = '' # update db if not decide_only_one: diff --git a/app/dashboard/templates/profiles/profile.html b/app/dashboard/templates/profiles/profile.html index 418f52c258d..18000a92496 100644 --- a/app/dashboard/templates/profiles/profile.html +++ b/app/dashboard/templates/profiles/profile.html @@ -56,10 +56,10 @@ {% if profile.is_org %} {% include 'profiles/organization.html' %} {% else %} - {% if profile.persona_is_hunter %} - {% include 'profiles/scorecard_hunter.html' %} + {% if profile.dominant_persona == 'funder' %} + {% include 'profiles/scorecard_funder.html' %} {% elif profile.persona_is_funder %} - {% include 'profiles/scorecard_funder.html' %} + {% include 'profiles/scorecard_hunter.html' %} {% endif %}
    diff --git a/app/dashboard/templates/shared/nav_auth.html b/app/dashboard/templates/shared/nav_auth.html index 95fae255e40..e7bdda10344 100644 --- a/app/dashboard/templates/shared/nav_auth.html +++ b/app/dashboard/templates/shared/nav_auth.html @@ -60,10 +60,6 @@ {% trans "My Avatar" %} - - - {% trans "My Onboarding (soon to be Koans)" %} - {% trans "My Profile" %} diff --git a/app/dashboard/views.py b/app/dashboard/views.py index aaf6231d421..eb24f4873df 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -3242,10 +3242,10 @@ def choose_persona(request): persona = request.POST.get('persona') if persona == 'persona_is_funder': profile.persona_is_funder = True - profile.persona_is_hunter = False + profile.dominant_persona = 'funder' elif persona == 'persona_is_hunter': profile.persona_is_hunter = True - profile.persona_is_funder = False + profile.dominant_persona = 'hunter' profile.save() else: return JsonResponse( From d7abd5b5ac3fb06816ce956980033926fbea2eb7 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 18:30:57 -0600 Subject: [PATCH 066/131] just some random touch ups --- app/assets/v2/js/pages/profile.js | 2 ++ .../templates/profiles/activity_stats.html | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/assets/v2/js/pages/profile.js b/app/assets/v2/js/pages/profile.js index 69f1b29f228..80b9ab0ed1a 100644 --- a/app/assets/v2/js/pages/profile.js +++ b/app/assets/v2/js/pages/profile.js @@ -98,6 +98,8 @@ $(document).ready(function() { (function($) { + $('.tooltip').bootstrapTooltip() + // rep graph if ($('#my_dataviz').length) { // Set the dimensions of the canvas / graph diff --git a/app/dashboard/templates/profiles/activity_stats.html b/app/dashboard/templates/profiles/activity_stats.html index 6d4ba708bd0..4bf933a874f 100644 --- a/app/dashboard/templates/profiles/activity_stats.html +++ b/app/dashboard/templates/profiles/activity_stats.html @@ -7,23 +7,32 @@ {% if profile.success_rate != -1 %}
  • - Success Rate: {{profile.success_rate}}% + + Success Rate: {{profile.success_rate}}%
  • {% endif %}
  • + Repeat {% if profile.persona_is_funder %}Workers{%else%}Funders{%endif%}: {{profile.num_repeated_relationships}}
  • {% if is_staff %} {% if profile.persona_is_hunter %}
  • + Longest activity streak: {{profile.longest_streak}} weekdays
  • {% endif %}
  • - Activity Level: {{profile.activity_level}} -
  • -
  • - REP: {{profile.rep}} + + REP: {{profile.rep}}
  • Avg Hourly Rate ${{profile.avg_hourly_rate}} From ffe6090fdeb21c399d1f859d7e18e6228bd7e0dd Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 18:42:15 -0600 Subject: [PATCH 067/131] smallfixes --- app/dashboard/templates/profiles/activity_stats.html | 4 +++- app/dashboard/templates/profiles/header_details.html | 9 ++++----- app/dashboard/templates/profiles/tab_activity.html | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/dashboard/templates/profiles/activity_stats.html b/app/dashboard/templates/profiles/activity_stats.html index 4bf933a874f..8175a932dc6 100644 --- a/app/dashboard/templates/profiles/activity_stats.html +++ b/app/dashboard/templates/profiles/activity_stats.html @@ -1,4 +1,5 @@ {% load humanize %} +{% if not profile.is_org %}
  • Last Seen: {{profile.last_visit|naturaltime}}
  • @@ -23,7 +24,7 @@ {% if profile.persona_is_hunter %}
  • Longest activity streak: {{profile.longest_streak}} weekdays
  • @@ -38,3 +39,4 @@ Avg Hourly Rate ${{profile.avg_hourly_rate}} {% endif %} +{% endif %} diff --git a/app/dashboard/templates/profiles/header_details.html b/app/dashboard/templates/profiles/header_details.html index 19928f3f5ca..f4e63ead522 100644 --- a/app/dashboard/templates/profiles/header_details.html +++ b/app/dashboard/templates/profiles/header_details.html @@ -25,7 +25,7 @@

    {% endif %} {% if profile.linkedin_url and user.is_authenticated %} - + {% endif %} {% if profile.data.email and user.is_authenticated %} @@ -36,17 +36,16 @@

    {% if preferred_payout_address %} - -
    {{ preferred_payout_address }} + Update preferred address
    {% else %}
    - {% if user.is_authenticated and request.path == '/profile/' %} + {% if is_my_profile %} Add a preferred address - {% else %} + {% elif not profile.is_org %} No preferred address {% endif %}
    diff --git a/app/dashboard/templates/profiles/tab_activity.html b/app/dashboard/templates/profiles/tab_activity.html index d74846f4477..258772c2c31 100644 --- a/app/dashboard/templates/profiles/tab_activity.html +++ b/app/dashboard/templates/profiles/tab_activity.html @@ -1,6 +1,6 @@ {% load i18n static %} - {% if is_staff %} + {% if is_staff and not profile.is_org %}
    {% include "profiles/REPgraph.html" %} From 88a1424e9aef4dcecba8dfba4589dc4635fdf3f7 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 18:45:27 -0600 Subject: [PATCH 068/131] make fix --- app/assets/v2/js/base.js | 3 ++- app/assets/v2/js/pages/profile.js | 2 +- app/dashboard/templates/profiles/header_details.html | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/assets/v2/js/base.js b/app/assets/v2/js/base.js index cf949e89b4b..6496bf76c03 100644 --- a/app/assets/v2/js/base.js +++ b/app/assets/v2/js/base.js @@ -305,7 +305,8 @@ const sendPersonal = (persona) => { }); }; let do_redirect = document.URL.indexOf('/profile/') == -1; - if(do_redirect){ + + if (do_redirect) { if (response.persona === 'persona_is_funder') { if (checkUrl(urls, document.location.href)) { window.location = '/onboard/funder'; diff --git a/app/assets/v2/js/pages/profile.js b/app/assets/v2/js/pages/profile.js index 80b9ab0ed1a..171492225e7 100644 --- a/app/assets/v2/js/pages/profile.js +++ b/app/assets/v2/js/pages/profile.js @@ -98,7 +98,7 @@ $(document).ready(function() { (function($) { - $('.tooltip').bootstrapTooltip() + $('.tooltip').bootstrapTooltip(); // rep graph if ($('#my_dataviz').length) { diff --git a/app/dashboard/templates/profiles/header_details.html b/app/dashboard/templates/profiles/header_details.html index f4e63ead522..d573ecd9fe8 100644 --- a/app/dashboard/templates/profiles/header_details.html +++ b/app/dashboard/templates/profiles/header_details.html @@ -39,7 +39,9 @@

    {{ preferred_payout_address }} - Update preferred address + {% if is_my_profile %} + Update preferred address + {% endif %}
    {% else %}
    From 2dc0bc82b461dd0ea73c46a80a333c5c709f2d62 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 18:55:40 -0600 Subject: [PATCH 069/131] allows calc of success rate --- app/dashboard/models.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/dashboard/models.py b/app/dashboard/models.py index fe06ee4f5ea..0ef8b79e0e9 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -2557,17 +2557,6 @@ def calc_rep_number(self): return rep.first().balance return 0 - @property - def success_rate(self): - network = self.get_network() - num_completed_bounties = self.bounties.filter( - idx_status__in=['done'], network=network).count() - terminal_state_bounties = self.bounties.filter( - idx_status__in=Bounty.TERMINAL_STATUSES, network=network).count() - if terminal_state_bounties == 0: - return 1.0 - return num_completed_bounties * 1.0 / (terminal_state_bounties + num_completed_bounties) - @property def get_quarterly_stats(self): """Generate last 90 days stats for this user. From 6934e50056b912a2f30d4d7988b0b37335782d0e Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 18:58:29 -0600 Subject: [PATCH 070/131] changes redir logic --- app/assets/v2/js/base.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/v2/js/base.js b/app/assets/v2/js/base.js index a28aa6c4d1a..8409ba77993 100644 --- a/app/assets/v2/js/base.js +++ b/app/assets/v2/js/base.js @@ -291,11 +291,11 @@ const sendPersonal = (persona) => { ]; const checkUrlRedirect = (arr, val) => { - return arr.some(arrObj => { - if (val.indexOf(arrObj.url) >= 0) { - return false; + return arr.all(arrObj => { + if (val.indexOf(arrObj.url) == -1) { + return true; } - return true; + return false; }); }; From 8f8387a08280a293026a6b4124b32b7072900ef9 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 18:58:55 -0600 Subject: [PATCH 071/131] hide modal --- app/assets/v2/js/base.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/v2/js/base.js b/app/assets/v2/js/base.js index 8409ba77993..017f52eb48a 100644 --- a/app/assets/v2/js/base.js +++ b/app/assets/v2/js/base.js @@ -271,7 +271,6 @@ $('body').on('click', '[data-persona]', function(e) { }); const sendPersonal = (persona) => { - $('#persona_modal').bootstrapModal('hide'); let postPersona = fetchData('/api/v0.1/choose_persona/', 'POST', {persona, 'access_token': document.contxt.access_token} ); @@ -280,6 +279,7 @@ const sendPersonal = (persona) => { if (statusCode.status != 200) { return _alert(response.msg, 'error'); } + $('#persona_modal').bootstrapModal('hide'); const urls = [ { From 8c064085ebdb0f3a510af1c2eeb7eb8f52132e6b Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 19:53:25 -0600 Subject: [PATCH 072/131] a few small fixes --- app/dashboard/models.py | 11 ++++++----- app/dashboard/views.py | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 0ef8b79e0e9..75d94c6020c 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -2362,14 +2362,15 @@ def no_times_been_removed_by_staff(self): return user_actions.count() def get_desc(self, funded_bounties, fulfilled_bounties): - total_funded = funded_bounties.aggregate(Sum('value_in_usdt'))['value_in_usdt__sum'] or 0 - total_fulfilled = fulfilled_bounties.aggregate(Sum('value_in_usdt'))['value_in_usdt__sum'] or 0 - role = 'newbie' - if total_funded > total_fulfilled: + if self.persona_is_funder and self.persona_is_hunter: + role = 'funder/coder' + elif self.persona_is_funder: role = 'funder' - elif total_funded < total_fulfilled: + elif self.persona_is_hunter: role = 'coder' + if self.is_org: + role = 'organization' total_funded_participated = funded_bounties.count() + fulfilled_bounties.count() plural = 's' if total_funded_participated != 1 else '' diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 365c8859ff0..4e5d41922ed 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -73,7 +73,7 @@ from .models import ( Activity, Bounty, BountyDocuments, BountyFulfillment, BountyInvites, CoinRedemption, CoinRedemptionRequest, Coupon, FeedbackEntry, HackathonEvent, HackathonSponsor, Interest, LabsResearch, Profile, ProfileSerializer, - RefundFeeRequest, SearchHistory, Sponsor, Subscription, Tool, ToolVote, UserAction, UserVerificationModel, REPEntry, + RefundFeeRequest, SearchHistory, Sponsor, Subscription, Tool, ToolVote, UserAction, UserVerificationModel, REPEntry, ProfileView ) from .notifications import ( maybe_market_tip_to_email, maybe_market_tip_to_github, maybe_market_tip_to_slack, maybe_market_to_email, From e4af29f40fd9ec50f3e80a016fa26ee2c615e959 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 10 Sep 2019 19:56:24 -0600 Subject: [PATCH 073/131] make fix --- app/dashboard/templates/profiles/heatmap.html | 3 --- app/dashboard/views.py | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/dashboard/templates/profiles/heatmap.html b/app/dashboard/templates/profiles/heatmap.html index ea29ab4dc70..364135d03d2 100644 --- a/app/dashboard/templates/profiles/heatmap.html +++ b/app/dashboard/templates/profiles/heatmap.html @@ -5,9 +5,6 @@
    -
    - {{profile.activity_level}} Activity Level; Active {{profile.last_visit|naturaltime}} -
    -
    -
    +
    +
    {{profile.rep}} REP
    -
    +
    From 624fd2f80e713f21641770d14255b52a7844f497 Mon Sep 17 00:00:00 2001 From: Owocki Date: Wed, 11 Sep 2019 15:39:56 -0600 Subject: [PATCH 083/131] make fix --- app/dashboard/management/commands/calc_profile.py | 2 +- app/dashboard/models.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/dashboard/management/commands/calc_profile.py b/app/dashboard/management/commands/calc_profile.py index b17c1b2429e..cb539dfade6 100644 --- a/app/dashboard/management/commands/calc_profile.py +++ b/app/dashboard/management/commands/calc_profile.py @@ -17,8 +17,8 @@ ''' from django.core.management.base import BaseCommand -from django.utils import timezone from django.db.models import F +from django.utils import timezone from dashboard.models import Profile, UserAction diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 5099ae6cc32..103a9a1a443 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -20,6 +20,7 @@ import base64 import collections +import json import logging from datetime import datetime, timedelta from urllib.parse import urlsplit @@ -44,12 +45,11 @@ from django.utils.translation import gettext_lazy as _ import pytz -import json import requests from app.utils import get_upload_filename from dashboard.points import point_values from dashboard.tokens import addr_to_token -from economy.models import ConversionRate, SuperModel, get_time, EncodeAnything +from economy.models import ConversionRate, EncodeAnything, SuperModel, get_time from economy.utils import ConversionRateNotFoundError, convert_amount, convert_token_to_usdt from gas.utils import recommend_min_gas_price_to_confirm_in_time from git.utils import ( From cc56e7abf28d3e3ebe9cae646971ad7526a58277 Mon Sep 17 00:00:00 2001 From: Owocki Date: Wed, 11 Sep 2019 15:59:24 -0600 Subject: [PATCH 084/131] bootstrap profile info --- app/dashboard/models.py | 8 +++++++- app/dashboard/templates/profiles/activity_stats.html | 2 +- app/dashboard/views.py | 11 ++++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 103a9a1a443..ffb69f0b4b7 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -3282,12 +3282,18 @@ def to_dict(self, activities=True, leaderboards=True, network=None, tips=True): @property def reassemble_profile_dict(self): params = self.as_dict + + # lazily generate profile dict on the fly + if not params.get('title'): + self.calculate_all() + self.save() + if params.get('tips'): params['tips'] = Tip.objects.filter(pk__in=params['tips']) if params.get('activities'): params['activities'] = Activity.objects.filter(pk__in=params['activities']) params['profile'] = self - params['portfolio'] = BountyFulfillment.objects.filter(pk__in=params['portfolio']) + params['portfolio'] = BountyFulfillment.objects.filter(pk__in=params.get('portfolio', [])) return params @property diff --git a/app/dashboard/templates/profiles/activity_stats.html b/app/dashboard/templates/profiles/activity_stats.html index 8175a932dc6..ec1693bd5a1 100644 --- a/app/dashboard/templates/profiles/activity_stats.html +++ b/app/dashboard/templates/profiles/activity_stats.html @@ -36,7 +36,7 @@ REP: {{profile.rep}}
  • - Avg Hourly Rate ${{profile.avg_hourly_rate}} + Avg Hourly Rate ${{profile.avg_hourly_rate|floatformat:2}}
  • {% endif %} {% endif %} diff --git a/app/dashboard/views.py b/app/dashboard/views.py index d744cb5286e..5e15543d0e0 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -2100,12 +2100,13 @@ def get_profile_tab(request, profile, tab, prev_context): all_activities = context.get('activities') - if all_activities.count() == 0: - context['none'] = True tabs = [] - - counts = all_activities.values('activity_type').order_by('activity_type').annotate(the_count=Count('activity_type')) - counts = {ele['activity_type']: ele['the_count'] for ele in counts} + counts = {} + if all_activities is None or all_activities.count() == 0: + context['none'] = True + else: + counts = all_activities.values('activity_type').order_by('activity_type').annotate(the_count=Count('activity_type')) + counts = {ele['activity_type']: ele['the_count'] for ele in counts} for name, actions in activity_tabs: # this functions as profile_filter_activities does From 1817dc71d1c733f9801f784084df2b56cb0663c7 Mon Sep 17 00:00:00 2001 From: Owocki Date: Thu, 12 Sep 2019 09:26:35 -0600 Subject: [PATCH 085/131] work from 20190912 --- app/dashboard/admin.py | 14 ++++- .../management/commands/create_earnings.py | 39 +++++++++++++ .../management/commands/migrate_profiles.py | 39 +++++++++++++ .../migrations/0059_auto_20190911_2313.py | 40 +++++++++++++ app/dashboard/models.py | 58 +++++++++++++++++-- .../templates/profiles/scorecard_funder.html | 2 +- .../templates/profiles/scorecard_hunter.html | 2 +- .../templates/profiles/tab_earnings.html | 26 +++++++++ .../templates/profiles/tab_spent.html | 1 + .../templates/profiles/tab_viewers.html | 2 - app/dashboard/templates/profiles/tabs.html | 20 ++++++- app/dashboard/views.py | 13 +++-- app/economy/management/commands/get_prices.py | 10 ++++ app/grants/models.py | 19 +++++- app/kudos/models.py | 13 +++++ 15 files changed, 281 insertions(+), 17 deletions(-) create mode 100644 app/dashboard/management/commands/create_earnings.py create mode 100644 app/dashboard/management/commands/migrate_profiles.py create mode 100644 app/dashboard/migrations/0059_auto_20190911_2313.py create mode 100644 app/dashboard/templates/profiles/tab_earnings.html create mode 100644 app/dashboard/templates/profiles/tab_spent.html diff --git a/app/dashboard/admin.py b/app/dashboard/admin.py index bb9b52103ab..471f7bbed49 100644 --- a/app/dashboard/admin.py +++ b/app/dashboard/admin.py @@ -24,9 +24,9 @@ from .models import ( Activity, BlockedUser, Bounty, BountyFulfillment, BountyInvites, BountySyncRequest, CoinRedemption, - CoinRedemptionRequest, Coupon, FeedbackEntry, HackathonEvent, HackathonSponsor, Interest, LabsResearch, Profile, - ProfileView, RefundFeeRequest, REPEntry, SearchHistory, Sponsor, Tip, TokenApproval, Tool, ToolVote, UserAction, - UserVerificationModel, + CoinRedemptionRequest, Coupon, Earning, FeedbackEntry, HackathonEvent, HackathonSponsor, Interest, LabsResearch, + Profile, ProfileView, RefundFeeRequest, REPEntry, SearchHistory, Sponsor, Tip, TokenApproval, Tool, ToolVote, + UserAction, UserVerificationModel, ) @@ -48,6 +48,13 @@ class REPEntryAdmin(admin.ModelAdmin): raw_id_fields = ['profile'] +class EarningAdmin(admin.ModelAdmin): + ordering = ['-id'] + list_display = ['created_on', '__str__'] + raw_id_fields = ['from_profile', 'to_profile'] + search_fields = ['from_profile__handle', 'to_profile__handle'] + + class ToolAdmin(admin.ModelAdmin): ordering = ['-id'] list_display = ['created_on', '__str__'] @@ -317,6 +324,7 @@ def link(self, instance): admin.site.register(SearchHistory, SearchHistoryAdmin) admin.site.register(Activity, ActivityAdmin) +admin.site.register(Earning, EarningAdmin) admin.site.register(REPEntry, REPEntryAdmin) admin.site.register(BlockedUser, GeneralAdmin) admin.site.register(ProfileView, GeneralAdmin) diff --git a/app/dashboard/management/commands/create_earnings.py b/app/dashboard/management/commands/create_earnings.py new file mode 100644 index 00000000000..3154f3de5f5 --- /dev/null +++ b/app/dashboard/management/commands/create_earnings.py @@ -0,0 +1,39 @@ +''' + Copyright (C) 2018 Gitcoin Core + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +''' + +from django.core.management.base import BaseCommand +from django.utils import timezone + +from dashboard.models import BountyFulfillment, Tip +from grants.models import Contribution +from kudos.models import KudosTransfer + + +class Command(BaseCommand): + + help = 'creates earnings records for deploy of https://github.com/gitcoinco/web/pull/5093' + + def handle(self, *args, **options): + for obj in BountyFulfillment.objects.all(): + obj.save() + for obj in Tip.objects.all(): + obj.save() + for obj in Contribution.objects.all(): + obj.save() + for obj in KudosTransfer.objects.all(): + obj.save() diff --git a/app/dashboard/management/commands/migrate_profiles.py b/app/dashboard/management/commands/migrate_profiles.py new file mode 100644 index 00000000000..60533e311c5 --- /dev/null +++ b/app/dashboard/management/commands/migrate_profiles.py @@ -0,0 +1,39 @@ +''' + Copyright (C) 2018 Gitcoin Core + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +''' + +from django.core import management +from django.core.management.base import BaseCommand +from django.utils import timezone + + +class Command(BaseCommand): + + help = 'runs all mgmt commands for https://github.com/gitcoinco/web/pull/5093' + + def handle(self, *args, **options): + + # one + management.call_command('create_rep_records', verbosity=0, interactive=False) + + # two + for instance in Profile.objects.filter(hide_profile=False): + instance.calculate_all() + instance.save() + + # three + management.call_command('create_earnings', verbosity=0, interactive=False) diff --git a/app/dashboard/migrations/0059_auto_20190911_2313.py b/app/dashboard/migrations/0059_auto_20190911_2313.py new file mode 100644 index 00000000000..7b14530e0c4 --- /dev/null +++ b/app/dashboard/migrations/0059_auto_20190911_2313.py @@ -0,0 +1,40 @@ +# Generated by Django 2.2.3 on 2019-09-11 23:13 + +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion +import economy.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('dashboard', '0058_profile_as_dict'), + ] + + operations = [ + migrations.AlterField( + model_name='profile', + name='as_dict', + field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict), + ), + migrations.CreateModel( + name='Earning', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_on', models.DateTimeField(db_index=True, default=economy.models.get_time)), + ('modified_on', models.DateTimeField(default=economy.models.get_time)), + ('value_usd', models.DecimalField(decimal_places=2, max_digits=50, null=True)), + ('source_id', models.PositiveIntegerField()), + ('network', models.CharField(default='', max_length=50)), + ('url', models.CharField(default='', max_length=500)), + ('from_profile', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sent_earnings', to='dashboard.Profile')), + ('source_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), + ('to_profile', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='earnings', to='dashboard.Profile')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/dashboard/models.py b/app/dashboard/models.py index ffb69f0b4b7..5f3683077f8 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -1556,10 +1556,21 @@ def psave_tip(sender, instance, **kwargs): instance.username = instance.username.replace(' ', '') -# @receiver(pre_save, sender=Bounty, dispatch_uid="normalize_usernames") -# def normalize_usernames(sender, instance, **kwargs): -# if instance.bounty_owner_github_username: -# instance.bounty_owner_github_username = instance.bounty_owner_github_username.lstrip('@') +@receiver(post_save, sender=Tip, dispatch_uid="post_save_tip") +def postsave_tip(sender, instance, **kwargs): + from django.contrib.contenttypes.models import ContentType + is_valid = instance.sender_profile != instance.recipient_profile + if is_valid: + Earning.objects.update_or_create( + created_on=instance.created_on, + from_profile=instance.sender_profile, + to_profile=instance.recipient_profile, + value_usd=instance.value_in_usdt_then, + source_type=ContentType.objects.get(app_label='dashboard', model='tip'), + source_id=instance.pk, + url='https://gitcoin.co/tips', + network=instance.network, + ) # method for updating @@ -1595,6 +1606,28 @@ def psave_bounty(sender, instance, **kwargs): instance.value_in_eth = instance.get_value_in_eth instance.value_true = instance.get_value_true + if not instance.bounty_owner_profile: + if instance.bounty_owner_github_username: + profiles = Profile.objects.filter(handle=instance.bounty_owner_github_username.lower().replace('@','')) + if profiles.exists(): + instance.bounty_owner_profile = profiles.first() + + +@receiver(post_save, sender=BountyFulfillment, dispatch_uid="psave_bounty_fulfill") +def psave_bounty_fulfilll(sender, instance, **kwargs): + from django.contrib.contenttypes.models import ContentType + if instance.accepted: + Earning.objects.update_or_create( + created_on=instance.created_on, + from_profile=instance.bounty.bounty_owner_profile, + to_profile=instance.profile, + value_usd=instance.bounty.value_in_usdt_then, + source_type=ContentType.objects.get(app_label='dashboard', model='bountyfulfillment'), + source_id=instance.pk, + url=instance.bounty.url, + network=instance.bounty.network, + ) + class InterestQuerySet(models.QuerySet): """Handle the manager queryset for Interests.""" @@ -3275,6 +3308,8 @@ def to_dict(self, activities=True, leaderboards=True, network=None, tips=True): context['suppress_sumo'] = True context['total_kudos_count'] = profile.get_my_kudos.count() + profile.get_sent_kudos.count() context['portfolio'] = profile.fulfilled.filter(bounty__network='mainnet').values_list('pk', flat=True) + context['earnings_total'] = sum(Earning.objects.filter(to_profile=profile, network='mainnet', value_usd__isnull=False).values_list('value_usd', flat=True)) + context['spent_total'] = sum(Earning.objects.filter(from_profile=profile, network='mainnet', value_usd__isnull=False).values_list('value_usd', flat=True)) return context @@ -3810,3 +3845,18 @@ def __str__(self): def psave_rep(sender, instance, **kwargs): instance.balance = sum(REPEntry.objects.filter(profile=instance.profile, created_on__lt=instance.created_on).values_list('value', flat=True)) + instance.value #print(f"updating {instance.pk} created on {instance.created_on} for {instance.why} worth {instance.value} to {instance.balance}") + +class Earning(SuperModel): + """Records Earning - the generic object for all earnings on the platform .""" + + from_profile = models.ForeignKey('dashboard.Profile', related_name='sent_earnings', on_delete=models.CASCADE, db_index=True, null=True) + to_profile = models.ForeignKey('dashboard.Profile', related_name='earnings', on_delete=models.CASCADE, db_index=True, null=True) + value_usd = models.DecimalField(decimal_places=2, max_digits=50, null=True) + source_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) + source_id = models.PositiveIntegerField() + source = GenericForeignKey('source_type', 'source_id') + network = models.CharField(max_length=50, default='') + url = models.CharField(max_length=500, default='') + + def __str__(self): + return f"{self.from_profile} => {self.to_profile} of ${self.value_usd} on {self.created_on} for {self.source}" diff --git a/app/dashboard/templates/profiles/scorecard_funder.html b/app/dashboard/templates/profiles/scorecard_funder.html index 4b5e3f78276..bba697972b3 100644 --- a/app/dashboard/templates/profiles/scorecard_funder.html +++ b/app/dashboard/templates/profiles/scorecard_funder.html @@ -15,7 +15,7 @@
    • {{ funded_bounties_count }} {% trans "bounties funded" %}
    • -
    • {{ sum_eth_funded|floatformat:2 }} ETH {% trans "funded" %}
    • +
    • ${{ spent_total|floatformat:0 }} {% trans "funded" %}
    • {% if works_with_funded|length %} {% trans "Funds" %}: diff --git a/app/dashboard/templates/profiles/scorecard_hunter.html b/app/dashboard/templates/profiles/scorecard_hunter.html index 85fb4a1814a..f780096bd3a 100644 --- a/app/dashboard/templates/profiles/scorecard_hunter.html +++ b/app/dashboard/templates/profiles/scorecard_hunter.html @@ -15,7 +15,7 @@
      • {{ count_bounties_completed }} {% trans "bounties completed" %}
      • -
      • {{ sum_eth_collected|floatformat:2 }} ETH {% trans "collected" %}
      • +
      • ${{ earnings_total|floatformat:0 }} {% trans "earned" %}
      • {% if no_times_been_removed %}
      • - {% trans "removed from" %} {{ no_times_been_removed }} {% trans "bounties" %}
      • {% endif %} diff --git a/app/dashboard/templates/profiles/tab_earnings.html b/app/dashboard/templates/profiles/tab_earnings.html new file mode 100644 index 00000000000..404e7d667d4 --- /dev/null +++ b/app/dashboard/templates/profiles/tab_earnings.html @@ -0,0 +1,26 @@ +{% load i18n static avatar_tags humanize %} +{% if not hidden %} +{% if is_editable %} + +
        + {% if earnings.count == 0 %} + No Earnings + {% endif %} + {% for earning in earnings %} +
        + +
        +
        +
        ${{earning.value_usd}}
          +
        + from {{earning.from_profile.handle}} {{earning.created_on | naturaltime}} + {% if earning.url %} + [source] + {% endif %} + +
        +
        + {% endfor %} +
        +{% endif %} +{% endif %} diff --git a/app/dashboard/templates/profiles/tab_spent.html b/app/dashboard/templates/profiles/tab_spent.html new file mode 100644 index 00000000000..7ac47f61cf7 --- /dev/null +++ b/app/dashboard/templates/profiles/tab_spent.html @@ -0,0 +1 @@ +{% include 'profiles/tab_earnings.html' with earnings=spent %} \ No newline at end of file diff --git a/app/dashboard/templates/profiles/tab_viewers.html b/app/dashboard/templates/profiles/tab_viewers.html index 0967a48515c..1a3a9423bbc 100644 --- a/app/dashboard/templates/profiles/tab_viewers.html +++ b/app/dashboard/templates/profiles/tab_viewers.html @@ -1,6 +1,5 @@ {% load i18n static avatar_tags humanize %} {% if not hidden %} -{% if is_staff %} {% if is_editable %}
        @@ -28,5 +27,4 @@
        {{viewer.viewer.handle}}
          {% endfor %}
        {% endif %} -{% endif %} {% endif %} diff --git a/app/dashboard/templates/profiles/tabs.html b/app/dashboard/templates/profiles/tabs.html index c7ef032884c..fed20ae43ef 100644 --- a/app/dashboard/templates/profiles/tabs.html +++ b/app/dashboard/templates/profiles/tabs.html @@ -44,7 +44,6 @@ Kudos {% if total_kudos_count %}({{total_kudos_count}}){%endif%} - {% if is_staff %} {% if is_editable %} {% endif %} + {% if is_editable and profile.persona_is_hunter %} + + {% endif %} + {% if is_editable and profile.persona_is_funder %} + {% endif %}
      @@ -78,6 +92,10 @@ {% include 'profiles/tab_ratings.html' %} {% elif tab == 'viewers' %} {% include 'profiles/tab_viewers.html' %} + {% elif tab == 'earnings' %} + {% include 'profiles/tab_earnings.html' %} + {% elif tab == 'spent' %} + {% include 'profiles/tab_spent.html' %} {% endif %}
    diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 5e15543d0e0..7a6a1ab8b84 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -72,8 +72,9 @@ from .helpers import get_bounty_data_for_activity, handle_bounty_views, load_files_in_directory from .models import ( Activity, Bounty, BountyDocuments, BountyFulfillment, BountyInvites, CoinRedemption, CoinRedemptionRequest, Coupon, - FeedbackEntry, HackathonEvent, HackathonSponsor, Interest, LabsResearch, Profile, ProfileSerializer, ProfileView, - RefundFeeRequest, REPEntry, SearchHistory, Sponsor, Subscription, Tool, ToolVote, UserAction, UserVerificationModel, + Earning, FeedbackEntry, HackathonEvent, HackathonSponsor, Interest, LabsResearch, Profile, ProfileSerializer, + ProfileView, RefundFeeRequest, REPEntry, SearchHistory, Sponsor, Subscription, Tool, ToolVote, UserAction, + UserVerificationModel, ) from .notifications import ( maybe_market_tip_to_email, maybe_market_tip_to_github, maybe_market_tip_to_slack, maybe_market_to_email, @@ -2158,6 +2159,10 @@ def get_profile_tab(request, profile, tab, prev_context): pass elif tab == 'portfolio': pass + elif tab == 'earnings': + context['earnings'] = Earning.objects.filter(to_profile=profile, network='mainnet', value_usd__isnull=False).order_by('-created_on') + elif tab == 'spent': + context['spent'] = Earning.objects.filter(from_profile=profile, network='mainnet', value_usd__isnull=False).order_by('-created_on') elif tab == 'kudos': owned_kudos = profile.get_my_kudos.order_by('id', order_by) sent_kudos = profile.get_sent_kudos.order_by('id', order_by) @@ -2232,7 +2237,7 @@ def profile(request, handle, tab=None): handle = handle.replace("@", "") # make sure tab param is correct - all_tabs = ['active', 'ratings', 'portfolio', 'viewers', 'activity', 'resume', 'kudos'] + all_tabs = ['active', 'ratings', 'portfolio', 'viewers', 'activity', 'resume', 'kudos', 'earnings', 'spent'] tab = default_tab if tab not in all_tabs else tab if handle in all_tabs and request.user.is_authenticated: # someone trying to go to their own profile? @@ -2243,7 +2248,7 @@ def profile(request, handle, tab=None): if not handle and request.user.is_authenticated: handle = request.user.username is_my_profile = request.user.is_authenticated and request.user.username.lower() == handle.lower() - user_only_tabs = ['viewers'] + user_only_tabs = ['viewers', 'earnings', 'spent'] tab = default_tab if tab in user_only_tabs and not is_my_profile else tab owned_kudos = None sent_kudos = None diff --git a/app/economy/management/commands/get_prices.py b/app/economy/management/commands/get_prices.py index 310f6a1283a..2e8cdac536f 100644 --- a/app/economy/management/commands/get_prices.py +++ b/app/economy/management/commands/get_prices.py @@ -26,6 +26,8 @@ import cryptocompare as cc from dashboard.models import Bounty, Tip from economy.models import ConversionRate +from grants.models import Contribution +from kudos.models import KudosTransfer from websocket import create_connection @@ -166,6 +168,14 @@ def cryptocompare(): print(f'CryptoCompare Tip {tip.pk}') refresh_conv_rate(tip.created_on, tip.tokenName) + for obj in KudosTransfer.objects.all(): + print(f'CryptoCompare KT {obj.pk}') + refresh_conv_rate(obj.created_on, obj.tokenName) + + for obj in Contribution.objects.all(): + print(f'CryptoCompare GrantContrib {obj.pk}') + refresh_conv_rate(obj.created_on, obj.subscription.token_symbol) + class Command(BaseCommand): """Define the management command to update currency conversion rates.""" diff --git a/app/grants/models.py b/app/grants/models.py index 457c797b3c9..20fafacbac6 100644 --- a/app/grants/models.py +++ b/app/grants/models.py @@ -25,7 +25,7 @@ from django.contrib.postgres.fields import ArrayField, JSONField from django.db import models from django.db.models import Q -from django.db.models.signals import pre_save +from django.db.models.signals import post_save, pre_save from django.dispatch import receiver from django.utils import timezone from django.utils.timezone import localtime @@ -853,6 +853,23 @@ def update_tx_status(self): self.success = tx_status == 'success' self.tx_cleared = True +@receiver(post_save, sender=Contribution, dispatch_uid="psave_contrib") +def psave_contrib(sender, instance, **kwargs): + + from django.contrib.contenttypes.models import ContentType + from dashboard.models import Earning + Earning.objects.update_or_create( + created_on=instance.created_on, + from_profile=instance.subscription.contributor_profile, + to_profile=instance.subscription.grant.admin_profile, + value_usd=instance.subscription.get_converted_amount(), + source_type=ContentType.objects.get(app_label='grants', model='contribution'), + source_id=instance.pk, + url=instance.subscription.grant.url, + network=instance.subscription.grant.network, + ) + + def next_month(): """Get the next month time.""" return localtime(timezone.now() + timedelta(days=30)) diff --git a/app/kudos/models.py b/app/kudos/models.py index cd632e5bf4a..56cb6ceca2a 100644 --- a/app/kudos/models.py +++ b/app/kudos/models.py @@ -446,6 +446,19 @@ def psave_kt(sender, instance, **kwargs): token.popularity_quarter = all_transfers.filter(created_on__gt=(timezone.now() - timezone.timedelta(days=90))).count() token.save() + from django.contrib.contenttypes.models import ContentType + from dashboard.models import Earning + Earning.objects.update_or_create( + created_on=instance.created_on, + from_profile=instance.sender_profile, + to_profile=instance.recipient_profile, + value_usd=instance.value_in_usdt_then, + source_type=ContentType.objects.get(app_label='kudos', model='kudostransfer'), + source_id=instance.pk, + url=instance.kudos_token_cloned_from.url, + network=instance.network, + ) + class Contract(SuperModel): From f707ad35c040ff668c45b1259128037ce546795a Mon Sep 17 00:00:00 2001 From: Owocki Date: Thu, 12 Sep 2019 13:36:31 -0600 Subject: [PATCH 086/131] threshold per frank comment --- app/dashboard/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 5f3683077f8..d160332ca85 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -2498,8 +2498,8 @@ def calc_activity_level(self): str: High, Low, Medium, or New """ - high_threshold = 15 - med_threshold = 7 + high_threshold = 7 + med_threshold = 2 new_threshold_days = 7 if self.created_on > (timezone.now() - timezone.timedelta(days=new_threshold_days)): From 1f61cb0b777e0f9dcc10e2118f7679f472f7700e Mon Sep 17 00:00:00 2001 From: Owocki Date: Thu, 12 Sep 2019 15:53:47 -0600 Subject: [PATCH 087/131] a bunch of small touch ups --- app/assets/v2/css/profile.css | 6 +++ app/assets/v2/js/pages/profile.js | 2 +- app/dashboard/models.py | 42 +++++++------------ app/dashboard/templates/profiles/heatmap.html | 2 +- .../templates/profiles/organization.html | 1 - .../templates/profiles/scorecard_funder.html | 7 ++-- .../templates/profiles/scorecard_hunter.html | 3 +- .../templates/profiles/tab_active.html | 2 +- .../templates/profiles/tab_earnings.html | 11 +++-- .../templates/profiles/tab_portfolio.html | 6 +-- .../templates/profiles/tab_ratings.html | 24 ++++++----- .../templates/profiles/tab_viewers.html | 2 +- app/dashboard/templates/profiles/tabs.html | 6 +-- app/dashboard/templates/shared/feedback.html | 12 +++--- .../templates/shared/rate_bounties.html | 4 +- 15 files changed, 62 insertions(+), 68 deletions(-) diff --git a/app/assets/v2/css/profile.css b/app/assets/v2/css/profile.css index aa177d09a63..639c298ed7c 100644 --- a/app/assets/v2/css/profile.css +++ b/app/assets/v2/css/profile.css @@ -134,6 +134,12 @@ width: 100%; height: 40px; } + +.odd{ + background-color: #f9f9f9; + border-top: #eeeeee 1px solid; + border-bottom: #eeeeee 1px solid; +} /* .is_editable a:hover .profile-header__avatar{ border: 3px solid #0fce7c; diff --git a/app/assets/v2/js/pages/profile.js b/app/assets/v2/js/pages/profile.js index a02803775e9..337d846933b 100644 --- a/app/assets/v2/js/pages/profile.js +++ b/app/assets/v2/js/pages/profile.js @@ -104,7 +104,7 @@ $(document).ready(function() { if ($('#rep_dataviz').length) { // Set the dimensions of the canvas / graph var margin = {top: 30, right: 30, bottom: 30, left: 70}; - var width = $('#tab_controller').width() - margin.left - margin.right; + var width = $('.container.position-relative').width() - margin.left - margin.right; var height = 120 - margin.top - margin.bottom; // Parse the date / time diff --git a/app/dashboard/models.py b/app/dashboard/models.py index d160332ca85..d9f7845dbbb 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -2335,7 +2335,7 @@ def calculate_all(self): self.avg_hourly_rate = self.calc_avg_hourly_rate() self.success_rate = self.calc_success_rate() self.rep = self.calc_rep_number() - self.as_dict = json.loads(json.dumps(self.to_dict(tips=False), cls=EncodeAnything)) + self.as_dict = json.loads(json.dumps(self.to_dict(), cls=EncodeAnything)) self.last_calc_date = timezone.now() + timezone.timedelta(seconds=1) def get_persona_action_count(self): @@ -3202,19 +3202,9 @@ def activate_avatar(self, avatar_pk): self.avatar_baseavatar_related.update(active=False) self.avatar_baseavatar_related.filter(pk=avatar_pk).update(active=True) - def to_dict(self, activities=True, leaderboards=True, network=None, tips=True): + def to_dict(self): """Get the dictionary representation with additional data. - Args: - activities (bool): Whether or not to include activity queryset data. - Defaults to: True. - leaderboards (bool): Whether or not to include leaderboard position data. - Defaults to: True. - network (str): The Ethereum network to use for relevant queries. - Defaults to: None (Environment specific). - tips (bool): Whether or not to include tip data. - Defaults to: True. - Attributes: params (dict): The context dictionary to be returned. network (str): The bounty network to operate on. @@ -3233,7 +3223,7 @@ def to_dict(self, activities=True, leaderboards=True, network=None, tips=True): """ params = {} - network = network or self.get_network() + network = self.get_network() query_kwargs = {'network': network} bounties = self.bounties fulfilled_bounties = self.get_fulfilled_bounties(network=network) @@ -3286,17 +3276,12 @@ def to_dict(self, activities=True, leaderboards=True, network=None, tips=True): 'bounties': bounties.values_list('pk', flat=True), } - if activities: - params['activities'] = self.get_various_activities().values_list('pk', flat=True) - - if tips: - params['tips'] = self.tips.filter(**query_kwargs).send_happy_path().values_list('pk', flat=True) - - if leaderboards: - params['scoreboard_position_contributor'] = self.get_contributor_leaderboard_index() - params['scoreboard_position_funder'] = self.get_funder_leaderboard_index() - if self.is_org: - params['scoreboard_position_org'] = self.get_org_leaderboard_index() + params['activities'] = self.get_various_activities().values_list('pk', flat=True) + params['tips'] = self.tips.filter(**query_kwargs).send_happy_path().values_list('pk', flat=True) + params['scoreboard_position_contributor'] = self.get_contributor_leaderboard_index() + params['scoreboard_position_funder'] = self.get_funder_leaderboard_index() + if self.is_org: + params['scoreboard_position_org'] = self.get_org_leaderboard_index() context = params profile = self @@ -3308,9 +3293,12 @@ def to_dict(self, activities=True, leaderboards=True, network=None, tips=True): context['suppress_sumo'] = True context['total_kudos_count'] = profile.get_my_kudos.count() + profile.get_sent_kudos.count() context['portfolio'] = profile.fulfilled.filter(bounty__network='mainnet').values_list('pk', flat=True) - context['earnings_total'] = sum(Earning.objects.filter(to_profile=profile, network='mainnet', value_usd__isnull=False).values_list('value_usd', flat=True)) - context['spent_total'] = sum(Earning.objects.filter(from_profile=profile, network='mainnet', value_usd__isnull=False).values_list('value_usd', flat=True)) - + context['earnings_total'] = round(sum(Earning.objects.filter(to_profile=profile, network='mainnet', value_usd__isnull=False).values_list('value_usd', flat=True))) + context['spent_total'] = round(sum(Earning.objects.filter(from_profile=profile, network='mainnet', value_usd__isnull=False).values_list('value_usd', flat=True))) + if context['earnings_total'] > 1000: + context['earnings_total'] = f"{round(context['earnings_total']/1000)}k" + if context['spent_total'] > 1000: + context['spent_total'] = f"{round(context['spent_total']/1000)}k" return context diff --git a/app/dashboard/templates/profiles/heatmap.html b/app/dashboard/templates/profiles/heatmap.html index 364135d03d2..cc3dce697d6 100644 --- a/app/dashboard/templates/profiles/heatmap.html +++ b/app/dashboard/templates/profiles/heatmap.html @@ -4,7 +4,7 @@ -
    +
    - - - - -

    Relationships

    -
    -
    - + + + +

    Relationships

    +
    + + +
    diff --git a/app/dashboard/templates/profiles/scorecard_funder.html b/app/dashboard/templates/profiles/scorecard_funder.html index 4a8f9ce403f..8d067a54ef0 100644 --- a/app/dashboard/templates/profiles/scorecard_funder.html +++ b/app/dashboard/templates/profiles/scorecard_funder.html @@ -1,37 +1,44 @@ {% load i18n static avatar_tags %}
    -
    -
    -
    - {% if scoreboard_position_funder %} - #{{ scoreboard_position_funder }} - {% else %} - {% endif %} - {% trans "Funder" %} - {% include "shared/profile_rank_link.html" with link='payers' %} -
    -
    -
      -
    • {{ funded_bounties_count }} {% trans "bounties funded" %}
    • -
    • ${{ spent_total }} {% trans "funded" %}
    • -
    • - {% if works_with_funded|length %} - {% trans "Funds" %}: - {% for profile, num_times in works_with_funded.items %} - {% if forloop.counter < 6 %} - - - - {% endif %} - {% endfor %} - {% if works_with_funded|length > 5 %} -
      +{{works_with_funded|length|add:"-5"}}
      - {% endif %} - {% endif %} -
    • -
    -
    -
    -
    - {% include "profiles/activity_level.html" with level='High'%} +
    +
    +
    + {% if scoreboard_position_funder %} + #{{ scoreboard_position_funder }} + {% else %} + {% endif %} + {% trans "Funder" %} + {% include "shared/profile_rank_link.html" with link='payers' %} +
    +
    +
      +
    • + {{ funded_bounties_count }} {% trans "bounties funded" %} +
    • +
    • + ${{ spent_total }} {% trans "funded" %} +
    • +
    • + {% if works_with_funded|length %} + + + {% trans "Funds" %}: + + {% for profile, num_times in works_with_funded.items %} + {% if forloop.counter < 6 %} + + + + {% endif %} + {% endfor %} + {% if works_with_funded|length > 5 %} +
      +{{works_with_funded|length|add:"-5"}}
      + {% endif %} + {% endif %} +
    • +
    +
    +
    +
    + {% include "profiles/activity_level.html" with level='High'%} \ No newline at end of file diff --git a/app/dashboard/templates/profiles/scorecard_hunter.html b/app/dashboard/templates/profiles/scorecard_hunter.html index 0054473cb4c..c52b76eac9a 100644 --- a/app/dashboard/templates/profiles/scorecard_hunter.html +++ b/app/dashboard/templates/profiles/scorecard_hunter.html @@ -15,10 +15,20 @@
      -
    • {{ count_bounties_completed }} {% trans "bounties completed" %}
    • -
    • ${{ earnings_total }} {% trans "earned" %}
    • +
    • + {{ count_bounties_completed }} + {% trans "bounties completed" %} +
    • +
    • + ${{ earnings_total }} + {% trans "earned" %} +
    • {% if no_times_been_removed %} -
    • - {% trans "removed from" %} {{ no_times_been_removed }} {% trans "bounties" %}
    • +
    • + - {% trans "removed from" %} + {{ no_times_been_removed }} + {% trans "bounties" %} +
    • {% endif %}
    • {% if works_with_collected|length %} @@ -38,10 +48,10 @@
    {% for keyword in profile.keywords %} - {{keyword}} + {{keyword}} {% endfor %}
    -
    - {% include "profiles/activity_level.html"%} +
    + {% include "profiles/activity_level.html"%} diff --git a/app/dashboard/templates/profiles/skillchart.html b/app/dashboard/templates/profiles/skillchart.html index 201e52c49c5..1e020dd0aa1 100644 --- a/app/dashboard/templates/profiles/skillchart.html +++ b/app/dashboard/templates/profiles/skillchart.html @@ -1,82 +1,81 @@ - - + - - - -
    - - + + const radarChartOptions = { + w: width, + h: height, + margin: margin, + maxValue: 0.5, + levels: 5, + roundStrokes: true, + color: color + }; + //Call function to draw the Radar chart + RadarChart(".radarChart", data, radarChartOptions); + \ No newline at end of file diff --git a/app/dashboard/templates/profiles/tab_active.html b/app/dashboard/templates/profiles/tab_active.html index 0fbef5d018b..e0da2b794b8 100644 --- a/app/dashboard/templates/profiles/tab_active.html +++ b/app/dashboard/templates/profiles/tab_active.html @@ -15,7 +15,7 @@
    {{bounty.title}}
      {% endfor %}
    - diff --git a/app/dashboard/templates/profiles/tab_activity.html b/app/dashboard/templates/profiles/tab_activity.html index 258772c2c31..ee228cbe008 100644 --- a/app/dashboard/templates/profiles/tab_activity.html +++ b/app/dashboard/templates/profiles/tab_activity.html @@ -1,58 +1,58 @@ {% load i18n static %} - {% if is_staff and not profile.is_org %} -
    -
    - {% include "profiles/REPgraph.html" %} -
    +{% if is_staff and not profile.is_org %} +
    +
    + {% include "profiles/REPgraph.html" %}
    - {% endif %} +
    +{% endif %} -
    -
    - {% include "profiles/heatmap.html" %} -
    -
    +
    +
    + {% include "profiles/heatmap.html" %} +
    +
    - {% if is_my_profile %} - {% include 'profiles/status_box.html' %} - {% endif %} +{% if is_my_profile %} + % include 'profiles/status_box.html' %} +{% endif %} -
    -
    -
    -
    - {% for tab in tabs %} - - {% endfor %} -
    -
    - {% for tab in tabs %} -
    -
    -
    -
    - {% if show_activity %} - {% if tab.type == 'activity' %} - {% include 'profiles/profile_activities.html' with activities=tab.objects %} - {% else %} - {% include 'profiles/profile_bounties.html' with bounties=tab.objects %} - {% endif %} - {% endif %} -
    -
    -
    +
    +
    +
    +
    + {% for tab in tabs %} + + {% endfor %} +
    +
    + {% for tab in tabs %} +
    +
    +
    +
    + {% if show_activity %} + {% if tab.type == 'activity' %} + {% include 'profiles/profile_activities.html' with activities=tab.objects %} + {% else %} + {% include 'profiles/profile_bounties.html' with bounties=tab.objects %} + {% endif %} + {% endif %}
    - {% endfor %} -
    -
    - -
    + {% endfor %} +
    +
    + -
    \ No newline at end of file + +
    +
    +
    +
    \ No newline at end of file diff --git a/app/dashboard/templates/profiles/tab_kudos.html b/app/dashboard/templates/profiles/tab_kudos.html index 28bc52664f9..63973767c93 100644 --- a/app/dashboard/templates/profiles/tab_kudos.html +++ b/app/dashboard/templates/profiles/tab_kudos.html @@ -1,9 +1,9 @@ {% load i18n static %} - {% if not hidden and not profile.is_org %} -
    -
    - {% include "shared/profile_kudos.html" %} -
    +{% if not hidden and not profile.is_org %} +
    +
    + {% include "shared/profile_kudos.html" %}
    - {% endif %} +
    +{% endif %} \ No newline at end of file diff --git a/app/dashboard/templates/profiles/tab_portfolio.html b/app/dashboard/templates/profiles/tab_portfolio.html index 8dcf73b9cc6..723904cd553 100644 --- a/app/dashboard/templates/profiles/tab_portfolio.html +++ b/app/dashboard/templates/profiles/tab_portfolio.html @@ -5,7 +5,9 @@ {{keyword}} {% endfor %}
    +
    +
    Projects
    @@ -23,12 +25,12 @@
    {{submission.bounty.title}}
      {% endfor %}
    -
    +
    View Bounty > {% if submission.fulfiller_github_url %} View Work > {% endif %} -
    +
    {% endfor %} @@ -46,11 +48,11 @@
    {{pi.title}}
      {% endfor %}
    -
    +
    {% if pi.link %} View Work > {% endif %} -
    +
    {% endfor %} @@ -60,30 +62,30 @@
    {{pi.title}}
     
    Add a project
    -
    -
    - {% csrf_token %} -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
     
    - -
    +
    + + {% csrf_token %} +
    +
    +
    + +
    -
    -
    +
    + + +
    +
    + + +
    +
    +
     
    + +
    +
    +
    +
    {% endif %} diff --git a/app/dashboard/templates/profiles/tab_ratings.html b/app/dashboard/templates/profiles/tab_ratings.html index 5ec5e02f917..025d17897dd 100644 --- a/app/dashboard/templates/profiles/tab_ratings.html +++ b/app/dashboard/templates/profiles/tab_ratings.html @@ -9,7 +9,7 @@ {% endfor %}
    -   {{ avg_rating_scaled.total_rating }} {% trans "rating" %}{{avg_rating_scaled.total_rating | pluralize}} +   {{ avg_rating_scaled.total_rating }} {% trans "rating" %}{{avg_rating_scaled.total_rating | pluralize}}
    @@ -78,8 +78,8 @@
    Reviews
    {% for feedback in feedbacks_got %} -
    - {% include "shared/feedback.html" %} -
    +
    + {% include "shared/feedback.html" %} +
    {% endfor %}
    \ No newline at end of file diff --git a/app/dashboard/templates/profiles/tab_resume.html b/app/dashboard/templates/profiles/tab_resume.html index 0c4cc243365..cc6ff570ae2 100644 --- a/app/dashboard/templates/profiles/tab_resume.html +++ b/app/dashboard/templates/profiles/tab_resume.html @@ -3,27 +3,31 @@ {% if not hidden and not profile.is_org and show_resume_tab %}
    Job Preferences
    -
    +
    + {% if is_my_profile %} +
    + + Only visible to you +
    + Edit this info +
    + {% endif %} - {% if is_my_profile %} -
    - Only visible to you -
    - Edit this info -
    - {% endif %} + {% if profile.job_status_verbose %} + + {{profile.job_status_verbose}} ({{profile.job_type}}) + {% endif %} +
    - {% if profile.job_status_verbose %} - - {{profile.job_status_verbose}} ({{profile.job_type}}) - {% endif %} -
    {% if profile.job_location %}
    - - Looking for companies in {% for loc in profile.job_location %}{{loc.name}}, {% endfor %} {% if profile.remote %}(Remote OK){%endif%} + + + Looking for companies in {% for loc in profile.job_location %}{{loc.name}}, {% endfor %} {% if profile.remote %}(Remote OK){%endif%} +
    {% endif %} + {% if profile.job_salary %}
    @@ -34,9 +38,9 @@
    {% if profile.resume %}
    -
    Resume
    - Download Resume -
    +
    Resume
    + Download Resume +
    diff --git a/app/dashboard/templates/profiles/tab_viewers.html b/app/dashboard/templates/profiles/tab_viewers.html index 41c662f624c..0ab1d651361 100644 --- a/app/dashboard/templates/profiles/tab_viewers.html +++ b/app/dashboard/templates/profiles/tab_viewers.html @@ -1,30 +1,29 @@ {% load i18n static avatar_tags humanize %} {% if not hidden %} -{% if is_editable %} - -
    - {% if profile.viewed_by.count == 0 %} - No Viewers - {% endif %} - {% for viewer in profile.viewed_by.all %} -
    - -
    -
    -
    {{viewer.viewer.handle}}
      -
    - Viewed profile {{viewer.created_on | naturaltime}} -
    - {% for keyword in viewer.keywords %} - {{keyword}} - {% endfor %} -
    -
    -
    - View Profile > + {% if is_editable %} +
    + {% if profile.viewed_by.count == 0 %} + No Viewers + {% endif %} + {% for viewer in profile.viewed_by.all %} +
    + +
    +
    +
    {{viewer.viewer.handle}}
      +
    + Viewed profile {{viewer.created_on | naturaltime}} +
    + {% for keyword in viewer.keywords %} + {{keyword}} + {% endfor %} +
    +
    +
    + {% endfor %}
    - {% endfor %} -
    -{% endif %} + {% endif %} {% endif %} diff --git a/app/dashboard/templates/profiles/tabs.html b/app/dashboard/templates/profiles/tabs.html index d0b1e8b1351..00d3d7dd480 100644 --- a/app/dashboard/templates/profiles/tabs.html +++ b/app/dashboard/templates/profiles/tabs.html @@ -1,83 +1,83 @@ {% load i18n static %} - {% if not hidden and not profile.is_org %} -
    -
    - -
    - {% endif %} +{% if not hidden and not profile.is_org %} +
    +
    + +
    +{% endif %} -
    -
    -
    -
    -
    +
    +
    +
    +
    +
    {% if tab == 'kudos' %} {% include 'profiles/tab_kudos.html' %} {% elif tab == 'resume' %} @@ -97,10 +97,8 @@ {% elif tab == 'spent' %} {% include 'profiles/tab_spent.html' %} {% endif %} -
    - - +
    \ No newline at end of file diff --git a/app/dashboard/templates/profiles/tabs_close.html b/app/dashboard/templates/profiles/tabs_close.html index a030dde7dab..1e3225e05d3 100644 --- a/app/dashboard/templates/profiles/tabs_close.html +++ b/app/dashboard/templates/profiles/tabs_close.html @@ -1,3 +1,3 @@ - {% if not hidden and not profile.is_org %} -
    - {% endif %} +{% if not hidden and not profile.is_org %} +
    +{% endif %} \ No newline at end of file diff --git a/app/dashboard/templates/shared/feedback.html b/app/dashboard/templates/shared/feedback.html index eb394320cf4..97bfa0d5822 100644 --- a/app/dashboard/templates/shared/feedback.html +++ b/app/dashboard/templates/shared/feedback.html @@ -15,32 +15,35 @@ along with this program. If not, see . {% endcomment %} {% load i18n staticfiles avatar_tags%} -
    -
    - - -
    + +
    +
    + +
    -
    -
    -
    - {% if feedback.private %} -
    - Only visible to you -
    - {% endif %} - @{{feedback.sender_profile}} - for {{feedback.bounty.org_name}}: - {{feedback.bounty.title}} - -
    -
    - {% for rating in ratings %} - - {% endfor %} -
    -
    +
    + +
    +
    +
    + {% if feedback.private %} +
    + Only visible to you +
    + {% endif %} + @{{feedback.sender_profile}} + for {{feedback.bounty.org_name}}: + {{feedback.bounty.title}} + +
    +
    + {% for rating in ratings %} + + {% endfor %} +
    - {% if feedback.comment %} - {{ feedback.comment }} - {% endif %} +
    + +{% if feedback.comment %} + {{ feedback.comment }} +{% endif %} diff --git a/app/dashboard/templates/shared/profile_rank_link.html b/app/dashboard/templates/shared/profile_rank_link.html index 53601ac2a3d..4f16445b621 100644 --- a/app/dashboard/templates/shared/profile_rank_link.html +++ b/app/dashboard/templates/shared/profile_rank_link.html @@ -14,8 +14,6 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . {% endcomment %} - {% if is_my_profile %} - (Toggle) - {% endif %} - - +{% if is_my_profile %} + (Toggle) +{% endif %} \ No newline at end of file From c8d3978d50e4ba53e7e38472e1765d8706cd7998 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 17 Sep 2019 12:43:23 -0600 Subject: [PATCH 096/131] tabs fix --- app/assets/v2/css/gitcoin.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/v2/css/gitcoin.css b/app/assets/v2/css/gitcoin.css index 6a12874ea19..bd3587f49a8 100644 --- a/app/assets/v2/css/gitcoin.css +++ b/app/assets/v2/css/gitcoin.css @@ -400,7 +400,7 @@ div.button-pink { margin-right: 0.5rem; } -.nav-link span { +#tabs .nav-link span { position: relative; font-size: 0.3rem; font-weight: bold; From 35177b2a8bb42c95e942ac08e67386a347de10a3 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 17 Sep 2019 15:34:20 -0600 Subject: [PATCH 097/131] massively optimizes profile calculations --- app/dashboard/models.py | 42 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 50ef7ea76b6..f8bcdbb558f 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -2534,8 +2534,9 @@ def calc_longest_streak(self): # setup action_dates = self.actions.all().values_list('created_on', flat=True) - start_date = timezone.datetime(self.created_on.year, self.created_on.month, self.created_on.day) - end_date = timezone.datetime(timezone.now().year, timezone.now().month, timezone.now().day) + action_dates = set([ele.replace(tzinfo=pytz.utc).strftime('%m/%d/%Y') for ele in action_dates]) + start_date = timezone.datetime(self.created_on.year, self.created_on.month, self.created_on.day).replace(tzinfo=pytz.utc) + end_date = timezone.datetime(timezone.now().year, timezone.now().month, timezone.now().day).replace(tzinfo=pytz.utc) # loop setup iterdate = start_date @@ -2550,7 +2551,7 @@ def calc_longest_streak(self): if not is_weekday: continue - has_action_during_window = len([ele for ele in action_dates if ele > last_iterdate.replace(tzinfo=pytz.utc) and ele < iterdate.replace(tzinfo=pytz.utc)]) + has_action_during_window = iterdate.strftime('%m/%d/%Y') in action_dates if has_action_during_window: this_streak += 1 if this_streak > max_streak: @@ -2569,15 +2570,9 @@ def calc_num_repeated_relationships(self): """ bounties = self.bounties - completed_bounties = bounties.filter(idx_status__in=['done']) relationships = [] - for bounty in completed_bounties: - fulfiller_handles = bounty.fulfillers_handles - if bounty.is_funder(self.handle): - for handle in fulfiller_handles: - relationships.append(handle) - if self.handle in fulfiller_handles: - relationships.append(bounty.bounty_owner_github_username) + relationships += list(self.sent_earnings.values_list('to_profile__handle', flat=True)) + relationships += list(self.earnings.values_list('from_profile__handle', flat=True)) rel_count = { key: 0 for key in relationships } for rel in relationships: @@ -2593,14 +2588,11 @@ def calc_avg_hourly_rate(self): float: the average hourly rate for this user in dollars """ - rates = [] - for bounty in self.bounties: - hr = bounty.hourly_rate - if hr: - rates.append(hr) - if len(rates) == 0: - return 0 - return sum(rates)/len(rates) + values_list = self.bounties.values_list('fulfillments__fulfiller_hours_worked', 'value_in_usdt') + values_list = [ele for ele in values_list if (ele[0] and ele[1])] + hourly_rates = [(ele[1]/ele[0]) for ele in values_list] + avg_hourly_rate = sum(hourly_rates)/len(hourly_rates) + return avg_hourly_rate def calc_success_rate(self): """ @@ -2609,14 +2601,16 @@ def calc_success_rate(self): int; the success percentage for this users bounties as a positive integer. """ - bounties = self.bounties - completed_bounties = bounties.filter(idx_status__in=['done']) - eligible_bounties = bounties.filter(idx_status__in=['done', 'expired', 'cancelled']) + bounties = self.bounties.filter(network=self.get_network()) if self.cascaded_persona == 'hunter' else self.bounties_funded.current() + completed_bounties = bounties.filter(idx_status='done').count() + expired_bounties = bounties.filter(idx_status='expired').count() + cancelled_bounties = bounties.filter(idx_status='cancelled').count() + eligible_bounties = cancelled_bounties + expired_bounties + completed_bounties - if eligible_bounties.count() == 0: + if eligible_bounties == 0: return -1 - return int(completed_bounties.count() * 100 / eligible_bounties.count()) + return int(completed_bounties * 100 / eligible_bounties) def calc_rep_number(self): """ From f35cb5c24987d580869ba17195cc8d56900b8a6f Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 17 Sep 2019 16:36:23 -0600 Subject: [PATCH 098/131] profile work --- app/assets/v2/css/profile.css | 4 +++ app/dashboard/helpers.py | 3 +- .../management/commands/migrate_profiles.py | 28 +++++++++++++++++-- .../templates/profiles/header_details.html | 19 +++++++++++-- app/dashboard/templates/profiles/heatmap.html | 1 + .../templates/profiles/organization.html | 9 ++++-- .../templates/profiles/scorecard_funder.html | 4 ++- app/dashboard/tests/test_dashboard_models.py | 2 +- app/dashboard/tip_views.py | 3 +- app/dashboard/views.py | 1 + app/retail/templates/home/nav.html | 8 +++++- app/retail/views.py | 2 +- 12 files changed, 71 insertions(+), 13 deletions(-) diff --git a/app/assets/v2/css/profile.css b/app/assets/v2/css/profile.css index 48e93e54c7a..852f68b0cea 100644 --- a/app/assets/v2/css/profile.css +++ b/app/assets/v2/css/profile.css @@ -109,6 +109,10 @@ box-shadow: 0 -2px 4px 0 rgba(0,0,0,0.50); } +#kudos_header img{ + box-shadow: none; +} + .avatar_edit { text-align: center; background: #000; diff --git a/app/dashboard/helpers.py b/app/dashboard/helpers.py index d721b594b76..a3815e1e258 100644 --- a/app/dashboard/helpers.py +++ b/app/dashboard/helpers.py @@ -741,7 +741,7 @@ def get_fulfillment_data_for_activity(fulfillment): return data -def record_bounty_activity(event_name, old_bounty, new_bounty, _fulfillment=None): +def record_bounty_activity(event_name, old_bounty, new_bounty, _fulfillment=None, override_created=None): """Records activity based on bounty changes Args: @@ -781,6 +781,7 @@ def record_bounty_activity(event_name, old_bounty, new_bounty, _fulfillment=None if user_profile: return Activity.objects.create( + created_on=timezone.now() if not override_created else override_created, profile=user_profile, activity_type=event_name, bounty=new_bounty, diff --git a/app/dashboard/management/commands/migrate_profiles.py b/app/dashboard/management/commands/migrate_profiles.py index 60533e311c5..2b20c922e43 100644 --- a/app/dashboard/management/commands/migrate_profiles.py +++ b/app/dashboard/management/commands/migrate_profiles.py @@ -27,8 +27,32 @@ class Command(BaseCommand): def handle(self, *args, **options): + + # four + from dashboard.helpers import record_bounty_activity + from dashboard.models import Bounty + bounties = Bounty.objects.current().filter(web3_created__lt=timezone.datetime(2019,3,5)).filter(network='mainnet') + for bounty in bounties: + try: + record_bounty_activity('new_bounty', None, bounty, _fulfillment=None, override_created=bounty.web3_created) + print(bounty.url) + for ful in bounty.fulfillments.all(): + record_bounty_activity('work_submitted', None, bounty, _fulfillment=ful, override_created=ful.created_on) + except Exception as e: + print(e) + + + from dashboard.models import Tip + from dashboard.tip_views import record_tip_activity + for tip in Tip.objects.filter(network='mainnet').filter(created_on__lt=timezone.datetime(2019,3,5)): + try: + record_tip_activity(tip, tip.username, 'new_tip', override_created=tip.created_on) + print(tip.pk) + except Exception as e: + print(e) + # one - management.call_command('create_rep_records', verbosity=0, interactive=False) + management.call_command('create_rep_records') # two for instance in Profile.objects.filter(hide_profile=False): @@ -36,4 +60,4 @@ def handle(self, *args, **options): instance.save() # three - management.call_command('create_earnings', verbosity=0, interactive=False) + management.call_command('create_earnings') diff --git a/app/dashboard/templates/profiles/header_details.html b/app/dashboard/templates/profiles/header_details.html index 0f3d514622a..f50364d941a 100644 --- a/app/dashboard/templates/profiles/header_details.html +++ b/app/dashboard/templates/profiles/header_details.html @@ -1,4 +1,4 @@ -{% load i18n static avatar_tags add_url_schema email_obfuscator %} +{% load i18n static avatar_tags add_url_schema email_obfuscator kudos_extras %}

    {{ profile.name }} @@ -59,10 +59,23 @@

    {% endif %}

    {% endif %} -{% if profile.show_job_status %} +
    + {% for i in ratings %} + + {% endfor %} + ({{ avg_rating.total_rating }} {% trans "rating" %}{{avg_rating.total_rating | pluralize}}) +
    +{% if profile.show_job_status %}
    {{ profile.job_status_verbose }}
    {% endif %} - +{% if total_kudos_count %} +
    + {% for kudos_group in my_kudos %} + + {% endfor %} + ({{ total_kudos_count }} {% trans "kudo" %}{{total_kudos_count | pluralize}}) +
    +{% endif %}
    \ No newline at end of file diff --git a/app/dashboard/templates/profiles/heatmap.html b/app/dashboard/templates/profiles/heatmap.html index 0dec88558b6..09b4850a3d2 100644 --- a/app/dashboard/templates/profiles/heatmap.html +++ b/app/dashboard/templates/profiles/heatmap.html @@ -19,6 +19,7 @@ legend: [1,3,5,8,13,21,34,55], tooltip: true, cellSize: 14, + tooltip: false, itemName: ["activity", "activities"], start: oneYearAgo, end: new Date(), diff --git a/app/dashboard/templates/profiles/organization.html b/app/dashboard/templates/profiles/organization.html index 257946889ba..73951973c04 100644 --- a/app/dashboard/templates/profiles/organization.html +++ b/app/dashboard/templates/profiles/organization.html @@ -15,14 +15,19 @@ along with this program. If not, see . {% endcomment %} {% load i18n static avatar_tags %} -
    +
    +   +
    +
    {% if scoreboard_position_org %} #{{ scoreboard_position_org }} {% else %} {% endif %} - {% trans "Organization" %} + + {% trans "Organization" %} + {% include "shared/profile_rank_link.html" with link='orgs' %}
    diff --git a/app/dashboard/templates/profiles/scorecard_funder.html b/app/dashboard/templates/profiles/scorecard_funder.html index 8d067a54ef0..1ffeeaac855 100644 --- a/app/dashboard/templates/profiles/scorecard_funder.html +++ b/app/dashboard/templates/profiles/scorecard_funder.html @@ -8,7 +8,9 @@ #{{ scoreboard_position_funder }} {% else %} {% endif %} - {% trans "Funder" %} + + {% trans "Funder" %} + {% include "shared/profile_rank_link.html" with link='payers' %}
    diff --git a/app/dashboard/tests/test_dashboard_models.py b/app/dashboard/tests/test_dashboard_models.py index a7f1a0b4adc..88c87c6e116 100644 --- a/app/dashboard/tests/test_dashboard_models.py +++ b/app/dashboard/tests/test_dashboard_models.py @@ -475,7 +475,7 @@ def test_profile(): assert profile.is_org is True assert profile.bounties.first() == bounty assert profile.tips.first() == tip - assert profile.desc == '@gitcoinco is a newbie who has participated in 1 funded issue on Gitcoin' + assert profile.desc == '@gitcoinco is a organization who has participated in 1 funded issue on Gitcoin' assert profile.github_url == 'https://github.com/gitcoinco' assert profile.get_relative_url() == '/profile/gitcoinco' diff --git a/app/dashboard/tip_views.py b/app/dashboard/tip_views.py index 8360d899a62..78b42843a36 100644 --- a/app/dashboard/tip_views.py +++ b/app/dashboard/tip_views.py @@ -60,8 +60,9 @@ def send_tip(request): return TemplateResponse(request, 'onepager/send1.html', params) -def record_tip_activity(tip, github_handle, event_name): +def record_tip_activity(tip, github_handle, event_name, override_created=None): kwargs = { + 'created_on': timezone.now() if not override_created else override_created, 'activity_type': event_name, 'tip': tip, 'metadata': { diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 439d61716b3..4b081f7e3ff 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -2055,6 +2055,7 @@ def get_profile_tab(request, profile, tab, prev_context): active_bounties = active_bounties.order_by('-web3_created') context['active_bounties_count'] = active_bounties.count() context['portfolio_count'] = len(context['portfolio']) + profile.portfolio_items.count() + context['my_kudos'] = profile.get_my_kudos.order_by('-id')[0:5] # specific tabs if tab == 'activity': diff --git a/app/retail/templates/home/nav.html b/app/retail/templates/home/nav.html index 6b8b6be7902..0100065608f 100644 --- a/app/retail/templates/home/nav.html +++ b/app/retail/templates/home/nav.html @@ -73,6 +73,12 @@ {% trans "Results" %} + + {% trans "Leaderboard" %} + + + {% trans "Activity Feed" %} +
    @@ -92,7 +98,7 @@ {% trans "Blog" %} - {% trans "No Token" %} + {% trans "No Utility Token ICO" %} {% trans "Jobs" %} diff --git a/app/retail/views.py b/app/retail/views.py index 80a1b2f9185..1b848ac8668 100644 --- a/app/retail/views.py +++ b/app/retail/views.py @@ -1080,7 +1080,7 @@ def results(request, keyword=None): def activity(request): """Render the Activity response.""" page_size = 15 - activities = Activity.objects.all().order_by('-created') + activities = Activity.objects.all().order_by('-created_on') p = Paginator(activities, page_size) page = int(request.GET.get('page', 1)) From f58649097e377ed6baef680ecdccdb5d346f92ea Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 17 Sep 2019 16:46:35 -0600 Subject: [PATCH 099/131] kudos display --- app/assets/v2/css/profile.css | 9 +++++++++ app/dashboard/templates/profiles/header_details.html | 10 +--------- app/dashboard/templates/profiles/profile.html | 10 +++++++++- app/dashboard/views.py | 2 +- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/app/assets/v2/css/profile.css b/app/assets/v2/css/profile.css index 852f68b0cea..6a26542ff1d 100644 --- a/app/assets/v2/css/profile.css +++ b/app/assets/v2/css/profile.css @@ -109,8 +109,17 @@ box-shadow: 0 -2px 4px 0 rgba(0,0,0,0.50); } +#kudos_header { + position: absolute; + top: -95px; + right: 0px; + background-color: rgba(255, 255, 255, 0.2); + border-radius: 5px; + padding: 5px; +} #kudos_header img{ box-shadow: none; + background: none; } .avatar_edit { diff --git a/app/dashboard/templates/profiles/header_details.html b/app/dashboard/templates/profiles/header_details.html index f50364d941a..8e67ee60ab1 100644 --- a/app/dashboard/templates/profiles/header_details.html +++ b/app/dashboard/templates/profiles/header_details.html @@ -1,4 +1,4 @@ -{% load i18n static avatar_tags add_url_schema email_obfuscator kudos_extras %} +{% load i18n static avatar_tags add_url_schema email_obfuscator %}

    {{ profile.name }} @@ -70,12 +70,4 @@

    {{ profile.job_status_verbose }}

    {% endif %} -{% if total_kudos_count %} -
    - {% for kudos_group in my_kudos %} - - {% endfor %} - ({{ total_kudos_count }} {% trans "kudo" %}{{total_kudos_count | pluralize}}) -
    -{% endif %}
    \ No newline at end of file diff --git a/app/dashboard/templates/profiles/profile.html b/app/dashboard/templates/profiles/profile.html index d21f7a411f4..256b0ea62b7 100644 --- a/app/dashboard/templates/profiles/profile.html +++ b/app/dashboard/templates/profiles/profile.html @@ -1,4 +1,4 @@ -{% load i18n humanize static avatar_tags %} +{% load i18n humanize static avatar_tags kudos_extras %} @@ -46,6 +46,14 @@
    + {% if total_kudos_count %} +
    + {% for kudos_group in my_kudos %} + + {% endfor %} +
    + {% endif %} +
    {% if not hidden %} {% include 'profiles/header_avatar.html' %} diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 4b081f7e3ff..2aaefe4c1ff 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -2055,7 +2055,7 @@ def get_profile_tab(request, profile, tab, prev_context): active_bounties = active_bounties.order_by('-web3_created') context['active_bounties_count'] = active_bounties.count() context['portfolio_count'] = len(context['portfolio']) + profile.portfolio_items.count() - context['my_kudos'] = profile.get_my_kudos.order_by('-id')[0:5] + context['my_kudos'] = profile.get_my_kudos.order_by('-id')[0:7] # specific tabs if tab == 'activity': From 449b9a31f1c7f1f0b5a3e97c740540dd25190d3a Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 17 Sep 2019 16:50:17 -0600 Subject: [PATCH 100/131] kudos on profile --- app/dashboard/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 2aaefe4c1ff..3d80bec0734 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -2055,7 +2055,7 @@ def get_profile_tab(request, profile, tab, prev_context): active_bounties = active_bounties.order_by('-web3_created') context['active_bounties_count'] = active_bounties.count() context['portfolio_count'] = len(context['portfolio']) + profile.portfolio_items.count() - context['my_kudos'] = profile.get_my_kudos.order_by('-id')[0:7] + context['my_kudos'] = profile.get_my_kudos.distinct('kudos_token_cloned_from__name')[0:7] # specific tabs if tab == 'activity': From 3c90e534db259a8af92a1287b024d5dd9c1310e5 Mon Sep 17 00:00:00 2001 From: Owocki Date: Tue, 17 Sep 2019 16:53:11 -0600 Subject: [PATCH 101/131] linter --- app/assets/v2/css/profile.css | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app/assets/v2/css/profile.css b/app/assets/v2/css/profile.css index 6a26542ff1d..0ca81f4ed7b 100644 --- a/app/assets/v2/css/profile.css +++ b/app/assets/v2/css/profile.css @@ -109,19 +109,6 @@ box-shadow: 0 -2px 4px 0 rgba(0,0,0,0.50); } -#kudos_header { - position: absolute; - top: -95px; - right: 0px; - background-color: rgba(255, 255, 255, 0.2); - border-radius: 5px; - padding: 5px; -} -#kudos_header img{ - box-shadow: none; - background: none; -} - .avatar_edit { text-align: center; background: #000; @@ -416,6 +403,19 @@ transform: scale(1.1); } +#kudos_header { + position: absolute; + top: -95px; + right: 0px; + background-color: rgba(255, 255, 255, 0.2); + border-radius: 5px; + padding: 5px; +} +#kudos_header img{ + box-shadow: none; + background: none; +} + .no-profile-button { background-color: #3E00FF; color: #FFFFFF; From f23414ca84eb82449ee365c2c6b2792664219ee8 Mon Sep 17 00:00:00 2001 From: Owocki Date: Wed, 18 Sep 2019 13:43:53 -0600 Subject: [PATCH 102/131] graphs --- app/app/context.py | 7 ++- app/app/urls.py | 4 +- app/assets/v2/js/pages/profile.js | 6 +- app/dashboard/admin.py | 14 +++-- .../management/commands/create_earnings.py | 4 +- .../management/commands/migrate_profiles.py | 15 +++-- .../{REPgraph.html => earningsgraph.html} | 11 ++-- .../templates/profiles/tab_activity.html | 10 +--- .../templates/profiles/tab_earnings.html | 14 +++++ .../templates/profiles/tab_spent.html | 2 +- .../templates/profiles/tab_viewers.html | 4 ++ app/dashboard/templates/profiles/tabs.html | 6 +- app/dashboard/views.py | 60 ++++++++++++++++--- 13 files changed, 115 insertions(+), 42 deletions(-) rename app/dashboard/templates/profiles/{REPgraph.html => earningsgraph.html} (68%) diff --git a/app/app/context.py b/app/app/context.py index a943ce458a3..dea35277778 100644 --- a/app/app/context.py +++ b/app/app/context.py @@ -21,6 +21,7 @@ from django.conf import settings from django.utils import timezone +import logging from app.utils import get_location_from_ip from dashboard.models import Activity, Tip, UserAction @@ -31,6 +32,7 @@ RECORD_VISIT_EVERY_N_SECONDS = 60 * 60 +logger = logging.getLogger(__name__) def preprocess(request): """Handle inserting pertinent data into the current context.""" @@ -61,7 +63,10 @@ def preprocess(request): if record_visit: ip_address = get_ip(request) profile.last_visit = timezone.now() - profile.save() + try: + profile.save() + except Exception as e: + logger.exception(e) metadata = {'useragent': request.META['HTTP_USER_AGENT'], } UserAction.objects.create( user=request.user, diff --git a/app/app/urls.py b/app/app/urls.py index e9e4daa3d08..492fe5bae6f 100644 --- a/app/app/urls.py +++ b/app/app/urls.py @@ -95,7 +95,9 @@ # api views url(r'^api/v0.1/profile/(.*)?/keywords', dashboard.views.profile_keywords, name='profile_keywords'), url(r'^api/v0.1/profile/(.*)?/activity.json', dashboard.views.profile_activity, name='profile_activity'), - url(r'^api/v0.1/profile/(.*)?/rep.csv', dashboard.views.profile_rep, name='profile_rep'), + url(r'^api/v0.1/profile/(.*)?/earnings.csv', dashboard.views.profile_earnings, name='profile_earnings'), + url(r'^api/v0.1/profile/(.*)?/viewers.csv', dashboard.views.profile_viewers, name='profile_viewers'), + url(r'^api/v0.1/profile/(.*)?/spent.csv', dashboard.views.profile_spent, name='profile_spent'), url(r'^api/v0.1/profile/banner', dashboard.views.change_user_profile_banner, name='change_user_profile_banner'), url(r'^api/v0.1/activity', retail.views.create_status_update, name='create_status_update'), url( diff --git a/app/assets/v2/js/pages/profile.js b/app/assets/v2/js/pages/profile.js index 5456962c9b0..9174db552eb 100644 --- a/app/assets/v2/js/pages/profile.js +++ b/app/assets/v2/js/pages/profile.js @@ -101,7 +101,7 @@ $(document).ready(function() { $('.tooltip').bootstrapTooltip(); // rep graph - if ($('#rep_dataviz').length) { + if ($('#earn_dataviz').length) { // Set the dimensions of the canvas / graph const margin = {top: 30, right: 30, bottom: 30, left: 70}; const width = $('.container.position-relative').width() - margin.left - margin.right; @@ -131,7 +131,7 @@ $(document).ready(function() { }); // Adds the svg canvas - var svg = d3.select('#rep_dataviz') + var svg = d3.select('#earn_dataviz') .append('svg') .attr('width', width + margin.left + margin.right) .attr('height', height + margin.top + margin.bottom) @@ -140,7 +140,7 @@ $(document).ready(function() { 'translate(' + margin.left + ',' + margin.top + ')'); // Get the data - d3.csv(document.rep_url, function(error, data) { + d3.csv(document.graph_url, function(error, data) { data.forEach(function(d) { d.date = parseDate(d.date); d.close = +d.close; diff --git a/app/dashboard/admin.py b/app/dashboard/admin.py index 2cdd806aa9a..f9407ff1724 100644 --- a/app/dashboard/admin.py +++ b/app/dashboard/admin.py @@ -42,7 +42,13 @@ class GeneralAdmin(admin.ModelAdmin): list_display = ['created_on', '__str__'] -class REPEntryAdmin(admin.ModelAdmin): +class ProfileViewAdmin(admin.ModelAdmin): + ordering = ['-id'] + raw_id_fields = ['target', 'viewer'] + list_display = ['created_on', '__str__'] + + +class PortfolioItemAdmin(admin.ModelAdmin): ordering = ['-id'] list_display = ['created_on', '__str__'] raw_id_fields = ['profile'] @@ -340,10 +346,10 @@ def link(self, instance): admin.site.register(SearchHistory, SearchHistoryAdmin) admin.site.register(Activity, ActivityAdmin) admin.site.register(Earning, EarningAdmin) -admin.site.register(REPEntry, REPEntryAdmin) +admin.site.register(REPEntry, GeneralAdmin) admin.site.register(BlockedUser, GeneralAdmin) -admin.site.register(PortfolioItem, GeneralAdmin) -admin.site.register(ProfileView, GeneralAdmin) +admin.site.register(PortfolioItem, PortfolioItemAdmin) +admin.site.register(ProfileView, ProfileViewAdmin) admin.site.register(UserAction, UserActionAdmin) admin.site.register(Interest, InterestAdmin) admin.site.register(Profile, ProfileAdmin) diff --git a/app/dashboard/management/commands/create_earnings.py b/app/dashboard/management/commands/create_earnings.py index 3154f3de5f5..f68c0d1266f 100644 --- a/app/dashboard/management/commands/create_earnings.py +++ b/app/dashboard/management/commands/create_earnings.py @@ -19,7 +19,7 @@ from django.core.management.base import BaseCommand from django.utils import timezone -from dashboard.models import BountyFulfillment, Tip +from dashboard.models import BountyFulfillment, Tip, Profile from grants.models import Contribution from kudos.models import KudosTransfer @@ -37,3 +37,5 @@ def handle(self, *args, **options): obj.save() for obj in KudosTransfer.objects.all(): obj.save() + for obj in Profile.objects.all(): + obj.save() diff --git a/app/dashboard/management/commands/migrate_profiles.py b/app/dashboard/management/commands/migrate_profiles.py index 2b20c922e43..36160825279 100644 --- a/app/dashboard/management/commands/migrate_profiles.py +++ b/app/dashboard/management/commands/migrate_profiles.py @@ -28,7 +28,10 @@ class Command(BaseCommand): def handle(self, *args, **options): - # four + # one + management.call_command('create_rep_records') + + # two from dashboard.helpers import record_bounty_activity from dashboard.models import Bounty bounties = Bounty.objects.current().filter(web3_created__lt=timezone.datetime(2019,3,5)).filter(network='mainnet') @@ -42,6 +45,7 @@ def handle(self, *args, **options): print(e) + # three from dashboard.models import Tip from dashboard.tip_views import record_tip_activity for tip in Tip.objects.filter(network='mainnet').filter(created_on__lt=timezone.datetime(2019,3,5)): @@ -50,14 +54,13 @@ def handle(self, *args, **options): print(tip.pk) except Exception as e: print(e) + # three + management.call_command('create_earnings') - # one - management.call_command('create_rep_records') - # two + # four + from dashboard.models import Profile for instance in Profile.objects.filter(hide_profile=False): instance.calculate_all() instance.save() - # three - management.call_command('create_earnings') diff --git a/app/dashboard/templates/profiles/REPgraph.html b/app/dashboard/templates/profiles/earningsgraph.html similarity index 68% rename from app/dashboard/templates/profiles/REPgraph.html rename to app/dashboard/templates/profiles/earningsgraph.html index 9ef94816ad9..2f72e3f7c37 100644 --- a/app/dashboard/templates/profiles/REPgraph.html +++ b/app/dashboard/templates/profiles/earningsgraph.html @@ -3,14 +3,14 @@ - -
    - - - \ No newline at end of file From 41c550a8ab7e30b1ad6777c630f6997438e87501 Mon Sep 17 00:00:00 2001 From: Owocki Date: Sat, 21 Sep 2019 20:23:07 -0600 Subject: [PATCH 130/131] make fix --- app/assets/v2/js/status.js | 3 ++- app/dashboard/management/commands/migrate_profiles.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/v2/js/status.js b/app/assets/v2/js/status.js index 04b45bd60b4..859c8d27368 100644 --- a/app/assets/v2/js/status.js +++ b/app/assets/v2/js/status.js @@ -41,8 +41,9 @@ $(document).ready(function() { 'success' ); const activityContainer = document.querySelector('.tab-section.active .activities'); + activityContainer.setAttribute('page', 0); - $(".tab-section.active .activities").html(''); + $('.tab-section.active .activities').html(''); message.val(''); } else { _alert( diff --git a/app/dashboard/management/commands/migrate_profiles.py b/app/dashboard/management/commands/migrate_profiles.py index 21067cc2cfd..3c8ea7e398a 100644 --- a/app/dashboard/management/commands/migrate_profiles.py +++ b/app/dashboard/management/commands/migrate_profiles.py @@ -19,6 +19,7 @@ from django.core import management from django.core.management.base import BaseCommand from django.utils import timezone + from dashboard.helpers import record_bounty_activity from dashboard.models import Bounty From 74b993e3493f39d464aeca6f814cf4c1cf1d8e7b Mon Sep 17 00:00:00 2001 From: Owocki Date: Sun, 22 Sep 2019 06:34:00 -0600 Subject: [PATCH 131/131] make fix --- app/dashboard/management/commands/migrate_profiles.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/dashboard/management/commands/migrate_profiles.py b/app/dashboard/management/commands/migrate_profiles.py index 3c8ea7e398a..33904911b60 100644 --- a/app/dashboard/management/commands/migrate_profiles.py +++ b/app/dashboard/management/commands/migrate_profiles.py @@ -21,7 +21,8 @@ from django.utils import timezone from dashboard.helpers import record_bounty_activity -from dashboard.models import Bounty +from dashboard.models import Bounty, Profile, Tip +from dashboard.tip_views import record_tip_activity class Command(BaseCommand): @@ -42,8 +43,6 @@ def handle(self, *args, **options): print(e) - from dashboard.models import Tip - from dashboard.tip_views import record_tip_activity for tip in Tip.objects.filter(network='mainnet').filter(created_on__lt=timezone.datetime(2019,3,5)): try: record_tip_activity(tip, tip.username, 'new_tip', override_created=tip.created_on) @@ -52,7 +51,6 @@ def handle(self, *args, **options): print(e) - from dashboard.models import Profile for instance in Profile.objects.filter(hide_profile=False): instance.calculate_all() instance.save()