diff --git a/Pipfile.lock b/Pipfile.lock index def6215c0..176653100 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -16,14 +16,6 @@ ] }, "default": { - "anyascii": { - "hashes": [ - "sha256:24f27431fb64c6c93a33125fb66f8cba007a5262bc1faabeafeda5f4bb70b593", - "sha256:68f6917fe5b22caf7dde8551b838e5e17d5e3c96c55734485699bd03ad92237f" - ], - "markers": "python_version >= '3.3'", - "version": "==0.3.0" - }, "babel": { "hashes": [ "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9", @@ -32,35 +24,12 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.9.1" }, - "beautifulsoup4": { - "hashes": [ - "sha256:05fd825eb01c290877657a56df4c6e4c311b3965bda790c613a3d6fb01a5462a", - "sha256:9fbb4d6e48ecd30bcacc5b63b94088192dcda178513b2ae3c394229f8911b887", - "sha256:e1505eeed31b0f4ce2dbb3bc8eb256c04cc2b3b72af7d551a4ab6efd5cbe5dae" - ], - "version": "==4.8.2" - }, - "certifi": { - "hashes": [ - "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", - "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" - ], - "version": "==2021.10.8" - }, "cfl-common": { "hashes": [ - "sha256:914d0f2ae1503094b6b0fb71554cfbe66b551944866d15da100e2032040e6dbc", - "sha256:9fa2c80d18459b01c85a692a2ca4333f3723553f63a98aafb9eb4a2f1d1f7d0f" - ], - "version": "==5.26.5" - }, - "charset-normalizer": { - "hashes": [ - "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721", - "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c" + "sha256:185c2cd25032928720203c627cf71f06dd775600307a93c68fb52d2f0342000a", + "sha256:9f77d842ee3c83bac5db9674667f6abb679b73dafab36973c94a3bbbfbef7fdc" ], - "markers": "python_version >= '3'", - "version": "==2.0.9" + "version": "==5.27.0" }, "django": { "hashes": [ @@ -88,14 +57,6 @@ ], "version": "==3.7" }, - "django-filter": { - "hashes": [ - "sha256:84e9d5bb93f237e451db814ed422a3a625751cbc9968b484ecc74964a8696b06", - "sha256:e00d32cebdb3d54273c48f4f878f898dced8d5dfaad009438fe61ebdf535ace1" - ], - "markers": "python_version >= '3.5'", - "version": "==2.4.0" - }, "django-formtools": { "hashes": [ "sha256:4699937e19ee041d803943714fe0c1c7ad4cab802600eb64bbf4cdd0a1bfe7d9", @@ -117,14 +78,6 @@ ], "version": "==0.9.1" }, - "django-modelcluster": { - "hashes": [ - "sha256:767084078b9e172540b271454ecc73cb320927131ca4b2c5f276daf771f9542f", - "sha256:e541a46a0a899ef4778a4708be22e71cac3efacc09a6ff44bc065c5c9194c054" - ], - "markers": "python_version >= '3.5'", - "version": "==5.2" - }, "django-otp": { "hashes": [ "sha256:8637be826c0465d0fd1710e4472efe9fc83883853a2141fefdbace9358d20003", @@ -147,22 +100,6 @@ ], "version": "==1.6.14" }, - "django-taggit": { - "hashes": [ - "sha256:dfe9e9c10b5929132041de0c00093ef0072c73c2a97d0f74a818ae50fa77149a", - "sha256:e5bb62891f458d55332e36a32e19c08d20142c43f74bc5656c803f8af25c084a" - ], - "markers": "python_version >= '3.6'", - "version": "==1.5.1" - }, - "django-treebeard": { - "hashes": [ - "sha256:7c2b1cdb1e9b46d595825186064a1228bc4d00dbbc186db5b0b9412357fba91c", - "sha256:80150017725239702054e5fa64dc66e383dc13ac262c8d47ee5a82cb005969da" - ], - "markers": "python_version >= '3.6'", - "version": "==4.5.1" - }, "django-two-factor-auth": { "hashes": [ "sha256:24c2850a687c86800f4aa4131b7cebadf56f35be04ca359c4990578df1cc249a", @@ -178,21 +115,6 @@ "markers": "python_version >= '3.5'", "version": "==3.12.2" }, - "draftjs-exporter": { - "hashes": [ - "sha256:5839cbc29d7bce2fb99837a404ca40c3a07313f2a20e2700de7ad6aa9a9a18fb", - "sha256:d415a9964690a2cddb66a31ef32dd46c277e9b80434b94e39e3043188ed83e33" - ], - "version": "==2.1.7" - }, - "et-xmlfile": { - "hashes": [ - "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c", - "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada" - ], - "markers": "python_version >= '3.6'", - "version": "==1.1.0" - }, "future": { "hashes": [ "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" @@ -200,29 +122,6 @@ "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==0.18.2" }, - "html5lib": { - "hashes": [ - "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d", - "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.1" - }, - "idna": { - "hashes": [ - "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", - "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" - ], - "markers": "python_version >= '3'", - "version": "==3.3" - }, - "l18n": { - "hashes": [ - "sha256:1956e890d673d17135cc20913253c154f6bc1c00266c22b7d503cc1a5a42d848", - "sha256:78495d1df95b6f7dcc694d1ba8994df709c463a1cbac1bf016e1b9a5ce7280b9" - ], - "version": "==2021.3" - }, "libsass": { "hashes": [ "sha256:1521d2a8d4b397c6ec90640a1f6b5529077035efc48ef1c2e53095544e713d1b", @@ -249,60 +148,6 @@ "markers": "python_version >= '3.5'", "version": "==8.6.0" }, - "openpyxl": { - "hashes": [ - "sha256:40f568b9829bf9e446acfffce30250ac1fa39035124d55fc024025c41481c90f", - "sha256:8f3b11bd896a95468a4ab162fc4fcd260d46157155d1f8bfaabb99d88cfcf79f" - ], - "version": "==3.0.9" - }, - "pillow": { - "hashes": [ - "sha256:066f3999cb3b070a95c3652712cffa1a748cd02d60ad7b4e485c3748a04d9d76", - "sha256:0a0956fdc5defc34462bb1c765ee88d933239f9a94bc37d132004775241a7585", - "sha256:0b052a619a8bfcf26bd8b3f48f45283f9e977890263e4571f2393ed8898d331b", - "sha256:1394a6ad5abc838c5cd8a92c5a07535648cdf6d09e8e2d6df916dfa9ea86ead8", - "sha256:1bc723b434fbc4ab50bb68e11e93ce5fb69866ad621e3c2c9bdb0cd70e345f55", - "sha256:244cf3b97802c34c41905d22810846802a3329ddcb93ccc432870243211c79fc", - "sha256:25a49dc2e2f74e65efaa32b153527fc5ac98508d502fa46e74fa4fd678ed6645", - "sha256:2e4440b8f00f504ee4b53fe30f4e381aae30b0568193be305256b1462216feff", - "sha256:3862b7256046fcd950618ed22d1d60b842e3a40a48236a5498746f21189afbbc", - "sha256:3eb1ce5f65908556c2d8685a8f0a6e989d887ec4057326f6c22b24e8a172c66b", - "sha256:3f97cfb1e5a392d75dd8b9fd274d205404729923840ca94ca45a0af57e13dbe6", - "sha256:493cb4e415f44cd601fcec11c99836f707bb714ab03f5ed46ac25713baf0ff20", - "sha256:4acc0985ddf39d1bc969a9220b51d94ed51695d455c228d8ac29fcdb25810e6e", - "sha256:5503c86916d27c2e101b7f71c2ae2cddba01a2cf55b8395b0255fd33fa4d1f1a", - "sha256:5b7bb9de00197fb4261825c15551adf7605cf14a80badf1761d61e59da347779", - "sha256:5e9ac5f66616b87d4da618a20ab0a38324dbe88d8a39b55be8964eb520021e02", - "sha256:620582db2a85b2df5f8a82ddeb52116560d7e5e6b055095f04ad828d1b0baa39", - "sha256:62cc1afda735a8d109007164714e73771b499768b9bb5afcbbee9d0ff374b43f", - "sha256:70ad9e5c6cb9b8487280a02c0ad8a51581dcbbe8484ce058477692a27c151c0a", - "sha256:72b9e656e340447f827885b8d7a15fc8c4e68d410dc2297ef6787eec0f0ea409", - "sha256:72cbcfd54df6caf85cc35264c77ede902452d6df41166010262374155947460c", - "sha256:792e5c12376594bfcb986ebf3855aa4b7c225754e9a9521298e460e92fb4a488", - "sha256:7b7017b61bbcdd7f6363aeceb881e23c46583739cb69a3ab39cb384f6ec82e5b", - "sha256:81f8d5c81e483a9442d72d182e1fb6dcb9723f289a57e8030811bac9ea3fef8d", - "sha256:82aafa8d5eb68c8463b6e9baeb4f19043bb31fefc03eb7b216b51e6a9981ae09", - "sha256:84c471a734240653a0ec91dec0996696eea227eafe72a33bd06c92697728046b", - "sha256:8c803ac3c28bbc53763e6825746f05cc407b20e4a69d0122e526a582e3b5e153", - "sha256:93ce9e955cc95959df98505e4608ad98281fff037350d8c2671c9aa86bcf10a9", - "sha256:9a3e5ddc44c14042f0844b8cf7d2cd455f6cc80fd7f5eefbe657292cf601d9ad", - "sha256:a4901622493f88b1a29bd30ec1a2f683782e57c3c16a2dbc7f2595ba01f639df", - "sha256:a5a4532a12314149d8b4e4ad8ff09dde7427731fcfa5917ff16d0291f13609df", - "sha256:b8831cb7332eda5dc89b21a7bce7ef6ad305548820595033a4b03cf3091235ed", - "sha256:b8e2f83c56e141920c39464b852de3719dfbfb6e3c99a2d8da0edf4fb33176ed", - "sha256:c70e94281588ef053ae8998039610dbd71bc509e4acbc77ab59d7d2937b10698", - "sha256:c8a17b5d948f4ceeceb66384727dde11b240736fddeda54ca740b9b8b1556b29", - "sha256:d82cdb63100ef5eedb8391732375e6d05993b765f72cb34311fab92103314649", - "sha256:d89363f02658e253dbd171f7c3716a5d340a24ee82d38aab9183f7fdf0cdca49", - "sha256:d99ec152570e4196772e7a8e4ba5320d2d27bf22fdf11743dd882936ed64305b", - "sha256:ddc4d832a0f0b4c52fff973a0d44b6c99839a9d016fe4e6a1cb8f3eea96479c2", - "sha256:e3dacecfbeec9a33e932f00c6cd7996e62f53ad46fbe677577394aaa90ee419a", - "sha256:eb9fc393f3c61f9054e1ed26e6fe912c7321af2f41ff49d3f83d05bacf22cc78" - ], - "markers": "python_version >= '3.6'", - "version": "==8.4.0" - }, "pyhamcrest": { "hashes": [ "sha256:412e00137858f04bde0729913874a48485665f2d36fe9ee449f26be864af9316", @@ -329,14 +174,6 @@ "editable": true, "path": "." }, - "requests": { - "hashes": [ - "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24", - "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==2.26.0" - }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -345,14 +182,6 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, - "soupsieve": { - "hashes": [ - "sha256:1a3cca2617c6b38c0343ed661b1fa5de5637f257d4fe22bd9f1338010a1efefb", - "sha256:b8d49b1cd4f037c7082a9683dfa1801aa2597fb11c3a1155b7a5b94829b4f1f9" - ], - "markers": "python_version >= '3.6'", - "version": "==2.3.1" - }, "sqlparse": { "hashes": [ "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae", @@ -360,87 +189,16 @@ ], "markers": "python_version >= '3.5'", "version": "==0.4.2" - }, - "tablib": { - "extras": [ - "xls", - "xlsx" - ], - "hashes": [ - "sha256:26141c9cf2d5904a2228d3f5d45f8a46a3f3f2f0fbb4c33b4a1c1ddca9f31348", - "sha256:d64c9f6712918a3d90ec5d71b44b8bab1083e3609e4844ad2be80eb633e097ed" - ], - "markers": "python_version >= '3.6'", - "version": "==3.1.0" - }, - "unidecode": { - "hashes": [ - "sha256:215fe33c9d1c889fa823ccb66df91b02524eb8cc8c9c80f9c5b8129754d27829", - "sha256:669898c1528912bcf07f9819dc60df18d057f7528271e31f8ec28cc88ef27504" - ], - "markers": "python_version >= '3.5'", - "version": "==1.3.2" - }, - "urllib3": { - "hashes": [ - "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece", - "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.26.7" - }, - "wagtail": { - "hashes": [ - "sha256:460c4da96ecb84f817b80cfb5f9907a5be215df2f271c7569d6f58bd72e3c126", - "sha256:4b280742a7a97401b4c10dbcf7336dc99e367b5b95c21b9b3560abc697a9a627" - ], - "markers": "python_version >= '3.6'", - "version": "==2.11.8" - }, - "webencodings": { - "hashes": [ - "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", - "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" - ], - "version": "==0.5.1" - }, - "willow": { - "hashes": [ - "sha256:698f755fc6bfb8984ac8550f470a0cb630ec1e628287475315d4d1e7595d7337", - "sha256:cde01e054c510284ac3459d6b531e1653a58e33a735706ac27905a94fe81742c" - ], - "version": "==1.4" - }, - "xlrd": { - "hashes": [ - "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd", - "sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88" - ], - "version": "==2.0.1" - }, - "xlsxwriter": { - "hashes": [ - "sha256:0956747859567ec01907e561a7d8413de18a7aae36860f979f9da52b9d58bc19", - "sha256:f9335f1736e2c4fd80e940fe1b6d92d967bf454a1e5d639b0b7a4459ade790cc" - ], - "version": "==1.4.5" - }, - "xlwt": { - "hashes": [ - "sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e", - "sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88" - ], - "version": "==1.3.0" } }, "develop": { "attrs": { "hashes": [ - "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", - "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" + "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", + "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.2.0" + "version": "==21.4.0" }, "django": { "hashes": [ @@ -468,11 +226,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:53ccfd5c134223e497627b9815d5030edf77d2ed573922f7a0b8f8bb81a1c100", - "sha256:75bdec14c397f528724c1bfd9709d660b33a4d2e77387a3358f20b848bb5e5fb" + "sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6", + "sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4" ], "markers": "python_version < '3.8' and python_version < '3.8'", - "version": "==4.8.2" + "version": "==4.10.0" }, "iniconfig": { "hashes": [ @@ -574,7 +332,7 @@ "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece", "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4.0'", "version": "==1.26.7" }, "zipp": { diff --git a/game/forms.py b/game/forms.py index d8567d446..66c20dd11 100644 --- a/game/forms.py +++ b/game/forms.py @@ -1,38 +1,9 @@ from __future__ import absolute_import import itertools -from builtins import str from django import forms - -from .models import Level - - -class ShareLevelPerson(forms.Form): - def __init__(self, *args, **kwargs): - super(ShareLevelPerson, self).__init__(*args, **kwargs) - self.fields["name"] = forms.CharField(max_length=100) - self.fields["surname"] = forms.CharField(max_length=100) - self.fields["level"] = forms.IntegerField() - self.fields["level"].widget = forms.HiddenInput() - - -class ShareLevelChoosePerson(forms.Form): - def __init__(self, *args, **kwargs): - people = kwargs.pop("people") - super(ShareLevelChoosePerson, self).__init__(*args, **kwargs) - self.fields["people"] = forms.ModelChoiceField(queryset=people) - self.fields["level"] = forms.IntegerField() - self.fields["level"].widget = forms.HiddenInput() - - -class ShareLevelClass(forms.Form): - def __init__(self, *args, **kwargs): - classes = kwargs.pop("classes") - super(ShareLevelClass, self).__init__(*args, **kwargs) - self.fields["classes"] = forms.ModelChoiceField(queryset=classes) - self.fields["levels"] = forms.IntegerField() - self.fields["levels"].widget = forms.HiddenInput() +from .models import Episode class ScoreboardForm(forms.Form): @@ -47,19 +18,14 @@ def __init__(self, *args, **kwargs): # Each tuple in choices has two elements, id and name of each level # First element is the actual value set on the model # Second element is the string displayed on the drop down menu - choice_list = ( - (level.id, str(level)) for level in Level.objects.sorted_levels() + episodes_choices = ( + (episode.id, episode.name) for episode in Episode.objects.all() ) - self.fields["levels"] = forms.MultipleChoiceField( - choices=itertools.chain(choice_list), widget=forms.CheckboxSelectMultiple() + self.fields["episodes"] = forms.MultipleChoiceField( + choices=itertools.chain(episodes_choices), + widget=forms.CheckboxSelectMultiple(), ) - def validate(self): - cleaned_data = super(ScoreboardForm, self).clean() - classes = cleaned_data.get("classes") - levels = cleaned_data.get("levels") - return classes and levels - class LevelModerationForm(forms.Form): def __init__(self, *args, **kwargs): @@ -71,8 +37,3 @@ def __init__(self, *args, **kwargs): widget=forms.Select(), ) self.fields["students"] = forms.CharField(required=False, widget=forms.Select()) - - def validate(self): - cleaned_data = super(LevelModerationForm, self).clean() - classes = cleaned_data.get("classes") - return classes diff --git a/game/static/game/css/dataTables.fixedColumns.css b/game/static/game/css/dataTables.fixedColumns.css index 0d6e18abf..0e058e0ef 100644 --- a/game/static/game/css/dataTables.fixedColumns.css +++ b/game/static/game/css/dataTables.fixedColumns.css @@ -1,25 +1,54 @@ - - /* Block out what is behind the fixed column's header and footer */ table.DTFC_Cloned thead, table.DTFC_Cloned tfoot { - background-color: white; + background-color: white; } /* Block out the gap above the scrollbar on the right, when there is a fixed * right column */ div.DTFC_Blocker { - background-color: white; + background-color: white; } div.DTFC_LeftWrapper table.dataTable, div.DTFC_RightWrapper table.dataTable { - margin-bottom: 0; - z-index: 2; + margin-bottom: 0; + z-index: 2; } div.DTFC_LeftWrapper table.dataTable.no-footer, div.DTFC_RightWrapper table.dataTable.no-footer { - border-bottom: none; + border-bottom: none; +} + +div.DTFC_LeftBodyLiner { + padding-right: 0; + width: inherit; +} + +#scoreboardTable tbody td, +#scoreboardTable_wrapper tbody td, +#improvementTable_wrapper td, +#improvementTable_wrapper tbody td { + border-right: 1px solid white; + border-top: 1px solid white; +} + +.DTFC_ScrollWrapper th, +.DTFC_ScrollWrapper td, +#scoreboardTable th, +#scoreboardTable td { + height: 34px; + min-width: 30px; +} + +.DTFC_LeftHeadWrapper, +.DTFC_LeftBodyWrapper { + box-shadow: 4px 0 10px 0 rgba(0, 0, 0, 0.5); +} + +.DTFC_RightHeadWrapper, +.DTFC_RightBodyWrapper { + box-shadow: -4px 0 10px 0 rgba(0, 0, 0, 0.5); } diff --git a/game/static/game/css/jquery.dataTables.css b/game/static/game/css/jquery.dataTables.css index 67690b586..58753a2bc 100644 --- a/game/static/game/css/jquery.dataTables.css +++ b/game/static/game/css/jquery.dataTables.css @@ -21,7 +21,6 @@ table.dataTable tfoot th { table.dataTable thead th, table.dataTable thead td { padding: 10px 18px; - border-bottom: 1px solid #111; } table.dataTable thead th:active, table.dataTable thead td:active { @@ -296,7 +295,7 @@ table.dataTable td { .dataTables_wrapper .dataTables_paginate { float: right; text-align: right; - padding-top: 0.25em; + padding-top: 0.55em; } .dataTables_wrapper .dataTables_paginate .paginate_button { box-sizing: border-box; diff --git a/game/static/game/css/jquery.ui.multiprogressbar.css b/game/static/game/css/jquery.ui.multiprogressbar.css deleted file mode 100644 index 3358d794b..000000000 --- a/game/static/game/css/jquery.ui.multiprogressbar.css +++ /dev/null @@ -1,18 +0,0 @@ -@CHARSET "UTF-8"; - -/* - * jQuery UI Multi-Progress Bar 1.1.0 - * http://github.com/j-ulrich/jquery-ui-multiprogressbar - * - * Copyright (c) 2012 Jochen Ulrich - * Licensed under the MIT license (MIT-LICENSE.txt). - */ - -.ju-multiprogressbar .ui-progressbar-value { - float: left; -} - -.ju-multiprogressbar .ju-multiprogressbar-valuetext { - margin-top: 0.3em; - text-align: center; -} \ No newline at end of file diff --git a/game/static/game/css/scoreboard.css b/game/static/game/css/scoreboard.css index 72891e0c8..6774ab2e7 100644 --- a/game/static/game/css/scoreboard.css +++ b/game/static/game/css/scoreboard.css @@ -1,155 +1,138 @@ -.form label { - width: 200px; - float: left; - margin: 0 20px 0 0; +.level_rr_logo { + text-align: center; } -.form input { - width: 200px; - border: 1px solid #000; - padding: 5px; +.level_rr_logo img { + width: 25%; } -.tableWrapper { - overflow: auto; - width: 100%; +.dropdown > .button--secondary, +.row > div > .button--secondary, +.row > div > .button--primary { + margin: 0; } -/* tables */ - -table { - width: 99%; +.input--icon > input[type="text"], +.input--icon > input[type="text"]:hover, +.input--icon > input[type="text"]:focus { + border: 2px solid #eab502; } -/* Needed for keeping the rows aligned after freezing the first column */ -table tbody td { - /* To ensure all rows have the same height as wrapping may increases row height */ - white-space: nowrap; - /* The height of the row has to be set in order for the progress bar to fit the row */ - height: 25px; - font-size: 15px +input[type="checkbox"] { + width: 20px; } -.ui-progressbar { - height: 100%; +.open > .dropdown-menu { + display: flex; + flex-direction: column; } -/* Colour for the portion of the bar which represents the percentage of levels players finished */ -.ui-progressbar .finished { - background: #74B06B; -} -/* Colour for the portion of the bar which represents the percentage of levels players finished but under a certain - * threshold - */ -.ui-progressbar .attempted { - background: #E1B377; -} -/* Colour for the portion of the bar which represents the percentage of levels players started but haven't submitted - * attempts yet - */ -.ui-progressbar .started { - background: #C24563; +.button--dropdown, +.dropdown-menu { + width: 100%; + background-color: #fff; } -#scoreboardTable tr td.untouched { - background: #d9d9d9; +.dropdown-menu { + overflow-x: hidden; + font-style: normal; + max-height: 380px; } -/* Used for making the inside of the progress bar to fill up the entire outer container - * margin and border are set in jquery-ui.structure.css and jquery-ui.css - * we are overwriting the settings for the following two properties - */ -.ui-progressbar .ui-progressbar-value{ - margin: 0px; - border: 0px; + +.dropdown-menu > ul { + font-style: normal; + overflow-y: auto; } -#scoreboardForm { - text-align: center; +.dropdown-menu > .row { + padding: 15px 0 15px 0; } -#scoreboardForm .select-list { - text-align: left; - overflow: scroll; - height: 300px; +.dropdown-menu__option__text { + width: 100%; } -#scoreboardForm .select-list label { - float: none; +.dropdown-menu__option__text label { + align-items: center; + display: flex; + flex-direction: row-reverse; + font-weight: normal; + justify-content: space-between; + margin: 0; } -#scoreboardForm .select-list ul { - list-style-type: none; +.tableWrapper { + width: 100%; } -#scoreboardForm .select-list li { - display: flex; +div.DTFC_LeftBodyLiner, +div.DTFC_RightBodyLiner { + overflow: hidden; } -#scoreboardForm .select-list li label { - margin: 0.1rem 0; - vertical-align: middle; - width: 100%; - text-align: left; - font-weight: normal; - text-decoration: none; - font-style: normal; - color: #000; +.dataTables_wrapper .dataTables_length, +.dataTables_wrapper .dataTables_filter, +.dataTables_wrapper .dataTables_paginate span, +.dataTables_wrapper .dataTables_paginate .disabled, +.dataTables_wrapper .dataTables_paginate .paginate_button.disabled { + display: none; } -#scoreboardForm .all-class { - background-color: #ccc; - padding: 1rem; - margin: 1rem; +a.next:focus, +a.previous:focus { + outline: none; } -#scoreboardForm .all-class.checked { - background-color: #6c696c; - color: #fff; +#scoreboardTable_wrapper table, +#scoreboardTable_wrapper th, +#scoreboardTable_wrapper td, +#improvementTable_wrapper table, +#improvementTable_wrapper th, +#improvementTable_wrapper td { + border: none; + border-right: 1px solid white; } -#scoreboardForm .class { - background-color: #fff; - padding: 1rem; - margin: 0 1rem; - border-bottom: 1px solid #aaa; +table { + width: 99%; } -#scoreboardForm .class.checked { - background-color: #ccc; +table tbody td { + font-size: 15px; } -#scoreboardForm .all-level { - background-color: #ccc; - padding: 1rem; - margin: 1rem; +table th.fixed-width, +table td.fixed-width { + max-width: 140px; + min-width: 140px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } -#scoreboardForm .all-level.checked { - background-color: #6c696c; - color: #fff; +#scoreboardTable_wrapper td.scoreboard--started { + background: #e0004d; + color: white; } -#scoreboardForm .episode { - background-color: #d2e6ed; - padding: 1rem; - margin: 0.5rem 1rem; +#scoreboardTable_wrapper td.scoreboard--completed { + color: #eab502; + font-size: 24px; } -#scoreboardForm .episode.checked { - background-color: #0c52a3; +#scoreboardTable_wrapper td.scoreboard--completed-secondary { + color: #fff; + font-size: 24px; } -#scoreboardForm .level { - background-color: #fff; - padding: 1rem; - margin: 0 1rem 0 5rem; - border-bottom: 1px solid #aaa; +#scoreboardTable_wrapper td.scoreboard--medium-performer { + background: #f6a500; } -#scoreboardForm .level.checked { - background-color: #ccc; +#scoreboardTable_wrapper td.scoreboard--top-performer { + background: #b1ba1d; } -#scoreboardForm .expander { - color: #000; +#scoreboardTable_wrapper tr.current-student > td { + background: #85ddff; /* $color-tertiary-50 */ } diff --git a/game/static/game/js/jquery.ui.multiprogressbar.js b/game/static/game/js/jquery.ui.multiprogressbar.js deleted file mode 100644 index 221497e37..000000000 --- a/game/static/game/js/jquery.ui.multiprogressbar.js +++ /dev/null @@ -1,188 +0,0 @@ -/*jslint white: true vars: true browser: true todo: true */ -/*jshint camelcase:true, plusplus:true, forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, unused:true, curly:true, browser:true, devel:true, maxerr:100, white:false, onevar:false */ -/*global jQuery:true $:true */ - -/* jQuery UI Multi-Progress Bar 1.1.0 - * http://github.com/j-ulrich/jquery-ui-multiprogressbar - * - * Copyright (c) 2012 Jochen Ulrich - * Licensed under the MIT license (MIT-LICENSE.txt). - */ - -/** - * @file jQuery UI Multi-Progress Bar - * @version 1.0 - * @copyright 2012 Jochen Ulrich - * @license MIT (MIT-LICENSE.txt) - */ - -(function($) { - "use strict"; - - /** - * Constructs a multiprogressbar. - * @name multiprogressbar - * @public - * @function - * @memberOf jQuery.ju - */ - $.widget("ju.multiprogressbar", - - /** - * @lends jQuery.ju.multiprogressbar.prototype - */ - { - - // Options - /** - * Default values of the options. - * @since 1.0 - */ - options: { - parts: [{value: 0, barClass: "", text: false, textClass: ""}] - }, - - /** - * Constructor for multiprogressbars. - * @private - * @author julrich - * @since 1.0 - */ - _create: function() { - var self = this; - self.element.progressbar({value: 0, disabled: self.options.disabled}); // Creates one part with width 0% - self.element.addClass("ju-multiprogressbar"); - - // Use the part generated by jQuery UI progressbar as template for the other parts - self._partTemplate = self._getPartElements().outerHTML() ; - self._createParts(self.options.parts); - $.extend(self,{ - created: true - }); - }, - - /** - * @returns {Object} a jQuery object containing all part elements. - * @private - * @author julrich - * @since 1.0 - */ - _getPartElements: function() { - return this.element.children(".ui-progressbar-value"); - }, - - /** - * (Re)creates the markup of the parts. - * @param {Array} parts - Array of part objects defining the properties of the parts to be created. - * @fires multiprogressbar#change when the function is called after the creation of the multiprogressbar - * (i.e. the event is not fired during the creation). - * @fires multiprogressbar#complete when the total progress reaches or exceeds 100%. - * @private - * @author julrich - * @since 1.0 - */ - _createParts: function(parts) { - var self = this; - - self._getPartElements().remove(); // Remove all existing parts and then rebuild them - var first = true; - var lastVisibleElement = null; - var totalValue = 0; - $.each(parts, function(i, part) { - var partElement = $(self._partTemplate).appendTo(self.element); - - if (first === false) { - partElement.removeClass("ui-corner-left"); - } - if (part.value > 0 && totalValue < 100) { - first = false; - // Check if the part would exceed the 100% and cut it at 100% - part.value = totalValue+part.value > 100 ? 100-totalValue : part.value; - partElement.css('width', part.value+"%").show(); - lastVisibleElement = partElement; - totalValue += part.value; - } - else { - // Hide part if the progress is <= 0 or if we exceeded 100% already - part.value = 0; - partElement.hide(); - } - - partElement.addClass(part.barClass); - - if (part.text !== undefined && part.text !== null && part.text !== false) { - var textForPart; - if (part.text === true) { - textForPart = Math.round(part.value)+"%"; - } - else if ($.trim(part.text) !== "") { - textForPart = part.text; - } - $('
').addClass("ju-multiprogressbar-valuetext").text(textForPart).addClass(part.textClass).appendTo(partElement); - } - }); - if (self.created === true) { // Don't trigger "change" when we are creating the progressbar for the first time - self._trigger("change", null, {parts: parts}); - } - if (totalValue >= 99.9) { - lastVisibleElement.addClass("ui-corner-right"); - // Trigger complete - self._trigger("complete"); - } - }, - - /** - * Restores the element to it's original state. - * @public - * @author julrich - * @since 1.0 - */ - destroy: function() { - var self = this; - self._getPartElements().remove(); - self.element.progressbar("destroy"); - }, - - /** - * Changes an option. - * @param {String} option - name of the option to be set. - * @param value - new value for the option. - * @private - * @author julrich - * @since 1.0 - */ - _setOption: function(option, value) { - var self = this; - $.Widget.prototype._setOption.apply( self, arguments ); - - switch(option) { - case "parts": - self._createParts(value); - break; - case "dummy": - break; - default: - break; - } - }, - - /** - * @return {Numeric} the sum of the progress of all visible parts. - * Note: When the sum of the progress of the parts exceeds 100, the progress - * will be truncated at 100 and the value of successive parts will be set to 0. This means - * that this function will always return a value in the range [0,100]. - * @public - * @author julrich - * @since 1.0 - */ - total: function() { - var self = this; - var totalValue = 0; - $.each(self.options.parts, function(i, part) { - totalValue += part.value; - }); - - return totalValue; - } - }); -}(jQuery)); \ No newline at end of file diff --git a/game/static/game/js/scoreboard.js b/game/static/game/js/scoreboard.js index 0028e0da9..bc6469236 100644 --- a/game/static/game/js/scoreboard.js +++ b/game/static/game/js/scoreboard.js @@ -1,31 +1,91 @@ -$(':checkbox').on('change', function() { - $(this).closest('li').toggleClass('checked', $(this).is(':checked')) -}) - -$('.all-class > label, .all-level').on('change', function() { - var check = $(this).find('input').is(':checked') - $(this).closest('ul').find(':checkbox').prop('checked', check).closest('li').toggleClass('checked', check) -}) - -$('.episode').on('change', function() { - var check = $(this).find('input').is(':checked') - var first = $(this).attr('data-first') - var last = $(this).attr('data-last') - for (var i = first; i <= last; i++) { - $('.level-'+i).find(':checkbox').prop('checked', check).closest('li').toggleClass('checked', check) - } -}) - -$('.expander').on('click', function() { - var el = $(this).closest('li') - var first = el.attr('data-first') - var last = el.attr('data-last') - if ($('.level-'+first).is(':visible')) { - el.find('span').text('arrow_left') - } else { - el.find('span').text('arrow_drop_down') - } - for (var i = first; i <= last; i++) { - $('.level-'+i).toggle('blind') - } -}) +$(document).ready(function () { + $("#clear-classes").on("click", () => { + $('[id^="id_classes_"],#select-all-classes').prop("checked", false); + }); + + $("#select-all-classes").on("click", () => { + $('[id^="id_classes_"]').prop("checked", $("#select-all-classes").is(":checked")); + }); + + $("#clear-levels").on("click", () => { + $('[id^="id_episodes_"],#select-all-levels').prop("checked", false); + }); + + $("#select-all-levels").on("click", () => { + $('[id^="id_episodes_"]').prop("checked", $("#select-all-levels").is(":checked")); + }); + + let scoreboardPresent = document.getElementById("scoreboardTable") !== null; + let improvementPresent = document.getElementById("improvementTable") !== null; + + if (scoreboardPresent) { + let table = $("#scoreboardTable").DataTable({ + scrollY: false, + scrollX: true, + scrollCollapse: false, + paging: true, + deferRender: true, + language: { + emptyTable: "No data available in table", + loadingRecords: "Loading...", + processing: "Processing...", + search: "Search:", + zeroRecords: "No matching records found" + }, + columnDefs: [ + { + orderable: false, + targets: "no-sort" + } + ] + }); + + new $.fn.dataTable.FixedColumns(table, { + leftColumns: 3, + rightColumns: 1 + }); + + $("#scoreboardSearch").on("keyup", function () { + table.search(this.value).draw(); + }); + + $("#scoreboardTable_next").append(" >"); + $(".next").removeClass("paginate_button"); + + table.on("draw", () => { + $("#scoreboardTable_next").append(" >"); + $("#scoreboardTable_previous").prepend("< "); + $(".next").removeClass("paginate_button"); + $(".previous").removeClass("paginate_button"); + }); + + $(window).on("load", function () { + table.columns.adjust(); + }); + } + + // Stops closing the dropdowns when selecting items within it or when pressing the confirmation buttons + $(document).on("click", ".dropdown .dropdown-menu", function (e) { + e.stopPropagation(); + }); + + if (improvementPresent) { + const impTable = $("#improvementTable").DataTable({ + pageLength: 5 + }); + + $("#scoreboardSearch").on("keyup", function () { + impTable.search(this.value).draw(); + }); + + $("#improvementTable_next").append(" >"); + $(".next").removeClass("paginate_button"); + + impTable.on("draw", () => { + $("#improvementTable_next").append(" >"); + $("#improvementTable_previous").prepend("< "); + $(".next").removeClass("paginate_button"); + $(".previous").removeClass("paginate_button"); + }); + } +}); diff --git a/game/templates/game/base.html b/game/templates/game/base.html index 4f7c17b0d..7cb4409b4 100644 --- a/game/templates/game/base.html +++ b/game/templates/game/base.html @@ -30,7 +30,13 @@

Rapid router has been created to teach the first principles of computer prog {% endblock header %} +{% if user|is_logged_in_as_student %} +