From 1497d90f6dead6196cefd382dde54118ddb0c01d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Thu, 21 May 2020 22:27:53 +0800 Subject: [PATCH 01/20] Initialize setting review / proposal stage page --- src/locale/zh_Hant/LC_MESSAGES/django.po | 6 ++ src/static/css/components/_texts.scss | 4 + src/static/css/components/_toggle.scss | 44 +++++++++++ src/static/css/main.scss | 1 + .../default/_includes/dashboard_tablist.html | 6 ++ .../default/reviews/review_change.html | 76 +++++++++++++++++++ src/users/models.py | 3 + src/users/urls.py | 1 + src/users/views.py | 2 + 9 files changed, 143 insertions(+) create mode 100644 src/static/css/components/_toggle.scss create mode 100644 src/templates/default/reviews/review_change.html diff --git a/src/locale/zh_Hant/LC_MESSAGES/django.po b/src/locale/zh_Hant/LC_MESSAGES/django.po index 39074d48b..50357c151 100644 --- a/src/locale/zh_Hant/LC_MESSAGES/django.po +++ b/src/locale/zh_Hant/LC_MESSAGES/django.po @@ -1298,6 +1298,12 @@ msgstr "更改密碼" msgid "Reviews" msgstr "審查" +#: templates/default/_includes/dashboard_tablist.html:28 +#: templates/default/reviews/review_change.html:12 +#: templates/default/reviews/review_change.html:18 +msgid "Change Review" +msgstr "更改審查設定" + #: templates/default/_includes/nav/dashboard_nav.html:10 msgid "Log out" msgstr "登出" diff --git a/src/static/css/components/_texts.scss b/src/static/css/components/_texts.scss index 659429f2c..e67e71acd 100644 --- a/src/static/css/components/_texts.scss +++ b/src/static/css/components/_texts.scss @@ -8,3 +8,7 @@ .text-emphasize { @include roboto-medium(); } + +.input-customized-size input{ + width: 16.2em; +} \ No newline at end of file diff --git a/src/static/css/components/_toggle.scss b/src/static/css/components/_toggle.scss new file mode 100644 index 000000000..914de8201 --- /dev/null +++ b/src/static/css/components/_toggle.scss @@ -0,0 +1,44 @@ +.material-switch > input[type="checkbox"] { + display: none; +} + +.material-switch > label { + cursor: pointer; + height: 0px; + position: relative; + width: 40px; +} + +.material-switch > label::before { + background: rgb(0, 0, 0); + box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.5); + border-radius: 8px; + content: ''; + height: 16px; + margin-top: -8px; + position:absolute; + opacity: 0.3; + transition: all 0.4s ease-in-out; + width: 40px; +} +.material-switch > label::after { + background: rgb(255, 255, 255); + border-radius: 16px; + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); + content: ''; + height: 24px; + left: -4px; + margin-top: -8px; + position: absolute; + top: -4px; + transition: all 0.3s ease-in-out; + width: 24px; +} +.material-switch > input[type="checkbox"]:checked + label::before { + background: inherit; + opacity: 0.5; +} +.material-switch > input[type="checkbox"]:checked + label::after { + background: inherit; + left: 20px; +} \ No newline at end of file diff --git a/src/static/css/main.scss b/src/static/css/main.scss index 565e2116f..58ee72545 100644 --- a/src/static/css/main.scss +++ b/src/static/css/main.scss @@ -20,6 +20,7 @@ @import "components/tables"; @import "components/texts"; @import "components/lists"; +@import "components/toggle"; // Pages @import "pages/proposals"; diff --git a/src/templates/default/_includes/dashboard_tablist.html b/src/templates/default/_includes/dashboard_tablist.html index 05154e393..a9f0ccb5a 100644 --- a/src/templates/default/_includes/dashboard_tablist.html +++ b/src/templates/default/_includes/dashboard_tablist.html @@ -22,4 +22,10 @@ {% endif %} {% endif %} + + {% if user.is_admin %} +
  • + {% trans 'Change Review' %} +
  • + {% endif %} diff --git a/src/templates/default/reviews/review_change.html b/src/templates/default/reviews/review_change.html new file mode 100644 index 000000000..9c5b67bee --- /dev/null +++ b/src/templates/default/reviews/review_change.html @@ -0,0 +1,76 @@ +{% extends 'dashboard_base.html' %} + +{% load i18n crispy_forms_tags %} + +{% block dashboard_tablist %} +{% include '_includes/dashboard_tablist.html' with active='admin' %} +{% endblock dashboard_tablist %} + +{% block main-content %} + +

    + {% trans 'Change Review' %} +

    + +
    +
    +
    +
    {% trans 'Change Review' %}
    +
      +
    • + pycontw-2020.proposals.creatable +
      + + +
      +
    • +
    • + pycontw-2020.proposals.editable +
      + + +
      +
    • +
    • + pycontw-2020.proposals.withdrawable +
      + + +
      +
    • +
    • + pycontw-2020.reviews.visible.to.submitters +
      + + +
      +
    • +
    • + pycontw-2020.reviews.stage +
      + +
      +
    • +
    • + pycontw-2020.proposals.disable.after +
      + +
      +
    • +
    +
    + +
    + {% csrf_token %} +
    + {{ form|crispy }} + +
    +
    +
    + + +{% endblock main-content %} diff --git a/src/users/models.py b/src/users/models.py index b9a094dc9..7b697175f 100644 --- a/src/users/models.py +++ b/src/users/models.py @@ -246,6 +246,9 @@ def is_valid_speaker(self): def is_reviewer(self): return self.has_perm('reviews.add_review') + def is_admin(self): + return self.is_superuser + @property def cospeaking_info_set(self): return self.additionalspeaker_set.filter( diff --git a/src/users/urls.py b/src/users/urls.py index 56d28c523..000154ed8 100644 --- a/src/users/urls.py +++ b/src/users/urls.py @@ -32,5 +32,6 @@ url(r'^agreement/$', views.coc_agree, name='coc_agreement'), + url(r'^review-change/$', views.review_change, name='review_change'), ] diff --git a/src/users/views.py b/src/users/views.py index 1d4993d0d..7a9fe6407 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -195,6 +195,8 @@ def get_context_data(self, **kwargs): context.update(**reviews_state()._asdict()) return context +def review_change(request): + return render(request, 'reviews/review_change.html') login = auth_views.LoginView.as_view(authentication_form=AuthenticationForm) logout = auth_views.LogoutView.as_view() From f3095e6b1f876ca3a866299a0e9df82958dc45c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Sat, 18 Jul 2020 16:30:40 +0800 Subject: [PATCH 02/20] Alice fixup with love --- src/proposals/templatetags/proposals.py | 7 +- src/static/css/components/_buttons.scss | 17 ++ src/static/css/components/_texts.scss | 3 +- src/static/css/components/_toggle.scss | 3 + .../css/vendors/bootstrap/_buttons.scss | 3 +- src/static/js/reviews/review_change.js | 74 ++++++++ .../default/_includes/dashboard_tablist.html | 2 +- .../default/reviews/review_change.html | 166 ++++++++++++------ src/users/models.py | 3 - src/users/views.py | 25 +++ 10 files changed, 238 insertions(+), 65 deletions(-) create mode 100644 src/static/js/reviews/review_change.js diff --git a/src/proposals/templatetags/proposals.py b/src/proposals/templatetags/proposals.py index fd4472b44..66d75d0f9 100644 --- a/src/proposals/templatetags/proposals.py +++ b/src/proposals/templatetags/proposals.py @@ -1,5 +1,5 @@ from django.template import Library - +from django.conf import settings from proposals.utils import SEP_DEFAULT, SEP_LAST, format_names @@ -11,3 +11,8 @@ def speaker_names_display( proposal, sep_default=SEP_DEFAULT, sep_last=SEP_LAST): names = [info.user.speaker_name for info in proposal.speakers] return format_names(names, sep_default=sep_default, sep_last=sep_last) + + +@register.filter +def configuration_switch(value): + return settings.CONFERENCE_DEFAULT_SLUG + value \ No newline at end of file diff --git a/src/static/css/components/_buttons.scss b/src/static/css/components/_buttons.scss index 0dda38643..3201b9d69 100644 --- a/src/static/css/components/_buttons.scss +++ b/src/static/css/components/_buttons.scss @@ -10,6 +10,10 @@ @include button-variant($btn-natural-color, $btn-natural-bg, $btn-natural-border); } +.btn-natural-noborder { + @include button-variant($btn-natural-color, $btn-natural-bg, $btn-natural-border); +} + .btn-action{ @include button-variant($btn-action-color, $btn-action-bg, $btn-action-border); } @@ -40,6 +44,19 @@ } } +.btn-natural-noborder { + &:hover { + background-color: $btn-natural-hover-bg; + } + &, + &:focus, + &:active { + outline: none; + border-color: transparent; + } + margin-bottom: 20px; +} + .btn-natural.btn-withdraw { &, &:hover, diff --git a/src/static/css/components/_texts.scss b/src/static/css/components/_texts.scss index e67e71acd..cf494cfb1 100644 --- a/src/static/css/components/_texts.scss +++ b/src/static/css/components/_texts.scss @@ -11,4 +11,5 @@ .input-customized-size input{ width: 16.2em; -} \ No newline at end of file +} + diff --git a/src/static/css/components/_toggle.scss b/src/static/css/components/_toggle.scss index 914de8201..f5d121e78 100644 --- a/src/static/css/components/_toggle.scss +++ b/src/static/css/components/_toggle.scss @@ -21,6 +21,7 @@ transition: all 0.4s ease-in-out; width: 40px; } + .material-switch > label::after { background: rgb(255, 255, 255); border-radius: 16px; @@ -34,10 +35,12 @@ transition: all 0.3s ease-in-out; width: 24px; } + .material-switch > input[type="checkbox"]:checked + label::before { background: inherit; opacity: 0.5; } + .material-switch > input[type="checkbox"]:checked + label::after { background: inherit; left: 20px; diff --git a/src/static/css/vendors/bootstrap/_buttons.scss b/src/static/css/vendors/bootstrap/_buttons.scss index 6452b709f..da8828aba 100755 --- a/src/static/css/vendors/bootstrap/_buttons.scss +++ b/src/static/css/vendors/bootstrap/_buttons.scss @@ -110,6 +110,7 @@ a.btn { &:hover, &:focus, &:active { + outline: none; border-color: transparent; } &:hover, @@ -128,7 +129,6 @@ a.btn { } } - // Button Sizes // -------------------------------------------------- @@ -166,3 +166,4 @@ input[type="button"] { width: 100%; } } + diff --git a/src/static/js/reviews/review_change.js b/src/static/js/reviews/review_change.js new file mode 100644 index 000000000..e77fe4b27 --- /dev/null +++ b/src/static/js/reviews/review_change.js @@ -0,0 +1,74 @@ + +var proposals_creatable = document.getElementById("proposals.creatable"); +var proposals_editable = document.getElementById("proposals.editable"); +var proposals_withdrawable = document.getElementById("proposals.withdrawable"); +var reviews_stage = document.getElementById("reviews.stage"); +var reviews_visible_to_submitters = document.getElementById("reviews.visible.to.submitters"); + +$('.hotkey').click(function () { + if ($(this).val() == "Call for Proposals") { + Call_for_Proposals(); + } + else if ($(this).val() == "First Round Review") { + First_Round_Review() + } + else if ($(this).val() == "Modification Stage") { + Modification_Stage() + } + else if ($(this).val() == "Second Round Review") { + Second_Round_Review() + } + else if ($(this).val() == "Internal Decision") { + Internal_Decision() + } + else { + Announcement_of_Acceptance() + } + + /* + Proposal Review Stage Setting + Reference : https://github.com/pycontw/pycon.tw/blob/master/src/reviews/README.md + */ + function Call_for_Proposals(){ + proposals_creatable.checked = true; + proposals_editable.checked = true; + proposals_withdrawable.checked = true; + reviews_stage.value = "0"; + reviews_visible_to_submitters.checked = false; + } + function First_Round_Review() { + proposals_creatable.checked = false; + proposals_editable.checked = false; + proposals_withdrawable.checked = false; + reviews_stage.value = "0"; + reviews_visible_to_submitters.checked = false; + } + function Modification_Stage() { + proposals_creatable.checked = false; + proposals_editable.checked = true; + proposals_withdrawable.checked = false; + reviews_stage.value = "0"; + reviews_visible_to_submitters.checked = true; + } + function Second_Round_Review() { + proposals_creatable.checked = false; + proposals_editable.checked = false; + proposals_withdrawable.checked = false; + reviews_stage.value = "2"; + reviews_visible_to_submitters.checked = false; + } + function Internal_Decision() { + proposals_creatable.checked = false; + proposals_editable.checked = false; + proposals_withdrawable.checked = false; + reviews_stage.value = "0"; + reviews_visible_to_submitters.checked = false; + } + function Announcement_of_Acceptance() { + proposals_creatable.checked = false; + proposals_editable.checked = true; + proposals_withdrawable.checked = false; + reviews_stage.value = "0"; + reviews_visible_to_submitters.checked = true; + } +}); \ No newline at end of file diff --git a/src/templates/default/_includes/dashboard_tablist.html b/src/templates/default/_includes/dashboard_tablist.html index a9f0ccb5a..a15e9afe7 100644 --- a/src/templates/default/_includes/dashboard_tablist.html +++ b/src/templates/default/_includes/dashboard_tablist.html @@ -23,7 +23,7 @@ {% endif %} - {% if user.is_admin %} + {% if user.is_superuser %}
  • {% trans 'Change Review' %}
  • diff --git a/src/templates/default/reviews/review_change.html b/src/templates/default/reviews/review_change.html index 9c5b67bee..bdbd4fa74 100644 --- a/src/templates/default/reviews/review_change.html +++ b/src/templates/default/reviews/review_change.html @@ -1,6 +1,8 @@ {% extends 'dashboard_base.html' %} -{% load i18n crispy_forms_tags %} +{% load i18n static %} +{% load proposals %} +{% load compress crispy_forms_tags %} {% block dashboard_tablist %} {% include '_includes/dashboard_tablist.html' with active='admin' %} @@ -12,65 +14,113 @@

    {% trans 'Change Review' %}

    -
    -
    -
    -
    {% trans 'Change Review' %}
    -
      -
    • - pycontw-2020.proposals.creatable -
      - - -
      -
    • -
    • - pycontw-2020.proposals.editable -
      - - -
      -
    • -
    • - pycontw-2020.proposals.withdrawable -
      - - -
      -
    • -
    • - pycontw-2020.reviews.visible.to.submitters -
      - - -
      -
    • -
    • - pycontw-2020.reviews.stage -
      - -
      -
    • -
    • - pycontw-2020.proposals.disable.after -
      - -
      -
    • -
    -
    +
    + +
    + + + + + + +
    + +
    +
    + {% csrf_token %} +
    +
    {% trans 'Change Review' %}
    +
      +
    • + {{ ".proposals.creatable"|configuration_switch }} +
      + + + +
      +
    • +
    • + {{ ".proposals.editable"|configuration_switch }} +
      + + + +
      +
    • +
    • + {{ ".proposals.withdrawable"|configuration_switch }} +
      + + + +
      +
    • +
    • + {{ ".reviews.visible.to.submitters"|configuration_switch }} +
      + + + +
      +
    • +
    • + {{ ".reviews.stage"|configuration_switch }} +
      + +
      +
    • +
    • + {{ ".proposals.disable.after"|configuration_switch }} +
      + +
      +
    • +
    • + timezone (non-required) +
      + +
      +
    • +
    • + comment (non-required) +
      + +
      +
    • +
    +
    - - {% csrf_token %} -
    - {{ form|crispy }} - -
    +
    + {{ form|crispy }} + +
    +
    - {% endblock main-content %} + +{% block extra_js %} + +{% compress js %} + +{% endcompress %} +{% endblock extra_js %} \ No newline at end of file diff --git a/src/users/models.py b/src/users/models.py index 7b697175f..b9a094dc9 100644 --- a/src/users/models.py +++ b/src/users/models.py @@ -246,9 +246,6 @@ def is_valid_speaker(self): def is_reviewer(self): return self.has_perm('reviews.add_review') - def is_admin(self): - return self.is_superuser - @property def cospeaking_info_set(self): return self.additionalspeaker_set.filter( diff --git a/src/users/views.py b/src/users/views.py index 7a9fe6407..d82f541e0 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -20,10 +20,13 @@ ) from .models import CocRecord from reviews.context import proposals_state, reviews_state +from registry.helper import reg from lxml import etree import lxml.html +from pytz import timezone +from datetime import datetime, timedelta User = auth.get_user_model() @@ -196,6 +199,28 @@ def get_context_data(self, **kwargs): return context def review_change(request): + if request.method == 'POST': + + CONFERENCE_DEFAULT_SLUG = settings.CONFERENCE_DEFAULT_SLUG + TIME_ZONE = settings.TIME_ZONE + + fmt = '%Y-%m-%d %H:%M:%S%z' + date_time_obj = datetime.strptime( + request.POST['proposals.disable.after'], '%Y-%m-%dT%H:%M:%S') + loc_dt = timezone(TIME_ZONE).localize(date_time_obj) + messages.info(request, 'Your setting has been changed successfully at ' + str(datetime.now())) + + reg[CONFERENCE_DEFAULT_SLUG + + '.proposals.creatable'] = request.POST['proposals.creatable'] + reg[CONFERENCE_DEFAULT_SLUG + + '.proposals.editable'] = request.POST['proposals.editable'] + reg[CONFERENCE_DEFAULT_SLUG + '.proposals.withdrawable'] = request.POST[ + 'proposals.withdrawable'] + reg[CONFERENCE_DEFAULT_SLUG + '.reviews.visible.to.submitters'] = request.POST[ + 'reviews.visible.to.submitters'] + reg[CONFERENCE_DEFAULT_SLUG + '.reviews.stage'] = int(request.POST['reviews.stage']) + reg[CONFERENCE_DEFAULT_SLUG + '.proposals.disable.after'] = loc_dt + return render(request, 'reviews/review_change.html') login = auth_views.LoginView.as_view(authentication_form=AuthenticationForm) From 57d036c5eff6ee5c280079d7225463a9bd750b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Sun, 27 Sep 2020 14:54:42 +0800 Subject: [PATCH 03/20] Clear gui --- src/templates/default/reviews/review_change.html | 4 ++-- src/users/views.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/templates/default/reviews/review_change.html b/src/templates/default/reviews/review_change.html index bdbd4fa74..31f8e0cd6 100644 --- a/src/templates/default/reviews/review_change.html +++ b/src/templates/default/reviews/review_change.html @@ -91,13 +91,13 @@

  • - timezone (non-required) + timezone (default is UTC +8)(non-required)
  • - comment (non-required) + timezone comment (non-required)
    diff --git a/src/users/views.py b/src/users/views.py index d82f541e0..761df959b 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -208,6 +208,7 @@ def review_change(request): date_time_obj = datetime.strptime( request.POST['proposals.disable.after'], '%Y-%m-%dT%H:%M:%S') loc_dt = timezone(TIME_ZONE).localize(date_time_obj) + print(loc_dt) messages.info(request, 'Your setting has been changed successfully at ' + str(datetime.now())) reg[CONFERENCE_DEFAULT_SLUG + From 2881ea9ada5a7cbcefeb42f30de8cbbd249d592a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Fri, 2 Oct 2020 11:53:46 +0800 Subject: [PATCH 04/20] Default timezone sring handling --- .../default/reviews/review_change.html | 39 ++++++++++++++++++- src/users/views.py | 20 ++++++---- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/templates/default/reviews/review_change.html b/src/templates/default/reviews/review_change.html index 31f8e0cd6..e837f986e 100644 --- a/src/templates/default/reviews/review_change.html +++ b/src/templates/default/reviews/review_change.html @@ -91,9 +91,41 @@

  • - timezone (default is UTC +8)(non-required) + timezone
    - +
  • @@ -115,6 +147,9 @@

    + {% endblock main-content %} {% block extra_js %} diff --git a/src/users/views.py b/src/users/views.py index 761df959b..4ce09183e 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -25,8 +25,8 @@ from lxml import etree import lxml.html -from pytz import timezone -from datetime import datetime, timedelta +import pytz +import datetime User = auth.get_user_model() @@ -199,16 +199,21 @@ def get_context_data(self, **kwargs): return context def review_change(request): + + # Get default TimeZone + tz = pytz.timezone(settings.TIME_ZONE) + now = datetime.datetime.now(tz=tz).isoformat() + default_tz = now[len(now)-6:] + if request.method == 'POST': CONFERENCE_DEFAULT_SLUG = settings.CONFERENCE_DEFAULT_SLUG - TIME_ZONE = settings.TIME_ZONE + print(request.POST['proposals.disable.after']) fmt = '%Y-%m-%d %H:%M:%S%z' - date_time_obj = datetime.strptime( + date_time_obj = datetime.datetime.strptime( request.POST['proposals.disable.after'], '%Y-%m-%dT%H:%M:%S') - loc_dt = timezone(TIME_ZONE).localize(date_time_obj) - print(loc_dt) + loc_dt = datetime.timezone(TIME_ZONE).localize(date_time_obj) messages.info(request, 'Your setting has been changed successfully at ' + str(datetime.now())) reg[CONFERENCE_DEFAULT_SLUG + @@ -222,7 +227,8 @@ def review_change(request): reg[CONFERENCE_DEFAULT_SLUG + '.reviews.stage'] = int(request.POST['reviews.stage']) reg[CONFERENCE_DEFAULT_SLUG + '.proposals.disable.after'] = loc_dt - return render(request, 'reviews/review_change.html') + return render(request, 'reviews/review_change.html',{'default_tz': default_tz}) + login = auth_views.LoginView.as_view(authentication_form=AuthenticationForm) logout = auth_views.LogoutView.as_view() From db4fea727ef44bd3893ad83f52f070e19cdd20b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Sun, 4 Oct 2020 18:04:09 +0800 Subject: [PATCH 05/20] rename to Review Stages --- src/locale/zh_Hant/LC_MESSAGES/django.po | 8 ++--- .../{review_change.js => review_stages.js} | 0 .../default/_includes/dashboard_tablist.html | 2 +- ...{review_change.html => review_stages.html} | 6 ++-- src/users/urls.py | 35 +++++++++---------- src/users/views.py | 4 +-- 6 files changed, 27 insertions(+), 28 deletions(-) rename src/static/js/reviews/{review_change.js => review_stages.js} (100%) rename src/templates/default/reviews/{review_change.html => review_stages.html} (97%) diff --git a/src/locale/zh_Hant/LC_MESSAGES/django.po b/src/locale/zh_Hant/LC_MESSAGES/django.po index 048e44e4c..3573b86a3 100644 --- a/src/locale/zh_Hant/LC_MESSAGES/django.po +++ b/src/locale/zh_Hant/LC_MESSAGES/django.po @@ -1444,10 +1444,10 @@ msgid "Reviews" msgstr "審查" #: templates/default/_includes/dashboard_tablist.html:28 -#: templates/default/reviews/review_change.html:12 -#: templates/default/reviews/review_change.html:18 -msgid "Change Review" -msgstr "更改審查設定" +#: templates/default/reviews/review_stages.html:12 +#: templates/default/reviews/review_stages.html:18 +msgid "Review Stages" +msgstr "審查階段" #: templates/default/_includes/nav/dashboard_nav.html:10 msgid "Log out" diff --git a/src/static/js/reviews/review_change.js b/src/static/js/reviews/review_stages.js similarity index 100% rename from src/static/js/reviews/review_change.js rename to src/static/js/reviews/review_stages.js diff --git a/src/templates/default/_includes/dashboard_tablist.html b/src/templates/default/_includes/dashboard_tablist.html index a15e9afe7..b3c72d496 100644 --- a/src/templates/default/_includes/dashboard_tablist.html +++ b/src/templates/default/_includes/dashboard_tablist.html @@ -25,7 +25,7 @@ {% if user.is_superuser %}
  • - {% trans 'Change Review' %} + {% trans 'Review Stages' %}
  • {% endif %} diff --git a/src/templates/default/reviews/review_change.html b/src/templates/default/reviews/review_stages.html similarity index 97% rename from src/templates/default/reviews/review_change.html rename to src/templates/default/reviews/review_stages.html index e837f986e..01db246ff 100644 --- a/src/templates/default/reviews/review_change.html +++ b/src/templates/default/reviews/review_stages.html @@ -11,7 +11,7 @@ {% block main-content %}

    - {% trans 'Change Review' %} + {% trans 'Review Stages' %}

    @@ -38,7 +38,7 @@

    -
    + {% csrf_token %}
    {% trans 'Change Review' %}
    @@ -156,6 +156,6 @@

    {% compress js %} - + {% endcompress %} {% endblock extra_js %} \ No newline at end of file diff --git a/src/users/urls.py b/src/users/urls.py index 000154ed8..2471ab97c 100644 --- a/src/users/urls.py +++ b/src/users/urls.py @@ -5,33 +5,32 @@ urlpatterns = [ - url(r'^login/$', views.login, name='login'), url(r'^logout/$', views.logout, name='logout'), url(r'^profile/$', views.user_profile_update, name='user_profile_update'), - url(r'^password-change/$', views.password_change, name='password_change'), url(r'^password-change/done/$', - views.password_change_done, name='password_change_done'), - - url(r'^signup/$', - views.user_signup, name='signup'), + views.password_change_done, + name='password_change_done'), + url(r'^signup/$', views.user_signup, name='signup'), url(r'^verify/(?P[-:\w]+)/$', - views.user_verify, name='user_verify'), + views.user_verify, + name='user_verify'), url(r'^verification-request/$', - views.request_verification, name='request_verification'), - + views.request_verification, + name='request_verification'), url(r'^password-reset/$', views.password_reset, name='password_reset'), url(r'^password-reset/done/$', - views.password_reset_done, name='password_reset_done'), - url(r'^password-reset/(?P[0-9A-Za-z_\-]+)/' + views.password_reset_done, + name='password_reset_done'), + url( + r'^password-reset/(?P[0-9A-Za-z_\-]+)/' r'(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', - views.password_reset_confirm, name='password_reset_confirm'), + views.password_reset_confirm, + name='password_reset_confirm'), url(r'^password-reset/complete/$', - views.password_reset_complete, name='password_reset_complete'), - - url(r'^agreement/$', - views.coc_agree, name='coc_agreement'), - url(r'^review-change/$', views.review_change, name='review_change'), - + views.password_reset_complete, + name='password_reset_complete'), + url(r'^agreement/$', views.coc_agree, name='coc_agreement'), + url(r'^review-stages/$', views.review_stages, name='review_stages'), ] diff --git a/src/users/views.py b/src/users/views.py index 4ce09183e..7e8ae2dc1 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -198,7 +198,7 @@ def get_context_data(self, **kwargs): context.update(**reviews_state()._asdict()) return context -def review_change(request): +def review_stages(request): # Get default TimeZone tz = pytz.timezone(settings.TIME_ZONE) @@ -227,7 +227,7 @@ def review_change(request): reg[CONFERENCE_DEFAULT_SLUG + '.reviews.stage'] = int(request.POST['reviews.stage']) reg[CONFERENCE_DEFAULT_SLUG + '.proposals.disable.after'] = loc_dt - return render(request, 'reviews/review_change.html',{'default_tz': default_tz}) + return render(request, 'reviews/review_stages.html',{'default_tz': default_tz}) login = auth_views.LoginView.as_view(authentication_form=AuthenticationForm) From 6ef2f5bae98217c0e625ae323515acc69f2afd10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Tue, 13 Oct 2020 00:05:50 +0800 Subject: [PATCH 06/20] Generating timezone dynamically with pytz --- .../default/reviews/review_stages.html | 12 ++++- src/users/views.py | 49 ++++++++++--------- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/templates/default/reviews/review_stages.html b/src/templates/default/reviews/review_stages.html index 01db246ff..36706e678 100644 --- a/src/templates/default/reviews/review_stages.html +++ b/src/templates/default/reviews/review_stages.html @@ -3,6 +3,8 @@ {% load i18n static %} {% load proposals %} {% load compress crispy_forms_tags %} +{% load tz %} +{% get_current_timezone as TIME_ZONE %} {% block dashboard_tablist %} {% include '_includes/dashboard_tablist.html' with active='admin' %} @@ -93,7 +95,7 @@

  • timezone
    - + + {% for tz in timezones %} + + {% endfor %}
  • timezone comment (non-required)
    - +
  • diff --git a/src/users/views.py b/src/users/views.py index 7e8ae2dc1..71ed0353f 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -200,34 +200,37 @@ def get_context_data(self, **kwargs): def review_stages(request): - # Get default TimeZone - tz = pytz.timezone(settings.TIME_ZONE) - now = datetime.datetime.now(tz=tz).isoformat() - default_tz = now[len(now)-6:] - if request.method == 'POST': - CONFERENCE_DEFAULT_SLUG = settings.CONFERENCE_DEFAULT_SLUG - - print(request.POST['proposals.disable.after']) fmt = '%Y-%m-%d %H:%M:%S%z' + tz_selectd = pytz.timezone(request.POST['review_timezone']) date_time_obj = datetime.datetime.strptime( request.POST['proposals.disable.after'], '%Y-%m-%dT%H:%M:%S') - loc_dt = datetime.timezone(TIME_ZONE).localize(date_time_obj) - messages.info(request, 'Your setting has been changed successfully at ' + str(datetime.now())) - - reg[CONFERENCE_DEFAULT_SLUG + - '.proposals.creatable'] = request.POST['proposals.creatable'] - reg[CONFERENCE_DEFAULT_SLUG + - '.proposals.editable'] = request.POST['proposals.editable'] - reg[CONFERENCE_DEFAULT_SLUG + '.proposals.withdrawable'] = request.POST[ - 'proposals.withdrawable'] - reg[CONFERENCE_DEFAULT_SLUG + '.reviews.visible.to.submitters'] = request.POST[ - 'reviews.visible.to.submitters'] - reg[CONFERENCE_DEFAULT_SLUG + '.reviews.stage'] = int(request.POST['reviews.stage']) - reg[CONFERENCE_DEFAULT_SLUG + '.proposals.disable.after'] = loc_dt - - return render(request, 'reviews/review_stages.html',{'default_tz': default_tz}) + loc_dt = tz_selectd.localize(date_time_obj).strftime(fmt) + + CONFERENCE_DEFAULT_SLUG = settings.CONFERENCE_DEFAULT_SLUG + review_stages_list = [ + 'proposals.creatable', 'proposals.editable', + 'proposals.withdrawable', 'reviews.visible.to.submitters', + 'reviews.stage', 'proposals.disable.after' + ] + + for tag in review_stages_list: + key = CONFERENCE_DEFAULT_SLUG + '.' + tag + if(tag == 'proposals.disable.after'): + value = loc_dt + else: + value = request.POST[tag] + reg[key] = value + print(key) + print(value) + + messages.info( + request, + 'This setting has been changed successfully and the review stage will expire at ' + + str(loc_dt) + ' (' + request.POST.get('review_timezone') + ')') + + return render(request, 'reviews/review_stages.html',{'timezones': pytz.common_timezones}) login = auth_views.LoginView.as_view(authentication_form=AuthenticationForm) From 211bf3c76a50ec1cf497180a2481dfeaafa835fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Tue, 13 Oct 2020 00:11:07 +0800 Subject: [PATCH 07/20] Delete comment in review_stages.html --- .../default/reviews/review_stages.html | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/src/templates/default/reviews/review_stages.html b/src/templates/default/reviews/review_stages.html index 36706e678..b3fde5a20 100644 --- a/src/templates/default/reviews/review_stages.html +++ b/src/templates/default/reviews/review_stages.html @@ -95,41 +95,7 @@

  • timezone
    -
  • -
  • - timezone comment (non-required) -
    - -
    -
  • @@ -121,14 +105,9 @@

    - {% endblock main-content %} {% block extra_js %} - {% compress js %} {% endcompress %} diff --git a/src/users/views.py b/src/users/views.py index dbb6ecfd4..674a4c5c9 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -199,6 +199,13 @@ def get_context_data(self, **kwargs): return context def review_stages(request): + + review_stages_list = [ + 'Call for Proposals', 'First Round Review_1', + 'First Round Review_2', 'Modification Stage', + 'Second Round Review', 'Internal Decision', + 'Announcement of Acceptance' + ] if request.method == 'POST': @@ -209,26 +216,32 @@ def review_stages(request): loc_dt = tz_selectd.localize(date_time_obj).strftime(fmt) CONFERENCE_DEFAULT_SLUG = settings.CONFERENCE_DEFAULT_SLUG - review_stages_list = [ + review_stages_var = [ 'proposals.creatable', 'proposals.editable', 'proposals.withdrawable', 'reviews.visible.to.submitters', 'reviews.stage', 'proposals.disable.after' ] - for tag in review_stages_list: + for tag in review_stages_var: key = CONFERENCE_DEFAULT_SLUG + '.' + tag if(tag == 'proposals.disable.after'): value = loc_dt + elif(tag == 'reviews.stage'): + value = int(request.POST[tag]) else: value = request.POST[tag] reg[key] = value - + messages.info( request, 'This setting has been changed successfully and the review stage will expire at ' + str(loc_dt) + ' (' + request.POST.get('review_timezone') + ')') - return render(request, 'reviews/review_stages.html',{'timezones': pytz.common_timezones}) + return render( + request, 'reviews/review_stages.html', { + 'timezones': pytz.common_timezones, + 'review_stages_list': review_stages_list + }) login = auth_views.LoginView.as_view(authentication_form=AuthenticationForm) From 8ade9c1db8f33d111ac3560be6a68d19f93bb86f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Tue, 27 Oct 2020 00:29:00 +0800 Subject: [PATCH 10/20] return value add reviews_state() --- src/users/views.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/users/views.py b/src/users/views.py index 674a4c5c9..6e3f9216b 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -199,10 +199,10 @@ def get_context_data(self, **kwargs): return context def review_stages(request): - + review_stages_list = [ 'Call for Proposals', 'First Round Review_1', - 'First Round Review_2', 'Modification Stage', + 'First Round Review', 'Modification Stage', 'Second Round Review', 'Internal Decision', 'Announcement of Acceptance' ] @@ -240,7 +240,8 @@ def review_stages(request): return render( request, 'reviews/review_stages.html', { 'timezones': pytz.common_timezones, - 'review_stages_list': review_stages_list + 'review_stages_list': review_stages_list, + **reviews_state()._asdict() }) From cfb5fa1a535c0dc1a99f073f62a64107334bb22c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Tue, 27 Oct 2020 00:35:29 +0800 Subject: [PATCH 11/20] Rename First Round Review_2 to First Round Review --- src/static/js/reviews/review_stages.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/static/js/reviews/review_stages.js b/src/static/js/reviews/review_stages.js index 3727e7da6..9917816b1 100644 --- a/src/static/js/reviews/review_stages.js +++ b/src/static/js/reviews/review_stages.js @@ -12,8 +12,8 @@ $('.hotkey').click(function () { else if ($(this).val() == "First Round Review_1") { First_Round_Review_1() } - else if ($(this).val() == "First Round Review_2") { - First_Round_Review_2() + else if ($(this).val() == "First Round Review") { + First_Round_Review() } else if ($(this).val() == "Modification Stage") { Modification_Stage() @@ -46,7 +46,7 @@ $('.hotkey').click(function () { reviews_stage.value = "0"; reviews_visible_to_submitters.checked = false; } - function First_Round_Review_2() { + function First_Round_Review() { proposals_creatable.checked = false; proposals_editable.checked = false; proposals_withdrawable.checked = false; From afaf6d5af4c52c1f03a060f70e09fba06482dbaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Thu, 10 Dec 2020 22:39:00 +0800 Subject: [PATCH 12/20] Change the typography to vertical --- .../default/reviews/review_stages.html | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/templates/default/reviews/review_stages.html b/src/templates/default/reviews/review_stages.html index ca6e5240a..c6852fbc4 100644 --- a/src/templates/default/reviews/review_stages.html +++ b/src/templates/default/reviews/review_stages.html @@ -17,14 +17,12 @@

    - -
    +
    + {% for rs in review_stages_list %} - + {% endfor %} -
    - -
    + {% csrf_token %}
    @@ -78,8 +76,8 @@

  • {{ ".proposals.disable.after"|configuration_switch }}
    - +
  • @@ -111,4 +109,5 @@

    {% compress js %} {% endcompress %} -{% endblock extra_js %} \ No newline at end of file +{% endblock extra_js %} + From 88ee598f295eaae913aa647352883274e4bcb39d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Thu, 10 Dec 2020 22:40:26 +0800 Subject: [PATCH 13/20] Rename First Round Review_1 to Locked (proposal editing and reviewing disabled) --- src/static/js/reviews/review_stages.js | 8 ++++---- src/users/views.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/static/js/reviews/review_stages.js b/src/static/js/reviews/review_stages.js index 9917816b1..909ae40cd 100644 --- a/src/static/js/reviews/review_stages.js +++ b/src/static/js/reviews/review_stages.js @@ -9,8 +9,8 @@ $('.hotkey').click(function () { if ($(this).val() == "Call for Proposals") { Call_for_Proposals(); } - else if ($(this).val() == "First Round Review_1") { - First_Round_Review_1() + else if ($(this).val() == "Locked (proposal editing and reviewing disabled)") { + Locked() } else if ($(this).val() == "First Round Review") { First_Round_Review() @@ -36,10 +36,10 @@ $('.hotkey').click(function () { proposals_creatable.checked = true; proposals_editable.checked = true; proposals_withdrawable.checked = true; - reviews_stage.value = 0; + reviews_stage.value = "0"; reviews_visible_to_submitters.checked = false; } - function First_Round_Review_1() { + function Locked() { proposals_creatable.checked = false; proposals_editable.checked = false; proposals_withdrawable.checked = false; diff --git a/src/users/views.py b/src/users/views.py index 6e3f9216b..6ed432e52 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -201,10 +201,10 @@ def get_context_data(self, **kwargs): def review_stages(request): review_stages_list = [ - 'Call for Proposals', 'First Round Review_1', - 'First Round Review', 'Modification Stage', - 'Second Round Review', 'Internal Decision', - 'Announcement of Acceptance' + 'Call for Proposals', + 'Locked (proposal editing and reviewing disabled)', + 'First Round Review', 'Modification Stage', 'Second Round Review', + 'Internal Decision', 'Announcement of Acceptance' ] if request.method == 'POST': From 9ef909eeb4f007f2539bff2a332287633e6e722c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Wed, 16 Dec 2020 00:20:11 +0800 Subject: [PATCH 14/20] Enhance user friendliness : accepting pycontw-2020.proposals.disable.after values without ss (seconds) --- src/templates/default/reviews/review_stages.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/templates/default/reviews/review_stages.html b/src/templates/default/reviews/review_stages.html index c6852fbc4..8967b9bda 100644 --- a/src/templates/default/reviews/review_stages.html +++ b/src/templates/default/reviews/review_stages.html @@ -76,7 +76,7 @@

  • {{ ".proposals.disable.after"|configuration_switch }}
    -
  • From d579e699ae864b2c0655d5664c2eca8a58243270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Wed, 16 Dec 2020 00:27:23 +0800 Subject: [PATCH 15/20] Enhance user friendliness : Try more django date format (DATETIME_INPUT_FORMATS) for pycontw-2020.proposals.disable.after & catch ValidationError --- src/users/views.py | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/users/views.py b/src/users/views.py index 6ed432e52..d4f2da8bd 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -1,4 +1,6 @@ from django.conf import settings +from django.conf.global_settings import DATETIME_INPUT_FORMATS +from django.core.exceptions import ValidationError from django.contrib import messages from django.contrib import auth # from django.contrib.auth import get_user_model, login @@ -199,31 +201,27 @@ def get_context_data(self, **kwargs): return context def review_stages(request): - review_stages_list = [ 'Call for Proposals', 'Locked (proposal editing and reviewing disabled)', 'First Round Review', 'Modification Stage', 'Second Round Review', 'Internal Decision', 'Announcement of Acceptance' ] + review_stages_var = [ + 'proposals.creatable', 'proposals.editable', + 'proposals.withdrawable', 'reviews.visible.to.submitters', + 'reviews.stage', 'proposals.disable.after' + ] if request.method == 'POST': - fmt = '%Y-%m-%d %H:%M:%S%z' + date_time_obj = date_preprocess( + DATETIME_INPUT_FORMATS, request.POST['proposals.disable.after']) tz_selectd = pytz.timezone(request.POST['review_timezone']) - date_time_obj = datetime.datetime.strptime( - request.POST['proposals.disable.after'], '%Y-%m-%dT%H:%M:%S') - loc_dt = tz_selectd.localize(date_time_obj).strftime(fmt) - - CONFERENCE_DEFAULT_SLUG = settings.CONFERENCE_DEFAULT_SLUG - review_stages_var = [ - 'proposals.creatable', 'proposals.editable', - 'proposals.withdrawable', 'reviews.visible.to.submitters', - 'reviews.stage', 'proposals.disable.after' - ] + loc_dt = tz_selectd.localize(date_time_obj).strftime('%Y-%m-%d %H:%M:%S%z') for tag in review_stages_var: - key = CONFERENCE_DEFAULT_SLUG + '.' + tag + key = settings.CONFERENCE_DEFAULT_SLUG + '.' + tag if(tag == 'proposals.disable.after'): value = loc_dt elif(tag == 'reviews.stage'): @@ -244,6 +242,17 @@ def review_stages(request): **reviews_state()._asdict() }) +def date_preprocess(DATETIME_INPUT_FORMATS, value): + # Add defined datetime formatx + DATETIME_INPUT_FORMATS += ['%Y-%m-%dT%H:%M:%S', '%Y-%m-%dT%H:%M'] + value = value.strip() + # Try to strptime against each input format. + for format in DATETIME_INPUT_FORMATS: + try: + return datetime.datetime.strptime(value, format) + except (ValueError, TypeError): + continue + raise ValidationError("Please input valid date format : " + "%Y-%m-%dT%H:%M") login = auth_views.LoginView.as_view(authentication_form=AuthenticationForm) logout = auth_views.LogoutView.as_view() From 2fb312d1dfc1c626037d9dbebae6f53e2d438a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Wed, 23 Dec 2020 01:42:52 +0800 Subject: [PATCH 16/20] Enhance user friendliness : display current review stage setting --- src/locale/zh_Hant/LC_MESSAGES/django.po | 12 +++++ .../default/reviews/review_stages.html | 46 ++++++++++++++++++- src/users/views.py | 16 +++++-- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/locale/zh_Hant/LC_MESSAGES/django.po b/src/locale/zh_Hant/LC_MESSAGES/django.po index 3573b86a3..55f9dc316 100644 --- a/src/locale/zh_Hant/LC_MESSAGES/django.po +++ b/src/locale/zh_Hant/LC_MESSAGES/django.po @@ -1449,6 +1449,18 @@ msgstr "審查" msgid "Review Stages" msgstr "審查階段" +#: templates/default/_includes/dashboard_tablist.html:28 +#: templates/default/reviews/review_stages.html:12 +#: templates/default/reviews/review_stages.html:18 +msgid "Current Review Stage Setting" +msgstr "目前審查階段設定" + +#: templates/default/_includes/dashboard_tablist.html:28 +#: templates/default/reviews/review_stages.html:12 +#: templates/default/reviews/review_stages.html:18 +msgid "Set Review Stage" +msgstr "設定審查階段" + #: templates/default/_includes/nav/dashboard_nav.html:10 msgid "Log out" msgstr "登出" diff --git a/src/templates/default/reviews/review_stages.html b/src/templates/default/reviews/review_stages.html index 8967b9bda..7bcb8526c 100644 --- a/src/templates/default/reviews/review_stages.html +++ b/src/templates/default/reviews/review_stages.html @@ -13,12 +13,56 @@ {% block main-content %}

    - {% trans 'Review Stages' %} + {% trans 'Review Stages' %}

    + +
    +
    {% trans 'Current Review Stage Setting' %}
    +
      +
    • + {{ ".proposals.creatable"|configuration_switch }} +
      +

      {{ current_review_stages_setting.proposals_creatable }}

      +
      +
    • +
    • + {{ ".proposals.editable"|configuration_switch }} +
      +

      {{ current_review_stages_setting.proposals_editable }}

      +
      +
    • +
    • + {{ ".proposals.withdrawable"|configuration_switch }} +
      +

      {{ current_review_stages_setting.proposals_withdrawable }}

      +
      +
    • +
    • + {{ ".proposals.reviews.visible.to.submitters"|configuration_switch }} +
      +

      {{ current_review_stages_setting.reviews_visible_to_submitters }}

      +
      +
    • +
    • + {{ ".proposals.reviews.stage"|configuration_switch }} +
      +

      {{ current_review_stages_setting.reviews_stage }}

      +
      +
    • +
    • + {{ ".proposals.proposals.disable.after"|configuration_switch }} +
      +

      {{ current_review_stages_setting.proposals_disable_after }}

      +
      +
    +
    +
    +

    {% trans 'Set Review Stage' %}

    +
    {% for rs in review_stages_list %} {% endfor %} diff --git a/src/users/views.py b/src/users/views.py index d4f2da8bd..4a8f4a088 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -201,6 +201,7 @@ def get_context_data(self, **kwargs): return context def review_stages(request): + current_review_stages_setting = {} review_stages_list = [ 'Call for Proposals', 'Locked (proposal editing and reviewing disabled)', @@ -214,7 +215,6 @@ def review_stages(request): ] if request.method == 'POST': - date_time_obj = date_preprocess( DATETIME_INPUT_FORMATS, request.POST['proposals.disable.after']) tz_selectd = pytz.timezone(request.POST['review_timezone']) @@ -230,15 +230,21 @@ def review_stages(request): value = request.POST[tag] reg[key] = value - messages.info( - request, - 'This setting has been changed successfully and the review stage will expire at ' - + str(loc_dt) + ' (' + request.POST.get('review_timezone') + ')') + messages.info(request, 'This setting has been changed successfully.') + else: + for tag in review_stages_var: + key = settings.CONFERENCE_DEFAULT_SLUG + '.' + tag + value = reg.get(key, '') + # Django template language does not support dictionary keys containing "." + if "." in tag: + tag = tag.replace(".", "_") + current_review_stages_setting[tag] = value return render( request, 'reviews/review_stages.html', { 'timezones': pytz.common_timezones, 'review_stages_list': review_stages_list, + 'current_review_stages_setting': current_review_stages_setting, **reviews_state()._asdict() }) From 500b9db18c69e3283379343807f3ad5d06a57ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Sun, 27 Dec 2020 22:40:06 +0800 Subject: [PATCH 17/20] Enhance user friendliness : automatically load the current settings to the form that will be submitted --- src/templates/default/reviews/review_stages.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/templates/default/reviews/review_stages.html b/src/templates/default/reviews/review_stages.html index 7bcb8526c..142f188b3 100644 --- a/src/templates/default/reviews/review_stages.html +++ b/src/templates/default/reviews/review_stages.html @@ -152,6 +152,13 @@

    {% trans 'Set Review Stage' %}

    {% block extra_js %} {% compress js %} + {% endcompress %} {% endblock extra_js %} From ced5b070fad96be87536707511085b68bfb13b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Sun, 27 Dec 2020 22:45:16 +0800 Subject: [PATCH 18/20] Move url.py & view.py to more precise folder --- src/reviews/urls.py | 6 ++-- src/reviews/views.py | 71 ++++++++++++++++++++++++++++++++++++++++++++ src/users/urls.py | 1 - src/users/views.py | 66 ---------------------------------------- 4 files changed, 75 insertions(+), 69 deletions(-) diff --git a/src/reviews/urls.py b/src/reviews/urls.py index 9250f9e51..4faaf3905 100644 --- a/src/reviews/urls.py +++ b/src/reviews/urls.py @@ -1,10 +1,12 @@ from django.conf.urls import url from .views import ReviewEditView, TalkProposalListView - +from . import views urlpatterns = [ url(r'^$', TalkProposalListView.as_view(), name='review_proposal_list'), url(r'^talk/(?P\d+)/$', - ReviewEditView.as_view(), name='review_edit'), + ReviewEditView.as_view(), + name='review_edit'), + url(r'^review-stages/$', views.review_stages, name='review_stages'), ] diff --git a/src/reviews/views.py b/src/reviews/views.py index cf7d97bbe..f93a22051 100644 --- a/src/reviews/views.py +++ b/src/reviews/views.py @@ -3,10 +3,13 @@ import random from django.conf import settings +from django.conf.global_settings import DATETIME_INPUT_FORMATS +from django.core.exceptions import ValidationError from django.contrib.auth.mixins import PermissionRequiredMixin from django.urls import reverse from django.db.models import Count from django.http import Http404 +from django.shortcuts import redirect, render from django.views.generic import ListView, UpdateView from core.utils import SequenceQuerySet @@ -16,6 +19,10 @@ from .models import REVIEW_REQUIRED_PERMISSIONS, Review, TalkProposalSnapshot from .context import reviews_state +from registry.helper import reg + +import pytz +import datetime class ReviewableMixin: def dispatch(self, request, *args, **kwargs): @@ -286,3 +293,67 @@ def get_success_url(self): if query_string: return url + '?' + query_string return url + +def review_stages(request): + current_review_stages_setting = {} + review_stages_list = [ + 'Call for Proposals', + 'Locked (proposal editing and reviewing disabled)', + 'First Round Review', 'Modification Stage', 'Second Round Review', + 'Internal Decision', 'Announcement of Acceptance' + ] + review_stages_var = [ + 'proposals.creatable', 'proposals.editable', 'proposals.withdrawable', + 'reviews.visible.to.submitters', 'reviews.stage', + 'proposals.disable.after' + ] + + if request.method == 'POST': + date_time_obj = date_preprocess( + DATETIME_INPUT_FORMATS, request.POST['proposals.disable.after']) + tz_selectd = pytz.timezone(request.POST['review_timezone']) + loc_dt = tz_selectd.localize(date_time_obj).strftime( + '%Y-%m-%d %H:%M:%S%z') + + for tag in review_stages_var: + key = settings.CONFERENCE_DEFAULT_SLUG + '.' + tag + if (tag == 'proposals.disable.after'): + value = loc_dt + elif (tag == 'reviews.stage'): + value = int(request.POST[tag]) + else: + value = request.POST[tag] + reg[key] = value + + messages.info(request, 'This setting has been changed successfully.') + else: + for tag in review_stages_var: + key = settings.CONFERENCE_DEFAULT_SLUG + '.' + tag + value = reg.get(key, '') + # Django template language does not support dictionary keys containing "." + if "." in tag: + tag = tag.replace(".", "_") + current_review_stages_setting[tag] = value + print(tag) + print(value) + + return render( + request, 'reviews/review_stages.html', { + 'timezones': pytz.common_timezones, + 'review_stages_list': review_stages_list, + 'current_review_stages_setting': current_review_stages_setting, + **reviews_state()._asdict() + }) + + +def date_preprocess(DATETIME_INPUT_FORMATS, value): + # Add defined datetime formatx + DATETIME_INPUT_FORMATS += ['%Y-%m-%dT%H:%M:%S', '%Y-%m-%dT%H:%M'] + value = value.strip() + # Try to strptime against each input format. + for format in DATETIME_INPUT_FORMATS: + try: + return datetime.datetime.strptime(value, format) + except (ValueError, TypeError): + continue + raise ValidationError("Please input valid date format : " + "%Y-%m-%dT%H:%M") diff --git a/src/users/urls.py b/src/users/urls.py index 2471ab97c..c49ed6b57 100644 --- a/src/users/urls.py +++ b/src/users/urls.py @@ -32,5 +32,4 @@ views.password_reset_complete, name='password_reset_complete'), url(r'^agreement/$', views.coc_agree, name='coc_agreement'), - url(r'^review-stages/$', views.review_stages, name='review_stages'), ] diff --git a/src/users/views.py b/src/users/views.py index 4a8f4a088..eba4854e0 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -1,6 +1,4 @@ from django.conf import settings -from django.conf.global_settings import DATETIME_INPUT_FORMATS -from django.core.exceptions import ValidationError from django.contrib import messages from django.contrib import auth # from django.contrib.auth import get_user_model, login @@ -22,14 +20,10 @@ ) from .models import CocRecord from reviews.context import proposals_state, reviews_state -from registry.helper import reg from lxml import etree import lxml.html -import pytz -import datetime - User = auth.get_user_model() @@ -200,66 +194,6 @@ def get_context_data(self, **kwargs): context.update(**reviews_state()._asdict()) return context -def review_stages(request): - current_review_stages_setting = {} - review_stages_list = [ - 'Call for Proposals', - 'Locked (proposal editing and reviewing disabled)', - 'First Round Review', 'Modification Stage', 'Second Round Review', - 'Internal Decision', 'Announcement of Acceptance' - ] - review_stages_var = [ - 'proposals.creatable', 'proposals.editable', - 'proposals.withdrawable', 'reviews.visible.to.submitters', - 'reviews.stage', 'proposals.disable.after' - ] - - if request.method == 'POST': - date_time_obj = date_preprocess( - DATETIME_INPUT_FORMATS, request.POST['proposals.disable.after']) - tz_selectd = pytz.timezone(request.POST['review_timezone']) - loc_dt = tz_selectd.localize(date_time_obj).strftime('%Y-%m-%d %H:%M:%S%z') - - for tag in review_stages_var: - key = settings.CONFERENCE_DEFAULT_SLUG + '.' + tag - if(tag == 'proposals.disable.after'): - value = loc_dt - elif(tag == 'reviews.stage'): - value = int(request.POST[tag]) - else: - value = request.POST[tag] - reg[key] = value - - messages.info(request, 'This setting has been changed successfully.') - else: - for tag in review_stages_var: - key = settings.CONFERENCE_DEFAULT_SLUG + '.' + tag - value = reg.get(key, '') - # Django template language does not support dictionary keys containing "." - if "." in tag: - tag = tag.replace(".", "_") - current_review_stages_setting[tag] = value - - return render( - request, 'reviews/review_stages.html', { - 'timezones': pytz.common_timezones, - 'review_stages_list': review_stages_list, - 'current_review_stages_setting': current_review_stages_setting, - **reviews_state()._asdict() - }) - -def date_preprocess(DATETIME_INPUT_FORMATS, value): - # Add defined datetime formatx - DATETIME_INPUT_FORMATS += ['%Y-%m-%dT%H:%M:%S', '%Y-%m-%dT%H:%M'] - value = value.strip() - # Try to strptime against each input format. - for format in DATETIME_INPUT_FORMATS: - try: - return datetime.datetime.strptime(value, format) - except (ValueError, TypeError): - continue - raise ValidationError("Please input valid date format : " + "%Y-%m-%dT%H:%M") - login = auth_views.LoginView.as_view(authentication_form=AuthenticationForm) logout = auth_views.LogoutView.as_view() password_change = PasswordChangeView.as_view() From 928e2d1a610f685ea2535ebc42edab892d234cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Tue, 29 Dec 2020 01:30:26 +0800 Subject: [PATCH 19/20] Fix problem that current settings will not be loaded after submitting form --- src/reviews/views.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/reviews/views.py b/src/reviews/views.py index f93a22051..a88303f36 100644 --- a/src/reviews/views.py +++ b/src/reviews/views.py @@ -6,6 +6,7 @@ from django.conf.global_settings import DATETIME_INPUT_FORMATS from django.core.exceptions import ValidationError from django.contrib.auth.mixins import PermissionRequiredMixin +from django.contrib import messages from django.urls import reverse from django.db.models import Count from django.http import Http404 @@ -326,16 +327,15 @@ def review_stages(request): reg[key] = value messages.info(request, 'This setting has been changed successfully.') - else: - for tag in review_stages_var: - key = settings.CONFERENCE_DEFAULT_SLUG + '.' + tag - value = reg.get(key, '') - # Django template language does not support dictionary keys containing "." - if "." in tag: - tag = tag.replace(".", "_") - current_review_stages_setting[tag] = value - print(tag) - print(value) + + # Render current setting to frontend + for tag in review_stages_var: + key = settings.CONFERENCE_DEFAULT_SLUG + '.' + tag + value = reg.get(key, '') + # Django template language does not support dictionary keys containing "." + if "." in tag: + tag = tag.replace(".", "_") + current_review_stages_setting[tag] = value return render( request, 'reviews/review_stages.html', { From c4ef31e7786a4e977f3835c54f177ab8d4a95400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E6=AB=BB=E7=80=9E?= Date: Sat, 16 Jan 2021 08:47:18 +0800 Subject: [PATCH 20/20] proposals.disabled.after not be required --- src/reviews/views.py | 30 +++++++++++++---- src/static/js/reviews/review_stages.js | 3 +- .../default/reviews/review_stages.html | 33 ++----------------- 3 files changed, 27 insertions(+), 39 deletions(-) diff --git a/src/reviews/views.py b/src/reviews/views.py index a88303f36..b975bb5b5 100644 --- a/src/reviews/views.py +++ b/src/reviews/views.py @@ -310,16 +310,31 @@ def review_stages(request): ] if request.method == 'POST': - date_time_obj = date_preprocess( - DATETIME_INPUT_FORMATS, request.POST['proposals.disable.after']) - tz_selectd = pytz.timezone(request.POST['review_timezone']) - loc_dt = tz_selectd.localize(date_time_obj).strftime( - '%Y-%m-%d %H:%M:%S%z') for tag in review_stages_var: key = settings.CONFERENCE_DEFAULT_SLUG + '.' + tag if (tag == 'proposals.disable.after'): - value = loc_dt + if(request.POST['proposals.disable.after'] == ""): + continue + else: + date_time_obj = date_preprocess( + DATETIME_INPUT_FORMATS, + request.POST['proposals.disable.after']) + if(date_time_obj is None): + messages.error(request,'Please input valid date format : " + "%Y-%m-%dT%H:%M') + return render( + request, 'reviews/review_stages.html', { + 'timezones': pytz.common_timezones, + 'review_stages_list': review_stages_list, + 'current_review_stages_setting': current_review_stages_setting, + **reviews_state()._asdict() + }) + continue + else: + tz_selectd = pytz.timezone(request.POST['review_timezone']) + loc_dt = tz_selectd.localize(date_time_obj).strftime( + '%Y-%m-%d %H:%M:%S%z') + value = loc_dt elif (tag == 'reviews.stage'): value = int(request.POST[tag]) else: @@ -356,4 +371,5 @@ def date_preprocess(DATETIME_INPUT_FORMATS, value): return datetime.datetime.strptime(value, format) except (ValueError, TypeError): continue - raise ValidationError("Please input valid date format : " + "%Y-%m-%dT%H:%M") + return None + # raise ValidationError("Please input valid date format : " + "%Y-%m-%dT%H:%M") diff --git a/src/static/js/reviews/review_stages.js b/src/static/js/reviews/review_stages.js index 909ae40cd..48baa9a8b 100644 --- a/src/static/js/reviews/review_stages.js +++ b/src/static/js/reviews/review_stages.js @@ -81,4 +81,5 @@ $('.hotkey').click(function () { reviews_stage.value = "0"; reviews_visible_to_submitters.checked = true; } -}); \ No newline at end of file + +}); diff --git a/src/templates/default/reviews/review_stages.html b/src/templates/default/reviews/review_stages.html index 142f188b3..3427d22b8 100644 --- a/src/templates/default/reviews/review_stages.html +++ b/src/templates/default/reviews/review_stages.html @@ -22,41 +22,12 @@

    {% trans 'Current Review Stage Setting' %}
      -
    • - {{ ".proposals.creatable"|configuration_switch }} -
      -

      {{ current_review_stages_setting.proposals_creatable }}

      -
      -
    • -
    • - {{ ".proposals.editable"|configuration_switch }} -
      -

      {{ current_review_stages_setting.proposals_editable }}

      -
      -
    • -
    • - {{ ".proposals.withdrawable"|configuration_switch }} -
      -

      {{ current_review_stages_setting.proposals_withdrawable }}

      -
      -
    • -
    • - {{ ".proposals.reviews.visible.to.submitters"|configuration_switch }} -
      -

      {{ current_review_stages_setting.reviews_visible_to_submitters }}

      -
      -
    • -
    • - {{ ".proposals.reviews.stage"|configuration_switch }} -
      -

      {{ current_review_stages_setting.reviews_stage }}

      -
      -
    • {{ ".proposals.proposals.disable.after"|configuration_switch }}

      {{ current_review_stages_setting.proposals_disable_after }}

      +
    @@ -121,7 +92,7 @@

    {% trans 'Set Review Stage' %}

    {{ ".proposals.disable.after"|configuration_switch }}
    + >