diff --git a/infoscreen/static/css/infoscreen_admin.css b/infoscreen/static/css/infoscreen_admin.css index 6031fcd..f4ceb48 100644 --- a/infoscreen/static/css/infoscreen_admin.css +++ b/infoscreen/static/css/infoscreen_admin.css @@ -1,5 +1,55 @@ -td{ -max-width:12vw; -overflow:hidden; -word-wrap:break-word; -} \ No newline at end of file +html { + font-size: 16px; +} + +body { + padding: 1.5rem; + margin: 0.5rem; +} + +tbody { + border: 1px solid #ddd; +} + +div { + margin-bottom: 0.5rem; +} + +td { + max-width: 12vw; + overflow: hidden; + word-wrap: break-word; +} + +@media (min-width: 760px) { + body { + font-size: 1rem; + } +} + +@media (max-width: 760px) { + body { + font-size: 0.7rem; + padding: 0; + } + h1 { + font-size: 2.5rem; + } + h2 { + font-size: 1.5rem; + } + .logout-button { + margin: 0; + } + table>tbody>tr>td, + table>tbody>tr>th { + white-space: normal; + padding: 0.2rem !important; + max-width: 100%; + } +} + + +#header { + max-width: 100%; +} diff --git a/infoscreen/templates/infoscreen_admin.html b/infoscreen/templates/infoscreen_admin.html index b9e550c..45c49dd 100644 --- a/infoscreen/templates/infoscreen_admin.html +++ b/infoscreen/templates/infoscreen_admin.html @@ -4,7 +4,7 @@ - + Infoscreen admin @@ -25,87 +25,148 @@ -
+

{% trans "Infoscreen Admin Pane" %}

-
-
-

{% trans "Info items" %}

-
{% trans "Infoitems available for rotations" %}
- - - - - - - - - - - - - - - -
{% trans "Item" %}{% trans "Type" %}{% trans "Set duration" %}{% trans "Add to rotation" %}{% trans "Delete" %}
{$ i.name $}{$ i.display_name $}
-

{% trans "Create new item" %}

- - - - - -
{% trans "Item type" %} - -
-
-
-
-

{% trans "Rotations" %}

-
- {% trans "Select rotation to edit" %}: -
- - - - - - - - - - - - - - - - - - - - - - -
{% trans "Rotation" %}{% trans "id" %}{% trans "Select" %}{% trans "Preview" %}{% trans "Delete" %}
{$ r.name $}{$ r.id $}
+ +
+
+
+
+

{% trans "Create new item" %}

+
{% trans "Create a new item by type" %}
+ + + + + +
{% trans "Item type" %} + +
+
+
+
+

{% trans "Info items" %}

+
{% trans "Infoitems available for rotations" %}
+ + + + + + + + + + + +
{% trans "Item" %}{% trans "Type" %}{% trans "Delete" %}
{$ i.name $}{$ i.display_name $}
-

{% trans "Rotation" %}: {$ selected_rot.name $}

-
{% trans "Instances in currently selected rotation" %}:
- - - - - - - - - - -
{% trans "Instance" %}{% trans "Duration" %}{% trans "Delete" %}
{$ i.item.name $}{$ i.duration $} s
+
+
+
+
+
+

{% trans "Info items" %}

+
{% trans "Infoitems available for rotations" %}
+ + + + + + + + + + + + + + + +
{% trans "Item" %}{% trans "Type" %}{% trans "Set duration" %}{% trans "Add to rotation" %}{% trans "Delete" %}
{$ i.name $}{$ i.display_name $}
+ +
+ +
+

{% trans "Rotation" %}: {$ selected_rot.name $}

+
{% trans "Instances in currently selected rotation" %}:
+ + + + + + + + + + +
{% trans "Instance" %}{% trans "Duration" %}{% trans "Delete" %}
{$ i.item.name $}{$ i.duration $} s
+
+
+
+
+

{% trans "Rotations" %}

+
+ {% trans "Select rotation to edit" %}: +
+ + + + + + + + + + + + + + + + + + + +
{% trans "Rotation" %}{% trans "id" %}{% trans "Preview" %}{% trans "Delete" %}
{$ r.name $}{$ r.id $}
+
+
+
+
+
+

{% trans "Settings" %}

+
+ +
{% csrf_token %} +
+

{% trans "Language" %}

+
+
+ +
+
+ +
+
+
diff --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo index 9435ae5..bd4b884 100644 Binary files a/locale/en/LC_MESSAGES/django.mo and b/locale/en/LC_MESSAGES/django.mo differ diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index b9ee95d..d283642 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-26 19:53+0300\n" +"POT-Creation-Date: 2017-06-01 19:20+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -50,7 +50,7 @@ msgid "External image" msgstr "External image" #: infoscreen/templates/infoscreen_admin.html:24 -#: members/templates/members_base.html:69 +#: members/templates/members_base.html:79 msgid "Log out" msgstr "Log out" @@ -58,99 +58,119 @@ msgstr "Log out" msgid "Infoscreen Admin Pane" msgstr "Infoscreen Admin Pane" -#: infoscreen/templates/infoscreen_admin.html:36 +#: infoscreen/templates/infoscreen_admin.html:35 +msgid "Manage Slides" +msgstr "" + +#: infoscreen/templates/infoscreen_admin.html:37 +msgid "Manage Rotations" +msgstr "Manage Rotations" + +#: infoscreen/templates/infoscreen_admin.html:41 +msgid "Create/Delete" +msgstr "Create/Delete" + +#: infoscreen/templates/infoscreen_admin.html:48 +msgid "Create new item" +msgstr "Create new item" + +#: infoscreen/templates/infoscreen_admin.html:49 +#, fuzzy +#| msgid "Create new item" +msgid "Create a new item by type" +msgstr "Create new item" + +#: infoscreen/templates/infoscreen_admin.html:52 +msgid "Item type" +msgstr "Item type" + +#: infoscreen/templates/infoscreen_admin.html:63 +#: infoscreen/templates/infoscreen_admin.html:83 msgid "Info items" msgstr "Info items" -#: infoscreen/templates/infoscreen_admin.html:37 +#: infoscreen/templates/infoscreen_admin.html:64 +#: infoscreen/templates/infoscreen_admin.html:84 msgid "Infoitems available for rotations" msgstr "Infoitems available for rotations" -#: infoscreen/templates/infoscreen_admin.html:40 +#: infoscreen/templates/infoscreen_admin.html:67 +#: infoscreen/templates/infoscreen_admin.html:87 msgid "Item" msgstr "Item" -#: infoscreen/templates/infoscreen_admin.html:41 +#: infoscreen/templates/infoscreen_admin.html:68 +#: infoscreen/templates/infoscreen_admin.html:88 msgid "Type" msgstr "Type" -#: infoscreen/templates/infoscreen_admin.html:42 -msgid "Set duration" -msgstr "Set duration" - -#: infoscreen/templates/infoscreen_admin.html:43 -msgid "Add to rotation" -msgstr "Add to rotation" - -#: infoscreen/templates/infoscreen_admin.html:44 -#: infoscreen/templates/infoscreen_admin.html:51 -#: infoscreen/templates/infoscreen_admin.html:78 -#: infoscreen/templates/infoscreen_admin.html:85 -#: infoscreen/templates/infoscreen_admin.html:102 -#: infoscreen/templates/infoscreen_admin.html:106 +#: infoscreen/templates/infoscreen_admin.html:69 +#: infoscreen/templates/infoscreen_admin.html:74 +#: infoscreen/templates/infoscreen_admin.html:91 +#: infoscreen/templates/infoscreen_admin.html:98 +#: infoscreen/templates/infoscreen_admin.html:112 +#: infoscreen/templates/infoscreen_admin.html:116 +#: infoscreen/templates/infoscreen_admin.html:134 +#: infoscreen/templates/infoscreen_admin.html:140 #: members/templates/member_edit.html:20 members/templates/payment_edit.html:20 msgid "Delete" msgstr "Delete" -#: infoscreen/templates/infoscreen_admin.html:50 +#: infoscreen/templates/infoscreen_admin.html:89 +msgid "Set duration" +msgstr "Set duration" + +#: infoscreen/templates/infoscreen_admin.html:90 +msgid "Add to rotation" +msgstr "Add to rotation" + +#: infoscreen/templates/infoscreen_admin.html:97 msgid "Add" msgstr "Add" -#: infoscreen/templates/infoscreen_admin.html:54 -msgid "Create new item" -msgstr "Create new item" - -#: infoscreen/templates/infoscreen_admin.html:57 -msgid "Item type" -msgstr "Item type" - -#: infoscreen/templates/infoscreen_admin.html:68 -msgid "Rotations" -msgstr "Rotations" - -#: infoscreen/templates/infoscreen_admin.html:70 -msgid "Select rotation to edit" -msgstr "Select rotation to edit" - -#: infoscreen/templates/infoscreen_admin.html:74 -#: infoscreen/templates/infoscreen_admin.html:96 +#: infoscreen/templates/infoscreen_admin.html:106 +#: infoscreen/templates/infoscreen_admin.html:131 msgid "Rotation" msgstr "Rotation" -#: infoscreen/templates/infoscreen_admin.html:75 -msgid "id" -msgstr "id" - -#: infoscreen/templates/infoscreen_admin.html:76 -#: infoscreen/templates/infoscreen_admin.html:83 -msgid "Select" -msgstr "Select" - -#: infoscreen/templates/infoscreen_admin.html:77 -#: infoscreen/templates/infoscreen_admin.html:84 +#: infoscreen/templates/infoscreen_admin.html:106 +#: infoscreen/templates/infoscreen_admin.html:133 +#: infoscreen/templates/infoscreen_admin.html:139 msgid "Preview" msgstr "Preview" -#: infoscreen/templates/infoscreen_admin.html:88 -msgid "Name" -msgstr "Name" - -#: infoscreen/templates/infoscreen_admin.html:89 -msgid "Create new" -msgstr "Create new" - -#: infoscreen/templates/infoscreen_admin.html:97 +#: infoscreen/templates/infoscreen_admin.html:107 msgid "Instances in currently selected rotation" msgstr "Instances in currently selected rotation" -#: infoscreen/templates/infoscreen_admin.html:100 +#: infoscreen/templates/infoscreen_admin.html:110 msgid "Instance" msgstr "Instance" -#: infoscreen/templates/infoscreen_admin.html:101 +#: infoscreen/templates/infoscreen_admin.html:111 msgid "Duration" msgstr "Duration" +#: infoscreen/templates/infoscreen_admin.html:125 +msgid "Rotations" +msgstr "Rotations" + +#: infoscreen/templates/infoscreen_admin.html:127 +msgid "Select rotation to edit" +msgstr "Select rotation to edit" + +#: infoscreen/templates/infoscreen_admin.html:132 +msgid "id" +msgstr "id" + +#: infoscreen/templates/infoscreen_admin.html:143 +msgid "Name" +msgstr "Name" + +#: infoscreen/templates/infoscreen_admin.html:144 +msgid "Create new" +msgstr "Create new" + #: members/models.py:16 msgid "First name" msgstr "First name" @@ -195,7 +215,7 @@ msgstr "Cash" msgid "Bank transfer" msgstr "Bank transfer" -#: members/models.py:98 +#: members/models.py:102 msgid "Created" msgstr "Created" @@ -239,7 +259,7 @@ msgstr "Error" msgid "Back" msgstr "Back" -#: members/templates/member_add.html:8 members/templates/members_base.html:45 +#: members/templates/member_add.html:8 members/templates/members_base.html:55 msgid "Add member" msgstr "Add member" @@ -289,6 +309,31 @@ msgstr "Are you sure you want to delete this member?" msgid "Yes, I'm sure" msgstr "Yes, I'm sure" +#: members/templates/member_duplicates.html:9 +msgid "Conflicting member entries" +msgstr "" + +#: members/templates/member_duplicates.html:13 +msgid "" +"Found conflicting member entries. Choose how to handle the problematic data." +msgstr "" + +#: members/templates/member_duplicates.html:29 +msgid "Which one has the correct information for this member?" +msgstr "" + +#: members/templates/member_duplicates.html:31 +msgid "Accept first and remove second" +msgstr "" + +#: members/templates/member_duplicates.html:32 +msgid "Accept second and remove first" +msgstr "" + +#: members/templates/member_duplicates.html:33 +msgid "Accept both as two members" +msgstr "" + #: members/templates/member_edit.html:9 msgid "Edit member" msgstr "Edit member" @@ -297,51 +342,64 @@ msgstr "Edit member" msgid "Member register" msgstr "Member register" -#: members/templates/member_list.html:23 +#: members/templates/member_list.html:16 +msgid "" +"There are duplicate member entries in the register.\n" +" Please visit duplicate resolver." +msgstr "" + +#: members/templates/member_list.html:28 +#, fuzzy +#| msgid "Member register" +msgid "Members in register:" +msgstr "Member register" + +#: members/templates/member_list.html:34 msgid "Download CSV" msgstr "Download CSV" #: members/templates/members_base.html:33 +#: members/templates/members_base.html:42 msgid "Member register of SIK ry" msgstr "Member register of SIK ry" -#: members/templates/members_base.html:42 webapp/templates/main_index.html:7 +#: members/templates/members_base.html:52 webapp/templates/main_index.html:7 msgid "Members" msgstr "Members" -#: members/templates/members_base.html:44 +#: members/templates/members_base.html:54 msgid "List members" msgstr "List members" -#: members/templates/members_base.html:46 +#: members/templates/members_base.html:56 msgid "Add multiple" msgstr "Add multiple" -#: members/templates/members_base.html:50 +#: members/templates/members_base.html:60 msgid "Payments" msgstr "Payments" -#: members/templates/members_base.html:52 +#: members/templates/members_base.html:62 msgid "List payments" msgstr "List payments" -#: members/templates/members_base.html:53 members/templates/payment_add.html:8 +#: members/templates/members_base.html:63 members/templates/payment_add.html:8 msgid "Add payment" msgstr "Add payment" -#: members/templates/members_base.html:57 +#: members/templates/members_base.html:67 msgid "Applications" msgstr "Applications" -#: members/templates/members_base.html:59 +#: members/templates/members_base.html:69 msgid "List applications" msgstr "List applications" -#: members/templates/members_base.html:60 +#: members/templates/members_base.html:70 msgid "Application form" msgstr "Application form" -#: members/templates/members_base.html:65 members/templates/settings.html:11 +#: members/templates/members_base.html:75 members/templates/settings.html:11 msgid "Settings" msgstr "Settings" @@ -361,96 +419,102 @@ msgstr "Payment events" msgid "Language" msgstr "Language" -#: members/templates/settings.html:20 sikweb/settings-sample.py:177 +#: members/templates/settings.html:20 sikweb/settings-sample.py:179 #: sikweb/settings.py:177 msgid "Finnish" msgstr "Finnish" -#: members/templates/settings.html:21 sikweb/settings-sample.py:176 +#: members/templates/settings.html:21 sikweb/settings-sample.py:178 #: sikweb/settings.py:176 msgid "English" msgstr "English" -#: members/views.py:114 members/views.py:171 members/views.py:190 +#: members/views.py:129 members/views.py:186 members/views.py:205 msgid "No member id specified" msgstr "No member id specified" -#: members/views.py:136 +#: members/views.py:151 msgid "Successfully added member" msgstr "Successfully added member" -#: members/views.py:157 +#: members/views.py:172 msgid "Successfully updated member" msgstr "Successfully updated member" -#: members/views.py:161 +#: members/views.py:176 msgid "Could not update member object" msgstr "Could not update member object" -#: members/views.py:175 +#: members/views.py:190 msgid "Successfully deleted member" msgstr "Successfully deleted member" -#: members/views.py:181 +#: members/views.py:196 msgid "Could not delete member object" msgstr "Could not delete member object" -#: members/views.py:224 members/views.py:258 members/views.py:276 +#: members/views.py:239 members/views.py:273 members/views.py:291 msgid "No application id specified" msgstr "No application id specified" -#: members/views.py:245 +#: members/views.py:260 msgid "Successfully accepted application" msgstr "Successfully accepted application" -#: members/views.py:248 +#: members/views.py:263 msgid "Could not accept application object" msgstr "Could not accept application object" -#: members/views.py:262 +#: members/views.py:277 msgid "Successfully deleted application" msgstr "Successfully deleted application" -#: members/views.py:267 +#: members/views.py:282 msgid "Could not delete application object" msgstr "Could not delete application object" -#: members/views.py:331 +#: members/views.py:346 msgid "Successfully added payment for member" msgstr "Successfully added payment for member" -#: members/views.py:344 members/views.py:357 members/views.py:371 +#: members/views.py:359 members/views.py:372 members/views.py:386 msgid "No payment id specified" msgstr "No payment id specified" -#: members/views.py:375 +#: members/views.py:390 msgid "Successfully deleted payment" msgstr "Successfully deleted payment" -#: members/views.py:380 +#: members/views.py:395 msgid "Could not delete payment object" msgstr "Could not delete payment object" -#: members/views.py:395 +#: members/views.py:410 msgid "Successfully updated payment" msgstr "Successfully updated payment" -#: members/views.py:398 +#: members/views.py:413 msgid "Could not update payment object" msgstr "Could not update payment object" -#: members/views.py:415 +#: members/views.py:430 msgid "Missing \"textfield\" POST request field" msgstr "Missing \"textfield\" POST request field" -#: members/views.py:420 +#: members/views.py:435 msgid "Successfully imported multiple members" msgstr "Successfully imported multiple members" -#: members/views.py:423 +#: members/views.py:438 msgid "Failed to import members" msgstr "Failed to import members" +#: members/views.py:504 +#, fuzzy +#| msgid "Successfully deleted member" +msgid "Successfully resolved all member conflicts." +msgstr "Successfully deleted member" + #: templates/footer.html:7 msgid "Copyright Aalto-yliopiston Sähköinsinöörikilta ry" msgstr "Copyright Aalto-yliopiston Sähköinsinöörikilta ry" @@ -463,6 +527,18 @@ msgstr "SIK Admin" msgid "Aalto-yliopiston Sähköinsinöörikilta ry" msgstr "Aalto-yliopiston Sähköinsinöörikilta ry" +#: webapp/templates/login.html:25 webapp/templates/login.html:27 +msgid "Username" +msgstr "Username" + +#: webapp/templates/login.html:31 webapp/templates/login.html:33 +msgid "Password" +msgstr "Password" + +#: webapp/templates/login.html:43 +msgid "Log in" +msgstr "Log in" + #: webapp/templates/main_index.html:8 msgid "Infoscreen" msgstr "Infoscreen" @@ -486,3 +562,6 @@ msgstr "Sössö" #: webapp/templates/navigation.html:32 msgid "Contact" msgstr "Contact" + +#~ msgid "Select" +#~ msgstr "Select" diff --git a/locale/fi/LC_MESSAGES/django.mo b/locale/fi/LC_MESSAGES/django.mo index e85684a..5fd3dd7 100644 Binary files a/locale/fi/LC_MESSAGES/django.mo and b/locale/fi/LC_MESSAGES/django.mo differ diff --git a/locale/fi/LC_MESSAGES/django.po b/locale/fi/LC_MESSAGES/django.po index 1abf0c5..b7de81d 100644 --- a/locale/fi/LC_MESSAGES/django.po +++ b/locale/fi/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-26 19:53+0300\n" +"POT-Creation-Date: 2017-06-01 19:20+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -51,7 +51,7 @@ msgid "External image" msgstr "Ulkoinen kuva" #: infoscreen/templates/infoscreen_admin.html:24 -#: members/templates/members_base.html:69 +#: members/templates/members_base.html:79 msgid "Log out" msgstr "Kirjaudu ulos" @@ -59,99 +59,117 @@ msgstr "Kirjaudu ulos" msgid "Infoscreen Admin Pane" msgstr "Infonäyttöjen hallintapaneeli" -#: infoscreen/templates/infoscreen_admin.html:36 +#: infoscreen/templates/infoscreen_admin.html:35 +msgid "Manage Slides" +msgstr "Hallinnoi dioja" + +#: infoscreen/templates/infoscreen_admin.html:37 +msgid "Manage Rotations" +msgstr "Hallinnoi Rotaatioita" + +#: infoscreen/templates/infoscreen_admin.html:41 +msgid "Create/Delete" +msgstr "Lisää/Poista" + +#: infoscreen/templates/infoscreen_admin.html:48 +msgid "Create new item" +msgstr "Luo uusi dia" + +#: infoscreen/templates/infoscreen_admin.html:49 +msgid "Create a new item by type" +msgstr "Luo uusi dia tyypin perusteella" + +#: infoscreen/templates/infoscreen_admin.html:52 +msgid "Item type" +msgstr "Diatyyppi" + +#: infoscreen/templates/infoscreen_admin.html:63 +#: infoscreen/templates/infoscreen_admin.html:83 msgid "Info items" msgstr "Diat" -#: infoscreen/templates/infoscreen_admin.html:37 +#: infoscreen/templates/infoscreen_admin.html:64 +#: infoscreen/templates/infoscreen_admin.html:84 msgid "Infoitems available for rotations" msgstr "Rotaatioon lisättävät diat" -#: infoscreen/templates/infoscreen_admin.html:40 +#: infoscreen/templates/infoscreen_admin.html:67 +#: infoscreen/templates/infoscreen_admin.html:87 msgid "Item" msgstr "Dia" -#: infoscreen/templates/infoscreen_admin.html:41 +#: infoscreen/templates/infoscreen_admin.html:68 +#: infoscreen/templates/infoscreen_admin.html:88 msgid "Type" msgstr "Tyyppi" -#: infoscreen/templates/infoscreen_admin.html:42 -msgid "Set duration" -msgstr "Aseta kesto" - -#: infoscreen/templates/infoscreen_admin.html:43 -msgid "Add to rotation" -msgstr "Lisää rotaatioon" - -#: infoscreen/templates/infoscreen_admin.html:44 -#: infoscreen/templates/infoscreen_admin.html:51 -#: infoscreen/templates/infoscreen_admin.html:78 -#: infoscreen/templates/infoscreen_admin.html:85 -#: infoscreen/templates/infoscreen_admin.html:102 -#: infoscreen/templates/infoscreen_admin.html:106 +#: infoscreen/templates/infoscreen_admin.html:69 +#: infoscreen/templates/infoscreen_admin.html:74 +#: infoscreen/templates/infoscreen_admin.html:91 +#: infoscreen/templates/infoscreen_admin.html:98 +#: infoscreen/templates/infoscreen_admin.html:112 +#: infoscreen/templates/infoscreen_admin.html:116 +#: infoscreen/templates/infoscreen_admin.html:134 +#: infoscreen/templates/infoscreen_admin.html:140 #: members/templates/member_edit.html:20 members/templates/payment_edit.html:20 msgid "Delete" msgstr "Poista" -#: infoscreen/templates/infoscreen_admin.html:50 +#: infoscreen/templates/infoscreen_admin.html:89 +msgid "Set duration" +msgstr "Aseta kesto" + +#: infoscreen/templates/infoscreen_admin.html:90 +msgid "Add to rotation" +msgstr "Lisää rotaatioon" + +#: infoscreen/templates/infoscreen_admin.html:97 msgid "Add" msgstr "Lisää" -#: infoscreen/templates/infoscreen_admin.html:54 -msgid "Create new item" -msgstr "Luo uusi dia" - -#: infoscreen/templates/infoscreen_admin.html:57 -msgid "Item type" -msgstr "Diatyyppi" - -#: infoscreen/templates/infoscreen_admin.html:68 -msgid "Rotations" -msgstr "Rotaatiot" - -#: infoscreen/templates/infoscreen_admin.html:70 -msgid "Select rotation to edit" -msgstr "Valitse muokattava rotaatio" - -#: infoscreen/templates/infoscreen_admin.html:74 -#: infoscreen/templates/infoscreen_admin.html:96 +#: infoscreen/templates/infoscreen_admin.html:106 +#: infoscreen/templates/infoscreen_admin.html:131 msgid "Rotation" msgstr "Rotaatio" -#: infoscreen/templates/infoscreen_admin.html:75 -msgid "id" -msgstr "id" - -#: infoscreen/templates/infoscreen_admin.html:76 -#: infoscreen/templates/infoscreen_admin.html:83 -msgid "Select" -msgstr "Valitse" - -#: infoscreen/templates/infoscreen_admin.html:77 -#: infoscreen/templates/infoscreen_admin.html:84 +#: infoscreen/templates/infoscreen_admin.html:106 +#: infoscreen/templates/infoscreen_admin.html:133 +#: infoscreen/templates/infoscreen_admin.html:139 msgid "Preview" msgstr "Esikatsele" -#: infoscreen/templates/infoscreen_admin.html:88 -msgid "Name" -msgstr "Nimi" - -#: infoscreen/templates/infoscreen_admin.html:89 -msgid "Create new" -msgstr "Luo uusi" - -#: infoscreen/templates/infoscreen_admin.html:97 +#: infoscreen/templates/infoscreen_admin.html:107 msgid "Instances in currently selected rotation" msgstr "Nykyisen rotaation diat" -#: infoscreen/templates/infoscreen_admin.html:100 +#: infoscreen/templates/infoscreen_admin.html:110 msgid "Instance" msgstr "Dia" -#: infoscreen/templates/infoscreen_admin.html:101 +#: infoscreen/templates/infoscreen_admin.html:111 msgid "Duration" msgstr "Kesto" +#: infoscreen/templates/infoscreen_admin.html:125 +msgid "Rotations" +msgstr "Rotaatiot" + +#: infoscreen/templates/infoscreen_admin.html:127 +msgid "Select rotation to edit" +msgstr "Valitse muokattava rotaatio" + +#: infoscreen/templates/infoscreen_admin.html:132 +msgid "id" +msgstr "id" + +#: infoscreen/templates/infoscreen_admin.html:143 +msgid "Name" +msgstr "Nimi" + +#: infoscreen/templates/infoscreen_admin.html:144 +msgid "Create new" +msgstr "Luo uusi" + #: members/models.py:16 msgid "First name" msgstr "Etunimi" @@ -196,7 +214,7 @@ msgstr "Käteinen" msgid "Bank transfer" msgstr "Tilisiirto" -#: members/models.py:98 +#: members/models.py:102 msgid "Created" msgstr "Lisätty" @@ -240,7 +258,7 @@ msgstr "Virhe" msgid "Back" msgstr "Takaisin" -#: members/templates/member_add.html:8 members/templates/members_base.html:45 +#: members/templates/member_add.html:8 members/templates/members_base.html:55 msgid "Add member" msgstr "Lisää jäsen" @@ -293,6 +311,32 @@ msgstr "Oletko varma, että haluat poistaa tämän jäsenen?" msgid "Yes, I'm sure" msgstr "Kyllä, olen varma" +#: members/templates/member_duplicates.html:9 +msgid "Conflicting member entries" +msgstr "Ongelmalliset jäsentiedot" + +#: members/templates/member_duplicates.html:13 +msgid "" +"Found conflicting member entries. Choose how to handle the problematic data." +msgstr "" +"Ongelmallista jäsendataa havaittu. Valitse, miten ongelmat ratkaistaan." + +#: members/templates/member_duplicates.html:29 +msgid "Which one has the correct information for this member?" +msgstr "Kummassa on jäsenen oikeat tiedot?" + +#: members/templates/member_duplicates.html:31 +msgid "Accept first and remove second" +msgstr "Hyväksy ensimmäinen ja poista toinen" + +#: members/templates/member_duplicates.html:32 +msgid "Accept second and remove first" +msgstr "Hyväksy toinen ja poista ensimmäinen" + +#: members/templates/member_duplicates.html:33 +msgid "Accept both as two members" +msgstr "Hyväksy molemmat kahtena jäsenenä" + #: members/templates/member_edit.html:9 msgid "Edit member" msgstr "Muokkaa jäsentä" @@ -301,51 +345,65 @@ msgstr "Muokkaa jäsentä" msgid "Member register" msgstr "Jäsenrekisteri" -#: members/templates/member_list.html:23 +#: members/templates/member_list.html:16 +msgid "" +"There are duplicate member entries in the register.\n" +" Please visit duplicate resolver." +msgstr "" +"Jäsenrekisterissä on duplikaattijäseniä.\n" +" Käytä ongelman ratkaisuun duplikaattityökalua." + +#: members/templates/member_list.html:28 +msgid "Members in register:" +msgstr "Jäseniä:" + +#: members/templates/member_list.html:34 msgid "Download CSV" msgstr "Lataa CSV" #: members/templates/members_base.html:33 +#: members/templates/members_base.html:42 msgid "Member register of SIK ry" msgstr "Aalto-yliopiston Sähköinsinöörikilta ry:n jäsenrekisteri" -#: members/templates/members_base.html:42 webapp/templates/main_index.html:7 +#: members/templates/members_base.html:52 webapp/templates/main_index.html:7 msgid "Members" msgstr "Jäsenet" -#: members/templates/members_base.html:44 +#: members/templates/members_base.html:54 msgid "List members" msgstr "Jäsenlistaus" -#: members/templates/members_base.html:46 +#: members/templates/members_base.html:56 msgid "Add multiple" msgstr "Lisää useita" -#: members/templates/members_base.html:50 +#: members/templates/members_base.html:60 msgid "Payments" msgstr "Maksutapahtumat" -#: members/templates/members_base.html:52 +#: members/templates/members_base.html:62 msgid "List payments" msgstr "Maksulistaus" -#: members/templates/members_base.html:53 members/templates/payment_add.html:8 +#: members/templates/members_base.html:63 members/templates/payment_add.html:8 msgid "Add payment" msgstr "Lisää maksu" -#: members/templates/members_base.html:57 +#: members/templates/members_base.html:67 msgid "Applications" msgstr "Jäsenhakemukset" -#: members/templates/members_base.html:59 +#: members/templates/members_base.html:69 msgid "List applications" msgstr "Hakemuslistaus" -#: members/templates/members_base.html:60 +#: members/templates/members_base.html:70 msgid "Application form" msgstr "Jäsenhakemuslomake" -#: members/templates/members_base.html:65 members/templates/settings.html:11 +#: members/templates/members_base.html:75 members/templates/settings.html:11 msgid "Settings" msgstr "Asetukset" @@ -365,96 +423,100 @@ msgstr "Maksutapahtumat" msgid "Language" msgstr "Kieli" -#: members/templates/settings.html:20 sikweb/settings-sample.py:177 +#: members/templates/settings.html:20 sikweb/settings-sample.py:179 #: sikweb/settings.py:177 msgid "Finnish" msgstr "suomi" -#: members/templates/settings.html:21 sikweb/settings-sample.py:176 +#: members/templates/settings.html:21 sikweb/settings-sample.py:178 #: sikweb/settings.py:176 msgid "English" msgstr "englanti" -#: members/views.py:114 members/views.py:171 members/views.py:190 +#: members/views.py:129 members/views.py:186 members/views.py:205 msgid "No member id specified" msgstr "Jäsenen ID ei määritelty" -#: members/views.py:136 +#: members/views.py:151 msgid "Successfully added member" msgstr "Onnistuneesti lisättiin jäsen" -#: members/views.py:157 +#: members/views.py:172 msgid "Successfully updated member" msgstr "Onnistuneesti päivitettiin jäsen" -#: members/views.py:161 +#: members/views.py:176 msgid "Could not update member object" msgstr "Jäsenobjektia ei voitu päivittää" -#: members/views.py:175 +#: members/views.py:190 msgid "Successfully deleted member" msgstr "Onnistuneesti poistettiin jäsen" -#: members/views.py:181 +#: members/views.py:196 msgid "Could not delete member object" msgstr "Jäsenobjektia ei voitu poistaa" -#: members/views.py:224 members/views.py:258 members/views.py:276 +#: members/views.py:239 members/views.py:273 members/views.py:291 msgid "No application id specified" msgstr "Hakemuksen ID ei määritelty" -#: members/views.py:245 +#: members/views.py:260 msgid "Successfully accepted application" msgstr "Onnistuneesti hyväksyttiin hakemus" -#: members/views.py:248 +#: members/views.py:263 msgid "Could not accept application object" msgstr "Hakemusobjektia ei voitu hyväksyä" -#: members/views.py:262 +#: members/views.py:277 msgid "Successfully deleted application" msgstr "Onnistuneesti poistettiin hakemus" -#: members/views.py:267 +#: members/views.py:282 msgid "Could not delete application object" msgstr "Hakemusobjektia ei voitu poistaa" -#: members/views.py:331 +#: members/views.py:346 msgid "Successfully added payment for member" msgstr "Onnistuneesti lisättiin maksutapahtuma jäsenelle" -#: members/views.py:344 members/views.py:357 members/views.py:371 +#: members/views.py:359 members/views.py:372 members/views.py:386 msgid "No payment id specified" msgstr "Maksutapahtuman ID ei määritelty" -#: members/views.py:375 +#: members/views.py:390 msgid "Successfully deleted payment" msgstr "Onnistuneesti poistettiin maksutapahtuma" -#: members/views.py:380 +#: members/views.py:395 msgid "Could not delete payment object" msgstr "Maksutapahtumaobjektia ei voitu poistaa" -#: members/views.py:395 +#: members/views.py:410 msgid "Successfully updated payment" msgstr "Onnistuneesti päivitettiin maksutapahtuma" -#: members/views.py:398 +#: members/views.py:413 msgid "Could not update payment object" msgstr "Maksutapahtumaobjektia ei voitu päivittää" -#: members/views.py:415 +#: members/views.py:430 msgid "Missing \"textfield\" POST request field" msgstr "Puuttuva \"textfield\" POST-kenttä" -#: members/views.py:420 +#: members/views.py:435 msgid "Successfully imported multiple members" msgstr "Onnistuneesti tuotu useita jäseniä" -#: members/views.py:423 +#: members/views.py:438 msgid "Failed to import members" msgstr "Jäsenten tuonti epäonnistui" +#: members/views.py:504 +msgid "Successfully resolved all member conflicts." +msgstr "Kaikki jäsenkonfliktit ratkaistu onnistuneesti." + #: templates/footer.html:7 msgid "Copyright Aalto-yliopiston Sähköinsinöörikilta ry" msgstr "Copyright Aalto-yliopiston Sähköinsinöörikilta ry" @@ -467,6 +529,18 @@ msgstr "SIK Hallintapaneeli" msgid "Aalto-yliopiston Sähköinsinöörikilta ry" msgstr "Aalto-yliopiston Sähköinsinöörikilta ry" +#: webapp/templates/login.html:25 webapp/templates/login.html:27 +msgid "Username" +msgstr "Käyttäjänimi" + +#: webapp/templates/login.html:31 webapp/templates/login.html:33 +msgid "Password" +msgstr "Salasana" + +#: webapp/templates/login.html:43 +msgid "Log in" +msgstr "Kirjaudu sisään" + #: webapp/templates/main_index.html:8 msgid "Infoscreen" msgstr "Infonäyttö" @@ -490,3 +564,6 @@ msgstr "Sössö" #: webapp/templates/navigation.html:32 msgid "Contact" msgstr "Yhteystiedot" + +#~ msgid "Select" +#~ msgstr "Valitse" diff --git a/members/admin.py b/members/admin.py index bb6b8e0..2251173 100644 --- a/members/admin.py +++ b/members/admin.py @@ -1,7 +1,8 @@ from django.contrib import admin -from members.models import Member, Request, Payment +from members.models import Member, Request, Payment, MemberConflict # Register your models here. admin.site.register(Member) admin.site.register(Request) admin.site.register(Payment) +admin.site.register(MemberConflict) diff --git a/members/migrations/0012_memberconflict.py b/members/migrations/0012_memberconflict.py new file mode 100644 index 0000000..f9ec985 --- /dev/null +++ b/members/migrations/0012_memberconflict.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-05-28 20:32 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('members', '0011_auto_20170526_2013'), + ] + + operations = [ + migrations.CreateModel( + name='MemberConflict', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_member', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberconflict_first_member', to='members.Member')), + ('second_member', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberconflict_second_member', to='members.Member')), + ], + ), + ] diff --git a/members/migrations/0013_auto_20170601_1822.py b/members/migrations/0013_auto_20170601_1822.py new file mode 100644 index 0000000..258e13a --- /dev/null +++ b/members/migrations/0013_auto_20170601_1822.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-06-01 15:22 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('members', '0012_memberconflict'), + ] + + operations = [ + migrations.AlterField( + model_name='payment', + name='member', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='payments', to='members.Member'), + ), + ] diff --git a/members/models.py b/members/models.py index 08550e1..96863c7 100644 --- a/members/models.py +++ b/members/models.py @@ -85,7 +85,11 @@ class Payment(models.Model): ('bank_transfer', _('Bank transfer')), ], max_length=255) - member = models.ForeignKey('Member', on_delete=models.SET_NULL, blank=True, null=True) + member = models.ForeignKey('Member', + on_delete=models.PROTECT, + blank=True, + null=True, + related_name='payments') def __str__(self): return 'Payment no. {}, {}'.format(self.id, str(self.date)) @@ -119,3 +123,21 @@ class Member(BaseMember): AYY=bool(array[4]), jas=bool(array[5]), ) + + +class MemberConflict(models.Model): + + first_member = models.ForeignKey('Member', related_name='%(class)s_first_member') + second_member = models.ForeignKey('Member', related_name='%(class)s_second_member') + + @property + def first_member_form(self): + return MemberForm(instance=self.first_member) + + @property + def second_member_form(self): + return MemberForm(instance=self.second_member) + + +# To avoid problems with a cyclical import, this is at the bottom of the file +from members.forms import MemberForm # nopep8 diff --git a/members/static/css/members.css b/members/static/css/members.css index 23d0aeb..fbe20db 100644 --- a/members/static/css/members.css +++ b/members/static/css/members.css @@ -246,3 +246,27 @@ input { max-width: 100%; height: 10rem !important; } + +.conflict-row { + overflow: auto; + margin-bottom: 2rem; + border: 1px dotted black; +} + +.table-conflict { +} + +.conflict-row>div>table>tbody>tr>th, +.conflict-row>div>table>tbody>tr>td { + border-top: none; + padding: 1rem; +} + +.conflict-row>div { +} + +.member_count { + margin-bottom: 0.5rem; + font-size: 1.2rem; + text-align: right; +} diff --git a/members/templates/member_duplicates.html b/members/templates/member_duplicates.html new file mode 100644 index 0000000..c6f2995 --- /dev/null +++ b/members/templates/member_duplicates.html @@ -0,0 +1,40 @@ +{% extends "members_base.html" %} + +{% load i18n %} +{% load bootstrap3 %} + +{% block content %} +
+
+

{% trans "Conflicting member entries" %}

+
+ +
+

{% blocktrans %}Found conflicting member entries. Choose how to handle the problematic data.{% endblocktrans %}

+ + {% for conflict in conflicts %} +
+
+ + {{ conflict.first_member_form }} +
+
+
+ + {{ conflict.second_member_form }} +
+
+
+
{% csrf_token %} +

{% blocktrans %}Which one has the correct information for this member?{% endblocktrans %}

+ + + + +
+
+
+ {% endfor %} +
+
+{% endblock content %} diff --git a/members/templates/member_list.html b/members/templates/member_list.html index 221764f..7aa6d71 100644 --- a/members/templates/member_list.html +++ b/members/templates/member_list.html @@ -11,12 +11,23 @@

{% trans "Member register" %}

+ {% if is_member_conflict %} +
+ {% blocktrans %}There are duplicate member entries in the register. + Please visit duplicate resolver.{% endblocktrans %} +
+ {% endif %} + {% if notification %}
{{ notification }}
{% endif %} +
+ {% trans "Members in register:" %} {{ member_count }} +
+ {{ table|safe }}
diff --git a/members/templates/settings.html b/members/templates/settings.html index cb9e559..ad70cb0 100644 --- a/members/templates/settings.html +++ b/members/templates/settings.html @@ -20,7 +20,7 @@ - +
diff --git a/members/urls.py b/members/urls.py index 792a1c7..9738af6 100644 --- a/members/urls.py +++ b/members/urls.py @@ -16,6 +16,8 @@ from members.views import member_update from members.views import member_delete_confirm from members.views import member_delete from members.views import payment_list +from members.views import member_duplicates +from members.views import resolve_conflict # rest api from members.views import MemberDetail @@ -102,9 +104,10 @@ urlpatterns = [ # rest api url url(r'^api/members/(?P\d+)$', MemberDetail.as_view()), - # email validation - # url(r'^validate/(?P[0-9A-Za-z_\-\']+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', validateEmail, name='user-activation-link'), - # url(r'^validate/success/$', validate_success), - # url(r'^validate/failure/$', validate_fail), + # member duplicate resolution view + url(r'^duplicates$', member_duplicates), + + # post target for resolving a conflict + url(r'^resolve_conflict$', resolve_conflict) ] diff --git a/members/views.py b/members/views.py index 7dbd7cc..59ca9ee 100644 --- a/members/views.py +++ b/members/views.py @@ -25,8 +25,9 @@ import requests import logging import html import csv +from smtplib import SMTPAuthenticationError -from members.models import Member, Request, Payment +from members.models import Member, Request, Payment, MemberConflict from members.forms import MemberForm, PaymentForm, ApplicationForm # Logger function, you can use the same idea when implementing other loggers to other apps @@ -105,7 +106,8 @@ def member_list(request, *args, **kwargs): context = { 'table': table_html, 'member_count': len(members), - 'notification': request.GET.get('notification', None) + 'notification': request.GET.get('notification', None), + 'is_member_conflict': MemberConflict.objects.exists() } return render(request, 'member_list.html', context) @@ -455,6 +457,54 @@ def export_csv(request, *args, **kwargs): return response +@ensure_csrf_cookie +@require_http_methods(["GET"]) +@permission_required('members.change_member', login_url='/login') +def member_duplicates(request, *args, **kwargs): + conflicts = MemberConflict.objects.all() + context = { + 'conflicts': conflicts + } + + return render(request, 'member_duplicates.html', context) + + +@ensure_csrf_cookie +@require_http_methods(["POST"]) +@permission_required('members.change_member', login_url='/login') +def resolve_conflict(request, *args, **kwargs): + action = request.POST.get('action', None) + if action not in ['first', 'second', 'both']: + return render(request, 'error.html', {'error': '{}: {}'.format(('Incorrect action value'), action)}) + + id = request.POST.get('id', None) + if id is None: + return render(request, 'error.html', {'error': '{}: {}'.format(('Incorrect id value'), id)}) + + conflict = MemberConflict.objects.get(id=id) + first_member = conflict.first_member + second_member = conflict.second_member + + if action == 'first': + for payment in second_member.payments.all(): + payment.member = first_member + payment.save() + second_member.delete() + elif action == 'second': + for payment in first_member.payments.all(): + payment.member = second_member + payment.save() + first_member.delete() + + conflict.delete() + + if MemberConflict.objects.exists(): + return HttpResponseRedirect('/members/duplicates') + else: + notification = _('Successfully resolved all member conflicts.') + return HttpResponseRedirect('/members/list?notification={}'.format(html.escape(notification))) + + def send_mail_wrapper(subject, message, email_to): send_mail(subject, message, @@ -465,18 +515,49 @@ def send_mail_wrapper(subject, message, email_to): @receiver(post_save, sender=Request) def email_on_request(sender, instance, created, **kwargs): - if created: - subject = 'Test1' - message = 'Please validate your email address\r\n' - send_mail_wrapper(subject, message, instance.email) + if not settings.ENABLE_AUTOMATIC_EMAILS: + return + + try: + if created: + subject = 'Test1' + message = 'Please validate your email address\r\n' + send_mail_wrapper(subject, message, instance.email) + except SMTPAuthenticationError: + memberlogger.error('Failed to send email to accepted request!') @receiver(post_save, sender=Member) def email_on_accept(sender, instance, created, **kwargs): - if created: - subject = 'Test2' - message = 'Jäsenhakemuksesi on hyväksytty!!!\r\n' - send_mail_wrapper(subject, message, instance.email) + if not settings.ENABLE_AUTOMATIC_EMAILS: + return + + try: + if created: + subject = 'Test2' + message = 'Jäsenhakemuksesi on hyväksytty!!!\r\n' + send_mail_wrapper(subject, message, instance.email) + except SMTPAuthenticationError: + memberlogger.error('Failed to send email to accepted member!') + + +def check_for_duplicates(instance): + name_candidates = Member.objects.filter(first_name=instance.first_name, + last_name=instance.last_name) + email_candidates = Member.objects.filter(email=instance.email) + + candidates = name_candidates | email_candidates + duplicates = candidates.exclude(id=instance.id) + + if len(duplicates) > 0: + conflict = MemberConflict(first_member=instance, + second_member=duplicates[0]) + conflict.save() + + +@receiver(post_save, sender=Member) +def duplicate_receiver(sender, instance, created, **kwargs): + check_for_duplicates(instance) # Can be used to retrieve single member information via REST API diff --git a/sikweb/settings-sample.py b/sikweb/settings-sample.py index ddce7b0..755f6c4 100644 --- a/sikweb/settings-sample.py +++ b/sikweb/settings-sample.py @@ -158,7 +158,7 @@ EMAIL_PORT = 587 EMAIL_HOST_USER = '@gmail.com' EMAIL_HOST_PASSWORD = '' DEFAULT_EMAIL_FROM = 'SIK Viestintä ' - +ENABLE_AUTOMATIC_EMAILS = False # ReCaptcha # http://www.yaconiello.com/blog/integrating-google-recaptcha-to-django/ diff --git a/webapp/static/css/login.css b/webapp/static/css/login.css index 5c16cf1..8d20848 100644 --- a/webapp/static/css/login.css +++ b/webapp/static/css/login.css @@ -1,7 +1,34 @@ +html { + width: 100%; + height: 100%; +} + +@media (max-width: 760px) { + html { + font-size: 24px; + } +} + +@media (min-width: 760px) { + html { + font-size: 16px; + } +} + +body { + max-width: 760px; + margin: auto; + font-size: 1rem; +} + +h1 { + padding-bottom: 3rem; + padding-top: 3rem; + font-size: 3rem; +} + #content-body { - width: 50vw; - max-width: 800px; - margin: 40px auto; + width: 100%; } #login-button { diff --git a/webapp/templates/login.html b/webapp/templates/login.html index 8688195..7d2d763 100644 --- a/webapp/templates/login.html +++ b/webapp/templates/login.html @@ -5,8 +5,8 @@ - SIK - Login + @@ -19,18 +19,18 @@
-

SIK Admin

+

SIK Admin

{% csrf_token %}
- +
- +
- +
- +
@@ -40,7 +40,7 @@
- +